xf86-video-intel: Branch 'modesetting' - 156 commits - configure.ac man/.gitignore man/i810.man README README.sgml src/brw_defines.h src/brw_structs.h src/common.h src/i810_dri.h src/i810_driver.c src/i810.h src/i810_reg.h src/i830_3d.c src/i830_accel.c src/i830_bios.c src/i830_common.h src/i830_cursor.c src/i830_dga.c src/i830_display.c src/i830_display.h src/i830_dri.c src/i830_dri.h src/i830_driver.c src/i830.h src/i830_memory.c src/i830_modes.c src/i830_randr.c src/i830_reg.h src/i830_rotate.c src/i830_video.c src/i830_video.h src/i915_3d.c src/i915_3d.h src/i915_reg.h src/i915_video.c src/Makefile.am src/packed_yuv_sf.g4a src/packed_yuv_wm.g4a src/sf_prog.h src/wm_prog.h

Eric Anholt anholt at kemper.freedesktop.org
Thu Sep 28 02:51:01 EEST 2006


 README                |  151 ++---
 README.sgml           |  117 ++--
 configure.ac          |   19 
 man/.gitignore        |    2 
 man/i810.man          |   33 -
 src/Makefile.am       |   27 
 src/brw_defines.h     |  847 +++++++++++++++++++++++++++++
 src/brw_structs.h     | 1340 +++++++++++++++++++++++++++++++++++++++++++++++
 src/common.h          |   50 +
 src/i810.h            |    4 
 src/i810_dri.h        |    4 
 src/i810_driver.c     |   19 
 src/i810_reg.h        |  338 +++++++++++
 src/i830.h            |   50 +
 src/i830_3d.c         |  131 ++++
 src/i830_accel.c      |   79 ++
 src/i830_bios.c       |    8 
 src/i830_common.h     |    8 
 src/i830_cursor.c     |  451 ++++++++-------
 src/i830_dga.c        |   19 
 src/i830_display.c    |   23 
 src/i830_display.h    |    2 
 src/i830_dri.c        |  139 ++--
 src/i830_dri.h        |   40 -
 src/i830_driver.c     | 1011 ++++++++++++++++-------------------
 src/i830_memory.c     |  111 +++
 src/i830_modes.c      |   43 +
 src/i830_randr.c      |  468 ++++++++++++++++
 src/i830_reg.h        |  637 ++++++++++++++++++++++
 src/i830_rotate.c     |  217 ++++---
 src/i830_video.c      | 1417 +++++++++++++++++++++++++++++++++++++++++++-------
 src/i830_video.h      |   77 ++
 src/i915_3d.c         |  107 +++
 src/i915_3d.h         |  431 +++++++++++++++
 src/i915_reg.h        |  848 +++++++++++++++++++++++++++++
 src/i915_video.c      |  467 ++++++++++++++++
 src/packed_yuv_sf.g4a |   17 
 src/packed_yuv_wm.g4a |  161 +++++
 src/sf_prog.h         |   17 
 src/wm_prog.h         |   82 ++
 40 files changed, 8684 insertions(+), 1328 deletions(-)

New commits:
diff-tree 6ea16bf6b06c8b3aed4d2c98679ab28304d1b56c (from parents)
Merge: fdb6de663579d3b9f31bf9e8a93430b8505ca73f b970166eab95ac024ff481b0f5fd9aaf3644aabf
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Sep 27 16:38:01 2006 -0700

    Merge branch 'master' into modesetting
    
    This reverts most of the mergedfb code.  This will instead be done in device-
    independent RandR code.
    
    Conflicts:
    
    	src/Makefile.am
    	src/i810_driver.c
    	src/i810_reg.h
    	src/i830.h
    	src/i830_cursor.c
    	src/i830_driver.c
    	src/i830_modes.c
    	src/i830_video.c

diff --cc src/Makefile.am
index 72d6276,ce7b40e..7af2dd7
@@@ -31,8 -31,11 +31,12 @@@
  i810_drv_ladir = @moduledir@/drivers
  
  i810_drv_la_SOURCES = \
+          brw_defines.h \
+          brw_structs.h \
+ 	 sf_prog.h \
+          wm_prog.h \
           common.h \
 +	 i2c_vid.h \
           i810_accel.c \
           i810_common.h \
           i810_cursor.c \
@@@ -44,32 -47,33 +48,47 @@@
           i810_reg.h \
           i810_video.c \
           i810_wmark.c \
++	 i830_3d.c \
           i830_accel.c \
 +         i830_bios.c \
 +         i830_bios.h \
           i830_common.h \
           i830_cursor.c \
 +	 i830_debug.c \
 +	 i830_debug.h \
           i830_dga.c \
 +	 i830_display.c \
 +	 i830_display.h \
           i830_driver.c \
 +	 i830_dvo.c \
           i830.h \
 +         i830_gtf.c \
 +         i830_i2c.c \
           i830_io.c \
           i830_memory.c \
           i830_modes.c \
           i830_video.c \
+          i830_video.h \
++	 i830_reg.h \
           i830_rotate.c \
  	 i830_randr.c \
 -	 i830_3d.c \
 -	 i830_reg.h \
 +	 i830_sdvo.c \
 +	 i830_sdvo.h \
 +	 i830_sdvo_regs.h \
 +	 i830_xf86Modes.h \
- 	 i830_xf86Modes.c
++	 i830_xf86Modes.c \
+ 	 i915_3d.c \
+ 	 i915_3d.h \
+ 	 i915_reg.h \
+ 	 i915_video.c
+ 
+ if HAVE_GEN4ASM
+ sf_prog.h: packed_yuv_sf.g4a
+ 	intel-gen4asm -o sf_prog.h packed_yuv_sf.g4a
+ wm_prog.h: packed_yuv_wm.g4a
+ 	intel-gen4asm -o wm_prog.h packed_yuv_wm.g4a
+ endif
+ 
  if DRI
  i810_drv_la_SOURCES += \
           i810_dri.c \
diff --cc src/i810_reg.h
index 3a15a46,4bb5bf1..4fec65f
@@@ -923,11 -837,12 +988,17 @@@
  #define DSPBPOS			0x7118C
  #define DSPBSIZE		0x71190
  
+ #define DSPASURF		0x7019C
+ #define DSPATILEOFF		0x701A4
+ 
+ #define DSPBSURF		0x7119C
+ #define DSPBTILEOFF		0x711A4
+ 
 +#define VGACNTRL		0x71400
 +# define VGA_DISP_DISABLE			(1 << 31)
 +# define VGA_2X_MODE				(1 << 30)
 +# define VGA_PIPE_B_SELECT			(1 << 29)
 +
  /* Various masks for reserved bits, etc. */
  #define I830_FWATER1_MASK        (~((1<<11)|(1<<10)|(1<<9)|      \
          (1<<8)|(1<<26)|(1<<25)|(1<<24)|(1<<5)|(1<<4)|(1<<3)|    \
diff --cc src/i830.h
index 1acba66,38a880f..7def141
@@@ -69,11 -71,14 +70,15 @@@
  #endif
  
  #include "common.h"
 +#include "i830_sdvo.h"
 +#include "i2c_vid.h"
  
 +/* I830 Video support */
+ #define NEED_REPLIES				/* ? */
+ #define EXTENSION_PROC_ARGS void *
+ #include "extnsionst.h" 			/* required */
+ #include <X11/extensions/panoramiXproto.h> 	/* required */
  
 -/* I830 Video BIOS support */
 -
  /*
   * The mode handling is based upon the VESA driver written by
   * Paulo César Pereira de Andrade <pcpa at conectiva.com.br>.
@@@ -295,8 -247,26 +300,7 @@@
     I830MemRange *OverlayMem;
     I830MemRange LinearMem;
  #endif
 -   int LinearAlloc;
 -
 -   Bool MergedFB;
 -   ScrnInfoPtr pScrn_2;
 -   char	*SecondHSync;
 -   char	*SecondVRefresh;
 -   char	*MetaModes;
 -   int SecondPosition;
 -   int FirstXOffs, FirstYOffs, SecondXOffs, SecondYOffs;
 -   int FirstframeX0, FirstframeX1, FirstframeY0, FirstframeY1;
 -   int MBXNR1XMAX, MBXNR1YMAX, MBXNR2XMAX, MBXNR2YMAX;
 -   Bool	NonRect, HaveNonRect, HaveOffsRegions, MouseRestrictions;
 -   int maxFirst_X1, maxFirst_X2, maxFirst_Y1, maxFirst_Y2;
 -   int maxSecond_X1, maxSecond_X2, maxSecond_Y1, maxSecond_Y2;
 -   region NonRectDead, OffDead1, OffDead2;
 -   Bool	IntelXinerama;
 -   Bool	SecondIsScrn0;
 -   ExtensionEntry *XineramaExtEntry;
 -   int I830XineramaVX, I830XineramaVY;
 -  
 +   unsigned long LinearAlloc;
-   
     XF86ModReqInfo shadowReq; /* to test for later libshadow */
     I830MemRange RotatedMem;
     I830MemRange RotatedMem2;
@@@ -432,79 -428,11 +442,81 @@@
 -   Bool vbeRestoreWorkaround;
 -   Bool displayInfo;
 -   Bool devicePresence;
  
     OsTimerPtr devicesTimer;
  
 -   CARD32 savedAsurf;
 -   CARD32 savedBsurf;
 +   int ddc2;
 +   int num_outputs;
 +   struct _I830OutputRec output[MAX_OUTPUTS];
 +   I830SDVOPtr sdvo;
 +
 +   /* Panel size pulled from the BIOS */
 +   int PanelXRes, PanelYRes;
 +
 +   /* The BIOS's fixed timings for the LVDS */
 +   int panel_fixed_clock;
 +   int panel_fixed_hactive;
 +   int panel_fixed_hblank;
 +   int panel_fixed_hsyncoff;
 +   int panel_fixed_hsyncwidth;
 +   int panel_fixed_vactive;
 +   int panel_fixed_vblank;
 +   int panel_fixed_vsyncoff;
 +   int panel_fixed_vsyncwidth;
 +
 +   int backlight_duty_cycle;  /* restore backlight to this value */
 +   
 +   Bool panel_wants_dither;
 +
 +   CARD32 saveDSPACNTR;
 +   CARD32 saveDSPBCNTR;
 +   CARD32 savePIPEACONF;
 +   CARD32 savePIPEBCONF;
 +   CARD32 savePIPEASRC;
 +   CARD32 savePIPEBSRC;
 +   CARD32 saveFPA0;
 +   CARD32 saveFPA1;
 +   CARD32 saveDPLL_A;
 +   CARD32 saveHTOTAL_A;
 +   CARD32 saveHBLANK_A;
 +   CARD32 saveHSYNC_A;
 +   CARD32 saveVTOTAL_A;
 +   CARD32 saveVBLANK_A;
 +   CARD32 saveVSYNC_A;
 +   CARD32 saveDSPASTRIDE;
 +   CARD32 saveDSPASIZE;
 +   CARD32 saveDSPAPOS;
 +   CARD32 saveDSPABASE;
++   CARD32 saveDSPASURF;
 +   CARD32 saveFPB0;
 +   CARD32 saveFPB1;
 +   CARD32 saveDPLL_B;
 +   CARD32 saveHTOTAL_B;
 +   CARD32 saveHBLANK_B;
 +   CARD32 saveHSYNC_B;
 +   CARD32 saveVTOTAL_B;
 +   CARD32 saveVBLANK_B;
 +   CARD32 saveVSYNC_B;
 +   CARD32 saveDSPBSTRIDE;
 +   CARD32 saveDSPBSIZE;
 +   CARD32 saveDSPBPOS;
 +   CARD32 saveDSPBBASE;
++   CARD32 saveDSPBSURF;
 +   CARD32 saveVCLK_DIVISOR_VGA0;
 +   CARD32 saveVCLK_DIVISOR_VGA1;
 +   CARD32 saveVCLK_POST_DIV;
 +   CARD32 saveVGACNTRL;
 +   CARD32 saveADPA;
 +   CARD32 saveLVDS;
 +   CARD32 saveDVOA;
 +   CARD32 saveDVOB;
 +   CARD32 saveDVOC;
 +   CARD32 savePP_ON;
 +   CARD32 savePP_OFF;
 +   CARD32 savePP_CONTROL;
 +   CARD32 savePP_CYCLE;
 +   CARD32 savePFIT_CONTROL;
 +   CARD32 savePaletteA[256];
 +   CARD32 savePaletteB[256];
 +   CARD32 saveSWF[17];
 +   CARD32 saveBLC_PWM_CTL;
  } I830Rec;
  
  #define I830PTR(p) ((I830Ptr)((p)->driverPrivate))
@@@ -519,11 -447,13 +531,14 @@@
  extern void I830SetPIOAccess(I830Ptr pI830);
  extern void I830SetMMIOAccess(I830Ptr pI830);
  extern void I830PrintErrorState(ScrnInfoPtr pScrn);
+ extern void I965PrintErrorState(ScrnInfoPtr pScrn);
  extern void I830Sync(ScrnInfoPtr pScrn);
  extern void I830InitHWCursor(ScrnInfoPtr pScrn);
 +extern void I830SetPipeCursor (ScrnInfoPtr pScrn, int pipe, Bool force);
  extern Bool I830CursorInit(ScreenPtr pScreen);
+ extern void IntelEmitInvarientState(ScrnInfoPtr pScrn);
  extern void I830EmitInvarientState(ScrnInfoPtr pScrn);
+ extern void I915EmitInvarientState(ScrnInfoPtr pScrn);
  extern void I830SelectBuffer(ScrnInfoPtr pScrn, int buffer);
  
  extern void I830RefreshRing(ScrnInfoPtr pScrn);
diff --cc src/i830_cursor.c
index 7389b66,c9e04e9..55bbe6a
@@@ -80,124 -80,51 +80,148 @@@
  #endif
  
  void
 +I830SetPipeCursor (ScrnInfoPtr pScrn, int pipe, Bool force)
 +{
 +   I830Ptr pI830 = I830PTR(pScrn);
 +   CARD32 temp;
 +    Bool show;
 +    
 +    if (!pI830->planeEnabled[pipe])
 +	return;
 +
 +    show = pI830->cursorOn && pI830->cursorInRange[pipe];
 +    if (show && (force || !pI830->cursorShown[pipe]))
 +    {
 +	if (IS_MOBILE(pI830) || IS_I9XX(pI830)) {
 +	    int	cursor_control, cursor_base;
 +	    if (pipe == 0)
 +	    {
 +		cursor_control = CURSOR_A_CONTROL;
 +		cursor_base = CURSOR_A_BASE;
 +	    }
 +	    else
 +	    {
 +		cursor_control = CURSOR_B_CONTROL;
 +		cursor_base = CURSOR_B_BASE;
 +	    }
 +	    temp = INREG(cursor_control);
 +	    temp &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT);
 +	    if (pI830->CursorIsARGB) {
 +		temp |= CURSOR_MODE_64_ARGB_AX;
 +		if (pI830->gammaEnabled[pipe])
 +		    temp |= MCURSOR_GAMMA_ENABLE;
 +	    } else
 +		temp |= CURSOR_MODE_64_4C_AX;
 +	    
 +	    temp |= (pipe << 28); /* Connect to correct pipe */
 +	    /* Need to set mode, then address. */
 +	    OUTREG(cursor_control, temp);
- 	    if (pI830->CursorIsARGB)
- 		OUTREG(cursor_base, pI830->CursorMemARGB->Physical);
- 	    else
- 		OUTREG(cursor_base, pI830->CursorMem->Physical);
++	    if (pI830->CursorNeedsPhysical) {
++		if (pI830->CursorIsARGB)
++		    OUTREG(cursor_base, pI830->CursorMemARGB->Physical);
++		else
++		    OUTREG(cursor_base, pI830->CursorMem->Physical);
++	    } else {
++		if (pI830->CursorIsARGB)
++		    OUTREG(cursor_base, pI830->CursorMemARGB->Start);
++		else
++		    OUTREG(cursor_base, pI830->CursorMem->Start);
++	    }
 +	} else {
 +	    temp = INREG(CURSOR_CONTROL);
 +	    temp &= ~(CURSOR_FORMAT_MASK);
 +	    temp |= CURSOR_ENABLE;
 +	    if (pI830->CursorIsARGB) {
 +		temp |= CURSOR_FORMAT_ARGB;
 +		if (pI830->gammaEnabled[pipe])
 +		    temp |= CURSOR_GAMMA_ENABLE;
 +	    } else
 +		temp |= CURSOR_FORMAT_3C;
 +	    OUTREG(CURSOR_CONTROL, temp);
 +	    if (pI830->CursorIsARGB)
 +		OUTREG(CURSOR_BASEADDR, pI830->CursorMemARGB->Start);
 +	    else
 +		OUTREG(CURSOR_BASEADDR, pI830->CursorMem->Start);
 +	}
 +	pI830->cursorShown[pipe] = TRUE;
 +    }
 +    else if (!show && (force || pI830->cursorShown[pipe]))
 +    {
 +	if (IS_MOBILE(pI830) || IS_I9XX(pI830)) 
 +	{
 +	    int	cursor_control, cursor_base;
 +	    if (pipe == 0)
 +	    {
 +		cursor_control = CURSOR_A_CONTROL;
 +		cursor_base = CURSOR_A_BASE;
 +	    }
 +	    else
 +	    {
 +		cursor_control = CURSOR_B_CONTROL;
 +		cursor_base = CURSOR_B_BASE;
 +	    }
 +	    temp = INREG(cursor_control);
 +	    temp &= ~(CURSOR_MODE|MCURSOR_GAMMA_ENABLE);
 +	    temp |= CURSOR_MODE_DISABLE;
 +	    OUTREG(cursor_control, temp);
 +	    /* This is needed to flush the above change. */
- 	    if (pI830->CursorIsARGB)
- 		OUTREG(cursor_base, pI830->CursorMemARGB->Physical);
- 	    else
- 		OUTREG(cursor_base, pI830->CursorMem->Physical);
++	    if (pI830->CursorNeedsPhysical) {
++		if (pI830->CursorIsARGB)
++		    OUTREG(cursor_base, pI830->CursorMemARGB->Physical);
++		else
++		    OUTREG(cursor_base, pI830->CursorMem->Physical);
++	    } else {
++		if (pI830->CursorIsARGB)
++		    OUTREG(cursor_base, pI830->CursorMemARGB->Start);
++		else
++		    OUTREG(cursor_base, pI830->CursorMem->Start);
++	    }
 +	} else {
 +	    temp = INREG(CURSOR_CONTROL);
 +	    temp &= ~(CURSOR_ENABLE|CURSOR_GAMMA_ENABLE);
 +	    OUTREG(CURSOR_CONTROL, temp);
 +	}
 +	pI830->cursorShown[pipe] = FALSE;
 +    }
 +}
 +
 +void
  I830InitHWCursor(ScrnInfoPtr pScrn)
  {
     I830Ptr pI830 = I830PTR(pScrn);
     CARD32 temp;
 +   int i;
  
     DPRINTF(PFX, "I830InitHWCursor\n");
 +   for (i = 0; i < MAX_DISPLAY_PIPES; i++) pI830->cursorShown[i] = FALSE;
     /* Initialise the HW cursor registers, leaving the cursor hidden. */
     if (IS_MOBILE(pI830) || IS_I9XX(pI830)) {
 -      temp = INREG(CURSOR_A_CONTROL);
 -      temp &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE | MCURSOR_MEM_TYPE_LOCAL |
 -		MCURSOR_PIPE_SELECT);
 -      temp |= CURSOR_MODE_DISABLE;
 -      temp |= (pI830->pipe << 28);
 -      if (pI830->CursorIsARGB)
 -         temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
 -      else
 -         temp |= CURSOR_MODE_64_4C_AX;
 -      /* Need to set control, then address. */
 -      OUTREG(CURSOR_A_CONTROL, temp);
 -      if (pI830->CursorNeedsPhysical) {
 -         if (pI830->CursorIsARGB)
 -            OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Physical);
 -         else
 -            OUTREG(CURSOR_A_BASE, pI830->CursorMem->Physical);
 -      } else {
 -         if (pI830->CursorIsARGB)
 -            OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Start);
 -         else
 -            OUTREG(CURSOR_A_BASE, pI830->CursorMem->Start);
 -      }
 -      if (pI830->Clone || pI830->MergedFB) {
 -         temp &= ~MCURSOR_PIPE_SELECT;
 -         temp |= (!pI830->pipe << 28);
 -         OUTREG(CURSOR_B_CONTROL, temp);
 -         if (pI830->CursorNeedsPhysical) {
 -            if (pI830->CursorIsARGB)
 -               OUTREG(CURSOR_B_BASE, pI830->CursorMemARGB->Physical);
 -            else
 -               OUTREG(CURSOR_B_BASE, pI830->CursorMem->Physical);
 +      for (i = 0; i < MAX_DISPLAY_PIPES; i++)
 +      {
 +	 int   cursor_control = i == 0 ? CURSOR_A_CONTROL : CURSOR_B_CONTROL;
 +	 int   cursor_base = i == 0 ? CURSOR_A_BASE : CURSOR_B_BASE;
 +	 temp = INREG(cursor_control);
 +	 temp &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE |
 +		   MCURSOR_MEM_TYPE_LOCAL |
 +		   MCURSOR_PIPE_SELECT);
- 	 temp |= CURSOR_MODE_DISABLE;
 +	 temp |= (i << 28);
- 	 /* Need to set control, then address. */
- 	 OUTREG(cursor_control, temp);
 +	 if (pI830->CursorIsARGB)
- 	    OUTREG(cursor_base, pI830->CursorMemARGB->Physical);
++	    temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
 +	 else
- 	    OUTREG(cursor_base, pI830->CursorMem->Physical);
++	    temp |= CURSOR_MODE_64_4C_AX;
++	 /* Need to set control, then address. */
++	 OUTREG(cursor_control, temp);
++	 if (pI830->CursorNeedsPhysical) {
++	    if (pI830->CursorIsARGB)
++	       OUTREG(cursor_base, pI830->CursorMemARGB->Physical);
++	    else
++	       OUTREG(cursor_base, pI830->CursorMem->Physical);
+ 	 } else {
 -            if (pI830->CursorIsARGB)
 -               OUTREG(CURSOR_B_BASE, pI830->CursorMemARGB->Start);
 -            else
 -               OUTREG(CURSOR_B_BASE, pI830->CursorMem->Start);
++	    if (pI830->CursorIsARGB)
++	       OUTREG(cursor_base, pI830->CursorMemARGB->Start);
++	    else
++	       OUTREG(cursor_base, pI830->CursorMem->Start);
+ 	 }
        }
     } else {
        temp = INREG(CURSOR_CONTROL);
@@@ -447,97 -377,223 +474,104 @@@
 -#define CDMPTR    ((I830ModePrivatePtr)pI830->currentMode->Private)->merged
 -
 -static void
 -I830SetCursorPositionMerged(ScrnInfoPtr pScrn, int x, int y)
 -{
 -   I830Ptr pI830 = I830PTR(pScrn);
 -   ScrnInfoPtr    pScrn2 = pI830->pScrn_2;
 -   DisplayModePtr mode1 = CDMPTR.First;
 -   Bool hide = FALSE, show = FALSE;
 -   DisplayModePtr mode2 = CDMPTR.Second;
 -   int x1, y1, x2, y2;
 -   int total_y1 = pScrn->frameY1 - pScrn->frameY0;
 -   int total_y2 = pScrn2->frameY1 - pScrn2->frameY0;
 -   CARD32 temp = 0, temp2 = 0;
 -
 -   x += pScrn->frameX0;
 -   y += pScrn->frameY0;
 -
 -   x1 = x - pI830->FirstframeX0;
 -   y1 = y - pI830->FirstframeY0;
 -
 -   x2 = x - pScrn2->frameX0;
 -   y2 = y - pScrn2->frameY0;
 -
 -   if (y1 > total_y1)
 -      y1 = total_y1;
 -   if (y2 > total_y2)                  
 -      y2 = total_y2;
 -
 -   /* move cursor offscreen */
 -   if (y1 >= 0 && y2 >= mode2->VDisplay) {
 -      y2 = -I810_CURSOR_Y;  
 -   } else if (y2 >= 0 && y1 >= mode1->VDisplay) {
 -      y1 = -I810_CURSOR_Y;  
 -   }
 -   if (x1 >= 0 && x2 >= mode2->HDisplay) {
 -      x2 = -I810_CURSOR_X;  
 -   } else if (x2 >= 0 && x1 >= mode1->HDisplay) {
 -      x1 = -I810_CURSOR_X;  
 -   }
 -
 -   /* Clamp the cursor position to the visible screen area */
 -   if (x1 >= mode1->HDisplay) x1 = mode1->HDisplay - 1;
 -   if (y1 >= mode1->VDisplay) y1 = mode1->VDisplay - 1;
 -   if (x1 <= -I810_CURSOR_X) x1 = -I810_CURSOR_X + 1;
 -   if (y1 <= -I810_CURSOR_Y) y1 = -I810_CURSOR_Y + 1;
 -   if (x2 >= mode2->HDisplay) x2 = mode2->HDisplay - 1;
 -   if (y2 >= mode2->VDisplay) y2 = mode2->VDisplay - 1;
 -   if (x2 <= -I810_CURSOR_X) x2 = -I810_CURSOR_X + 1;
 -   if (y2 <= -I810_CURSOR_Y) y2 = -I810_CURSOR_Y + 1;
 -
 -   if (x1 < 0) {
 -      temp |= (CURSOR_POS_SIGN << CURSOR_X_SHIFT);
 -      x1 = -x1;
 -   }
 -   if (y1 < 0) {
 -      temp |= (CURSOR_POS_SIGN << CURSOR_Y_SHIFT);
 -      y1 = -y1;
 -   }
 -   if (x2 < 0) {
 -      temp2 |= (CURSOR_POS_SIGN << CURSOR_X_SHIFT);
 -      x2 = -x2;
 -   }
 -   if (y2 < 0) {
 -      temp2 |= (CURSOR_POS_SIGN << CURSOR_Y_SHIFT);
 -      y2 = -y2;
 -   }
 -
 -   temp |= ((x1 & CURSOR_POS_MASK) << CURSOR_X_SHIFT);
 -   temp |= ((y1 & CURSOR_POS_MASK) << CURSOR_Y_SHIFT);
 -   temp2 |= ((x2 & CURSOR_POS_MASK) << CURSOR_X_SHIFT);
 -   temp2 |= ((y2 & CURSOR_POS_MASK) << CURSOR_Y_SHIFT);
 -
 -   OUTREG(CURSOR_A_POSITION, temp);
 -   OUTREG(CURSOR_B_POSITION, temp2);
 -
 -   if (pI830->cursorOn) {
 -      if (hide)
 -	 pI830->CursorInfoRec->HideCursor(pScrn);
 -      else if (show)
 -	 pI830->CursorInfoRec->ShowCursor(pScrn);
 -      pI830->cursorOn = TRUE;
 -   }
 -
 -   /* have to upload the base for the new position */
 -   if (IS_I9XX(pI830)) {
 -      if (pI830->CursorIsARGB) {
 -         OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Physical);
 -         OUTREG(CURSOR_B_BASE, pI830->CursorMemARGB->Physical);
 -      } else {
 -         OUTREG(CURSOR_A_BASE, pI830->CursorMem->Physical);
 -         OUTREG(CURSOR_B_BASE, pI830->CursorMem->Physical);
 -      }
 -   }
 -}
 -
  static void
  I830SetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
  {
 -   I830Ptr pI830 = I830PTR(pScrn);
 -   CARD32 temp = 0;
 -   Bool hide = FALSE, show = FALSE;
 -   int oldx = x, oldy = y;
 -   int hotspotx = 0, hotspoty = 0;
 -#if 0
 -   static Bool outsideViewport = FALSE;
 -#endif
 -
 -   if (pI830->MergedFB) {
 -      I830SetCursorPositionMerged(pScrn, x, y);
 -      return;
 -   }
 -
 -   oldx += pScrn->frameX0; /* undo what xf86HWCurs did */
 -   oldy += pScrn->frameY0;
 -
 -   switch (pI830->rotation) {
 -      case RR_Rotate_0:
 -         x = oldx;
 -         y = oldy;
 -         break;
 -      case RR_Rotate_90:
 -         x = oldy;
 -         y = pScrn->pScreen->width - oldx;
 -         hotspoty = I810_CURSOR_X;
 -         break;
 -      case RR_Rotate_180:
 -         x = pScrn->pScreen->width - oldx;
 -         y = pScrn->pScreen->height - oldy;
 -         hotspotx = I810_CURSOR_X;
 -         hotspoty = I810_CURSOR_Y;
 -         break;
 -      case RR_Rotate_270:
 -         x = pScrn->pScreen->height - oldy;
 -         y = oldx;
 -         hotspotx = I810_CURSOR_Y;
 -         break;
 -   }
 -
 -   x -= hotspotx;
 -   y -= hotspoty;
 -
 -   /* Now, readjust */
 -   x -= pScrn->frameX0;
 -   y -= pScrn->frameY0;
 -
 -   /* Clamp the cursor position to the visible screen area */
 -   if (x >= pScrn->currentMode->HDisplay) x = pScrn->currentMode->HDisplay - 1;
 -   if (y >= pScrn->currentMode->VDisplay) y = pScrn->currentMode->VDisplay - 1;
 -   if (x <= -I810_CURSOR_X) x = -I810_CURSOR_X + 1;
 -   if (y <= -I810_CURSOR_Y) y = -I810_CURSOR_Y + 1;
 -
 -#if 0
 -   /*
 -    * There is a screen display problem when the cursor position is set
 -    * wholely outside of the viewport.  We trap that here, turning the
 -    * cursor off when that happens, and back on when it comes back into
 -    * the viewport.
 -    */
 -   if (x >= pScrn->currentMode->HDisplay ||
 -       y >= pScrn->currentMode->VDisplay ||
 -       x <= -I810_CURSOR_X || y <= -I810_CURSOR_Y) {
 -      hide = TRUE;
 -      outsideViewport = TRUE;
 -   } else if (outsideViewport) {
 -      show = TRUE;
 -      outsideViewport = FALSE;
 -   }
 -#endif
 -
 -   if (x < 0) {
 -      temp |= (CURSOR_POS_SIGN << CURSOR_X_SHIFT);
 -      x = -x;
 -   }
 -   if (y < 0) {
 -      temp |= (CURSOR_POS_SIGN << CURSOR_Y_SHIFT);
 -      y = -y;
 -   }
 -   temp |= ((x & CURSOR_POS_MASK) << CURSOR_X_SHIFT);
 -   temp |= ((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT);
 -
 -   OUTREG(CURSOR_A_POSITION, temp);
 -   if (pI830->Clone)
 -      OUTREG(CURSOR_B_POSITION, temp);
 -
 -   if (pI830->cursorOn) {
 -      if (hide)
 -	 pI830->CursorInfoRec->HideCursor(pScrn);
 -      else if (show)
 -	 pI830->CursorInfoRec->ShowCursor(pScrn);
 -      pI830->cursorOn = TRUE;
 -   }
 -
 -   /* have to upload the base for the new position */
 -   if (IS_I9XX(pI830)) {
 -      if (pI830->CursorNeedsPhysical) {
 -         if (pI830->CursorIsARGB)
 -            OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Physical);
 -         else
 -            OUTREG(CURSOR_A_BASE, pI830->CursorMem->Physical);
 -      } else {
 -         if (pI830->CursorIsARGB)
 -            OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Start);
 -         else
 -            OUTREG(CURSOR_A_BASE, pI830->CursorMem->Start);
 -      }
 -      if (pI830->Clone) {
 -         if (pI830->CursorNeedsPhysical) {
 -            if (pI830->CursorIsARGB)
 -               OUTREG(CURSOR_B_BASE, pI830->CursorMemARGB->Physical);
 -            else
 -               OUTREG(CURSOR_B_BASE, pI830->CursorMem->Physical);
 -	 } else {
 -            if (pI830->CursorIsARGB)
 -               OUTREG(CURSOR_B_BASE, pI830->CursorMemARGB->Start);
 -            else
 -               OUTREG(CURSOR_B_BASE, pI830->CursorMem->Start);
 -	 }
 -      }
 -   }
 +    I830Ptr pI830 = I830PTR(pScrn);
 +    CARD32 temp;
 +    Bool inrange;
 +    int oldx = x, oldy = y;
 +    int hotspotx = 0, hotspoty = 0;
 +    int pipe;
 +
 +    oldx += pScrn->frameX0; /* undo what xf86HWCurs did */
 +    oldy += pScrn->frameY0;
 +
 +    switch (pI830->rotation) {
 +    case RR_Rotate_0:
 +	x = oldx;
 +	y = oldy;
 +	break;
 +    case RR_Rotate_90:
 +	x = oldy;
 +	y = pScrn->pScreen->width - oldx;
 +	hotspoty = I810_CURSOR_X;
 +	break;
 +    case RR_Rotate_180:
 +	x = pScrn->pScreen->width - oldx;
 +	y = pScrn->pScreen->height - oldy;
 +	hotspotx = I810_CURSOR_X;
 +	hotspoty = I810_CURSOR_Y;
 +	break;
 +    case RR_Rotate_270:
 +	x = pScrn->pScreen->height - oldy;
 +	y = oldx;
 +	hotspotx = I810_CURSOR_Y;
 +	break;
 +    }
 +
 +    x -= hotspotx;
 +    y -= hotspoty;
 +
 +    for (pipe = 0; pipe < MAX_DISPLAY_PIPES; pipe++)
 +    {
 +	DisplayModePtr	mode = &pI830->pipeCurMode[pipe];
 +	int		thisx = x - pI830->pipeX[pipe];
 +	int		thisy = y - pI830->pipeY[pipe];
 +
 +	if (!pI830->planeEnabled[pipe])
 +	    continue;
 +
 +	/*
 +	 * There is a screen display problem when the cursor position is set
 +	 * wholely outside of the viewport.  We trap that here, turning the
 +	 * cursor off when that happens, and back on when it comes back into
 +	 * the viewport.
 +	 */
 +	inrange = TRUE;
 +	if (thisx >= mode->HDisplay ||
 +	    thisy >= mode->VDisplay ||
 +	    thisx <= -I810_CURSOR_X || thisy <= -I810_CURSOR_Y) 
 +	{
 +	    inrange = FALSE;
 +	    thisx = 0;
 +	    thisy = 0;
 +	}
 +
 +	temp = 0;
 +	if (thisx < 0) {
 +	    temp |= (CURSOR_POS_SIGN << CURSOR_X_SHIFT);
 +	    thisx = -thisx;
 +	}
 +	if (thisy < 0) {
 +	    temp |= (CURSOR_POS_SIGN << CURSOR_Y_SHIFT);
 +	    thisy = -thisy;
 +	}
 +	temp |= ((thisx & CURSOR_POS_MASK) << CURSOR_X_SHIFT);
 +	temp |= ((thisy & CURSOR_POS_MASK) << CURSOR_Y_SHIFT);
 +
 +	if (pipe == 0)
 +	    OUTREG(CURSOR_A_POSITION, temp);
 +	if (pipe == 1)
 +	    OUTREG(CURSOR_B_POSITION, temp);
 +
 +	pI830->cursorInRange[pipe] = inrange;
 +	
 +        I830SetPipeCursor (pScrn, pipe, FALSE);
 +
 +	/* have to upload the base for the new position */
 +	if (IS_I9XX(pI830)) {
 +	    int base = pipe == 0 ? CURSOR_A_BASE : CURSOR_B_BASE;
- 	    if (pI830->CursorIsARGB)
- 		OUTREG(base, pI830->CursorMemARGB->Physical);
- 	    else
- 		OUTREG(base, pI830->CursorMem->Physical);
++	    if (pI830->CursorNeedsPhysical) {
++	       if (pI830->CursorIsARGB)
++		  OUTREG(base, pI830->CursorMemARGB->Physical);
++	       else
++		  OUTREG(base, pI830->CursorMem->Physical);
++	    } else {
++	       if (pI830->CursorIsARGB)
++		  OUTREG(base, pI830->CursorMemARGB->Start);
++	       else
++		  OUTREG(base, pI830->CursorMem->Start);
++	    }
 +	}
 +    }
  }
  
  static void
diff --cc src/i830_display.c
index 24ce50f,0000000..2b53128
mode 100644,000000..100644
@@@ -1,1128 -1,0 +1,1133 @@@
 +/* -*- 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>
 + *
 + */
 +
 +#ifdef HAVE_CONFIG_H
 +#include "config.h"
 +#endif
 +
 +#include <unistd.h>
 +#include <string.h>
 +#include <assert.h>
 +#include <stdlib.h>
 +#include <math.h>
 +
 +#include "xf86.h"
 +#include "i830.h"
 +#include "i830_bios.h"
 +#include "i830_display.h"
 +#include "i830_debug.h"
 +#include "i830_xf86Modes.h"
 +
 +/** Returns the pixel clock for the given refclk and divisors. */
 +static int i830_clock(int refclk, int m1, int m2, int n, int p1, int p2)
 +{
 +    return refclk * (5 * m1 + m2) / n / (p1 * p2);
 +}
 +
 +static void
 +i830PrintPll(char *prefix, int refclk, int m1, int m2, int n, int p1, int p2)
 +{
 +    int dotclock;
 +
 +    dotclock = i830_clock(refclk, m1, m2, n, p1, p2);
 +
 +    ErrorF("%s: dotclock %d ((%d, %d), %d, (%d, %d))\n", prefix, dotclock,
 +	   m1, m2, n, p1, p2);
 +}
 +
 +/**
 + * Returns whether the given set of divisors are valid for a given refclk with
 + * the given outputs.
 + *
 + * The equation for these divisors would be:
 + * clk = refclk * (5 * m1 + m2) / n / (p1 * p2)
 + */
 +static Bool
 +i830PllIsValid(ScrnInfoPtr pScrn, int outputs, int refclk, int m1, int m2,
 +	       int n, int p1, int p2)
 +{
 +    I830Ptr pI830 = I830PTR(pScrn);
 +    int p, m, vco, dotclock;
 +    int min_m1, max_m1, min_m2, max_m2, min_m, max_m, min_n, max_n;
 +    int min_p1, max_p1, min_p, max_p, min_vco, max_vco, min_dot, max_dot;
 +
 +    if (IS_I9XX(pI830)) {
 +	min_m1 = 10;
 +	max_m1 = 20;
 +	min_m2 = 5;
 +	max_m2 = 9;
 +	min_m = 70;
 +	max_m = 120;
 +	min_n = 3;
 +	max_n = 8;
 +	min_p1 = 1;
 +	max_p1 = 8;
 +	if (outputs & PIPE_LCD_ACTIVE) {
 +	    min_p = 7;
 +	    max_p = 98;
 +	} else {
 +	    min_p = 5;
 +	    max_p = 80;
 +	}
 +	min_vco = 1400000;
 +	max_vco = 2800000;
 +	min_dot = 20000;
 +	max_dot = 400000;
 +    } else {
 +	min_m1 = 18;
 +	max_m1 = 26;
 +	min_m2 = 6;
 +	max_m2 = 16;
 +	min_m = 96;
 +	max_m = 140;
 +	min_n = 3;
 +	max_n = 16;
 +	min_p1 = 2;
 +	max_p1 = 18;
 +	min_vco = 930000;
 +	max_vco = 1400000;
 +	min_dot = 20000;
 +	max_dot = 350000;
 +	min_p = 4;
 +	max_p = 128;
 +    }
 +
 +    p = p1 * p2;
 +    m = 5 * m1 + m2;
 +    vco = refclk * m / n;
 +    dotclock = i830_clock(refclk, m1, m2, n, p1, p2);
 +
 +    if (p1 < min_p1 || p1 > max_p1)
 +	return FALSE;
 +    if (p < min_p || p > max_p)
 +	return FALSE;
 +    if (m2 < min_m2 || m2 > max_m2)
 +	return FALSE;
 +    if (m1 < min_m1 || m1 > max_m1)
 +	return FALSE;
 +    if (m1 <= m2)
 +	return FALSE;
 +    if (m < min_m || m > max_m)
 +	return FALSE;
 +    if (n < min_n || n > max_n)
 +	return FALSE;
 +    if (vco < min_vco || vco > max_vco)
 +	return FALSE;
 +    /* XXX: We may need to be checking "Dot clock" depending on the multiplier,
 +     * output, etc., rather than just a single range.
 +     */
 +    if (dotclock < min_dot || dotclock > max_dot)
 +	return FALSE;
 +
 +    return TRUE;
 +}
 +
 +/**
 + * Returns a set of divisors for the desired target clock with the given refclk,
 + * or FALSE.  Divisor values are the actual divisors for
 + * clk = refclk * (5 * m1 + m2) / n / (p1 * p2)
 + */
 +static Bool
 +i830FindBestPLL(ScrnInfoPtr pScrn, int outputs, int target, int refclk,
 +		int *outm1, int *outm2, int *outn, int *outp1, int *outp2)
 +{
 +    I830Ptr pI830 = I830PTR(pScrn);
 +    int m1, m2, n, p1, p2;
 +    int err = target;
 +    int min_m1, max_m1, min_m2, max_m2, min_n, max_n, min_p1, max_p1;
 +
 +    if (IS_I9XX(pI830)) {
 +	min_m1 = 10;
 +	max_m1 = 20;
 +	min_m2 = 5;
 +	max_m2 = 9;
 +	min_n = 3;
 +	max_n = 8;
 +	min_p1 = 1;
 +	max_p1 = 8;
 +	if (outputs & PIPE_LCD_ACTIVE) {
 +	    if (target < 200000) /* XXX: Is this the right cutoff? */
 +		p2 = 14;
 +	    else
 +		p2 = 7;
 +	} else {
 +	    if (target < 200000)
 +		p2 = 10;
 +	    else
 +		p2 = 5;
 +	}
 +    } else {
 +	min_m1 = 18;
 +	max_m1 = 26;
 +	min_m2 = 6;
 +	max_m2 = 16;
 +	min_n = 3;
 +	max_n = 16;
 +	min_p1 = 2;
 +	max_p1 = 18;
 +	if (target < 165000)
 +	    p2 = 4;
 +	else
 +	    p2 = 2;
 +    }
 +
 +
 +    for (m1 = min_m1; m1 <= max_m1; m1++) {
 +	for (m2 = min_m2; m2 < max_m2; m2++) {
 +	    for (n = min_n; n <= max_n; n++) {
 +		for (p1 = min_p1; p1 <= max_p1; p1++) {
 +		    int clock, this_err;
 +
 +		    if (!i830PllIsValid(pScrn, outputs, refclk, m1, m2, n,
 +					p1, p2)) {
 +			continue;
 +		    }
 +
 +		    clock = i830_clock(refclk, m1, m2, n, p1, p2);
 +		    this_err = abs(clock - target);
 +		    if (this_err < err) {
 +			*outm1 = m1;
 +			*outm2 = m2;
 +			*outn = n;
 +			*outp1 = p1;
 +			*outp2 = p2;
 +			err = this_err;
 +		    }
 +		}
 +	    }
 +	}
 +    }
 +
 +    return (err != target);
 +}
 +
 +static void
 +i830WaitForVblank(ScrnInfoPtr pScreen)
 +{
 +    /* Wait for 20ms, i.e. one cycle at 50hz. */
 +    usleep(20000);
 +}
 +
 +void
 +i830PipeSetBase(ScrnInfoPtr pScrn, int pipe, int x, int y)
 +{
 +    I830Ptr pI830 = I830PTR(pScrn);
 +    unsigned long Start;
++    int dspbase = (pipe == 0 ? DSPABASE : DSPBBASE);
++    int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF);
 +
 +    if (I830IsPrimary(pScrn))
 +	Start = pI830->FrontBuffer.Start;
 +    else {
 +	I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
 +	Start = pI8301->FrontBuffer2.Start;
 +    }
 +
-     if (pipe == 0)
- 	OUTREG(DSPABASE, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
-     else
- 	OUTREG(DSPBBASE, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
++    if (IS_I965G(pI830)) {
++	OUTREG(dspbase, 0);
++	OUTREG(dspsurf, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
++    } else {
++	OUTREG(dspbase, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
++    }
++
 +    pI830->pipeX[pipe] = x;
 +    pI830->pipeY[pipe] = y;
 +}
 +
 +/**
 + * Sets the given video mode on the given pipe.  Assumes that plane A feeds
 + * pipe A, and plane B feeds pipe B.  Should not affect the other planes/pipes.
 + */
 +Bool
 +i830PipeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe)
 +{
 +    I830Ptr pI830 = I830PTR(pScrn);
 +    int m1 = 0, m2 = 0, n = 0, p1 = 0, p2 = 0;
 +    CARD32 dpll = 0, fp = 0, temp;
 +    CARD32 htot, hblank, hsync, vtot, vblank, vsync, dspcntr;
 +    CARD32 pipesrc, dspsize, adpa;
 +    CARD32 sdvob = 0, sdvoc = 0, dvo = 0;
 +    Bool ok, is_sdvo, is_dvo;
 +    int refclk, pixel_clock, sdvo_pixel_multiply;
 +    int outputs;
 +    DisplayModePtr pMasterMode = pMode;
 +
 +    assert(pMode->VRefresh != 0.0);
 +    /* If we've got a list of modes probed for the device, find the best match
 +     * in there to the requested mode.
 +     */
 +    if (pI830->pipeMon[pipe] != NULL) {
 +	DisplayModePtr pBest = NULL, pScan;
 +
 +	assert(pScan->VRefresh != 0.0);
 +	for (pScan = pI830->pipeMon[pipe]->Modes; pScan != NULL;
 +	     pScan = pScan->next)
 +	{
 +	    /* If there's an exact match, we're done. */
 +	    if (I830ModesEqual(pScan, pMode)) {
 +		pBest = pMode;
 +		break;
 +	    }
 +
 +	    /* Reject if it's larger than the desired mode. */
 +	    if (pScan->HDisplay > pMode->HDisplay ||
 +		pScan->VDisplay > pMode->VDisplay)
 +	    {
 +		continue;
 +	    }
 +
 +	    if (pBest == NULL) {
 +		pBest = pScan;
 +	        continue;
 +	    }
 +	    /* Find if it's closer to the right size than the current best
 +	     * option.
 +	     */
 +	    if ((pScan->HDisplay > pBest->HDisplay && 
 +		pScan->VDisplay >= pBest->VDisplay) ||
 +	        (pScan->HDisplay >= pBest->HDisplay && 
 +		pScan->VDisplay > pBest->VDisplay))
 +	    {
 +		pBest = pScan;
 +		continue;
 +	    }
 +	    /* Find if it's still closer to the right refresh than the current
 +	     * best resolution.
 +	     */
 +	    if (pScan->HDisplay == pBest->HDisplay && 
 +		pScan->VDisplay == pBest->VDisplay &&
 +		(fabs(pScan->VRefresh - pMode->VRefresh) <
 +		fabs(pBest->VRefresh - pMode->VRefresh)))
 +	    {
 +		pBest = pScan;
 +	    }
 +	}
 +	if (pBest != NULL) {
 +	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 +		       "Choosing pipe %d's mode %dx%d@%.1f instead of xf86 "
 +		       "mode %dx%d@%.1f\n", pipe,
 +		       pBest->HDisplay, pBest->VDisplay, pBest->VRefresh,
 +		       pMode->HDisplay, pMode->VDisplay, pMode->VRefresh);
 +	    pMode = pBest;
 +	}
 +    }
 +    if (pipe == 0)
 +	outputs = pI830->operatingDevices & 0xff;
 +    else
 +	outputs = (pI830->operatingDevices >> 8) & 0xff;
 +
 +    if (outputs & PIPE_LCD_ACTIVE) {
 +	if (I830ModesEqual(&pI830->pipeCurMode[pipe], pMasterMode))
 +	    return TRUE;
 +    } else {
 +	if (I830ModesEqual(&pI830->pipeCurMode[pipe], pMode))
 +	    return TRUE;
 +    }
 +
 +    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Requested pix clock: %d\n",
 +	       pMode->Clock);
 +
 +    if ((outputs & PIPE_LCD_ACTIVE) && (outputs & ~PIPE_LCD_ACTIVE)) {
 +	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 +		   "Can't enable LVDS and non-LVDS on the same pipe\n");
 +	return FALSE;
 +    }
 +    if (((outputs & PIPE_TV_ACTIVE) && (outputs & ~PIPE_TV_ACTIVE)) ||
 +	((outputs & PIPE_TV2_ACTIVE) && (outputs & ~PIPE_TV2_ACTIVE))) {
 +	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 +		   "Can't enable a TV and any other output on the same pipe\n");
 +	return FALSE;
 +    }
 +    if (pipe == 0 && (outputs & PIPE_LCD_ACTIVE)) {
 +	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 +		   "Can't support LVDS on pipe A\n");
 +	return FALSE;
 +    }
 +    if ((outputs & PIPE_DFP_ACTIVE) || (outputs & PIPE_DFP2_ACTIVE)) {
 +	/* We'll change how we control outputs soon, but to get the SDVO code up
 +	 * and running, just check for these two possibilities.
 +	 */
 +	if (IS_I9XX(pI830)) {
 +	    is_sdvo = TRUE;
 +	    is_dvo = FALSE;
 +	} else {
 +	    is_dvo = TRUE;
 +	    is_sdvo = FALSE;
 +	}
 +    } else {
 +	is_sdvo = FALSE;
 +	is_dvo = FALSE;
 +    }
 +
 +    htot = (pMode->CrtcHDisplay - 1) | ((pMode->CrtcHTotal - 1) << 16);
 +    hblank = (pMode->CrtcHBlankStart - 1) | ((pMode->CrtcHBlankEnd - 1) << 16);
 +    hsync = (pMode->CrtcHSyncStart - 1) | ((pMode->CrtcHSyncEnd - 1) << 16);
 +    vtot = (pMode->CrtcVDisplay - 1) | ((pMode->CrtcVTotal - 1) << 16);
 +    vblank = (pMode->CrtcVBlankStart - 1) | ((pMode->CrtcVBlankEnd - 1) << 16);
 +    vsync = (pMode->CrtcVSyncStart - 1) | ((pMode->CrtcVSyncEnd - 1) << 16);
 +    pipesrc = ((pMode->HDisplay - 1) << 16) | (pMode->VDisplay - 1);
 +    dspsize = ((pMode->VDisplay - 1) << 16) | (pMode->HDisplay - 1);
 +    pixel_clock = pMode->Clock;
 +    if (outputs & PIPE_LCD_ACTIVE && pI830->panel_fixed_hactive != 0)
 +    {
 +	/* To enable panel fitting, we need to set the pipe timings to that of
 +	 * the screen at its full resolution.  So, drop the timings from the
 +	 * BIOS VBT tables here.
 +	 */
 +	htot = (pI830->panel_fixed_hactive - 1) |
 +		((pI830->panel_fixed_hactive + pI830->panel_fixed_hblank - 1)
 +		 << 16);
 +	hblank = (pI830->panel_fixed_hactive - 1) |
 +		((pI830->panel_fixed_hactive + pI830->panel_fixed_hblank - 1)
 +		 << 16);
 +	hsync = (pI830->panel_fixed_hactive + pI830->panel_fixed_hsyncoff - 1) |
 +		((pI830->panel_fixed_hactive + pI830->panel_fixed_hsyncoff +
 +		  pI830->panel_fixed_hsyncwidth - 1) << 16);
 +
 +	vtot = (pI830->panel_fixed_vactive - 1) |
 +		((pI830->panel_fixed_vactive + pI830->panel_fixed_vblank - 1)
 +		 << 16);
 +	vblank = (pI830->panel_fixed_vactive - 1) |
 +		((pI830->panel_fixed_vactive + pI830->panel_fixed_vblank - 1)
 +		 << 16);
 +	vsync = (pI830->panel_fixed_vactive + pI830->panel_fixed_vsyncoff - 1) |
 +		((pI830->panel_fixed_vactive + pI830->panel_fixed_vsyncoff +
 +		  pI830->panel_fixed_vsyncwidth - 1) << 16);
 +	pixel_clock = pI830->panel_fixed_clock;
 +
 +	if (pMasterMode->HDisplay <= pI830->panel_fixed_hactive &&
 +	    pMasterMode->HDisplay <= pI830->panel_fixed_vactive)
 +	{
 +	    pipesrc = ((pMasterMode->HDisplay - 1) << 16) |
 +		       (pMasterMode->VDisplay - 1);
 +	    dspsize = ((pMasterMode->VDisplay - 1) << 16) |
 +		       (pMasterMode->HDisplay - 1);
 +	}
 +    }
 +
 +    if (pMode->Clock >= 100000)
 +	sdvo_pixel_multiply = 1;
 +    else if (pMode->Clock >= 50000)
 +	sdvo_pixel_multiply = 2;
 +    else
 +	sdvo_pixel_multiply = 4;
 +
 +    /* In SDVO, we need to keep the clock on the bus between 1Ghz and 2Ghz.
 +     * The clock on the bus is 10 times the pixel clock normally.  If that
 +     * would be too low, we run the DPLL at a multiple of the pixel clock, and
 +     * tell the SDVO device the multiplier so it can throw away the dummy bytes.
 +     */
 +    if (is_sdvo) {
 +	pixel_clock *= sdvo_pixel_multiply;
 +    }
 +
 +    if (IS_I9XX(pI830)) {
 +	refclk = 96000;
 +    } else {
 +	refclk = 48000;
 +    }
 +    ok = i830FindBestPLL(pScrn, outputs, pixel_clock, refclk, &m1, &m2, &n,
 +			 &p1, &p2);
 +    if (!ok) {
 +	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 +		   "Couldn't find PLL settings for mode!\n");
 +	return FALSE;
 +    }
 +
 +    dpll = DPLL_VCO_ENABLE | DPLL_VGA_MODE_DIS;
 +    if (IS_I9XX(pI830)) {
 +	if (outputs & PIPE_LCD_ACTIVE)
 +	    dpll |= DPLLB_MODE_LVDS;
 +	else
 +	    dpll |= DPLLB_MODE_DAC_SERIAL;
 +	dpll |= (1 << (p1 - 1)) << 16;
 +	switch (p2) {
 +	case 5:
 +	    dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_5;
 +	    break;
 +	case 7:
 +	    dpll |= DPLLB_LVDS_P2_CLOCK_DIV_7;
 +	    break;
 +	case 10:
 +	    dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_10;
 +	    break;
 +	case 14:
 +	    dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14;
 +	    break;
 +	}
 +    } else {
 +	dpll |= (p1 - 2) << 16;
 +	if (p2 == 4)
 +	    dpll |= PLL_P2_DIVIDE_BY_4;
 +    }
 +
 +    if (outputs & (PIPE_TV_ACTIVE | PIPE_TV2_ACTIVE))
 +	dpll |= PLL_REF_INPUT_TVCLKINBC;
 +#if 0    
 +    else if (outputs & (PIPE_LCD_ACTIVE))
 +	dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
 +#endif
 +    else	
 +	dpll |= PLL_REF_INPUT_DREFCLK;
 +
 +    if (is_dvo) {
 +	dpll |= DPLL_DVO_HIGH_SPEED;
 +
 +	/* Save the data order, since I don't know what it should be set to. */
 +	dvo = INREG(DVOC) & (DVO_PRESERVE_MASK | DVO_DATA_ORDER_GBRG);
 +	dvo |= DVO_ENABLE;
 +	dvo |= DVO_DATA_ORDER_FP | DVO_BORDER_ENABLE | DVO_BLANK_ACTIVE_HIGH;
 +
 +	if (pipe == 1)
 +	    dvo |= DVO_PIPE_B_SELECT;
 +
 +	if (pMode->Flags & V_PHSYNC)
 +	    dvo |= DVO_HSYNC_ACTIVE_HIGH;
 +	if (pMode->Flags & V_PVSYNC)
 +	    dvo |= DVO_VSYNC_ACTIVE_HIGH;
 +
 +	OUTREG(DVOC, dvo & ~DVO_ENABLE);
 +    }
 +
 +    if (is_sdvo) {
 +	dpll |= DPLL_DVO_HIGH_SPEED;
 +
 +	ErrorF("DVOB: %08x\nDVOC: %08x\n", (int)INREG(SDVOB), (int)INREG(SDVOC));
 +
 +        sdvob = INREG(SDVOB) & SDVOB_PRESERVE_MASK;
 +	sdvoc = INREG(SDVOC) & SDVOC_PRESERVE_MASK;
 +	sdvob |= SDVO_ENABLE | (9 << 19) | SDVO_BORDER_ENABLE;
 +	sdvoc |= 9 << 19;
 +	if (pipe == 1)
 +	    sdvob |= SDVO_PIPE_B_SELECT;
 +
 +	if (IS_I945G(pI830) || IS_I945GM(pI830))
 +	    dpll |= (sdvo_pixel_multiply - 1) << SDVO_MULTIPLIER_SHIFT_HIRES;
 +	else
 +	    sdvob |= (sdvo_pixel_multiply - 1) << SDVO_PORT_MULTIPLY_SHIFT;
 +
 +	OUTREG(SDVOC, INREG(SDVOC) & ~SDVO_ENABLE);
 +	OUTREG(SDVOB, INREG(SDVOB) & ~SDVO_ENABLE);
 +    }
 +
 +    fp = ((n - 2) << 16) | ((m1 - 2) << 8) | (m2 - 2);
 +
 +#if 1
 +    ErrorF("hact: %d htot: %d hbstart: %d hbend: %d hsyncstart: %d hsyncend: %d\n",
 +	(int)(htot & 0xffff) + 1, (int)(htot >> 16) + 1,
 +	(int)(hblank & 0xffff) + 1, (int)(hblank >> 16) + 1,
 +	(int)(hsync & 0xffff) + 1, (int)(hsync >> 16) + 1);
 +    ErrorF("vact: %d vtot: %d vbstart: %d vbend: %d vsyncstart: %d vsyncend: %d\n",
 +	(int)(vtot & 0xffff) + 1, (int)(vtot >> 16) + 1,
 +	(int)(vblank & 0xffff) + 1, (int)(vblank >> 16) + 1,
 +	(int)(vsync & 0xffff) + 1, (int)(vsync >> 16) + 1);
 +    ErrorF("pipesrc: %dx%d, dspsize: %dx%d\n",
 +	(int)(pipesrc >> 16) + 1, (int)(pipesrc & 0xffff) + 1,
 +	(int)(dspsize & 0xffff) + 1, (int)(dspsize >> 16) + 1);
 +#endif
 +
 +    i830PrintPll("chosen", refclk, m1, m2, n, p1, p2);
 +    ErrorF("clock regs: 0x%08x, 0x%08x\n", (int)dpll, (int)fp);
 +
 +    dspcntr = DISPLAY_PLANE_ENABLE;
 +    switch (pScrn->bitsPerPixel) {
 +    case 8:
 +	dspcntr |= DISPPLANE_8BPP | DISPPLANE_GAMMA_ENABLE;
 +	break;
 +    case 16:
 +	if (pScrn->depth == 15)
 +	    dspcntr |= DISPPLANE_15_16BPP;
 +	else
 +	    dspcntr |= DISPPLANE_16BPP;
 +	break;
 +    case 32:
 +	dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
 +	break;
 +    default:
 +	FatalError("unknown display bpp\n");
 +    }
 +
 +    if (pI830->gammaEnabled[pipe]) {
 + 	dspcntr |= DISPPLANE_GAMMA_ENABLE;
 +    }
 +
 +    if (is_sdvo)
 +	adpa = ADPA_DAC_DISABLE;
 +    else
 +	adpa = ADPA_DAC_ENABLE;
 +    if (pMode->Flags & V_PHSYNC)
 +	adpa |= ADPA_HSYNC_ACTIVE_HIGH;
 +    if (pMode->Flags & V_PVSYNC)
 +	adpa |= ADPA_VSYNC_ACTIVE_HIGH;
 +    
 +    if (pipe == 0) {
 +	dspcntr |= DISPPLANE_SEL_PIPE_A;
 +	adpa |= ADPA_PIPE_A_SELECT;
 +    } else {
 +	dspcntr |= DISPPLANE_SEL_PIPE_B;
 +	adpa |= ADPA_PIPE_B_SELECT;
 +    }
 +
 +    OUTREG(VGACNTRL, VGA_DISP_DISABLE);
 +
 +    /* Set up display timings and PLLs for the pipe. */
 +    if (pipe == 0) {
 +	/* First, disable display planes */
 +	temp = INREG(DSPACNTR);
 +	OUTREG(DSPACNTR, temp & ~DISPLAY_PLANE_ENABLE);
 +
 +	/* Wait for vblank for the disable to take effect */
 +	i830WaitForVblank(pScrn);
 +
 +	/* Next, disable display pipes */
 +	temp = INREG(PIPEACONF);
 +	OUTREG(PIPEACONF, temp & ~PIPEACONF_ENABLE);
 +
 +	OUTREG(FPA0, fp);
 +	OUTREG(DPLL_A, dpll);
 +
 +	OUTREG(HTOTAL_A, htot);
 +	OUTREG(HBLANK_A, hblank);
 +	OUTREG(HSYNC_A, hsync);
 +	OUTREG(VTOTAL_A, vtot);
 +	OUTREG(VBLANK_A, vblank);
 +	OUTREG(VSYNC_A, vsync);
 +	OUTREG(DSPASTRIDE, pScrn->displayWidth * pI830->cpp);
 +	OUTREG(DSPASIZE, dspsize);
 +	OUTREG(DSPAPOS, 0);
 +	i830PipeSetBase(pScrn, pipe, pI830->pipeX[pipe], pI830->pipeX[pipe]);
 +	OUTREG(PIPEASRC, pipesrc);
 +
 +	/* Then, turn the pipe on first */
 +	temp = INREG(PIPEACONF);
 +	OUTREG(PIPEACONF, temp | PIPEACONF_ENABLE);
 +
 +	/* And then turn the plane on */
 +	OUTREG(DSPACNTR, dspcntr);
 +    } else {
 +	/* Always make sure the LVDS is off before we play with DPLLs and pipe
 +	 * configuration.
 +	 */
 +	i830SetLVDSPanelPower(pScrn, FALSE);
 +
 +	/* First, disable display planes */
 +	temp = INREG(DSPBCNTR);
 +	OUTREG(DSPBCNTR, temp & ~DISPLAY_PLANE_ENABLE);
 +
 +	/* Wait for vblank for the disable to take effect */
 +	i830WaitForVblank(pScrn);
 +
 +	/* Next, disable display pipes */
 +	temp = INREG(PIPEBCONF);
 +	OUTREG(PIPEBCONF, temp & ~PIPEBCONF_ENABLE);
 +
 +	if (outputs & PIPE_LCD_ACTIVE) {
 +	    /* Disable the PLL before messing with LVDS enable */
 +	    OUTREG(FPB0, fp & ~DPLL_VCO_ENABLE);
 +
 +	    /* LVDS must be powered on before PLL is enabled and before power
 +	     * sequencing the panel.
 +	     */
 +	    temp = INREG(LVDS);
 +	    OUTREG(LVDS, temp | LVDS_PORT_EN | LVDS_PIPEB_SELECT);
 +	}
 +
 +	OUTREG(FPB0, fp);
 +	OUTREG(DPLL_B, dpll);
 +	OUTREG(HTOTAL_B, htot);
 +	OUTREG(HBLANK_B, hblank);
 +	OUTREG(HSYNC_B, hsync);
 +	OUTREG(VTOTAL_B, vtot);
 +	OUTREG(VBLANK_B, vblank);
 +	OUTREG(VSYNC_B, vsync);
 +	OUTREG(DSPBSTRIDE, pScrn->displayWidth * pI830->cpp);
 +	OUTREG(DSPBSIZE, dspsize);
 +	OUTREG(DSPBPOS, 0);
 +	i830PipeSetBase(pScrn, pipe, pI830->pipeX[pipe], pI830->pipeY[pipe]);
 +	OUTREG(PIPEBSRC, pipesrc);
 +
 +	if (outputs & PIPE_LCD_ACTIVE) {
 +	    CARD32  pfit_control;
 +	    
 +	    /* Enable automatic panel scaling so that non-native modes fill the
 +	     * screen.
 +	     */
 +	    /* XXX: Allow (auto-?) enabling of 8-to-6 dithering */
 +	    pfit_control = (PFIT_ENABLE |
 +			    VERT_AUTO_SCALE | HORIZ_AUTO_SCALE |
 +			    VERT_INTERP_BILINEAR | HORIZ_INTERP_BILINEAR);
 +	    if (pI830->panel_wants_dither)
 +		pfit_control |= PANEL_8TO6_DITHER_ENABLE;
 +	    OUTREG(PFIT_CONTROL, pfit_control);
 +	}
 +
 +	/* Then, turn the pipe on first */
 +	temp = INREG(PIPEBCONF);
 +	OUTREG(PIPEBCONF, temp | PIPEBCONF_ENABLE);
 +
 +	/* And then turn the plane on */
 +	OUTREG(DSPBCNTR, dspcntr);
 +
 +	if (outputs & PIPE_LCD_ACTIVE) {
 +	    i830SetLVDSPanelPower(pScrn, TRUE);
 +	}
 +    }
 +
 +    if (outputs & PIPE_CRT_ACTIVE)
 +	OUTREG(ADPA, adpa);
 +
 +    if (is_dvo) {
 +	/*OUTREG(DVOB_SRCDIM, (pMode->HDisplay << DVO_SRCDIM_HORIZONTAL_SHIFT) |
 +	    (pMode->VDisplay << DVO_SRCDIM_VERTICAL_SHIFT));*/
 +	OUTREG(DVOC_SRCDIM, (pMode->HDisplay << DVO_SRCDIM_HORIZONTAL_SHIFT) |
 +	    (pMode->VDisplay << DVO_SRCDIM_VERTICAL_SHIFT));
 +	/*OUTREG(DVOB, dvo);*/
 +	OUTREG(DVOC, dvo);
 +    }
 +
 +    if (is_sdvo) {
 +	OUTREG(SDVOB, sdvob);
 +	OUTREG(SDVOC, sdvoc);
 +    }
 +
 +    if (outputs & PIPE_LCD_ACTIVE) {
 +	pI830->pipeCurMode[pipe] = *pMasterMode;
 +    } else {
 +	pI830->pipeCurMode[pipe] = *pMode;
 +    }
 +
 +    return TRUE;
 +}
 +
 +void
 +i830DisableUnusedFunctions(ScrnInfoPtr pScrn)
 +{
 +    I830Ptr pI830 = I830PTR(pScrn);
 +    int outputsA, outputsB;
 +
 +    outputsA = pI830->operatingDevices & 0xff;
 +    outputsB = (pI830->operatingDevices >> 8) & 0xff;
 +
 +    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling unused functions\n");
 +
 +    /* First, disable the unused outputs */
 +    if ((outputsA & PIPE_CRT_ACTIVE) == 0 &&
 +	(outputsB & PIPE_CRT_ACTIVE) == 0)
 +    {
 +	CARD32 adpa = INREG(ADPA);
 +
 +	if (adpa & ADPA_DAC_ENABLE) {
 +	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling CRT output\n");
 +	    OUTREG(ADPA, adpa & ~ADPA_DAC_ENABLE);
 +	}
 +    }
 +
 +    if ((outputsB & PIPE_LCD_ACTIVE) == 0) {
 +	CARD32 pp_status = INREG(PP_STATUS);
 +
 +	if (pp_status & PP_ON) {
 +	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling LVDS output\n");
 +	    i830SetLVDSPanelPower(pScrn, FALSE);
 +	}
 +    }
 +
 +    if (IS_I9XX(pI830) && ((outputsA & PIPE_DFP_ACTIVE) == 0 &&
 +	(outputsB & PIPE_DFP_ACTIVE) == 0))
 +    {
 +	CARD32 sdvob = INREG(SDVOB);
 +	CARD32 sdvoc = INREG(SDVOC);
 +
 +	if (sdvob & SDVO_ENABLE) {
 +	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling SDVOB output\n");
 +	    OUTREG(SDVOB, sdvob & ~SDVO_ENABLE);
 +	}
 +	if (sdvoc & SDVO_ENABLE) {
 +	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling SDVOC output\n");
 +	    OUTREG(SDVOC, sdvoc & ~SDVO_ENABLE);
 +	}
 +    }
 +
 +    /* Now, any unused plane, pipe, and DPLL (FIXME: except for DVO, i915
 +     * internal TV) should have no outputs trying to pull data out of it, so
 +     * we're ready to turn those off.
 +     */
 +    if (!pI830->planeEnabled[0]) {
 +	CARD32 dspcntr, pipeconf, dpll;
 +
 +	dspcntr = INREG(DSPACNTR);
 +	if (dspcntr & DISPLAY_PLANE_ENABLE) {
 +	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling plane A\n");
 +	    OUTREG(DSPACNTR, dspcntr & ~DISPLAY_PLANE_ENABLE);
 +
 +	    /* Wait for vblank for the disable to take effect */
 +	    i830WaitForVblank(pScrn);
 +	}
 +
 +	pipeconf = INREG(PIPEACONF);
 +	if (pipeconf & PIPEACONF_ENABLE) {
 +	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling pipe A\n");
 +	   OUTREG(PIPEACONF, pipeconf & ~PIPEACONF_ENABLE);
 +	}
 +
 +	dpll = INREG(DPLL_A);
 +	if (dpll & DPLL_VCO_ENABLE) {
 +	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling DPLL A\n");
 +	    OUTREG(DPLL_A, dpll & ~DPLL_VCO_ENABLE);
 +	}
 +
 +	memset(&pI830->pipeCurMode[0], 0, sizeof(pI830->pipeCurMode[0]));
 +    }
 +
 +    if (!pI830->planeEnabled[1]) {
 +	CARD32 dspcntr, pipeconf, dpll;
 +
 +	dspcntr = INREG(DSPBCNTR);
 +	if (dspcntr & DISPLAY_PLANE_ENABLE) {
 +	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling plane B\n");
 +	    OUTREG(DSPBCNTR, dspcntr & ~DISPLAY_PLANE_ENABLE);
 +
 +	    /* Wait for vblank for the disable to take effect */
 +	    i830WaitForVblank(pScrn);
 +	}
 +
 +	pipeconf = INREG(PIPEBCONF);
 +	if (pipeconf & PIPEBCONF_ENABLE) {
 +	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling pipe B\n");
 +	   OUTREG(PIPEBCONF, pipeconf & ~PIPEBCONF_ENABLE);
 +	}
 +
 +	dpll = INREG(DPLL_B);
 +	if (dpll & DPLL_VCO_ENABLE) {
 +	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling DPLL B\n");
 +	    OUTREG(DPLL_B, dpll & ~DPLL_VCO_ENABLE);
 +	}
 +
 +	memset(&pI830->pipeCurMode[1], 0, sizeof(pI830->pipeCurMode[1]));
 +    }
 +}
 +
 +/**
 + * This function sets the given mode on the active pipes.
 + */
 +Bool
 +i830SetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
 +{
 +    I830Ptr pI830 = I830PTR(pScrn);
 +    Bool ok = TRUE;
 +    CARD32 planeA, planeB;
 +#ifdef XF86DRI
 +    Bool didLock = FALSE;
 +#endif
 +    int i;
 +
 +    DPRINTF(PFX, "i830SetMode\n");
 +
 +#ifdef XF86DRI
 +    didLock = I830DRILock(pScrn);
 +#endif
 +
 +    if (pI830->operatingDevices & 0xff) {
 +	pI830->planeEnabled[0] = 1;
 +    } else {
 +	pI830->planeEnabled[0] = 0;
 +    }
 +
 +    if (pI830->operatingDevices & 0xff00) {
 +	pI830->planeEnabled[1] = 1;
 +    } else {
 +	pI830->planeEnabled[1] = 0;
 +    }
 +
 +    for (i = 0; i < pI830->num_outputs; i++) {
 +	struct _I830OutputRec *output = &pI830->output[i];
 +
 +	if (output->sdvo_drv)
 +	    I830SDVOPreSetMode(output->sdvo_drv, pMode);
 +
 +	if (output->i2c_drv != NULL)
 +	    output->i2c_drv->vid_rec->Mode(output->i2c_drv->dev_priv,
 +					   pMode);
 +    }
 +
 +    if (pI830->planeEnabled[0]) {
 +	ok = i830PipeSetMode(pScrn, pMode, 0);
 +	if (!ok)
 +	    goto done;
 +    }
 +    if (pI830->planeEnabled[1]) {
 +	ok = i830PipeSetMode(pScrn, pMode, 1);
 +	if (!ok)
 +	    goto done;
 +    }
 +    for (i = 0; i < pI830->num_outputs; i++) {
 +	if (pI830->output[i].sdvo_drv)
 +	    I830SDVOPostSetMode(pI830->output[i].sdvo_drv, pMode);
 +    }
 +
 +    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Mode bandwidth is %d Mpixel/s\n",
 +	       (int)(pMode->HDisplay * pMode->VDisplay *
 +		     pMode->VRefresh / 1000000));
 +
 +    if (pI830->savedCurrentMode) {
 +	/* We're done with the currentMode that the last randr probe had left
 +	 * behind, so free it.
 +	 */
 +	xfree(pI830->savedCurrentMode->name);
 +	xfree(pI830->savedCurrentMode);
 +	pI830->savedCurrentMode = NULL;
 +	    
 +	/* If we might have enabled/disabled some pipes, we need to reset
 +	 * cloning mode support.
 +	 */
 +	if ((pI830->operatingDevices & 0x00ff) &&
 +	    (pI830->operatingDevices & 0xff00))
 +	{
 +	    pI830->Clone = TRUE;
 +	} else {
 +	    pI830->Clone = FALSE;
 +	}
 +
 +	/* If HW cursor currently showing, reset cursor state */
 +	if (pI830->CursorInfoRec && !pI830->SWCursor && pI830->cursorOn)
 +	    pI830->CursorInfoRec->ShowCursor(pScrn);
 +    }
 +
 +    i830DisableUnusedFunctions(pScrn);
 +
 +    planeA = INREG(DSPACNTR);
 +    planeB = INREG(DSPBCNTR);
 +
 +    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 +	       "Display plane A is now %s and connected to %s.\n",
 +	       pI830->planeEnabled[0] ? "enabled" : "disabled",
 +	       planeA & DISPPLANE_SEL_PIPE_MASK ? "Pipe B" : "Pipe A");
 +    if (pI830->availablePipes == 2)
 +	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 +		   "Display plane B is now %s and connected to %s.\n",
 +		   pI830->planeEnabled[1] ? "enabled" : "disabled",
 +		   planeB & DISPPLANE_SEL_PIPE_MASK ? "Pipe B" : "Pipe A");
 +
 +#ifdef XF86DRI
 +   I830DRISetVBlankInterrupt (pScrn, TRUE);
 +#endif
 +done:
 +#ifdef XF86DRI
 +    if (didLock)
 +	I830DRIUnlock(pScrn);
 +#endif
 +
 +    i830DumpRegs (pScrn);
 +    I830DumpSDVO (pScrn);
 +    return ok;
 +}
 +
 +/**
 + * Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect CRT presence.
 + *
 + * Only for I945G/GM.
 + */
 +static Bool
 +i830HotplugDetectCRT(ScrnInfoPtr pScrn)
 +{
 +    I830Ptr pI830 = I830PTR(pScrn);
 +    CARD32 temp;
 +    const int timeout_ms = 1000;
 +    int starttime, curtime;
 +
 +    temp = INREG(PORT_HOTPLUG_EN);
 +
 +    OUTREG(PORT_HOTPLUG_EN, temp | CRT_HOTPLUG_FORCE_DETECT | (1 << 5));
 +
 +    for (curtime = starttime = GetTimeInMillis();
 +	 (curtime - starttime) < timeout_ms; curtime = GetTimeInMillis())
 +    {
 +	if ((INREG(PORT_HOTPLUG_EN) & CRT_HOTPLUG_FORCE_DETECT) == 0)
 +	    break;
 +    }
 +
 +    if ((INREG(PORT_HOTPLUG_STAT) & CRT_HOTPLUG_MONITOR_MASK) ==
 +	CRT_HOTPLUG_MONITOR_COLOR)
 +    {
 +	return TRUE;
 +    } else {
 +	return FALSE;
 +    }
 +}
 +
 +/**
 + * Detects CRT presence by checking for load.
 + *
 + * Requires that the current pipe's DPLL is active.  This will cause flicker
 + * on the CRT, so it should not be used while the display is being used.  Only
 + * color (not monochrome) displays are detected.
 + */
 +static Bool
 +i830LoadDetectCRT(ScrnInfoPtr pScrn)
 +{
 +    I830Ptr pI830 = I830PTR(pScrn);
 +    CARD32 adpa, pipeconf;
 +    CARD8 st00;
 +    int pipeconf_reg, bclrpat_reg, dpll_reg;
 +    int pipe;
 +
 +    pipe = pI830->pipe;
 +    if (pipe == 0) {
 +	bclrpat_reg = BCLRPAT_A;
 +	pipeconf_reg = PIPEACONF;
 +	dpll_reg = DPLL_A;
 +    } else {
 +	bclrpat_reg = BCLRPAT_B;
 +	pipeconf_reg = PIPEBCONF;
 +	dpll_reg = DPLL_B;
 +    }
 +
 +    /* Don't try this if the DPLL isn't running. */
 +    if (!(INREG(dpll_reg) & DPLL_VCO_ENABLE))
 +	return FALSE;
 +
 +    adpa = INREG(ADPA);
 +
 +    /* Enable CRT output if disabled. */
 +    if (!(adpa & ADPA_DAC_ENABLE)) {
 +	OUTREG(ADPA, adpa | ADPA_DAC_ENABLE |
 +	       ((pipe == 1) ? ADPA_PIPE_B_SELECT : 0));
 +    }
 +
 +    /* Set the border color to red, green.  Maybe we should save/restore this
 +     * reg.
 +     */
 +    OUTREG(bclrpat_reg, 0x00500050);
 +
 +    /* Force the border color through the active region */
 +    pipeconf = INREG(pipeconf_reg);
 +    OUTREG(pipeconf_reg, pipeconf | PIPECONF_FORCE_BORDER);
 +
 +    /* Read the ST00 VGA status register */
 +    st00 = pI830->readStandard(pI830, 0x3c2);
 +
 +    /* Restore previous settings */
 +    OUTREG(pipeconf_reg, pipeconf);
 +    OUTREG(ADPA, adpa);
 +
 +    if (st00 & (1 << 4))
 +	return TRUE;
 +    else
 +	return FALSE;
 +}
 +
 +/**
 + * Detects CRT presence by probing for a response on the DDC address.
 + *
 + * This takes approximately 5ms in testing on an i915GM, with CRT connected or
 + * not.
 + */
 +static Bool
 +i830DDCDetectCRT(ScrnInfoPtr pScrn)
 +{
 +    I830Ptr pI830 = I830PTR(pScrn);
 +    struct _I830OutputRec *output;
 +
 +    output = &pI830->output[0];
 +    /* CRT should always be at 0, but check anyway */
 +    if (output->type != I830_OUTPUT_ANALOG)
 +	return FALSE;
 +
 +    return xf86I2CProbeAddress(output->pDDCBus, 0x00A0);
 +}
 +
 +/**
 + * Attempts to detect CRT presence through any method available.
 + *
 + * @param allow_disturb enables detection methods that may cause flickering
 + *        on active displays.
 + */
 +Bool
 +i830DetectCRT(ScrnInfoPtr pScrn, Bool allow_disturb)
 +{
 +    I830Ptr pI830 = I830PTR(pScrn);
 +    Bool found_ddc;
 +
 +    if (IS_I945G(pI830) || IS_I945GM(pI830))
 +	return i830HotplugDetectCRT(pScrn);
 +
 +    found_ddc = i830DDCDetectCRT(pScrn);
 +    if (found_ddc)
 +	return TRUE;
 +
 +    /* Use the load-detect method if we're not currently outputting to the CRT,
 +     * or we don't care.
 +     *
 +     * Actually, the method is unreliable currently.  We need to not share a
 +     * pipe, as it seems having other outputs on that pipe will result in a
 +     * false positive.
 +     */
 +    if (0 && (allow_disturb || !(INREG(ADPA) & !ADPA_DAC_ENABLE))) {
 +	return i830LoadDetectCRT(pScrn);
 +    }
 +
 +    return FALSE;
 +}
 +
 +/**
 + * Sets the power state for the panel.
 + */
 +void
 +i830SetLVDSPanelPower(ScrnInfoPtr pScrn, Bool on)
 +{
 +    I830Ptr pI830 = I830PTR(pScrn);
 +    CARD32 pp_status, pp_control;
 +    CARD32 blc_pwm_ctl;
 +    int backlight_duty_cycle;
 +
 +    blc_pwm_ctl = INREG (BLC_PWM_CTL);
 +    backlight_duty_cycle = blc_pwm_ctl & BACKLIGHT_DUTY_CYCLE_MASK;
 +    if (backlight_duty_cycle)
 +        pI830->backlight_duty_cycle = backlight_duty_cycle;
 +    
 +    if (on) {
 +	OUTREG(PP_STATUS, INREG(PP_STATUS) | PP_ON);
 +	OUTREG(PP_CONTROL, INREG(PP_CONTROL) | POWER_TARGET_ON);
 +	do {
 +	    pp_status = INREG(PP_STATUS);
 +	    pp_control = INREG(PP_CONTROL);
 +	} while (!(pp_status & PP_ON) && !(pp_control & POWER_TARGET_ON));
 +	OUTREG(BLC_PWM_CTL,
 +	       (blc_pwm_ctl & ~BACKLIGHT_DUTY_CYCLE_MASK) |
 +	       pI830->backlight_duty_cycle);
 +    } else {
 +	OUTREG(BLC_PWM_CTL,
 +	       (blc_pwm_ctl & ~BACKLIGHT_DUTY_CYCLE_MASK));
 +	       
 +	OUTREG(PP_STATUS, INREG(PP_STATUS) & ~PP_ON);
 +	OUTREG(PP_CONTROL, INREG(PP_CONTROL) & ~POWER_TARGET_ON);
 +	do {
 +	    pp_status = INREG(PP_STATUS);
 +	    pp_control = INREG(PP_CONTROL);
 +	} while ((pp_status & PP_ON) || (pp_control & POWER_TARGET_ON));
 +    }
 +}
diff --cc src/i830_driver.c
index b4f5394,ffa93f8..d46fc1b
@@@ -161,9 -166,9 +166,10 @@@
  #endif
  
  #include <string.h>
+ #include <stdio.h>
  #include <unistd.h>
  #include <stdlib.h>
 +#include <stdio.h>
  
  #include "xf86.h"
  #include "xf86_OSproc.h"
@@@ -182,12 -188,12 +189,11 @@@
  #include "xf86xv.h"
  #include <X11/extensions/Xv.h>
  #include "vbe.h"
- #include "vbeModes.h"
  #include "shadow.h"
  #include "i830.h"
 -
 -#ifdef HAS_MTRR_SUPPORT
 -#include <asm/mtrr.h>
 -#endif
 +#include "i830_display.h"
 +#include "i830_debug.h"
 +#include "i830_bios.h"
  
  #ifdef XF86DRI
  #include "dri.h"
@@@ -248,10 -262,16 +262,10 @@@
     OPTION_CHECKDEVICES,
     OPTION_FIXEDPIPE,
     OPTION_ROTATE,
-    OPTION_LINEARALLOC
+    OPTION_LINEARALLOC,
 -   OPTION_MERGEDFB,
 -   OPTION_METAMODES,
 -   OPTION_SECONDHSYNC,
 -   OPTION_SECONDVREFRESH,
 -   OPTION_SECONDPOSITION,
 -   OPTION_INTELXINERAMA
  } I830Opts;
  
 -static OptionInfoRec I830BIOSOptions[] = {
 +static OptionInfoRec I830Options[] = {
     {OPTION_NOACCEL,	"NoAccel",	OPTV_BOOLEAN,	{0},	FALSE},
     {OPTION_SW_CURSOR,	"SWcursor",	OPTV_BOOLEAN,	{0},	FALSE},
     {OPTION_CACHE_LINES,	"CacheLines",	OPTV_INTEGER,	{0},	FALSE},
@@@ -298,7 -316,22 +312,6 @@@
 -static Bool 		I830noPanoramiXExtension = TRUE;
 -static int		I830XineramaNumScreens = 0;
 -static I830XineramaData	*I830XineramadataPtr = NULL;
 -static int		I830XineramaGeneration;
 -
 -static int I830ProcXineramaQueryVersion(ClientPtr client);
 -static int I830ProcXineramaGetState(ClientPtr client);
 -static int I830ProcXineramaGetScreenCount(ClientPtr client);
 -static int I830ProcXineramaGetScreenSize(ClientPtr client);
 -static int I830ProcXineramaIsActive(ClientPtr client);
 -static int I830ProcXineramaQueryScreens(ClientPtr client);
 -static int I830SProcXineramaDispatch(ClientPtr client);
 -
  /* temporary */
  extern void xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y);
  
- 
 -static const char *SecondMonitorName = "MergedFBMonitor";
 -
 -
  #ifdef I830DEBUG
  void
  I830DPRINTF_stub(const char *filename, int line, const char *function,
@@@ -353,7 -386,7 +366,6 @@@
  {
     I830Ptr pI830;
     VESAPtr pVesa;
--   DisplayModePtr mode;
  
     if (!pScrn)
        return;
@@@ -361,21 -394,19 +373,6 @@@
        return;
  
     pI830 = I830PTR(pScrn);
--   mode = pScrn->modes;
--
--   if (mode) {
--      do {
--	 if (mode->Private) {
- 	    VbeModeInfoData *data = (VbeModeInfoData *) mode->Private;
- 
- 	    if (data->block)
- 	       xfree(data->block);
- 	    xfree(data);
- 	    mode->Private = NULL;
- 	 }
- 	 mode = mode->next;
-       } while (mode && mode != pScrn->modes);
-    }
 -	    I830ModePrivatePtr mp = (I830ModePrivatePtr) mode->Private;
 -
 -	    xfree(mp);
 -	    mode->Private = NULL;
 -	 }
 -	 mode = mode->next;
 -      } while (mode && mode != pScrn->modes);
 -   }
  
     if (I830IsPrimary(pScrn)) {
        if (pI830->vbeInfo)
@@@ -395,224 -424,2664 +390,220 @@@
     pScrn->driverPrivate = NULL;
  }
  
 -static Bool
 -InRegion(int x, int y, region r)
 -{
 -    return (r.x0 <= x) && (x <= r.x1) && (r.y0 <= y) && (y <= r.y1);
 -}
 -
 -static int
 -I830StrToRanges(range *r, char *s, int max)
 +static void
 +I830ProbeDDC(ScrnInfoPtr pScrn, int index)
  {
 -   float num = 0.0;
 -   int rangenum = 0;
 -   Bool gotdash = FALSE;
 -   Bool nextdash = FALSE;
 -   char *strnum = NULL;
 -   do {
 -      switch(*s) {
 -      case '0':
 -      case '1':
 -      case '2':
 -      case '3':
 -      case '4':
 -      case '5':
 -      case '6':
 -      case '7':
 -      case '8':
 -      case '9':
 -      case '.':
 -         if(strnum == NULL) {
 -            strnum = s;
 -            gotdash = nextdash;
 -            nextdash = FALSE;
 -         }
 -         break;
 -      case '-':
 -      case ' ':
 -      case 0:
 -         if(strnum == NULL) break;
 -         sscanf(strnum, "%f", &num);
 -	 strnum = NULL;
 -         if(gotdash) {
 -            r[rangenum - 1].hi = num;
 -         } else {
 -            r[rangenum].lo = num;
 -            r[rangenum].hi = num;
 -            rangenum++;
 -         }
 -         if(*s == '-') nextdash = (rangenum != 0);
 -	 else if(rangenum >= max) return rangenum;
 -         break;
 -      default:
 -         return 0;
 -      }
 +   vbeInfoPtr pVbe;
  
 -   } while(*(s++) != 0);
 +   /* The vbe module gets loaded in PreInit(), so no need to load it here. */
  
 -   return rangenum;
 +   pVbe = VBEInit(NULL, index);
 +   ConfiguredMonitor = vbeDoEDID(pVbe, NULL);
  }
  
 -/* Calculate the vertical refresh rate from a mode */
 -static float
 -I830CalcVRate(DisplayModePtr mode)
 -{
 -   float hsync, refresh = 0;
 -
 -   if(mode->HSync > 0.0)
 -       	hsync = mode->HSync;
 -   else if(mode->HTotal > 0)
 -       	hsync = (float)mode->Clock / (float)mode->HTotal;
 -   else
 -       	hsync = 0.0;
 -
 -   if(mode->VTotal > 0)
 -       	refresh = hsync * 1000.0 / mode->VTotal;
 -
 -   if(mode->Flags & V_INTERLACE)
 -       	refresh *= 2.0;
 -
 -   if(mode->Flags & V_DBLSCAN)
 -       	refresh /= 2.0;
 -
 -   if(mode->VScan > 1)
 -        refresh /= mode->VScan;
 -
 -   if(mode->VRefresh > 0.0)
 -	refresh = mode->VRefresh;
 -
 -   if(hsync == 0.0 || refresh == 0.0) return 0.0;
 +/* Various extended video BIOS functions. 
 + * 100 and 120Hz aren't really supported, they work but only get close
 + * to the requested refresh, and really not close enough.
 + * I've seen 100Hz come out at 104Hz, and 120Hz come out at 128Hz */
 +const int i830refreshes[] = {
 +   43, 56, 60, 70, 72, 75, 85 /* 100, 120 */
 +};
 +static const int nrefreshes = sizeof(i830refreshes) / sizeof(i830refreshes[0]);
  
 -   return refresh;
 +static Bool
 +Check5fStatus(ScrnInfoPtr pScrn, int func, int ax)
 +{
 +   if (ax == 0x005f)
 +      return TRUE;
 +   else if (ax == 0x015f) {
 +      xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 +		 "Extended BIOS function 0x%04x failed.\n", func);
 +      return FALSE;
 +   } else if ((ax & 0xff) != 0x5f) {
 +      xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 +		 "Extended BIOS function 0x%04x not supported.\n", func);
 +      return FALSE;
 +   } else {
 +      xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 +		 "Extended BIOS function 0x%04x returns 0x%04x.\n",
 +		 func, ax & 0xffff);
 +      return FALSE;
 +   }
  }
  
 -/* Copy and link two modes (i, j) for mergedfb mode
 - * (Code base taken from mga driver)
 - *
 - * - Copy mode i, merge j to copy of i, link the result to dest
 - * - Link i and j in private record.
 - * - If dest is NULL, return value is copy of i linked to itself.
 - * - For mergedfb auto-config, we only check the dimension
 - *   against virtualX/Y, if they were user-provided.
 - * - No special treatment required for CRTxxOffs.
 - * - Provide fake dotclock in order to distinguish between similar
 - *   looking MetaModes (for RandR and VidMode extensions)
 - * - Set unique VRefresh of dest mode for RandR
 - */
 -static DisplayModePtr
 -I830CopyModeNLink(ScrnInfoPtr pScrn, DisplayModePtr dest,
 -                 DisplayModePtr i, DisplayModePtr j,
 -		 int pos)
 -{
 -    DisplayModePtr mode;
 -    int dx = 0,dy = 0;
 -
 -    if(!((mode = xalloc(sizeof(DisplayModeRec))))) return dest;
 -    memcpy(mode, i, sizeof(DisplayModeRec));
 -    if(!((mode->Private = xalloc(sizeof(I830ModePrivateRec))))) {
 -       xfree(mode);
 -       return dest;
 -    }
 -    ((I830ModePrivatePtr)mode->Private)->merged.First = i;
 -    ((I830ModePrivatePtr)mode->Private)->merged.Second = j;
 -    ((I830ModePrivatePtr)mode->Private)->merged.SecondPosition = pos;
 -    if (((I830ModePrivatePtr)i->Private)->vbeData.mode > 0x30) {
 -       ((I830ModePrivatePtr)mode->Private)->vbeData.mode = ((I830ModePrivatePtr)i->Private)->vbeData.mode;
 -       ((I830ModePrivatePtr)mode->Private)->vbeData.data = ((I830ModePrivatePtr)i->Private)->vbeData.data;
 -    } else {
 -       ((I830ModePrivatePtr)mode->Private)->vbeData.mode = ((I830ModePrivatePtr)j->Private)->vbeData.mode;
 -       ((I830ModePrivatePtr)mode->Private)->vbeData.data = ((I830ModePrivatePtr)j->Private)->vbeData.data;
 -    }
 -    mode->PrivSize = sizeof(I830ModePrivateRec);
 +struct panelid {
 +	short hsize;
 +	short vsize;
 +	short fptype;
 +	char redbpp;
 +	char greenbpp;
 +	char bluebpp;
 +	char reservedbpp;
 +	int rsvdoffscrnmemsize;
 +	int rsvdoffscrnmemptr;
 +	char reserved[14];
 +};
  
 -    switch(pos) {
 -    case PosLeftOf:
 -    case PosRightOf:
 -       if(!(pScrn->display->virtualX)) {
 -          dx = i->HDisplay + j->HDisplay;
 -       } else {
 -          dx = min(pScrn->virtualX, i->HDisplay + j->HDisplay);
 -       }
 -       dx -= mode->HDisplay;
 -       if(!(pScrn->display->virtualY)) {
 -          dy = max(i->VDisplay, j->VDisplay);
 -       } else {
 -          dy = min(pScrn->virtualY, max(i->VDisplay, j->VDisplay));
 -       }
 -       dy -= mode->VDisplay;
 -       break;
 -    case PosAbove:
 -    case PosBelow:
 -       if(!(pScrn->display->virtualY)) {
 -          dy = i->VDisplay + j->VDisplay;
 -       } else {
 -          dy = min(pScrn->virtualY, i->VDisplay + j->VDisplay);
 -       }
 -       dy -= mode->VDisplay;
 -       if(!(pScrn->display->virtualX)) {
 -          dx = max(i->HDisplay, j->HDisplay);
 -       } else {
 -          dx = min(pScrn->virtualX, max(i->HDisplay, j->HDisplay));
 -       }
 -       dx -= mode->HDisplay;
 -       break;
 -    }
 -    mode->HDisplay += dx;
 -    mode->HSyncStart += dx;
 -    mode->HSyncEnd += dx;
 -    mode->HTotal += dx;
 -    mode->VDisplay += dy;
 -    mode->VSyncStart += dy;
 -    mode->VSyncEnd += dy;
 -    mode->VTotal += dy;
 -
 -    mode->type = M_T_DEFAULT;
 -
 -    /* Set up as user defined (ie fake that the mode has been named in the
 -     * Modes-list in the screen section; corrects cycling with CTRL-ALT-[-+]
 -     * when source mode has not been listed there.)
 -     */
 -    mode->type |= M_T_USERDEF;
 -
 -    /* Set the VRefresh field (in order to make RandR use it for the rates). We
 -     * simply set this to the refresh rate for the First mode (since Second will
 -     * mostly be LCD or TV anyway).
 -     */
 -    mode->VRefresh = I830CalcVRate(i);
 -
 -    if( ((mode->HDisplay * ((pScrn->bitsPerPixel + 7) / 8) * mode->VDisplay) > (pScrn->videoRam * 1024)) ||
 -	(mode->HDisplay > 4088) ||
 -	(mode->VDisplay > 4096) ) {
 -
 -       xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 -		"Skipped \"%s\" (%dx%d), not enough video RAM or beyond hardware specs\n",
 -		mode->name, mode->HDisplay, mode->VDisplay);
 -       xfree(mode->Private);
 -       xfree(mode);
 +static Bool
 +SetBIOSPipe(ScrnInfoPtr pScrn, int pipe)
 +{
 +   I830Ptr pI830 = I830PTR(pScrn);
 +   vbeInfoPtr pVbe = pI830->pVbe;
  
 -       return dest;
 -    }
 +   DPRINTF(PFX, "SetBIOSPipe: pipe 0x%x\n", pipe);
  
 -    /* Now see if the resulting mode would be discarded as a "size" by the
 -     * RandR extension, and increase its clock by 1000 in case it does.
 -     */
 -    if(dest) {
 -       DisplayModePtr t = dest;
 -       do {
 -          if((t->HDisplay == mode->HDisplay) &&
 -	     (t->VDisplay == mode->VDisplay) &&
 -	     ((int)(t->VRefresh + .5) == (int)(mode->VRefresh + .5))) {
 -	     mode->VRefresh += 1000.0;
 -	  }
 -	  t = t->next;
 -       } while((t) && (t != dest));
 -    }
 +   /* single pipe machines should always return TRUE */
 +   if (pI830->availablePipes == 1) return TRUE;
  
 -    /* Provide a fake but unique DotClock in order to trick the vidmode
 -     * extension to allow selecting among a number of modes whose merged result
 -     * looks identical but consists of different modes for First and Second
 -     */
 -    mode->Clock = (int)(mode->VRefresh * 1000.0);
 -
 -    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 -	"Merged \"%s\" (%dx%d) and \"%s\" (%dx%d) to %dx%d (%d)\n",
 -	i->name, i->HDisplay, i->VDisplay, j->name, j->HDisplay, j->VDisplay,
 -	mode->HDisplay, mode->VDisplay, (int)mode->VRefresh);
 -
 -    mode->next = mode;
 -    mode->prev = mode;
 -
 -    if(dest) {
 -       mode->next = dest->next; 	/* Insert node after "dest" */
 -       dest->next->prev = mode;
 -       mode->prev = dest;
 -       dest->next = mode;
 -    }
 +   pVbe->pInt10->num = 0x10;
 +   pVbe->pInt10->ax = 0x5f1c;
 +   if (pI830->newPipeSwitch) {
 +      pVbe->pInt10->bx = pipe;
 +      pVbe->pInt10->cx = 0;
 +   } else {
 +      pVbe->pInt10->bx = 0x0;
 +      pVbe->pInt10->cx = pipe << 8;
 +   }
  
 -    return mode;
 +   xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);
 +   if (Check5fStatus(pScrn, 0x5f1c, pVbe->pInt10->ax)) {
 +      return TRUE;
 +   }
 +	
 +   return FALSE;
  }
  
 -/* Helper function to find a mode from a given name
 - * (Code base taken from mga driver)
 - */
 -static DisplayModePtr
 -I830GetModeFromName(char* str, DisplayModePtr i)
 +static Bool
 +SetPipeAccess(ScrnInfoPtr pScrn)
  {
 -    DisplayModePtr c = i;
 -    if(!i) return NULL;
 -    do {
 -       if(strcmp(str, c->name) == 0) return c;
 -       c = c->next;
 -    } while(c != i);
 -    return NULL;
 -}
 -
 -static DisplayModePtr
 -I830FindWidestTallestMode(DisplayModePtr i, Bool tallest)
 -{
 -    DisplayModePtr c = i, d = NULL;
 -    int max = 0;
 -    if(!i) return NULL;
 -    do {
 -       if(tallest) {
 -          if(c->VDisplay > max) {
 -	     max = c->VDisplay;
 -	     d = c;
 -          }
 -       } else {
 -          if(c->HDisplay > max) {
 -	     max = c->HDisplay;
 -	     d = c;
 -          }
 -       }
 -       c = c->next;
 -    } while(c != i);
 -    return d;
 +   I830Ptr pI830 = I830PTR(pScrn);
 +
 +   /* Don't try messing with the pipe, unless we're dual head */
 +   if (xf86IsEntityShared(pScrn->entityList[0]) || pI830->Clone || pI830->origPipe != pI830->pipe) {
 +      if (!SetBIOSPipe(pScrn, pI830->pipe))
 +         return FALSE;
 +   }
 +   
 +   return TRUE;
  }
  
 -static void
 -I830FindWidestTallestCommonMode(DisplayModePtr i, DisplayModePtr j, Bool tallest,
 -				DisplayModePtr *a, DisplayModePtr *b)
 +static Bool
 +GetBIOSVersion(ScrnInfoPtr pScrn, unsigned int *version)
  {
 -    DisplayModePtr c = i, d;
 -    int max = 0;
 -    Bool foundone;
 -
 -    (*a) = (*b) = NULL;
 -
 -    if(!i || !j) return;
 -
 -    do {
 -       d = j;
 -       foundone = FALSE;
 -       do {
 -	  if( (c->HDisplay == d->HDisplay) &&
 -	      (c->VDisplay == d->VDisplay) ) {
 -	     foundone = TRUE;
 -	     break;
 -	  }
 -	  d = d->next;
 -       } while(d != j);
 -       if(foundone) {
 -	  if(tallest) {
 -	     if(c->VDisplay > max) {
 -		max = c->VDisplay;
 -		(*a) = c;
 -		(*b) = d;
 -	     }
 -	  } else {
 -	     if(c->HDisplay > max) {
 -		max = c->HDisplay;
 -		(*a) = c;
 -		(*b) = d;
 -	     }
 -	  }
 -       }
 -       c = c->next;
 -    } while(c != i);
 -}
 -
 -static DisplayModePtr
 -I830GenerateModeListFromLargestModes(ScrnInfoPtr pScrn,
 -		    DisplayModePtr i, DisplayModePtr j,
 -		    int pos)
 -{
 -    I830Ptr pI830 = I830PTR(pScrn);
 -    DisplayModePtr mode1 = NULL;
 -    DisplayModePtr mode2 = NULL;
 -    DisplayModePtr mode3 = NULL;
 -    DisplayModePtr mode4 = NULL;
 -    DisplayModePtr result = NULL;
 -
 -    /* Now build a default list of MetaModes.
 -     * - Non-clone: If the user enabled NonRectangular, we use the
 -     * largest mode for each First and Second. If not, we use the largest
 -     * common mode for First and Second (if available). Additionally, and
 -     * regardless if the above, we produce a clone mode consisting of
 -     * the largest common mode (if available) in order to use DGA.
 -     */
 -
 -    switch(pos) {
 -    case PosLeftOf:
 -    case PosRightOf:
 -       mode1 = I830FindWidestTallestMode(i, FALSE);
 -       mode2 = I830FindWidestTallestMode(j, FALSE);
 -       I830FindWidestTallestCommonMode(i, j, FALSE, &mode3, &mode4);
 -       break;
 -    case PosAbove:
 -    case PosBelow:
 -       mode1 = I830FindWidestTallestMode(i, TRUE);
 -       mode2 = I830FindWidestTallestMode(j, TRUE);
 -       I830FindWidestTallestCommonMode(i, j, TRUE, &mode3, &mode4);
 -       break;
 -    }
 +   vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe;
  
 -    if(mode3 && mode4 && !pI830->NonRect) {
 -       mode1 = mode3;
 -       mode2 = mode2;
 -    }
 +   DPRINTF(PFX, "GetBIOSVersion\n");
  
 -    if(mode1 && mode2) {
 -       result = I830CopyModeNLink(pScrn, result, mode1, mode2, pos);
 -    }
 +   pVbe->pInt10->num = 0x10;
 +   pVbe->pInt10->ax = 0x5f01;
 +
 +   xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);
 +   if (Check5fStatus(pScrn, 0x5f01, pVbe->pInt10->ax)) {
 +      *version = pVbe->pInt10->bx;
 +      return TRUE;
 +   }
  
 -    return result;
 +   *version = 0;
 +   return FALSE;
  }
  
 -/* Generate the merged-fb mode modelist
 - * (Taken from mga driver)
 +/*
 + * Returns a string matching the device corresponding to the first bit set
 + * in "device".  savedDevice is then set to device with that bit cleared.
 + * Subsequent calls with device == -1 will use savedDevice.
   */
 -static DisplayModePtr
 -I830GenerateModeListFromMetaModes(ScrnInfoPtr pScrn, char* str,
 -		    DisplayModePtr i, DisplayModePtr j,
 -		    int pos)
 -{
 -    char* strmode = str;
 -    char modename[256];
 -    Bool gotdash = FALSE;
 -    char gotsep = 0;
 -    int p; 
 -    DisplayModePtr mode1 = NULL;
 -    DisplayModePtr mode2 = NULL;
 -    DisplayModePtr result = NULL;
 -    int myslen;
 -
 -    do {
 -        switch(*str) {
 -        case 0:
 -        case '-':
 -	case '+':
 -        case ' ':
 -	case ',':
 -	case ';':
 -           if(strmode != str) {
 -
 -              myslen = str - strmode;
 -              if(myslen > 255) myslen = 255;
 -  	      strncpy(modename, strmode, myslen);
 -  	      modename[myslen] = 0;
 -
 -              if(gotdash) {
 -                 if(mode1 == NULL) {
 -  	             xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 -  	                        "Error parsing MetaModes parameter\n");
 -  	             return NULL;
 -  	         }
 -                 mode2 = I830GetModeFromName(modename, j);
 -                 if(!mode2) {
 -                    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 -                        "Mode \"%s\" is not a supported mode for Second\n", modename);
 -                    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 -                        "\t(Skipping metamode \"%s%c%s\")\n", mode1->name, gotsep, modename);
 -                    mode1 = NULL;
 -		    gotsep = 0;
 -                 }
 -              } else {
 -                 mode1 = I830GetModeFromName(modename, i);
 -                 if(!mode1) {
 -                    char* tmps = str;
 -                    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 -                        "Mode \"%s\" is not a supported mode for First\n", modename);
 -                    while(*tmps == ' ' || *tmps == ';') tmps++;
 -                    /* skip the next mode */
 -  	            if(*tmps == '-' || *tmps == '+' || *tmps == ',') {
 -                       tmps++;
 -		       /* skip spaces */
 -		       while(*tmps == ' ' || *tmps == ';') tmps++;
 -		       /* skip modename */
 -		       while(*tmps && *tmps != ' ' && *tmps != ';' && *tmps != '-' && *tmps != '+' && *tmps != ',') tmps++;
 -  	               myslen = tmps - strmode;
 -  	               if(myslen > 255) myslen = 255;
 -  	               strncpy(modename,strmode,myslen);
 -  	               modename[myslen] = 0;
 -                       str = tmps - 1;
 -                    }
 -                    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 -                        "\t(Skipping metamode \"%s\")\n", modename);
 -                    mode1 = NULL;
 -		    gotsep = 0;
 -                 }
 -              }
 -              gotdash = FALSE;
 -           }
 -           strmode = str + 1;
 -           gotdash |= (*str == '-' || *str == '+' || *str == ',');
 -	   if (*str == '-' || *str == '+' || *str == ',')
 -  	      gotsep = *str;
 -
 -           if(*str != 0) break;
 -	   /* Fall through otherwise */
 -
 -        default:
 -           if(!gotdash && mode1) {
 -              p = pos ;
 -              if(!mode2) {
 -                 xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 -                     "Mode \"%s\" is not a supported mode for Second\n", mode1->name);
 -                 xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 -                     "\t(Skipping metamode \"%s\")\n", modename);
 -                 mode1 = NULL;
 -              } else {
 -                 result = I830CopyModeNLink(pScrn, result, mode1, mode2, p);
 -                 mode1 = NULL;
 -                 mode2 = NULL;
 -              }
 -	      gotsep = 0;
 -           }
 -           break;
 -
 -        }
  
 -    } while(*(str++) != 0);
 -     
 -    return result;
 -}
 +static const char *displayDevices[] = {
 +   "CRT",
 +   "TV",
 +   "DFP (digital flat panel)",
 +   "LFP (local flat panel)",
 +   "CRT2 (second CRT)",
 +   "TV2 (second TV)",
 +   "DFP2 (second digital flat panel)",
 +   "LFP2 (second local flat panel)",
 +   NULL
 +};
  
 -static DisplayModePtr
 -I830GenerateModeList(ScrnInfoPtr pScrn, char* str,
 -		    DisplayModePtr i, DisplayModePtr j,
 -		    int pos)
 +static const char *
 +DeviceToString(int device)
  {
 -   I830Ptr pI830 = I830PTR(pScrn);
 +   static int savedDevice = -1;
 +   int bit = 0;
 +   const char *name;
  
 -   if(str != NULL) {
 -      return(I830GenerateModeListFromMetaModes(pScrn, str, i, j, pos));
 -   } else {
 -      xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 -	"No MetaModes given, linking %s modes by default\n",
 -	   (pI830->NonRect ?
 -		(((pos == PosLeftOf) || (pos == PosRightOf)) ? "widest" :  "tallest")
 -		:
 -		(((pos == PosLeftOf) || (pos == PosRightOf)) ? "widest common" :  "tallest common")) );
 -      return(I830GenerateModeListFromLargestModes(pScrn, i, j, pos));
 +   if (device == -1) {
 +      device = savedDevice;
 +      bit = 0;
     }
 -}
  
 -static void
 -I830RecalcDefaultVirtualSize(ScrnInfoPtr pScrn)
 -{
 -    I830Ptr pI830 = I830PTR(pScrn);
 -    DisplayModePtr mode, bmode;
 -    int maxh, maxv;
 -    static const char *str = "MergedFB: Virtual %s %d\n";
 -    static const char *errstr = "Virtual %s to small for given SecondPosition offset\n";
 -
 -    mode = bmode = pScrn->modes;
 -    maxh = maxv = 0;
 -    do {
 -       if(mode->HDisplay > maxh) maxh = mode->HDisplay;
 -       if(mode->VDisplay > maxv) maxv = mode->VDisplay;
 -       mode = mode->next;
 -    } while(mode != bmode);
 -
 -    maxh += pI830->FirstXOffs + pI830->SecondXOffs;
 -    maxv += pI830->FirstYOffs + pI830->SecondYOffs;
 -
 -    if(!(pScrn->display->virtualX)) {
 -       if(maxh > 4088) {
 -	  xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 -		"Virtual width with SecondPosition offset beyond hardware specs\n");
 -	  pI830->FirstXOffs = pI830->SecondXOffs = 0;
 -	  maxh -= (pI830->FirstXOffs + pI830->SecondXOffs);
 -       }
 -       pScrn->virtualX = maxh;
 -       pScrn->displayWidth = maxh;
 -       xf86DrvMsg(pScrn->scrnIndex, X_PROBED, str, "width", maxh);
 -    } else {
 -       if(maxh < pScrn->display->virtualX) {
 -	  xf86DrvMsg(pScrn->scrnIndex, X_ERROR, errstr, "width");
 -	  pI830->FirstXOffs = pI830->SecondXOffs = 0;
 -       }
 -    }
 +   if (device == -1)
 +      return NULL;
  
 -    if(!(pScrn->display->virtualY)) {
 -       pScrn->virtualY = maxv;
 -       xf86DrvMsg(pScrn->scrnIndex, X_PROBED, str, "height", maxv);
 -    } else {
 -       if(maxv < pScrn->display->virtualY) {
 -	  xf86DrvMsg(pScrn->scrnIndex, X_ERROR, errstr, "height");
 -	  pI830->FirstYOffs = pI830->SecondYOffs = 0;
 -       }
 -    }
 +   while (displayDevices[bit]) {
 +      if (device & (1 << bit)) {
 +	 name = displayDevices[bit];
 +	 savedDevice = device & ~(1 << bit);
 +	 bit++;
 +	 return name;
 +      }
 +      bit++;
 +   }
 +   return NULL;
  }
  
 -#define SDMPTR(x) ((I830ModePrivatePtr)x->currentMode->Private)->merged
 -#define CDMPTR    ((I830ModePrivatePtr)pI830->currentMode->Private)->merged
 -
 -#define BOUND(test,low,hi) 			\
 -    {						\
 -	if((test) < (low)) (test) = (low);	\
 -	if((test) > (hi))  (test) = (hi);	\
 -    }
 -
 -#define REBOUND(low,hi,test)		\
 -    {					\
 -	if((test) < (low)) {		\
 -		(hi) += (test)-(low);	\
 -		(low) = (test); 	\
 -	}				\
 -	if((test) > (hi)) {		\
 -		(low) += (test)-(hi);	\
 -		(hi) = (test); 		\
 -	}				\
 -    }
 -
 -
  static void
 -I830MergedPointerMoved(int scrnIndex, int x, int y)
 +PrintDisplayDeviceInfo(ScrnInfoPtr pScrn)
  {
 -  ScrnInfoPtr	pScrn1 = xf86Screens[scrnIndex];
 -  I830Ptr	pI830 = I830PTR(pScrn1);
 -  ScrnInfoPtr	pScrn2 = pI830->pScrn_2;
 -  region	out, in1, in2, f2, f1;
 -  int		deltax, deltay;
 -  int		temp1, temp2;
 -  int		old1x0, old1y0, old2x0, old2y0;
 -  int		FirstXOffs = 0, FirstYOffs = 0, SecondXOffs = 0, SecondYOffs = 0;
 -  int		HVirt = pScrn1->virtualX;
 -  int		VVirt = pScrn1->virtualY;
 -  int		sigstate;
 -  Bool		doit = FALSE, HaveNonRect = FALSE, HaveOffsRegions = FALSE;
 -  int           pos = ((I830MergedDisplayModePtr)pI830->currentMode->Private)->SecondPosition;
 -
 -  if(pI830->DGAactive) {
 -     return;
 -     /* DGA: There is no cursor and no panning while DGA is active. */
 -  } else {
 -     FirstXOffs = pI830->FirstXOffs;
 -     FirstYOffs = pI830->FirstYOffs;
 -     SecondXOffs = pI830->SecondXOffs;
 -     SecondYOffs = pI830->SecondYOffs;
 -     HaveNonRect = pI830->HaveNonRect;
 -     HaveOffsRegions = pI830->HaveOffsRegions;
 -  }
 -
 -  /* Check if the pointer is inside our dead areas */
 -  if((pI830->MouseRestrictions) && !I830noPanoramiXExtension) {
 -     if(HaveNonRect) {
 -	if(InRegion(x, y, pI830->NonRectDead)) {
 -	   switch(pos) {
 -	   case PosLeftOf:
 -	   case PosRightOf: y = pI830->NonRectDead.y0 - 1;
 -			    doit = TRUE;
 -			    break;
 -	   case PosAbove:
 -	   case PosBelow:   x = pI830->NonRectDead.x0 - 1;
 -			    doit = TRUE;
 -	   default:	    break;
 -	   }
 -	}
 -     }
 -     if(HaveOffsRegions) {
 -	if(InRegion(x, y, pI830->OffDead1)) {
 -	   switch(pos) {
 -	   case PosLeftOf:
 -	   case PosRightOf: y = pI830->OffDead1.y1;
 -			    doit = TRUE;
 -			    break;
 -	   case PosAbove:
 -	   case PosBelow:   x = pI830->OffDead1.x1;
 -			    doit = TRUE;
 -	   default:	    break;
 -	   }
 -	} else if(InRegion(x, y, pI830->OffDead2)) {
 -	   switch(pos) {
 -	   case PosLeftOf:
 -	   case PosRightOf: y = pI830->OffDead2.y0 - 1;
 -			    doit = TRUE;
 -			    break;
 -	   case PosAbove:
 -	   case PosBelow:   x = pI830->OffDead2.x0 - 1;
 -			    doit = TRUE;
 -	   default:	    break;
 -	   }
 -	}
 -     }
 -     if(doit) {
 -	UpdateCurrentTime();
 -	sigstate = xf86BlockSIGIO();
 -	miPointerAbsoluteCursor(x, y, currentTime.milliseconds);
 -	xf86UnblockSIGIO(sigstate);
 -	return;
 -     }
 -  }
 +   I830Ptr pI830 = I830PTR(pScrn);
 +   int pipe, n;
 +   int displays;
  
 -  f1.x0 = old1x0 = pI830->FirstframeX0;
 -  f1.x1 = pI830->FirstframeX1;
 -  f1.y0 = old1y0 = pI830->FirstframeY0;
 -  f1.y1 = pI830->FirstframeY1;
 -  f2.x0 = old2x0 = pScrn2->frameX0;
 -  f2.x1 = pScrn2->frameX1;
 -  f2.y0 = old2y0 = pScrn2->frameY0;
 -  f2.y1 = pScrn2->frameY1;
 -
 -  /* Define the outer region. Crossing this causes all frames to move */
 -  out.x0 = pScrn1->frameX0;
 -  out.x1 = pScrn1->frameX1;
 -  out.y0 = pScrn1->frameY0;
 -  out.y1 = pScrn1->frameY1;
 -
 -  /*
 -   * Define the inner sliding window. Being outsize both frames but
 -   * inside the outer clipping window will slide corresponding frame
 -   */
 -  in1 = out;
 -  in2 = out;
 -  switch(pos) {
 -     case PosLeftOf:
 -        in1.x0 = f1.x0;
 -        in2.x1 = f2.x1;
 -        break;
 -     case PosRightOf:
 -        in1.x1 = f1.x1;
 -        in2.x0 = f2.x0;
 -        break;
 -     case PosBelow:
 -        in1.y1 = f1.y1;
 -        in2.y0 = f2.y0;
 -        break;
 -     case PosAbove:
 -        in1.y0 = f1.y0;
 -        in2.y1 = f2.y1;
 -        break;
 -  }
 +   DPRINTF(PFX, "PrintDisplayDeviceInfo\n");
  
 -  deltay = 0;
 -  deltax = 0;
 +   displays = pI830->operatingDevices;
 +   if (displays == -1) {
 +      xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 +		 "No active display devices.\n");
 +      return;
 +   }
  
 -  if(InRegion(x, y, out)) {	/* inside outer region */
 +   /* Check for active devices connected to each display pipe. */
 +   for (n = 0; n < pI830->availablePipes; n++) {
 +      pipe = ((displays >> PIPE_SHIFT(n)) & PIPE_ACTIVE_MASK);
 +      if (pipe) {
 +	 const char *name;
  
 -     if(InRegion(x, y, in1) && !InRegion(x, y, f1)) {
 -	REBOUND(f1.x0, f1.x1, x);
 -	REBOUND(f1.y0, f1.y1, y);
 -	deltax = 1;
 -     }
 -     if(InRegion(x, y, in2) && !InRegion(x, y, f2)) {
 -	REBOUND(f2.x0, f2.x1, x);
 -	REBOUND(f2.y0, f2.y1, y);
 -	deltax = 1;
 -     }
 +	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 +		    "Currently active displays on Pipe %c:\n", PIPE_NAME(n));
 +	 name = DeviceToString(pipe);
 +	 do {
 +	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "\t%s\n", name);
 +	    name = DeviceToString(-1);
 +	 } while (name);
  
- 	 if (pipe & PIPE_UNKNOWN_ACTIVE)
- 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- 		       "\tSome unknown display devices may also be present\n");
- 
 -  } else {			/* outside outer region */
 +      } else {
 +	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 +		    "No active displays on Pipe %c.\n", PIPE_NAME(n));
 +      }
 +   }
 +}
  
 -     if(out.x0 > x) {
 -	deltax = x - out.x0;
 -     }
 -     if(out.x1 < x) {
 -	deltax = x - out.x1;
 -     }
 -     if(deltax) {
 -	pScrn1->frameX0 += deltax;
 -	pScrn1->frameX1 += deltax;
 -	f1.x0 += deltax;
 -	f1.x1 += deltax;
 -	f2.x0 += deltax;
 -	f2.x1 += deltax;
 -     }
 +static int
 +I830DetectMemory(ScrnInfoPtr pScrn)
 +{
 +   I830Ptr pI830 = I830PTR(pScrn);
 +   PCITAG bridge;
 +   CARD16 gmch_ctrl;
 +   int memsize = 0;
 +   int range;
  
 -     if(out.y0 > y) {
 -	deltay = y - out.y0;
 -     }
 -     if(out.y1 < y) {
 -	deltay = y - out.y1;
 -     }
 -     if(deltay) {
 -	pScrn1->frameY0 += deltay;
 -	pScrn1->frameY1 += deltay;
 -	f1.y0 += deltay;
 -	f1.y1 += deltay;
 -	f2.y0 += deltay;
 -	f2.y1 += deltay;
 -     }
 -
 -     switch(pos) {
 -	case PosLeftOf:
 -	   if(x >= f1.x0) { REBOUND(f1.y0, f1.y1, y); }
 -	   if(x <= f2.x1) { REBOUND(f2.y0, f2.y1, y); }
 -	   break;
 -	case PosRightOf:
 -	   if(x <= f1.x1) { REBOUND(f1.y0, f1.y1, y); }
 -	   if(x >= f2.x0) { REBOUND(f2.y0, f2.y1, y); }
 -	   break;
 -	case PosBelow:
 -	   if(y <= f1.y1) { REBOUND(f1.x0, f1.x1, x); }
 -	   if(y >= f2.y0) { REBOUND(f2.x0, f2.x1, x); }
 -	   break;
 -	case PosAbove:
 -	   if(y >= f1.y0) { REBOUND(f1.x0, f1.x1, x); }
 -	   if(y <= f2.y1) { REBOUND(f2.x0, f2.x1, x); }
 -	   break;
 -     }
 -
 -  }
 -
 -  if(deltax || deltay) {
 -     pI830->FirstframeX0 = f1.x0;
 -     pI830->FirstframeY0 = f1.y0;
 -     pScrn2->frameX0 = f2.x0;
 -     pScrn2->frameY0 = f2.y0;
 -
 -     switch(pos) {
 -	case PosLeftOf:
 -	case PosRightOf:
 -	   if(FirstYOffs || SecondYOffs || HaveNonRect) {
 -	      if(pI830->FirstframeY0 != old1y0) {
 -	         if(pI830->FirstframeY0 < FirstYOffs)
 -	            pI830->FirstframeY0 = FirstYOffs;
 -
 -	         temp1 = pI830->FirstframeY0 + CDMPTR.First->VDisplay;
 -	         temp2 = min((VVirt - SecondYOffs), (FirstYOffs + pI830->MBXNR1YMAX));
 -	         if(temp1 > temp2)
 -	            pI830->FirstframeY0 -= (temp1 - temp2);
 -	      }
 -	      if(pScrn2->frameY0 != old2y0) {
 -	         if(pScrn2->frameY0 < SecondYOffs)
 -	            pScrn2->frameY0 = SecondYOffs;
 -
 -	         temp1 = pScrn2->frameY0 + CDMPTR.Second->VDisplay;
 -	         temp2 = min((VVirt - FirstYOffs), (SecondYOffs + pI830->MBXNR2YMAX));
 -	         if(temp1 > temp2)
 -	            pScrn2->frameY0 -= (temp1 - temp2);
 -	      }
 -	   }
 -	   break;
 -	case PosBelow:
 -	case PosAbove:
 -	   if(FirstXOffs || SecondXOffs || HaveNonRect) {
 -	      if(pI830->FirstframeX0 != old1x0) {
 -	         if(pI830->FirstframeX0 < FirstXOffs)
 -	            pI830->FirstframeX0 = FirstXOffs;
 -
 -	         temp1 = pI830->FirstframeX0 + CDMPTR.First->HDisplay;
 -	         temp2 = min((HVirt - SecondXOffs), (FirstXOffs + pI830->MBXNR1XMAX));
 -	         if(temp1 > temp2)
 -	            pI830->FirstframeX0 -= (temp1 - temp2);
 -	      }
 -	      if(pScrn2->frameX0 != old2x0) {
 -	         if(pScrn2->frameX0 < SecondXOffs)
 -	            pScrn2->frameX0 = SecondXOffs;
 -
 -	         temp1 = pScrn2->frameX0 + CDMPTR.Second->HDisplay;
 -	         temp2 = min((HVirt - FirstXOffs), (SecondXOffs + pI830->MBXNR2XMAX));
 -	         if(temp1 > temp2)
 -	            pScrn2->frameX0 -= (temp1 - temp2);
 -	      }
 -	   }
 -	   break;
 -     }
 -
 -     pI830->FirstframeX1 = pI830->FirstframeX0 + CDMPTR.First->HDisplay - 1;
 -     pI830->FirstframeY1 = pI830->FirstframeY0 + CDMPTR.First->VDisplay - 1;
 -     pScrn2->frameX1   = pScrn2->frameX0   + CDMPTR.Second->HDisplay - 1;
 -     pScrn2->frameY1   = pScrn2->frameY0   + CDMPTR.Second->VDisplay - 1;
 -
 -     /* No need to update pScrn1->frame?1, done above */
 -    if (pI830->pipe == 0) {
 -       OUTREG(DSPABASE, pI830->FrontBuffer.Start + ((pI830->FirstframeY0 * pScrn1->displayWidth + pI830->FirstframeX0) * pI830->cpp));
 -       OUTREG(DSPBBASE, pI830->FrontBuffer.Start + ((pScrn2->frameY0 * pScrn1->displayWidth + pScrn2->frameX0) * pI830->cpp));
 -    } else {
 -       OUTREG(DSPBBASE, pI830->FrontBuffer.Start + ((pI830->FirstframeY0 * pScrn1->displayWidth + pI830->FirstframeX0) * pI830->cpp));
 -       OUTREG(DSPABASE, pI830->FrontBuffer.Start + ((pScrn2->frameY0 * pScrn1->displayWidth + pScrn2->frameX0) * pI830->cpp));
 -    }
 -  }
 -}
 -
 -static void
 -I830AdjustFrameMerged(int scrnIndex, int x, int y, int flags)
 -{
 -    ScrnInfoPtr pScrn1 = xf86Screens[scrnIndex];
 -    I830Ptr pI830 = I830PTR(pScrn1);
 -    ScrnInfoPtr pScrn2 = pI830->pScrn_2;
 -    int HTotal = pI830->currentMode->HDisplay;
 -    int VTotal = pI830->currentMode->VDisplay;
 -    int HMax = HTotal;
 -    int VMax = VTotal;
 -    int HVirt = pScrn1->virtualX;
 -    int VVirt = pScrn1->virtualY;
 -    int x1 = x, x2 = x;
 -    int y1 = y, y2 = y;
 -    int FirstXOffs = 0, FirstYOffs = 0, SecondXOffs = 0, SecondYOffs = 0;
 -    int MBXNR1XMAX = 65536, MBXNR1YMAX = 65536, MBXNR2XMAX = 65536, MBXNR2YMAX = 65536;
 -
 -    if(pI830->DGAactive) {
 -       HVirt = pScrn1->displayWidth;
 -       VVirt = pScrn1->virtualY;
 -    } else {
 -       FirstXOffs = pI830->FirstXOffs;
 -       FirstYOffs = pI830->FirstYOffs;
 -       SecondXOffs = pI830->SecondXOffs;
 -       SecondYOffs = pI830->SecondYOffs;
 -       MBXNR1XMAX = pI830->MBXNR1XMAX;
 -       MBXNR1YMAX = pI830->MBXNR1YMAX;
 -       MBXNR2XMAX = pI830->MBXNR2XMAX;
 -       MBXNR2YMAX = pI830->MBXNR2YMAX;
 -    }
 -
 -    BOUND(x, 0, HVirt - HTotal);
 -    BOUND(y, 0, VVirt - VTotal);
 -    BOUND(x1, FirstXOffs, min(HVirt, MBXNR1XMAX + FirstXOffs) - min(HTotal, MBXNR1XMAX) - SecondXOffs);
 -    BOUND(y1, FirstYOffs, min(VVirt, MBXNR1YMAX + FirstYOffs) - min(VTotal, MBXNR1YMAX) - SecondYOffs);
 -    BOUND(x2, SecondXOffs, min(HVirt, MBXNR2XMAX + SecondXOffs) - min(HTotal, MBXNR2XMAX) - FirstXOffs);
 -    BOUND(y2, SecondYOffs, min(VVirt, MBXNR2YMAX + SecondYOffs) - min(VTotal, MBXNR2YMAX) - FirstYOffs);
 -
 -    switch(SDMPTR(pScrn1).SecondPosition) {
 -        case PosLeftOf:
 -            pScrn2->frameX0 = x2;
 -            BOUND(pScrn2->frameY0,   y2, y2 + min(VMax, MBXNR2YMAX) - CDMPTR.Second->VDisplay);
 -            pI830->FirstframeX0 = x1 + CDMPTR.Second->HDisplay;
 -            BOUND(pI830->FirstframeY0, y1, y1 + min(VMax, MBXNR1YMAX) - CDMPTR.First->VDisplay);
 -            break;
 -        case PosRightOf:
 -            pI830->FirstframeX0 = x1;
 -            BOUND(pI830->FirstframeY0, y1, y1 + min(VMax, MBXNR1YMAX) - CDMPTR.First->VDisplay);
 -            pScrn2->frameX0 = x2 + CDMPTR.First->HDisplay;
 -            BOUND(pScrn2->frameY0,   y2, y2 + min(VMax, MBXNR2YMAX) - CDMPTR.Second->VDisplay);
 -            break;
 -        case PosAbove:
 -            BOUND(pScrn2->frameX0,   x2, x2 + min(HMax, MBXNR2XMAX) - CDMPTR.Second->HDisplay);
 -            pScrn2->frameY0 = y2;
 -            BOUND(pI830->FirstframeX0, x1, x1 + min(HMax, MBXNR1XMAX) - CDMPTR.First->HDisplay);
 -            pI830->FirstframeY0 = y1 + CDMPTR.Second->VDisplay;
 -            break;
 -        case PosBelow:
 -            BOUND(pI830->FirstframeX0, x1, x1 + min(HMax, MBXNR1XMAX) - CDMPTR.First->HDisplay);
 -            pI830->FirstframeY0 = y1;
 -            BOUND(pScrn2->frameX0,   x2, x2 + min(HMax, MBXNR2XMAX) - CDMPTR.Second->HDisplay);
 -            pScrn2->frameY0 = y2 + CDMPTR.First->VDisplay;
 -            break;
 -    }
 -
 -    BOUND(pI830->FirstframeX0, 0, HVirt - CDMPTR.First->HDisplay);
 -    BOUND(pI830->FirstframeY0, 0, VVirt - CDMPTR.First->VDisplay);
 -    BOUND(pScrn2->frameX0,   0, HVirt - CDMPTR.Second->HDisplay);
 -    BOUND(pScrn2->frameY0,   0, VVirt - CDMPTR.Second->VDisplay);
 -
 -    pScrn1->frameX0 = x;
 -    pScrn1->frameY0 = y;
 -
 -    pI830->FirstframeX1 = pI830->FirstframeX0 + CDMPTR.First->HDisplay - 1;
 -    pI830->FirstframeY1 = pI830->FirstframeY0 + CDMPTR.First->VDisplay - 1;
 -    pScrn2->frameX1   = pScrn2->frameX0   + CDMPTR.Second->HDisplay - 1;
 -    pScrn2->frameY1   = pScrn2->frameY0   + CDMPTR.Second->VDisplay - 1;
 -
 -    pScrn1->frameX1   = pScrn1->frameX0   + pI830->currentMode->HDisplay  - 1;
 -    pScrn1->frameY1   = pScrn1->frameY0   + pI830->currentMode->VDisplay  - 1;
 -    pScrn1->frameX1 += FirstXOffs + SecondXOffs;
 -    pScrn1->frameY1 += FirstYOffs + SecondYOffs;
 -}
 -
 -/* Pseudo-Xinerama extension for MergedFB mode */
 -static void
 -I830UpdateXineramaScreenInfo(ScrnInfoPtr pScrn1)
 -{
 -    I830Ptr pI830 = I830PTR(pScrn1);
 -    int scrnnum1 = 0, scrnnum2 = 1;
 -    int x1=0, x2=0, y1=0, y2=0, h1=0, h2=0, w1=0, w2=0;
 -    int realvirtX, realvirtY;
 -    DisplayModePtr currentMode, firstMode;
 -    Bool infochanged = FALSE;
 -    Bool usenonrect = pI830->NonRect;
 -    const char *rectxine = "\t... setting up rectangular Xinerama layout\n";
 -
 -    pI830->MBXNR1XMAX = pI830->MBXNR1YMAX = pI830->MBXNR2XMAX = pI830->MBXNR2YMAX = 65536;
 -    pI830->HaveNonRect = pI830->HaveOffsRegions = FALSE;
 -
 -    if(!pI830->MergedFB) return;
 -
 -    if(I830noPanoramiXExtension) return;
 -
 -    if(!I830XineramadataPtr) return;
 -
 -    if(pI830->SecondIsScrn0) {
 -       scrnnum1 = 1;
 -       scrnnum2 = 0;
 -    }
 -
 -    /* Attention: Usage of RandR may lead to virtual X and Y dimensions
 -     * actually smaller than our MetaModes. To avoid this, we calculate
 -     * the max* fields here (and not somewhere else, like in CopyNLink)
 -     *
 -     * *** Note: RandR is disabled if one of CRTxxOffs is non-zero.
 -     */
 -
 -    /* "Real" virtual: Virtual without the Offset */
 -    realvirtX = pScrn1->virtualX - pI830->FirstXOffs - pI830->SecondXOffs;
 -    realvirtY = pScrn1->virtualY - pI830->FirstYOffs - pI830->SecondYOffs;
 -
 -    if((pI830->I830XineramaVX != pScrn1->virtualX) || (pI830->I830XineramaVY != pScrn1->virtualY)) {
 -
 -       if(!(pScrn1->modes)) return;
 -
 -       pI830->maxFirst_X1 = pI830->maxFirst_X2 = 0;
 -       pI830->maxFirst_Y1 = pI830->maxFirst_Y2 = 0;
 -       pI830->maxSecond_X1 = pI830->maxSecond_X2 = 0;
 -       pI830->maxSecond_Y1 = pI830->maxSecond_Y2 = 0;
 -
 -       currentMode = firstMode = pScrn1->modes;
 -
 -       do {
 -
 -          DisplayModePtr p = currentMode->next;
 -          DisplayModePtr i = ((I830ModePrivatePtr)currentMode->Private)->merged.First;
 -          DisplayModePtr j = ((I830ModePrivatePtr)currentMode->Private)->merged.Second;
 -
 -          if((currentMode->HDisplay <= realvirtX) && (currentMode->VDisplay <= realvirtY) &&
 -	     (i->HDisplay <= realvirtX) && (j->HDisplay <= realvirtX) &&
 -	     (i->VDisplay <= realvirtY) && (j->VDisplay <= realvirtY)) {
 -
 -		if(pI830->maxFirst_X1 == i->HDisplay) {
 -		   if(pI830->maxFirst_X2 < j->HDisplay) {
 -		      pI830->maxFirst_X2 = j->HDisplay;   /* Widest Second mode displayed with widest CRT1 mode */
 -		   }
 -		} else if(pI830->maxFirst_X1 < i->HDisplay) {
 -		   pI830->maxFirst_X1 = i->HDisplay;      /* Widest CRT1 mode */
 -		   pI830->maxFirst_X2 = j->HDisplay;
 -		}
 -		if(pI830->maxSecond_X2 == j->HDisplay) {
 -		   if(pI830->maxSecond_X1 < i->HDisplay) {
 -		      pI830->maxSecond_X1 = i->HDisplay;   /* Widest First mode displayed with widest Second mode */
 -		   }
 -		} else if(pI830->maxSecond_X2 < j->HDisplay) {
 -		   pI830->maxSecond_X2 = j->HDisplay;      /* Widest Second mode */
 -		   pI830->maxSecond_X1 = i->HDisplay;
 -		}
 -		if(pI830->maxFirst_Y1 == i->VDisplay) {   /* Same as above, but tallest instead of widest */
 -		   if(pI830->maxFirst_Y2 < j->VDisplay) {
 -		      pI830->maxFirst_Y2 = j->VDisplay;
 -		   }
 -		} else if(pI830->maxFirst_Y1 < i->VDisplay) {
 -		   pI830->maxFirst_Y1 = i->VDisplay;
 -		   pI830->maxFirst_Y2 = j->VDisplay;
 -		}
 -		if(pI830->maxSecond_Y2 == j->VDisplay) {
 -		   if(pI830->maxSecond_Y1 < i->VDisplay) {
 -		      pI830->maxSecond_Y1 = i->VDisplay;
 -		   }
 -		} else if(pI830->maxSecond_Y2 < j->VDisplay) {
 -		   pI830->maxSecond_Y2 = j->VDisplay;
 -		   pI830->maxSecond_Y1 = i->VDisplay;
 -		}
 -	  }
 -	  currentMode = p;
 -
 -       } while((currentMode) && (currentMode != firstMode));
 -
 -       pI830->I830XineramaVX = pScrn1->virtualX;
 -       pI830->I830XineramaVY = pScrn1->virtualY;
 -       infochanged = TRUE;
 -
 -    }
 -
 -    if((usenonrect) && pI830->maxFirst_X1) {
 -       switch(pI830->SecondPosition) {
 -       case PosLeftOf:
 -       case PosRightOf:
 -	  if((pI830->maxFirst_Y1 != realvirtY) && (pI830->maxSecond_Y2 != realvirtY)) {
 -	     usenonrect = FALSE;
 -	  }
 -	  break;
 -       case PosAbove:
 -       case PosBelow:
 -	  if((pI830->maxFirst_X1 != realvirtX) && (pI830->maxSecond_X2 != realvirtX)) {
 -	     usenonrect = FALSE;
 -	  }
 -	  break;
 -       }
 -       if(infochanged && !usenonrect) {
 -	  xf86DrvMsg(pScrn1->scrnIndex, X_INFO,
 -			"Virtual screen size does not match maximum display modes...\n");
 -	  xf86DrvMsg(pScrn1->scrnIndex, X_INFO, rectxine);
 -
 -       }
 -    } else if(infochanged && usenonrect) {
 -       usenonrect = FALSE;
 -       xf86DrvMsg(pScrn1->scrnIndex, X_INFO,
 -		"Only clone modes available for this virtual screen size...\n");
 -       xf86DrvMsg(pScrn1->scrnIndex, X_INFO, rectxine);
 -    }
 -
 -    if(pI830->maxFirst_X1) {		/* Means we have at least one non-clone mode */
 -       switch(pI830->SecondPosition) {
 -       case PosLeftOf:
 -	  x1 = min(pI830->maxFirst_X2, pScrn1->virtualX - pI830->maxFirst_X1);
 -	  if(x1 < 0) x1 = 0;
 -	  y1 = pI830->FirstYOffs;
 -	  w1 = pScrn1->virtualX - x1;
 -	  h1 = realvirtY;
 -	  if((usenonrect) && (pI830->maxFirst_Y1 != realvirtY)) {
 -	     h1 = pI830->MBXNR1YMAX = pI830->maxFirst_Y1;
 -	     pI830->NonRectDead.x0 = x1;
 -	     pI830->NonRectDead.x1 = x1 + w1 - 1;
 -	     pI830->NonRectDead.y0 = y1 + h1;
 -	     pI830->NonRectDead.y1 = pScrn1->virtualY - 1;
 -	     pI830->HaveNonRect = TRUE;
 -	  }
 -	  x2 = 0;
 -	  y2 = pI830->SecondYOffs;
 -	  w2 = max(pI830->maxSecond_X2, pScrn1->virtualX - pI830->maxSecond_X1);
 -	  if(w2 > pScrn1->virtualX) w2 = pScrn1->virtualX;
 -	  h2 = realvirtY;
 -	  if((usenonrect) && (pI830->maxSecond_Y2 != realvirtY)) {
 -	     h2 = pI830->MBXNR2YMAX = pI830->maxSecond_Y2;
 -	     pI830->NonRectDead.x0 = x2;
 -	     pI830->NonRectDead.x1 = x2 + w2 - 1;
 -	     pI830->NonRectDead.y0 = y2 + h2;
 -	     pI830->NonRectDead.y1 = pScrn1->virtualY - 1;
 -	     pI830->HaveNonRect = TRUE;
 -	  }
 -	  break;
 -       case PosRightOf:
 -	  x1 = 0;
 -	  y1 = pI830->FirstYOffs;
 -	  w1 = max(pI830->maxFirst_X1, pScrn1->virtualX - pI830->maxFirst_X2);
 -	  if(w1 > pScrn1->virtualX) w1 = pScrn1->virtualX;
 -	  h1 = realvirtY;
 -	  if((usenonrect) && (pI830->maxFirst_Y1 != realvirtY)) {
 -	     h1 = pI830->MBXNR1YMAX = pI830->maxFirst_Y1;
 -	     pI830->NonRectDead.x0 = x1;
 -	     pI830->NonRectDead.x1 = x1 + w1 - 1;
 -	     pI830->NonRectDead.y0 = y1 + h1;
 -	     pI830->NonRectDead.y1 = pScrn1->virtualY - 1;
 -	     pI830->HaveNonRect = TRUE;
 -	  }
 -	  x2 = min(pI830->maxSecond_X1, pScrn1->virtualX - pI830->maxSecond_X2);
 -	  if(x2 < 0) x2 = 0;
 -	  y2 = pI830->SecondYOffs;
 -	  w2 = pScrn1->virtualX - x2;
 -	  h2 = realvirtY;
 -	  if((usenonrect) && (pI830->maxSecond_Y2 != realvirtY)) {
 -	     h2 = pI830->MBXNR2YMAX = pI830->maxSecond_Y2;
 -	     pI830->NonRectDead.x0 = x2;
 -	     pI830->NonRectDead.x1 = x2 + w2 - 1;
 -	     pI830->NonRectDead.y0 = y2 + h2;
 -	     pI830->NonRectDead.y1 = pScrn1->virtualY - 1;
 -	     pI830->HaveNonRect = TRUE;
 -	  }
 -	  break;
 -       case PosAbove:
 -	  x1 = pI830->FirstXOffs;
 -	  y1 = min(pI830->maxFirst_Y2, pScrn1->virtualY - pI830->maxFirst_Y1);
 -	  if(y1 < 0) y1 = 0;
 -	  w1 = realvirtX;
 -	  h1 = pScrn1->virtualY - y1;
 -	  if((usenonrect) && (pI830->maxFirst_X1 != realvirtX)) {
 -	     w1 = pI830->MBXNR1XMAX = pI830->maxFirst_X1;
 -	     pI830->NonRectDead.x0 = x1 + w1;
 -	     pI830->NonRectDead.x1 = pScrn1->virtualX - 1;
 -	     pI830->NonRectDead.y0 = y1;
 -	     pI830->NonRectDead.y1 = y1 + h1 - 1;
 -	     pI830->HaveNonRect = TRUE;
 -	  }
 -	  x2 = pI830->SecondXOffs;
 -	  y2 = 0;
 -	  w2 = realvirtX;
 -	  h2 = max(pI830->maxSecond_Y2, pScrn1->virtualY - pI830->maxSecond_Y1);
 -	  if(h2 > pScrn1->virtualY) h2 = pScrn1->virtualY;
 -	  if((usenonrect) && (pI830->maxSecond_X2 != realvirtX)) {
 -	     w2 = pI830->MBXNR2XMAX = pI830->maxSecond_X2;
 -	     pI830->NonRectDead.x0 = x2 + w2;
 -	     pI830->NonRectDead.x1 = pScrn1->virtualX - 1;
 -	     pI830->NonRectDead.y0 = y2;
 -	     pI830->NonRectDead.y1 = y2 + h2 - 1;
 -	     pI830->HaveNonRect = TRUE;
 -	  }
 -	  break;
 -       case PosBelow:
 -	  x1 = pI830->FirstXOffs;
 -	  y1 = 0;
 -	  w1 = realvirtX;
 -	  h1 = max(pI830->maxFirst_Y1, pScrn1->virtualY - pI830->maxFirst_Y2);
 -	  if(h1 > pScrn1->virtualY) h1 = pScrn1->virtualY;
 -	  if((usenonrect) && (pI830->maxFirst_X1 != realvirtX)) {
 -	     w1 = pI830->MBXNR1XMAX = pI830->maxFirst_X1;
 -	     pI830->NonRectDead.x0 = x1 + w1;
 -	     pI830->NonRectDead.x1 = pScrn1->virtualX - 1;
 -	     pI830->NonRectDead.y0 = y1;
 -	     pI830->NonRectDead.y1 = y1 + h1 - 1;
 -	     pI830->HaveNonRect = TRUE;
 -	  }
 -	  x2 = pI830->SecondXOffs;
 -	  y2 = min(pI830->maxSecond_Y1, pScrn1->virtualY - pI830->maxSecond_Y2);
 -	  if(y2 < 0) y2 = 0;
 -	  w2 = realvirtX;
 -	  h2 = pScrn1->virtualY - y2;
 -	  if((usenonrect) && (pI830->maxSecond_X2 != realvirtX)) {
 -	     w2 = pI830->MBXNR2XMAX = pI830->maxSecond_X2;
 -	     pI830->NonRectDead.x0 = x2 + w2;
 -	     pI830->NonRectDead.x1 = pScrn1->virtualX - 1;
 -	     pI830->NonRectDead.y0 = y2;
 -	     pI830->NonRectDead.y1 = y2 + h2 - 1;
 -	     pI830->HaveNonRect = TRUE;
 -	  }
 -       default:
 -	  break;
 -       }
 -
 -       switch(pI830->SecondPosition) {
 -       case PosLeftOf:
 -       case PosRightOf:
 -	  if(pI830->FirstYOffs) {
 -	     pI830->OffDead1.x0 = x1;
 -	     pI830->OffDead1.x1 = x1 + w1 - 1;
 -	     pI830->OffDead1.y0 = 0;
 -	     pI830->OffDead1.y1 = y1 - 1;
 -	     pI830->OffDead2.x0 = x2;
 -	     pI830->OffDead2.x1 = x2 + w2 - 1;
 -	     pI830->OffDead2.y0 = y2 + h2;
 -	     pI830->OffDead2.y1 = pScrn1->virtualY - 1;
 -	     pI830->HaveOffsRegions = TRUE;
 -	  } else if(pI830->SecondYOffs) {
 -	     pI830->OffDead1.x0 = x2;
 -	     pI830->OffDead1.x1 = x2 + w2 - 1;
 -	     pI830->OffDead1.y0 = 0;
 -	     pI830->OffDead1.y1 = y2 - 1;
 -	     pI830->OffDead2.x0 = x1;
 -	     pI830->OffDead2.x1 = x1 + w1 - 1;
 -	     pI830->OffDead2.y0 = y1 + h1;
 -	     pI830->OffDead2.y1 = pScrn1->virtualY - 1;
 -	     pI830->HaveOffsRegions = TRUE;
 -	  }
 -	  break;
 -       case PosAbove:
 -       case PosBelow:
 -	  if(pI830->FirstXOffs) {
 -	     pI830->OffDead1.x0 = x2 + w2;
 -	     pI830->OffDead1.x1 = pScrn1->virtualX - 1;
 -	     pI830->OffDead1.y0 = y2;
 -	     pI830->OffDead1.y1 = y2 + h2 - 1;
 -	     pI830->OffDead2.x0 = 0;
 -	     pI830->OffDead2.x1 = x1 - 1;
 -	     pI830->OffDead2.y0 = y1;
 -	     pI830->OffDead2.y1 = y1 + h1 - 1;
 -	     pI830->HaveOffsRegions = TRUE;
 -	  } else if(pI830->SecondXOffs) {
 -	     pI830->OffDead1.x0 = x1 + w1;
 -	     pI830->OffDead1.x1 = pScrn1->virtualX - 1;
 -	     pI830->OffDead1.y0 = y1;
 -	     pI830->OffDead1.y1 = y1 + h1 - 1;
 -	     pI830->OffDead2.x0 = 0;
 -	     pI830->OffDead2.x1 = x2 - 1;
 -	     pI830->OffDead2.y0 = y2;
 -	     pI830->OffDead2.y1 = y2 + h2 - 1;
 -	     pI830->HaveOffsRegions = TRUE;
 -	  }
 -       default:
 -	  break;
 -       }
 -
 -    }
 -
 -    I830XineramadataPtr[scrnnum1].x = x1;
 -    I830XineramadataPtr[scrnnum1].y = y1;
 -    I830XineramadataPtr[scrnnum1].width = w1;
 -    I830XineramadataPtr[scrnnum1].height = h1;
 -    I830XineramadataPtr[scrnnum2].x = x2;
 -    I830XineramadataPtr[scrnnum2].y = y2;
 -    I830XineramadataPtr[scrnnum2].width = w2;
 -    I830XineramadataPtr[scrnnum2].height = h2;
 -
 -    if(infochanged) {
 -       xf86DrvMsg(pScrn1->scrnIndex, X_INFO,
 -	  "Pseudo-Xinerama: First (Screen %d) (%d,%d)-(%d,%d)\n",
 -	  scrnnum1, x1, y1, w1+x1-1, h1+y1-1);
 -       xf86DrvMsg(pScrn1->scrnIndex, X_INFO,
 -	  "Pseudo-Xinerama: Second (Screen %d) (%d,%d)-(%d,%d)\n",
 -	  scrnnum2, x2, y2, w2+x2-1, h2+y2-1);
 -       if(pI830->HaveNonRect) {
 -	  xf86DrvMsg(pScrn1->scrnIndex, X_INFO,
 -		"Pseudo-Xinerama: Inaccessible area (%d,%d)-(%d,%d)\n",
 -		pI830->NonRectDead.x0, pI830->NonRectDead.y0,
 -		pI830->NonRectDead.x1, pI830->NonRectDead.y1);
 -       }
 -       if(pI830->HaveOffsRegions) {
 -	  xf86DrvMsg(pScrn1->scrnIndex, X_INFO,
 -		"Pseudo-Xinerama: Inaccessible offset area (%d,%d)-(%d,%d)\n",
 -		pI830->OffDead1.x0, pI830->OffDead1.y0,
 -		pI830->OffDead1.x1, pI830->OffDead1.y1);
 -	  xf86DrvMsg(pScrn1->scrnIndex, X_INFO,
 -		"Pseudo-Xinerama: Inaccessible offset area (%d,%d)-(%d,%d)\n",
 -		pI830->OffDead2.x0, pI830->OffDead2.y0,
 -		pI830->OffDead2.x1, pI830->OffDead2.y1);
 -       }
 -       if(pI830->HaveNonRect || pI830->HaveOffsRegions) {
 -	  xf86DrvMsg(pScrn1->scrnIndex, X_INFO,
 -		"Mouse restriction for inaccessible areas is %s\n",
 -		pI830->MouseRestrictions ? "enabled" : "disabled");
 -       }
 -    }
 -}
 -
 -/* Proc */
 -
 -int
 -I830ProcXineramaQueryVersion(ClientPtr client)
 -{
 -    xPanoramiXQueryVersionReply	  rep;
 -    register int		  n;
 -
 -    REQUEST_SIZE_MATCH(xPanoramiXQueryVersionReq);
 -    rep.type = X_Reply;
 -    rep.length = 0;
 -    rep.sequenceNumber = client->sequence;
 -    rep.majorVersion = 1;
 -    rep.minorVersion = 0;
 -    if(client->swapped) {
 -        swaps(&rep.sequenceNumber, n);
 -        swapl(&rep.length, n);
 -        swaps(&rep.majorVersion, n);
 -        swaps(&rep.minorVersion, n);
 -    }
 -    WriteToClient(client, sizeof(xPanoramiXQueryVersionReply), (char *)&rep);
 -    return (client->noClientException);
 -}
 -
 -int
 -I830ProcXineramaGetState(ClientPtr client)
 -{
 -    REQUEST(xPanoramiXGetStateReq);
 -    WindowPtr			pWin;
 -    xPanoramiXGetStateReply	rep;
 -    register int		n;
 -
 -    REQUEST_SIZE_MATCH(xPanoramiXGetStateReq);
 -    pWin = LookupWindow(stuff->window, client);
 -    if(!pWin) return BadWindow;
 -
 -    rep.type = X_Reply;
 -    rep.length = 0;
 -    rep.sequenceNumber = client->sequence;
 -    rep.state = !I830noPanoramiXExtension;
 -    if(client->swapped) {
 -       swaps (&rep.sequenceNumber, n);
 -       swapl (&rep.length, n);
 -       swaps (&rep.state, n);
 -    }
 -    WriteToClient(client, sizeof(xPanoramiXGetStateReply), (char *)&rep);
 -    return client->noClientException;
 -}
 -
 -int
 -I830ProcXineramaGetScreenCount(ClientPtr client)
 -{
 -    REQUEST(xPanoramiXGetScreenCountReq);
 -    WindowPtr				pWin;
 -    xPanoramiXGetScreenCountReply	rep;
 -    register int			n;
 -
 -    REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq);
 -    pWin = LookupWindow(stuff->window, client);
 -    if(!pWin) return BadWindow;
 -
 -    rep.type = X_Reply;
 -    rep.length = 0;
 -    rep.sequenceNumber = client->sequence;
 -    rep.ScreenCount = I830XineramaNumScreens;
 -    if(client->swapped) {
 -       swaps(&rep.sequenceNumber, n);
 -       swapl(&rep.length, n);
 -       swaps(&rep.ScreenCount, n);
 -    }
 -    WriteToClient(client, sizeof(xPanoramiXGetScreenCountReply), (char *)&rep);
 -    return client->noClientException;
 -}
 -
 -int
 -I830ProcXineramaGetScreenSize(ClientPtr client)
 -{
 -    REQUEST(xPanoramiXGetScreenSizeReq);
 -    WindowPtr				pWin;
 -    xPanoramiXGetScreenSizeReply	rep;
 -    register int			n;
 -
 -    REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq);
 -    pWin = LookupWindow (stuff->window, client);
 -    if(!pWin)  return BadWindow;
 -
 -    rep.type = X_Reply;
 -    rep.length = 0;
 -    rep.sequenceNumber = client->sequence;
 -    rep.width  = I830XineramadataPtr[stuff->screen].width;
 -    rep.height = I830XineramadataPtr[stuff->screen].height;
 -    if(client->swapped) {
 -       swaps(&rep.sequenceNumber, n);
 -       swapl(&rep.length, n);
 -       swaps(&rep.width, n);
 -       swaps(&rep.height, n);
 -    }
 -    WriteToClient(client, sizeof(xPanoramiXGetScreenSizeReply), (char *)&rep);
 -    return client->noClientException;
 -}
 -
 -int
 -I830ProcXineramaIsActive(ClientPtr client)
 -{
 -    xXineramaIsActiveReply	rep;
 -
 -    REQUEST_SIZE_MATCH(xXineramaIsActiveReq);
 -
 -    rep.type = X_Reply;
 -    rep.length = 0;
 -    rep.sequenceNumber = client->sequence;
 -    rep.state = !I830noPanoramiXExtension;
 -    if(client->swapped) {
 -	register int n;
 -	swaps(&rep.sequenceNumber, n);
 -	swapl(&rep.length, n);
 -	swapl(&rep.state, n);
 -    }
 -    WriteToClient(client, sizeof(xXineramaIsActiveReply), (char *) &rep);
 -    return client->noClientException;
 -}
 -
 -int
 -I830ProcXineramaQueryScreens(ClientPtr client)
 -{
 -    xXineramaQueryScreensReply	rep;
 -
 -    REQUEST_SIZE_MATCH(xXineramaQueryScreensReq);
 -
 -    rep.type = X_Reply;
 -    rep.sequenceNumber = client->sequence;
 -    rep.number = (I830noPanoramiXExtension) ? 0 : I830XineramaNumScreens;
 -    rep.length = rep.number * sz_XineramaScreenInfo >> 2;
 -    if(client->swapped) {
 -       register int n;
 -       swaps(&rep.sequenceNumber, n);
 -       swapl(&rep.length, n);
 -       swapl(&rep.number, n);
 -    }
 -    WriteToClient(client, sizeof(xXineramaQueryScreensReply), (char *)&rep);
 -
 -    if(!I830noPanoramiXExtension) {
 -       xXineramaScreenInfo scratch;
 -       int i;
 -
 -       for(i = 0; i < I830XineramaNumScreens; i++) {
 -	  scratch.x_org  = I830XineramadataPtr[i].x;
 -	  scratch.y_org  = I830XineramadataPtr[i].y;
 -	  scratch.width  = I830XineramadataPtr[i].width;
 -	  scratch.height = I830XineramadataPtr[i].height;
 -	  if(client->swapped) {
 -	     register int n;
 -	     swaps(&scratch.x_org, n);
 -	     swaps(&scratch.y_org, n);
 -	     swaps(&scratch.width, n);
 -	     swaps(&scratch.height, n);
 -	  }
 -	  WriteToClient(client, sz_XineramaScreenInfo, (char *)&scratch);
 -       }
 -    }
 -
 -    return client->noClientException;
 -}
 -
 -static int
 -I830ProcXineramaDispatch(ClientPtr client)
 -{
 -    REQUEST(xReq);
 -    switch (stuff->data) {
 -	case X_PanoramiXQueryVersion:
 -	     return I830ProcXineramaQueryVersion(client);
 -	case X_PanoramiXGetState:
 -	     return I830ProcXineramaGetState(client);
 -	case X_PanoramiXGetScreenCount:
 -	     return I830ProcXineramaGetScreenCount(client);
 -	case X_PanoramiXGetScreenSize:
 -	     return I830ProcXineramaGetScreenSize(client);
 -	case X_XineramaIsActive:
 -	     return I830ProcXineramaIsActive(client);
 -	case X_XineramaQueryScreens:
 -	     return I830ProcXineramaQueryScreens(client);
 -    }
 -    return BadRequest;
 -}
 -
 -/* SProc */
 -
 -static int
 -I830SProcXineramaQueryVersion (ClientPtr client)
 -{
 -    REQUEST(xPanoramiXQueryVersionReq);
 -    register int n;
 -    swaps(&stuff->length,n);
 -    REQUEST_SIZE_MATCH (xPanoramiXQueryVersionReq);
 -    return I830ProcXineramaQueryVersion(client);
 -}
 -
 -static int
 -I830SProcXineramaGetState(ClientPtr client)
 -{
 -    REQUEST(xPanoramiXGetStateReq);
 -    register int n;
 -    swaps (&stuff->length, n);
 -    REQUEST_SIZE_MATCH(xPanoramiXGetStateReq);
 -    return I830ProcXineramaGetState(client);
 -}
 -
 -static int
 -I830SProcXineramaGetScreenCount(ClientPtr client)
 -{
 -    REQUEST(xPanoramiXGetScreenCountReq);
 -    register int n;
 -    swaps (&stuff->length, n);
 -    REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq);
 -    return I830ProcXineramaGetScreenCount(client);
 -}
 -
 -static int
 -I830SProcXineramaGetScreenSize(ClientPtr client)
 -{
 -    REQUEST(xPanoramiXGetScreenSizeReq);
 -    register int n;
 -    swaps (&stuff->length, n);
 -    REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq);
 -    return I830ProcXineramaGetScreenSize(client);
 -}
 -
 -static int
 -I830SProcXineramaIsActive(ClientPtr client)
 -{
 -    REQUEST(xXineramaIsActiveReq);
 -    register int n;
 -    swaps (&stuff->length, n);
 -    REQUEST_SIZE_MATCH(xXineramaIsActiveReq);
 -    return I830ProcXineramaIsActive(client);
 -}
 -
 -static int
 -I830SProcXineramaQueryScreens(ClientPtr client)
 -{
 -    REQUEST(xXineramaQueryScreensReq);
 -    register int n;
 -    swaps (&stuff->length, n);
 -    REQUEST_SIZE_MATCH(xXineramaQueryScreensReq);
 -    return I830ProcXineramaQueryScreens(client);
 -}
 -
 -int
 -I830SProcXineramaDispatch(ClientPtr client)
 -{
 -    REQUEST(xReq);
 -    switch (stuff->data) {
 -	case X_PanoramiXQueryVersion:
 -	     return I830SProcXineramaQueryVersion(client);
 -	case X_PanoramiXGetState:
 -	     return I830SProcXineramaGetState(client);
 -	case X_PanoramiXGetScreenCount:
 -	     return I830SProcXineramaGetScreenCount(client);
 -	case X_PanoramiXGetScreenSize:
 -	     return I830SProcXineramaGetScreenSize(client);
 -	case X_XineramaIsActive:
 -	     return I830SProcXineramaIsActive(client);
 -	case X_XineramaQueryScreens:
 -	     return I830SProcXineramaQueryScreens(client);
 -    }
 -    return BadRequest;
 -}
 -
 -static void
 -I830XineramaResetProc(ExtensionEntry* extEntry)
 -{
 -    /* Called by CloseDownExtensions() */
 -    if(I830XineramadataPtr) {
 -       Xfree(I830XineramadataPtr);
 -       I830XineramadataPtr = NULL;
 -    }
 -}
 -
 -static void
 -I830XineramaExtensionInit(ScrnInfoPtr pScrn)
 -{
 -    I830Ptr	pI830 = I830PTR(pScrn);
 -    Bool	success = FALSE;
 -
 -    if(!(I830XineramadataPtr)) {
 -
 -       if(!pI830->MergedFB) {
 -	  I830noPanoramiXExtension = TRUE;
 -	  pI830->MouseRestrictions = FALSE;
 -	  return;
 -       }
 -
 -#ifdef PANORAMIX
 -       if(!noPanoramiXExtension) {
 -	  xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 -	     "Xinerama active, not initializing Intel Pseudo-Xinerama\n");
 -	  I830noPanoramiXExtension = TRUE;
 -	  pI830->MouseRestrictions = FALSE;
 -	  return;
 -       }
 -#endif
 -
 -       if(I830noPanoramiXExtension) {
 -	  xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 -	      "Intel Pseudo-Xinerama disabled\n");
 -	  pI830->MouseRestrictions = FALSE;
 -	  return;
 -       }
 -
 -       I830XineramaNumScreens = 2;
 -
 -       while(I830XineramaGeneration != serverGeneration) {
 -
 -	  pI830->XineramaExtEntry = AddExtension(PANORAMIX_PROTOCOL_NAME, 0,0,
 -					I830ProcXineramaDispatch,
 -					I830SProcXineramaDispatch,
 -					I830XineramaResetProc,
 -					StandardMinorOpcode);
 -
 -	  if(!pI830->XineramaExtEntry) break;
 -
 -	  if(!(I830XineramadataPtr = (I830XineramaData *)
 -	        xcalloc(I830XineramaNumScreens, sizeof(I830XineramaData)))) break;
 -
 -	  I830XineramaGeneration = serverGeneration;
 -	  success = TRUE;
 -       }
 -
 -       if(!success) {
 -          xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 -	      "Failed to initialize Intel Pseudo-Xinerama extension\n");
 -	  I830noPanoramiXExtension = TRUE;
 -	  pI830->MouseRestrictions = FALSE;
 -	  return;
 -       }
 -
 -       xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 -	  "Intel Pseudo-Xinerama extension initialized\n");
 -
 -       pI830->I830XineramaVX = 0;
 -       pI830->I830XineramaVY = 0;
 -
 -    }
 -
 -    I830UpdateXineramaScreenInfo(pScrn);
 -
 -}
 -
 -static void
 -I830BIOSProbeDDC(ScrnInfoPtr pScrn, int index)
 -{
 -   vbeInfoPtr pVbe;
 -
 -   /* The vbe module gets loaded in PreInit(), so no need to load it here. */
 -
 -   pVbe = VBEInit(NULL, index);
 -   ConfiguredMonitor = vbeDoEDID(pVbe, NULL);
 -}
 -
 -/* Various extended video BIOS functions. 
 - * 100 and 120Hz aren't really supported, they work but only get close
 - * to the requested refresh, and really not close enough.
 - * I've seen 100Hz come out at 104Hz, and 120Hz come out at 128Hz */
 -const int i830refreshes[] = {
 -   43, 56, 60, 70, 72, 75, 85 /* 100, 120 */
 -};
 -static const int nrefreshes = sizeof(i830refreshes) / sizeof(i830refreshes[0]);
 -
 -static Bool
 -Check5fStatus(ScrnInfoPtr pScrn, int func, int ax)
 -{
 -   if (ax == 0x005f)
 -      return TRUE;
 -   else if (ax == 0x015f) {
 -      xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 -		 "Extended BIOS function 0x%04x failed.\n", func);
 -      return FALSE;
 -   } else if ((ax & 0xff) != 0x5f) {
 -      xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 -		 "Extended BIOS function 0x%04x not supported.\n", func);
 -      return FALSE;
 -   } else {
 -      xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 -		 "Extended BIOS function 0x%04x returns 0x%04x.\n",
 -		 func, ax & 0xffff);
 -      return FALSE;
 -   }
 -}
 -
 -static int
 -GetToggleList(ScrnInfoPtr pScrn, int toggle)
 -{
 -   vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe;
 -
 -   DPRINTF(PFX, "GetToggleList\n");
 -
 -   pVbe->pInt10->num = 0x10;
 -   pVbe->pInt10->ax = 0x5f64;
 -   pVbe->pInt10->bx = 0x500;
 - 
 -   pVbe->pInt10->bx |= toggle;
 -
 -   xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);
 -   if (Check5fStatus(pScrn, 0x5f64, pVbe->pInt10->ax)) {
 -      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Toggle (%d) 0x%x\n", toggle, pVbe->pInt10->cx);
 -      return pVbe->pInt10->cx & 0xffff;
 -   }
 -
 -   return 0;
 -}
 -
 -static int
 -GetNextDisplayDeviceList(ScrnInfoPtr pScrn, int toggle)
 -{
 -   vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe;
 -   int devices = 0;
 -   int pipe = 0;
 -   int i;
 -
 -   DPRINTF(PFX, "GetNextDisplayDeviceList\n");
 -
 -   pVbe->pInt10->num = 0x10;
 -   pVbe->pInt10->ax = 0x5f64;
 -   pVbe->pInt10->bx = 0xA00;
 -   pVbe->pInt10->bx |= toggle;
 -   pVbe->pInt10->es = SEG_ADDR(pVbe->real_mode_base);
 -   pVbe->pInt10->di = SEG_OFF(pVbe->real_mode_base);
 -
 -   xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);
 -   if (!Check5fStatus(pScrn, 0x5f64, pVbe->pInt10->ax))
 -      return 0;
 -
 -   for (i=0; i<(pVbe->pInt10->cx & 0xff); i++) {
 -      CARD32 VODA = (CARD32)((CARD32*)pVbe->memory)[i];
 -
 -      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Next ACPI _DGS [%d] 0x%lx\n",
 -		i, VODA);
 -
 -      /* Check if it's a custom Video Output Device Attribute */
 -      if (!(VODA & 0x80000000)) 
 -         continue;
 -
 -      pipe = (VODA & 0x000000F0) >> 4;
 -
 -      if (pipe != 0 && pipe != 1) {
 -         pipe = 0;
 -#if 0
 -         ErrorF("PIPE %d\n",pipe);
 -#endif
 -      }
 -
 -      switch ((VODA & 0x00000F00) >> 8) {
 -      case 0x0:
 -      case 0x1: /* CRT */
 -         devices |= PIPE_CRT << (pipe == 1 ? 8 : 0);
 -         break;
 -      case 0x2: /* TV/HDTV */
 -         devices |= PIPE_TV << (pipe == 1 ? 8 : 0);
 -         break;
 -      case 0x3: /* DFP */
 -         devices |= PIPE_DFP << (pipe == 1 ? 8 : 0);
 -         break;
 -      case 0x4: /* LFP */
 -         devices |= PIPE_LFP << (pipe == 1 ? 8 : 0);
 -         break;
 -      }
 -   }
 -
 -   xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ACPI Toggle devices 0x%x\n", devices);
 -
 -   return devices;
 -}
 -
 -static int
 -GetAttachableDisplayDeviceList(ScrnInfoPtr pScrn)
 -{
 -   vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe;
 -   int i;
 -
 -   DPRINTF(PFX, "GetAttachableDisplayDeviceList\n");
 -
 -   pVbe->pInt10->num = 0x10;
 -   pVbe->pInt10->ax = 0x5f64;
 -   pVbe->pInt10->bx = 0x900;
 -   pVbe->pInt10->es = SEG_ADDR(pVbe->real_mode_base);
 -   pVbe->pInt10->di = SEG_OFF(pVbe->real_mode_base);
 -
 -   xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);
 -   if (!Check5fStatus(pScrn, 0x5f64, pVbe->pInt10->ax))
 -      return 0;
 -
 -   for (i=0; i<(pVbe->pInt10->cx & 0xff); i++)
 -        xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
 -		"Attachable device 0x%lx.\n", ((CARD32*)pVbe->memory)[i]);
 -
 -   return pVbe->pInt10->cx & 0xffff;
 -}
 -
 -static int
 -BitToRefresh(int bits)
 -{
 -   int i;
 -
 -   for (i = 0; i < nrefreshes; i++)
 -      if (bits & (1 << i))
 -	 return i830refreshes[i];
 -   return 0;
 -}
 -
 -static int
 -GetRefreshRate(ScrnInfoPtr pScrn, int mode, int *availRefresh)
 -{
 -   vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe;
 -
 -   DPRINTF(PFX, "GetRefreshRate\n");
 -
 -   /* Only 8-bit mode numbers are supported. */
 -   if (mode & 0x100)
 -      return 0;
 -
 -   pVbe->pInt10->num = 0x10;
 -   pVbe->pInt10->ax = 0x5f05;
 -   pVbe->pInt10->bx = (mode & 0xff) | 0x100;
 -
 -   xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);
 -   if (Check5fStatus(pScrn, 0x5f05, pVbe->pInt10->ax)) {
 -      if (availRefresh)
 -         *availRefresh = pVbe->pInt10->bx;
 -      return BitToRefresh(pVbe->pInt10->cx);
 -   } else
 -      return 0;
 -}
 -
 -struct panelid {
 -	short hsize;
 -	short vsize;
 -	short fptype;
 -	char redbpp;
 -	char greenbpp;
 -	char bluebpp;
 -	char reservedbpp;
 -	int rsvdoffscrnmemsize;
 -	int rsvdoffscrnmemptr;
 -	char reserved[14];
 -};
 -
 -static void
 -I830InterpretPanelID(int scrnIndex, unsigned char *tmp)
 -{
 -    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
 -    struct panelid *block = (struct panelid *)tmp;
 -
 -#define PANEL_DEFAULT_HZ 60
 -
 -   xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 -	 "PanelID returned panel resolution : %dx%d\n", 
 -						block->hsize, block->vsize);
 -
 -   /* If we get bogus values from this, don't accept it */
 -   if (block->hsize == 0 || block->vsize == 0) {
 -   	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 -	 "Bad Panel resolution - ignoring panelID\n");
 -	
 -	return;
 -   }
 -
 -   /* If we have monitor timings then don't overwrite them */
 -   if (pScrn->monitor->nHsync > 0 &&
 -	pScrn->monitor->nVrefresh > 0)
 -	return;
 -
 -   /* With panels, we're always assuming a refresh of 60Hz */
 -
 -   pScrn->monitor->nHsync = 1;
 -   pScrn->monitor->nVrefresh = 1;
 -
 -   /* Give a little tolerance for the selected panel */
 -   pScrn->monitor->hsync[0].lo = (float)((PANEL_DEFAULT_HZ/1.05)*block->vsize)/1000;
 -   pScrn->monitor->hsync[0].hi = (float)((PANEL_DEFAULT_HZ/0.95)*block->vsize)/1000;
 -   pScrn->monitor->vrefresh[0].lo = (float)PANEL_DEFAULT_HZ;
 -   pScrn->monitor->vrefresh[0].hi = (float)PANEL_DEFAULT_HZ;
 -}
 -
 -/* This should probably go into the VBE layer */
 -static unsigned char *
 -vbeReadPanelID(vbeInfoPtr pVbe)
 -{
 -    int RealOff = pVbe->real_mode_base;
 -    pointer page = pVbe->memory;
 -    unsigned char *tmp = NULL;
 -    int screen = pVbe->pInt10->scrnIndex;
 -
 -    pVbe->pInt10->ax = 0x4F11;
 -    pVbe->pInt10->bx = 0x01;
 -    pVbe->pInt10->cx = 0;
 -    pVbe->pInt10->dx = 0;
 -    pVbe->pInt10->es = SEG_ADDR(RealOff);
 -    pVbe->pInt10->di = SEG_OFF(RealOff);
 -    pVbe->pInt10->num = 0x10;
 -
 -    xf86ExecX86int10(pVbe->pInt10);
 -
 -    if ((pVbe->pInt10->ax & 0xff) != 0x4f) {
 -        xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE PanelID invalid\n");
 -	goto error;
 -    }
 -    switch (pVbe->pInt10->ax & 0xff00) {
 -    case 0x0:
 -	xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE PanelID read successfully\n");
 -  	tmp = (unsigned char *)xnfalloc(32); 
 -  	memcpy(tmp,page,32); 
 -	break;
 -    case 0x100:
 -	xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE PanelID read failed\n");	
 -	break;
 -    default:
 -	xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE PanelID unknown failure %i\n",
 -		       pVbe->pInt10->ax & 0xff00);
 -	break;
 -    }
 -
 - error:
 -    return tmp;
 -}
 -
 -static void
 -vbeDoPanelID(vbeInfoPtr pVbe)
 -{
 -    unsigned char *PanelID_data;
 -    
 -    if (!pVbe) return;
 -
 -    PanelID_data = vbeReadPanelID(pVbe);
 -
 -    if (!PanelID_data) 
 -	return;
 -    
 -    I830InterpretPanelID(pVbe->pInt10->scrnIndex, PanelID_data);
 -}
 -
 -int 
 -I830GetBestRefresh(ScrnInfoPtr pScrn, int refresh)
 -{
 -   int i;
 -
 -   for (i = nrefreshes - 1; i >= 0; i--) {
 -      /*
 -       * Look for the highest value that the requested (refresh + 2) is
 -       * greater than or equal to.
 -       */
 -      if (i830refreshes[i] <= (refresh + 2))
 -	 break;
 -   }
 -   /* i can be 0 if the requested refresh was higher than the max. */
 -   if (i == 0) {
 -      if (refresh >= i830refreshes[nrefreshes - 1])
 -         i = nrefreshes - 1;
 -   }
 -
 -   return i;
 -}
 -
 -static int
 -SetRefreshRate(ScrnInfoPtr pScrn, int mode, int refresh)
 -{
 -   vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe;
 -   int i = I830GetBestRefresh(pScrn, refresh);
 -
 -   DPRINTF(PFX, "SetRefreshRate: mode 0x%x, refresh: %d\n", mode, refresh);
 -
 -   DPRINTF(PFX, "Setting refresh rate to %dHz for mode 0x%02x\n",
 -	   i830refreshes[i], mode & 0xff);
 -
 -   /* Only 8-bit mode numbers are supported. */
 -   if (mode & 0x100)
 -      return 0;
 -
 -   pVbe->pInt10->num = 0x10;
 -   pVbe->pInt10->ax = 0x5f05;
 -   pVbe->pInt10->bx = mode & 0xff;
 -
 -   pVbe->pInt10->cx = 1 << i;
 -   xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);
 -   if (Check5fStatus(pScrn, 0x5f05, pVbe->pInt10->ax))
 -      return i830refreshes[i];
 -   else
 -      return 0;
 -}
 -
 -#if 0
 -static Bool
 -SetPowerStatus(ScrnInfoPtr pScrn, int mode)
 -{
 -   vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe;
 -
 -   pVbe->pInt10->num = 0x10;
 -   pVbe->pInt10->ax = 0x5f64;
 -   pVbe->pInt10->bx = 0x0800 | mode;
 -   pVbe->pInt10->cx = 0x0000;
 -
 -   xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);
 -   if (Check5fStatus(pScrn, 0x5f64, pVbe->pInt10->ax))
 -      return TRUE;
 -  
 -   return FALSE;
 -}
 -#endif
 -
 -static Bool
 -GetModeSupport(ScrnInfoPtr pScrn, int modePipeA, int modePipeB,
 -	       int devicesPipeA, int devicesPipeB, int *maxBandwidth,
 -	       int *bandwidthPipeA, int *bandwidthPipeB)
 -{
 -   vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe;
 -
 -   DPRINTF(PFX, "GetModeSupport: modes 0x%x, 0x%x, devices: 0x%x, 0x%x\n",
 -	   modePipeA, modePipeB, devicesPipeA, devicesPipeB);
 -
 -   /* Only 8-bit mode numbers are supported. */
 -   if ((modePipeA & 0x100) || (modePipeB & 0x100))
 -      return FALSE;
 -
 -   pVbe->pInt10->num = 0x10;
 -   pVbe->pInt10->ax = 0x5f28;
 -   pVbe->pInt10->bx = (modePipeA & 0xff) | ((modePipeB & 0xff) << 8);
 -   if ((devicesPipeA & 0x80) || (devicesPipeB & 0x80))
 -      pVbe->pInt10->cx = 0x8000;
 -   else
 -      pVbe->pInt10->cx = (devicesPipeA & 0xff) | ((devicesPipeB & 0xff) << 8);
 -
 -   xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);
 -   if (Check5fStatus(pScrn, 0x5f28, pVbe->pInt10->ax)) {
 -      if (maxBandwidth)
 -	 *maxBandwidth = pVbe->pInt10->cx;
 -      if (bandwidthPipeA)
 -	 *bandwidthPipeA = pVbe->pInt10->dx & 0xffff;
 -      /* XXX For XFree86 4.2.0 and earlier, ->dx is truncated to 16 bits. */
 -      if (bandwidthPipeB)
 -	 *bandwidthPipeB = (pVbe->pInt10->dx >> 16) & 0xffff;
 -      return TRUE;
 -   } else
 -      return FALSE;
 -}
 -
 -#if 0
 -static int
 -GetLFPCompMode(ScrnInfoPtr pScrn)
 -{
 -   vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe;
 -
 -   DPRINTF(PFX, "GetLFPCompMode\n");
 -
 -   pVbe->pInt10->num = 0x10;
 -   pVbe->pInt10->ax = 0x5f61;
 -   pVbe->pInt10->bx = 0x100;
 -
 -   xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);
 -   if (Check5fStatus(pScrn, 0x5f61, pVbe->pInt10->ax))
 -      return pVbe->pInt10->cx & 0xffff;
 -   else
 -      return -1;
 -}
 -
 -static Bool
 -SetLFPCompMode(ScrnInfoPtr pScrn, int compMode)
 -{
 -   vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe;
 -
 -   DPRINTF(PFX, "SetLFPCompMode: compMode %d\n", compMode);
 -
 -   pVbe->pInt10->num = 0x10;
 -   pVbe->pInt10->ax = 0x5f61;
 -   pVbe->pInt10->bx = 0;
 -   pVbe->pInt10->cx = compMode;
 -
 -   xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);
 -   return Check5fStatus(pScrn, 0x5f61, pVbe->pInt10->ax);
 -}
 -#endif
 -
 -static int
 -GetDisplayDevices(ScrnInfoPtr pScrn)
 -{
 -   I830Ptr pI830 = I830PTR(pScrn);
 -   vbeInfoPtr pVbe = pI830->pVbe;
 -
 -   DPRINTF(PFX, "GetDisplayDevices\n");
 -
 -#if 0
 -   {
 -      CARD32 temp;
 -      ErrorF("ADPA is 0x%08x\n", INREG(ADPA));
 -      ErrorF("DVOA is 0x%08x\n", INREG(DVOA));
 -      ErrorF("DVOB is 0x%08x\n", INREG(DVOB));
 -      ErrorF("DVOC is 0x%08x\n", INREG(DVOC));
 -      ErrorF("LVDS is 0x%08x\n", INREG(LVDS));
 -      temp = INREG(DVOA_SRCDIM);
 -      ErrorF("DVOA_SRCDIM is 0x%08x (%d x %d)\n", temp,
 -	     (temp >> 12) & 0xfff, temp & 0xfff);
 -      temp = INREG(DVOB_SRCDIM);
 -      ErrorF("DVOB_SRCDIM is 0x%08x (%d x %d)\n", temp,
 -	     (temp >> 12) & 0xfff, temp & 0xfff);
 -      temp = INREG(DVOC_SRCDIM);
 -      ErrorF("DVOC_SRCDIM is 0x%08x (%d x %d)\n", temp,
 -	     (temp >> 12) & 0xfff, temp & 0xfff);
 -      ErrorF("SWF0 is 0x%08x\n", INREG(SWF0));
 -      ErrorF("SWF4 is 0x%08x\n", INREG(SWF4));
 -   }
 -#endif
 -
 -   pVbe->pInt10->num = 0x10;
 -   pVbe->pInt10->ax = 0x5f64;
 -   pVbe->pInt10->bx = 0x100;
 -
 -   xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);
 -   if (Check5fStatus(pScrn, 0x5f64, pVbe->pInt10->ax)) {
 -      return pVbe->pInt10->cx & 0xffff;
 -   } else {
 -      if (pI830->PciInfo->chipType == PCI_CHIP_E7221_G) /* FIXED CONFIG */
 -         return PIPE_CRT;
 -      else
 -         return -1;
 -   }
 -}
 -
 -static int
 -GetBIOSPipe(ScrnInfoPtr pScrn)
 -{
 -   I830Ptr pI830 = I830PTR(pScrn);
 -   vbeInfoPtr pVbe = pI830->pVbe;
 -   int pipe;
 -
 -   DPRINTF(PFX, "GetBIOSPipe:\n");
 -
 -   /* single pipe machines should always return Pipe A */
 -   if (pI830->availablePipes == 1) return 0;
 -
 -   pVbe->pInt10->num = 0x10;
 -   pVbe->pInt10->ax = 0x5f1c;
 -   pVbe->pInt10->bx = 0x100;
 -
 -   xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);
 -   if (Check5fStatus(pScrn, 0x5f1c, pVbe->pInt10->ax)) {
 -      if (pI830->newPipeSwitch) {
 -         pipe = ((pVbe->pInt10->bx & 0x0001));
 -      } else {
 -         pipe = ((pVbe->pInt10->cx & 0x0100) >> 8);
 -      }
 -      return pipe;
 -   }
 -
 -   /* failed, assume pipe A */
 -   return 0;
 -}
 -
 -static Bool
 -SetBIOSPipe(ScrnInfoPtr pScrn, int pipe)
 -{
 -   I830Ptr pI830 = I830PTR(pScrn);
 -   vbeInfoPtr pVbe = pI830->pVbe;
 -
 -   DPRINTF(PFX, "SetBIOSPipe: pipe 0x%x\n", pipe);
 -
 -   /* single pipe machines should always return TRUE */
 -   if (pI830->availablePipes == 1) return TRUE;
 -
 -   pVbe->pInt10->num = 0x10;
 -   pVbe->pInt10->ax = 0x5f1c;
 -   if (pI830->newPipeSwitch) {
 -      pVbe->pInt10->bx = pipe;
 -      pVbe->pInt10->cx = 0;
 -   } else {
 -      pVbe->pInt10->bx = 0x0;
 -      pVbe->pInt10->cx = pipe << 8;
 -   }
 -
 -   xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);
 -   if (Check5fStatus(pScrn, 0x5f1c, pVbe->pInt10->ax)) {
 -      return TRUE;
 -   }
 -	
 -   return FALSE;
 -}
 -
 -static Bool
 -SetPipeAccess(ScrnInfoPtr pScrn)
 -{
 -   I830Ptr pI830 = I830PTR(pScrn);
 -
 -   /* Don't try messing with the pipe, unless we're dual head */
 -   if (xf86IsEntityShared(pScrn->entityList[0]) || pI830->Clone || pI830->MergedFB || pI830->origPipe != pI830->pipe) {
 -      if (!SetBIOSPipe(pScrn, pI830->pipe))
 -         return FALSE;
 -   }
 -   
 -   return TRUE;
 -}
 -
 -static Bool
 -I830Set640x480(ScrnInfoPtr pScrn)
 -{
 -   I830Ptr pI830 = I830PTR(pScrn);
 -   int m = 0x30; /* 640x480 8bpp */
 -
 -   switch (pScrn->depth) {
 -   case 15:
 -	 m = 0x40;
 -	 break;
 -   case 16:
 -	 m = 0x41;
 -	 break;
 -   case 24:
 -	 m = 0x50;
 -	 break;
 -   }
 -
 -   m |= (1 << 15) | (1 << 14);
 -   if (VBESetVBEMode(pI830->pVbe, m, NULL))
 -	   return TRUE;
 -
 -
 -   /* if the first failed, let's try the next - usually 800x600 */
 -   m = 0x32;
 -   switch (pScrn->depth) {
 -   case 15:
 -   case 16:
 -	 m = 0x42;
 -	 break;
 -   case 24:
 -	 m = 0x52;
 -	 break;
 -   }
 -   m |= (1 << 15) | (1 << 14);
 -
 -   if (VBESetVBEMode(pI830->pVbe, m, NULL))
 -	   return TRUE;
 -
 -   return FALSE;
 -}
 -
 -/* This is needed for SetDisplayDevices to work correctly on I915G.
 - * Enable for all chipsets now as it has no bad side effects, apart
 - * from slightly longer startup time.
 - */
 -#define I915G_WORKAROUND
 -
 -static Bool
 -SetDisplayDevices(ScrnInfoPtr pScrn, int devices)
 -{
 -   I830Ptr pI830 = I830PTR(pScrn);
 -   vbeInfoPtr pVbe = pI830->pVbe;
 -   CARD32 temp;
 -   int singlepipe = 0;
 -#ifdef I915G_WORKAROUND
 -   int getmode1;
 -   Bool setmode = FALSE;
 -#endif
 -
 -   DPRINTF(PFX, "SetDisplayDevices: devices 0x%x\n", devices);
 -
 -   if (!pI830->specifiedMonitor)
 -      return TRUE;
 -
 -#ifdef I915G_WORKAROUND
 -   if (pI830->preinit)
 -      setmode = TRUE;
 -   if (pI830->leaving)
 -      setmode = FALSE;
 -   if (pI830->closing)
 -      setmode = FALSE;
 -
 -   if (setmode) {
 -      VBEGetVBEMode(pVbe, &getmode1);
 -      I830Set640x480(pScrn);
 -   }
 -#endif
 -
 -   pVbe->pInt10->num = 0x10;
 -   pVbe->pInt10->ax = 0x5f64;
 -   pVbe->pInt10->bx = 0x1;
 -   pVbe->pInt10->cx = devices;
 -
 -   xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);
 -   if (Check5fStatus(pScrn, 0x5f64, pVbe->pInt10->ax)) {
 -#ifdef I915G_WORKAROUND
 -      if (setmode) {
 -  	 VBESetVBEMode(pI830->pVbe, getmode1 | 1<<15, NULL);
 -      }
 -#endif
 -      pI830->pipeEnabled[0] = (devices & 0xff) ? TRUE : FALSE;
 -      pI830->pipeEnabled[1] = (devices & 0xff00) ? TRUE : FALSE;
 -
 -      return TRUE;
 -   }
 -
 -#ifdef I915G_WORKAROUND
 -   if (setmode)
 -      VBESetVBEMode(pI830->pVbe, getmode1 | 1<<15, NULL);
 -#endif
 -
 -   if (devices & 0xff) {
 -      pVbe->pInt10->num = 0x10;
 -      pVbe->pInt10->ax = 0x5f64;
 -      pVbe->pInt10->bx = 0x1;
 -      pVbe->pInt10->cx = devices & 0xff;
 -
 -      xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);
 -      if (Check5fStatus(pScrn, 0x5f64, pVbe->pInt10->ax)) {
 -         xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 -	 	"Successfully set display devices to 0x%x.\n",devices & 0xff);
 -         singlepipe = devices & 0xff00; /* set alternate */
 -      } else {
 -         xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 -	 	"Failed to set display devices to 0x%x.\n",devices & 0xff);
 -         singlepipe = devices;
 -      }
 -   } else
 -      singlepipe = devices; 
 -
 -   if (singlepipe == devices && devices & 0xff00) {
 -      pVbe->pInt10->num = 0x10;
 -      pVbe->pInt10->ax = 0x5f64;
 -      pVbe->pInt10->bx = 0x1;
 -      pVbe->pInt10->cx = devices & 0xff00;
 -
 -      xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);
 -      if (Check5fStatus(pScrn, 0x5f64, pVbe->pInt10->ax)) {
 -         xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 -	 	"Successfully set display devices to 0x%x.\n",devices & 0xff00);
 -         singlepipe = devices & 0xff; /* set alternate */
 -      } else {
 -         xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 -	 	"Failed to set display devices to 0x%x.\n",devices & 0xff00);
 -         singlepipe = devices;
 -      }
 -   } 
 -
 -   /* LVDS doesn't exist on these */
 -   if (IS_I830(pI830) || IS_845G(pI830) || IS_I865G(pI830) || IS_I915G(pI830) || IS_I945G(pI830) || IS_I965G(pI830))
 -      singlepipe &= ~(PIPE_LFP | (PIPE_LFP<<8));
 -
 -   if (pI830->availablePipes == 1) 
 -      singlepipe &= 0xFF;
 -
 -   /* Disable LVDS */
 -   if (singlepipe & PIPE_LFP)  {
 -      /* LFP on PipeA is unlikely! */
 -      OUTREG(0x61200, INREG(0x61200) & ~0x80000000);
 -      OUTREG(0x61204, INREG(0x61204) & ~0x00000001);
 -      while ((INREG(0x61200) & 0x80000000) || (INREG(0x61204) & 1));
 -      /* Fix up LVDS */
 -      OUTREG(LVDS, (INREG(LVDS) & ~1<<30) | 0x80000300);
 -      /* Enable LVDS */
 -      OUTREG(0x61200, INREG(0x61200) | 0x80000000);
 -      OUTREG(0x61204, INREG(0x61204) | 0x00000001);
 -      while (!(INREG(0x61200) & 0x80000000) && !(INREG(0x61204) & 1));
 -      xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 -	 	"Enabling LVDS directly. Pipe A.\n");
 -   } else
 -   if (singlepipe & (PIPE_LFP << 8))  {
 -      OUTREG(0x61200, INREG(0x61200) & ~0x80000000);
 -      OUTREG(0x61204, INREG(0x61204) & ~0x00000001);
 -      while ((INREG(0x61200) & 0x80000000) || (INREG(0x61204) & 1));
 -      /* Fix up LVDS */
 -      OUTREG(LVDS, (INREG(LVDS) | 1<<30) | 0x80000300);
 -      /* Enable LVDS */
 -      OUTREG(0x61200, INREG(0x61200) | 0x80000000);
 -      OUTREG(0x61204, INREG(0x61204) | 0x00000001);
 -      while (!(INREG(0x61200) & 0x80000000) && !(INREG(0x61204) & 1));
 -      xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 -	 	"Enabling LVDS directly. Pipe B.\n");
 -   }
 -   else if (!(IS_I830(pI830) || IS_845G(pI830) || IS_I865G(pI830))) {
 -      if (!(devices & (PIPE_LFP | PIPE_LFP<<8))) {
 -         OUTREG(0x61200, INREG(0x61200) & ~0x80000000);
 -         OUTREG(0x61204, INREG(0x61204) & ~0x00000001);
 -         while ((INREG(0x61200) & 0x80000000) || (INREG(0x61204) & 1));
 -         /* Fix up LVDS */
 -         OUTREG(LVDS, (INREG(LVDS) | 1<<30) & ~0x80000300);
 -         xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 -	 	"Disabling LVDS directly.\n");
 -      }
 -   }
 -
 -   /* Now try to program the registers directly if the BIOS failed. */
 -   temp = INREG(ADPA);
 -   temp &= ~(ADPA_DAC_ENABLE | ADPA_PIPE_SELECT_MASK);
 -   temp &= ~(ADPA_VSYNC_CNTL_DISABLE | ADPA_HSYNC_CNTL_DISABLE);
 -   /* Turn on ADPA */
 -   if (singlepipe & PIPE_CRT)  {
 -      xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 -	 	"Enabling ADPA directly. Pipe A.\n");
 -      temp |= ADPA_DAC_ENABLE | ADPA_PIPE_A_SELECT;
 -      OUTREG(ADPA, temp);
 -   } else
 -   if (singlepipe & (PIPE_CRT << 8)) {
 -      xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 -	 	"Enabling ADPA directly. Pipe B.\n");
 -      temp |= ADPA_DAC_ENABLE | ADPA_PIPE_B_SELECT;
 -      OUTREG(ADPA, temp);
 -   } 
 -   else {
 -      if (!(devices & (PIPE_CRT | PIPE_CRT<<8))) {
 -         xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 -	 	"Disabling ADPA directly.\n");
 -         temp |= ADPA_VSYNC_CNTL_DISABLE | ADPA_HSYNC_CNTL_DISABLE;
 -         OUTREG(ADPA, temp);
 -      }
 -   }
 -
 -   xf86DrvMsg(pScrn->scrnIndex, X_WARNING,"Writing config directly to SWF0.\n");
 -   temp = INREG(SWF0);
 -   OUTREG(SWF0, (temp & ~(0xffff)) | (devices & 0xffff));
 -
 -   if (GetDisplayDevices(pScrn) != devices) {
 -      xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 -		 "SetDisplayDevices failed with devices 0x%x instead of 0x%x\n",
 -	         GetDisplayDevices(pScrn), devices);
 -      return FALSE;
 -   }
 -
 -   pI830->pipeEnabled[0] = (devices & 0xff) ? TRUE : FALSE;
 -   pI830->pipeEnabled[1] = (devices & 0xff00) ? TRUE : FALSE;
 -
 -   return TRUE;
 -}
 -
 -static Bool
 -GetBIOSVersion(ScrnInfoPtr pScrn, unsigned int *version)
 -{
 -   vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe;
 -
 -   DPRINTF(PFX, "GetBIOSVersion\n");
 -
 -   pVbe->pInt10->num = 0x10;
 -   pVbe->pInt10->ax = 0x5f01;
 -
 -   xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);
 -   if (Check5fStatus(pScrn, 0x5f01, pVbe->pInt10->ax)) {
 -      *version = pVbe->pInt10->bx;
 -      return TRUE;
 -   }
 -
 -   *version = 0;
 -   return FALSE;
 -}
 -
 -static Bool
 -GetDevicePresence(ScrnInfoPtr pScrn, Bool *required, int *attached,
 -		  int *encoderPresent)
 -{
 -   vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe;
 -
 -   DPRINTF(PFX, "GetDevicePresence\n");
 -
 -   pVbe->pInt10->num = 0x10;
 -   pVbe->pInt10->ax = 0x5f64;
 -   pVbe->pInt10->bx = 0x200;
 -
 -   xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);
 -   if (Check5fStatus(pScrn, 0x5f64, pVbe->pInt10->ax)) {
 -      if (required)
 -	 *required = ((pVbe->pInt10->bx & 0x1) == 0);
 -      if (attached)
 -	 *attached = (pVbe->pInt10->cx >> 8) & 0xff;
 -      if (encoderPresent)
 -	 *encoderPresent = pVbe->pInt10->cx & 0xff;
 -      return TRUE;
 -   } else
 -      return FALSE;
 -}
 -
 -static Bool
 -GetDisplayInfo(ScrnInfoPtr pScrn, int device, Bool *attached, Bool *present,
 -	       short *x, short *y)
 -{
 -   vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe;
 -
 -   DPRINTF(PFX, "GetDisplayInfo: device: 0x%x\n", device);
 -
 -   switch (device & 0xff) {
 -   case PIPE_CRT:
 -   case PIPE_TV:
 -   case PIPE_DFP:
 -   case PIPE_LFP:
 -   case PIPE_CRT2:
 -   case PIPE_TV2:
 -   case PIPE_DFP2:
 -   case PIPE_LFP2:
 -      break;
 -   default:
 -      xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 -		 "GetDisplayInfo: invalid device: 0x%x\n", device & 0xff);
 -      return FALSE;
 -   }
 -
 -   pVbe->pInt10->num = 0x10;
 -   pVbe->pInt10->ax = 0x5f64;
 -   pVbe->pInt10->bx = 0x300;
 -   pVbe->pInt10->cx = device & 0xff;
 -
 -   xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);
 -   if (Check5fStatus(pScrn, 0x5f64, pVbe->pInt10->ax)) {
 -      if (attached)
 -	 *attached = ((pVbe->pInt10->bx & 0x2) != 0);
 -      if (present)
 -	 *present = ((pVbe->pInt10->bx & 0x1) != 0);
 -      if (pVbe->pInt10->cx != (device & 0xff)) {
 -	 if (y) {
 -	    *y = pVbe->pInt10->cx & 0xffff;
 -	 }
 -	 if (x) {
 -	    *x = (pVbe->pInt10->cx >> 16) & 0xffff;
 -	 }
 -      }
 -      return TRUE;
 -   } else
 -      return FALSE;
 -}
 -
 -/*
 - * Returns a string matching the device corresponding to the first bit set
 - * in "device".  savedDevice is then set to device with that bit cleared.
 - * Subsequent calls with device == -1 will use savedDevice.
 - */
 -
 -static const char *displayDevices[] = {
 -   "CRT",
 -   "TV",
 -   "DFP (digital flat panel)",
 -   "LFP (local flat panel)",
 -   "Second (second CRT)",
 -   "TV2 (second TV)",
 -   "DFP2 (second digital flat panel)",
 -   "LFP2 (second local flat panel)",
 -   NULL
 -};
 -
 -static const char *
 -DeviceToString(int device)
 -{
 -   static int savedDevice = -1;
 -   int bit = 0;
 -   const char *name;
 -
 -   if (device == -1) {
 -      device = savedDevice;
 -      bit = 0;
 -   }
 -
 -   if (device == -1)
 -      return NULL;
 -
 -   while (displayDevices[bit]) {
 -      if (device & (1 << bit)) {
 -	 name = displayDevices[bit];
 -	 savedDevice = device & ~(1 << bit);
 -	 bit++;
 -	 return name;
 -      }
 -      bit++;
 -   }
 -   return NULL;
 -}
 -
 -static void
 -PrintDisplayDeviceInfo(ScrnInfoPtr pScrn)
 -{
 -   I830Ptr pI830 = I830PTR(pScrn);
 -   int pipe, n;
 -   int displays;
 -
 -   DPRINTF(PFX, "PrintDisplayDeviceInfo\n");
 -
 -   displays = pI830->operatingDevices;
 -   if (displays == -1) {
 -      xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 -		 "No active display devices.\n");
 -      return;
 -   }
 -
 -   /* Check for active devices connected to each display pipe. */
 -   for (n = 0; n < pI830->availablePipes; n++) {
 -      pipe = ((displays >> PIPE_SHIFT(n)) & PIPE_ACTIVE_MASK);
 -      if (pipe) {
 -	 const char *name;
 -
 -	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 -		    "Currently active displays on Pipe %c:\n", PIPE_NAME(n));
 -	 name = DeviceToString(pipe);
 -	 do {
 -	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "\t%s\n", name);
 -	    name = DeviceToString(-1);
 -	 } while (name);
 -
 -      } else {
 -	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 -		    "No active displays on Pipe %c.\n", PIPE_NAME(n));
 -      }
 -
 -      if (pI830->pipeDisplaySize[n].x2 != 0) {
 -	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 -		    "Lowest common panel size for pipe %c is %d x %d\n",
 -		    PIPE_NAME(n), pI830->pipeDisplaySize[n].x2,
 -		    pI830->pipeDisplaySize[n].y2);
 -      } else if (pI830->pipeEnabled[n] && pipe & ~PIPE_CRT_ACTIVE) {
 -	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 -		    "No display size information available for pipe %c.\n",
 -		    PIPE_NAME(n));
 -      }
 -   }
 -}
 -
 -static void
 -GetPipeSizes(ScrnInfoPtr pScrn)
 -{
 -   I830Ptr pI830 = I830PTR(pScrn);
 -   int pipe, n;
 -   DisplayType i;
 -
 -   DPRINTF(PFX, "GetPipeSizes\n");
 -
 -
 -   for (n = 0; n < pI830->availablePipes; n++) {
 -      pipe = (pI830->operatingDevices >> PIPE_SHIFT(n)) & PIPE_ACTIVE_MASK;
 -      pI830->pipeDisplaySize[n].x1 = pI830->pipeDisplaySize[n].y1 = 0;
 -      pI830->pipeDisplaySize[n].x2 = pI830->pipeDisplaySize[n].y2 = 4096;
 -      for (i = 0; i < NumDisplayTypes; i++) {
 -         if (pipe & (1 << i) & PIPE_SIZED_DISP_MASK) {
 -	    if (pI830->displaySize[i].x2 != 0) {
 -	       xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 -		          "Size of device %s is %d x %d\n",
 -		          displayDevices[i],
 -		          pI830->displaySize[i].x2,
 -		          pI830->displaySize[i].y2);
 -	       if (pI830->displaySize[i].x2 < pI830->pipeDisplaySize[n].x2)
 -	          pI830->pipeDisplaySize[n].x2 = pI830->displaySize[i].x2;
 -	       if (pI830->displaySize[i].y2 < pI830->pipeDisplaySize[n].y2)
 -	          pI830->pipeDisplaySize[n].y2 = pI830->displaySize[i].y2;
 -	    }
 -         }
 -      }
 -
 -      if (pI830->pipeDisplaySize[n].x2 == 4096)
 -         pI830->pipeDisplaySize[n].x2 = 0;
 -      if (pI830->pipeDisplaySize[n].y2 == 4096)
 -         pI830->pipeDisplaySize[n].y2 = 0;
 -   }
 -}
 -
 -static Bool
 -I830DetectDisplayDevice(ScrnInfoPtr pScrn)
 -{
 -   I830Ptr pI830 = I830PTR(pScrn);
 -   int pipe, n;
 -   DisplayType i;
 -   
 -   /* This seems to lockup some Dell BIOS'. So it's on option to turn on */
 -   if (pI830->displayInfo) {
 -       xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 -		  "Broken BIOSes cause the system to hang here.\n"
 -		  "\t      If you encounter this problem please add \n"
 -		  "\t\t Option \"DisplayInfo\" \"FALSE\"\n"
 -		  "\t      to the Device section of your XF86Config file.\n");
 -      for (i = 0; i < NumDisplayTypes; i++) {
 -         if (GetDisplayInfo(pScrn, 1 << i, &pI830->displayAttached[i],
 -			 &pI830->displayPresent[i],
 -			 &pI830->displaySize[i].x2,
 -			 &pI830->displaySize[i].y2)) {
 -	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 -		    "Display Info: %s: attached: %s, present: %s, size: "
 -		    "(%d,%d)\n", displayDevices[i],
 -		    BOOLTOSTRING(pI830->displayAttached[i]),
 -		    BOOLTOSTRING(pI830->displayPresent[i]),
 -		    pI830->displaySize[i].x2, pI830->displaySize[i].y2);
 -         }
 -      }
 -   }
 -
 -   /* Check for active devices connected to each display pipe. */
 -   for (n = 0; n < pI830->availablePipes; n++) {
 -      pipe = ((pI830->operatingDevices >> PIPE_SHIFT(n)) & PIPE_ACTIVE_MASK);
 -      if (pipe)
 -	 pI830->pipeEnabled[n] = TRUE;
 -      else
 -	 pI830->pipeEnabled[n] = FALSE;
 -   }
 -
 -   GetPipeSizes(pScrn);
 -
 -   return TRUE;
 -}
 -
 -static int
 -I830DetectMemory(ScrnInfoPtr pScrn)
 -{
 -   I830Ptr pI830 = I830PTR(pScrn);
 -   PCITAG bridge;
 -   CARD16 gmch_ctrl;
 -   int memsize = 0;
 -   int range;
 -
 -   bridge = pciTag(0, 0, 0);		/* This is always the host bridge */
 -   gmch_ctrl = pciReadWord(bridge, I830_GMCH_CTRL);
 +   bridge = pciTag(0, 0, 0);		/* This is always the host bridge */
 +   gmch_ctrl = pciReadWord(bridge, I830_GMCH_CTRL);
  
     /* We need to reduce the stolen size, by the GTT and the popup.
 -    * The GTT varying according the the FbMapSize and the popup is 4KB. */
 -   if (IS_I965G(pI830))
 -      range = 512 + 4; /* Fixed 512KB size for i965 */
 -   else
 -      range = (pI830->FbMapSize / MB(1)) + 4;
 +    * The GTT varying according the the FbMapSize and the popup is 4KB */
 +   range = (pI830->FbMapSize / (1024*1024)) + 4;
  
     if (IS_I85X(pI830) || IS_I865G(pI830) || IS_I9XX(pI830)) {
        switch (gmch_ctrl & I830_GMCH_GMS_MASK) {
@@@ -653,85 -3122,378 +644,91 @@@
  	 break;
        case I830_GMCH_GMS_LOCAL:
  	 memsize = 0;
 -	 xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 -		    "Local memory found, but won't be used.\n");
 -	 break;
 -      }
 -   }
 -
 -#if 0
 -   /* And 64KB page aligned */
 -   memsize &= ~0xFFFF;
 -#endif
 -
 -   if (memsize > 0) {
 -      xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 -		 "detected %d kB stolen memory.\n", memsize / 1024);
 -   } else {
 -      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "no video memory detected.\n");
 -   }
 -   return memsize;
 -}
 -
 -static Bool
 -I830MapMMIO(ScrnInfoPtr pScrn)
 -{
 -   int mmioFlags;
 -   I830Ptr pI830 = I830PTR(pScrn);
 -
 -#if !defined(__alpha__)
 -   mmioFlags = VIDMEM_MMIO | VIDMEM_READSIDEEFFECT;
 -#else
 -   mmioFlags = VIDMEM_MMIO | VIDMEM_READSIDEEFFECT | VIDMEM_SPARSE;
 -#endif
 -
 -   pI830->MMIOBase = xf86MapPciMem(pScrn->scrnIndex, mmioFlags,
 -				   pI830->PciTag,
 -				   pI830->MMIOAddr, I810_REG_SIZE);
 -   if (!pI830->MMIOBase)
 -      return FALSE;
 -   return TRUE;
 -}
 -
 -static Bool
 -I830MapMem(ScrnInfoPtr pScrn)
 -{
 -   I830Ptr pI830 = I830PTR(pScrn);
 -   long i;
 -
 -   for (i = 2; i < pI830->FbMapSize; i <<= 1) ;
 -   pI830->FbMapSize = i;
 -
 -   if (!I830MapMMIO(pScrn))
 -      return FALSE;
 -
 -   pI830->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
 -				 pI830->PciTag,
 -				 pI830->LinearAddr, pI830->FbMapSize);
 -   if (!pI830->FbBase)
 -      return FALSE;
 -
 -   if (I830IsPrimary(pScrn))
 -   pI830->LpRing->virtual_start = pI830->FbBase + pI830->LpRing->mem.Start;
 -
 -   return TRUE;
 -}
 -
 -static void
 -I830UnmapMMIO(ScrnInfoPtr pScrn)
 -{
 -   I830Ptr pI830 = I830PTR(pScrn);
 -
 -   xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pI830->MMIOBase,
 -		   I810_REG_SIZE);
 -   pI830->MMIOBase = 0;
 -}
 -
 -static Bool
 -I830UnmapMem(ScrnInfoPtr pScrn)
 -{
 -   I830Ptr pI830 = I830PTR(pScrn);
 -
 -   xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pI830->FbBase,
 -		   pI830->FbMapSize);
 -   pI830->FbBase = 0;
 -   I830UnmapMMIO(pScrn);
 -   return TRUE;
 -}
 -
 -#ifndef HAVE_GET_PUT_BIOSMEMSIZE
 -#define HAVE_GET_PUT_BIOSMEMSIZE 1
 -#endif
 -
 -#if HAVE_GET_PUT_BIOSMEMSIZE
 -/*
 - * Tell the BIOS how much video memory is available.  The BIOS call used
 - * here won't always be available.
 - */
 -static Bool
 -PutBIOSMemSize(ScrnInfoPtr pScrn, int memSize)
 -{
 -   vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe;
 -
 -   DPRINTF(PFX, "PutBIOSMemSize: %d kB\n", memSize / 1024);
 -
 -   pVbe->pInt10->num = 0x10;
 -   pVbe->pInt10->ax = 0x5f11;
 -   pVbe->pInt10->bx = 0;
 -   pVbe->pInt10->cx = memSize / GTT_PAGE_SIZE;
 -
 -   xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);
 -   return Check5fStatus(pScrn, 0x5f11, pVbe->pInt10->ax);
 -}
 -
 -/*
 - * This reports what the previous VBEGetVBEInfo() found.  Be sure to call
 - * VBEGetVBEInfo() after changing the BIOS memory size view.  If
 - * a separate BIOS call is added for this, it can be put here.  Only
 - * return a valid value if the funtionality for PutBIOSMemSize()
 - * is available.
 - */
 -static int
 -GetBIOSMemSize(ScrnInfoPtr pScrn)
 -{
 -   I830Ptr pI830 = I830PTR(pScrn);
 -   int memSize = KB(pI830->vbeInfo->TotalMemory * 64);
 -
 -   DPRINTF(PFX, "GetBIOSMemSize\n");
 -
 -   if (PutBIOSMemSize(pScrn, memSize))
 -      return memSize;
 -   else
 -      return -1;
 -}
 -#endif
 -
 -/*
 - * These three functions allow the video BIOS's view of the available video
 - * memory to be changed.  This is currently implemented only for the 830
 - * and 845G, which can do this via a BIOS scratch register that holds the
 - * BIOS's view of the (pre-reserved) memory size.  If another mechanism
 - * is available in the future, it can be plugged in here.  
 - *
 - * The mapping used for the 830/845G scratch register's low 4 bits is:
 - *
 - *             320k => 0
 - *             832k => 1
 - *            8000k => 8
 - *
 - * The "unusual" values are the 512k, 1M, 8M pre-reserved memory, less
 - * overhead, rounded down to the BIOS-reported 64k granularity.
 - */
 -
 -static Bool
 -SaveBIOSMemSize(ScrnInfoPtr pScrn)
 -{
 -   I830Ptr pI830 = I830PTR(pScrn);
 -
 -   DPRINTF(PFX, "SaveBIOSMemSize\n");
 -
 -   if (!I830IsPrimary(pScrn))
 -      return FALSE;
 -
 -   pI830->useSWF1 = FALSE;
 -
 -#if HAVE_GET_PUT_BIOSMEMSIZE
 -   if ((pI830->saveBIOSMemSize = GetBIOSMemSize(pScrn)) != -1)
 -      return TRUE;
 -#endif
 -
 -   if (IS_I830(pI830) || IS_845G(pI830)) {
 -      pI830->useSWF1 = TRUE;
 -      pI830->saveSWF1 = INREG(SWF1) & 0x0f;
 -
 -      /*
 -       * This is for sample purposes only.  pI830->saveBIOSMemSize isn't used
 -       * when pI830->useSWF1 is TRUE.
 -       */
 -      switch (pI830->saveSWF1) {
 -      case 0:
 -	 pI830->saveBIOSMemSize = KB(320);
 -	 break;
 -      case 1:
 -	 pI830->saveBIOSMemSize = KB(832);
 -	 break;
 -      case 8:
 -	 pI830->saveBIOSMemSize = KB(8000);
 -	 break;
 -      default:
 -	 pI830->saveBIOSMemSize = 0;
 -	 break;
 -      }
 -      return TRUE;
 -   }
 -   return FALSE;
 -}
 -
 -/*
 - * TweakMemorySize() tweaks the BIOS image to set the correct size.
 - * Original implementation by Christian Zietz in a stand-alone tool.
 - */
 -static CARD32
 -TweakMemorySize(ScrnInfoPtr pScrn, CARD32 newsize, Bool preinit)
 -{
 -#define SIZE 0x10000
 -#define _855_IDOFFSET (-23)
 -#define _845_IDOFFSET (-19)
 -    
 -    const char *MAGICstring = "Total time for VGA POST:";
 -    const int len = strlen(MAGICstring);
 -    I830Ptr pI830 = I830PTR(pScrn);
 -    volatile char *position;
 -    char *biosAddr;
 -    CARD32 oldsize;
 -    CARD32 oldpermission;
 -    CARD32 ret = 0;
 -    int i,j = 0;
 -    int reg = (IS_845G(pI830) || IS_I865G(pI830)) ? _845_DRAM_RW_CONTROL
 -	: _855_DRAM_RW_CONTROL;
 -    
 -    PCITAG tag =pciTag(0,0,0);
 -
 -    if (!I830IsPrimary(pScrn))
 -       return 0;
 -
 -    if(!pI830->PciInfo 
 -       || !(IS_845G(pI830) || IS_I85X(pI830) || IS_I865G(pI830)))
 -	return 0;
 -
 -    if (!pI830->pVbe)
 -	return 0;
 -
 -    biosAddr = xf86int10Addr(pI830->pVbe->pInt10, 
 -				    pI830->pVbe->pInt10->BIOSseg << 4);
 -
 -    if (!pI830->BIOSMemSizeLoc) {
 -	if (!preinit)
 -	    return 0;
 -
 -	/* Search for MAGIC string */
 -	for (i = 0; i < SIZE; i++) {
 -	    if (biosAddr[i] == MAGICstring[j]) {
 -		if (++j == len)
 -		    break;
 -	    } else {
 -		i -= j;
 -		j = 0;
 -	    }
 -	}
 -	if (j < len) return 0;
 -
 -	pI830->BIOSMemSizeLoc =  (i - j + 1 + (IS_845G(pI830)
 -					    ? _845_IDOFFSET : _855_IDOFFSET));
 -    }
 -    
 -    position = biosAddr + pI830->BIOSMemSizeLoc;
 -    oldsize = *(CARD32 *)position;
 -
 -    ret = oldsize - 0x21000;
 -    
 -    /* verify that register really contains current size */
 -    if (preinit && ((ret >> 16) !=  pI830->vbeInfo->TotalMemory))
 -	return 0;
 -
 -    oldpermission = pciReadLong(tag, reg);
 -    pciWriteLong(tag, reg, DRAM_WRITE | (oldpermission & 0xffff)); 
 -    
 -    *(CARD32 *)position = newsize + 0x21000;
 -
 -    if (preinit) {
 -	/* reinitialize VBE for new size */
 -	if (I830IsPrimary(pScrn)) {
 -	   VBEFreeVBEInfo(pI830->vbeInfo);
 -	   vbeFree(pI830->pVbe);
 -	   pI830->pVbe = VBEInit(NULL, pI830->pEnt->index);
 -	   pI830->vbeInfo = VBEGetVBEInfo(pI830->pVbe);
 -	} else {
 -           I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
 -           pI830->pVbe = pI8301->pVbe;
 -           pI830->vbeInfo = pI8301->vbeInfo;
 -	}
 -	
 -	/* verify that change was successful */
 -	if (pI830->vbeInfo->TotalMemory != (newsize >> 16)){
 -	    ret = 0;
 -	    *(CARD32 *)position = oldsize;
 -	} else {
 -	    pI830->BIOSMemorySize = KB(pI830->vbeInfo->TotalMemory * 64);
 -	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
 -		       "Tweak BIOS image to %d kB VideoRAM\n",
 -		       (int)(pI830->BIOSMemorySize / 1024));
 -	}
 -    }
 +	 xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 +		    "Local memory found, but won't be used.\n");
 +	 break;
 +      }
 +   }
+ 
 -    pciWriteLong(tag, reg, oldpermission);
++#if 0
++   /* And 64KB page aligned */
++   memsize &= ~0xFFFF;
++#endif
+ 
 -     return ret;
 +   if (memsize > 0) {
 +      xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 +		 "detected %d kB stolen memory.\n", memsize / 1024);
 +   } else {
 +      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "no video memory detected.\n");
 +   }
 +   return memsize;
  }
  
 -static void
 -RestoreBIOSMemSize(ScrnInfoPtr pScrn)
 +static Bool
 +I830MapMMIO(ScrnInfoPtr pScrn)
  {
 +   int mmioFlags;
     I830Ptr pI830 = I830PTR(pScrn);
 -   CARD32 swf1;
 -
 -   DPRINTF(PFX, "RestoreBIOSMemSize\n");
 -
 -   if (!I830IsPrimary(pScrn))
 -      return;
 -
 -   if (TweakMemorySize(pScrn, pI830->saveBIOSMemSize,FALSE))
 -      return;
 -
 -   if (!pI830->overrideBIOSMemSize)
 -      return;
  
 -#if HAVE_GET_PUT_BIOSMEMSIZE
 -   if (!pI830->useSWF1) {
 -      PutBIOSMemSize(pScrn, pI830->saveBIOSMemSize);
 -      return;
 -   }
 +#if !defined(__alpha__)
 +   mmioFlags = VIDMEM_MMIO | VIDMEM_READSIDEEFFECT;
 +#else
 +   mmioFlags = VIDMEM_MMIO | VIDMEM_READSIDEEFFECT | VIDMEM_SPARSE;
  #endif
  
 -   if ((IS_I830(pI830) || IS_845G(pI830)) && pI830->useSWF1) {
 -      swf1 = INREG(SWF1);
 -      swf1 &= ~0x0f;
 -      swf1 |= (pI830->saveSWF1 & 0x0f);
 -      OUTREG(SWF1, swf1);
 -   }
 +   pI830->MMIOBase = xf86MapPciMem(pScrn->scrnIndex, mmioFlags,
 +				   pI830->PciTag,
 +				   pI830->MMIOAddr, I810_REG_SIZE);
 +   if (!pI830->MMIOBase)
 +      return FALSE;
 +   return TRUE;
  }
  
 -static void
 -SetBIOSMemSize(ScrnInfoPtr pScrn, int newSize)
 +static Bool
 +I830MapMem(ScrnInfoPtr pScrn)
  {
     I830Ptr pI830 = I830PTR(pScrn);
 -   unsigned long swf1;
 -   Bool mapped;
 +   long i;
  
 -   DPRINTF(PFX, "SetBIOSMemSize: %d kB\n", newSize / 1024);
 +   for (i = 2; i < pI830->FbMapSize; i <<= 1) ;
 +   pI830->FbMapSize = i;
  
 -   if (!pI830->overrideBIOSMemSize)
 -      return;
 +   if (!I830MapMMIO(pScrn))
 +      return FALSE;
  
 -#if HAVE_GET_PUT_BIOSMEMSIZE
 -   if (!pI830->useSWF1) {
 -      PutBIOSMemSize(pScrn, newSize);
 -      return;
 -   }
 -#endif
 +   pI830->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
 +				 pI830->PciTag,
 +				 pI830->LinearAddr, pI830->FbMapSize);
 +   if (!pI830->FbBase)
 +      return FALSE;
  
 -   if ((IS_I830(pI830) || IS_845G(pI830)) && pI830->useSWF1) {
 -      unsigned long newSWF1;
 +   if (I830IsPrimary(pScrn))
 +   pI830->LpRing->virtual_start = pI830->FbBase + pI830->LpRing->mem.Start;
  
 -      /* Need MMIO access here. */
 -      mapped = (pI830->MMIOBase != NULL);
 -      if (!mapped)
 -	 I830MapMMIO(pScrn);
 +   return TRUE;
 +}
  
 -      if (newSize <= KB(832))
 -	 newSWF1 = 1;
 -      else
 -	 newSWF1 = 8;
 +static void
 +I830UnmapMMIO(ScrnInfoPtr pScrn)
 +{
 +   I830Ptr pI830 = I830PTR(pScrn);
  
 -      swf1 = INREG(SWF1);
 -      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Before: SWF1 is 0x%08lx\n", swf1);
 -      swf1 &= ~0x0f;
 -      swf1 |= (newSWF1 & 0x0f);
 -      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "After: SWF1 is 0x%08lx\n", swf1);
 -      OUTREG(SWF1, swf1);
 -      if (!mapped)
 -	 I830UnmapMMIO(pScrn);
 -   }
 +   xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pI830->MMIOBase,
 +		   I810_REG_SIZE);
 +   pI830->MMIOBase = 0;
  }
  
 -static CARD32 val8[256];
 +static Bool
 +I830UnmapMem(ScrnInfoPtr pScrn)
 +{
 +   I830Ptr pI830 = I830PTR(pScrn);
 +
 +   xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pI830->FbBase,
 +		   pI830->FbMapSize);
 +   pI830->FbBase = 0;
 +   I830UnmapMMIO(pScrn);
 +   return TRUE;
 +}
  
  static void
  I830LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
@@@ -742,8 -3504,7 +739,8 @@@
     unsigned char r, g, b;
     CARD32 val, temp;
     int palreg;
-    int dspreg, dspbase;
+    int dspreg, dspbase, dspsurf;
 +   int p;
  
     DPRINTF(PFX, "I830LoadPalette: numColors: %d\n", numColors);
     pI830 = I830PTR(pScrn);
@@@ -754,23 -3514,18 +751,27 @@@
           palreg = PALETTE_A;
           dspreg = DSPACNTR;
           dspbase = DSPABASE;
++	 dspsurf = DSPASURF;
        } else {
           palreg = PALETTE_B;
           dspreg = DSPBCNTR;
           dspbase = DSPBBASE;
++	 dspsurf = DSPBSURF;
        }
 -   
 +
 +      if (pI830->planeEnabled[p] == 0)
 +	 continue;  
 +
 +      pI830->gammaEnabled[p] = 1;
 +      
        /* To ensure gamma is enabled we need to turn off and on the plane */
        temp = INREG(dspreg);
        OUTREG(dspreg, temp & ~(1<<31));
        OUTREG(dspbase, INREG(dspbase));
        OUTREG(dspreg, temp | DISPPLANE_GAMMA_ENABLE);
        OUTREG(dspbase, INREG(dspbase));
++      if (IS_I965G(pI830))
++	 OUTREG(dspsurf, INREG(dspsurf));
  
        /* It seems that an initial read is needed. */
        temp = INREG(palreg);
@@@ -1339,9 -4044,10 +1350,10 @@@
        from = X_CONFIG;
        xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n",
  		 pI830->pEnt->device->chipID);
+       pI830->PciInfo->chipType = pI830->pEnt->device->chipID;
     } else {
        from = X_PROBED;
 -      pScrn->chipset = (char *)xf86TokenToString(I830BIOSChipsets,
 +      pScrn->chipset = (char *)xf86TokenToString(I830Chipsets,
  						 pI830->PciInfo->chipType);
     }
  
@@@ -1516,10 -4222,13 +1528,13 @@@
  #endif
  
     pI830->LinearAlloc = 0;
 -   if (xf86GetOptValInteger(pI830->Options, OPTION_LINEARALLOC,
 +   if (xf86GetOptValULong(pI830->Options, OPTION_LINEARALLOC,
  			    &(pI830->LinearAlloc))) {
-       xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Allocating %luKbytes of memory\n",
+       if (pI830->LinearAlloc > 0)
 -         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Allocating %dKbytes of memory\n",
++         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Allocating %luKbytes of memory\n",
  		 pI830->LinearAlloc);
+       else 
+          pI830->LinearAlloc = 0;
     }
  
     pI830->fixedPipe = -1;
@@@ -1755,10 -4365,18 +1770,17 @@@
        return FALSE;
     }
  
 -   if ((pI830->entityPrivate && I830IsPrimary(pScrn)) || pI830->Clone ||
 -	pI830->MergedFB) {
 +   if ((pI830->entityPrivate && I830IsPrimary(pScrn)) || pI830->Clone) {
+       if ((!xf86GetOptValString(pI830->Options, OPTION_MONITOR_LAYOUT))) {
+ 	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "You must have a MonitorLayout "
+ 	 		"defined for use in a DualHead, Clone or MergedFB setup.\n");
+          PreInitCleanup(pScrn);
+          return FALSE;
+       }
 -         
++
        if (pI830->MonType1 == PIPE_NONE || pI830->MonType2 == PIPE_NONE) {
           xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Monitor 1 or Monitor 2 "
- 	 		"cannot be type NONE in Dual or Clone setup.\n");
 -	 		"cannot be type NONE in DualHead, Clone or MergedFB setup.\n");
++	 		"cannot be type NONE in DualHead or Clone setup.\n");
           PreInitCleanup(pScrn);
           return FALSE;
        }
@@@ -2394,205 -5661,451 +2430,220 @@@
     OUTREG(LP_RING + RING_START, 0);
    
     if (pI830->CursorInfoRec && pI830->CursorInfoRec->HideCursor)
 -      pI830->CursorInfoRec->HideCursor(pScrn);
 -}
 -
 -static void
 -SetFenceRegs(ScrnInfoPtr pScrn)
 -{
 -   I830Ptr pI830 = I830PTR(pScrn);
 -   int i;
 -
 -   DPRINTF(PFX, "SetFenceRegs\n");
 -
 -   if (!I830IsPrimary(pScrn)) return;
 -
 -   if (IS_I965G(pI830)) {
 -      for (i = 0; i < FENCE_NEW_NR; i++) {
 -         OUTREG(FENCE_NEW + i * 8, pI830->ModeReg.Fence[i]);
 -         OUTREG(FENCE_NEW + 4 + i * 8, pI830->ModeReg.Fence[i+FENCE_NEW_NR]);
 -         if (I810_DEBUG & DEBUG_VERBOSE_VGA) {
 -	    ErrorF("Fence Start Register : %x\n", pI830->ModeReg.Fence[i]);
 -	    ErrorF("Fence End Register : %x\n", pI830->ModeReg.Fence[i+FENCE_NEW_NR]);
 -         }
 -      }
 -   } else {
 -      for (i = 0; i < FENCE_NR; i++) {
 -         OUTREG(FENCE + i * 4, pI830->ModeReg.Fence[i]);
 -         if (I810_DEBUG & DEBUG_VERBOSE_VGA)
 -	    ErrorF("Fence Register : %x\n", pI830->ModeReg.Fence[i]);
 -      }
 -   }
 -}
 -
 -static void
 -SetRingRegs(ScrnInfoPtr pScrn)
 -{
 -   I830Ptr pI830 = I830PTR(pScrn);
 -   unsigned int itemp;
 -
 -   DPRINTF(PFX, "SetRingRegs\n");
 -
 -   if (pI830->noAccel)
 -      return;
 -
 -   if (!I830IsPrimary(pScrn)) return;
 -
 -   if (pI830->entityPrivate)
 -      pI830->entityPrivate->RingRunning = 1;
 -
 -   OUTREG(LP_RING + RING_LEN, 0);
 -   OUTREG(LP_RING + RING_TAIL, 0);
 -   OUTREG(LP_RING + RING_HEAD, 0);
 -
 -   if ((long)(pI830->LpRing->mem.Start & I830_RING_START_MASK) !=
 -       pI830->LpRing->mem.Start) {
 -      xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 -		 "I830SetRingRegs: Ring buffer start (%lx) violates its "
 -		 "mask (%x)\n", pI830->LpRing->mem.Start, I830_RING_START_MASK);
 -   }
 -   /* Don't care about the old value.  Reserved bits must be zero anyway. */
 -   itemp = pI830->LpRing->mem.Start & I830_RING_START_MASK;
 -   OUTREG(LP_RING + RING_START, itemp);
 -
 -   if (((pI830->LpRing->mem.Size - 4096) & I830_RING_NR_PAGES) !=
 -       pI830->LpRing->mem.Size - 4096) {
 -      xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 -		 "I830SetRingRegs: Ring buffer size - 4096 (%lx) violates its "
 -		 "mask (%x)\n", pI830->LpRing->mem.Size - 4096,
 -		 I830_RING_NR_PAGES);
 -   }
 -   /* Don't care about the old value.  Reserved bits must be zero anyway. */
 -   itemp = (pI830->LpRing->mem.Size - 4096) & I830_RING_NR_PAGES;
 -   itemp |= (RING_NO_REPORT | RING_VALID);
 -   OUTREG(LP_RING + RING_LEN, itemp);
 -   I830RefreshRing(pScrn);
 -}
 -
 -/*
 - * This should be called everytime the X server gains control of the screen,
 - * before any video modes are programmed (ScreenInit, EnterVT).
 - */
 -static void
 -SetHWOperatingState(ScrnInfoPtr pScrn)
 -{
 -   I830Ptr pI830 = I830PTR(pScrn);
 -
 -   DPRINTF(PFX, "SetHWOperatingState\n");
 -
 -   if (!pI830->noAccel)
 -      SetRingRegs(pScrn);
 -   SetFenceRegs(pScrn);
 -   if (!pI830->SWCursor)
 -      I830InitHWCursor(pScrn);
 -}
 -
 -static Bool
 -SaveHWState(ScrnInfoPtr pScrn)
 -{
 -   I830Ptr pI830 = I830PTR(pScrn);
 -   vbeInfoPtr pVbe = pI830->pVbe;
 -   vgaHWPtr hwp = VGAHWPTR(pScrn);
 -   vgaRegPtr vgaReg = &hwp->SavedReg;
 -   VbeModeInfoBlock *modeInfo;
 -   VESAPtr pVesa;
 -
 -   DPRINTF(PFX, "SaveHWState\n");
 -
 -   if (I830IsPrimary(pScrn) && pI830->pipe != pI830->origPipe)
 -      SetBIOSPipe(pScrn, pI830->origPipe);
 -   else
 -      SetPipeAccess(pScrn);
 -
 -   pVesa = pI830->vesa;
 -
 -   /* Make sure we save at least this information in case of failure. */
 -   VBEGetVBEMode(pVbe, &pVesa->stateMode);
 -   pVesa->stateRefresh = GetRefreshRate(pScrn, pVesa->stateMode, NULL);
 -   modeInfo = VBEGetModeInfo(pVbe, pVesa->stateMode);
 -   pVesa->savedScanlinePitch = 0;
 -   if (modeInfo) {
 -      if (VBE_MODE_GRAPHICS(modeInfo)) {
 -         VBEGetLogicalScanline(pVbe, &pVesa->savedScanlinePitch, NULL, NULL);
 -      }
 -      VBEFreeModeInfo(modeInfo);
 -   }
 -
 -   vgaHWUnlock(hwp);
 -   vgaHWSave(pScrn, vgaReg, VGA_SR_FONTS);
 -
 -   pVesa = pI830->vesa;
 -
 -   if (IS_I965G(pI830)) {
 -      pI830->savedAsurf = INREG(DSPASURF);
 -      pI830->savedBsurf = INREG(DSPBSURF);
 -   }
 -
 -   /*
 -    * This save/restore method doesn't work for 845G BIOS, or for some
 -    * other platforms.  Enable it in all cases.
 -    */
 -   /*
 -    * KW: This may have been because of the behaviour I've found on my
 -    * board: The 'save' command actually modifies the interrupt
 -    * registers, turning off the irq & breaking the kernel module
 -    * behaviour.
 -    */
 -   if (!pI830->vbeRestoreWorkaround) {
 -      CARD16 imr = INREG16(IMR);
 -      CARD16 ier = INREG16(IER);
 -      CARD16 hwstam = INREG16(HWSTAM);
 -
 -      if (!VBESaveRestore(pVbe, MODE_SAVE, &pVesa->state, &pVesa->stateSize,
 -			  &pVesa->statePage)) {
 -	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 -		    "SaveHWState: VBESaveRestore(MODE_SAVE) failed.\n");
 -	 return FALSE;
 -      }
 -
 -      OUTREG16(IMR, imr);
 -      OUTREG16(IER, ier);
 -      OUTREG16(HWSTAM, hwstam);
 -   }
 -
 -   pVesa->savedPal = VBESetGetPaletteData(pVbe, FALSE, 0, 256,
 -					     NULL, FALSE, FALSE);
 -   if (!pVesa->savedPal) {
 -      xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 -		 "SaveHWState: VBESetGetPaletteData(GET) failed.\n");
 -      return FALSE;
 -   }
 -
 -   VBEGetDisplayStart(pVbe, &pVesa->x, &pVesa->y);
 -
 -   return TRUE;
 -}
 -
 -static Bool
 -RestoreHWState(ScrnInfoPtr pScrn)
 -{
 -   I830Ptr pI830 = I830PTR(pScrn);
 -   vbeInfoPtr pVbe = pI830->pVbe;
 -   vgaHWPtr hwp = VGAHWPTR(pScrn);
 -   vgaRegPtr vgaReg = &hwp->SavedReg;
 -   VESAPtr pVesa;
 -   Bool restored = FALSE;
 -
 -   DPRINTF(PFX, "RestoreHWState\n");
 -
 -   if (I830IsPrimary(pScrn) && pI830->pipe != pI830->origPipe)
 -      SetBIOSPipe(pScrn, pI830->origPipe);
 -   else
 -      SetPipeAccess(pScrn);
 -
 -   pVesa = pI830->vesa;
 -
 -   /*
 -    * Workaround for text mode restoration with some flat panels.
 -    * Temporarily program a 640x480 mode before switching back to
 -    * text mode.
 -    */
 -   if (pVesa->useDefaultRefresh)
 -      I830Set640x480(pScrn);
 -
 -   if (pVesa->state && pVesa->stateSize) {
 -      CARD16 imr = INREG16(IMR);
 -      CARD16 ier = INREG16(IER);
 -      CARD16 hwstam = INREG16(HWSTAM);
 -
 -      /* Make a copy of the state.  Don't rely on it not being touched. */
 -      if (!pVesa->pstate) {
 -	 pVesa->pstate = xalloc(pVesa->stateSize);
 -	 if (pVesa->pstate)
 -	    memcpy(pVesa->pstate, pVesa->state, pVesa->stateSize);
 -      }
 -      restored = VBESaveRestore(pVbe, MODE_RESTORE, &pVesa->state,
 -				   &pVesa->stateSize, &pVesa->statePage);
 -      if (!restored) {
 -	 xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 -		    "RestoreHWState: VBESaveRestore failed.\n");
 -      }
 -      /* Copy back */
 -      if (pVesa->pstate)
 -	 memcpy(pVesa->state, pVesa->pstate, pVesa->stateSize);
 -
 -      OUTREG16(IMR, imr);
 -      OUTREG16(IER, ier);
 -      OUTREG16(HWSTAM, hwstam);
 -   }
 -   /* If that failed, restore the original mode. */
 -   if (!restored) {
 -      xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 -		 "Setting the original video mode instead of restoring\n\t"
 -		 "the saved state\n");
 -      I830VESASetVBEMode(pScrn, pVesa->stateMode, NULL);
 -      if (!pVesa->useDefaultRefresh && pI830->useExtendedRefresh) {
 -         SetRefreshRate(pScrn, pVesa->stateMode, pVesa->stateRefresh);
 -      }
 -   }
 -   if (pVesa->savedScanlinePitch)
 -       VBESetLogicalScanline(pVbe, pVesa->savedScanlinePitch);
 -
 -   if (pVesa->savedPal)
 -      VBESetGetPaletteData(pVbe, TRUE, 0, 256, pVesa->savedPal, FALSE, TRUE);
 -
 -   VBESetDisplayStart(pVbe, pVesa->x, pVesa->y, TRUE);
 -
 -   if (IS_I965G(pI830)) {
 -      OUTREG(DSPASURF, pI830->savedAsurf);
 -      OUTREG(DSPBSURF, pI830->savedBsurf);
 -   }
 -
 -   vgaHWRestore(pScrn, vgaReg, VGA_SR_FONTS);
 -   vgaHWLock(hwp);
 -
 -   return TRUE;
 +      pI830->CursorInfoRec->HideCursor(pScrn);
  }
  
 -static void I830SetCloneVBERefresh(ScrnInfoPtr pScrn, int mode, VbeCRTCInfoBlock * block, int refresh)
 +static void
 +SetFenceRegs(ScrnInfoPtr pScrn)
  {
     I830Ptr pI830 = I830PTR(pScrn);
 -   DisplayModePtr p = NULL;
 -   int RefreshRate;
 -   int clock;
 -
 -   /* Search for our mode and get a refresh to match */
 -   for (p = pScrn->monitor->Modes; p != NULL; p = p->next) {
 -      if ((p->HDisplay != pI830->CloneHDisplay) ||
 -          (p->VDisplay != pI830->CloneVDisplay) ||
 -          (p->Flags & (V_INTERLACE | V_DBLSCAN | V_CLKDIV2)))
 -         continue;
 -      RefreshRate = ((double)(p->Clock * 1000) /
 -                     (double)(p->HTotal * p->VTotal)) * 100;
 -      /* we could probably do better here that 2Hz boundaries */
 -      if (RefreshRate > (refresh - 200) && RefreshRate < (refresh + 200)) {
 -         block->HorizontalTotal = p->HTotal;
 -         block->HorizontalSyncStart = p->HSyncStart;
 -         block->HorizontalSyncEnd = p->HSyncEnd;
 -         block->VerticalTotal = p->VTotal;
 -         block->VerticalSyncStart = p->VSyncStart;
 -         block->VerticalSyncEnd = p->VSyncEnd;
 -         block->Flags = ((p->Flags & V_NHSYNC) ? CRTC_NHSYNC : 0) |
 -                        ((p->Flags & V_NVSYNC) ? CRTC_NVSYNC : 0);
 -         block->PixelClock = p->Clock * 1000;
 -         /* XXX May not have this. */
 -         clock = VBEGetPixelClock(pI830->pVbe, mode, block->PixelClock);
 -#ifdef DEBUG
 -         ErrorF("Setting clock %.2fMHz, closest is %.2fMHz\n",
 -                    (double)data->block->PixelClock / 1000000.0, 
 -                    (double)clock / 1000000.0);
 -#endif
 -         if (clock)
 -            block->PixelClock = clock;
 -         block->RefreshRate = RefreshRate;
 -         return;
 +   int i;
 +
 +   DPRINTF(PFX, "SetFenceRegs\n");
 +
 +   if (!I830IsPrimary(pScrn)) return;
 +
-    for (i = 0; i < 8; i++) {
-       OUTREG(FENCE + i * 4, pI830->ModeReg.Fence[i]);
-       if (I810_DEBUG & DEBUG_VERBOSE_VGA)
- 	 ErrorF("Fence Register : %x\n", pI830->ModeReg.Fence[i]);
++   if (IS_I965G(pI830)) {
++      for (i = 0; i < FENCE_NEW_NR; i++) {
++         OUTREG(FENCE_NEW + i * 8, pI830->ModeReg.Fence[i]);
++         OUTREG(FENCE_NEW + 4 + i * 8, pI830->ModeReg.Fence[i+FENCE_NEW_NR]);
++         if (I810_DEBUG & DEBUG_VERBOSE_VGA) {
++	    ErrorF("Fence Start Register : %x\n", pI830->ModeReg.Fence[i]);
++	    ErrorF("Fence End Register : %x\n", pI830->ModeReg.Fence[i+FENCE_NEW_NR]);
++         }
++      }
++   } else {
++      for (i = 0; i < FENCE_NR; i++) {
++         OUTREG(FENCE + i * 4, pI830->ModeReg.Fence[i]);
++         if (I810_DEBUG & DEBUG_VERBOSE_VGA)
++	    ErrorF("Fence Register : %x\n", pI830->ModeReg.Fence[i]);
+       }
     }
  }
  
 -static Bool
 -I830VESASetVBEMode(ScrnInfoPtr pScrn, int mode, VbeCRTCInfoBlock * block)
 +static void
 +SetRingRegs(ScrnInfoPtr pScrn)
  {
     I830Ptr pI830 = I830PTR(pScrn);
 -   Bool ret = FALSE;
 -   int Mon;
 -
 -   DPRINTF(PFX, "Setting mode 0x%.8x\n", mode);
 -
 -#if 0
 -   /* Clear the framebuffer (could do this with VBIOS call) */
 -   if (I830IsPrimary(pScrn))
 -      memset(pI830->FbBase + pI830->FrontBuffer.Start, 0,
 -	  pScrn->virtualY * pI830->displayWidth * pI830->cpp);
 -   else
 -      memset(pI830->FbBase + pI830->FrontBuffer2.Start, 0,
 -	  pScrn->virtualY * pI830->displayWidth * pI830->cpp);
 -#endif
 -
 -   if (pI830->Clone && 
 -	pI830->CloneHDisplay && pI830->CloneVDisplay &&
 -       !pI830->preinit && !pI830->closing) {
 -      VbeCRTCInfoBlock newblock;
 -      int newmode = mode;
 -
 -      if (pI830->pipe == 1)
 -         Mon = pI830->MonType1;
 -      else
 -         Mon = pI830->MonType2;
 +   unsigned int itemp;
  
 -      SetBIOSPipe(pScrn, !pI830->pipe);
 +   DPRINTF(PFX, "SetRingRegs\n");
  
 -      /* Now recheck refresh operations we can use */
 -      pI830->useExtendedRefresh = FALSE;
 -      pI830->vesa->useDefaultRefresh = FALSE;
 +   if (pI830->noAccel)
 +      return;
  
 -      if (Mon != PIPE_CRT) {
 -	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 -		    "A non-CRT device is attached to Clone pipe %c.\n"
 -		    "\tNo refresh rate overrides will be attempted (0x%x).\n",
 -		    PIPE_NAME(!pI830->pipe), newmode);
 -	 pI830->vesa->useDefaultRefresh = TRUE;
 -      }
 -      /*
 -       * Some desktop platforms might not have 0x5f05, so useExtendedRefresh
 -       * would need to be set to FALSE for those cases.
 -       */
 -      if (!pI830->vesa->useDefaultRefresh) 
 -	 pI830->useExtendedRefresh = TRUE;
 +   if (!I830IsPrimary(pScrn)) return;
  
 -      newmode |= 1 << 11;
 -      if (pI830->vesa->useDefaultRefresh)
 -            newmode &= ~(1 << 11);
 +   if (pI830->entityPrivate)
 +      pI830->entityPrivate->RingRunning = 1;
  
 -      if (!SetRefreshRate(pScrn, newmode, 60)) {
 -	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 -		    "BIOS call 0x5f05 not supported on Clone Head, "
 -		    "setting refresh with VBE 3 method.\n");
 -	 pI830->useExtendedRefresh = FALSE;
 -      }
 +   OUTREG(LP_RING + RING_LEN, 0);
 +   OUTREG(LP_RING + RING_TAIL, 0);
 +   OUTREG(LP_RING + RING_HEAD, 0);
  
 -      if (!pI830->vesa->useDefaultRefresh) {
 -         I830SetCloneVBERefresh(pScrn, newmode, &newblock, pI830->CloneRefresh * 100);
 -
 -         if (!VBESetVBEMode(pI830->pVbe, newmode, &newblock)) {
 -            if (!VBESetVBEMode(pI830->pVbe, (newmode & ~(1 << 11)), NULL))
 -               xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 -		 "Failed to set mode for Clone head.\n");
 -         } else {
 -            xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 -		 "Setting refresh on clone head with VBE 3 method.\n");
 -            pI830->useExtendedRefresh = FALSE;
 -         }
 -      } else {
 -         if (!VBESetVBEMode(pI830->pVbe, (newmode & ~(1 << 11)), NULL))
 -            xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 -		 "Failed to set mode for Clone head.\n");
 -      }
 +   if ((long)(pI830->LpRing->mem.Start & I830_RING_START_MASK) !=
 +       pI830->LpRing->mem.Start) {
 +      xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 +		 "I830SetRingRegs: Ring buffer start (%lx) violates its "
 +		 "mask (%x)\n", pI830->LpRing->mem.Start, I830_RING_START_MASK);
 +   }
 +   /* Don't care about the old value.  Reserved bits must be zero anyway. */
 +   itemp = pI830->LpRing->mem.Start & I830_RING_START_MASK;
 +   OUTREG(LP_RING + RING_START, itemp);
  
 -      if (pI830->useExtendedRefresh && !pI830->vesa->useDefaultRefresh) {
 -         if (!SetRefreshRate(pScrn, newmode, pI830->CloneRefresh))
 -	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 -		    "Failed to set refresh rate to %dHz on Clone head.\n",
 -		    pI830->CloneRefresh);
 -         else
 -	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 -		    "Set refresh rate to %dHz on Clone head.\n",
 -		    pI830->CloneRefresh);
 -      }
 -      SetPipeAccess(pScrn);
 +   if (((pI830->LpRing->mem.Size - 4096) & I830_RING_NR_PAGES) !=
 +       pI830->LpRing->mem.Size - 4096) {
 +      xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 +		 "I830SetRingRegs: Ring buffer size - 4096 (%lx) violates its "
 +		 "mask (%x)\n", pI830->LpRing->mem.Size - 4096,
 +		 I830_RING_NR_PAGES);
     }
 +   /* Don't care about the old value.  Reserved bits must be zero anyway. */
 +   itemp = (pI830->LpRing->mem.Size - 4096) & I830_RING_NR_PAGES;
 +   itemp |= (RING_NO_REPORT | RING_VALID);
 +   OUTREG(LP_RING + RING_LEN, itemp);
 +   I830RefreshRing(pScrn);
 +}
  
 -   if (pI830->pipe == 0)
 -      Mon = pI830->MonType1;
 -   else
 -      Mon = pI830->MonType2;
 +/*
 + * This should be called everytime the X server gains control of the screen,
 + * before any video modes are programmed (ScreenInit, EnterVT).
 + */
 +static void
 +SetHWOperatingState(ScrnInfoPtr pScrn)
 +{
 +   I830Ptr pI830 = I830PTR(pScrn);
  
 +   DPRINTF(PFX, "SetHWOperatingState\n");
  
 -   /* Now recheck refresh operations we can use */
 -   pI830->useExtendedRefresh = FALSE;
 -   pI830->vesa->useDefaultRefresh = FALSE;
 +   if (!pI830->noAccel)
 +      SetRingRegs(pScrn);
 +   SetFenceRegs(pScrn);
 +   if (!pI830->SWCursor)
 +      I830InitHWCursor(pScrn);
 +}
  
 -   if (Mon != PIPE_CRT) {
 -      xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
 -		    "A non-CRT device is attached to pipe %c.\n"
 -		    "\tNo refresh rate overrides will be attempted.\n",
 -		    PIPE_NAME(pI830->pipe));
 -      pI830->vesa->useDefaultRefresh = TRUE;
 -   }
 +static Bool
 +SaveHWState(ScrnInfoPtr pScrn)
 +{
 +   I830Ptr pI830 = I830PTR(pScrn);
 +   vgaHWPtr hwp = VGAHWPTR(pScrn);
 +   vgaRegPtr vgaReg = &hwp->SavedReg;
 +   CARD32 temp;
 +   int i;
  
 -   mode |= 1 << 11;
 -   if (pI830->vesa->useDefaultRefresh)
 -      mode &= ~(1 << 11);
     /*
 -    * Some desktop platforms might not have 0x5f05, so useExtendedRefresh
 -    * would need to be set to FALSE for those cases.
 +    * Print out the PIPEACONF and PIPEBCONF registers.
      */
 -   if (!pI830->vesa->useDefaultRefresh) 
 -      pI830->useExtendedRefresh = TRUE;
 -
 -   if (!SetRefreshRate(pScrn, mode, 60)) {
 -      xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 -		    "BIOS call 0x5f05 not supported, "
 -		    "setting refresh with VBE 3 method.\n");
 -      pI830->useExtendedRefresh = FALSE;
 +   temp = INREG(PIPEACONF);
 +   xf86DrvMsg(pScrn->scrnIndex, X_INFO, "PIPEACONF is 0x%08lx\n", 
 +	      (unsigned long) temp);
 +   if (pI830->availablePipes == 2) {
 +      temp = INREG(PIPEBCONF);
 +      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "PIPEBCONF is 0x%08lx\n", 
 +		 (unsigned long) temp);
     }
  
 -   if (!pI830->vesa->useDefaultRefresh && block) {
 -      ret = VBESetVBEMode(pI830->pVbe, mode, block);
 -      if (!ret)
 -         ret = VBESetVBEMode(pI830->pVbe, (mode & ~(1 << 11)), NULL);
 -      else {
 -         xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 -		 "Setting refresh with VBE 3 method.\n");
 -	 pI830->useExtendedRefresh = FALSE;
 +   i830TakeRegSnapshot(pScrn);
 +
 +   /* Save video mode information for native mode-setting. */
 +   pI830->saveDSPACNTR = INREG(DSPACNTR);
 +   pI830->savePIPEACONF = INREG(PIPEACONF);
 +   pI830->savePIPEASRC = INREG(PIPEASRC);
 +   pI830->saveFPA0 = INREG(FPA0);
 +   pI830->saveFPA1 = INREG(FPA1);
 +   pI830->saveDPLL_A = INREG(DPLL_A);
 +   pI830->saveHTOTAL_A = INREG(HTOTAL_A);
 +   pI830->saveHBLANK_A = INREG(HBLANK_A);
 +   pI830->saveHSYNC_A = INREG(HSYNC_A);
 +   pI830->saveVTOTAL_A = INREG(VTOTAL_A);
 +   pI830->saveVBLANK_A = INREG(VBLANK_A);
 +   pI830->saveVSYNC_A = INREG(VSYNC_A);
 +   pI830->saveDSPASTRIDE = INREG(DSPASTRIDE);
 +   pI830->saveDSPASIZE = INREG(DSPASIZE);
 +   pI830->saveDSPAPOS = INREG(DSPAPOS);
 +   pI830->saveDSPABASE = INREG(DSPABASE);
 +
 +   for(i= 0; i < 256; i++) {
 +      pI830->savePaletteA[i] = INREG(PALETTE_A + (i << 2));
 +   }
 +
 +   if(pI830->availablePipes == 2) {
 +      pI830->savePIPEBCONF = INREG(PIPEBCONF);
 +      pI830->savePIPEBSRC = INREG(PIPEBSRC);
 +      pI830->saveDSPBCNTR = INREG(DSPBCNTR);
 +      pI830->saveFPB0 = INREG(FPB0);
 +      pI830->saveFPB1 = INREG(FPB1);
 +      pI830->saveDPLL_B = INREG(DPLL_B);
 +      pI830->saveHTOTAL_B = INREG(HTOTAL_B);
 +      pI830->saveHBLANK_B = INREG(HBLANK_B);
 +      pI830->saveHSYNC_B = INREG(HSYNC_B);
 +      pI830->saveVTOTAL_B = INREG(VTOTAL_B);
 +      pI830->saveVBLANK_B = INREG(VBLANK_B);
 +      pI830->saveVSYNC_B = INREG(VSYNC_B);
 +      pI830->saveDSPBSTRIDE = INREG(DSPBSTRIDE);
 +      pI830->saveDSPBSIZE = INREG(DSPBSIZE);
 +      pI830->saveDSPBPOS = INREG(DSPBPOS);
 +      pI830->saveDSPBBASE = INREG(DSPBBASE);
 +      for(i= 0; i < 256; i++) {
 +         pI830->savePaletteB[i] = INREG(PALETTE_B + (i << 2));
        }
 -   } else {
 -      ret = VBESetVBEMode(pI830->pVbe, (mode & ~(1 << 11)), NULL);
     }
  
 -   /* Might as well bail now if we've failed */
 -   if (!ret) return FALSE;
++   if (IS_I965G(pI830)) {
++      pI830->saveDSPASURF = INREG(DSPASURF);
++      pI830->saveDSPBSURF = INREG(DSPBSURF);
++   }
+ 
 -   if (pI830->useExtendedRefresh && !pI830->vesa->useDefaultRefresh && block) {
 -      if (!SetRefreshRate(pScrn, mode, block->RefreshRate / 100)) {
 -	 xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 -		    "Failed to set refresh rate to %dHz.\n",
 -		    block->RefreshRate / 100);
 -	 pI830->useExtendedRefresh = FALSE;
 +   pI830->saveVCLK_DIVISOR_VGA0 = INREG(VCLK_DIVISOR_VGA0);
 +   pI830->saveVCLK_DIVISOR_VGA1 = INREG(VCLK_DIVISOR_VGA1);
 +   pI830->saveVCLK_POST_DIV = INREG(VCLK_POST_DIV);
 +   pI830->saveVGACNTRL = INREG(VGACNTRL);
 +
 +   pI830->saveADPA = INREG(ADPA);
 +
 +   pI830->savePFIT_CONTROL = INREG(PFIT_CONTROL);
 +   pI830->savePP_ON = INREG(LVDSPP_ON);
 +   pI830->savePP_OFF = INREG(LVDSPP_OFF);
 +   pI830->saveLVDS = INREG(LVDS);
 +   pI830->savePP_CONTROL = INREG(PP_CONTROL);
 +   pI830->savePP_CYCLE = INREG(PP_CYCLE);
 +   pI830->saveBLC_PWM_CTL = INREG(BLC_PWM_CTL);
 +   pI830->backlight_duty_cycle = (pI830->saveBLC_PWM_CTL & 
 +				  BACKLIGHT_DUTY_CYCLE_MASK);
 +   /*
 +    * If the light is off at server startup, just make it full brightness
 +    */
 +   if (!pI830->backlight_duty_cycle)
 +      pI830->backlight_duty_cycle = ((pI830->saveBLC_PWM_CTL &
 +				      BACKLIGHT_MODULATION_FREQ_MASK) >>
 +				     BACKLIGHT_MODULATION_FREQ_SHIFT);
-     
 +
 +   if (!IS_I9XX(pI830)) {
 +      pI830->saveDVOA = INREG(DVOA);
 +      pI830->saveDVOB = INREG(DVOB);
 +      pI830->saveDVOC = INREG(DVOC);
 +   }
 +
 +   for(i = 0; i < 7; i++) {
 +      pI830->saveSWF[i] = INREG(SWF0 + (i << 2));
 +      pI830->saveSWF[i+7] = INREG(SWF00 + (i << 2));
 +   }
 +   pI830->saveSWF[14] = INREG(SWF30);
 +   pI830->saveSWF[15] = INREG(SWF31);
 +   pI830->saveSWF[16] = INREG(SWF32);
 +
 +   for (i = 0; i < pI830->num_outputs; i++) {
 +      if (pI830->output[i].type == I830_OUTPUT_DVO &&
 +	  pI830->output[i].i2c_drv != NULL)
 +      {
 +	 pI830->output[i].i2c_drv->vid_rec->SaveRegs(
 +	    pI830->output[i].i2c_drv->dev_priv);
 +      }
 +      if (pI830->output[i].type == I830_OUTPUT_SDVO &&
 +	  pI830->output[i].sdvo_drv != NULL)
 +      {
 +	 i830SDVOSave(pScrn, i);
        }
     }
  
@@@ -2603,121 -6113,409 +2654,126 @@@
  }
  
  static Bool
 -I830VESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
 +RestoreHWState(ScrnInfoPtr pScrn)
  {
     I830Ptr pI830 = I830PTR(pScrn);
 -   vbeInfoPtr pVbe = pI830->pVbe;
 -   I830ModePrivatePtr mp = (I830ModePrivatePtr) pMode->Private;
 -   int mode, i;
 -   CARD32 planeA, planeB, temp;
 -   int refresh = 60;
 -#ifdef XF86DRI
 -   Bool didLock = FALSE;
 -#endif
 -
 -   DPRINTF(PFX, "I830VESASetMode\n");
 +   vgaHWPtr hwp = VGAHWPTR(pScrn);
 +   vgaRegPtr vgaReg = &hwp->SavedReg;
 +   CARD32 temp;
 +   int i;
  
 -   /* Always Enable Linear Addressing */
 -   mode = mp->vbeData.mode | (1 << 15) | (1 << 14);
 +   DPRINTF(PFX, "RestoreHWState\n");
  
  #ifdef XF86DRI
 -   didLock = I830DRILock(pScrn);
 -#endif
 -
 -   if (pI830->Clone) {
 -      pI830->CloneHDisplay = pMode->HDisplay;
 -      pI830->CloneVDisplay = pMode->VDisplay;
 -   }
 -
 -#ifndef MODESWITCH_RESET_STATE
 -#define MODESWITCH_RESET_STATE 0
 -#endif
 -#if MODESWITCH_RESET_STATE
 -   ResetState(pScrn, TRUE);
 +   I830DRISetVBlankInterrupt (pScrn, FALSE);
  #endif
 +   vgaHWRestore(pScrn, vgaReg, VGA_SR_FONTS);
 +   vgaHWLock(hwp);
  
 -   SetPipeAccess(pScrn);
 -
 -   if (!pI830->MergedFB) {
 -      if (I830VESASetVBEMode(pScrn, mode, mp->vbeData.block) == FALSE) {
 -         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Set VBE Mode failed!\n");
 -         return FALSE;
 -      }
 -   }else {
 -      I830ModePrivatePtr s = (I830ModePrivatePtr)mp->merged.Second->Private;
 -      I830ModePrivatePtr f = (I830ModePrivatePtr)mp->merged.First->Private;
 -      int pipe = pI830->pipe; /* save current pipe */
 -
 -      SetBIOSPipe(pScrn, !pI830->pipe);
 -
 -      pI830->pipe = !pI830->pipe;
 -      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting mode on Pipe %s.\n", pI830->pipe ? "B" : "A");
 -
 -      if (I830VESASetVBEMode(pScrn, (s->vbeData.mode | 1<<15 | 1<<14), s->vbeData.block) == FALSE) {
 -         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Set VBE Mode failed!\n");
 -         return FALSE;
 -      }
 -
 -      pI830->pipe = pipe; /* restore current pipe */
 -      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting mode on Pipe %s.\n", pI830->pipe ? "B" : "A");
 -
 -      SetPipeAccess(pScrn);
 -
 -      if (I830VESASetVBEMode(pScrn, (f->vbeData.mode | 1<<15 | 1<<14), f->vbeData.block) == FALSE) {
 -         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Set VBE Mode failed!\n");
 -         return FALSE;
 -      }
 -   }
 -
 -#if 0
 -   { /* I965G ENABLE TILING */
 -      planeA = INREG(DSPACNTR) | 1<<10;
 -      OUTREG(DSPACNTR, planeA);
 -      /* flush the change. */
 -      temp = INREG(DSPABASE);
 -      OUTREG(DSPABASE, temp);
 -   }
 -#else
 -   { /* I965G DISABLE TILING */
 -      planeA = INREG(DSPACNTR) & ~1<<10;
 -      OUTREG(DSPACNTR, planeA);
 -      /* flush the change. */
 -      temp = INREG(DSPABASE);
 -      OUTREG(DSPABASE, temp);
 -      OUTREG(DSPASURF, INREG(DSPASURF));
 -   }
 -#endif
 +   /* First, disable display planes */
 +   temp = INREG(DSPACNTR);
 +   OUTREG(DSPACNTR, temp & ~DISPLAY_PLANE_ENABLE);
 +   temp = INREG(DSPBCNTR);
 +   OUTREG(DSPBCNTR, temp & ~DISPLAY_PLANE_ENABLE);
  
 -   /*
 -    * The BIOS may not set a scanline pitch that would require more video
 -    * memory than it's aware of.  We check for this later, and set it
 -    * explicitly if necessary.
 -    */
 -   if (mp->vbeData.data->XResolution != pI830->displayWidth) {
 -      if (pI830->Clone || pI830->MergedFB) {
 -         SetBIOSPipe(pScrn, !pI830->pipe);
 -         VBESetLogicalScanline(pVbe, pI830->displayWidth);
 +   /* Next, disable display pipes */
 +   temp = INREG(PIPEACONF);
 +   OUTREG(PIPEACONF, temp & ~PIPEACONF_ENABLE);
 +   temp = INREG(PIPEBCONF);
 +   OUTREG(PIPEBCONF, temp & ~PIPEBCONF_ENABLE);
 +
 +   /* XXX: Wait for a vblank */
 +   sleep(1);
 +
 +   i830SetLVDSPanelPower(pScrn, FALSE);
 +
 +   for (i = 0; i < pI830->num_outputs; i++) {
 +      if (pI830->output[i].type == I830_OUTPUT_SDVO &&
 +	  pI830->output[i].sdvo_drv != NULL)
 +      {
 +	 i830SDVOPreRestore(pScrn, i);
        }
 -      SetPipeAccess(pScrn);
 -      VBESetLogicalScanline(pVbe, pI830->displayWidth);
     }
  
 -   if (pScrn->bitsPerPixel >= 8 && pI830->vbeInfo->Capabilities[0] & 0x01) {
 -      if (pI830->Clone || pI830->MergedFB) {
 -         SetBIOSPipe(pScrn, !pI830->pipe);
 -         VBESetGetDACPaletteFormat(pVbe, 8);
 +   OUTREG(FPA0, pI830->saveFPA0);
 +   OUTREG(FPA1, pI830->saveFPA1);
 +   OUTREG(DPLL_A, pI830->saveDPLL_A);
 +   OUTREG(HTOTAL_A, pI830->saveHTOTAL_A);
 +   OUTREG(HBLANK_A, pI830->saveHBLANK_A);
 +   OUTREG(HSYNC_A, pI830->saveHSYNC_A);
 +   OUTREG(VTOTAL_A, pI830->saveVTOTAL_A);
 +   OUTREG(VBLANK_A, pI830->saveVBLANK_A);
 +   OUTREG(VSYNC_A, pI830->saveVSYNC_A);
 +   OUTREG(DSPASTRIDE, pI830->saveDSPASTRIDE);
 +   OUTREG(DSPASIZE, pI830->saveDSPASIZE);
 +   OUTREG(DSPAPOS, pI830->saveDSPAPOS);
 +   OUTREG(DSPABASE, pI830->saveDSPABASE);
 +   OUTREG(PIPEASRC, pI830->savePIPEASRC);
 +   for(i = 0; i < 256; i++) {
 +         OUTREG(PALETTE_A + (i << 2), pI830->savePaletteA[i]);
 +   }
 +
 +   if(pI830->availablePipes == 2) {
 +      OUTREG(FPB0, pI830->saveFPB0);
 +      OUTREG(FPB1, pI830->saveFPB1);
 +      OUTREG(DPLL_B, pI830->saveDPLL_B);
 +      OUTREG(HTOTAL_B, pI830->saveHTOTAL_B);
 +      OUTREG(HBLANK_B, pI830->saveHBLANK_B);
 +      OUTREG(HSYNC_B, pI830->saveHSYNC_B);
 +      OUTREG(VTOTAL_B, pI830->saveVTOTAL_B);
 +      OUTREG(VBLANK_B, pI830->saveVBLANK_B);
 +      OUTREG(VSYNC_B, pI830->saveVSYNC_B);
 +      OUTREG(DSPBSTRIDE, pI830->saveDSPBSTRIDE);
 +      OUTREG(DSPBSIZE, pI830->saveDSPBSIZE);
 +      OUTREG(DSPBPOS, pI830->saveDSPBPOS);
 +      OUTREG(DSPBBASE, pI830->saveDSPBBASE);
 +      OUTREG(PIPEBSRC, pI830->savePIPEBSRC);
 +      for(i= 0; i < 256; i++) {
 +         OUTREG(PALETTE_B + (i << 2), pI830->savePaletteB[i]);
        }
 -      SetPipeAccess(pScrn);
 -      VBESetGetDACPaletteFormat(pVbe, 8);
     }
  
 -   /* XXX Fix plane A with pipe A, and plane B with pipe B. */
 -   planeA = INREG(DSPACNTR);
 -   planeB = INREG(DSPBCNTR);
 -
 -   pI830->planeEnabled[0] = ((planeA & DISPLAY_PLANE_ENABLE) != 0);
 -   pI830->planeEnabled[1] = ((planeB & DISPLAY_PLANE_ENABLE) != 0);
 -
 -   xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Display plane A is %s and connected to %s.\n",
 -	      pI830->planeEnabled[0] ? "enabled" : "disabled",
 -	      planeA & DISPPLANE_SEL_PIPE_MASK ? "Pipe B" : "Pipe A");
 -   if (pI830->availablePipes == 2)
 -      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Display plane B is %s and connected to %s.\n",
 -	      pI830->planeEnabled[1] ? "enabled" : "disabled",
 -	      planeB & DISPPLANE_SEL_PIPE_MASK ? "Pipe B" : "Pipe A");
 -   
 -   if (pI830->operatingDevices & 0xff) {
 -      pI830->planeEnabled[0] = 1;
 -   } else { 
 -      pI830->planeEnabled[0] = 0;
++   if (IS_I965G(pI830)) {
++      OUTREG(DSPASURF, pI830->saveDSPABASE);
++      OUTREG(DSPBSURF, pI830->saveDSPBBASE);
+    }
+ 
 -   if (pI830->operatingDevices & 0xff00) {
 -      pI830->planeEnabled[1] = 1;
 -   } else {
 -      pI830->planeEnabled[1] = 0;
 -   }
 +   OUTREG(BLC_PWM_CTL, pI830->saveBLC_PWM_CTL);
 +   OUTREG(LVDSPP_ON, pI830->savePP_ON);
 +   OUTREG(LVDSPP_OFF, pI830->savePP_OFF);
 +   OUTREG(PP_CYCLE, pI830->savePP_CYCLE);
 +   OUTREG(PFIT_CONTROL, pI830->savePFIT_CONTROL);
     
 -   if (pI830->planeEnabled[0]) {
 -      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Enabling plane A.\n");
 -      planeA |= DISPLAY_PLANE_ENABLE;
 -      planeA &= ~DISPPLANE_SEL_PIPE_MASK;
 -      planeA |= DISPPLANE_SEL_PIPE_A;
 -      OUTREG(DSPACNTR, planeA);
 -      /* flush the change. */
 -      temp = INREG(DSPABASE);
 -      OUTREG(DSPABASE, temp);
 -      if (IS_I965G(pI830)) {
 -         temp = INREG(DSPASURF);
 -         OUTREG(DSPASURF, temp);
 -      }
 -   }
 -   if (pI830->planeEnabled[1]) {
 -      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Enabling plane B.\n");
 -      planeB |= DISPLAY_PLANE_ENABLE;
 -      planeB &= ~DISPPLANE_SEL_PIPE_MASK;
 -      planeB |= DISPPLANE_SEL_PIPE_B;
 -      OUTREG(DSPBCNTR, planeB);
 -      /* flush the change. */
 -      temp = INREG(DSPBADDR);
 -      OUTREG(DSPBADDR, temp);
 -      if (IS_I965G(pI830)) {
 -         temp = INREG(DSPBSURF);
 -         OUTREG(DSPBSURF, temp);
 -      }
 -   }
 +   OUTREG(VCLK_DIVISOR_VGA0, pI830->saveVCLK_DIVISOR_VGA0);
 +   OUTREG(VCLK_DIVISOR_VGA1, pI830->saveVCLK_DIVISOR_VGA1);
 +   OUTREG(VCLK_POST_DIV, pI830->saveVCLK_POST_DIV);
  
 -   planeA = INREG(DSPACNTR);
 -   planeB = INREG(DSPBCNTR);
 -   xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Display plane A is now %s and connected to %s.\n",
 -	      pI830->planeEnabled[0] ? "enabled" : "disabled",
 -	      planeA & DISPPLANE_SEL_PIPE_MASK ? "Pipe B" : "Pipe A");
 -   if (pI830->availablePipes == 2)
 -      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Display plane B is now %s and connected to %s.\n",
 -	      pI830->planeEnabled[1] ? "enabled" : "disabled",
 -	      planeB & DISPPLANE_SEL_PIPE_MASK ? "Pipe B" : "Pipe A");
 +   OUTREG(PIPEACONF, pI830->savePIPEACONF);
 +   OUTREG(PIPEBCONF, pI830->savePIPEBCONF);
  
 -   /* XXX Plane C is ignored for now (overlay). */
 +   OUTREG(VGACNTRL, pI830->saveVGACNTRL);
 +   OUTREG(DSPACNTR, pI830->saveDSPACNTR);
 +   OUTREG(DSPBCNTR, pI830->saveDSPBCNTR);
  
 -   /*
 -    * Print out the PIPEACONF and PIPEBCONF registers.
 -    */
 -   temp = INREG(PIPEACONF);
 -   xf86DrvMsg(pScrn->scrnIndex, X_INFO, "PIPEACONF is 0x%08lx\n", 
 -	      (unsigned long) temp);
 -   if (pI830->availablePipes == 2) {
 -      temp = INREG(PIPEBCONF);
 -      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "PIPEBCONF is 0x%08lx\n", 
 -		 (unsigned long) temp);
 +   OUTREG(ADPA, pI830->saveADPA);
 +   OUTREG(LVDS, pI830->saveLVDS);
 +   if (!IS_I9XX(pI830)) {
 +      OUTREG(DVOA, pI830->saveDVOA);
 +      OUTREG(DVOB, pI830->saveDVOB);
 +      OUTREG(DVOC, pI830->saveDVOC);
     }
  
 -   if (xf86IsEntityShared(pScrn->entityList[0])) {
 -      /* Clean this up !! */
 -      if (I830IsPrimary(pScrn)) {
 -         CARD32 stridereg = !pI830->pipe ? DSPASTRIDE : DSPBSTRIDE;
 -         CARD32 basereg = !pI830->pipe ? DSPABASE : DSPBBASE;
 -         CARD32 sizereg = !pI830->pipe ? DSPASIZE : DSPBSIZE;
 -         CARD32 surfreg = !pI830->pipe ? DSPASURF : DSPBSURF;
 -         I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
 -
 -         temp = INREG(stridereg);
 -         if (temp / pI8301->cpp != (CARD32)(pI830->displayWidth)) {
 -            xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 -		    "Correcting plane %c stride (%d -> %d)\n", PIPE_NAME(!pI830->pipe),
 -		    (int)(temp / pI8301->cpp), pI830->displayWidth);
 -	    OUTREG(stridereg, pI830->displayWidth * pI8301->cpp);
 -         }
 -         OUTREG(sizereg, (pMode->HDisplay - 1) | ((pMode->VDisplay - 1) << 16));
 -         /* Trigger update */
 -         temp = INREG(basereg);
 -         OUTREG(basereg, temp);
 -         if (IS_I965G(pI830)) {
 -            temp = INREG(surfreg);
 -            OUTREG(surfreg, temp);
 -         }
 -
 -         if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) {
 -            I830Ptr pI8302 = I830PTR(pI830->entityPrivate->pScrn_2);
 -            stridereg = pI830->pipe ? DSPASTRIDE : DSPBSTRIDE;
 -            basereg = pI830->pipe ? DSPABASE : DSPBBASE;
 -            sizereg = pI830->pipe ? DSPASIZE : DSPBSIZE;
 -            surfreg = pI830->pipe ? DSPASURF : DSPBSURF;
 -
 -            temp = INREG(stridereg);
 -            if (temp / pI8302->cpp != (CARD32)(pI8302->displayWidth)) {
 -	       xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 -		    "Correcting plane %c stride (%d -> %d)\n", PIPE_NAME(pI830->pipe),
 -		    (int)(temp / pI8302->cpp), pI8302->displayWidth);
 -	       OUTREG(stridereg, pI8302->displayWidth * pI8302->cpp);
 -            }
 -            OUTREG(sizereg, (pI830->entityPrivate->pScrn_2->currentMode->HDisplay - 1) | ((pI830->entityPrivate->pScrn_2->currentMode->VDisplay - 1) << 16));
 -            /* Trigger update */
 -            temp = INREG(basereg);
 -            OUTREG(basereg, temp);
 -            if (IS_I965G(pI830)) {
 -               temp = INREG(surfreg);
 -               OUTREG(surfreg, temp);
 -            }
 -         }
 -      } else {
 -         CARD32 stridereg = pI830->pipe ? DSPASTRIDE : DSPBSTRIDE;
 -         CARD32 basereg = pI830->pipe ? DSPABASE : DSPBBASE;
 -         CARD32 sizereg = pI830->pipe ? DSPASIZE : DSPBSIZE;
 -         CARD32 surfreg = pI830->pipe ? DSPASURF : DSPBSURF;
 -         I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
 -         I830Ptr pI8302 = I830PTR(pI830->entityPrivate->pScrn_2);
 -
 -         temp = INREG(stridereg);
 -         if (temp / pI8301->cpp != (CARD32)(pI8301->displayWidth)) {
 -	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 -		    "Correcting plane %c stride (%d -> %d)\n", PIPE_NAME(pI830->pipe),
 -		    (int)(temp / pI8301->cpp), pI8301->displayWidth);
 -	    OUTREG(stridereg, pI8301->displayWidth * pI8301->cpp);
 -         }
 -         OUTREG(sizereg, (pI830->entityPrivate->pScrn_1->currentMode->HDisplay - 1) | ((pI830->entityPrivate->pScrn_1->currentMode->VDisplay - 1) << 16));
 -         /* Trigger update */
 -         temp = INREG(basereg);
 -         OUTREG(basereg, temp);
 -         if (IS_I965G(pI830)) {
 -            temp = INREG(surfreg);
 -            OUTREG(surfreg, temp);
 -         }
 -
 -         stridereg = !pI830->pipe ? DSPASTRIDE : DSPBSTRIDE;
 -         basereg = !pI830->pipe ? DSPABASE : DSPBBASE;
 -         sizereg = !pI830->pipe ? DSPASIZE : DSPBSIZE;
 -         surfreg = !pI830->pipe ? DSPASURF : DSPBSURF;
 -
 -         temp = INREG(stridereg);
 -         if (temp / pI8302->cpp != ((CARD32)pI8302->displayWidth)) {
 -	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 -		    "Correcting plane %c stride (%d -> %d)\n", PIPE_NAME(!pI830->pipe),
 -		    (int)(temp / pI8302->cpp), pI8302->displayWidth);
 -	    OUTREG(stridereg, pI8302->displayWidth * pI8302->cpp);
 -         }
 -         OUTREG(sizereg, (pMode->HDisplay - 1) | ((pMode->VDisplay - 1) << 16));
 -         /* Trigger update */
 -         temp = INREG(basereg);
 -         OUTREG(basereg, temp);
 -         if (IS_I965G(pI830)) {
 -            temp = INREG(surfreg);
 -            OUTREG(surfreg, temp);
 -         }
 -      }
 -   } else {
 -      for (i = 0; i < pI830->availablePipes; i++) {
 -         CARD32 stridereg = i ? DSPBSTRIDE : DSPASTRIDE;
 -         CARD32 basereg = i ? DSPBBASE : DSPABASE;
 -         CARD32 sizereg = i ? DSPBSIZE : DSPASIZE;
 -         CARD32 surfreg = i ? DSPBSURF : DSPASURF;
 -
 -         if (!pI830->planeEnabled[i])
 -	    continue;
 -
 -         temp = INREG(stridereg);
 -         if (temp / pI830->cpp != (CARD32)pI830->displayWidth) {
 -	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 -		    "Correcting plane %c stride (%d -> %d)\n", PIPE_NAME(i),
 -		    (int)(temp / pI830->cpp), pI830->displayWidth);
 -	    OUTREG(stridereg, pI830->displayWidth * pI830->cpp);
 -         }
 -
 -	 if (pI830->MergedFB) {
 -	    switch (pI830->SecondPosition) {
 -	       case PosRightOf:
 -	       case PosBelow:
 -                  OUTREG(DSPABASE, (CDMPTR.First->HDisplay - 1) | ((CDMPTR.First->VDisplay - 1) << 16));
 -                  OUTREG(DSPBBASE, (CDMPTR.Second->HDisplay - 1) | ((CDMPTR.Second->VDisplay - 1) << 16));
 -	          break;
 -	       case PosLeftOf:
 -	       case PosAbove:
 -                  OUTREG(DSPABASE, (CDMPTR.Second->HDisplay - 1) | ((CDMPTR.Second->VDisplay - 1) << 16));
 -                  OUTREG(DSPBBASE, (CDMPTR.First->HDisplay - 1) | ((CDMPTR.First->VDisplay - 1) << 16));
 -	          break;
 -	    }
 -         } else
 -            OUTREG(sizereg, (pMode->HDisplay - 1) | ((pMode->VDisplay - 1) << 16));
 -	 /* Trigger update */
 -	 temp = INREG(basereg);
 -	 OUTREG(basereg, temp);
 -         if (IS_I965G(pI830)) {
 -            temp = INREG(surfreg);
 -            OUTREG(surfreg, temp);
 -         }
 +   for (i = 0; i < pI830->num_outputs; i++) {
 +      if (pI830->output[i].type == I830_OUTPUT_DVO &&
 +	  pI830->output[i].i2c_drv != NULL)
 +      {
 +	 pI830->output[i].i2c_drv->vid_rec->RestoreRegs(
 +	    pI830->output[i].i2c_drv->dev_priv);
        }
 -   }
 -
 -#if 0
 -   /* Print out some CRTC/display information. */
 -   temp = INREG(HTOTAL_A);
 -   ErrorF("Horiz active: %d, Horiz total: %d\n", temp & 0x7ff,
 -	  (temp >> 16) & 0xfff);
 -   temp = INREG(HBLANK_A);
 -   ErrorF("Horiz blank start: %d, Horiz blank end: %d\n", temp & 0xfff,
 -	  (temp >> 16) & 0xfff);
 -   temp = INREG(HSYNC_A);
 -   ErrorF("Horiz sync start: %d, Horiz sync end: %d\n", temp & 0xfff,
 -	  (temp >> 16) & 0xfff);
 -   temp = INREG(VTOTAL_A);
 -   ErrorF("Vert active: %d, Vert total: %d\n", temp & 0x7ff,
 -	  (temp >> 16) & 0xfff);
 -   temp = INREG(VBLANK_A);
 -   ErrorF("Vert blank start: %d, Vert blank end: %d\n", temp & 0xfff,
 -	  (temp >> 16) & 0xfff);
 -   temp = INREG(VSYNC_A);
 -   ErrorF("Vert sync start: %d, Vert sync end: %d\n", temp & 0xfff,
 -	  (temp >> 16) & 0xfff);
 -   temp = INREG(PIPEASRC);
 -   ErrorF("Image size: %dx%d (%dx%d)\n",
 -          (temp >> 16) & 0x7ff, temp & 0x7ff,
 -	  (((temp >> 16) & 0x7ff) + 1), ((temp & 0x7ff) + 1));
 -   ErrorF("Pixel multiply is %d\n", (planeA >> 20) & 0x3);
 -   temp = INREG(DSPABASE);
 -   ErrorF("Plane A start offset is %d\n", temp);
 -   temp = INREG(DSPASTRIDE);
 -   ErrorF("Plane A stride is %d bytes (%d pixels)\n", temp, temp / pI830->cpp);
 -   temp = INREG(DSPAPOS);
 -   ErrorF("Plane A position %d %d\n", temp & 0xffff, (temp & 0xffff0000) >> 16);
 -   temp = INREG(DSPASIZE);
 -   ErrorF("Plane A size %d %d\n", temp & 0xffff, (temp & 0xffff0000) >> 16);
 -
 -   /* Print out some CRTC/display information. */
 -   temp = INREG(HTOTAL_B);
 -   ErrorF("Horiz active: %d, Horiz total: %d\n", temp & 0x7ff,
 -	  (temp >> 16) & 0xfff);
 -   temp = INREG(HBLANK_B);
 -   ErrorF("Horiz blank start: %d, Horiz blank end: %d\n", temp & 0xfff,
 -	  (temp >> 16) & 0xfff);
 -   temp = INREG(HSYNC_B);
 -   ErrorF("Horiz sync start: %d, Horiz sync end: %d\n", temp & 0xfff,
 -	  (temp >> 16) & 0xfff);
 -   temp = INREG(VTOTAL_B);
 -   ErrorF("Vert active: %d, Vert total: %d\n", temp & 0x7ff,
 -	  (temp >> 16) & 0xfff);
 -   temp = INREG(VBLANK_B);
 -   ErrorF("Vert blank start: %d, Vert blank end: %d\n", temp & 0xfff,
 -	  (temp >> 16) & 0xfff);
 -   temp = INREG(VSYNC_B);
 -   ErrorF("Vert sync start: %d, Vert sync end: %d\n", temp & 0xfff,
 -	  (temp >> 16) & 0xfff);
 -   temp = INREG(PIPEBSRC);
 -   ErrorF("Image size: %dx%d (%dx%d)\n",
 -          (temp >> 16) & 0x7ff, temp & 0x7ff,
 -	  (((temp >> 16) & 0x7ff) + 1), ((temp & 0x7ff) + 1));
 -   ErrorF("Pixel multiply is %d\n", (planeA >> 20) & 0x3);
 -   temp = INREG(DSPBBASE);
 -   ErrorF("Plane B start offset is %d\n", temp);
 -   temp = INREG(DSPBSTRIDE);
 -   ErrorF("Plane B stride is %d bytes (%d pixels)\n", temp, temp / pI830->cpp);
 -   temp = INREG(DSPBPOS);
 -   ErrorF("Plane B position %d %d\n", temp & 0xffff, (temp & 0xffff0000) >> 16);
 -   temp = INREG(DSPBSIZE);
 -   ErrorF("Plane B size %d %d\n", temp & 0xffff, (temp & 0xffff0000) >> 16);
 -#endif
 -
 -   xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Mode bandwidth is %d Mpixel/s\n",
 -	      pMode->HDisplay * pMode->VDisplay * refresh / 1000000);
 -
 -   {
 -      int maxBandwidth, bandwidthA, bandwidthB;
 -
 -      if (GetModeSupport(pScrn, 0x80, 0x80, 0x80, 0x80,
 -			&maxBandwidth, &bandwidthA, &bandwidthB)) {
 -	 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "maxBandwidth is %d Mbyte/s, "
 -		    "pipe bandwidths are %d Mbyte/s, %d Mbyte/s\n",
 -		    maxBandwidth, bandwidthA, bandwidthB);
 +      if (pI830->output[i].type == I830_OUTPUT_SDVO &&
 +	  pI830->output[i].sdvo_drv != NULL)
 +      {
 +	 i830SDVOPostRestore(pScrn, i);
        }
     }
  
@@@ -3053,8 -6953,40 +3175,40 @@@
     return ret;
  }
  
+ /* Initialize the first context */
+ void
+ IntelEmitInvarientState(ScrnInfoPtr pScrn)
+ {
+    I830Ptr pI830 = I830PTR(pScrn);
+    CARD32 ctx_addr;
+ 
+    if (pI830->noAccel)
+       return;
+ 
+    ctx_addr = pI830->ContextMem.Start;
+    /* Align to a 2k boundry */
+    ctx_addr = ((ctx_addr + 2048 - 1) / 2048) * 2048;
+ 
+    {
+       BEGIN_LP_RING(2);
+       OUT_RING(MI_SET_CONTEXT);
+       OUT_RING(ctx_addr |
+ 	       CTXT_NO_RESTORE |
+ 	       CTXT_PALETTE_SAVE_DISABLE | CTXT_PALETTE_RESTORE_DISABLE);
+       ADVANCE_LP_RING();
+    }
+ 
+    if (!IS_I965G(pI830))
+    {
+       if (IS_I9XX(pI830))
+          I915EmitInvarientState(pScrn);
+       else
+          I830EmitInvarientState(pScrn);
+    }
+ }
+ 
  static Bool
 -I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
 +I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
  {
     ScrnInfoPtr pScrn;
     vgaHWPtr hwp;
@@@ -3479,14 -7493,18 +3694,12 @@@
  }
  
  static void
 -I830AdjustFrame(int scrnIndex, int x, int y, int flags)
 +i830AdjustFrame(int scrnIndex, int x, int y, int flags)
  {
 -   ScrnInfoPtr pScrn;
 -   I830Ptr pI830;
 -   vbeInfoPtr pVbe;
 -   unsigned long Start;
 -
 -   pScrn = xf86Screens[scrnIndex];
 -   pI830 = I830PTR(pScrn);
 -   pVbe = pI830->pVbe;
 +   ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
-    I830Ptr pI830;
- 
-    pI830 = I830PTR(pScrn);
++   I830Ptr pI830 = I830PTR(pScrn);
  
 -   DPRINTF(PFX, "I830AdjustFrame: y = %d (+ %d), x = %d (+ %d)\n",
 +   DPRINTF(PFX, "i830AdjustFrame: y = %d (+ %d), x = %d (+ %d)\n",
  	   x, pI830->xoffset, y, pI830->yoffset);
  
     /* Sync the engine before adjust frame */
@@@ -3582,20 -7712,32 +3798,17 @@@
  
     /* Re-read EDID */
     pDDCModule = xf86LoadSubModule(pScrn, "ddc");
-    if (pI830->vesa->monitor)
-       xfree(pI830->vesa->monitor);
-    pI830->vesa->monitor = vbeDoEDID(pI830->pVbe, pDDCModule);
+ 
 -   if (pI830->MergedFB) {
 -      pI830->pVbe->ddc = DDC_UNCHECKED;
 -      SetBIOSPipe(pScrn, !pI830->pipe);
 -      monitor = vbeDoEDID(pI830->pVbe, pDDCModule);
 -      if ((pI830->pScrn_2->monitor->DDC = monitor) != NULL) {
 -         xf86PrintEDID(monitor);
 -         xf86SetDDCproperties(pScrn, monitor);
 -      } 
 -      SetPipeAccess(pScrn);
 -   }
 -
+    pI830->pVbe->ddc = DDC_UNCHECKED;
+    monitor = vbeDoEDID(pI830->pVbe, pDDCModule);
     xf86UnloadSubModule(pDDCModule);
-    if ((pScrn->monitor->DDC = pI830->vesa->monitor) != NULL) {
-       xf86PrintEDID(pI830->vesa->monitor);
-       xf86SetDDCproperties(pScrn, pI830->vesa->monitor);
-    } else 
-       /* No DDC, so get out of here, and continue to use the current settings */
-       return FALSE; 
+    if ((pScrn->monitor->DDC = monitor) != NULL) {
+       xf86PrintEDID(monitor);
+       xf86SetDDCproperties(pScrn, monitor);
+    } 
  
-    if (!(DDCclock = I830UseDDC(pScrn)))
-       return FALSE;
+    DDCclock = I830UseDDC(pScrn);
  
 -   /* Check if DDC exists on the second head, if not don't abort. */
 -   if (pI830->MergedFB)
 -      DDCclock2 = I830UseDDC(pI830->pScrn_2);
 -
     /* Revalidate the modes */
  
     /*
@@@ -3612,8 -7756,24 +3827,7 @@@
        return FALSE;
     }
  
-    SetPipeAccess(pScrn);
 -   if (pI830->MergedFB) {
 -      SetBIOSPipe(pScrn, !pI830->pipe);
 -      xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 -		 "Retrieving mode pool for second head.\n");
 -      pI830->pScrn_2->modePool = I830GetModePool(pI830->pScrn_2, pI830->pVbe, pI830->vbeInfo);
 -
 -      if (!pI830->pScrn_2->modePool) {
 -         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 -		 "No Video BIOS modes for chosen depth.\n");
 -         PreInitCleanup(pScrn);
 -         return FALSE;
 -      }
 -      SetPipeAccess(pScrn);
 -   }
 -
     VBESetModeNames(pScrn->modePool);
 -   if (pI830->MergedFB)
 -      VBESetModeNames(pI830->pScrn_2->modePool);
  
     if (pScrn->videoRam > (pI830->vbeInfo->TotalMemory * 64))
        memsize = pI830->vbeInfo->TotalMemory * 64;
@@@ -3657,10 -7827,64 +3881,39 @@@
        } while (p != NULL && p != pScrn->modes);
     }
  
-    pScrn->displayWidth = displayWidth; /* restore old displayWidth */
+    /* Only use this if we've got DDC available */
+    if (pI830->MergedFB && DDCclock2 > 0) {
+       p = pI830->pScrn_2->modes;
+       if (p == NULL)
+          return FALSE;
+       do {
+          int Clock = 100000000; /* incredible value */
+ 
+ 	 if (p->status == MODE_OK) {
+             for (pMon = pI830->pScrn_2->monitor->Modes; pMon != NULL; pMon = pMon->next) {
+                if ((pMon->HDisplay != p->HDisplay) ||
+                    (pMon->VDisplay != p->VDisplay) ||
+                    (pMon->Flags & (V_INTERLACE | V_DBLSCAN | V_CLKDIV2)))
+                    continue;
+ 
+                /* Find lowest supported Clock for this resolution */
+                if (Clock > pMon->Clock)
+                   Clock = pMon->Clock;
+             } 
+ 
+             if (Clock != 100000000 && DDCclock2 < 2550 && Clock / 1000.0 > DDCclock2) {
+                ErrorF("(%s,%s) mode clock %gMHz exceeds DDC maximum %dMHz\n",
+ 		   p->name, pI830->pScrn_2->monitor->id,
+ 		   Clock/1000.0, DDCclock2);
+                p->status = MODE_BAD;
+             } 
+  	 }
+          p = p->next;
+       } while (p != NULL && p != pI830->pScrn_2->modes);
+    }
  
     xf86PruneDriverModes(pScrn);
 -
 -   if (pI830->MergedFB)
 -      xf86PruneDriverModes(pI830->pScrn_2);
 -
 -   if (pI830->MergedFB) {
 -      DisplayModePtr old_modes, cur_mode;
 -
 -      old_modes = pScrn->modes;
 -      cur_mode = pScrn->currentMode;
 -
 -      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "MergedFB: Generating mode list\n");
 -
 -      pScrn->modes = I830GenerateModeList(pScrn, pI830->MetaModes,
 -					  old_modes, pI830->pScrn_2->modes,
 -					  pI830->SecondPosition);
 -
 -      if(!pScrn->modes) {
 -          xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes. Disabling MergedFB.\n");
 -	  pScrn->modes = old_modes;
 -	  pScrn->currentMode = cur_mode;
 -	  pI830->MergedFB = FALSE;
 -      }
 -   }
 -
 -   if (!pI830->vesa->useDefaultRefresh)
 -      I830SetModeParameters(pScrn, pI830->pVbe);
 +   I830PrintModes(pScrn);
  
     /* Now check if the previously used mode is o.k. for the current monitor.
      * This allows VT switching to continue happily when not disconnecting
@@@ -3704,10 -7945,38 +3974,13 @@@
        }
     }
  
+    if (pI830->MergedFB)
+       I830AdjustFrameMerged(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+ 
     return TRUE;
 +#endif /* 0 */
  }
  
 -Bool
 -I830CheckModeSupport(ScrnInfoPtr pScrn, int x, int y, int mode)
 -{
 -   I830Ptr pI830 = I830PTR(pScrn);
 -   Bool ret = TRUE;
 -
 -   if (pI830->Clone) {
 -      if (pI830->pipeDisplaySize[0].x2 != 0) {
 -	 if (x > pI830->pipeDisplaySize[0].x2 ||
 -             y > pI830->pipeDisplaySize[0].y2) {
 -	 	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Bad Clone Mode removing\n");
 -		return FALSE;
 -         }
 -      }
 -      if (pI830->pipeDisplaySize[1].x2 != 0) {
 -	 if (x > pI830->pipeDisplaySize[1].x2 ||
 -             y > pI830->pipeDisplaySize[1].y2) {
 -	 	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Bad Clone Mode removing\n");
 -		return FALSE;
 -         }
 -      }
 -   }
 -
 -   return ret;
 -}
 -		
  /*
   * This gets called when gaining control of the VT, and from ScreenInit().
   */
@@@ -3764,12 -8072,22 +4037,18 @@@
  
     pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
  
 -#if SAVERESTORE_HWSTATE
 -   RestoreHWOperatingState(pScrn);
 -#endif
 -
  #ifdef XF86DRI
     if (pI830->directRenderingEnabled) {
+ 
+       I830DRISetVBlankInterrupt (pScrn, TRUE);
+ 
        if (!pI830->starting) {
+          ScreenPtr pScreen = pScrn->pScreen;
+          drmI830Sarea *sarea = (drmI830Sarea *) DRIGetSAREAPrivate(pScreen);
+          int i;
+ 
  	 I830DRIResume(screenInfo.screens[scrnIndex]);
        
- 	 I830EmitInvarientState(pScrn);
  	 I830RefreshRing(pScrn);
  	 I830Sync(pScrn);
  	 DO_RING_IDLE();
@@@ -3781,13 -8103,9 +4064,16 @@@
     }
  #endif
  
 +   /* Set the hotkey to just notify us.  We can check its results periodically
 +    * in the CheckDevicesTimer.  Eventually we want the kernel to just hand us
 +    * an input event when someone presses the button, but for now we just have
 +    * to poll.
 +    */
 +   i830SetHotkeyControl(pScrn, HOTKEY_DRIVER_NOTIFY);
 +
+    /* Needed for rotation */
+    IntelEmitInvarientState(pScrn);
+ 
     if (pI830->checkDevices)
        pI830->devicesTimer = TimerSet(NULL, 0, 1000, I830CheckDevicesTimer, pScrn);
  
@@@ -3873,31 -8199,34 +4160,37 @@@
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
     I830Ptr pI830 = I830PTR(pScrn);
     Bool on = xf86IsUnblank(mode);
-    CARD32 temp, ctrl, base;
+    CARD32 temp, ctrl, base, surf;
 +   int i;
  
 -   DPRINTF(PFX, "I830BIOSSaveScreen: %d, on is %s\n", mode, BOOLTOSTRING(on));
 +   DPRINTF(PFX, "I830SaveScreen: %d, on is %s\n", mode, BOOLTOSTRING(on));
  
     if (pScrn->vtSema) {
 -      if (pI830->pipe == 0) {
 -	 ctrl = DSPACNTR;
 -	 base = DSPABASE;
 -	 surf = DSPASURF;
 -      } else {
 -	 ctrl = DSPBCNTR;
 -	 base = DSPBADDR;
 -	 surf = DSPBSURF;
 -      }
 -      if (pI830->planeEnabled[pI830->pipe]) {
 -	 temp = INREG(ctrl);
 -	 if (on)
 -	    temp |= DISPLAY_PLANE_ENABLE;
 -	 else
 -	    temp &= ~DISPLAY_PLANE_ENABLE;
 -	 OUTREG(ctrl, temp);
 -	 /* Flush changes */
 -	 temp = INREG(base);
 -	 OUTREG(base, temp);
 -	 if (IS_I965G(pI830)) {
 -            temp = INREG(surf);
 -            OUTREG(surf, temp);
 -         }
 +      for (i = 0; i < pI830->availablePipes; i++) {
 +        if (i == 0) {
 +	    ctrl = DSPACNTR;
 +	    base = DSPABASE;
++	    surf = DSPASURF;
 +        } else {
 +	    ctrl = DSPBCNTR;
 +	    base = DSPBADDR;
++	    surf = DSPBSURF;
 +        }
 +        if (pI830->planeEnabled[i]) {
 +	   temp = INREG(ctrl);
 +	   if (on)
 +	      temp |= DISPLAY_PLANE_ENABLE;
 +	   else
 +	      temp &= ~DISPLAY_PLANE_ENABLE;
 +	   OUTREG(ctrl, temp);
 +	   /* Flush changes */
 +	   temp = INREG(base);
 +	   OUTREG(base, temp);
++	   if (IS_I965G(pI830)) {
++	      temp = INREG(surf);
++	      OUTREG(surf, temp);
++	   }
 +        }
        }
  
        if (pI830->CursorInfoRec && !pI830->SWCursor && pI830->cursorOn) {
diff --cc src/i830_memory.c
index 2d8610a,2d09b2d..a14027d
@@@ -822,7 -854,8 +846,8 @@@
  	 alignflags = 0;
        }
  
+ #if 1 /* ROTATION */
 -      if (!pI830->MergedFB && pScrn->virtualX > pScrn->virtualY)
 +      if (pScrn->virtualX > pScrn->virtualY)
           size = lineSize * (pScrn->virtualX + cacheLines);
        else 
           size = lineSize * (pScrn->virtualY + cacheLines);
diff --cc src/i830_video.c
index 05f7f46,bbf1df7..83c032b
@@@ -114,9 -121,12 +121,12 @@@
  
  static void I830BlockHandler(int, pointer, pointer, pointer);
  
+ static FBLinearPtr
+ I830AllocateMemory(ScrnInfoPtr pScrn, FBLinearPtr linear, int size);
+ 
  #define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
  
 -static Atom xvBrightness, xvContrast, xvColorKey, xvPipe, xvDoubleBuffer;
 +static Atom xvBrightness, xvContrast, xvSaturation, xvColorKey, xvPipe, xvDoubleBuffer;
  static Atom xvGamma0, xvGamma1, xvGamma2, xvGamma3, xvGamma4, xvGamma5;
  
  #define IMAGE_MAX_WIDTH		1920
@@@ -502,9 -511,11 +512,11 @@@
     overlay->SWIDTHSW = 0;
     overlay->SHEIGHT = 0;
     overlay->OCLRC0 = (pPriv->contrast << 18) | (pPriv->brightness & 0xff);
 -   overlay->OCLRC1 = 0x00000080;	/* saturation: bypass */
 +   overlay->OCLRC1 = pPriv->saturation;
+ #if 0
     overlay->AWINPOS = 0;
     overlay->AWINSZ = 0;
+ #endif
     overlay->FASTHSCALE = 0;
  
     /*
@@@ -1427,21 -1573,24 +1589,12 @@@
     CompareOverlay(pI830, (CARD32 *) overlay, 0x100);
  #endif
  
-    /* When in dual head with different bpp setups we need to refresh the
-     * color key, so let's reset the video parameters and refresh here */
-    if (pI830->entityPrivate)
-       I830ResetVideo(pScrn);
- 
-    /* Ensure overlay is turned on with OVERLAY_ENABLE at 0 */
-    if (!*pI830->overlayOn)
-       OVERLAY_UPDATE;
- 
     switch (pI830->rotation) {
  	case RR_Rotate_0:
 -                if (pI830->MergedFB) {
 -		   memcpy(&dstBox2, dstBox, sizeof(BoxRec));
 -		   dstBox->x1 -= pI830->FirstframeX0;
 -		   dstBox->x2 -= pI830->FirstframeX0;
 -		   dstBox->y1 -= pI830->FirstframeY0;
 -		   dstBox->y2 -= pI830->FirstframeY0;
 -		   dstBox2.x1 -= pI830->pScrn_2->frameX0;
 -		   dstBox2.x2 -= pI830->pScrn_2->frameX0;
 -		   dstBox2.y1 -= pI830->pScrn_2->frameY0;
 -		   dstBox2.y2 -= pI830->pScrn_2->frameY0;
 -                } else {
 -		   dstBox->x1 -= pScrn->frameX0;
 -		   dstBox->x2 -= pScrn->frameX0;
 -		   dstBox->y1 -= pScrn->frameY0;
 -		   dstBox->y2 -= pScrn->frameY0;
 -                }
 +		dstBox->x1 -= pScrn->frameX0;
 +		dstBox->x2 -= pScrn->frameX0;
 +		dstBox->y1 -= pScrn->frameY0;
 +		dstBox->y2 -= pScrn->frameY0;
  		break;
  	case RR_Rotate_90:
  		tmp = dstBox->x1;
@@@ -1475,6 -1624,72 +1628,16 @@@
  		break;
     }
  
 -   if (pI830->MergedFB) {
 -      I830ModePrivatePtr mp = (I830ModePrivatePtr)pScrn->currentMode->Private;
 -      int w1, h1, w2, h2;
 -
 -      /* Clip the video to the independent modes of the merged screens */
 -      if (dstBox->x1 > mp->merged.First->HDisplay) dstBox->x1 = mp->merged.First->HDisplay - 1;
 -      if (dstBox->x2 > mp->merged.First->HDisplay) dstBox->x2 = mp->merged.First->HDisplay - 1;
 -      if (dstBox2.x1 > mp->merged.Second->HDisplay) dstBox2.x1 = mp->merged.Second->HDisplay - 1;
 -      if (dstBox2.x2 > mp->merged.Second->HDisplay) dstBox2.x2 = mp->merged.Second->HDisplay - 1;
 -      if (dstBox->y1 > mp->merged.First->VDisplay) dstBox->y1 = mp->merged.First->VDisplay - 1;
 -      if (dstBox->y2 > mp->merged.First->VDisplay) dstBox->y2 = mp->merged.First->VDisplay - 1;
 -      if (dstBox2.y1 > mp->merged.Second->VDisplay) dstBox2.y1 = mp->merged.Second->VDisplay - 1;
 -      if (dstBox2.y2 > mp->merged.Second->VDisplay) dstBox2.y2 = mp->merged.Second->VDisplay - 1;
 -      if (dstBox->y1 < 0) dstBox->y1 = 0;
 -      if (dstBox->y2 < 0) dstBox->y2 = 0;
 -      if (dstBox->x1 < 0) dstBox->x1 = 0;
 -      if (dstBox->x2 < 0) dstBox->x2 = 0;
 -      if (dstBox2.y1 < 0) dstBox2.y1 = 0;
 -      if (dstBox2.y2 < 0) dstBox2.y2 = 0;
 -      if (dstBox2.x1 < 0) dstBox2.x1 = 0;
 -      if (dstBox2.x2 < 0) dstBox2.x2 = 0;
 -
 -      w1 = dstBox->x2 - dstBox->x1;
 -      w2 = dstBox2.x2 - dstBox2.x1;
 -      h1 = dstBox->y2 - dstBox->y1;
 -      h2 = dstBox2.y2 - dstBox2.y1;
 -
 -      switch (pI830->SecondPosition) {
 -         case PosRightOf:
 -         case PosBelow:
 -            if ((w2 > 0 && w1 == 0) ||
 -                (h2 > 0 && h1 == 0)) {
 -               pPriv->pipe = !pI830->pipe;
 -               dstBox->x1 = dstBox2.x1;
 -               dstBox->y1 = dstBox2.y1;
 -               dstBox->x2 = dstBox2.x2;
 -               dstBox->y2 = dstBox2.y2;
 -            } else 
 -               pPriv->pipe = pI830->pipe;
 -            break;
 -         case PosLeftOf:
 -         case PosAbove:
 -            if ((w1 > 0 && w2 == 0) ||
 -                (h1 > 0 && h2 == 0)) { 
 -               pPriv->pipe = pI830->pipe;
 -            } else {
 -               pPriv->pipe = !pI830->pipe;
 -               dstBox->x1 = dstBox2.x1;
 -               dstBox->y1 = dstBox2.y1;
 -               dstBox->x2 = dstBox2.x2;
 -               dstBox->y2 = dstBox2.y2;
 -            }
 -            break;
 -      }
 -   }
 -
+    /* When in dual head with different bpp setups we need to refresh the
+     * color key, so let's reset the video parameters and refresh here.
+     * In MergedFB mode, we may need to flip pipes too. */
 -   if (pI830->entityPrivate || pI830->MergedFB)
++   if (pI830->entityPrivate)
+       I830ResetVideo(pScrn);
+ 
+    /* Ensure overlay is turned on with OVERLAY_ENABLE at 0 */
+    if (!*pI830->overlayOn)
+       OVERLAY_UPDATE;
+ 
     /* Fix up the dstBox if outside the visible screen */
     {
        int offset_x = (dstBox->x1 < 0) ? -dstBox->x1 : 0;
diff --cc src/i830_video.h
index 0000000,9e11641..6a09a25
mode 000000,100644..100644
@@@ -1,0 -1,76 +1,77 @@@
+ /***************************************************************************
+  
+ Copyright 2000 Intel Corporation.  All Rights Reserved. 
+ 
+ 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, sub license, 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 NON-INFRINGEMENT. 
+ IN NO EVENT SHALL INTEL, AND/OR ITS SUPPLIERS 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.
+ 
+ **************************************************************************/
+ 
+ #include "xf86.h"
+ #include "xf86_OSproc.h"
+ 
+ typedef struct {
+    CARD32 YBuf0offset;
+    CARD32 UBuf0offset;
+    CARD32 VBuf0offset;
+ 
+    CARD32 YBuf1offset;
+    CARD32 UBuf1offset;
+    CARD32 VBuf1offset;
+ 
+    unsigned char currentBuf;
+ 
+    int brightness;
+    int contrast;
++   int saturation;
+    int pipe;
+    int doubleBuffer;
+ 
+    RegionRec clip;
+    CARD32 colorKey;
+ 
+    CARD32 gamma0;
+    CARD32 gamma1;
+    CARD32 gamma2;
+    CARD32 gamma3;
+    CARD32 gamma4;
+    CARD32 gamma5;
+ 
+    CARD32 videoStatus;
+    Time offTime;
+    Time freeTime;
+    FBLinearPtr linear;
+ 
+    Bool overlayOK;
+    int oneLineMode;
+    int scaleRatio;
+    Bool textured;
+ } I830PortPrivRec, *I830PortPrivPtr;
+ 
+ #define GET_PORT_PRIVATE(pScrn) \
+    (I830PortPrivPtr)((I830PTR(pScrn))->adaptor->pPortPrivates[0].ptr)
+ 
+ void I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv,
+ 			      int id, RegionPtr dstRegion, short width,
+ 			      short height, int video_pitch,
+ 			      int x1, int y1, int x2, int y2,
+ 			      short src_w, short src_h,
+ 			      short drw_w, short drw_h,
+ 			      DrawablePtr pDraw);
diff-tree fdb6de663579d3b9f31bf9e8a93430b8505ca73f (from 1407a42c7378706644fd8be554b43b0e7b581011)
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Sep 27 13:59:41 2006 -0700

    Re-disable broken load-based CRT detection.

diff --git a/src/i830_display.c b/src/i830_display.c
index 88280bb..24ce50f 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -1081,7 +1081,7 @@ i830DetectCRT(ScrnInfoPtr pScrn, Bool al
      * pipe, as it seems having other outputs on that pipe will result in a
      * false positive.
      */
-    if (1 && (allow_disturb || !(INREG(ADPA) & !ADPA_DAC_ENABLE))) {
+    if (0 && (allow_disturb || !(INREG(ADPA) & !ADPA_DAC_ENABLE))) {
 	return i830LoadDetectCRT(pScrn);
     }
 
diff-tree 1407a42c7378706644fd8be554b43b0e7b581011 (from parents)
Merge: 25890ecda9fd00fad9bc53dea83fc58e0013fcdf 4bd3b89c73b6c5aa9b0eb553ad5d553ee0e8a489
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Sep 27 13:33:23 2006 -0700

    Merge branch 'randr-1.2' into modesetting

diff --cc src/i830_driver.c
index 5b98bfd,bc9b71a..b4f5394
@@@ -3342,11 -3498,17 +3328,14 @@@
     if (!vgaHWMapMem(pScrn))
        return FALSE;
  
 -   /* Clear SavedReg */
 -   memset(&pI830->SavedReg, 0, sizeof(pI830->SavedReg));
 -
 -   DPRINTF(PFX, "assert( if(!I830BIOSEnterVT(scrnIndex, 0)) )\n");
 +   DPRINTF(PFX, "assert( if(!I830EnterVT(scrnIndex, 0)) )\n");
  
 -   if (!I830BIOSEnterVT(scrnIndex, 0))
 +   if (!I830EnterVT(scrnIndex, 0))
        return FALSE;
  
+     if (pScrn->virtualX > pScrn->displayWidth)
+ 	pScrn->displayWidth = pScrn->virtualX;
+ 
     DPRINTF(PFX, "assert( if(!fbScreenInit(pScreen, ...) )\n");
     if (!fbScreenInit(pScreen, pI830->FbBase + pScrn->fbOffset, 
                       pScrn->virtualX, pScrn->virtualY,
diff-tree 25890ecda9fd00fad9bc53dea83fc58e0013fcdf (from parents)
Merge: 965609f6fa63e28e5a28128f5bc44f8c4d7b9f68 117ff04b504578a24dff70659e2db1b81aaa1177
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Sep 27 13:33:17 2006 -0700

    Merge branch 'acpi-hotkey' into modesetting
    
    Conflicts:
    
    	src/i830.h
    	src/i830_driver.c

diff --cc src/i830.h
index 92c9111,4a95441..19bdd74
@@@ -392,11 -393,12 +392,8 @@@
     CARD32 saveSWF4;
  
     Bool checkDevices;
-    int monitorSwitch;
     int operatingDevices;
-    int toggleDevices;
-    int lastDevice0, lastDevice1, lastDevice2;
  
 -   /* These are indexed by the display types */
 -   Bool displayAttached[NumDisplayTypes];
 -   Bool displayPresent[NumDisplayTypes];
 -
     /* [0] is Pipe A, [1] is Pipe B. */
     int availablePipes;
     /* [0] is display plane A, [1] is display plane B. */
diff --cc src/i830_driver.c
index 31e3b17,c3ae8c3..5b98bfd
@@@ -1190,8 -1107,33 +1080,33 @@@
     return TRUE;
  }
  
+ #define HOTKEY_BIOS_SWITCH	0
+ #define HOTKEY_DRIVER_NOTIFY	1
+ 
+ /**
+  * Controls the BIOS's behavior on hotkey switch.
+  *
+  * If the mode is HOTKEY_BIOS_SWITCH, the BIOS will be set to do a mode switch
+  * on its own and update the state in the scratch register.
+  * If the mode is HOTKEY_DRIVER_NOTIFY, the BIOS won't do a mode switch and
+  * will just update the state to represent what it would have been switched to.
+  */
+ static void
+ i830SetHotkeyControl(ScrnInfoPtr pScrn, int mode)
+ {
+    I830Ptr pI830 = I830PTR(pScrn);
+    CARD8 gr18;
+ 
+    gr18 = pI830->readControl(pI830, GRX, 0x18);
+    if (mode == HOTKEY_BIOS_SWITCH)
+       gr18 &= ~HOTKEY_VBIOS_SWITCH_BLOCK;
+    else
+       gr18 |= HOTKEY_VBIOS_SWITCH_BLOCK;
+    pI830->writeControl(pI830, GRX, 0x18, gr18);
+ }
+ 
  static Bool
 -I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
 +I830PreInit(ScrnInfoPtr pScrn, int flags)
  {
     vgaHWPtr hwp;
     I830Ptr pI830;
diff-tree 117ff04b504578a24dff70659e2db1b81aaa1177 (from daade50ca271d1cdf236bbe84afade85d4111ac9)
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Sep 21 17:03:34 2006 -0700

    Attempt to make the ACPI hotkey support a little more modesetting-compatible.
    
    Previously, we watched for the BIOS to have changed the layout, and repaired
    the resulting configuration.  Now, we request that the BIOS make no changes,
    but leave a note in a register for when the key has been pressed.  When we
    notice this, we reprobe monitors and turn on/off the things we find.
    
    This is a temporary solution until we can get the hotkey hooked up as an
    input key to external applications to control the change using RandR 1.2.  It
    is also untested as neither of my laptops do anything with the hotkey.
    However, this code does result in many fewer BIOS calls.

diff --git a/src/i810_reg.h b/src/i810_reg.h
index 275d858..3a15a46 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -94,6 +94,10 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define LINEAR_MODE_ENABLE     0x02
 #define PAGE_MAPPING_ENABLE    0x01
 
+#define HOTKEY_VBIOS_SWITCH_BLOCK	0x80
+#define HOTKEY_SWITCH			0x20
+#define HOTKEY_TOGGLE			0x10
+
 /* Blitter control, p378
  */
 #define BITBLT_CNTL        0x7000c
diff --git a/src/i830.h b/src/i830.h
index 3a93931..4a95441 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -393,10 +393,7 @@ typedef struct _I830Rec {
    CARD32 saveSWF4;
 
    Bool checkDevices;
-   int monitorSwitch;
    int operatingDevices;
-   int toggleDevices;
-   int lastDevice0, lastDevice1, lastDevice2;
 
    /* These are indexed by the display types */
    Bool displayAttached[NumDisplayTypes];
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 75ea480..c3ae8c3 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -438,116 +438,6 @@ Check5fStatus(ScrnInfoPtr pScrn, int fun
    }
 }
 
-static int
-GetToggleList(ScrnInfoPtr pScrn, int toggle)
-{
-   vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe;
-
-   DPRINTF(PFX, "GetToggleList\n");
-
-   pVbe->pInt10->num = 0x10;
-   pVbe->pInt10->ax = 0x5f64;
-   pVbe->pInt10->bx = 0x500;
- 
-   pVbe->pInt10->bx |= toggle;
-
-   xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);
-   if (Check5fStatus(pScrn, 0x5f64, pVbe->pInt10->ax)) {
-      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Toggle (%d) 0x%x\n", toggle, pVbe->pInt10->cx);
-      return pVbe->pInt10->cx & 0xffff;
-   }
-
-   return 0;
-}
-
-static int
-GetNextDisplayDeviceList(ScrnInfoPtr pScrn, int toggle)
-{
-   vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe;
-   int devices = 0;
-   int pipe = 0;
-   int i;
-
-   DPRINTF(PFX, "GetNextDisplayDeviceList\n");
-
-   pVbe->pInt10->num = 0x10;
-   pVbe->pInt10->ax = 0x5f64;
-   pVbe->pInt10->bx = 0xA00;
-   pVbe->pInt10->bx |= toggle;
-   pVbe->pInt10->es = SEG_ADDR(pVbe->real_mode_base);
-   pVbe->pInt10->di = SEG_OFF(pVbe->real_mode_base);
-
-   xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);
-   if (!Check5fStatus(pScrn, 0x5f64, pVbe->pInt10->ax))
-      return 0;
-
-   for (i=0; i<(pVbe->pInt10->cx & 0xff); i++) {
-      CARD32 VODA = (CARD32)((CARD32*)pVbe->memory)[i];
-
-      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Next ACPI _DGS [%d] 0x%lx\n",
-		 i, (unsigned long) VODA);
-
-      /* Check if it's a custom Video Output Device Attribute */
-      if (!(VODA & 0x80000000)) 
-         continue;
-
-      pipe = (VODA & 0x000000F0) >> 4;
-
-      if (pipe != 0 && pipe != 1) {
-         pipe = 0;
-#if 0
-         ErrorF("PIPE %d\n",pipe);
-#endif
-      }
-
-      switch ((VODA & 0x00000F00) >> 8) {
-      case 0x0:
-      case 0x1: /* CRT */
-         devices |= PIPE_CRT << (pipe == 1 ? 8 : 0);
-         break;
-      case 0x2: /* TV/HDTV */
-         devices |= PIPE_TV << (pipe == 1 ? 8 : 0);
-         break;
-      case 0x3: /* DFP */
-         devices |= PIPE_DFP << (pipe == 1 ? 8 : 0);
-         break;
-      case 0x4: /* LFP */
-         devices |= PIPE_LFP << (pipe == 1 ? 8 : 0);
-         break;
-      }
-   }
-
-   xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ACPI Toggle devices 0x%x\n", devices);
-
-   return devices;
-}
-
-static int
-GetAttachableDisplayDeviceList(ScrnInfoPtr pScrn)
-{
-   vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe;
-   int i;
-
-   DPRINTF(PFX, "GetAttachableDisplayDeviceList\n");
-
-   pVbe->pInt10->num = 0x10;
-   pVbe->pInt10->ax = 0x5f64;
-   pVbe->pInt10->bx = 0x900;
-   pVbe->pInt10->es = SEG_ADDR(pVbe->real_mode_base);
-   pVbe->pInt10->di = SEG_OFF(pVbe->real_mode_base);
-
-   xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);
-   if (!Check5fStatus(pScrn, 0x5f64, pVbe->pInt10->ax))
-      return 0;
-
-   for (i=0; i<(pVbe->pInt10->cx & 0xff); i++)
-        xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
-		"Attachable device 0x%lx.\n", 
-		   (unsigned long) ((CARD32*)pVbe->memory)[i]);
-
-   return pVbe->pInt10->cx & 0xffff;
-}
-
 struct panelid {
 	short hsize;
 	short vsize;
@@ -1217,6 +1107,31 @@ I830IsPrimary(ScrnInfoPtr pScrn)
    return TRUE;
 }
 
+#define HOTKEY_BIOS_SWITCH	0
+#define HOTKEY_DRIVER_NOTIFY	1
+
+/**
+ * Controls the BIOS's behavior on hotkey switch.
+ *
+ * If the mode is HOTKEY_BIOS_SWITCH, the BIOS will be set to do a mode switch
+ * on its own and update the state in the scratch register.
+ * If the mode is HOTKEY_DRIVER_NOTIFY, the BIOS won't do a mode switch and
+ * will just update the state to represent what it would have been switched to.
+ */
+static void
+i830SetHotkeyControl(ScrnInfoPtr pScrn, int mode)
+{
+   I830Ptr pI830 = I830PTR(pScrn);
+   CARD8 gr18;
+
+   gr18 = pI830->readControl(pI830, GRX, 0x18);
+   if (mode == HOTKEY_BIOS_SWITCH)
+      gr18 &= ~HOTKEY_VBIOS_SWITCH_BLOCK;
+   else
+      gr18 |= HOTKEY_VBIOS_SWITCH_BLOCK;
+   pI830->writeControl(pI830, GRX, 0x18, gr18);
+}
+
 static Bool
 I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
 {
@@ -2179,28 +2094,6 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int f
    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
 	      "Maximum frambuffer space: %d kByte\n", pScrn->videoRam);
 
-   /* XXX Move this to a header. */
-#define VIDEO_BIOS_SCRATCH 0x18
-
-#if 1
-   /*
-    * XXX This should be in ScreenInit/EnterVT.  PreInit should not leave the
-    * state changed.
-    */
-   /* Enable hot keys by writing the proper value to GR18 */
-   {
-      CARD8 gr18;
-
-      gr18 = pI830->readControl(pI830, GRX, VIDEO_BIOS_SCRATCH);
-      gr18 &= ~0x80;			/*
-					 * Clear Hot key bit so that Video
-					 * BIOS performs the hot key
-					 * servicing
-					 */
-      pI830->writeControl(pI830, GRX, VIDEO_BIOS_SCRATCH, gr18);
-   }
-#endif
-
    /*
     * Limit videoram available for mode selection to what the video
     * BIOS can see.
@@ -3734,6 +3627,8 @@ I830BIOSLeaveVT(int scrnIndex, int flags
       TimerCancel(pI830->devicesTimer);
    pI830->devicesTimer = NULL;
 
+   i830SetHotkeyControl(pScrn, HOTKEY_BIOS_SWITCH);
+
 #ifdef I830_XV
    /* Give the video overlay code a chance to shutdown. */
    I830VideoSwitchModeBefore(pScrn, NULL);
@@ -3951,9 +3846,6 @@ I830BIOSEnterVT(int scrnIndex, int flags
 	  pScrn->virtualY * pScrn->displayWidth * pI830->cpp);
 #endif
 
-   /* Setup for device monitoring status */
-   pI830->monitorSwitch = pI830->toggleDevices = INREG(SWF0) & 0x0000FFFF;
-
    if (I830IsPrimary(pScrn))
       if (!I830BindAGPMemory(pScrn))
          return FALSE;
@@ -4003,6 +3895,13 @@ I830BIOSEnterVT(int scrnIndex, int flags
    }
 #endif
 
+   /* Set the hotkey to just notify us.  We can check its results periodically
+    * in the CheckDevicesTimer.  Eventually we want the kernel to just hand us
+    * an input event when someone presses the button, but for now we just have
+    * to poll.
+    */
+   i830SetHotkeyControl(pScrn, HOTKEY_DRIVER_NOTIFY);
+
    if (pI830->checkDevices)
       pI830->devicesTimer = TimerSet(NULL, 0, 1000, I830CheckDevicesTimer, pScrn);
 
@@ -4367,15 +4266,6 @@ I830PMEvent(int scrnIndex, pmEvent event
 
       ErrorF("I830PMEvent: Capability change\n");
 
-      /* ACPI Toggle */
-      pI830->toggleDevices = GetNextDisplayDeviceList(pScrn, 1);
-      if (xf86IsEntityShared(pScrn->entityList[0])) {
-         I830Ptr pI8302 = I830PTR(pI830->entityPrivate->pScrn_2);
-         pI8302->toggleDevices = pI830->toggleDevices;
-      }
-
-      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ACPI Toggle to 0x%x\n",pI830->toggleDevices);
-
       I830CheckDevicesTimer(NULL, 0, pScrn);
       SaveScreens(SCREEN_SAVER_FORCER, ScreenSaverReset);
       break;
@@ -4385,27 +4275,16 @@ I830PMEvent(int scrnIndex, pmEvent event
    return TRUE;
 }
 
-static int CountBits(int a)
-{
-   int i;
-   int b = 0;
-
-   for (i=0;i<8;i++) {
-     if (a & (1<<i))
-        b+=1;
-   }
-
-   return b;
-}
-
-static CARD32
-I830CheckDevicesTimer(OsTimerPtr timer, CARD32 now, pointer arg)
-{
-   ScrnInfoPtr pScrn = (ScrnInfoPtr) arg;
-   I830Ptr pI830 = I830PTR(pScrn);
-   int cloned = 0;
 #if 0
+/**
+ * This function is used for testing of the screen detect functions from the
+ * periodic timer.
+ */
+static void
+i830MonitorDetectDebugger(ScrnInfoPtr pScrn)
+{
    Bool found_crt;
+   I830Ptr pI830 = I830PTR(pScrn);
    int start, finish, i;
 
    if (!pScrn->vtSema)
@@ -4431,303 +4310,41 @@ I830CheckDevicesTimer(OsTimerPtr timer, 
       xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Detected SDVO as %s in %dms\n",
 		 found_sdvo ? "connected" : "disconnected", finish - start);
    }
+}
 #endif
 
-   if (pScrn->vtSema) {
-      /* Check for monitor lid being closed/opened and act accordingly */
-      CARD32 adjust;
-      CARD32 temp = INREG(SWF0) & 0x0000FFFF;
-      int fixup = 0;
-      I830Ptr pI8301;
-      I830Ptr pI8302 = NULL;
-
-      if (I830IsPrimary(pScrn))
-         pI8301 = pI830;
-      else 
-         pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
-
-      if (xf86IsEntityShared(pScrn->entityList[0]))
-         pI8302 = I830PTR(pI830->entityPrivate->pScrn_2);
-
-      /* this avoids several BIOS calls if possible */
-      if (pI830->monitorSwitch != temp || pI830->monitorSwitch != pI830->toggleDevices) {
-         xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
-		    "Hotkey switch to 0x%lx.\n", (unsigned long) temp);
-
-         if (pI830->AccelInfoRec && pI830->AccelInfoRec->NeedToSync) {
-            (*pI830->AccelInfoRec->Sync)(pScrn);
-            pI830->AccelInfoRec->NeedToSync = FALSE;
-            if (xf86IsEntityShared(pScrn->entityList[0]))
-               pI8302->AccelInfoRec->NeedToSync = FALSE;
-         }
-
-         GetAttachableDisplayDeviceList(pScrn);
-         
-	 pI8301->lastDevice0 = pI8301->lastDevice1;
-         pI8301->lastDevice1 = pI8301->lastDevice2;
-         pI8301->lastDevice2 = pI8301->monitorSwitch;
-
-	 if (temp != pI8301->lastDevice1 && 
-	     temp != pI8301->lastDevice2) {
-            xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
-			"Detected three device configs.\n");
-	 } else
-         if (CountBits(temp & 0xff) > 1) {
-            xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
-			"Detected cloned pipe mode (A).\n");
-            if (xf86IsEntityShared(pScrn->entityList[0]) || pI830->Clone)
-	       temp = pI8301->MonType2 << 8 | pI8301->MonType1;
-         } else
-         if (CountBits((temp & 0xff00) >> 8) > 1) {
-            xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
-			"Detected cloned pipe mode (B).\n");
-            if (xf86IsEntityShared(pScrn->entityList[0]) || pI830->Clone)
-	       temp = pI8301->MonType2 << 8 | pI8301->MonType1;
-         } else
-         if (pI8301->lastDevice1 && pI8301->lastDevice2) {
-            if ( ((pI8301->lastDevice1 & 0xFF00) == 0) && 
-                 ((pI8301->lastDevice2 & 0x00FF) == 0) ) {
-               xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
-			"Detected last devices (1).\n");
-	       cloned = 1;
-            } else if ( ((pI8301->lastDevice2 & 0xFF00) == 0) && 
-                 ((pI8301->lastDevice1 & 0x00FF) == 0) ) {
-               xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
-			"Detected last devices (2).\n");
-	       cloned = 1;
-            } else
-               cloned = 0;
-         }
-
-         if (cloned &&
-             ((CountBits(pI8301->lastDevice1 & 0xff) > 1) ||
-             ((CountBits((pI8301->lastDevice1 & 0xff00) >> 8) > 1))) ) {
-               xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
-			"Detected duplicate (1).\n");
-               cloned = 0;
-         } else
-         if (cloned &&
-             ((CountBits(pI8301->lastDevice2 & 0xff) > 1) ||
-             ((CountBits((pI8301->lastDevice2 & 0xff00) >> 8) > 1))) ) {
-               xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
-			"Detected duplicate (2).\n");
-               cloned = 0;
-         } 
-
-         xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
-			"Requested display devices 0x%lx.\n", 
-		    (unsigned long) temp);
-
-
-         /* If the BIOS doesn't flip between CRT, LFP and CRT+LFP we fake
-          * it here as it seems some just flip between CRT and LFP. Ugh!
-          *
-          * So this pushes them onto Pipe B and clones the displays, which
-          * is what most BIOS' should be doing.
-          *
-          * Cloned pipe mode should only be done when running single head.
-          */
-         if (xf86IsEntityShared(pScrn->entityList[0])) {
-            cloned = 0;
-
-	    /* Some BIOS' don't realize we may be in true dual head mode.
-	     * And only display the primary output on both when switching.
-	     * We detect this here and cycle back to both pipes.
-	     */
-	    if ((pI830->lastDevice0 == temp) &&
-                ((CountBits(pI8301->lastDevice2 & 0xff) > 1) ||
-                ((CountBits((pI8301->lastDevice2 & 0xff00) >> 8) > 1))) ) {
-               xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
-			"Detected cloned pipe mode when dual head on previous switch. (0x%x -> 0x%x)\n", (int)temp, pI8301->MonType2 << 8 | pI8301->MonType1);
-	       temp = pI8301->MonType2 << 8 | pI8301->MonType1;
-	    }
-	    
-	 }
-
-         if (cloned) { 
-            if (pI830->Clone)
-               temp = pI8301->MonType2 << 8 | pI8301->MonType1;
-	    else if (pI8301->lastDevice1 & 0xFF)
-	       temp = pI8301->lastDevice1 << 8 | pI8301->lastDevice2;
-            else
-	       temp = pI8301->lastDevice2 << 8 | pI8301->lastDevice1;
-         } 
-
-         /* Jump to our next mode if we detect we've been here before */
-         if (temp == pI8301->lastDevice1 || temp == pI8301->lastDevice2) {
-             temp = GetToggleList(pScrn, 1);
-             xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
-			"Detected duplicate devices. Toggling (0x%lx)\n", 
-			(unsigned long) temp);
-         }
-
-         xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
-		"Detected display change operation (0x%x, 0x%x, 0x%lx).\n", 
-                pI8301->lastDevice1, pI8301->lastDevice2, 
-		    (unsigned long) temp);
-
-         /* So that if we close on the wrong config, we restore correctly */
-         pI830->specifiedMonitor = TRUE;
-
-         if (!xf86IsEntityShared(pScrn->entityList[0])) {
-            if ((temp & 0xFF00) && (temp & 0x00FF)) {
-               pI830->Clone = TRUE;
-               xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting Clone mode\n");
-            } else {
-               pI830->Clone = FALSE;
-               xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clearing Clone mode\n");
-            }
-         }
-
-         {
-            /* Turn Cursor off before switching */
-            Bool on = pI830->cursorOn;
-            if (pI830->CursorInfoRec && pI830->CursorInfoRec->HideCursor)
-               pI830->CursorInfoRec->HideCursor(pScrn);
-            pI830->cursorOn = on;
-         }
-
-#if 0 /* Disable -- I'll need to look at this whole function later. */
-         /* double check the display devices are what's configured and try
-          * not to do it twice because of dual heads with the code above */
-         if (!SetDisplayDevices(pScrn, temp)) {
-            if ( cloned &&
-                    ((CountBits(temp & 0xff) > 1) ||
-                     (CountBits((temp & 0xff00) >> 8) > 1)) ) {
-	       temp = pI8301->lastDevice2 | pI8301->lastDevice1;
-               xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Cloning failed, "
-			  "trying dual pipe clone mode (0x%lx)\n", 
-			  (unsigned long) temp);
-               if (!SetDisplayDevices(pScrn, temp))
-                    xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Failed to switch "
- 		    "to configured display devices (0x%lx).\n", 
-			       (unsigned long) temp);
-               else {
-                 pI830->Clone = TRUE;
-                 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting Clone mode\n");
-               }
-            }
-         }
-#endif
-
-         pI8301->monitorSwitch = temp;
-	 pI8301->operatingDevices = temp;
-	 pI8301->toggleDevices = temp;
-
-         if (xf86IsEntityShared(pScrn->entityList[0])) {
-	    pI8302->operatingDevices = pI8301->operatingDevices;
-            pI8302->monitorSwitch = pI8301->monitorSwitch;
-	    pI8302->toggleDevices = pI8301->toggleDevices;
-         }
+static CARD32
+I830CheckDevicesTimer(OsTimerPtr timer, CARD32 now, pointer arg)
+{
+   ScrnInfoPtr pScrn = (ScrnInfoPtr) arg;
+   I830Ptr pI830 = I830PTR(pScrn);
+   CARD8 gr18;
 
-         fixup = 1;
+   if (!pScrn->vtSema)
+      return 1000;
 
 #if 0
-         xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
-			"ACPI _DGS queried devices is 0x%x, but probed is 0x%x monitorSwitch=0x%x\n", 
-			pI830->toggleDevices, INREG(SWF0), pI830->monitorSwitch);
+   i830MonitorDetectDebugger(pScrn);
 #endif
-      } else {
-         int offset = -1;
-         if (I830IsPrimary(pScrn))
-            offset = pI8301->FrontBuffer.Start + ((pScrn->frameY0 * pI830->displayWidth + pScrn->frameX0) * pI830->cpp);
-         else {
-            offset = pI8301->FrontBuffer2.Start + ((pScrn->frameY0 * pI830->displayWidth + pScrn->frameX0) * pI830->cpp);
-	 }
-
-         if (pI830->pipe == 0)
-            adjust = INREG(DSPABASE);
-         else 
-            adjust = INREG(DSPBBASE);
-
-         if (adjust != offset) {
-            xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-			                       "Fixing display offsets.\n");
-
-            i830AdjustFrame(pScrn->pScreen->myNum, pScrn->frameX0, pScrn->frameY0, 0);
-         }
-      }
-
-      if (fixup) {
-         ScreenPtr   pCursorScreen;
-         int x = 0, y = 0;
-
 
-         pCursorScreen = miPointerCurrentScreen();
-         if (pScrn->pScreen == pCursorScreen)
-            miPointerPosition(&x, &y);
-
-         /* Now, when we're single head, make sure we switch pipes */
-         if (!(xf86IsEntityShared(pScrn->entityList[0]) || pI830->Clone) || cloned) {
-            if (temp & 0xFF00)
-               pI830->pipe = 1;
-            else 
-               pI830->pipe = 0;
-	       xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-			 "Primary pipe is now %s.\n", pI830->pipe ? "B" : "A");
-         } 
-
-         pI830->currentMode = NULL;
-         I830BIOSSwitchMode(pScrn->pScreen->myNum, pScrn->currentMode, 0);
-         i830AdjustFrame(pScrn->pScreen->myNum, pScrn->frameX0, pScrn->frameY0, 0);
-
-         if (xf86IsEntityShared(pScrn->entityList[0])) {
-	    ScrnInfoPtr pScrn2;
-            I830Ptr pI8302;
-
-            if (I830IsPrimary(pScrn)) {
-	       pScrn2 = pI830->entityPrivate->pScrn_2;
-               pI8302 = I830PTR(pI830->entityPrivate->pScrn_2);
-            } else {
-	       pScrn2 = pI830->entityPrivate->pScrn_1;
-               pI8302 = I830PTR(pI830->entityPrivate->pScrn_1);
-            }
-
-            if (pScrn2->pScreen == pCursorScreen)
-               miPointerPosition(&x, &y);
-
-            pI8302->currentMode = NULL;
-            I830BIOSSwitchMode(pScrn2->pScreen->myNum, pScrn2->currentMode, 0);
-            i830AdjustFrame(pScrn2->pScreen->myNum, pScrn2->frameX0, pScrn2->frameY0, 0);
-
- 	    (*pScrn2->EnableDisableFBAccess) (pScrn2->pScreen->myNum, FALSE);
- 	    (*pScrn2->EnableDisableFBAccess) (pScrn2->pScreen->myNum, TRUE);
-
-            if (pScrn2->pScreen == pCursorScreen) {
-               int sigstate = xf86BlockSIGIO ();
-               miPointerWarpCursor(pScrn2->pScreen,x,y);
-
-               /* xf86Info.currentScreen = pScrn->pScreen; */
-               xf86UnblockSIGIO (sigstate);
-               if (pI8302->CursorInfoRec && !pI8302->SWCursor && pI8302->cursorOn) {
-                  pI8302->CursorInfoRec->HideCursor(pScrn);
-	          xf86SetCursor(pScrn2->pScreen, pI830->pCurs, x, y);
-                  pI8302->CursorInfoRec->ShowCursor(pScrn);
-                  pI8302->cursorOn = TRUE;
-               }
-            }
-	 }
-
- 	 (*pScrn->EnableDisableFBAccess) (pScrn->pScreen->myNum, FALSE);
- 	 (*pScrn->EnableDisableFBAccess) (pScrn->pScreen->myNum, TRUE);
+   /* Check for a hotkey press report from the BIOS. */
+   gr18 = pI830->readControl(pI830, GRX, 0x18);
+   if ((gr18 & (HOTKEY_TOGGLE | HOTKEY_SWITCH)) != 0) {
+      /* The user has pressed the hotkey requesting a toggle or switch.
+       * Re-probe our connected displays and turn on whatever we find.
+       *
+       * In the future, we want the hotkey to dump down to a user app which
+       * implements a sensible policy using RandR-1.2.  For now, all we get
+       * is this.
+       */
+      I830ValidateXF86ModeList(pScrn, FALSE);
+      xf86SwitchMode(pScrn->pScreen, pScrn->currentMode);
 
-         if (pScrn->pScreen == pCursorScreen) {
-            int sigstate = xf86BlockSIGIO ();
-            miPointerWarpCursor(pScrn->pScreen,x,y);
-
-            /* xf86Info.currentScreen = pScrn->pScreen; */
-            xf86UnblockSIGIO (sigstate);
-            if (pI830->CursorInfoRec && !pI830->SWCursor && pI830->cursorOn) {
-               pI830->CursorInfoRec->HideCursor(pScrn);
-	       xf86SetCursor(pScrn->pScreen, pI830->pCurs, x, y);
-               pI830->CursorInfoRec->ShowCursor(pScrn);
-               pI830->cursorOn = TRUE;
-            }
-         }
-      }
+      /* Clear the BIOS's hotkey press flags */
+      gr18 &= ~(HOTKEY_TOGGLE | HOTKEY_SWITCH);
+      pI830->writeControl(pI830, GRX, 0x18, gr18);
    }
 
-  
    return 1000;
 }
 
diff-tree 4bd3b89c73b6c5aa9b0eb553ad5d553ee0e8a489 (from c34490bbda6604a21809d15c798607806fa6c725)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Sat Sep 23 16:41:38 2006 +0100

    Oops, duplicated CRT-redetect code.

diff --git a/src/i830_randr.c b/src/i830_randr.c
index d86911c..d973173 100644
--- a/src/i830_randr.c
+++ b/src/i830_randr.c
@@ -776,12 +776,6 @@ I830RandRGetInfo12 (ScreenPtr pScreen, R
     I830Ptr		pI830 = I830PTR(pScrn);
     int			found_crt;
 
-    /* Re-probe the outputs for new monitors or modes */
-    pI830->operatingDevices = pI830->operatingDevices & ~PIPE_CRT;
-    found_crt = i830DetectCRT(pScrn, FALSE);
-    if (found_crt)
-        pI830->operatingDevices = pI830->operatingDevices | PIPE_CRT;
-
     I830ValidateXF86ModeList(pScrn, FALSE);
     return I830RandRSetInfo12 (pScreen);
 }
diff-tree c34490bbda6604a21809d15c798607806fa6c725 (from 4820caf46e050761d9b347b8a440381e1b1f4727)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Sat Sep 23 12:00:43 2006 +0100

    Construct default monitor description for hotplug non-DDC monitor.
    
    When detecting a monitor that doesn't support DDC, construct a default
    monitor with "sensible" values instead of using whatever the builtin LCD
    screen uses. Clearly we need a way to set the monitor parameters when we
    cannot detect them.

diff --git a/src/i830_display.c b/src/i830_display.c
index 24ce50f..88280bb 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -1081,7 +1081,7 @@ i830DetectCRT(ScrnInfoPtr pScrn, Bool al
      * pipe, as it seems having other outputs on that pipe will result in a
      * false positive.
      */
-    if (0 && (allow_disturb || !(INREG(ADPA) & !ADPA_DAC_ENABLE))) {
+    if (1 && (allow_disturb || !(INREG(ADPA) & !ADPA_DAC_ENABLE))) {
 	return i830LoadDetectCRT(pScrn);
     }
 
diff --git a/src/i830_modes.c b/src/i830_modes.c
index 3b70d5d..3d2b8f3 100644
--- a/src/i830_modes.c
+++ b/src/i830_modes.c
@@ -685,6 +685,36 @@ i830GetConfiguredMonitor(ScrnInfoPtr pSc
     return mon;
 }
 
+static MonPtr
+i830GetDefaultMonitor(ScrnInfoPtr pScrn)
+{
+    MonPtr mon;
+
+    mon = xnfcalloc(1, sizeof(*mon));
+
+    mon->id = xnfstrdup("Unknown Id");
+    mon->vendor = xnfstrdup("Unknown Vendor");
+    mon->model = xnfstrdup("Unknown Model");
+
+    mon->nHsync = 1;
+    mon->hsync[0].lo = 31.0;
+    mon->hsync[0].hi = 100.0;
+    mon->nVrefresh = 1;
+    mon->vrefresh[0].lo = 50.0;
+    mon->vrefresh[0].hi = 70.0;
+    mon->widthmm = 400;
+    mon->heightmm = 300;
+    /* Use VESA standard and user modelines, and do additional validation
+     * on them beyond what pipe config will do (x/y/pitch, clocks, flags)
+     */
+    mon->Modes = i830DuplicateModes(pScrn, pScrn->monitor->Modes);
+    i830xf86ValidateModesSync(pScrn, mon->Modes, mon);
+    i830xf86PruneInvalidModes(pScrn, &mon->Modes, TRUE);
+    mon->Last = i830GetModeListTail(mon->Modes);
+
+    return mon;
+}
+
 static void
 i830FreeMonitor(ScrnInfoPtr pScrn, MonPtr mon)
 {
@@ -771,8 +801,12 @@ I830ReprobePipeModeList(ScrnInfoPtr pScr
 	     * know if a monitor is attached, and this detect process should be
 	     * infrequent.
 	     */
-	    if (i830DetectCRT(pScrn, TRUE))
-		pI830->pipeMon[pipe] = i830GetConfiguredMonitor(pScrn);
+	    if (i830DetectCRT(pScrn, TRUE)) {
+/*		if (pipe == pI830->pipe)
+		    pI830->pipeMon[pipe] = i830GetConfiguredMonitor(pScrn);
+		else */
+		    pI830->pipeMon[pipe] = i830GetDefaultMonitor(pScrn);
+	    }
 	    break;
 	default:
 	    pI830->pipeMon[pipe] = i830GetConfiguredMonitor(pScrn);
diff --git a/src/i830_randr.c b/src/i830_randr.c
index 7c67aea..d86911c 100644
--- a/src/i830_randr.c
+++ b/src/i830_randr.c
@@ -773,7 +773,15 @@ static Bool
 I830RandRGetInfo12 (ScreenPtr pScreen, Rotation *rotations)
 {
     ScrnInfoPtr		pScrn = xf86Screens[pScreen->myNum];
+    I830Ptr		pI830 = I830PTR(pScrn);
+    int			found_crt;
+
     /* Re-probe the outputs for new monitors or modes */
+    pI830->operatingDevices = pI830->operatingDevices & ~PIPE_CRT;
+    found_crt = i830DetectCRT(pScrn, FALSE);
+    if (found_crt)
+        pI830->operatingDevices = pI830->operatingDevices | PIPE_CRT;
+
     I830ValidateXF86ModeList(pScrn, FALSE);
     return I830RandRSetInfo12 (pScreen);
 }
diff-tree 4820caf46e050761d9b347b8a440381e1b1f4727 (from c11c445bdeac34253b48192a5d406b55ff8b2be7)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Thu Sep 21 01:47:27 2006 -0700

    Make planeEnabled track pipes controlled by randr.
    
    Also add code to deal with disabling pipes.

diff --git a/src/i830_display.c b/src/i830_display.c
index 3bd662d..24ce50f 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -719,7 +719,7 @@ i830PipeSetMode(ScrnInfoPtr pScrn, Displ
     return TRUE;
 }
 
-static void
+void
 i830DisableUnusedFunctions(ScrnInfoPtr pScrn)
 {
     I830Ptr pI830 = I830PTR(pScrn);
diff --git a/src/i830_display.h b/src/i830_display.h
index e5bca1c..2b808ad 100644
--- a/src/i830_display.h
+++ b/src/i830_display.h
@@ -27,6 +27,7 @@
 
 /* i830_display.c */
 Bool i830PipeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe);
+void i830DisableUnusedFunctions(ScrnInfoPtr pScrn);
 Bool i830SetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode);
 Bool i830DetectCRT(ScrnInfoPtr pScrn, Bool allow_disturb);
 void i830SetLVDSPanelPower(ScrnInfoPtr pScrn, Bool on);
diff --git a/src/i830_randr.c b/src/i830_randr.c
index 4132eb2..7c67aea 100644
--- a/src/i830_randr.c
+++ b/src/i830_randr.c
@@ -548,7 +548,7 @@ I830RandRCrtcSet (ScreenPtr	pScreen,
     ScrnInfoPtr		pScrn = xf86Screens[pScreen->myNum];
     I830Ptr		pI830 = I830PTR(pScrn);
     int			pipe = (int) (crtc->devPrivate);
-    DisplayModePtr	display_mode = mode->devPrivate;
+    DisplayModePtr	display_mode = mode ? mode->devPrivate : NULL;
     
     /* Sync the engine before adjust mode */
     if (pI830->AccelInfoRec && pI830->AccelInfoRec->NeedToSync) {
@@ -558,8 +558,24 @@ I830RandRCrtcSet (ScreenPtr	pScreen,
 
     if (display_mode != randrp->modes[pipe])
     {
-	if (!i830PipeSetMode (pScrn, display_mode, pipe))
-	    return FALSE;
+	pI830->planeEnabled[pipe] = mode != NULL;
+	if (display_mode)
+	{
+	    if (!i830PipeSetMode (pScrn, display_mode, pipe))
+		return FALSE;
+	    /* XXX need I830SDVOPostSetMode here */
+	}
+	else
+	{
+	    CARD32  operatingDevices = pI830->operatingDevices;
+
+	    if (pipe == 0)
+		pI830->operatingDevices &= ~0xff;
+	    else
+		pI830->operatingDevices &= ~0xff00;
+	    i830DisableUnusedFunctions (pScrn);
+	    pI830->operatingDevices = operatingDevices;
+	}
 	randrp->modes[pipe] = display_mode;
     }
     i830PipeSetBase(pScrn, pipe, x, y);
diff-tree c11c445bdeac34253b48192a5d406b55ff8b2be7 (from 4a8b9515e914369e1faf1dca6b11204b233c73ee)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Thu Sep 21 01:23:10 2006 -0700

    Consistently use Cursor A on Pipe 0 and Cursor B on Pipe 1.
    
    Mixing random cursors and pipes didn't work very well. I'm left wondering
    whether the palette stuff will work on pre-9xx series hardware though; it is
    special cased everwhere else.

diff --git a/src/i830.h b/src/i830.h
index fcd03ef..a0ded02 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -534,7 +534,7 @@ extern void I830SetMMIOAccess(I830Ptr pI
 extern void I830PrintErrorState(ScrnInfoPtr pScrn);
 extern void I830Sync(ScrnInfoPtr pScrn);
 extern void I830InitHWCursor(ScrnInfoPtr pScrn);
-extern void I830SetPipeCursor (ScrnInfoPtr pScrn, int pipe);
+extern void I830SetPipeCursor (ScrnInfoPtr pScrn, int pipe, Bool force);
 extern Bool I830CursorInit(ScreenPtr pScreen);
 extern void I830EmitInvarientState(ScrnInfoPtr pScrn);
 extern void I830SelectBuffer(ScrnInfoPtr pScrn, int buffer);
diff --git a/src/i830_cursor.c b/src/i830_cursor.c
index 1e7beef..7389b66 100644
--- a/src/i830_cursor.c
+++ b/src/i830_cursor.c
@@ -80,7 +80,7 @@ static Bool I830UseHWCursorARGB(ScreenPt
 #endif
 
 void
-I830SetPipeCursor (ScrnInfoPtr pScrn, int pipe)
+I830SetPipeCursor (ScrnInfoPtr pScrn, int pipe, Bool force)
 {
    I830Ptr pI830 = I830PTR(pScrn);
    CARD32 temp;
@@ -90,7 +90,7 @@ I830SetPipeCursor (ScrnInfoPtr pScrn, in
 	return;
 
     show = pI830->cursorOn && pI830->cursorInRange[pipe];
-    if (show && !pI830->cursorShown[pipe])
+    if (show && (force || !pI830->cursorShown[pipe]))
     {
 	if (IS_MOBILE(pI830) || IS_I9XX(pI830)) {
 	    int	cursor_control, cursor_base;
@@ -138,7 +138,7 @@ I830SetPipeCursor (ScrnInfoPtr pScrn, in
 	}
 	pI830->cursorShown[pipe] = TRUE;
     }
-    else if (!show && pI830->cursorShown[pipe])
+    else if (!show && (force || pI830->cursorShown[pipe]))
     {
 	if (IS_MOBILE(pI830) || IS_I9XX(pI830)) 
 	{
@@ -182,25 +182,22 @@ I830InitHWCursor(ScrnInfoPtr pScrn)
    for (i = 0; i < MAX_DISPLAY_PIPES; i++) pI830->cursorShown[i] = FALSE;
    /* Initialise the HW cursor registers, leaving the cursor hidden. */
    if (IS_MOBILE(pI830) || IS_I9XX(pI830)) {
-      temp = INREG(CURSOR_A_CONTROL);
-      temp &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE | MCURSOR_MEM_TYPE_LOCAL |
-		MCURSOR_PIPE_SELECT);
-      temp |= CURSOR_MODE_DISABLE;
-      temp |= (pI830->pipe << 28);
-      /* Need to set control, then address. */
-      OUTREG(CURSOR_A_CONTROL, temp);
-      if (pI830->CursorIsARGB)
-         OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Physical);
-      else
-         OUTREG(CURSOR_A_BASE, pI830->CursorMem->Physical);
-      if (pI830->Clone) {
-         temp &= ~MCURSOR_PIPE_SELECT;
-         temp |= (!pI830->pipe << 28);
-         OUTREG(CURSOR_B_CONTROL, temp);
-         if (pI830->CursorIsARGB)
-            OUTREG(CURSOR_B_BASE, pI830->CursorMemARGB->Physical);
-         else
-            OUTREG(CURSOR_B_BASE, pI830->CursorMem->Physical);
+      for (i = 0; i < MAX_DISPLAY_PIPES; i++)
+      {
+	 int   cursor_control = i == 0 ? CURSOR_A_CONTROL : CURSOR_B_CONTROL;
+	 int   cursor_base = i == 0 ? CURSOR_A_BASE : CURSOR_B_BASE;
+	 temp = INREG(cursor_control);
+	 temp &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE |
+		   MCURSOR_MEM_TYPE_LOCAL |
+		   MCURSOR_PIPE_SELECT);
+	 temp |= CURSOR_MODE_DISABLE;
+	 temp |= (i << 28);
+	 /* Need to set control, then address. */
+	 OUTREG(cursor_control, temp);
+	 if (pI830->CursorIsARGB)
+	    OUTREG(cursor_base, pI830->CursorMemARGB->Physical);
+	 else
+	    OUTREG(cursor_base, pI830->CursorMem->Physical);
       }
    } else {
       temp = INREG(CURSOR_CONTROL);
@@ -530,20 +527,15 @@ I830SetCursorPosition(ScrnInfoPtr pScrn,
 
 	pI830->cursorInRange[pipe] = inrange;
 	
-        I830SetPipeCursor (pScrn, pipe);
-    }
+        I830SetPipeCursor (pScrn, pipe, FALSE);
 
-    /* have to upload the base for the new position */
-    if (IS_I9XX(pI830)) {
-	if (pI830->CursorIsARGB)
-	    OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Physical);
-	else
-	    OUTREG(CURSOR_A_BASE, pI830->CursorMem->Physical);
-	if (pI830->Clone) {
+	/* have to upload the base for the new position */
+	if (IS_I9XX(pI830)) {
+	    int base = pipe == 0 ? CURSOR_A_BASE : CURSOR_B_BASE;
 	    if (pI830->CursorIsARGB)
-		OUTREG(CURSOR_B_BASE, pI830->CursorMemARGB->Physical);
+		OUTREG(base, pI830->CursorMemARGB->Physical);
 	    else
-		OUTREG(CURSOR_B_BASE, pI830->CursorMem->Physical);
+		OUTREG(base, pI830->CursorMem->Physical);
 	}
     }
 }
@@ -566,7 +558,7 @@ I830ShowCursor(ScrnInfoPtr pScrn)
 
     pI830->cursorOn = TRUE;
     for (pipe = 0; pipe < MAX_DISPLAY_PIPES; pipe++)
-	I830SetPipeCursor (pScrn, pipe);
+	I830SetPipeCursor (pScrn, pipe, TRUE);
 }
 
 static void
@@ -579,7 +571,7 @@ I830HideCursor(ScrnInfoPtr pScrn)
 
    pI830->cursorOn = FALSE;
     for (pipe = 0; pipe < MAX_DISPLAY_PIPES; pipe++)
-	I830SetPipeCursor (pScrn, pipe);
+	I830SetPipeCursor (pScrn, pipe, TRUE);
 }
 
 static void
@@ -595,11 +587,15 @@ I830SetCursorColors(ScrnInfoPtr pScrn, i
 
    DPRINTF(PFX, "I830SetCursorColors\n");
 
-   OUTREG(CURSOR_A_PALETTE0, bg & 0x00ffffff);
-   OUTREG(CURSOR_A_PALETTE1, fg & 0x00ffffff);
-   OUTREG(CURSOR_A_PALETTE2, fg & 0x00ffffff);
-   OUTREG(CURSOR_A_PALETTE3, bg & 0x00ffffff);
-   if (pI830->Clone) {
+   if (pI830->planeEnabled[0])
+   {
+       OUTREG(CURSOR_A_PALETTE0, bg & 0x00ffffff);
+       OUTREG(CURSOR_A_PALETTE1, fg & 0x00ffffff);
+       OUTREG(CURSOR_A_PALETTE2, fg & 0x00ffffff);
+       OUTREG(CURSOR_A_PALETTE3, bg & 0x00ffffff);
+   }
+   if (pI830->planeEnabled[1])
+   {
       OUTREG(CURSOR_B_PALETTE0, bg & 0x00ffffff);
       OUTREG(CURSOR_B_PALETTE1, fg & 0x00ffffff);
       OUTREG(CURSOR_B_PALETTE2, fg & 0x00ffffff);
diff-tree 4a8b9515e914369e1faf1dca6b11204b233c73ee (from parents)
Merge: 18a510bf9af2f288c0e94359f672775d6e9c9ab2 bdca8697cc6ac5a98e0548b2ce2e0032e9bcfa52
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Wed Sep 20 22:46:55 2006 -0700

    Merge branch 'modesetting' into randr-1.2

diff-tree bdca8697cc6ac5a98e0548b2ce2e0032e9bcfa52 (from parents)
Merge: d9db5ec6866555ec13ba3ddabb1516eb45637afa daade50ca271d1cdf236bbe84afade85d4111ac9
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Wed Sep 20 22:46:42 2006 -0700

    Merge branch 'modesetting-origin' into modesetting

diff-tree 18a510bf9af2f288c0e94359f672775d6e9c9ab2 (from parents)
Merge: f6500e94fec0d6db8c1f1350bee1d137bf06a09e d9db5ec6866555ec13ba3ddabb1516eb45637afa
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Wed Sep 20 22:45:48 2006 -0700

    Merge branch 'modesetting' into randr-1.2

diff-tree f6500e94fec0d6db8c1f1350bee1d137bf06a09e (from cbaf3cf74bd420533d299c4113761ec536097e33)
Author: Keith Packard <keithp at guitar.keithp.com>
Date:   Wed Sep 20 22:38:55 2006 -0700

    Update driver for RandR 1.2 X server API.
    
    This is not entirely what I'd like to see, but it's at least functional.
    
    Limitations:
    	Can't disable/enable crtcs
    	Can't move outputs on/off crtcs
    
    But, it does handle monitor hot-plug, detecting changes in VGA and SDVO
    status on-the fly. Which makes for good demo material.

diff --git a/configure.ac b/configure.ac
index 5c9291b..3375fa9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -99,8 +99,6 @@ if test "x$GCC" = "xyes"; then
 	-Wnested-externs -fno-strict-aliasing"
 fi
 
-CFLAGS="$CFLAGS $WARN_CFLAGS"
-
 AM_CONDITIONAL(DRI, test x$DRI = xyes)
 if test "$DRI" = yes; then
         PKG_CHECK_MODULES(DRI, [libdrm >= 2.0 xf86driproto])
@@ -110,6 +108,7 @@ fi
 
 AC_SUBST([DRI_CFLAGS])
 AC_SUBST([XORG_CFLAGS])
+AC_SUBST([WARN_CFLAGS])
 AC_SUBST([moduledir])
 
 DRIVER_NAME=i810
diff --git a/src/Makefile.am b/src/Makefile.am
index 50d0ad1..03b5fe6 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -24,7 +24,7 @@ SUBDIRS = xvmc bios_reader ch7xxx sil164
 # -avoid-version prevents gratuitous .0.0.0 version numbers on the end
 # _ladir passes a dummy rpath to libtool so the thing will actually link
 # TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc.
-AM_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@ -DI830_XV
+AM_CFLAGS = @WARN_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@ -DI830_XV
 
 i810_drv_la_LTLIBRARIES = i810_drv.la
 i810_drv_la_LDFLAGS = -module -avoid-version
diff --git a/src/i830.h b/src/i830.h
index 3a93931..fcd03ef 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -79,6 +79,16 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * Paulo César Pereira de Andrade <pcpa at conectiva.com.br>.
  */
 
+#define PIPE_CRT_ID	0
+#define PIPE_TV_ID    	1
+#define PIPE_DFP_ID	2
+#define PIPE_LFP_ID	3
+#define PIPE_CRT2_ID	4
+#define PIPE_TV2_ID	5
+#define PIPE_DFP2_ID	6
+#define PIPE_LFP2_ID	7
+#define PIPE_NUM_ID	8
+
 #define PIPE_NONE	0<<0
 #define PIPE_CRT	1<<0
 #define PIPE_TV		1<<1
@@ -201,10 +211,12 @@ typedef struct _I830SDVODriver {
    CARD32 save_SDVOX;
 } I830SDVORec, *I830SDVOPtr;
 
+extern const char *i830_output_type_names[];
+
 struct _I830OutputRec {
    int type;
-   int pipe;
-   int flags;
+/*   int pipe;
+   int flags;*/
    xf86MonPtr MonInfo;
    I2CBusPtr pI2CBus;
    I2CBusPtr pDDCBus;
@@ -233,6 +245,10 @@ typedef struct _I830Rec {
 
    Bool gammaEnabled[MAX_DISPLAY_PIPES];
 
+   int pipeX[MAX_DISPLAY_PIPES];
+   int pipeY[MAX_DISPLAY_PIPES];
+   Bool cursorInRange[MAX_DISPLAY_PIPES];
+   Bool cursorShown[MAX_DISPLAY_PIPES];
    Bool Clone;
    int CloneRefresh;
    int CloneHDisplay;
@@ -518,6 +534,7 @@ extern void I830SetMMIOAccess(I830Ptr pI
 extern void I830PrintErrorState(ScrnInfoPtr pScrn);
 extern void I830Sync(ScrnInfoPtr pScrn);
 extern void I830InitHWCursor(ScrnInfoPtr pScrn);
+extern void I830SetPipeCursor (ScrnInfoPtr pScrn, int pipe);
 extern Bool I830CursorInit(ScreenPtr pScreen);
 extern void I830EmitInvarientState(ScrnInfoPtr pScrn);
 extern void I830SelectBuffer(ScrnInfoPtr pScrn, int buffer);
@@ -610,6 +627,7 @@ DisplayModePtr i830GetGTF(int h_pixels, 
 int I830ValidateXF86ModeList(ScrnInfoPtr pScrn, Bool first_time);
 
 /* i830_randr.c */
+Bool I830RandRCreateScreenResources (ScreenPtr pScreen);
 Bool I830RandRInit(ScreenPtr pScreen, int rotation);
 Bool I830RandRSetConfig(ScreenPtr pScreen, Rotation rotation, int rate,
 			RRScreenSizePtr pSize);
diff --git a/src/i830_cursor.c b/src/i830_cursor.c
index 2cb069c..1e7beef 100644
--- a/src/i830_cursor.c
+++ b/src/i830_cursor.c
@@ -80,12 +80,106 @@ static Bool I830UseHWCursorARGB(ScreenPt
 #endif
 
 void
+I830SetPipeCursor (ScrnInfoPtr pScrn, int pipe)
+{
+   I830Ptr pI830 = I830PTR(pScrn);
+   CARD32 temp;
+    Bool show;
+    
+    if (!pI830->planeEnabled[pipe])
+	return;
+
+    show = pI830->cursorOn && pI830->cursorInRange[pipe];
+    if (show && !pI830->cursorShown[pipe])
+    {
+	if (IS_MOBILE(pI830) || IS_I9XX(pI830)) {
+	    int	cursor_control, cursor_base;
+	    if (pipe == 0)
+	    {
+		cursor_control = CURSOR_A_CONTROL;
+		cursor_base = CURSOR_A_BASE;
+	    }
+	    else
+	    {
+		cursor_control = CURSOR_B_CONTROL;
+		cursor_base = CURSOR_B_BASE;
+	    }
+	    temp = INREG(cursor_control);
+	    temp &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT);
+	    if (pI830->CursorIsARGB) {
+		temp |= CURSOR_MODE_64_ARGB_AX;
+		if (pI830->gammaEnabled[pipe])
+		    temp |= MCURSOR_GAMMA_ENABLE;
+	    } else
+		temp |= CURSOR_MODE_64_4C_AX;
+	    
+	    temp |= (pipe << 28); /* Connect to correct pipe */
+	    /* Need to set mode, then address. */
+	    OUTREG(cursor_control, temp);
+	    if (pI830->CursorIsARGB)
+		OUTREG(cursor_base, pI830->CursorMemARGB->Physical);
+	    else
+		OUTREG(cursor_base, pI830->CursorMem->Physical);
+	} else {
+	    temp = INREG(CURSOR_CONTROL);
+	    temp &= ~(CURSOR_FORMAT_MASK);
+	    temp |= CURSOR_ENABLE;
+	    if (pI830->CursorIsARGB) {
+		temp |= CURSOR_FORMAT_ARGB;
+		if (pI830->gammaEnabled[pipe])
+		    temp |= CURSOR_GAMMA_ENABLE;
+	    } else
+		temp |= CURSOR_FORMAT_3C;
+	    OUTREG(CURSOR_CONTROL, temp);
+	    if (pI830->CursorIsARGB)
+		OUTREG(CURSOR_BASEADDR, pI830->CursorMemARGB->Start);
+	    else
+		OUTREG(CURSOR_BASEADDR, pI830->CursorMem->Start);
+	}
+	pI830->cursorShown[pipe] = TRUE;
+    }
+    else if (!show && pI830->cursorShown[pipe])
+    {
+	if (IS_MOBILE(pI830) || IS_I9XX(pI830)) 
+	{
+	    int	cursor_control, cursor_base;
+	    if (pipe == 0)
+	    {
+		cursor_control = CURSOR_A_CONTROL;
+		cursor_base = CURSOR_A_BASE;
+	    }
+	    else
+	    {
+		cursor_control = CURSOR_B_CONTROL;
+		cursor_base = CURSOR_B_BASE;
+	    }
+	    temp = INREG(cursor_control);
+	    temp &= ~(CURSOR_MODE|MCURSOR_GAMMA_ENABLE);
+	    temp |= CURSOR_MODE_DISABLE;
+	    OUTREG(cursor_control, temp);
+	    /* This is needed to flush the above change. */
+	    if (pI830->CursorIsARGB)
+		OUTREG(cursor_base, pI830->CursorMemARGB->Physical);
+	    else
+		OUTREG(cursor_base, pI830->CursorMem->Physical);
+	} else {
+	    temp = INREG(CURSOR_CONTROL);
+	    temp &= ~(CURSOR_ENABLE|CURSOR_GAMMA_ENABLE);
+	    OUTREG(CURSOR_CONTROL, temp);
+	}
+	pI830->cursorShown[pipe] = FALSE;
+    }
+}
+
+void
 I830InitHWCursor(ScrnInfoPtr pScrn)
 {
    I830Ptr pI830 = I830PTR(pScrn);
    CARD32 temp;
+   int i;
 
    DPRINTF(PFX, "I830InitHWCursor\n");
+   for (i = 0; i < MAX_DISPLAY_PIPES; i++) pI830->cursorShown[i] = FALSE;
    /* Initialise the HW cursor registers, leaving the cursor hidden. */
    if (IS_MOBILE(pI830) || IS_I9XX(pI830)) {
       temp = INREG(CURSOR_A_CONTROL);
@@ -356,121 +450,109 @@ static void I830LoadCursorARGB (ScrnInfo
 static void
 I830SetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
 {
-   I830Ptr pI830 = I830PTR(pScrn);
-   CARD32 temp = 0;
-   Bool hide = FALSE, show = FALSE;
-   int oldx = x, oldy = y;
-   int hotspotx = 0, hotspoty = 0;
-#if 0
-   static Bool outsideViewport = FALSE;
-#endif
-
-   oldx += pScrn->frameX0; /* undo what xf86HWCurs did */
-   oldy += pScrn->frameY0;
-
-   switch (pI830->rotation) {
-      case RR_Rotate_0:
-         x = oldx;
-         y = oldy;
-         break;
-      case RR_Rotate_90:
-         x = oldy;
-         y = pScrn->pScreen->width - oldx;
-         hotspoty = I810_CURSOR_X;
-         break;
-      case RR_Rotate_180:
-         x = pScrn->pScreen->width - oldx;
-         y = pScrn->pScreen->height - oldy;
-         hotspotx = I810_CURSOR_X;
-         hotspoty = I810_CURSOR_Y;
-         break;
-      case RR_Rotate_270:
-         x = pScrn->pScreen->height - oldy;
-         y = oldx;
-         hotspotx = I810_CURSOR_Y;
-         break;
-   }
-
-   x -= hotspotx;
-   y -= hotspoty;
-
-   /* Now, readjust */
-   x -= pScrn->frameX0;
-   y -= pScrn->frameY0;
-
-   /* Clamp the cursor position to the visible screen area.  Ignore this if we
-    * are doing motion (with SilkenMouse) while the currentMode being changed.
-    */
-   if (pScrn->currentMode != NULL) {
-     if (x >= pScrn->currentMode->HDisplay)
-       x = pScrn->currentMode->HDisplay - 1;
-     if (y >= pScrn->currentMode->VDisplay)
-       y = pScrn->currentMode->VDisplay - 1;
-   }
-   if (x <= -I810_CURSOR_X) x = -I810_CURSOR_X + 1;
-   if (y <= -I810_CURSOR_Y) y = -I810_CURSOR_Y + 1;
-
-#if 0
-   /*
-    * There is a screen display problem when the cursor position is set
-    * wholely outside of the viewport.  We trap that here, turning the
-    * cursor off when that happens, and back on when it comes back into
-    * the viewport.
-    */
-   if (x >= pScrn->currentMode->HDisplay ||
-       y >= pScrn->currentMode->VDisplay ||
-       x <= -I810_CURSOR_X || y <= -I810_CURSOR_Y) {
-      hide = TRUE;
-      outsideViewport = TRUE;
-   } else if (outsideViewport) {
-      show = TRUE;
-      outsideViewport = FALSE;
-   }
-#endif
-
-   if (x < 0) {
-      temp |= (CURSOR_POS_SIGN << CURSOR_X_SHIFT);
-      x = -x;
-   }
-   if (y < 0) {
-      temp |= (CURSOR_POS_SIGN << CURSOR_Y_SHIFT);
-      y = -y;
-   }
-   temp |= ((x & CURSOR_POS_MASK) << CURSOR_X_SHIFT);
-   temp |= ((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT);
-
-   OUTREG(CURSOR_A_POSITION, temp);
-   if (pI830->Clone)
-      OUTREG(CURSOR_B_POSITION, temp);
-
-   if (pI830->cursorOn) {
-      if (hide)
-	 pI830->CursorInfoRec->HideCursor(pScrn);
-      else if (show)
-	 pI830->CursorInfoRec->ShowCursor(pScrn);
-      pI830->cursorOn = TRUE;
-   }
-
-   /* have to upload the base for the new position */
-   if (IS_I9XX(pI830)) {
-      if (pI830->CursorIsARGB)
-         OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Physical);
-      else
-         OUTREG(CURSOR_A_BASE, pI830->CursorMem->Physical);
-      if (pI830->Clone) {
-         if (pI830->CursorIsARGB)
-            OUTREG(CURSOR_B_BASE, pI830->CursorMemARGB->Physical);
-         else
-            OUTREG(CURSOR_B_BASE, pI830->CursorMem->Physical);
-      }
-   }
+    I830Ptr pI830 = I830PTR(pScrn);
+    CARD32 temp;
+    Bool inrange;
+    int oldx = x, oldy = y;
+    int hotspotx = 0, hotspoty = 0;
+    int pipe;
+
+    oldx += pScrn->frameX0; /* undo what xf86HWCurs did */
+    oldy += pScrn->frameY0;
+
+    switch (pI830->rotation) {
+    case RR_Rotate_0:
+	x = oldx;
+	y = oldy;
+	break;
+    case RR_Rotate_90:
+	x = oldy;
+	y = pScrn->pScreen->width - oldx;
+	hotspoty = I810_CURSOR_X;
+	break;
+    case RR_Rotate_180:
+	x = pScrn->pScreen->width - oldx;
+	y = pScrn->pScreen->height - oldy;
+	hotspotx = I810_CURSOR_X;
+	hotspoty = I810_CURSOR_Y;
+	break;
+    case RR_Rotate_270:
+	x = pScrn->pScreen->height - oldy;
+	y = oldx;
+	hotspotx = I810_CURSOR_Y;
+	break;
+    }
+
+    x -= hotspotx;
+    y -= hotspoty;
+
+    for (pipe = 0; pipe < MAX_DISPLAY_PIPES; pipe++)
+    {
+	DisplayModePtr	mode = &pI830->pipeCurMode[pipe];
+	int		thisx = x - pI830->pipeX[pipe];
+	int		thisy = y - pI830->pipeY[pipe];
+
+	if (!pI830->planeEnabled[pipe])
+	    continue;
+
+	/*
+	 * There is a screen display problem when the cursor position is set
+	 * wholely outside of the viewport.  We trap that here, turning the
+	 * cursor off when that happens, and back on when it comes back into
+	 * the viewport.
+	 */
+	inrange = TRUE;
+	if (thisx >= mode->HDisplay ||
+	    thisy >= mode->VDisplay ||
+	    thisx <= -I810_CURSOR_X || thisy <= -I810_CURSOR_Y) 
+	{
+	    inrange = FALSE;
+	    thisx = 0;
+	    thisy = 0;
+	}
+
+	temp = 0;
+	if (thisx < 0) {
+	    temp |= (CURSOR_POS_SIGN << CURSOR_X_SHIFT);
+	    thisx = -thisx;
+	}
+	if (thisy < 0) {
+	    temp |= (CURSOR_POS_SIGN << CURSOR_Y_SHIFT);
+	    thisy = -thisy;
+	}
+	temp |= ((thisx & CURSOR_POS_MASK) << CURSOR_X_SHIFT);
+	temp |= ((thisy & CURSOR_POS_MASK) << CURSOR_Y_SHIFT);
+
+	if (pipe == 0)
+	    OUTREG(CURSOR_A_POSITION, temp);
+	if (pipe == 1)
+	    OUTREG(CURSOR_B_POSITION, temp);
+
+	pI830->cursorInRange[pipe] = inrange;
+	
+        I830SetPipeCursor (pScrn, pipe);
+    }
+
+    /* have to upload the base for the new position */
+    if (IS_I9XX(pI830)) {
+	if (pI830->CursorIsARGB)
+	    OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Physical);
+	else
+	    OUTREG(CURSOR_A_BASE, pI830->CursorMem->Physical);
+	if (pI830->Clone) {
+	    if (pI830->CursorIsARGB)
+		OUTREG(CURSOR_B_BASE, pI830->CursorMemARGB->Physical);
+	    else
+		OUTREG(CURSOR_B_BASE, pI830->CursorMem->Physical);
+	}
+    }
 }
 
 static void
 I830ShowCursor(ScrnInfoPtr pScrn)
 {
    I830Ptr pI830 = I830PTR(pScrn);
-   CARD32 temp;
+    int pipe;
 
    DPRINTF(PFX, "I830ShowCursor\n");
    DPRINTF(PFX,
@@ -482,81 +564,22 @@ I830ShowCursor(ScrnInfoPtr pScrn)
 	   " Value of CursorMemARGB->Start is %x ",
 	   pI830->CursorMemARGB->Physical, pI830->CursorMemARGB->Start);
 
-   pI830->cursorOn = TRUE;
-   if (IS_MOBILE(pI830) || IS_I9XX(pI830)) {
-      temp = INREG(CURSOR_A_CONTROL);
-      temp &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT);
-      if (pI830->CursorIsARGB) {
-         temp |= CURSOR_MODE_64_ARGB_AX;
-	 if (pI830->gammaEnabled[pI830->pipe])
-	    temp |= MCURSOR_GAMMA_ENABLE;
-      } else
-         temp |= CURSOR_MODE_64_4C_AX;
-      temp |= (pI830->pipe << 28); /* Connect to correct pipe */
-      /* Need to set mode, then address. */
-      OUTREG(CURSOR_A_CONTROL, temp);
-      if (pI830->CursorIsARGB)
-         OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Physical);
-      else
-         OUTREG(CURSOR_A_BASE, pI830->CursorMem->Physical);
-      if (pI830->Clone) {
-         temp &= ~MCURSOR_PIPE_SELECT;
-         temp |= (!pI830->pipe << 28);
-         OUTREG(CURSOR_B_CONTROL, temp);
-         if (pI830->CursorIsARGB)
-            OUTREG(CURSOR_B_BASE, pI830->CursorMemARGB->Physical);
-         else
-            OUTREG(CURSOR_B_BASE, pI830->CursorMem->Physical);
-      }
-   } else {
-      temp = INREG(CURSOR_CONTROL);
-      temp &= ~(CURSOR_FORMAT_MASK);
-      temp |= CURSOR_ENABLE;
-      if (pI830->CursorIsARGB) {
-         temp |= CURSOR_FORMAT_ARGB;
-	 if (pI830->gammaEnabled[pI830->pipe])
-	    temp |= CURSOR_GAMMA_ENABLE;
-      } else
-         temp |= CURSOR_FORMAT_3C;
-      OUTREG(CURSOR_CONTROL, temp);
-      if (pI830->CursorIsARGB)
-         OUTREG(CURSOR_BASEADDR, pI830->CursorMemARGB->Start);
-      else
-         OUTREG(CURSOR_BASEADDR, pI830->CursorMem->Start);
-   }
+    pI830->cursorOn = TRUE;
+    for (pipe = 0; pipe < MAX_DISPLAY_PIPES; pipe++)
+	I830SetPipeCursor (pScrn, pipe);
 }
 
 static void
 I830HideCursor(ScrnInfoPtr pScrn)
 {
-   CARD32 temp;
    I830Ptr pI830 = I830PTR(pScrn);
+    int pipe;
 
    DPRINTF(PFX, "I830HideCursor\n");
 
    pI830->cursorOn = FALSE;
-   if (IS_MOBILE(pI830) || IS_I9XX(pI830)) {
-      temp = INREG(CURSOR_A_CONTROL);
-      temp &= ~(CURSOR_MODE|MCURSOR_GAMMA_ENABLE);
-      temp |= CURSOR_MODE_DISABLE;
-      OUTREG(CURSOR_A_CONTROL, temp);
-      /* This is needed to flush the above change. */
-      if (pI830->CursorIsARGB)
-         OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Physical);
-      else
-         OUTREG(CURSOR_A_BASE, pI830->CursorMem->Physical);
-      if (pI830->Clone) {
-         OUTREG(CURSOR_B_CONTROL, temp);
-         if (pI830->CursorIsARGB)
-            OUTREG(CURSOR_B_BASE, pI830->CursorMemARGB->Physical);
-         else
-            OUTREG(CURSOR_B_BASE, pI830->CursorMem->Physical);
-      }
-   } else {
-      temp = INREG(CURSOR_CONTROL);
-      temp &= ~(CURSOR_ENABLE|CURSOR_GAMMA_ENABLE);
-      OUTREG(CURSOR_CONTROL, temp);
-   }
+    for (pipe = 0; pipe < MAX_DISPLAY_PIPES; pipe++)
+	I830SetPipeCursor (pScrn, pipe);
 }
 
 static void
diff --git a/src/i830_display.c b/src/i830_display.c
index 6eb2a33..52d488a 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -245,13 +245,15 @@ i830PipeSetBase(ScrnInfoPtr pScrn, int p
 	OUTREG(DSPABASE, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
     else
 	OUTREG(DSPBBASE, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
+    pI830->pipeX[pipe] = x;
+    pI830->pipeY[pipe] = y;
 }
 
 /**
  * Sets the given video mode on the given pipe.  Assumes that plane A feeds
  * pipe A, and plane B feeds pipe B.  Should not affect the other planes/pipes.
  */
-static Bool
+Bool
 i830PipeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe)
 {
     I830Ptr pI830 = I830PTR(pScrn);
@@ -608,7 +610,7 @@ i830PipeSetMode(ScrnInfoPtr pScrn, Displ
 	OUTREG(DSPASTRIDE, pScrn->displayWidth * pI830->cpp);
 	OUTREG(DSPASIZE, dspsize);
 	OUTREG(DSPAPOS, 0);
-	i830PipeSetBase(pScrn, pipe, pScrn->frameX0, pScrn->frameY0);
+	i830PipeSetBase(pScrn, pipe, pI830->pipeX[pipe], pI830->pipeX[pipe]);
 	OUTREG(PIPEASRC, pipesrc);
 
 	/* Then, turn the pipe on first */
@@ -656,7 +658,7 @@ i830PipeSetMode(ScrnInfoPtr pScrn, Displ
 	OUTREG(DSPBSTRIDE, pScrn->displayWidth * pI830->cpp);
 	OUTREG(DSPBSIZE, dspsize);
 	OUTREG(DSPBPOS, 0);
-	i830PipeSetBase(pScrn, pipe, pScrn->frameX0, pScrn->frameY0);
+	i830PipeSetBase(pScrn, pipe, pI830->pipeX[pipe], pI830->pipeY[pipe]);
 	OUTREG(PIPEBSRC, pipesrc);
 
 	if (outputs & PIPE_LCD_ACTIVE) {
diff --git a/src/i830_display.h b/src/i830_display.h
index 2e61afc..e5bca1c 100644
--- a/src/i830_display.h
+++ b/src/i830_display.h
@@ -26,6 +26,7 @@
  */
 
 /* i830_display.c */
+Bool i830PipeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe);
 Bool i830SetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode);
 Bool i830DetectCRT(ScrnInfoPtr pScrn, Bool allow_disturb);
 void i830SetLVDSPanelPower(ScrnInfoPtr pScrn, Bool on);
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 8464b39..dc136a3 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -273,7 +273,7 @@ static OptionInfoRec I830BIOSOptions[] =
 };
 /* *INDENT-ON* */
 
-static const char *output_type_names[] = {
+const char *i830_output_type_names[] = {
    "Unused",
    "Analog",
    "DVO",
@@ -1133,7 +1133,7 @@ I830DetectMonitors(ScrnInfoPtr pScrn)
 						    pI830->output[i].pDDCBus);
 
 	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "DDC %s %d, %08lX\n",
-		    output_type_names[pI830->output[i].type], i,
+		    i830_output_type_names[pI830->output[i].type], i,
 		    pI830->output[i].pDDCBus->DriverPrivate.uval);
 	 xf86PrintEDID(pI830->output[i].MonInfo);
 	 break;
@@ -3164,22 +3164,8 @@ I830CreateScreenResources (ScreenPtr pSc
    if (!(*pScreen->CreateScreenResources)(pScreen))
       return FALSE;
 
-   if (pI830->rotation != RR_Rotate_0) {
-      RRScreenSize p;
-      Rotation requestedRotation = pI830->rotation;
-
-      pI830->rotation = RR_Rotate_0;
-
-      /* Just setup enough for an initial rotate */
-      p.width = pScreen->width;
-      p.height = pScreen->height;
-      p.mmWidth = pScreen->mmWidth;
-      p.mmHeight = pScreen->mmHeight;
-
-      pI830->starting = TRUE; /* abuse this for dual head & rotation */
-      I830RandRSetConfig (pScreen, requestedRotation, 0, &p);
-      pI830->starting = FALSE;
-   } 
+   if (!I830RandRCreateScreenResources (pScreen))
+      return FALSE;
 
    return TRUE;
 }
@@ -3507,6 +3493,9 @@ I830BIOSScreenInit(int scrnIndex, Screen
    if (!I830BIOSEnterVT(scrnIndex, 0))
       return FALSE;
 
+    if (pScrn->virtualX > pScrn->displayWidth)
+	pScrn->displayWidth = pScrn->virtualX;
+
    DPRINTF(PFX, "assert( if(!fbScreenInit(pScreen, ...) )\n");
    if (!fbScreenInit(pScreen, pI830->FbBase + pScrn->fbOffset, 
                      pScrn->virtualX, pScrn->virtualY,
diff --git a/src/i830_modes.c b/src/i830_modes.c
index 6bff1d0..3b70d5d 100644
--- a/src/i830_modes.c
+++ b/src/i830_modes.c
@@ -954,6 +954,11 @@ I830ValidateXF86ModeList(ScrnInfoPtr pSc
 		    maxY = mode->VDisplay;
 	    }
 	}
+	/* let the user specify a bigger virtual size if they like */
+	if (pScrn->display->virtualX > maxX)
+	    maxX = pScrn->display->virtualX;
+	if (pScrn->display->virtualY > maxY)
+	    maxY = pScrn->display->virtualY;
 	pScrn->virtualX = maxX;
 	pScrn->virtualY = maxY;
 	pScrn->displayWidth = (maxX + 63) & ~63;
diff --git a/src/i830_randr.c b/src/i830_randr.c
index 4c7c087..4132eb2 100644
--- a/src/i830_randr.c
+++ b/src/i830_randr.c
@@ -23,6 +23,10 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include "xf86.h"
 #include "os.h"
 #include "mibank.h"
@@ -33,9 +37,11 @@
 #include "mipointer.h"
 #include "windowstr.h"
 #include <randrstr.h>
+#include <X11/extensions/render.h>
 
 #include "i830.h"
 #include "i830_xf86Modes.h"
+#include "i830_display.h"
 
 typedef struct _i830RandRInfo {
     int				    virtualX;
@@ -46,8 +52,18 @@ typedef struct _i830RandRInfo {
     int				    maxY;
     Rotation			    rotation; /* current mode */
     Rotation                        supported_rotations; /* driver supported */
+#ifdef RANDR_12_INTERFACE
+    RRCrtcPtr			    crtcs[MAX_DISPLAY_PIPES];
+    RROutputPtr			    outputs[MAX_OUTPUTS];
+    DisplayModePtr  		    modes[MAX_DISPLAY_PIPES];
+#endif
 } XF86RandRInfoRec, *XF86RandRInfoPtr;
     
+#ifdef RANDR_12_INTERFACE
+static Bool I830RandRInit12 (ScreenPtr pScreen);
+static Bool I830RandRCreateScreenResources12 (ScreenPtr pScreen);
+#endif
+
 static int	    i830RandRIndex;
 static int	    i830RandRGeneration;
 
@@ -317,6 +333,40 @@ I830GetRotation(ScreenPtr pScreen)
 }
 
 Bool
+I830RandRCreateScreenResources (ScreenPtr pScreen)
+{
+    ScrnInfoPtr		pScrn = xf86Screens[pScreen->myNum];
+    I830Ptr pI830 = I830PTR(pScrn);
+#ifdef PANORAMIX
+    /* XXX disable RandR when using Xinerama */
+    if (!noPanoramiXExtension)
+	return TRUE;
+#endif
+#if RANDR_12_INTERFACE
+    if (I830RandRCreateScreenResources12 (pScreen))
+	return TRUE;
+#endif
+    if (pI830->rotation != RR_Rotate_0) {
+	RRScreenSize p;
+	Rotation requestedRotation = pI830->rotation;
+
+	pI830->rotation = RR_Rotate_0;
+
+	/* Just setup enough for an initial rotate */
+	p.width = pScreen->width;
+	p.height = pScreen->height;
+	p.mmWidth = pScreen->mmWidth;
+	p.mmHeight = pScreen->mmHeight;
+
+	pI830->starting = TRUE; /* abuse this for dual head & rotation */
+	I830RandRSetConfig (pScreen, requestedRotation, 0, &p);
+	pI830->starting = FALSE;
+    } 
+    return TRUE;
+}
+    
+    
+Bool
 I830RandRInit (ScreenPtr    pScreen, int rotation)
 {
     rrScrPrivPtr	rp;
@@ -359,6 +409,10 @@ I830RandRInit (ScreenPtr    pScreen, int
 
     pScreen->devPrivates[i830RandRIndex].ptr = randrp;
 
+#if RANDR_12_INTERFACE
+    if (!I830RandRInit12 (pScreen))
+	return FALSE;
+#endif
     return TRUE;
 }
 
@@ -379,3 +433,399 @@ I830GetOriginalVirtualSize(ScrnInfoPtr p
 	*y = randrp->virtualY;
     }
 }
+
+#if RANDR_12_INTERFACE
+static Bool
+I830RandRScreenSetSize (ScreenPtr	pScreen,
+			CARD16		width,
+			CARD16		height,
+			CARD32		mmWidth,
+			CARD32		mmHeight)
+{
+    XF86RandRInfoPtr	randrp = XF86RANDRINFO(pScreen);
+    ScrnInfoPtr		pScrn = XF86SCRNINFO(pScreen);
+    WindowPtr		pRoot = WindowTable[pScreen->myNum];
+    Bool 		ret = TRUE;
+    
+    if (randrp->virtualX == -1 || randrp->virtualY == -1) 
+    {
+	randrp->virtualX = pScrn->virtualX;
+	randrp->virtualY = pScrn->virtualY;
+    }
+    if (pRoot)
+	(*pScrn->EnableDisableFBAccess) (pScreen->myNum, FALSE);
+    pScrn->virtualX = width;
+    pScrn->virtualY = height;
+
+    pScreen->width = pScrn->virtualX;
+    pScreen->height = pScrn->virtualY;
+    pScreen->mmWidth = mmWidth;
+    pScreen->mmHeight = mmHeight;
+    
+    xf86SetViewport (pScreen, pScreen->width, pScreen->height);
+    xf86SetViewport (pScreen, 0, 0);
+    if (pRoot)
+	(*pScrn->EnableDisableFBAccess) (pScreen->myNum, TRUE);
+    if (WindowTable[pScreen->myNum])
+	RRScreenSizeNotify (pScreen);
+    return ret;
+}
+
+static Bool
+I830RandRCrtcNotify (RRCrtcPtr	crtc)
+{
+    ScreenPtr		pScreen = crtc->pScreen;
+    XF86RandRInfoPtr	randrp = XF86RANDRINFO(pScreen);
+    ScrnInfoPtr		pScrn = xf86Screens[pScreen->myNum];
+    I830Ptr		pI830 = I830PTR(pScrn);
+    RRModePtr		mode = NULL;
+    int			x;
+    int			y;
+    Rotation		rotation;
+    int			numOutputs;
+    RROutputPtr		outputs[MAX_OUTPUTS];
+    struct _I830OutputRec   *output;
+    RROutputPtr		rrout;
+    int			pipe = (int) crtc->devPrivate;
+    int			i, j;
+    DisplayModePtr	pipeMode = &pI830->pipeCurMode[pipe];
+    int			pipe_type;
+    
+    x = pI830->pipeX[pipe];
+    y = pI830->pipeY[pipe];
+    rotation = RR_Rotate_0;
+    numOutputs = 0;
+    for (i = 0; i < pI830->num_outputs; i++)
+    {
+	output = &pI830->output[i];
+	/*
+	 * Valid crtcs
+	 */
+	switch (output->type) {
+	case I830_OUTPUT_DVO:
+	case I830_OUTPUT_SDVO:
+	    pipe_type = PIPE_DFP;
+	    break;
+	case I830_OUTPUT_ANALOG:
+	    pipe_type = PIPE_CRT;
+	    break;
+	case I830_OUTPUT_LVDS:
+	    pipe_type = PIPE_LFP;
+	    break;
+	case I830_OUTPUT_TVOUT:
+	    pipe_type = PIPE_TV;
+	    break;
+	default:
+	    pipe_type = PIPE_NONE;
+	    break;
+	}
+	if (pI830->operatingDevices & (pipe_type << (pipe << 3)))
+	{
+	    rrout = randrp->outputs[i];
+	    outputs[numOutputs++] = rrout;
+	    for (j = 0; j < rrout->numModes; j++)
+	    {
+		DisplayModePtr	outMode = rrout->modes[j]->devPrivate;
+		if (I830ModesEqual(pipeMode, outMode))
+		    mode = rrout->modes[j];
+	    }
+	}
+    }
+    return RRCrtcNotify (crtc, mode, x, y, rotation, numOutputs, outputs);
+}
+    
+static Bool
+I830RandRCrtcSet (ScreenPtr	pScreen,
+		  RRCrtcPtr	crtc,
+		  RRModePtr	mode,
+		  int		x,
+		  int		y,
+		  Rotation	rotation,
+		  int		numOutputs,
+		  RROutputPtr	*outputs)
+{
+    XF86RandRInfoPtr	randrp = XF86RANDRINFO(pScreen);
+    ScrnInfoPtr		pScrn = xf86Screens[pScreen->myNum];
+    I830Ptr		pI830 = I830PTR(pScrn);
+    int			pipe = (int) (crtc->devPrivate);
+    DisplayModePtr	display_mode = mode->devPrivate;
+    
+    /* Sync the engine before adjust mode */
+    if (pI830->AccelInfoRec && pI830->AccelInfoRec->NeedToSync) {
+	(*pI830->AccelInfoRec->Sync)(pScrn);
+	pI830->AccelInfoRec->NeedToSync = FALSE;
+    }
+
+    if (display_mode != randrp->modes[pipe])
+    {
+	if (!i830PipeSetMode (pScrn, display_mode, pipe))
+	    return FALSE;
+	randrp->modes[pipe] = display_mode;
+    }
+    i830PipeSetBase(pScrn, pipe, x, y);
+    return I830RandRCrtcNotify (crtc);
+}
+
+static Bool
+I830RandRCrtcSetGamma (ScreenPtr    pScreen,
+		       RRCrtcPtr    crtc)
+{
+    return FALSE;
+}
+
+/*
+ * Mirror the current mode configuration to RandR
+ */
+static Bool
+I830RandRSetInfo12 (ScreenPtr pScreen)
+{
+    XF86RandRInfoPtr	randrp = XF86RANDRINFO(pScreen);
+    ScrnInfoPtr		pScrn = xf86Screens[pScreen->myNum];
+    I830Ptr		pI830 = I830PTR(pScrn);
+    RROutputPtr		clones[MAX_OUTPUTS];
+    RRCrtcPtr		crtc;
+    int			nclone;
+    RRCrtcPtr		crtcs[MAX_DISPLAY_PIPES];
+    int			ncrtc;
+    RRModePtr		*modes;
+    int			nmode;
+    struct _I830OutputRec   *output;
+    int			i;
+    int			j;
+    int			clone_types;
+    int			crtc_types;
+    int			connection;
+    int			pipe_type;
+    int			pipe;
+    int			subpixel;
+    
+    if (randrp->virtualX == -1 || randrp->virtualY == -1) 
+    {
+	randrp->virtualX = pScrn->virtualX;
+	randrp->virtualY = pScrn->virtualY;
+    }
+    RRScreenSetSizeRange (pScreen, 320, 240, 
+			  randrp->virtualX, randrp->virtualY);
+    for (i = 0; i < pI830->num_outputs; i++)
+    {
+	output = &pI830->output[i];
+	/*
+	 * Valid crtcs
+	 */
+	switch (output->type) {
+	case I830_OUTPUT_DVO:
+	case I830_OUTPUT_SDVO:
+	    crtc_types = ((1 << 0)|
+			  (1 << 1));
+	    clone_types = ((1 << I830_OUTPUT_ANALOG) |
+			   (1 << I830_OUTPUT_DVO) |
+			   (1 << I830_OUTPUT_SDVO));
+	    pipe_type = PIPE_DFP;
+	    subpixel = SubPixelHorizontalRGB;
+	    break;
+	case I830_OUTPUT_ANALOG:
+	    crtc_types = (1 << 0);
+	    clone_types = ((1 << I830_OUTPUT_ANALOG) |
+			   (1 << I830_OUTPUT_DVO) |
+			   (1 << I830_OUTPUT_SDVO));
+	    pipe_type = PIPE_CRT;
+	    subpixel = SubPixelNone;
+	    break;
+	case I830_OUTPUT_LVDS:
+	    crtc_types = (1 << 1);
+	    clone_types = (1 << I830_OUTPUT_LVDS);
+	    pipe_type = PIPE_LFP;
+	    subpixel = SubPixelHorizontalRGB;
+	    break;
+	case I830_OUTPUT_TVOUT:
+	    crtc_types = ((1 << 0) |
+			  (1 << 1));
+	    clone_types = (1 << I830_OUTPUT_TVOUT);
+	    pipe_type = PIPE_TV;
+	    subpixel = SubPixelNone;
+	    break;
+	default:
+	    crtc_types = 0;
+	    clone_types = 0;
+	    pipe_type = PIPE_NONE;
+	    subpixel = SubPixelUnknown;
+	    break;
+	}
+	ncrtc = 0;
+	pipe = -1;
+	crtc = NULL;
+	for (j = 0; j < MAX_DISPLAY_PIPES; j++)
+	{
+#if 0
+	     /* Can't flip outputs among crtcs yet */
+	    if (crtc_types & (1 << j))
+		crtcs[ncrtc++] = randrp->crtcs[j];
+#endif
+	    if (pI830->operatingDevices & (pipe_type << (j << 3)))
+	    {
+		pipe = j;
+		crtc = randrp->crtcs[j];
+		crtcs[ncrtc++] = crtc;
+	    }
+	}
+	if (!RROutputSetCrtcs (randrp->outputs[i], crtcs, ncrtc))
+	    return FALSE;
+
+	RROutputSetCrtc (randrp->outputs[i], crtc);
+    
+	if (pipe >= 0)
+	{
+	    MonPtr	    mon = pI830->pipeMon[pipe];
+	    DisplayModePtr  mode;
+	    xRRModeInfo	    modeInfo;
+	    RRModePtr	    rrmode;
+	    
+	    nmode = 0;
+	    for (mode = mon->Modes; mode; mode = mode->next)
+		nmode++;
+	    
+	    if (nmode)
+	    {
+		modes = xalloc (nmode * sizeof (RRModePtr));
+		if (!modes)
+		    return FALSE;
+		nmode = 0;
+		for (mode = mon->Modes; mode; mode = mode->next)
+		{
+		    modeInfo.nameLength = strlen (mode->name);
+		    modeInfo.mmWidth = mon->widthmm;
+		    modeInfo.mmHeight = mon->heightmm;
+
+		    modeInfo.width = mode->HDisplay;
+		    modeInfo.dotClock = mode->Clock * 1000;
+		    modeInfo.hSyncStart = mode->HSyncStart;
+		    modeInfo.hSyncEnd = mode->HSyncEnd;
+		    modeInfo.hTotal = mode->HTotal;
+		    modeInfo.hSkew = mode->HSkew;
+
+		    modeInfo.height = mode->VDisplay;
+		    modeInfo.vSyncStart = mode->VSyncStart;
+		    modeInfo.vSyncEnd = mode->VSyncEnd;
+		    modeInfo.vTotal = mode->VTotal;
+		    modeInfo.modeFlags = mode->Flags;
+
+		    rrmode = RRModeGet (pScreen, &modeInfo, mode->name);
+		    rrmode->devPrivate = mode;
+		    if (rrmode)
+			modes[nmode++] = rrmode;
+		}
+		if (!RROutputSetModes (randrp->outputs[i], modes, nmode))
+		{
+		    xfree (modes);
+		    return FALSE;
+		}
+
+		xfree (modes);
+	    }
+	}
+	connection = RR_Disconnected;
+	if (pipe >= 0)
+	    connection = RR_Connected;
+
+	RROutputSetConnection (randrp->outputs[i], connection);
+	    
+	RROutputSetSubpixelOrder (randrp->outputs[i], subpixel);
+
+	/*
+	 * Valid clones
+	 */
+	nclone = 0;
+	for (j = 0; j < pI830->num_outputs; j++)
+	{
+	    if (i != j && ((1 << pI830->output[j].type) & clone_types))
+		clones[nclone++] = randrp->outputs[j];
+	}
+	if (!RROutputSetClones (randrp->outputs[i], clones, nclone))
+	    return FALSE;
+    }
+    for (i = 0; i < MAX_DISPLAY_PIPES; i++)
+	I830RandRCrtcNotify (randrp->crtcs[i]);
+    return TRUE;
+}
+
+    
+/*
+ * Query the hardware for the current state, then mirror
+ * that to RandR
+ */
+static Bool
+I830RandRGetInfo12 (ScreenPtr pScreen, Rotation *rotations)
+{
+    ScrnInfoPtr		pScrn = xf86Screens[pScreen->myNum];
+    /* Re-probe the outputs for new monitors or modes */
+    I830ValidateXF86ModeList(pScrn, FALSE);
+    return I830RandRSetInfo12 (pScreen);
+}
+
+static Bool
+I830RandRCreateScreenResources12 (ScreenPtr pScreen)
+{
+    XF86RandRInfoPtr	randrp = XF86RANDRINFO(pScreen);
+    ScrnInfoPtr		pScrn = xf86Screens[pScreen->myNum];
+    I830Ptr		pI830 = I830PTR(pScrn);
+    struct _I830OutputRec   *output;
+    const char		*name;
+    int			i;
+    DisplayModePtr	mode;
+
+    /*
+     * Create RandR resources, then probe them
+     */
+    for (i = 0; i < MAX_DISPLAY_PIPES; i++)
+    {
+	randrp->crtcs[i] = RRCrtcCreate (pScreen, (void *) i);
+	RRCrtcGammaSetSize (randrp->crtcs[i], 256);
+    }
+
+    for (i = 0; i < pI830->num_outputs; i++)
+    {
+	output = &pI830->output[i];
+	name = i830_output_type_names[output->type];
+	randrp->outputs[i] = RROutputCreate (pScreen,
+					     name, strlen (name),
+					     (void *) i);
+    }
+    
+    mode = pScrn->currentMode;
+    if (mode)
+    {
+	I830RandRScreenSetSize (pScreen,
+				mode->HDisplay,
+				mode->VDisplay,
+				pScreen->mmWidth,
+				pScreen->mmHeight);
+	
+    }
+			    
+    for (i = 0; i < MAX_DISPLAY_PIPES; i++)
+	i830PipeSetBase(pScrn, i, 0, 0);
+	
+    return I830RandRSetInfo12 (pScreen);
+}
+
+static void
+I830RandRPointerMoved (int scrnIndex, int x, int y)
+{
+}
+
+static Bool
+I830RandRInit12 (ScreenPtr pScreen)
+{
+    ScrnInfoPtr		pScrn = xf86Screens[pScreen->myNum];
+    rrScrPrivPtr	rp = rrGetScrPriv(pScreen);
+
+    rp->rrGetInfo = I830RandRGetInfo12;
+    rp->rrScreenSetSize = I830RandRScreenSetSize;
+    rp->rrCrtcSet = I830RandRCrtcSet;
+    rp->rrCrtcSetGamma = I830RandRCrtcSetGamma;
+    rp->rrSetConfig = NULL;
+    memset (rp->modes, '\0', sizeof (rp->modes));
+    pScrn->PointerMoved = I830RandRPointerMoved;
+    return TRUE;
+}
+#endif
diff-tree d9db5ec6866555ec13ba3ddabb1516eb45637afa (from parents)
Merge: cbaf3cf74bd420533d299c4113761ec536097e33 e3f4caf40708478ef327b029d0a75944c51ea905
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Tue Sep 19 16:03:04 2006 -0700

    Merge branch 'modesetting-origin' into modesetting

diff-tree b970166eab95ac024ff481b0f5fd9aaf3644aabf (from 8b9d7a5f8560ee55ca5cb5376517a4246cd79fb9)
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Sep 8 11:09:19 2006 -0700

    Fix a compile failure from the last commit.

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 99c35c0..ffa93f8 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -6918,6 +6918,7 @@ I830InitFBManager(
     BoxPtr FullBox
 ){
    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+   I830Ptr pI830 = I830PTR(pScrn);
    RegionRec ScreenRegion;
    RegionRec FullRegion;
    BoxRec ScreenBox;
diff-tree 8b9d7a5f8560ee55ca5cb5376517a4246cd79fb9 (from parents)
Merge: 6500a3aa134e11a75b7ddaf7fff253003b223241 1e6e288b8826789f3b2520d12426ff7852a67ccd
Author: Alan Hourihane <alanh at fairlite.demon.co.uk>
Date:   Thu Sep 7 17:45:57 2006 +0100

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

diff-tree 6500a3aa134e11a75b7ddaf7fff253003b223241 (from 1feb733eb8b09a8b07b7a6987add5149c53b0157)
Author: Alan Hourihane <alanh at fairlite.demon.co.uk>
Date:   Thu Sep 7 17:45:28 2006 +0100

    When in MergedFB mode, fix offscreen memory allocation.

diff --git a/src/i830_driver.c b/src/i830_driver.c
index a05fb17..99c35c0 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -6926,7 +6926,7 @@ I830InitFBManager(
    ScreenBox.x1 = 0;
    ScreenBox.y1 = 0;
    ScreenBox.x2 = pScrn->displayWidth;
-   if (pScrn->virtualX > pScrn->virtualY)
+   if (!pI830->MergedFB && pScrn->virtualX > pScrn->virtualY)
       ScreenBox.y2 = pScrn->virtualX;
    else
       ScreenBox.y2 = pScrn->virtualY;
diff --git a/src/i830_memory.c b/src/i830_memory.c
index f270a51..2d09b2d 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -783,7 +783,7 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, 
       pI830->FbMemBox.x1 = 0;
       pI830->FbMemBox.x2 = pScrn->displayWidth;
       pI830->FbMemBox.y1 = 0;
-      if (pScrn->virtualX > pScrn->virtualY)
+      if (!pI830->MergedFB && pScrn->virtualX > pScrn->virtualY)
          pI830->FbMemBox.y2 = pScrn->virtualX;
       else
          pI830->FbMemBox.y2 = pScrn->virtualY;
@@ -855,7 +855,7 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, 
       }
 
 #if 1 /* ROTATION */
-      if (pScrn->virtualX > pScrn->virtualY)
+      if (!pI830->MergedFB && pScrn->virtualX > pScrn->virtualY)
          size = lineSize * (pScrn->virtualX + cacheLines);
       else 
          size = lineSize * (pScrn->virtualY + cacheLines);
diff-tree 1e6e288b8826789f3b2520d12426ff7852a67ccd (from 1feb733eb8b09a8b07b7a6987add5149c53b0157)
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Sep 1 16:47:17 2006 -0700

    Add a check for intel-gen4asm, and rules to compile {wm,sf}_prog.h using it.
    
    This adds assembly source for the two programs used in the textured video
    implementation on the 965, which should make them easier to modify in the
    future. The compiled versions are also included, so that intel-gen4asm isn't a
    build requirement for people that aren't modifying these programs.
    
    There are minor differences in the compiled versions of these programs compared
    to their previous versions which were compiled with a different tool.  I
    believe the changes should be harmless, and video continues to work on my
    system.

diff --git a/configure.ac b/configure.ac
index 436d7e5..a27822e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -49,6 +49,9 @@ AC_DISABLE_STATIC
 AC_PROG_LIBTOOL
 AC_PROG_CC
 
+AC_CHECK_PROG(gen4asm, [intel-gen4asm], yes, no)
+AM_CONDITIONAL(HAVE_GEN4ASM, test x$gen4asm = xyes)
+
 AH_TOP([#include "xorg-server.h"])
 
 AC_ARG_WITH(xorg-module-dir,
diff --git a/src/Makefile.am b/src/Makefile.am
index 63370ab..ce7b40e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -33,6 +33,7 @@ i810_drv_ladir = @moduledir@/drivers
 i810_drv_la_SOURCES = \
          brw_defines.h \
          brw_structs.h \
+	 sf_prog.h \
          wm_prog.h \
          common.h \
          i810_accel.c \
@@ -66,6 +67,13 @@ i810_drv_la_SOURCES = \
 	 i915_reg.h \
 	 i915_video.c
 
+if HAVE_GEN4ASM
+sf_prog.h: packed_yuv_sf.g4a
+	intel-gen4asm -o sf_prog.h packed_yuv_sf.g4a
+wm_prog.h: packed_yuv_wm.g4a
+	intel-gen4asm -o wm_prog.h packed_yuv_wm.g4a
+endif
+
 if DRI
 i810_drv_la_SOURCES += \
          i810_dri.c \
@@ -74,3 +82,7 @@ i810_drv_la_SOURCES += \
          i810_hwmc.c \
          i830_dri.h 
 endif
+
+EXTRA_DIST = \
+	packed_yuv_sf.g4a \
+	packed_yuv_wm.g4a
diff --git a/src/i830_video.c b/src/i830_video.c
index 7f6eb80..bbf1df7 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2128,40 +2128,7 @@ static const CARD32 sip_kernel_static[][
 #define SF_MAX_THREADS	   1
 
 static const CARD32 sf_kernel_static[][4] = {
-/*    send   0 (1) g6<1>F g1.12<0,1,0>F math mlen 1 rlen 1 { align1 +  } */
-   { 0x00000031, 0x20c01fbd, 0x0000002c, 0x01110081 },
-/*    send   0 (1) g6.4<1>F g1.20<0,1,0>F math mlen 1 rlen 1 { align1 +  } */
-   { 0x00000031, 0x20c41fbd, 0x00000034, 0x01110081 },
-/*    add (8) g7<1>F g4<8,8,1>F g3<8,8,1>F { align1 +  } */
-   { 0x00600040, 0x20e077bd, 0x008d0080, 0x008d4060 },
-/*    mul (1) g7<1>F g7<0,1,0>F g6<0,1,0>F { align1 +  } */
-   { 0x00000041, 0x20e077bd, 0x000000e0, 0x000000c0 },
-/*    mul (1) g7.4<1>F g7.4<0,1,0>F g6.4<0,1,0>F { align1 +  } */
-   { 0x00000041, 0x20e477bd, 0x000000e4, 0x000000c4 },
-/*    mov (8) m1<1>F g7<0,1,0>F { align1 +  } */
-   { 0x00600001, 0x202003be, 0x000000e0, 0x00000000 },
-/*    mov (8) m2<1>F g7.4<0,1,0>F { align1 +  } */
-   { 0x00600001, 0x204003be, 0x000000e4, 0x00000000 },
-/*    mov (8) m3<1>F g3<8,8,1>F { align1 +  } */
-   { 0x00600001, 0x206003be, 0x008d0060, 0x00000000 },
-/*    send   0 (8) a0<1>F g0<8,8,1>F urb mlen 4 rlen 0 write +0 transpose used complete EOT{ align1 +  } */
-   { 0x00600031, 0x20001fbc, 0x008d0000, 0x8640c800 },
-/*    nop (4) g0<1>UD { align1 +  } */
-   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-/*    nop (4) g0<1>UD { align1 +  } */
-   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-/*    nop (4) g0<1>UD { align1 +  } */
-   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-/*    nop (4) g0<1>UD { align1 +  } */
-   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-/*    nop (4) g0<1>UD { align1 +  } */
-   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-/*    nop (4) g0<1>UD { align1 +  } */
-   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-/*    nop (4) g0<1>UD { align1 +  } */
-   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-/*    nop (4) g0<1>UD { align1 +  } */
-   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+#include "sf_prog.h"
 };
 
 /*
diff --git a/src/packed_yuv_sf.g4a b/src/packed_yuv_sf.g4a
new file mode 100644
index 0000000..8c1398f
--- /dev/null
+++ b/src/packed_yuv_sf.g4a
@@ -0,0 +1,17 @@
+send (1) 0 g6<1>F g1.12<0,1,0>F math inv scalar mlen 1 rlen 1 { align1 };
+send (1) 0 g6.4<1>F g1.20<0,1,0>F math inv scalar mlen 1 rlen 1 { align1 };
+add (8) g7<1>F g4<8,8,1>F -g3<8,8,1>F { align1 };
+mul (1) g7<1>F g7<0,1,0>F g6<0,1,0>F { align1 };
+mul (1) g7.4<1>F g7.4<0,1,0>F g6.4<0,1,0>F { align1 };
+mov (8) m1<1>F g7<0,1,0>F { align1 };
+mov (8) m2<1>F g7.4<0,1,0>F { align1 };
+mov (8) m3<1>F g3<8,8,1>F { align1 };
+send (8) 0 null g0<8,8,1>F urb 0 transpose used complete mlen 4 rlen 0 { align1 EOT };
+nop;
+nop;
+nop;
+nop;
+nop;
+nop;
+nop;
+nop;
diff --git a/src/packed_yuv_wm.g4a b/src/packed_yuv_wm.g4a
new file mode 100644
index 0000000..d312d17
--- /dev/null
+++ b/src/packed_yuv_wm.g4a
@@ -0,0 +1,161 @@
+/* The initial payload of the thread is always g0.
+ * WM_URB (incoming URB entries) is g3
+ * X0_R is g4
+ * X1_R is g5
+ * Y0_R is g6
+ * Y1_R is g7
+ */
+
+    /* Set up the X/Y screen coordinates of the pixels in our 4 subspans.  Each
+     * subspan is a 2x2 rectangle, and the screen x/y of the upper left of each
+     * subspan are given in GRF register 1.2 through 1.5 (which, with the word
+     * addressing below, are 1.4 through 1.11).
+     *
+     * The result is WM_X*_R and WM_Y*R being:
+     *
+     * X0: {ss0.x, ss0.x+1, ss0.x,   ss0.x+1, ss1.x, ss1.x+1, ss1.x,   ss1.x+y}
+     * Y0: {ss0.y, ss0.y,   ss0.y+1, ss0.y+1, ss1.y, ss1.y,   ss1.y+1, ss1.y+1}
+     * X1: {ss2.x, ss2.x+1, ss2.x,   ss2.x+1, ss3.x, ss3.x+1, ss3.x,   ss3.x+y}
+     * Y1: {ss2.y, ss2.y,   ss2.y+1, ss2.y+1, ss3.y, ss3.y,   ss3.y+1, ss3.y+1}
+     */
+
+    /* Set up ss0.x coordinates*/
+mov (1) g4<1>F g1.8<0,1,0>UW { align1 };
+add (1) g4.4<1>F g1.8<0,1,0>UW 1UB { align1 };
+mov (1) g4.8<1>F g1.8<0,1,0>UW { align1 };
+add (1) g4.12<1>F g1.8<0,1,0>UW 1UB { align1 };
+    /* Set up ss0.y coordinates */
+mov (1) g6<1>F g1.10<0,1,0>UW { align1 };
+mov (1) g6.4<1>F g1.10<0,1,0>UW { align1 };
+add (1) g6.8<1>F g1.10<0,1,0>UW 1UB { align1 };
+add (1) g6.12<1>F g1.10<0,1,0>UW 1UB { align1 };
+    /* set up ss1.x coordinates */
+mov (1) g4.16<1>F g1.12<0,1,0>UW { align1 };
+add (1) g4.20<1>F g1.12<0,1,0>UW 1UB { align1 };
+mov (1) g4.24<1>F g1.12<0,1,0>UW { align1 };
+add (1) g4.28<1>F g1.12<0,1,0>UW 1UB { align1 };
+    /* set up ss1.y coordinates */
+mov (1) g6.16<1>F g1.14<0,1,0>UW { align1 };
+mov (1) g6.20<1>F g1.14<0,1,0>UW { align1 };
+add (1) g6.24<1>F g1.14<0,1,0>UW 1UB { align1 };
+add (1) g6.28<1>F g1.14<0,1,0>UW 1UB { align1 };
+    /* Set up ss2.x coordinates */
+mov (1) g5<1>F g1.16<0,1,0>UW { align1 };
+add (1) g5.4<1>F g1.16<0,1,0>UW 1UB { align1 };
+mov (1) g5.8<1>F g1.16<0,1,0>UW { align1 };
+add (1) g5.12<1>F g1.16<0,1,0>UW 1UB { align1 };
+    /* Set up ss2.y coordinates */
+mov (1) g7<1>F g1.18<0,1,0>UW { align1 };
+mov (1) g7.4<1>F g1.18<0,1,0>UW { align1 };
+add (1) g7.8<1>F g1.18<0,1,0>UW 1UB { align1 };
+add (1) g7.12<1>F g1.18<0,1,0>UW 1UB { align1 };
+    /* Set up ss3.x coordinates */
+mov (1) g5.16<1>F g1.20<0,1,0>UW { align1 };
+add (1) g5.20<1>F g1.20<0,1,0>UW 1UB { align1 };
+mov (1) g5.24<1>F g1.20<0,1,0>UW { align1 };
+add (1) g5.28<1>F g1.20<0,1,0>UW 1UB { align1 };
+    /* Set up ss3.y coordinates */
+mov (1) g7.16<1>F g1.22<0,1,0>UW { align1 };
+mov (1) g7.20<1>F g1.22<0,1,0>UW { align1 };
+add (1) g7.24<1>F g1.22<0,1,0>UW 1UB { align1 };
+add (1) g7.28<1>F g1.22<0,1,0>UW 1UB { align1 };
+
+    /* Now, map these screen space coordinates into texture coordinates. */
+    /* subtract screen-space X origin of vertex 0. */
+add (8) g4<1>F g4<8,8,1>F -g1<0,1,0>F { align1 };
+add (8) g5<1>F g5<8,8,1>F -g1<0,1,0>F { align1 };
+    /* scale by texture X increment */
+mul (8) g4<1>F g4<8,8,1>F g3<0,1,0>F { align1 };
+mul (8) g5<1>F g5<8,8,1>F g3<0,1,0>F { align1 };
+    /* add in texture X offset */
+add (8) g4<1>F g4<8,8,1>F g3.12<0,1,0>F { align1 };
+add (8) g5<1>F g5<8,8,1>F g3.12<0,1,0>F { align1 };
+    /* subtract screen-space Y origin of vertex 0. */
+add (8) g6<1>F g6<8,8,1>F -g1.4<0,1,0>F { align1 };
+add (8) g7<1>F g7<8,8,1>F -g1.4<0,1,0>F { align1 };
+    /* scale by texture Y increment */
+mul (8) g6<1>F g6<8,8,1>F g3.20<0,1,0>F { align1 };
+mul (8) g7<1>F g7<8,8,1>F g3.20<0,1,0>F { align1 };
+    /* add in texture Y offset */
+add (8) g6<1>F g6<8,8,1>F g3.28<0,1,0>F { align1 };
+add (8) g7<1>F g7<8,8,1>F g3.28<0,1,0>F { align1 };
+    /* sampler  */
+mov (8) m1<1>F g4<8,8,1>F { align1 };
+mov (8) m2<1>F g5<8,8,1>F { align1 };
+mov (8) m3<1>F g6<8,8,1>F { align1 };
+mov (8) m4<1>F g7<8,8,1>F { align1 };
+
+    /*
+     * g0 holds the PS thread payload, which (oddly) contains
+     * precisely what the sampler wants to see in m0
+     */
+send  (16) 0 g12<1>UW g0<8,8,1>UW sampler (1,0,F) mlen 5 rlen 8 { align1 };
+mov (8) g19<1>UW g19<8,8,1>UW { align1 };
+
+    /* color space conversion function:
+     * R = Clamp ( 1.164(Y-16/255) + 1.596(Cr-128/255), 0, 1)
+     * G = Clamp ( 1.164(Y-16/255) - 0.813(Cr-128/255) - 0.392(Cb-128/255), 0, 1)
+     * B = Clamp ( 1.164(Y-16/255) + 2.017(Cb-128/255), 0, 1)
+     *
+     * Y is g14, g15.
+     * Cr is g12, g13.
+     * Cb is g16, g17.
+     *
+     * R is g2, g6.
+     * G is g3, g7.
+     * B is g4, g8.
+     */
+	/* Y = Y - 16/255 */
+add (8) g14<1>F g14<8,8,1>F -0.0627451F { align1 };
+	/* Cr = Cr - 128/255 */
+add (8) g12<1>F g12<8,8,1>F -0.501961F { align1 };
+	/* Cb = Cb - 128 / 255 */
+add (8) g16<1>F g16<8,8,1>F -0.501961F { align1 };
+	/* Y = Y * 1.164 */
+mul (8) g14<1>F g14<8,8,1>F 1.164F { align1 };
+	/* acc = 1.596 * Cr */
+mul (8) null g12<8,8,1>F 1.596F { align1 };
+	/* R = acc + Y */
+mac.sat (8) m2<1>F g14<8,8,1>F 1F { align1  };
+	/* acc = Cr * -0.813 */
+mul (8) null g12<8,8,1>F -0.813F { align1 };
+	/* acc += Cb * -0.392 */
+mac (8) null g16<8,8,1>F -0.392F { align1 };
+	/* G = acc + Y */
+mac.sat (8) m3<1>F g14<8,8,1>F 1F { align1  };
+	/* acc = Cb * 2.017 */
+mul (8) null g16<8,8,1>F 2.017F { align1 };
+	/* B = acc + Y */
+mac.sat (8) m4<1>F g14<8,8,1>F 1F { align1  };
+ /* and do it again */
+add (8) g15<1>F g15<8,8,1>F -0.0627451F { align1 };
+add (8) g13<1>F g13<8,8,1>F -0.501961F { align1 };
+add (8) g17<1>F g17<8,8,1>F -0.501961F { align1 };
+mul (8) g15<1>F g15<8,8,1>F 1.164F { align1 };
+mul (8) null g13<8,8,1>F 1.596F { align1 };
+mac.sat (8) m6<1>F g15<8,8,1>F 1F { align1  };
+mul (8) null g13<8,8,1>F -0.813F { align1 };
+mac (8) null g17<8,8,1>F -0.392F { align1 };
+mac.sat (8) m7<1>F g15<8,8,1>F 1F { align1  };
+mul (8) null g17<8,8,1>F 2.017F { align1 };
+mac.sat (8) m8<1>F g15<8,8,1>F 1F { align1  };
+
+   /* Pass through control information:
+    */
+mov (8) m1<1>UD g1<8,8,1>UD { align1 mask_disable };
+   /* Send framebuffer write message: XXX: acc0? */
+send (16) 0 null g0<8,8,1>UW write (
+	0, /* binding table index 0 */
+	8, /* pixel scoreboard clear */
+	4, /* render target write */
+	0 /* no write commit message */
+	) mlen 10 rlen 0 { align1 EOT };
+   /* padding */
+nop;
+nop;
+nop;
+nop;
+nop;
+nop;
+nop;
+nop;
diff --git a/src/sf_prog.h b/src/sf_prog.h
new file mode 100644
index 0000000..830d176
--- /dev/null
+++ b/src/sf_prog.h
@@ -0,0 +1,17 @@
+   { 0x00000031, 0x20c01fbd, 0x0000002c, 0x01110081 },
+   { 0x00000031, 0x20c41fbd, 0x00000034, 0x01110081 },
+   { 0x00600040, 0x20e077bd, 0x008d0080, 0x008d4060 },
+   { 0x00000041, 0x20e077bd, 0x000000e0, 0x000000c0 },
+   { 0x00000041, 0x20e477bd, 0x000000e4, 0x000000c4 },
+   { 0x00600001, 0x202003be, 0x000000e0, 0x00000000 },
+   { 0x00600001, 0x204003be, 0x000000e4, 0x00000000 },
+   { 0x00600001, 0x206003be, 0x008d0060, 0x00000000 },
+   { 0x00600031, 0x20001fbc, 0x008d0000, 0x8640c800 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
diff --git a/src/wm_prog.h b/src/wm_prog.h
index 297ddcb..708e6eb 100644
--- a/src/wm_prog.h
+++ b/src/wm_prog.h
@@ -1,166 +1,82 @@
-/* wm_program */
-/*    mov (1) g4<1>F g1.8<0,1,0>UW { align1 +  } */
    { 0x00000001, 0x2080013d, 0x00000028, 0x00000000 },
-/*    add (1) g4.4<1>F g1.8<0,1,0>UW 1 { align1 +  } */
    { 0x00000040, 0x20840d3d, 0x00000028, 0x00000001 },
-/*    mov (1) g4.8<1>F g1.8<0,1,0>UW { align1 +  } */
    { 0x00000001, 0x2088013d, 0x00000028, 0x00000000 },
-/*    add (1) g4.12<1>F g1.8<0,1,0>UW 1 { align1 +  } */
    { 0x00000040, 0x208c0d3d, 0x00000028, 0x00000001 },
-/*    mov (1) g6<1>F g1.10<0,1,0>UW { align1 +  } */
    { 0x00000001, 0x20c0013d, 0x0000002a, 0x00000000 },
-/*    mov (1) g6.4<1>F g1.10<0,1,0>UW { align1 +  } */
    { 0x00000001, 0x20c4013d, 0x0000002a, 0x00000000 },
-/*    add (1) g6.8<1>F g1.10<0,1,0>UW 1 { align1 +  } */
    { 0x00000040, 0x20c80d3d, 0x0000002a, 0x00000001 },
-/*    add (1) g6.12<1>F g1.10<0,1,0>UW 1 { align1 +  } */
    { 0x00000040, 0x20cc0d3d, 0x0000002a, 0x00000001 },
-/*    mov (1) g4.16<1>F g1.12<0,1,0>UW { align1 +  } */
    { 0x00000001, 0x2090013d, 0x0000002c, 0x00000000 },
-/*    add (1) g4.20<1>F g1.12<0,1,0>UW 1 { align1 +  } */
    { 0x00000040, 0x20940d3d, 0x0000002c, 0x00000001 },
-/*    mov (1) g4.24<1>F g1.12<0,1,0>UW { align1 +  } */
    { 0x00000001, 0x2098013d, 0x0000002c, 0x00000000 },
-/*    add (1) g4.28<1>F g1.12<0,1,0>UW 1 { align1 +  } */
    { 0x00000040, 0x209c0d3d, 0x0000002c, 0x00000001 },
-/*    mov (1) g6.16<1>F g1.14<0,1,0>UW { align1 +  } */
    { 0x00000001, 0x20d0013d, 0x0000002e, 0x00000000 },
-/*    mov (1) g6.20<1>F g1.14<0,1,0>UW { align1 +  } */
    { 0x00000001, 0x20d4013d, 0x0000002e, 0x00000000 },
-/*    add (1) g6.24<1>F g1.14<0,1,0>UW 1 { align1 +  } */
    { 0x00000040, 0x20d80d3d, 0x0000002e, 0x00000001 },
-/*    add (1) g6.28<1>F g1.14<0,1,0>UW 1 { align1 +  } */
    { 0x00000040, 0x20dc0d3d, 0x0000002e, 0x00000001 },
-/*    mov (1) g5<1>F g1.16<0,1,0>UW { align1 +  } */
    { 0x00000001, 0x20a0013d, 0x00000030, 0x00000000 },
-/*    add (1) g5.4<1>F g1.16<0,1,0>UW 1 { align1 +  } */
    { 0x00000040, 0x20a40d3d, 0x00000030, 0x00000001 },
-/*    mov (1) g5.8<1>F g1.16<0,1,0>UW { align1 +  } */
    { 0x00000001, 0x20a8013d, 0x00000030, 0x00000000 },
-/*    add (1) g5.12<1>F g1.16<0,1,0>UW 1 { align1 +  } */
    { 0x00000040, 0x20ac0d3d, 0x00000030, 0x00000001 },
-/*    mov (1) g7<1>F g1.18<0,1,0>UW { align1 +  } */
    { 0x00000001, 0x20e0013d, 0x00000032, 0x00000000 },
-/*    mov (1) g7.4<1>F g1.18<0,1,0>UW { align1 +  } */
    { 0x00000001, 0x20e4013d, 0x00000032, 0x00000000 },
-/*    add (1) g7.8<1>F g1.18<0,1,0>UW 1 { align1 +  } */
    { 0x00000040, 0x20e80d3d, 0x00000032, 0x00000001 },
-/*    add (1) g7.12<1>F g1.18<0,1,0>UW 1 { align1 +  } */
    { 0x00000040, 0x20ec0d3d, 0x00000032, 0x00000001 },
-/*    mov (1) g5.16<1>F g1.20<0,1,0>UW { align1 +  } */
    { 0x00000001, 0x20b0013d, 0x00000034, 0x00000000 },
-/*    add (1) g5.20<1>F g1.20<0,1,0>UW 1 { align1 +  } */
    { 0x00000040, 0x20b40d3d, 0x00000034, 0x00000001 },
-/*    mov (1) g5.24<1>F g1.20<0,1,0>UW { align1 +  } */
    { 0x00000001, 0x20b8013d, 0x00000034, 0x00000000 },
-/*    add (1) g5.28<1>F g1.20<0,1,0>UW 1 { align1 +  } */
    { 0x00000040, 0x20bc0d3d, 0x00000034, 0x00000001 },
-/*    mov (1) g7.16<1>F g1.22<0,1,0>UW { align1 +  } */
    { 0x00000001, 0x20f0013d, 0x00000036, 0x00000000 },
-/*    mov (1) g7.20<1>F g1.22<0,1,0>UW { align1 +  } */
    { 0x00000001, 0x20f4013d, 0x00000036, 0x00000000 },
-/*    add (1) g7.24<1>F g1.22<0,1,0>UW 1 { align1 +  } */
    { 0x00000040, 0x20f80d3d, 0x00000036, 0x00000001 },
-/*    add (1) g7.28<1>F g1.22<0,1,0>UW 1 { align1 +  } */
    { 0x00000040, 0x20fc0d3d, 0x00000036, 0x00000001 },
-/*    add (8) g4<1>F g4<8,8,1>F g1<0,1,0>F { align1 +  } */
    { 0x00600040, 0x208077bd, 0x008d0080, 0x00004020 },
-/*    add (8) g5<1>F g5<8,8,1>F g1<0,1,0>F { align1 +  } */
    { 0x00600040, 0x20a077bd, 0x008d00a0, 0x00004020 },
-/*    mul (8) g4<1>F g4<8,8,1>F g3<0,1,0>F { align1 +  } */
    { 0x00600041, 0x208077bd, 0x008d0080, 0x00000060 },
-/*    mul (8) g5<1>F g5<8,8,1>F g3<0,1,0>F { align1 +  } */
    { 0x00600041, 0x20a077bd, 0x008d00a0, 0x00000060 },
-/*    add (8) g4<1>F g4<8,8,1>F g3.12<0,1,0>F { align1 +  } */
    { 0x00600040, 0x208077bd, 0x008d0080, 0x0000006c },
-/*    add (8) g5<1>F g5<8,8,1>F g3.12<0,1,0>F { align1 +  } */
    { 0x00600040, 0x20a077bd, 0x008d00a0, 0x0000006c },
-/*    add (8) g6<1>F g6<8,8,1>F g1.4<0,1,0>F { align1 +  } */
    { 0x00600040, 0x20c077bd, 0x008d00c0, 0x00004024 },
-/*    add (8) g7<1>F g7<8,8,1>F g1.4<0,1,0>F { align1 +  } */
    { 0x00600040, 0x20e077bd, 0x008d00e0, 0x00004024 },
-/*    mul (8) g6<1>F g6<8,8,1>F g3.20<0,1,0>F { align1 +  } */
    { 0x00600041, 0x20c077bd, 0x008d00c0, 0x00000074 },
-/*    mul (8) g7<1>F g7<8,8,1>F g3.20<0,1,0>F { align1 +  } */
    { 0x00600041, 0x20e077bd, 0x008d00e0, 0x00000074 },
-/*    add (8) g6<1>F g6<8,8,1>F g3.28<0,1,0>F { align1 +  } */
    { 0x00600040, 0x20c077bd, 0x008d00c0, 0x0000007c },
-/*    add (8) g7<1>F g7<8,8,1>F g3.28<0,1,0>F { align1 +  } */
    { 0x00600040, 0x20e077bd, 0x008d00e0, 0x0000007c },
-/*    mov (8) m1<1>F g4<8,8,1>F { align1 +  } */
    { 0x00600001, 0x202003be, 0x008d0080, 0x00000000 },
-/*    mov (8) m2<1>F g5<8,8,1>F { align1 +  } */
    { 0x00600001, 0x204003be, 0x008d00a0, 0x00000000 },
-/*    mov (8) m3<1>F g6<8,8,1>F { align1 +  } */
    { 0x00600001, 0x206003be, 0x008d00c0, 0x00000000 },
-/*    mov (8) m4<1>F g7<8,8,1>F { align1 +  } */
    { 0x00600001, 0x208003be, 0x008d00e0, 0x00000000 },
-/*    send   0 (16) g12<1>UW g0<8,8,1>UW sampler mlen 5 rlen 8 { align1 +  } */
    { 0x00800031, 0x21801d29, 0x008d0000, 0x02580001 },
-/*    mov (8) g19<1>UW g19<8,8,1>UW { align1 +  } */
    { 0x00600001, 0x22600129, 0x008d0260, 0x00000000 },
-/*    add (8) g14<1>F g14<8,8,1>F -0.0627451{ align1 +  } */
    { 0x00600040, 0x21c07fbd, 0x008d01c0, 0xbd808081 },
-/*    add (8) g12<1>F g12<8,8,1>F -0.501961{ align1 +  } */
-   { 0x00600040, 0x21807fbd, 0x008d0180, 0xbf008081 },
-/*    add (8) g16<1>F g16<8,8,1>F -0.501961{ align1 +  } */
-   { 0x00600040, 0x22007fbd, 0x008d0200, 0xbf008081 },
-/*    mul (8) g14<1>F g14<8,8,1>F 1.164{ align1 +  } */
+   { 0x00600040, 0x21807fbd, 0x008d0180, 0xbf008084 },
+   { 0x00600040, 0x22007fbd, 0x008d0200, 0xbf008084 },
    { 0x00600041, 0x21c07fbd, 0x008d01c0, 0x3f94fdf4 },
-/*    mul (8) a0<1>F g12<8,8,1>F 1.596{ align1 +  } */
    { 0x00600041, 0x20007fbc, 0x008d0180, 0x3fcc49ba },
-/*    mac (8) m2<1>F g14<8,8,1>F 1{ align1 + Saturate  } */
    { 0x80600048, 0x20407fbe, 0x008d01c0, 0x3f800000 },
-/*    mul (8) a0<1>F g12<8,8,1>F -0.813{ align1 +  } */
    { 0x00600041, 0x20007fbc, 0x008d0180, 0xbf5020c5 },
-/*    mac (8) a0<1>F g16<8,8,1>F -0.392{ align1 +  } */
    { 0x00600048, 0x20007fbc, 0x008d0200, 0xbec8b439 },
-/*    mac (8) m3<1>F g14<8,8,1>F 1{ align1 + Saturate  } */
    { 0x80600048, 0x20607fbe, 0x008d01c0, 0x3f800000 },
-/*    mul (8) a0<1>F g16<8,8,1>F 2.017{ align1 +  } */
    { 0x00600041, 0x20007fbc, 0x008d0200, 0x40011687 },
-/*    mac (8) m4<1>F g14<8,8,1>F 1{ align1 + Saturate  } */
    { 0x80600048, 0x20807fbe, 0x008d01c0, 0x3f800000 },
-/*    add (8) g15<1>F g15<8,8,1>F -0.0627451{ align1 +  } */
    { 0x00600040, 0x21e07fbd, 0x008d01e0, 0xbd808081 },
-/*    add (8) g13<1>F g13<8,8,1>F -0.501961{ align1 +  } */
-   { 0x00600040, 0x21a07fbd, 0x008d01a0, 0xbf008081 },
-/*    add (8) g17<1>F g17<8,8,1>F -0.501961{ align1 +  } */
-   { 0x00600040, 0x22207fbd, 0x008d0220, 0xbf008081 },
-/*    mul (8) g15<1>F g15<8,8,1>F 1.164{ align1 +  } */
+   { 0x00600040, 0x21a07fbd, 0x008d01a0, 0xbf008084 },
+   { 0x00600040, 0x22207fbd, 0x008d0220, 0xbf008084 },
    { 0x00600041, 0x21e07fbd, 0x008d01e0, 0x3f94fdf4 },
-/*    mul (8) a0<1>F g13<8,8,1>F 1.596{ align1 +  } */
    { 0x00600041, 0x20007fbc, 0x008d01a0, 0x3fcc49ba },
-/*    mac (8) m6<1>F g15<8,8,1>F 1{ align1 + Saturate  } */
    { 0x80600048, 0x20c07fbe, 0x008d01e0, 0x3f800000 },
-/*    mul (8) a0<1>F g13<8,8,1>F -0.813{ align1 +  } */
    { 0x00600041, 0x20007fbc, 0x008d01a0, 0xbf5020c5 },
-/*    mac (8) a0<1>F g17<8,8,1>F -0.392{ align1 +  } */
    { 0x00600048, 0x20007fbc, 0x008d0220, 0xbec8b439 },
-/*    mac (8) m7<1>F g15<8,8,1>F 1{ align1 + Saturate  } */
    { 0x80600048, 0x20e07fbe, 0x008d01e0, 0x3f800000 },
-/*    mul (8) a0<1>F g17<8,8,1>F 2.017{ align1 +  } */
    { 0x00600041, 0x20007fbc, 0x008d0220, 0x40011687 },
-/*    mac (8) m8<1>F g15<8,8,1>F 1{ align1 + Saturate  } */
    { 0x80600048, 0x21007fbe, 0x008d01e0, 0x3f800000 },
-/*    mov (8) m1<1>UD g1<8,8,1>UD { align1 mask_disable +  } */
    { 0x00600201, 0x20200022, 0x008d0020, 0x00000000 },
-/*    send   0 (16) a0<1>UW g0<8,8,1>UW write mlen 10 rlen 0 EOT{ align1 +  } */
-   { 0x00800031, 0x20001d28, 0x008d0000, 0x85a04800 },
-/*    nop (4) g0<1>UD { align1 +  } */
-   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-/*    nop (4) g0<1>UD { align1 +  } */
-   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-/*    nop (4) g0<1>UD { align1 +  } */
-   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-/*    nop (4) g0<1>UD { align1 +  } */
-   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-/*    nop (4) g0<1>UD { align1 +  } */
-   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-/*    nop (4) g0<1>UD { align1 +  } */
-   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-/*    nop (4) g0<1>UD { align1 +  } */
-   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-/*    nop (4) g0<1>UD { align1 +  } */
-   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-
+   { 0x00800031, 0x20001d3c, 0x008d0000, 0x85a04800 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
diff-tree cbaf3cf74bd420533d299c4113761ec536097e33 (from 421b415e23c1ddc78837cd222167d6ed71a3ef88)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Thu Aug 31 18:25:21 2006 -0700

    verbose debug message for panel sync data

diff --git a/src/i830_bios.c b/src/i830_bios.c
index 4b87351..b68c467 100644
--- a/src/i830_bios.c
+++ b/src/i830_bios.c
@@ -210,7 +210,13 @@ i830GetLVDSInfoFromBIOS(ScrnInfoPtr pScr
 	    pI830->panel_fixed_vblank = _V_BLANK(timing_ptr);
 	    pI830->panel_fixed_vsyncoff = _V_SYNC_OFF(timing_ptr);
 	    pI830->panel_fixed_vsyncwidth = _V_SYNC_WIDTH(timing_ptr);
-
+	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+		       "Panel mode h active %d blank %d rate %f v active %d blank %d rate %f\n",
+		       pI830->panel_fixed_hactive, pI830->panel_fixed_hblank,
+		       (double) pI830->panel_fixed_clock / (pI830->panel_fixed_hactive + pI830->panel_fixed_hblank),
+		       pI830->panel_fixed_vactive, pI830->panel_fixed_vblank,
+		       (double) pI830->panel_fixed_clock / 
+		       ((pI830->panel_fixed_hactive + pI830->panel_fixed_hblank) * (pI830->panel_fixed_vactive + pI830->panel_fixed_vblank)));
 	    found_panel_info = TRUE;
 	    break;
 	}
diff-tree 1feb733eb8b09a8b07b7a6987add5149c53b0157 (from 26e6c074c17b2d4e9b9f165468ad45a3b0ecc0ef)
Author: Alan Hourihane <alanh at fairlite.demon.co.uk>
Date:   Tue Aug 29 14:54:15 2006 +0100

    Fix bug with probing info of DFP2 and LFP2 connected
    devices (Aaron Ridout)

diff --git a/src/i810_reg.h b/src/i810_reg.h
index 05710c4..4bb5bf1 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -1238,12 +1238,11 @@ typedef enum {
    TvIndex,
    DfpIndex,
    LfpIndex,
+   Crt2Index,
    Tv2Index,
    Dfp2Index,
-   UnknownIndex,
-   Unknown2Index,
-   NumDisplayTypes,
-   NumKnownDisplayTypes = UnknownIndex
+   Lfp2Index,
+   NumDisplayTypes
 } DisplayType;
 
 /* What's connected to the pipes (as reported by the BIOS) */
@@ -1252,10 +1251,10 @@ typedef enum {
 #define PIPE_TV_ACTIVE			(1 << TvIndex)
 #define PIPE_DFP_ACTIVE			(1 << DfpIndex)
 #define PIPE_LCD_ACTIVE			(1 << LfpIndex)
+#define PIPE_CRT2_ACTIVE		(1 << Crt2Index)
 #define PIPE_TV2_ACTIVE			(1 << Tv2Index)
 #define PIPE_DFP2_ACTIVE		(1 << Dfp2Index)
-#define PIPE_UNKNOWN_ACTIVE		((1 << UnknownIndex) |	\
-					 (1 << Unknown2Index))
+#define PIPE_LCD2_ACTIVE		(1 << Lfp2Index)
 
 #define PIPE_SIZED_DISP_MASK		(PIPE_DFP_ACTIVE |	\
 					 PIPE_LCD_ACTIVE |	\
diff --git a/src/i830_driver.c b/src/i830_driver.c
index cebb379..a05fb17 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -2852,12 +2852,14 @@ GetDisplayInfo(ScrnInfoPtr pScrn, int de
    DPRINTF(PFX, "GetDisplayInfo: device: 0x%x\n", device);
 
    switch (device & 0xff) {
-   case 0x01:
-   case 0x02:
-   case 0x04:
-   case 0x08:
-   case 0x10:
-   case 0x20:
+   case PIPE_CRT:
+   case PIPE_TV:
+   case PIPE_DFP:
+   case PIPE_LFP:
+   case PIPE_CRT2:
+   case PIPE_TV2:
+   case PIPE_DFP2:
+   case PIPE_LFP2:
       break;
    default:
       xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
@@ -2964,10 +2966,6 @@ PrintDisplayDeviceInfo(ScrnInfoPtr pScrn
 	    name = DeviceToString(-1);
 	 } while (name);
 
-	 if (pipe & PIPE_UNKNOWN_ACTIVE)
-	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-		       "\tSome unknown display devices may also be present\n");
-
       } else {
 	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 		    "No active displays on Pipe %c.\n", PIPE_NAME(n));
@@ -3000,7 +2998,7 @@ GetPipeSizes(ScrnInfoPtr pScrn)
       pipe = (pI830->operatingDevices >> PIPE_SHIFT(n)) & PIPE_ACTIVE_MASK;
       pI830->pipeDisplaySize[n].x1 = pI830->pipeDisplaySize[n].y1 = 0;
       pI830->pipeDisplaySize[n].x2 = pI830->pipeDisplaySize[n].y2 = 4096;
-      for (i = 0; i < NumKnownDisplayTypes; i++) {
+      for (i = 0; i < NumDisplayTypes; i++) {
          if (pipe & (1 << i) & PIPE_SIZED_DISP_MASK) {
 	    if (pI830->displaySize[i].x2 != 0) {
 	       xf86DrvMsg(pScrn->scrnIndex, X_INFO,
@@ -3037,7 +3035,7 @@ I830DetectDisplayDevice(ScrnInfoPtr pScr
 		  "\t      If you encounter this problem please add \n"
 		  "\t\t Option \"DisplayInfo\" \"FALSE\"\n"
 		  "\t      to the Device section of your XF86Config file.\n");
-      for (i = 0; i < NumKnownDisplayTypes; i++) {
+      for (i = 0; i < NumDisplayTypes; i++) {
          if (GetDisplayInfo(pScrn, 1 << i, &pI830->displayAttached[i],
 			 &pI830->displayPresent[i],
 			 &pI830->displaySize[i].x2,
diff-tree 26e6c074c17b2d4e9b9f165468ad45a3b0ecc0ef (from ea63e82ef417a9918e7d7105910a8ddeba2994f6)
Author: Alan Hourihane <alanh at fairlite.demon.co.uk>
Date:   Mon Aug 28 11:55:38 2006 +0100

    Fix SetVBlank to operate all the time

diff --git a/src/i830_driver.c b/src/i830_driver.c
index c0d9672..cebb379 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -8079,13 +8079,15 @@ I830BIOSEnterVT(int scrnIndex, int flags
 
 #ifdef XF86DRI
    if (pI830->directRenderingEnabled) {
+
+      I830DRISetVBlankInterrupt (pScrn, TRUE);
+
       if (!pI830->starting) {
          ScreenPtr pScreen = pScrn->pScreen;
          drmI830Sarea *sarea = (drmI830Sarea *) DRIGetSAREAPrivate(pScreen);
          int i;
 
 	 I830DRIResume(screenInfo.screens[scrnIndex]);
-         I830DRISetVBlankInterrupt (pScrn, TRUE);
       
 	 I830RefreshRing(pScrn);
 	 I830Sync(pScrn);
diff-tree ea63e82ef417a9918e7d7105910a8ddeba2994f6 (from dc4128ea0781124984dee0cb41e7b6ee87e362a1)
Author: Alan Hourihane <alanh at fairlite.demon.co.uk>
Date:   Tue Aug 22 16:40:08 2006 +0100

    fix typo

diff --git a/src/brw_structs.h b/src/brw_structs.h
index c3b78f7..d2f9be0 100644
--- a/src/brw_structs.h
+++ b/src/brw_structs.h
@@ -648,7 +648,7 @@ struct brw_cc_unit_state
    struct {
       union {
 	 float f;  
-	 unsigned byte ub[4];
+	 unsigned char ub[4];
       } alpha_ref;
    } cc7;
 };
diff-tree dc4128ea0781124984dee0cb41e7b6ee87e362a1 (from dad0e7fc09fa7794f20278d9d99abd96a21b691e)
Author: Alan Hourihane <alanh at fairlite.demon.co.uk>
Date:   Mon Aug 21 12:13:42 2006 +0100

    remove GL* usage

diff --git a/src/brw_structs.h b/src/brw_structs.h
index 50b5fda..c3b78f7 100644
--- a/src/brw_structs.h
+++ b/src/brw_structs.h
@@ -28,45 +28,43 @@
 #ifndef BRW_STRUCTS_H
 #define BRW_STRUCTS_H
 
-#include <GL/gl.h>
-
 /* Command packets:
  */
 struct header 
 {
-   GLuint length:16; 
-   GLuint opcode:16; 
+   unsigned int length:16; 
+   unsigned int opcode:16; 
 } bits;
 
 
 union header_union
 {
    struct header bits;
-   GLuint dword;
+   unsigned int dword;
 };
 
 struct brw_3d_control
 {   
    struct 
    {
-      GLuint length:8;
-      GLuint notify_enable:1;
-      GLuint pad:3;
-      GLuint wc_flush_enable:1; 
-      GLuint depth_stall_enable:1; 
-      GLuint operation:2; 
-      GLuint opcode:16; 
+      unsigned int length:8;
+      unsigned int notify_enable:1;
+      unsigned int pad:3;
+      unsigned int wc_flush_enable:1; 
+      unsigned int depth_stall_enable:1; 
+      unsigned int operation:2; 
+      unsigned int opcode:16; 
    } header;
    
    struct
    {
-      GLuint pad:2;
-      GLuint dest_addr_type:1; 
-      GLuint dest_addr:29; 
+      unsigned int pad:2;
+      unsigned int dest_addr_type:1; 
+      unsigned int dest_addr:29; 
    } dest;
    
-   GLuint dword2;   
-   GLuint dword3;   
+   unsigned int dword2;   
+   unsigned int dword3;   
 };
 
 
@@ -74,18 +72,18 @@ struct brw_3d_primitive
 {
    struct
    {
-      GLuint length:8; 
-      GLuint pad:2;
-      GLuint topology:5; 
-      GLuint indexed:1; 
-      GLuint opcode:16; 
+      unsigned int length:8; 
+      unsigned int pad:2;
+      unsigned int topology:5; 
+      unsigned int indexed:1; 
+      unsigned int opcode:16; 
    } header;
 
-   GLuint verts_per_instance;  
-   GLuint start_vert_location;  
-   GLuint instance_count;  
-   GLuint start_instance_location;  
-   GLuint base_vert_location;  
+   unsigned int verts_per_instance;  
+   unsigned int start_vert_location;  
+   unsigned int instance_count;  
+   unsigned int start_instance_location;  
+   unsigned int base_vert_location;  
 };
 
 /* These seem to be passed around as function args, so it works out
@@ -98,16 +96,16 @@ struct brw_3d_primitive
 
 struct brw_mi_flush
 {
-   GLuint flags:4;
-   GLuint pad:12;
-   GLuint opcode:16;
+   unsigned int flags:4;
+   unsigned int pad:12;
+   unsigned int opcode:16;
 };
 
 struct brw_vf_statistics
 {
-   GLuint statistics_enable:1;
-   GLuint pad:15;
-   GLuint opcode:16;
+   unsigned int statistics_enable:1;
+   unsigned int pad:15;
+   unsigned int opcode:16;
 };
 
 
@@ -115,18 +113,18 @@ struct brw_vf_statistics
 struct brw_binding_table_pointers
 {
    struct header header;
-   GLuint vs; 
-   GLuint gs; 
-   GLuint clp; 
-   GLuint sf; 
-   GLuint wm; 
+   unsigned int vs; 
+   unsigned int gs; 
+   unsigned int clp; 
+   unsigned int sf; 
+   unsigned int wm; 
 };
 
 
 struct brw_blend_constant_color
 {
    struct header header;
-   GLfloat blend_constant_color[4];  
+   float blend_constant_color[4];  
 };
 
 
@@ -136,50 +134,50 @@ struct brw_depthbuffer
    
    union {
       struct {
-	 GLuint pitch:18; 
-	 GLuint format:3; 
-	 GLuint pad:4;
-	 GLuint depth_offset_disable:1; 
-	 GLuint tile_walk:1; 
-	 GLuint tiled_surface:1; 
-	 GLuint pad2:1;
-	 GLuint surface_type:3; 
+	 unsigned int pitch:18; 
+	 unsigned int format:3; 
+	 unsigned int pad:4;
+	 unsigned int depth_offset_disable:1; 
+	 unsigned int tile_walk:1; 
+	 unsigned int tiled_surface:1; 
+	 unsigned int pad2:1;
+	 unsigned int surface_type:3; 
       } bits;
-      GLuint dword;
+      unsigned int dword;
    } dword1;
    
-   GLuint dword2_base_addr; 
+   unsigned int dword2_base_addr; 
  
    union {
       struct {
-	 GLuint pad:1;
-	 GLuint mipmap_layout:1; 
-	 GLuint lod:4; 
-	 GLuint width:13; 
-	 GLuint height:13; 
+	 unsigned int pad:1;
+	 unsigned int mipmap_layout:1; 
+	 unsigned int lod:4; 
+	 unsigned int width:13; 
+	 unsigned int height:13; 
       } bits;
-      GLuint dword;
+      unsigned int dword;
    } dword3;
 
    union {
       struct {
-	 GLuint pad:12;
-	 GLuint min_array_element:9; 
-	 GLuint depth:11; 
+	 unsigned int pad:12;
+	 unsigned int min_array_element:9; 
+	 unsigned int depth:11; 
       } bits;
-      GLuint dword;
+      unsigned int dword;
    } dword4;
 };
 
 struct brw_drawrect
 {
    struct header header;
-   GLuint xmin:16; 
-   GLuint ymin:16; 
-   GLuint xmax:16; 
-   GLuint ymax:16; 
-   GLuint xorg:16;  
-   GLuint yorg:16;  
+   unsigned int xmin:16; 
+   unsigned int ymin:16; 
+   unsigned int xmax:16; 
+   unsigned int ymax:16; 
+   unsigned int xorg:16;  
+   unsigned int yorg:16;  
 };
 
 
@@ -188,7 +186,7 @@ struct brw_drawrect
 struct brw_global_depth_offset_clamp
 {
    struct header header;
-   GLfloat depth_offset_clamp;  
+   float depth_offset_clamp;  
 };
 
 struct brw_indexbuffer
@@ -196,18 +194,18 @@ struct brw_indexbuffer
    union {
       struct
       {
-	 GLuint length:8; 
-	 GLuint index_format:2; 
-	 GLuint cut_index_enable:1; 
-	 GLuint pad:5; 
-	 GLuint opcode:16; 
+	 unsigned int length:8; 
+	 unsigned int index_format:2; 
+	 unsigned int cut_index_enable:1; 
+	 unsigned int pad:5; 
+	 unsigned int opcode:16; 
       } bits;
-      GLuint dword;
+      unsigned int dword;
 
    } header;
 
-   GLuint buffer_start; 
-   GLuint buffer_end; 
+   unsigned int buffer_start; 
+   unsigned int buffer_end; 
 };
 
 
@@ -217,15 +215,15 @@ struct brw_line_stipple
   
    struct
    {
-      GLuint pattern:16; 
-      GLuint pad:16;
+      unsigned int pattern:16; 
+      unsigned int pad:16;
    } bits0;
    
    struct
    {
-      GLuint repeat_count:9; 
-      GLuint pad:7;
-      GLuint inverse_repeat_count:16; 
+      unsigned int repeat_count:9; 
+      unsigned int pad:7;
+      unsigned int inverse_repeat_count:16; 
    } bits1;
 };
 
@@ -235,40 +233,40 @@ struct brw_pipelined_state_pointers
    struct header header;
    
    struct {
-      GLuint pad:5;
-      GLuint offset:27; 
+      unsigned int pad:5;
+      unsigned int offset:27; 
    } vs;
    
    struct
    {
-      GLuint enable:1;
-      GLuint pad:4;
-      GLuint offset:27; 
+      unsigned int enable:1;
+      unsigned int pad:4;
+      unsigned int offset:27; 
    } gs;
    
    struct
    {
-      GLuint enable:1;
-      GLuint pad:4;
-      GLuint offset:27; 
+      unsigned int enable:1;
+      unsigned int pad:4;
+      unsigned int offset:27; 
    } clp;
    
    struct
    {
-      GLuint pad:5;
-      GLuint offset:27; 
+      unsigned int pad:5;
+      unsigned int offset:27; 
    } sf;
 
    struct
    {
-      GLuint pad:5;
-      GLuint offset:27; 
+      unsigned int pad:5;
+      unsigned int offset:27; 
    } wm;
    
    struct
    {
-      GLuint pad:5;
-      GLuint offset:27; /* KW: check me! */
+      unsigned int pad:5;
+      unsigned int offset:27; /* KW: check me! */
    } cc;
 };
 
@@ -278,10 +276,10 @@ struct brw_polygon_stipple_offset
    struct header header;
 
    struct {
-      GLuint y_offset:5; 
-      GLuint pad:3;
-      GLuint x_offset:5; 
-      GLuint pad0:19;
+      unsigned int y_offset:5; 
+      unsigned int pad:3;
+      unsigned int x_offset:5; 
+      unsigned int pad0:19;
    } bits0;
 };
 
@@ -290,7 +288,7 @@ struct brw_polygon_stipple_offset
 struct brw_polygon_stipple
 {
    struct header header;
-   GLuint stipple[32];
+   unsigned int stipple[32];
 };
 
 
@@ -299,9 +297,9 @@ struct brw_pipeline_select
 {
    struct
    {
-      GLuint pipeline_select:1;   
-      GLuint pad:15;
-      GLuint opcode:16;   
+      unsigned int pipeline_select:1;   
+      unsigned int pad:15;
+      unsigned int opcode:16;   
    } header;
 };
 
@@ -310,26 +308,26 @@ struct brw_pipe_control
 {
    struct
    {
-      GLuint length:8;
-      GLuint notify_enable:1;
-      GLuint pad:2;
-      GLuint instruction_state_cache_flush_enable:1;
-      GLuint write_cache_flush_enable:1;
-      GLuint depth_stall_enable:1;
-      GLuint post_sync_operation:2;
+      unsigned int length:8;
+      unsigned int notify_enable:1;
+      unsigned int pad:2;
+      unsigned int instruction_state_cache_flush_enable:1;
+      unsigned int write_cache_flush_enable:1;
+      unsigned int depth_stall_enable:1;
+      unsigned int post_sync_operation:2;
 
-      GLuint opcode:16;
+      unsigned int opcode:16;
    } header;
 
    struct
    {
-      GLuint pad:2;
-      GLuint dest_addr_type:1;
-      GLuint dest_addr:29;
+      unsigned int pad:2;
+      unsigned int dest_addr_type:1;
+      unsigned int dest_addr:29;
    } bits1;
 
-   GLuint data0;
-   GLuint data1;
+   unsigned int data0;
+   unsigned int data1;
 };
 
 
@@ -337,31 +335,31 @@ struct brw_urb_fence
 {
    struct
    {
-      GLuint length:8;   
-      GLuint vs_realloc:1;   
-      GLuint gs_realloc:1;   
-      GLuint clp_realloc:1;   
-      GLuint sf_realloc:1;   
-      GLuint vfe_realloc:1;   
-      GLuint cs_realloc:1;   
-      GLuint pad:2;
-      GLuint opcode:16;   
+      unsigned int length:8;   
+      unsigned int vs_realloc:1;   
+      unsigned int gs_realloc:1;   
+      unsigned int clp_realloc:1;   
+      unsigned int sf_realloc:1;   
+      unsigned int vfe_realloc:1;   
+      unsigned int cs_realloc:1;   
+      unsigned int pad:2;
+      unsigned int opcode:16;   
    } header;
 
    struct
    {
-      GLuint vs_fence:10;  
-      GLuint gs_fence:10;  
-      GLuint clp_fence:10;  
-      GLuint pad:2;
+      unsigned int vs_fence:10;  
+      unsigned int gs_fence:10;  
+      unsigned int clp_fence:10;  
+      unsigned int pad:2;
    } bits0;
 
    struct
    {
-      GLuint sf_fence:10;  
-      GLuint vf_fence:10;  
-      GLuint cs_fence:10;  
-      GLuint pad:2;
+      unsigned int sf_fence:10;  
+      unsigned int vf_fence:10;  
+      unsigned int cs_fence:10;  
+      unsigned int pad:2;
    } bits1;
 };
 
@@ -371,10 +369,10 @@ struct brw_constant_buffer_state /* prev
 
    struct
    {
-      GLuint nr_urb_entries:3;   
-      GLuint pad:1;
-      GLuint urb_entry_size:5;   
-      GLuint pad0:23;
+      unsigned int nr_urb_entries:3;   
+      unsigned int pad:1;
+      unsigned int urb_entry_size:5;   
+      unsigned int pad0:23;
    } bits0;
 };
 
@@ -382,16 +380,16 @@ struct brw_constant_buffer
 {
    struct
    {
-      GLuint length:8;   
-      GLuint valid:1;   
-      GLuint pad:7;
-      GLuint opcode:16;   
+      unsigned int length:8;   
+      unsigned int valid:1;   
+      unsigned int pad:7;
+      unsigned int opcode:16;   
    } header;
 
    struct
    {
-      GLuint buffer_length:6;   
-      GLuint buffer_address:26;  
+      unsigned int buffer_length:6;   
+      unsigned int buffer_address:26;  
    } bits0;
 };
 
@@ -401,37 +399,37 @@ struct brw_state_base_address
 
    struct
    {
-      GLuint modify_enable:1;
-      GLuint pad:4;
-      GLuint general_state_address:27;  
+      unsigned int modify_enable:1;
+      unsigned int pad:4;
+      unsigned int general_state_address:27;  
    } bits0;
 
    struct
    {
-      GLuint modify_enable:1;
-      GLuint pad:4;
-      GLuint surface_state_address:27;  
+      unsigned int modify_enable:1;
+      unsigned int pad:4;
+      unsigned int surface_state_address:27;  
    } bits1;
 
    struct
    {
-      GLuint modify_enable:1;
-      GLuint pad:4;
-      GLuint indirect_object_state_address:27;  
+      unsigned int modify_enable:1;
+      unsigned int pad:4;
+      unsigned int indirect_object_state_address:27;  
    } bits2;
 
    struct
    {
-      GLuint modify_enable:1;
-      GLuint pad:11;
-      GLuint general_state_upper_bound:20;  
+      unsigned int modify_enable:1;
+      unsigned int pad:11;
+      unsigned int general_state_upper_bound:20;  
    } bits3;
 
    struct
    {
-      GLuint modify_enable:1;
-      GLuint pad:11;
-      GLuint indirect_object_state_upper_bound:20;  
+      unsigned int modify_enable:1;
+      unsigned int pad:11;
+      unsigned int indirect_object_state_upper_bound:20;  
    } bits4;
 };
 
@@ -441,9 +439,9 @@ struct brw_state_prefetch
 
    struct
    {
-      GLuint prefetch_count:3;   
-      GLuint pad:3;
-      GLuint prefetch_pointer:26;  
+      unsigned int prefetch_count:3;   
+      unsigned int pad:3;
+      unsigned int prefetch_pointer:26;  
    } bits0;
 };
 
@@ -453,8 +451,8 @@ struct brw_system_instruction_pointer
 
    struct
    {
-      GLuint pad:4;
-      GLuint system_instruction_pointer:28;  
+      unsigned int pad:4;
+      unsigned int system_instruction_pointer:28;  
    } bits0;
 };
 
@@ -467,48 +465,48 @@ struct brw_system_instruction_pointer
 
 struct thread0
 {
-   GLuint pad0:1;
-   GLuint grf_reg_count:3; 
-   GLuint pad1:2;
-   GLuint kernel_start_pointer:26; 
+   unsigned int pad0:1;
+   unsigned int grf_reg_count:3; 
+   unsigned int pad1:2;
+   unsigned int kernel_start_pointer:26; 
 };
 
 struct thread1
 {
-   GLuint ext_halt_exception_enable:1; 
-   GLuint sw_exception_enable:1; 
-   GLuint mask_stack_exception_enable:1; 
-   GLuint timeout_exception_enable:1; 
-   GLuint illegal_op_exception_enable:1; 
-   GLuint pad0:3;
-   GLuint depth_coef_urb_read_offset:6;	/* WM only */
-   GLuint pad1:2;
-   GLuint floating_point_mode:1; 
-   GLuint thread_priority:1; 
-   GLuint binding_table_entry_count:8; 
-   GLuint pad3:5;
-   GLuint single_program_flow:1; 
+   unsigned int ext_halt_exception_enable:1; 
+   unsigned int sw_exception_enable:1; 
+   unsigned int mask_stack_exception_enable:1; 
+   unsigned int timeout_exception_enable:1; 
+   unsigned int illegal_op_exception_enable:1; 
+   unsigned int pad0:3;
+   unsigned int depth_coef_urb_read_offset:6;	/* WM only */
+   unsigned int pad1:2;
+   unsigned int floating_point_mode:1; 
+   unsigned int thread_priority:1; 
+   unsigned int binding_table_entry_count:8; 
+   unsigned int pad3:5;
+   unsigned int single_program_flow:1; 
 };
 
 struct thread2
 {
-   GLuint per_thread_scratch_space:4; 
-   GLuint pad0:6;
-   GLuint scratch_space_base_pointer:22; 
+   unsigned int per_thread_scratch_space:4; 
+   unsigned int pad0:6;
+   unsigned int scratch_space_base_pointer:22; 
 };
 
    
 struct thread3
 {
-   GLuint dispatch_grf_start_reg:4; 
-   GLuint urb_entry_read_offset:6; 
-   GLuint pad0:1;
-   GLuint urb_entry_read_length:6; 
-   GLuint pad1:1;
-   GLuint const_urb_entry_read_offset:6; 
-   GLuint pad2:1;
-   GLuint const_urb_entry_read_length:6; 
-   GLuint pad3:1;
+   unsigned int dispatch_grf_start_reg:4; 
+   unsigned int urb_entry_read_offset:6; 
+   unsigned int pad0:1;
+   unsigned int urb_entry_read_length:6; 
+   unsigned int pad1:1;
+   unsigned int const_urb_entry_read_offset:6; 
+   unsigned int pad2:1;
+   unsigned int const_urb_entry_read_length:6; 
+   unsigned int pad3:1;
 };
 
 
@@ -522,43 +520,43 @@ struct brw_clip_unit_state
 
    struct
    {
-      GLuint pad0:9;
-      GLuint gs_output_stats:1; /* not always */
-      GLuint stats_enable:1; 
-      GLuint nr_urb_entries:7; 
-      GLuint pad1:1;
-      GLuint urb_entry_allocation_size:5; 
-      GLuint pad2:1;
-      GLuint max_threads:6; 	/* may be less */
-      GLuint pad3:1;
+      unsigned int pad0:9;
+      unsigned int gs_output_stats:1; /* not always */
+      unsigned int stats_enable:1; 
+      unsigned int nr_urb_entries:7; 
+      unsigned int pad1:1;
+      unsigned int urb_entry_allocation_size:5; 
+      unsigned int pad2:1;
+      unsigned int max_threads:6; 	/* may be less */
+      unsigned int pad3:1;
    } thread4;   
       
    struct
    {
-      GLuint pad0:13;
-      GLuint clip_mode:3; 
-      GLuint userclip_enable_flags:8; 
-      GLuint userclip_must_clip:1; 
-      GLuint pad1:1;
-      GLuint guard_band_enable:1; 
-      GLuint viewport_z_clip_enable:1; 
-      GLuint viewport_xy_clip_enable:1; 
-      GLuint vertex_position_space:1; 
-      GLuint api_mode:1; 
-      GLuint pad2:1;
+      unsigned int pad0:13;
+      unsigned int clip_mode:3; 
+      unsigned int userclip_enable_flags:8; 
+      unsigned int userclip_must_clip:1; 
+      unsigned int pad1:1;
+      unsigned int guard_band_enable:1; 
+      unsigned int viewport_z_clip_enable:1; 
+      unsigned int viewport_xy_clip_enable:1; 
+      unsigned int vertex_position_space:1; 
+      unsigned int api_mode:1; 
+      unsigned int pad2:1;
    } clip5;
    
    struct
    {
-      GLuint pad0:5;
-      GLuint clipper_viewport_state_ptr:27; 
+      unsigned int pad0:5;
+      unsigned int clipper_viewport_state_ptr:27; 
    } clip6;
 
    
-   GLfloat viewport_xmin;  
-   GLfloat viewport_xmax;  
-   GLfloat viewport_ymin;  
-   GLfloat viewport_ymax;  
+   float viewport_xmin;  
+   float viewport_xmax;  
+   float viewport_ymin;  
+   float viewport_ymax;  
 };
 
 
@@ -567,90 +565,90 @@ struct brw_cc_unit_state
 {
    struct
    {
-      GLuint pad0:3;
-      GLuint bf_stencil_pass_depth_pass_op:3; 
-      GLuint bf_stencil_pass_depth_fail_op:3; 
-      GLuint bf_stencil_fail_op:3; 
-      GLuint bf_stencil_func:3; 
-      GLuint bf_stencil_enable:1; 
-      GLuint pad1:2;
-      GLuint stencil_write_enable:1; 
-      GLuint stencil_pass_depth_pass_op:3; 
-      GLuint stencil_pass_depth_fail_op:3; 
-      GLuint stencil_fail_op:3; 
-      GLuint stencil_func:3; 
-      GLuint stencil_enable:1; 
+      unsigned int pad0:3;
+      unsigned int bf_stencil_pass_depth_pass_op:3; 
+      unsigned int bf_stencil_pass_depth_fail_op:3; 
+      unsigned int bf_stencil_fail_op:3; 
+      unsigned int bf_stencil_func:3; 
+      unsigned int bf_stencil_enable:1; 
+      unsigned int pad1:2;
+      unsigned int stencil_write_enable:1; 
+      unsigned int stencil_pass_depth_pass_op:3; 
+      unsigned int stencil_pass_depth_fail_op:3; 
+      unsigned int stencil_fail_op:3; 
+      unsigned int stencil_func:3; 
+      unsigned int stencil_enable:1; 
    } cc0;
 
    
    struct
    {
-      GLuint bf_stencil_ref:8; 
-      GLuint stencil_write_mask:8; 
-      GLuint stencil_test_mask:8; 
-      GLuint stencil_ref:8; 
+      unsigned int bf_stencil_ref:8; 
+      unsigned int stencil_write_mask:8; 
+      unsigned int stencil_test_mask:8; 
+      unsigned int stencil_ref:8; 
    } cc1;
 
    
    struct
    {
-      GLuint logicop_enable:1; 
-      GLuint pad0:10;
-      GLuint depth_write_enable:1; 
-      GLuint depth_test_function:3; 
-      GLuint depth_test:1; 
-      GLuint bf_stencil_write_mask:8; 
-      GLuint bf_stencil_test_mask:8; 
+      unsigned int logicop_enable:1; 
+      unsigned int pad0:10;
+      unsigned int depth_write_enable:1; 
+      unsigned int depth_test_function:3; 
+      unsigned int depth_test:1; 
+      unsigned int bf_stencil_write_mask:8; 
+      unsigned int bf_stencil_test_mask:8; 
    } cc2;
 
    
    struct
    {
-      GLuint pad0:8;
-      GLuint alpha_test_func:3; 
-      GLuint alpha_test:1; 
-      GLuint blend_enable:1; 
-      GLuint ia_blend_enable:1; 
-      GLuint pad1:1;
-      GLuint alpha_test_format:1;
-      GLuint pad2:16;
+      unsigned int pad0:8;
+      unsigned int alpha_test_func:3; 
+      unsigned int alpha_test:1; 
+      unsigned int blend_enable:1; 
+      unsigned int ia_blend_enable:1; 
+      unsigned int pad1:1;
+      unsigned int alpha_test_format:1;
+      unsigned int pad2:16;
    } cc3;
    
    struct
    {
-      GLuint pad0:5; 
-      GLuint cc_viewport_state_offset:27; 
+      unsigned int pad0:5; 
+      unsigned int cc_viewport_state_offset:27; 
    } cc4;
    
    struct
    {
-      GLuint pad0:2;
-      GLuint ia_dest_blend_factor:5; 
-      GLuint ia_src_blend_factor:5; 
-      GLuint ia_blend_function:3; 
-      GLuint statistics_enable:1; 
-      GLuint logicop_func:4; 
-      GLuint pad1:11;
-      GLuint dither_enable:1; 
+      unsigned int pad0:2;
+      unsigned int ia_dest_blend_factor:5; 
+      unsigned int ia_src_blend_factor:5; 
+      unsigned int ia_blend_function:3; 
+      unsigned int statistics_enable:1; 
+      unsigned int logicop_func:4; 
+      unsigned int pad1:11;
+      unsigned int dither_enable:1; 
    } cc5;
 
    struct
    {
-      GLuint clamp_post_alpha_blend:1; 
-      GLuint clamp_pre_alpha_blend:1; 
-      GLuint clamp_range:2; 
-      GLuint pad0:11;
-      GLuint y_dither_offset:2; 
-      GLuint x_dither_offset:2; 
-      GLuint dest_blend_factor:5; 
-      GLuint src_blend_factor:5; 
-      GLuint blend_function:3; 
+      unsigned int clamp_post_alpha_blend:1; 
+      unsigned int clamp_pre_alpha_blend:1; 
+      unsigned int clamp_range:2; 
+      unsigned int pad0:11;
+      unsigned int y_dither_offset:2; 
+      unsigned int x_dither_offset:2; 
+      unsigned int dest_blend_factor:5; 
+      unsigned int src_blend_factor:5; 
+      unsigned int blend_function:3; 
    } cc6;
 
    struct {
       union {
-	 GLfloat f;  
-	 GLubyte ub[4];
+	 float f;  
+	 unsigned byte ub[4];
       } alpha_ref;
    } cc7;
 };
@@ -661,18 +659,18 @@ struct brw_sf_unit_state
 {
    struct thread0 thread0;
    struct {
-      GLuint pad0:7;
-      GLuint sw_exception_enable:1; 
-      GLuint pad1:3;
-      GLuint mask_stack_exception_enable:1; 
-      GLuint pad2:1;
-      GLuint illegal_op_exception_enable:1; 
-      GLuint pad3:2;
-      GLuint floating_point_mode:1; 
-      GLuint thread_priority:1; 
-      GLuint binding_table_entry_count:8; 
-      GLuint pad4:5;
-      GLuint single_program_flow:1; 
+      unsigned int pad0:7;
+      unsigned int sw_exception_enable:1; 
+      unsigned int pad1:3;
+      unsigned int mask_stack_exception_enable:1; 
+      unsigned int pad2:1;
+      unsigned int illegal_op_exception_enable:1; 
+      unsigned int pad3:2;
+      unsigned int floating_point_mode:1; 
+      unsigned int thread_priority:1; 
+      unsigned int binding_table_entry_count:8; 
+      unsigned int pad4:5;
+      unsigned int single_program_flow:1; 
    } sf1;
    
    struct thread2 thread2;
@@ -680,51 +678,51 @@ struct brw_sf_unit_state
 
    struct
    {
-      GLuint pad0:10;
-      GLuint stats_enable:1; 
-      GLuint nr_urb_entries:7; 
-      GLuint pad1:1;
-      GLuint urb_entry_allocation_size:5; 
-      GLuint pad2:1;
-      GLuint max_threads:6; 
-      GLuint pad3:1;
+      unsigned int pad0:10;
+      unsigned int stats_enable:1; 
+      unsigned int nr_urb_entries:7; 
+      unsigned int pad1:1;
+      unsigned int urb_entry_allocation_size:5; 
+      unsigned int pad2:1;
+      unsigned int max_threads:6; 
+      unsigned int pad3:1;
    } thread4;   
 
    struct
    {
-      GLuint front_winding:1; 
-      GLuint viewport_transform:1; 
-      GLuint pad0:3;
-      GLuint sf_viewport_state_offset:27; 
+      unsigned int front_winding:1; 
+      unsigned int viewport_transform:1; 
+      unsigned int pad0:3;
+      unsigned int sf_viewport_state_offset:27; 
    } sf5;
    
    struct
    {
-      GLuint pad0:9;
-      GLuint dest_org_vbias:4; 
-      GLuint dest_org_hbias:4; 
-      GLuint scissor:1; 
-      GLuint disable_2x2_trifilter:1; 
-      GLuint disable_zero_pix_trifilter:1; 
-      GLuint point_rast_rule:2; 
-      GLuint line_endcap_aa_region_width:2; 
-      GLuint line_width:4; 
-      GLuint fast_scissor_disable:1; 
-      GLuint cull_mode:2; 
-      GLuint aa_enable:1; 
+      unsigned int pad0:9;
+      unsigned int dest_org_vbias:4; 
+      unsigned int dest_org_hbias:4; 
+      unsigned int scissor:1; 
+      unsigned int disable_2x2_trifilter:1; 
+      unsigned int disable_zero_pix_trifilter:1; 
+      unsigned int point_rast_rule:2; 
+      unsigned int line_endcap_aa_region_width:2; 
+      unsigned int line_width:4; 
+      unsigned int fast_scissor_disable:1; 
+      unsigned int cull_mode:2; 
+      unsigned int aa_enable:1; 
    } sf6;
 
    struct
    {
-      GLuint point_size:11; 
-      GLuint use_point_size_state:1; 
-      GLuint subpixel_precision:1; 
-      GLuint sprite_point:1; 
-      GLuint pad0:11;
-      GLuint trifan_pv:2; 
-      GLuint linestrip_pv:2; 
-      GLuint tristrip_pv:2; 
-      GLuint line_last_pixel_enable:1; 
+      unsigned int point_size:11; 
+      unsigned int use_point_size_state:1; 
+      unsigned int subpixel_precision:1; 
+      unsigned int sprite_point:1; 
+      unsigned int pad0:11;
+      unsigned int trifan_pv:2; 
+      unsigned int linestrip_pv:2; 
+      unsigned int tristrip_pv:2; 
+      unsigned int line_last_pixel_enable:1; 
    } sf7;
 
 };
@@ -739,30 +737,30 @@ struct brw_gs_unit_state
 
    struct
    {
-      GLuint pad0:10;
-      GLuint stats_enable:1; 
-      GLuint nr_urb_entries:7; 
-      GLuint pad1:1;
-      GLuint urb_entry_allocation_size:5; 
-      GLuint pad2:1;
-      GLuint max_threads:1; 
-      GLuint pad3:6;
+      unsigned int pad0:10;
+      unsigned int stats_enable:1; 
+      unsigned int nr_urb_entries:7; 
+      unsigned int pad1:1;
+      unsigned int urb_entry_allocation_size:5; 
+      unsigned int pad2:1;
+      unsigned int max_threads:1; 
+      unsigned int pad3:6;
    } thread4;   
       
    struct
    {
-      GLuint sampler_count:3; 
-      GLuint pad0:2;
-      GLuint sampler_state_pointer:27; 
+      unsigned int sampler_count:3; 
+      unsigned int pad0:2;
+      unsigned int sampler_state_pointer:27; 
    } gs5;
 
    
    struct
    {
-      GLuint max_vp_index:4; 
-      GLuint pad0:26;
-      GLuint reorder_enable:1; 
-      GLuint pad1:1;
+      unsigned int max_vp_index:4; 
+      unsigned int pad0:26;
+      unsigned int reorder_enable:1; 
+      unsigned int pad1:1;
    } gs6;
 };
 
@@ -776,28 +774,28 @@ struct brw_vs_unit_state
    
    struct
    {
-      GLuint pad0:10;
-      GLuint stats_enable:1; 
-      GLuint nr_urb_entries:7; 
-      GLuint pad1:1;
-      GLuint urb_entry_allocation_size:5; 
-      GLuint pad2:1;
-      GLuint max_threads:4; 
-      GLuint pad3:3;
+      unsigned int pad0:10;
+      unsigned int stats_enable:1; 
+      unsigned int nr_urb_entries:7; 
+      unsigned int pad1:1;
+      unsigned int urb_entry_allocation_size:5; 
+      unsigned int pad2:1;
+      unsigned int max_threads:4; 
+      unsigned int pad3:3;
    } thread4;   
 
    struct
    {
-      GLuint sampler_count:3; 
-      GLuint pad0:2;
-      GLuint sampler_state_pointer:27; 
+      unsigned int sampler_count:3; 
+      unsigned int pad0:2;
+      unsigned int sampler_state_pointer:27; 
    } vs5;
 
    struct
    {
-      GLuint vs_enable:1; 
-      GLuint vert_cache_disable:1; 
-      GLuint pad0:30;
+      unsigned int vs_enable:1; 
+      unsigned int vert_cache_disable:1; 
+      unsigned int pad0:30;
    } vs6;
 };
 
@@ -810,41 +808,41 @@ struct brw_wm_unit_state
    struct thread3 thread3;
    
    struct {
-      GLuint stats_enable:1; 
-      GLuint pad0:1;
-      GLuint sampler_count:3; 
-      GLuint sampler_state_pointer:27; 
+      unsigned int stats_enable:1; 
+      unsigned int pad0:1;
+      unsigned int sampler_count:3; 
+      unsigned int sampler_state_pointer:27; 
    } wm4;
    
    struct
    {
-      GLuint enable_8_pix:1; 
-      GLuint enable_16_pix:1; 
-      GLuint enable_32_pix:1; 
-      GLuint pad0:7;
-      GLuint legacy_global_depth_bias:1; 
-      GLuint line_stipple:1; 
-      GLuint depth_offset:1; 
-      GLuint polygon_stipple:1; 
-      GLuint line_aa_region_width:2; 
-      GLuint line_endcap_aa_region_width:2; 
-      GLuint early_depth_test:1; 
-      GLuint thread_dispatch_enable:1; 
-      GLuint program_uses_depth:1; 
-      GLuint program_computes_depth:1; 
-      GLuint program_uses_killpixel:1; 
-      GLuint legacy_line_rast: 1; 
-      GLuint pad1:1; 
-      GLuint max_threads:6; 
-      GLuint pad2:1;
+      unsigned int enable_8_pix:1; 
+      unsigned int enable_16_pix:1; 
+      unsigned int enable_32_pix:1; 
+      unsigned int pad0:7;
+      unsigned int legacy_global_depth_bias:1; 
+      unsigned int line_stipple:1; 
+      unsigned int depth_offset:1; 
+      unsigned int polygon_stipple:1; 
+      unsigned int line_aa_region_width:2; 
+      unsigned int line_endcap_aa_region_width:2; 
+      unsigned int early_depth_test:1; 
+      unsigned int thread_dispatch_enable:1; 
+      unsigned int program_uses_depth:1; 
+      unsigned int program_computes_depth:1; 
+      unsigned int program_uses_killpixel:1; 
+      unsigned int legacy_line_rast: 1; 
+      unsigned int pad1:1; 
+      unsigned int max_threads:6; 
+      unsigned int pad2:1;
    } wm5;
    
-   GLfloat global_depth_offset_constant;  
-   GLfloat global_depth_offset_scale;   
+   float global_depth_offset_constant;  
+   float global_depth_offset_scale;   
 };
 
 struct brw_sampler_default_color {
-   GLfloat color[4];
+   float color[4];
 };
 
 struct brw_sampler_state
@@ -852,79 +850,79 @@ struct brw_sampler_state
    
    struct
    {
-      GLuint shadow_function:3; 
-      GLuint lod_bias:11; 
-      GLuint min_filter:3; 
-      GLuint mag_filter:3; 
-      GLuint mip_filter:2; 
-      GLuint base_level:5; 
-      GLuint pad:1;
-      GLuint lod_preclamp:1; 
-      GLuint default_color_mode:1; 
-      GLuint pad0:1;
-      GLuint disable:1; 
+      unsigned int shadow_function:3; 
+      unsigned int lod_bias:11; 
+      unsigned int min_filter:3; 
+      unsigned int mag_filter:3; 
+      unsigned int mip_filter:2; 
+      unsigned int base_level:5; 
+      unsigned int pad:1;
+      unsigned int lod_preclamp:1; 
+      unsigned int default_color_mode:1; 
+      unsigned int pad0:1;
+      unsigned int disable:1; 
    } ss0;
 
    struct
    {
-      GLuint r_wrap_mode:3; 
-      GLuint t_wrap_mode:3; 
-      GLuint s_wrap_mode:3; 
-      GLuint pad:3;
-      GLuint max_lod:10; 
-      GLuint min_lod:10; 
+      unsigned int r_wrap_mode:3; 
+      unsigned int t_wrap_mode:3; 
+      unsigned int s_wrap_mode:3; 
+      unsigned int pad:3;
+      unsigned int max_lod:10; 
+      unsigned int min_lod:10; 
    } ss1;
 
    
    struct
    {
-      GLuint pad:5;
-      GLuint default_color_pointer:27; 
+      unsigned int pad:5;
+      unsigned int default_color_pointer:27; 
    } ss2;
    
    struct
    {
-      GLuint pad:19;
-      GLuint max_aniso:3; 
-      GLuint chroma_key_mode:1; 
-      GLuint chroma_key_index:2; 
-      GLuint chroma_key_enable:1; 
-      GLuint monochrome_filter_width:3; 
-      GLuint monochrome_filter_height:3; 
+      unsigned int pad:19;
+      unsigned int max_aniso:3; 
+      unsigned int chroma_key_mode:1; 
+      unsigned int chroma_key_index:2; 
+      unsigned int chroma_key_enable:1; 
+      unsigned int monochrome_filter_width:3; 
+      unsigned int monochrome_filter_height:3; 
    } ss3;
 };
 
 
 struct brw_clipper_viewport
 {
-   GLfloat xmin;  
-   GLfloat xmax;  
-   GLfloat ymin;  
-   GLfloat ymax;  
+   float xmin;  
+   float xmax;  
+   float ymin;  
+   float ymax;  
 };
 
 struct brw_cc_viewport
 {
-   GLfloat min_depth;  
-   GLfloat max_depth;  
+   float min_depth;  
+   float max_depth;  
 };
 
 struct brw_sf_viewport
 {
    struct {
-      GLfloat m00;  
-      GLfloat m11;  
-      GLfloat m22;  
-      GLfloat m30;  
-      GLfloat m31;  
-      GLfloat m32;  
+      float m00;  
+      float m11;  
+      float m22;  
+      float m30;  
+      float m31;  
+      float m32;  
    } viewport;
 
    struct {
-      GLshort xmin;
-      GLshort ymin;
-      GLshort xmax;
-      GLshort ymax;
+      short xmin;
+      short ymin;
+      short xmax;
+      short ymax;
    } scissor;
 };
 
@@ -933,51 +931,51 @@ struct brw_sf_viewport
 struct brw_surface_state
 {
    struct {
-      GLuint cube_pos_z:1; 
-      GLuint cube_neg_z:1; 
-      GLuint cube_pos_y:1; 
-      GLuint cube_neg_y:1; 
-      GLuint cube_pos_x:1; 
-      GLuint cube_neg_x:1; 
-      GLuint pad:3;
-      GLuint render_cache_read_mode:1;
-      GLuint mipmap_layout_mode:1; 
-      GLuint vert_line_stride_ofs:1; 
-      GLuint vert_line_stride:1; 
-      GLuint color_blend:1; 
-      GLuint writedisable_blue:1; 
-      GLuint writedisable_green:1; 
-      GLuint writedisable_red:1; 
-      GLuint writedisable_alpha:1; 
-      GLuint surface_format:9; 
-      GLuint data_return_format:1; 
-      GLuint pad0:1;
-      GLuint surface_type:3; 
+      unsigned int cube_pos_z:1; 
+      unsigned int cube_neg_z:1; 
+      unsigned int cube_pos_y:1; 
+      unsigned int cube_neg_y:1; 
+      unsigned int cube_pos_x:1; 
+      unsigned int cube_neg_x:1; 
+      unsigned int pad:3;
+      unsigned int render_cache_read_mode:1;
+      unsigned int mipmap_layout_mode:1; 
+      unsigned int vert_line_stride_ofs:1; 
+      unsigned int vert_line_stride:1; 
+      unsigned int color_blend:1; 
+      unsigned int writedisable_blue:1; 
+      unsigned int writedisable_green:1; 
+      unsigned int writedisable_red:1; 
+      unsigned int writedisable_alpha:1; 
+      unsigned int surface_format:9; 
+      unsigned int data_return_format:1; 
+      unsigned int pad0:1;
+      unsigned int surface_type:3; 
    } ss0;
    
    struct {
-      GLuint base_addr;  
+      unsigned int base_addr;  
    } ss1;
    
    struct {
-      GLuint render_target_rotation:2;
-      GLuint mip_count:4; 
-      GLuint width:13; 
-      GLuint height:13; 
+      unsigned int render_target_rotation:2;
+      unsigned int mip_count:4; 
+      unsigned int width:13; 
+      unsigned int height:13; 
    } ss2;
 
    struct {
-      GLuint tile_walk:1; 
-      GLuint tiled_surface:1; 
-      GLuint pad:1; 
-      GLuint pitch:18; 
-      GLuint depth:11; 
+      unsigned int tile_walk:1; 
+      unsigned int tiled_surface:1; 
+      unsigned int pad:1; 
+      unsigned int pitch:18; 
+      unsigned int depth:11; 
    } ss3;
    
    struct {
-      GLuint pad:19;
-      GLuint min_array_elt:9; 
-      GLuint min_lod:4; 
+      unsigned int pad:19;
+      unsigned int min_array_elt:9; 
+      unsigned int min_lod:4; 
    } ss4;
 };
 
@@ -986,16 +984,16 @@ struct brw_surface_state
 struct brw_vertex_buffer_state
 {
    struct {
-      GLuint pitch:11; 
-      GLuint pad:15;
-      GLuint access_type:1; 
-      GLuint vb_index:5; 
+      unsigned int pitch:11; 
+      unsigned int pad:15;
+      unsigned int access_type:1; 
+      unsigned int vb_index:5; 
    } vb0;
    
-   GLuint start_addr; 
-   GLuint max_index;   
+   unsigned int start_addr; 
+   unsigned int max_index;   
 #if 1
-   GLuint instance_data_step_rate; /* not included for sequential/random vertices? */
+   unsigned int instance_data_step_rate; /* not included for sequential/random vertices? */
 #endif
 };
 
@@ -1011,22 +1009,22 @@ struct brw_vertex_element_state
 {
    struct
    {
-      GLuint src_offset:11; 
-      GLuint pad:5;
-      GLuint src_format:9; 
-      GLuint pad0:1;
-      GLuint valid:1; 
-      GLuint vertex_buffer_index:5; 
+      unsigned int src_offset:11; 
+      unsigned int pad:5;
+      unsigned int src_format:9; 
+      unsigned int pad0:1;
+      unsigned int valid:1; 
+      unsigned int vertex_buffer_index:5; 
    } ve0;
    
    struct
    {
-      GLuint dst_offset:8; 
-      GLuint pad:8;
-      GLuint vfcomponent3:4; 
-      GLuint vfcomponent2:4; 
-      GLuint vfcomponent1:4; 
-      GLuint vfcomponent0:4; 
+      unsigned int dst_offset:8; 
+      unsigned int pad:8;
+      unsigned int vfcomponent3:4; 
+      unsigned int vfcomponent2:4; 
+      unsigned int vfcomponent1:4; 
+      unsigned int vfcomponent0:4; 
    } ve1;
 };
 
@@ -1039,18 +1037,18 @@ struct brw_vertex_element_packet {
 
 
 struct brw_urb_immediate {
-   GLuint opcode:4;
-   GLuint offset:6;
-   GLuint swizzle_control:2; 
-   GLuint pad:1;
-   GLuint allocate:1;
-   GLuint used:1;
-   GLuint complete:1;
-   GLuint response_length:4;
-   GLuint msg_length:4;
-   GLuint msg_target:4;
-   GLuint pad1:3;
-   GLuint end_of_thread:1;
+   unsigned int opcode:4;
+   unsigned int offset:6;
+   unsigned int swizzle_control:2; 
+   unsigned int pad:1;
+   unsigned int allocate:1;
+   unsigned int used:1;
+   unsigned int complete:1;
+   unsigned int response_length:4;
+   unsigned int msg_length:4;
+   unsigned int msg_target:4;
+   unsigned int pad1:3;
+   unsigned int end_of_thread:1;
 };
 
 /* Instruction format for the execution units:
@@ -1060,79 +1058,79 @@ struct brw_instruction
 {
    struct 
    {
-      GLuint opcode:7;
-      GLuint pad:1;
-      GLuint access_mode:1;
-      GLuint mask_control:1;
-      GLuint dependency_control:2;
-      GLuint compression_control:2;
-      GLuint thread_control:2;
-      GLuint predicate_control:4;
-      GLuint predicate_inverse:1;
-      GLuint execution_size:3;
-      GLuint destreg__conditonalmod:4; /* destreg - send, conditionalmod - others */
-      GLuint pad0:2;
-      GLuint debug_control:1;
-      GLuint saturate:1;
+      unsigned int opcode:7;
+      unsigned int pad:1;
+      unsigned int access_mode:1;
+      unsigned int mask_control:1;
+      unsigned int dependency_control:2;
+      unsigned int compression_control:2;
+      unsigned int thread_control:2;
+      unsigned int predicate_control:4;
+      unsigned int predicate_inverse:1;
+      unsigned int execution_size:3;
+      unsigned int destreg__conditonalmod:4; /* destreg - send, conditionalmod - others */
+      unsigned int pad0:2;
+      unsigned int debug_control:1;
+      unsigned int saturate:1;
    } header;
 
    union {
       struct
       {
-	 GLuint dest_reg_file:2;
-	 GLuint dest_reg_type:3;
-	 GLuint src0_reg_file:2;
-	 GLuint src0_reg_type:3;
-	 GLuint src1_reg_file:2;
-	 GLuint src1_reg_type:3;
-	 GLuint pad:1;
-	 GLuint dest_subreg_nr:5;
-	 GLuint dest_reg_nr:8;
-	 GLuint dest_horiz_stride:2;
-	 GLuint dest_address_mode:1;
+	 unsigned int dest_reg_file:2;
+	 unsigned int dest_reg_type:3;
+	 unsigned int src0_reg_file:2;
+	 unsigned int src0_reg_type:3;
+	 unsigned int src1_reg_file:2;
+	 unsigned int src1_reg_type:3;
+	 unsigned int pad:1;
+	 unsigned int dest_subreg_nr:5;
+	 unsigned int dest_reg_nr:8;
+	 unsigned int dest_horiz_stride:2;
+	 unsigned int dest_address_mode:1;
       } da1;
 
       struct
       {
-	 GLuint dest_reg_file:2;
-	 GLuint dest_reg_type:3;
-	 GLuint src0_reg_file:2;
-	 GLuint src0_reg_type:3;
-	 GLuint pad:6;
-	 GLint dest_indirect_offset:10;	/* offset against the deref'd address reg */
-	 GLuint dest_subreg_nr:3; /* subnr for the address reg a0.x */
-	 GLuint dest_horiz_stride:2;
-	 GLuint dest_address_mode:1;
+	 unsigned int dest_reg_file:2;
+	 unsigned int dest_reg_type:3;
+	 unsigned int src0_reg_file:2;
+	 unsigned int src0_reg_type:3;
+	 unsigned int pad:6;
+	 int dest_indirect_offset:10;	/* offset against the deref'd address reg */
+	 unsigned int dest_subreg_nr:3; /* subnr for the address reg a0.x */
+	 unsigned int dest_horiz_stride:2;
+	 unsigned int dest_address_mode:1;
       } ia1;
 
       struct
       {
-	 GLuint dest_reg_file:2;
-	 GLuint dest_reg_type:3;
-	 GLuint src0_reg_file:2;
-	 GLuint src0_reg_type:3;
-	 GLuint src1_reg_file:2;
-	 GLuint src1_reg_type:3;
-	 GLuint pad0:1;
-	 GLuint dest_writemask:4;
-	 GLuint dest_subreg_nr:1;
-	 GLuint dest_reg_nr:8;
-	 GLuint pad1:2;
-	 GLuint dest_address_mode:1;
+	 unsigned int dest_reg_file:2;
+	 unsigned int dest_reg_type:3;
+	 unsigned int src0_reg_file:2;
+	 unsigned int src0_reg_type:3;
+	 unsigned int src1_reg_file:2;
+	 unsigned int src1_reg_type:3;
+	 unsigned int pad0:1;
+	 unsigned int dest_writemask:4;
+	 unsigned int dest_subreg_nr:1;
+	 unsigned int dest_reg_nr:8;
+	 unsigned int pad1:2;
+	 unsigned int dest_address_mode:1;
       } da16;
 
       struct
       {
-	 GLuint dest_reg_file:2;
-	 GLuint dest_reg_type:3;
-	 GLuint src0_reg_file:2;
-	 GLuint src0_reg_type:3;
-	 GLuint pad0:6;
-	 GLuint dest_writemask:4;
-	 GLint dest_indirect_offset:6;
-	 GLuint dest_subreg_nr:3;
-	 GLuint pad1:2;
-	 GLuint dest_address_mode:1;
+	 unsigned int dest_reg_file:2;
+	 unsigned int dest_reg_type:3;
+	 unsigned int src0_reg_file:2;
+	 unsigned int src0_reg_type:3;
+	 unsigned int pad0:6;
+	 unsigned int dest_writemask:4;
+	 int dest_indirect_offset:6;
+	 unsigned int dest_subreg_nr:3;
+	 unsigned int pad1:2;
+	 unsigned int dest_address_mode:1;
       } ia16;
    } bits1;
 
@@ -1140,64 +1138,64 @@ struct brw_instruction
    union {
       struct
       {
-	 GLuint src0_subreg_nr:5;
-	 GLuint src0_reg_nr:8;
-	 GLuint src0_abs:1;
-	 GLuint src0_negate:1;
-	 GLuint src0_address_mode:1;
-	 GLuint src0_horiz_stride:2;
-	 GLuint src0_width:3;
-	 GLuint src0_vert_stride:4;
-	 GLuint flag_reg_nr:1;
-	 GLuint pad:6;
+	 unsigned int src0_subreg_nr:5;
+	 unsigned int src0_reg_nr:8;
+	 unsigned int src0_abs:1;
+	 unsigned int src0_negate:1;
+	 unsigned int src0_address_mode:1;
+	 unsigned int src0_horiz_stride:2;
+	 unsigned int src0_width:3;
+	 unsigned int src0_vert_stride:4;
+	 unsigned int flag_reg_nr:1;
+	 unsigned int pad:6;
       } da1;
 
       struct
       {
-	 GLint src0_indirect_offset:10;
-	 GLuint src0_subreg_nr:3;
-	 GLuint src0_abs:1;
-	 GLuint src0_negate:1;
-	 GLuint src0_address_mode:1;
-	 GLuint src0_horiz_stride:2;
-	 GLuint src0_width:3;
-	 GLuint src0_vert_stride:4;
-	 GLuint flag_reg_nr:1;
-	 GLuint pad:6;	
+	 int src0_indirect_offset:10;
+	 unsigned int src0_subreg_nr:3;
+	 unsigned int src0_abs:1;
+	 unsigned int src0_negate:1;
+	 unsigned int src0_address_mode:1;
+	 unsigned int src0_horiz_stride:2;
+	 unsigned int src0_width:3;
+	 unsigned int src0_vert_stride:4;
+	 unsigned int flag_reg_nr:1;
+	 unsigned int pad:6;	
       } ia1;
 
       struct
       {
-	 GLuint src0_swz_x:2;
-	 GLuint src0_swz_y:2;
-	 GLuint src0_subreg_nr:1;
-	 GLuint src0_reg_nr:8;
-	 GLuint src0_abs:1;
-	 GLuint src0_negate:1;
-	 GLuint src0_address_mode:1;
-	 GLuint src0_swz_z:2;
-	 GLuint src0_swz_w:2;
-	 GLuint pad0:1;
-	 GLuint src0_vert_stride:4;
-	 GLuint flag_reg_nr:1;
-	 GLuint pad1:6;
+	 unsigned int src0_swz_x:2;
+	 unsigned int src0_swz_y:2;
+	 unsigned int src0_subreg_nr:1;
+	 unsigned int src0_reg_nr:8;
+	 unsigned int src0_abs:1;
+	 unsigned int src0_negate:1;
+	 unsigned int src0_address_mode:1;
+	 unsigned int src0_swz_z:2;
+	 unsigned int src0_swz_w:2;
+	 unsigned int pad0:1;
+	 unsigned int src0_vert_stride:4;
+	 unsigned int flag_reg_nr:1;
+	 unsigned int pad1:6;
       } da16;
 
       struct
       {
-	 GLuint src0_swz_x:2;
-	 GLuint src0_swz_y:2;
-	 GLint src0_indirect_offset:6;
-	 GLuint src0_subreg_nr:3;
-	 GLuint src0_abs:1;
-	 GLuint src0_negate:1;
-	 GLuint src0_address_mode:1;
-	 GLuint src0_swz_z:2;
-	 GLuint src0_swz_w:2;
-	 GLuint pad0:1;
-	 GLuint src0_vert_stride:4;
-	 GLuint flag_reg_nr:1;
-	 GLuint pad1:6;
+	 unsigned int src0_swz_x:2;
+	 unsigned int src0_swz_y:2;
+	 int src0_indirect_offset:6;
+	 unsigned int src0_subreg_nr:3;
+	 unsigned int src0_abs:1;
+	 unsigned int src0_negate:1;
+	 unsigned int src0_address_mode:1;
+	 unsigned int src0_swz_z:2;
+	 unsigned int src0_swz_w:2;
+	 unsigned int pad0:1;
+	 unsigned int src0_vert_stride:4;
+	 unsigned int flag_reg_nr:1;
+	 unsigned int pad1:6;
       } ia16;
 
    } bits2;
@@ -1206,135 +1204,135 @@ struct brw_instruction
    {
       struct
       {
-	 GLuint src1_subreg_nr:5;
-	 GLuint src1_reg_nr:8;
-	 GLuint src1_abs:1;
-	 GLuint src1_negate:1;
-	 GLuint pad:1;
-	 GLuint src1_horiz_stride:2;
-	 GLuint src1_width:3;
-	 GLuint src1_vert_stride:4;
-	 GLuint pad0:7;
+	 unsigned int src1_subreg_nr:5;
+	 unsigned int src1_reg_nr:8;
+	 unsigned int src1_abs:1;
+	 unsigned int src1_negate:1;
+	 unsigned int pad:1;
+	 unsigned int src1_horiz_stride:2;
+	 unsigned int src1_width:3;
+	 unsigned int src1_vert_stride:4;
+	 unsigned int pad0:7;
       } da1;
 
       struct
       {
-	 GLuint src1_swz_x:2;
-	 GLuint src1_swz_y:2;
-	 GLuint src1_subreg_nr:1;
-	 GLuint src1_reg_nr:8;
-	 GLuint src1_abs:1;
-	 GLuint src1_negate:1;
-	 GLuint pad0:1;
-	 GLuint src1_swz_z:2;
-	 GLuint src1_swz_w:2;
-	 GLuint pad1:1;
-	 GLuint src1_vert_stride:4;
-	 GLuint pad2:7;
+	 unsigned int src1_swz_x:2;
+	 unsigned int src1_swz_y:2;
+	 unsigned int src1_subreg_nr:1;
+	 unsigned int src1_reg_nr:8;
+	 unsigned int src1_abs:1;
+	 unsigned int src1_negate:1;
+	 unsigned int pad0:1;
+	 unsigned int src1_swz_z:2;
+	 unsigned int src1_swz_w:2;
+	 unsigned int pad1:1;
+	 unsigned int src1_vert_stride:4;
+	 unsigned int pad2:7;
       } da16;
 
       struct
       {
-	 GLint  src1_indirect_offset:10;
-	 GLuint src1_subreg_nr:3;
-	 GLuint src1_abs:1;
-	 GLuint src1_negate:1;
-	 GLuint pad0:1;
-	 GLuint src1_horiz_stride:2;
-	 GLuint src1_width:3;
-	 GLuint src1_vert_stride:4;
-	 GLuint flag_reg_nr:1;
-	 GLuint pad1:6;	
+	 int  src1_indirect_offset:10;
+	 unsigned int src1_subreg_nr:3;
+	 unsigned int src1_abs:1;
+	 unsigned int src1_negate:1;
+	 unsigned int pad0:1;
+	 unsigned int src1_horiz_stride:2;
+	 unsigned int src1_width:3;
+	 unsigned int src1_vert_stride:4;
+	 unsigned int flag_reg_nr:1;
+	 unsigned int pad1:6;	
       } ia1;
 
       struct
       {
-	 GLuint src1_swz_x:2;
-	 GLuint src1_swz_y:2;
-	 GLint  src1_indirect_offset:6;
-	 GLuint src1_subreg_nr:3;
-	 GLuint src1_abs:1;
-	 GLuint src1_negate:1;
-	 GLuint pad0:1;
-	 GLuint src1_swz_z:2;
-	 GLuint src1_swz_w:2;
-	 GLuint pad1:1;
-	 GLuint src1_vert_stride:4;
-	 GLuint flag_reg_nr:1;
-	 GLuint pad2:6;
+	 unsigned int src1_swz_x:2;
+	 unsigned int src1_swz_y:2;
+	 int  src1_indirect_offset:6;
+	 unsigned int src1_subreg_nr:3;
+	 unsigned int src1_abs:1;
+	 unsigned int src1_negate:1;
+	 unsigned int pad0:1;
+	 unsigned int src1_swz_z:2;
+	 unsigned int src1_swz_w:2;
+	 unsigned int pad1:1;
+	 unsigned int src1_vert_stride:4;
+	 unsigned int flag_reg_nr:1;
+	 unsigned int pad2:6;
       } ia16;
 
 
       struct
       {
-	 GLint  jump_count:16;	/* note: signed */
-	 GLuint  pop_count:4;
-	 GLuint  pad0:12;
+	 int  jump_count:16;	/* note: signed */
+	 unsigned int  pop_count:4;
+	 unsigned int  pad0:12;
       } if_else;
 
       struct {
-	 GLuint function:4;
-	 GLuint int_type:1;
-	 GLuint precision:1;
-	 GLuint saturate:1;
-	 GLuint data_type:1;
-	 GLuint pad0:8;
-	 GLuint response_length:4;
-	 GLuint msg_length:4;
-	 GLuint msg_target:4;
-	 GLuint pad1:3;
-	 GLuint end_of_thread:1;
+	 unsigned int function:4;
+	 unsigned int int_type:1;
+	 unsigned int precision:1;
+	 unsigned int saturate:1;
+	 unsigned int data_type:1;
+	 unsigned int pad0:8;
+	 unsigned int response_length:4;
+	 unsigned int msg_length:4;
+	 unsigned int msg_target:4;
+	 unsigned int pad1:3;
+	 unsigned int end_of_thread:1;
       } math;
 
       struct {
-	 GLuint binding_table_index:8;
-	 GLuint sampler:4;
-	 GLuint return_format:2; 
-	 GLuint msg_type:2;   
-	 GLuint response_length:4;
-	 GLuint msg_length:4;
-	 GLuint msg_target:4;
-	 GLuint pad1:3;
-	 GLuint end_of_thread:1;
+	 unsigned int binding_table_index:8;
+	 unsigned int sampler:4;
+	 unsigned int return_format:2; 
+	 unsigned int msg_type:2;   
+	 unsigned int response_length:4;
+	 unsigned int msg_length:4;
+	 unsigned int msg_target:4;
+	 unsigned int pad1:3;
+	 unsigned int end_of_thread:1;
       } sampler;
 
       struct brw_urb_immediate urb;
 
       struct {
-	 GLuint binding_table_index:8;
-	 GLuint msg_control:4;  
-	 GLuint msg_type:2;  
-	 GLuint target_cache:2;    
-	 GLuint response_length:4;
-	 GLuint msg_length:4;
-	 GLuint msg_target:4;
-	 GLuint pad1:3;
-	 GLuint end_of_thread:1;
+	 unsigned int binding_table_index:8;
+	 unsigned int msg_control:4;  
+	 unsigned int msg_type:2;  
+	 unsigned int target_cache:2;    
+	 unsigned int response_length:4;
+	 unsigned int msg_length:4;
+	 unsigned int msg_target:4;
+	 unsigned int pad1:3;
+	 unsigned int end_of_thread:1;
       } dp_read;
 
       struct {
-	 GLuint binding_table_index:8;
-	 GLuint msg_control:3;
-	 GLuint pixel_scoreboard_clear:1;
-	 GLuint msg_type:3;    
-	 GLuint send_commit_msg:1;
-	 GLuint response_length:4;
-	 GLuint msg_length:4;
-	 GLuint msg_target:4;
-	 GLuint pad1:3;
-	 GLuint end_of_thread:1;
+	 unsigned int binding_table_index:8;
+	 unsigned int msg_control:3;
+	 unsigned int pixel_scoreboard_clear:1;
+	 unsigned int msg_type:3;    
+	 unsigned int send_commit_msg:1;
+	 unsigned int response_length:4;
+	 unsigned int msg_length:4;
+	 unsigned int msg_target:4;
+	 unsigned int pad1:3;
+	 unsigned int end_of_thread:1;
       } dp_write;
 
       struct {
-	 GLuint pad:16;
-	 GLuint response_length:4;
-	 GLuint msg_length:4;
-	 GLuint msg_target:4;
-	 GLuint pad1:3;
-	 GLuint end_of_thread:1;
+	 unsigned int pad:16;
+	 unsigned int response_length:4;
+	 unsigned int msg_length:4;
+	 unsigned int msg_target:4;
+	 unsigned int pad1:3;
+	 unsigned int end_of_thread:1;
       } generic;
 
-      GLuint ud;
+      unsigned int ud;
    } bits3;
 };
 
diff-tree dad0e7fc09fa7794f20278d9d99abd96a21b691e (from parents)
Merge: 361c49ad3cfe58b9ab98dfb6e95de505c0d63730 43daaec63929c1f0e54a5125375d8147629da4b9
Author: Alan Hourihane <alanh at fairlite.demon.co.uk>
Date:   Mon Aug 21 12:08:01 2006 +0100

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

diff-tree 361c49ad3cfe58b9ab98dfb6e95de505c0d63730 (from cdcc6f23e8cad797e6cfd57e2ff454ec8509b5ba)
Author: Alan Hourihane <alanh at fairlite.demon.co.uk>
Date:   Mon Aug 21 12:07:29 2006 +0100

    Fix bug #7930, i810 doesn't compile without DRI
    (Samuel Thibault)

diff --git a/src/brw_structs.h b/src/brw_structs.h
index c9c0751..50b5fda 100644
--- a/src/brw_structs.h
+++ b/src/brw_structs.h
@@ -28,6 +28,8 @@
 #ifndef BRW_STRUCTS_H
 #define BRW_STRUCTS_H
 
+#include <GL/gl.h>
+
 /* Command packets:
  */
 struct header 
diff --git a/src/i810_driver.c b/src/i810_driver.c
index 3481d0b..22635c8 100644
--- a/src/i810_driver.c
+++ b/src/i810_driver.c
@@ -333,6 +333,8 @@ const char *I810driSymbols[] = {
    NULL
 };
 
+#endif /* I830_ONLY */
+
 const char *I810shadowSymbols[] = {
     "shadowInit",
     "shadowSetup",
@@ -340,8 +342,6 @@ const char *I810shadowSymbols[] = {
     NULL
 };
 
-#endif /* I830_ONLY */
-
 #ifndef I810_DEBUG
 int I810_DEBUG = (0
 /*     		  | DEBUG_ALWAYS_SYNC  */
@@ -408,9 +408,9 @@ i810Setup(pointer module, pointer opts, 
 #ifdef XF86DRI
 			I810drmSymbols,
 			I810driSymbols,
+#endif
 			I810shadowSymbols,
 			I810shadowFBSymbols,
-#endif
 			I810vbeSymbols, vbeOptionalSymbols,
 			I810ddcSymbols, I810int10Symbols, NULL);
 
diff --git a/src/i830_accel.c b/src/i830_accel.c
index aa43cbe..b029968 100644
--- a/src/i830_accel.c
+++ b/src/i830_accel.c
@@ -395,6 +395,7 @@ I830AccelInit(ScreenPtr pScreen)
    return XAAInit(pScreen, infoPtr);
 }
 
+#ifdef XF86DRI
 static unsigned int
 CheckTiling(ScrnInfoPtr pScrn)
 {
@@ -416,6 +417,9 @@ CheckTiling(ScrnInfoPtr pScrn)
 
    return tiled;
 }
+#else
+#define CheckTiling(pScrn) 0
+#endif
 
 void
 I830SetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
diff-tree 43daaec63929c1f0e54a5125375d8147629da4b9 (from cdcc6f23e8cad797e6cfd57e2ff454ec8509b5ba)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Thu Aug 17 15:57:31 2006 -0700

    Bug #7905: Mark DRI state as dirty in 965 textured video, fixing hangs with 3d.

diff --git a/src/i830_video.c b/src/i830_video.c
index 693c703..7f6eb80 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2288,6 +2288,15 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
     */
    *pI830->used3D |= 1 << 30;
 
+#ifdef XF86DRI
+   /* Tell the DRI that we're smashing its state. */
+   if (pI830->directRenderingEnabled) {
+     drmI830Sarea *pSAREAPriv = DRIGetSAREAPrivate(pScrn->pScreen);
+
+     pSAREAPriv->ctxOwner = DRIGetContext(pScrn->pScreen);
+   }
+#endif /* XF86DRI */
+
    next_offset = 0;
 
    /* Set up our layout of state in framebuffer.  First the general state: */
diff-tree cdcc6f23e8cad797e6cfd57e2ff454ec8509b5ba (from a94c96abf90c691faecbebf0c8d08f8010bc67ef)
Author: Alan Hourihane <alanh at fairlite.demon.co.uk>
Date:   Wed Aug 16 17:16:28 2006 +0100

    Disable device check when mergedfb in operation.

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 21adbaf..c0d9672 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -4398,7 +4398,7 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int f
    /*
     * Let's setup the mobile systems to check the lid status
     */
-   if (IS_MOBILE(pI830)) {
+   if (IS_MOBILE(pI830) && !pI830->MergedFB) {
       pI830->checkDevices = TRUE;
 
       if (!xf86ReturnOptValBool(pI830->Options, OPTION_CHECKDEVICES, TRUE)) {
diff-tree a94c96abf90c691faecbebf0c8d08f8010bc67ef (from 2a4e486d2990af433e915cfa26dc57cae02e01b7)
Author: Alan Hourihane <alanh at fairlite.demon.co.uk>
Date:   Wed Aug 16 17:15:26 2006 +0100

    Fix bug #5150. Disable LVDS usage on i915G, i945G and i965G.

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 5d5fb72..21adbaf 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -2709,7 +2709,7 @@ SetDisplayDevices(ScrnInfoPtr pScrn, int
    } 
 
    /* LVDS doesn't exist on these */
-   if (IS_I830(pI830) || IS_845G(pI830) || IS_I865G(pI830))
+   if (IS_I830(pI830) || IS_845G(pI830) || IS_I865G(pI830) || IS_I915G(pI830) || IS_I945G(pI830) || IS_I965G(pI830))
       singlepipe &= ~(PIPE_LFP | (PIPE_LFP<<8));
 
    if (pI830->availablePipes == 1) 
diff-tree 2a4e486d2990af433e915cfa26dc57cae02e01b7 (from 4cfed93df6b23903704348cafe050a6546e84479)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Fri Aug 11 11:07:08 2006 +0800

    Fix undefined alloc type for agp memory
    
    This shuts up the nonfatal warning that type 3 for alloc agp
    memory is undefined for intel-agp.

diff --git a/src/i830_memory.c b/src/i830_memory.c
index 902b876..f270a51 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -209,17 +209,12 @@ AllocFromAGP(ScrnInfoPtr pScrn, I830MemR
       if (newApStart > newApEnd)
 	 return 0;
 
-      if (flags & NEED_PHYSICAL_ADDR) {
+      if (flags & NEED_PHYSICAL_ADDR) 
 	 result->Key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 2,
 					      &(result->Physical));
-      } else {
-         /* Due to a bug in agpgart in 2.6 kernels resulting in very poor
-	  * allocation performance we need to workaround it here...
-	  */
-	 result->Key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 3, NULL);
-         if (result->Key == -1)
-	    result->Key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 0, NULL);
-      }
+      else 
+	 result->Key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 0, NULL);
+
       if (result->Key == -1)
 	 return 0;
    }
@@ -973,13 +968,7 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, 
     */
    if (!dryrun) {
       memset(&(pI830->Dummy), 0, sizeof(pI830->Dummy));
-      /* Due to a bug in agpgart in 2.6 kernels resulting in very poor
-       * allocation performance we need to workaround it here...
-       */
-      pI830->Dummy.Key = 
-           xf86AllocateGARTMemory(pScrn->scrnIndex, size, 3, NULL);
-      if (pI830->Dummy.Key == -1)
-         pI830->Dummy.Key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 0, NULL);
+      pI830->Dummy.Key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 0, NULL);
       pI830->Dummy.Offset = 0;
    }
 #endif
@@ -1399,14 +1388,7 @@ I830DoPoolAllocation(ScrnInfoPtr pScrn, 
 
    if (pool->Total.Size > pool->Fixed.Size) {
       pool->Allocated.Size = pool->Total.Size - pool->Fixed.Size;
-      /* Due to a bug in agpgart in 2.6 kernels resulting in very poor
-       * allocation performance we need to workaround it here...
-       */
-      pool->Allocated.Key = 
-           xf86AllocateGARTMemory(pScrn->scrnIndex, pool->Allocated.Size,
-				   3, NULL);
-      if (pool->Allocated.Key == -1)
-         pool->Allocated.Key = xf86AllocateGARTMemory(pScrn->scrnIndex, 
+      pool->Allocated.Key = xf86AllocateGARTMemory(pScrn->scrnIndex, 
 				   pool->Allocated.Size, 0, NULL);
       if (pool->Allocated.Key == -1) {
 	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Pool allocation failed\n");
diff-tree 4cfed93df6b23903704348cafe050a6546e84479 (from 38e7e48418cd48a46e48f5bc8a6547721db8f76d)
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Aug 10 15:41:32 2006 -0700

    Bump to 1.6.5 for release.

diff --git a/configure.ac b/configure.ac
index edd5d7b..436d7e5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -22,7 +22,7 @@
 
 AC_PREREQ(2.57)
 AC_INIT([xf86-video-i810],
-        1.6.4,
+        1.6.5,
         [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
         xf86-video-i810)
 
diff-tree 38e7e48418cd48a46e48f5bc8a6547721db8f76d (from 975e60261088dee124b329d28c64e508bce1f90b)
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Aug 10 15:38:14 2006 -0700

    Fix README typos from in the generated file.

diff --git a/README b/README
index 804f79d..e2061c4 100644
--- a/README
+++ b/README
@@ -1,6 +1,6 @@
   Information for Intel graphics driver users
   Eric Anholt
-  206-08-04
+  2006-08-04
   ____________________________________________________________
 
   Table of Contents
@@ -117,7 +117,7 @@
      fixed in the current release, but is being actively worked on in
      the modesetting branch.
 
-  +o  Bug #5774: Some systems have issues with VT switching.  This should
+  +o  Bug #5795: Some systems have issues with VT switching.  This should
      be fixed with the modesetting brach integration.
 
   +o  Bug #5817: Hotkey switching from LVDS to CRT breaks CRT output.
diff-tree 975e60261088dee124b329d28c64e508bce1f90b (from 820e9a22fdb759cbdaac4a488322825bc0908b0d)
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Aug 10 13:49:43 2006 -0700

    Bug #7829: Fix reported driver version.
    
    The driver now reports itself as the PACKAGE_VERSION from autoconf.  The DRI
    DDX -> client interface version is dissociated from this so that we can do
    appropriate major/minor versioning of the interface that's not tied to the
    package version.  Bumped the i830 ddx dri version patchlevel to note the
    fix in the previous commit.

diff --git a/configure.ac b/configure.ac
index 74e676b..edd5d7b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -26,6 +26,16 @@ AC_INIT([xf86-video-i810],
         [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
         xf86-video-i810)
 
+AC_DEFINE_UNQUOTED([INTEL_VERSION_MAJOR],
+		   [$(echo $PACKAGE_VERSION | sed -e 's/^\([[0-9]]\)\.[[0-9]]\.[[0-9]]/\1/')],
+		   [Major version])
+AC_DEFINE_UNQUOTED([INTEL_VERSION_MINOR],
+		   [$(echo $PACKAGE_VERSION | sed -e 's/^[[0-9]]\.\([[0-9]]\)\.[[0-9]]/\1/')],
+		   [Minor version])
+AC_DEFINE_UNQUOTED([INTEL_VERSION_PATCH],
+		   [$(echo $PACKAGE_VERSION | sed -e 's/^[[0-9]]\.[[0-9]]\.\([[0-9]]\)/\1/')],
+		   [Patch version])
+
 AC_CONFIG_SRCDIR([Makefile.am])
 AM_CONFIG_HEADER([config.h])
 AC_CONFIG_AUX_DIR(.)
diff --git a/src/i810.h b/src/i810.h
index 4237485..852a64a 100644
--- a/src/i810.h
+++ b/src/i810.h
@@ -64,10 +64,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define I810_VERSION 4000
 #define I810_NAME "I810"
 #define I810_DRIVER_NAME "i810"
-#define I810_MAJOR_VERSION 1
-#define I810_MINOR_VERSION 6
-#define I810_PATCHLEVEL 3
-
 
 /* HWMC Surfaces */
 #define I810_MAX_SURFACES 7
diff --git a/src/i810_dri.h b/src/i810_dri.h
index 408a4eb..027a47a 100644
--- a/src/i810_dri.h
+++ b/src/i810_dri.h
@@ -8,6 +8,10 @@
 
 #define I810_MAX_DRAWABLES 256
 
+#define I810_MAJOR_VERSION 1
+#define I810_MINOR_VERSION 6
+#define I810_PATCHLEVEL 3
+
 typedef struct {
    drm_handle_t regs;
    drmSize regsSize;
diff --git a/src/i810_driver.c b/src/i810_driver.c
index 65136bf..3481d0b 100644
--- a/src/i810_driver.c
+++ b/src/i810_driver.c
@@ -379,7 +379,7 @@ static XF86ModuleVersionInfo i810VersRec
    MODINFOSTRING1,
    MODINFOSTRING2,
    XORG_VERSION_CURRENT,
-   I810_MAJOR_VERSION, I810_MINOR_VERSION, I810_PATCHLEVEL,
+   INTEL_VERSION_MAJOR, INTEL_VERSION_MINOR, INTEL_VERSION_PATCH,
    ABI_CLASS_VIDEODRV,
    ABI_VIDEODRV_VERSION,
    MOD_CLASS_VIDEODRV,
diff --git a/src/i830_dri.h b/src/i830_dri.h
index 44be353..41f8a90 100644
--- a/src/i830_dri.h
+++ b/src/i830_dri.h
@@ -10,7 +10,7 @@
 
 #define I830_MAJOR_VERSION 1
 #define I830_MINOR_VERSION 6
-#define I830_PATCHLEVEL 2
+#define I830_PATCHLEVEL 4
 
 #define I830_REG_SIZE 0x80000
 
diff-tree 820e9a22fdb759cbdaac4a488322825bc0908b0d (from caa3b35cd772fc75d65a7ff791f00addbb39a764)
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Aug 10 13:37:18 2006 -0700

    Bug #7835: Restore unused fields in I830DRIRec to avoid i915 DRI breakage.
    
    As it was, 1.6.4 broke compatibility with the released DRI driver.

diff --git a/src/i830_dri.h b/src/i830_dri.h
index f97c1dd..44be353 100644
--- a/src/i830_dri.h
+++ b/src/i830_dri.h
@@ -3,7 +3,6 @@
 #ifndef _I830_DRI_H
 #define _I830_DRI_H
 
-#include "xf86dri.h"
 #include "xf86drm.h"
 #include "i830_common.h"
 
@@ -19,6 +18,21 @@ typedef struct _I830DRIRec {
    drm_handle_t regs;
    drmSize regsSize;
 
+   drmSize unused1; /* backbufferSize */
+   drm_handle_t unused2; /* backbuffer */
+
+   drmSize unused3; /* depthbufferSize */
+   drm_handle_t unused4; /* depthbuffer */
+
+   drmSize unused5; /* rotatedSize /*/
+   drm_handle_t unused6; /* rotatedbuffer */
+
+   drm_handle_t unused7; /* textures */
+   int unused8; /* textureSize */
+
+   drm_handle_t unused9; /* agp_buffers */
+   drmSize unused10; /* agp_buf_size */
+
    int deviceID;
    int width;
    int height;
@@ -26,6 +40,11 @@ typedef struct _I830DRIRec {
    int cpp;
    int bitsPerPixel;
 
+   int unused11[8]; /* was front/back/depth/rotated offset/pitch */
+
+   int unused12; /* logTextureGranularity */
+   int unused13; /* textureOffset */
+
    int irq;
    int sarea_priv_offset;
 } I830DRIRec, *I830DRIPtr;
diff-tree caa3b35cd772fc75d65a7ff791f00addbb39a764 (from 2a7426cf138e518a5eafb40f478359160a7ec98b)
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Aug 9 16:11:30 2006 -0700

    Correct typos in README source.

diff --git a/README.sgml b/README.sgml
index 2f9abb7..fd52608 100644
--- a/README.sgml
+++ b/README.sgml
@@ -5,7 +5,7 @@
 <article>
 <title>Information for Intel graphics driver users
 <author>Eric Anholt
-<date>206-08-04
+<date>2006-08-04
 <toc>
 
 <sect>Introduction
@@ -84,7 +84,7 @@ for information on configuration options
   <item>Many systems with Intel graphics have issues with setting video modes
 at larger than some small maximum resolution.  This is not fixed in the current
 release, but is being actively worked on in the modesetting branch.
-  <item>Bug #5774: Some systems have issues with VT switching.  This should
+  <item>Bug #5795: Some systems have issues with VT switching.  This should
 be fixed with the modesetting brach integration.
   <item>Bug #5817: Hotkey switching from LVDS to CRT breaks CRT output.  This
 is a known issue, but will not be fixed in the current release.
diff-tree 2a7426cf138e518a5eafb40f478359160a7ec98b (from 24e59a0daa20b7c3e5028c9ca7972052801d02a1)
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Aug 9 15:47:09 2006 -0700

    Clean up warnings.

diff --git a/src/i830.h b/src/i830.h
index ced8c75..38a880f 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -447,6 +447,7 @@ extern int I830WaitLpRing(ScrnInfoPtr pS
 extern void I830SetPIOAccess(I830Ptr pI830);
 extern void I830SetMMIOAccess(I830Ptr pI830);
 extern void I830PrintErrorState(ScrnInfoPtr pScrn);
+extern void I965PrintErrorState(ScrnInfoPtr pScrn);
 extern void I830Sync(ScrnInfoPtr pScrn);
 extern void I830InitHWCursor(ScrnInfoPtr pScrn);
 extern Bool I830CursorInit(ScreenPtr pScreen);
diff --git a/src/i830_cursor.c b/src/i830_cursor.c
index dd3071e..c9e04e9 100644
--- a/src/i830_cursor.c
+++ b/src/i830_cursor.c
@@ -475,7 +475,6 @@ I830SetCursorPosition(ScrnInfoPtr pScrn,
 {
    I830Ptr pI830 = I830PTR(pScrn);
    CARD32 temp = 0;
-   static Bool outsideViewport = FALSE;
    Bool hide = FALSE, show = FALSE;
    int oldx = x, oldy = y;
    int hotspotx = 0, hotspoty = 0;
diff --git a/src/i830_dri.c b/src/i830_dri.c
index 445bbec..c9b52c4 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -102,8 +102,6 @@ static void I830DRIInitBuffers(WindowPtr
 static void I830DRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg,
 			       RegionPtr prgnSrc, CARD32 index);
 
-static Bool I830DRICloseFullScreen(ScreenPtr pScreen);
-static Bool I830DRIOpenFullScreen(ScreenPtr pScreen);
 static void I830DRITransitionTo2d(ScreenPtr pScreen);
 static void I830DRITransitionTo3d(ScreenPtr pScreen);
 static void I830DRITransitionMultiToSingle3d(ScreenPtr pScreen);
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 62a62ab..5d5fb72 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -6614,39 +6614,52 @@ I965PrintErrorState(ScrnInfoPtr pScrn)
 	  INREG(LP_RING + RING_LEN), INREG(LP_RING + RING_START));
 
    ErrorF("Err ID (eir): %x Err Status (esr): %x Err Mask (emr): %x\n",
-	  INREG(EIR), INREG(ESR), INREG(EMR));
+	  (int)INREG(EIR), (int)INREG(ESR), (int)INREG(EMR));
 
-   ErrorF("instdone: %x instdone_1: %x\n", INREG(INST_DONE_I965), INREG(INST_DONE_1));
-   ErrorF("instpm: %x\n", INREG(INST_PM));
+   ErrorF("instdone: %x instdone_1: %x\n", (int)INREG(INST_DONE_I965),
+	  (int)INREG(INST_DONE_1));
+   ErrorF("instpm: %x\n", (int)INREG(INST_PM));
 
    ErrorF("memmode: %lx instps: %lx\n", INREG(MEMMODE), INREG(INST_PS_I965));
 
    ErrorF("HW Status mask (hwstam): %x\nIRQ enable (ier): %x imr: %x iir: %x\n",
-	  INREG(HWSTAM), INREG(IER), INREG(IMR), INREG(IIR));
+	  (int)INREG(HWSTAM), (int)INREG(IER), (int)INREG(IMR),
+	  (int)INREG(IIR));
 
    ErrorF("acthd: %lx dma_fadd_p: %lx\n", INREG(ACTHD), INREG(DMA_FADD_P));
    ErrorF("ecoskpd: %lx excc: %lx\n", INREG(ECOSKPD), INREG(EXCC));
 
-   ErrorF("cache_mode: %x/%x\n", INREG(CACHE_MODE_0), INREG(CACHE_MODE_1));
-   ErrorF("mi_arb_state: %x\n", INREG(MI_ARB_STATE));
-
-   ErrorF("IA_VERTICES_COUNT_QW %x/%x\n", INREG(IA_VERTICES_COUNT_QW), INREG(IA_VERTICES_COUNT_QW+4));
-   ErrorF("IA_PRIMITIVES_COUNT_QW %x/%x\n", INREG(IA_PRIMITIVES_COUNT_QW), INREG(IA_PRIMITIVES_COUNT_QW+4));
-
-   ErrorF("VS_INVOCATION_COUNT_QW %x/%x\n", INREG(VS_INVOCATION_COUNT_QW), INREG(VS_INVOCATION_COUNT_QW+4));
-
-   ErrorF("GS_INVOCATION_COUNT_QW %x/%x\n", INREG(GS_INVOCATION_COUNT_QW), INREG(GS_INVOCATION_COUNT_QW+4));
-   ErrorF("GS_PRIMITIVES_COUNT_QW %x/%x\n", INREG(GS_PRIMITIVES_COUNT_QW), INREG(GS_PRIMITIVES_COUNT_QW+4));
-
-   ErrorF("CL_INVOCATION_COUNT_QW %x/%x\n", INREG(CL_INVOCATION_COUNT_QW), INREG(CL_INVOCATION_COUNT_QW+4));
-   ErrorF("CL_PRIMITIVES_COUNT_QW %x/%x\n", INREG(CL_PRIMITIVES_COUNT_QW), INREG(CL_PRIMITIVES_COUNT_QW+4));
-
-   ErrorF("PS_INVOCATION_COUNT_QW %x/%x\n", INREG(PS_INVOCATION_COUNT_QW), INREG(PS_INVOCATION_COUNT_QW+4));
-   ErrorF("PS_DEPTH_COUNT_QW %x/%x\n", INREG(PS_DEPTH_COUNT_QW), INREG(PS_DEPTH_COUNT_QW+4));
-
-   ErrorF("WIZ_CTL %x\n", INREG(WIZ_CTL));
-   ErrorF("TS_CTL %x  TS_DEBUG_DATA %x\n", INREG(TS_CTL), INREG(TS_DEBUG_DATA));
-   ErrorF("TD_CTL %x / %x\n", INREG(TD_CTL), INREG(TD_CTL2));
+   ErrorF("cache_mode: %x/%x\n", (int)INREG(CACHE_MODE_0),
+	  (int)INREG(CACHE_MODE_1));
+   ErrorF("mi_arb_state: %x\n", (int)INREG(MI_ARB_STATE));
+
+   ErrorF("IA_VERTICES_COUNT_QW %x/%x\n", (int)INREG(IA_VERTICES_COUNT_QW),
+	  (int)INREG(IA_VERTICES_COUNT_QW+4));
+   ErrorF("IA_PRIMITIVES_COUNT_QW %x/%x\n", (int)INREG(IA_PRIMITIVES_COUNT_QW),
+	  (int)INREG(IA_PRIMITIVES_COUNT_QW+4));
+
+   ErrorF("VS_INVOCATION_COUNT_QW %x/%x\n", (int)INREG(VS_INVOCATION_COUNT_QW),
+	  (int)INREG(VS_INVOCATION_COUNT_QW+4));
+
+   ErrorF("GS_INVOCATION_COUNT_QW %x/%x\n", (int)INREG(GS_INVOCATION_COUNT_QW),
+	  (int)INREG(GS_INVOCATION_COUNT_QW+4));
+   ErrorF("GS_PRIMITIVES_COUNT_QW %x/%x\n", (int)INREG(GS_PRIMITIVES_COUNT_QW),
+	  (int)INREG(GS_PRIMITIVES_COUNT_QW+4));
+
+   ErrorF("CL_INVOCATION_COUNT_QW %x/%x\n", (int)INREG(CL_INVOCATION_COUNT_QW),
+	  (int)INREG(CL_INVOCATION_COUNT_QW+4));
+   ErrorF("CL_PRIMITIVES_COUNT_QW %x/%x\n", (int)INREG(CL_PRIMITIVES_COUNT_QW),
+	  (int)INREG(CL_PRIMITIVES_COUNT_QW+4));
+
+   ErrorF("PS_INVOCATION_COUNT_QW %x/%x\n", (int)INREG(PS_INVOCATION_COUNT_QW),
+	  (int)INREG(PS_INVOCATION_COUNT_QW+4));
+   ErrorF("PS_DEPTH_COUNT_QW %x/%x\n", (int)INREG(PS_DEPTH_COUNT_QW),
+	  (int)INREG(PS_DEPTH_COUNT_QW+4));
+
+   ErrorF("WIZ_CTL %x\n", (int)INREG(WIZ_CTL));
+   ErrorF("TS_CTL %x  TS_DEBUG_DATA %x\n", (int)INREG(TS_CTL),
+	  (int)INREG(TS_DEBUG_DATA));
+   ErrorF("TD_CTL %x / %x\n", (int)INREG(TD_CTL), (int)INREG(TD_CTL2));
 
    
 }
diff --git a/src/i830_rotate.c b/src/i830_rotate.c
index aee04da..020d7e6 100644
--- a/src/i830_rotate.c
+++ b/src/i830_rotate.c
@@ -217,7 +217,6 @@ I915UpdateRotate (ScreenPtr      pScreen
    drm_context_t myContext = 0;
 #endif
    Bool didLock = FALSE;
-   CARD32 format;
 
    if (I830IsPrimary(pScrn)) {
       pI8301 = pI830;
diff --git a/src/i830_video.c b/src/i830_video.c
index 9a66f7f..693c703 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2191,6 +2191,7 @@ static CARD32 float_to_uint (float f) {
    return x.i;
 }
 
+#if 0
 static struct {
    CARD32   svg_ctl;
    char	    *name;
@@ -2219,6 +2220,7 @@ brw_debug (ScrnInfoPtr pScrn, char *when
       ErrorF("\t%34.34s: 0x%08x\n", svg_ctl_bits[i].name, v);
    }
 }
+#endif
 
 #define WATCH_SF 0
 #define WATCH_WIZ 0
@@ -2234,10 +2236,8 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
 			       DrawablePtr pDraw)
 {
    I830Ptr pI830 = I830PTR(pScrn);
-   CARD32 format, ms3, s2;
    BoxPtr pbox;
    int nbox, dxo, dyo;
-   Bool planar;
    int urb_vs_start, urb_vs_size;
    int urb_gs_start, urb_gs_size;
    int urb_clip_start, urb_clip_size;
@@ -2811,9 +2811,6 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
       OUT_RING(0); /* index buffer offset, ignored */
       ADVANCE_LP_RING();
 
-      int   j, k;
-      CARD32	  ctl = 0, rdata;
-      
 #if 0
       for (j = 0; j < 100000; j++) {
 	ctl = INREG(BRW_VF_CTL);
diff-tree 24e59a0daa20b7c3e5028c9ca7972052801d02a1 (from parents)
Merge: bb6080735efc40e103e92b65d0c2f1f729156632 32f1199937e92b9100aba52cbbb97157014e3182
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Aug 9 14:19:06 2006 -0700

    Merge branch 'textured-video', bringing in fixed-up i915 textured video.
    
    Conflicts:
    
    	src/i830_video.c

diff --cc src/i810_reg.h
index 9774a4c,2c5e271..05710c4
@@@ -1607,244 -918,6 +992,244 @@@
  #define ENABLE_FOG_CONST	(1<<24)
  #define ENABLE_FOG_DENSITY	(1<<23)
  
 +/*
 + * New regs for broadwater -- we need to split this file up sensibly somehow.
 + */
- #define BRW_3D(Pipeline,Opcode,Subopcode) (CMD_3D | \
++#define BRW_3D(Pipeline,Opcode,Subopcode) ((3 << 29) | \
 +					   ((Pipeline) << 27) | \
 +					   ((Opcode) << 24) | \
 +					   ((Subopcode) << 16))
 +
 +#define BRW_URB_FENCE				BRW_3D(0, 0, 0)
 +#define BRW_CS_URB_STATE			BRW_3D(0, 0, 1)
 +#define BRW_CONSTANT_BUFFER			BRW_3D(0, 0, 2)
 +#define BRW_STATE_PREFETCH			BRW_3D(0, 0, 3)
 +
 +#define BRW_STATE_BASE_ADDRESS			BRW_3D(0, 1, 1)
 +#define BRW_STATE_SIP				BRW_3D(0, 1, 2)
 +#define BRW_PIPELINE_SELECT			BRW_3D(0, 1, 4)
 +
 +#define BRW_MEDIA_STATE_POINTERS		BRW_3D(2, 0, 0)
 +#define BRW_MEDIA_OBJECT			BRW_3D(2, 1, 0)
 +
 +#define BRW_3DSTATE_PIPELINED_POINTERS		BRW_3D(3, 0, 0)
 +#define BRW_3DSTATE_BINDING_TABLE_POINTERS	BRW_3D(3, 0, 1)
 +#define BRW_3DSTATE_VERTEX_BUFFERS		BRW_3D(3, 0, 8)
 +#define BRW_3DSTATE_VERTEX_ELEMENTS		BRW_3D(3, 0, 9)
 +#define BRW_3DSTATE_INDEX_BUFFER		BRW_3D(3, 0, 0xa)
 +#define BRW_3DSTATE_VF_STATISTICS		BRW_3D(3, 0, 0xb)
 +
 +#define BRW_3DSTATE_DRAWING_RECTANGLE		BRW_3D(3, 1, 0)
 +#define BRW_3DSTATE_CONSTANT_COLOR		BRW_3D(3, 1, 1)
 +#define BRW_3DSTATE_SAMPLER_PALETTE_LOAD	BRW_3D(3, 1, 2)
 +#define BRW_3DSTATE_CHROMA_KEY			BRW_3D(3, 1, 4)
 +#define BRW_3DSTATE_DEPTH_BUFFER		BRW_3D(3, 1, 5)
 +#define BRW_3DSTATE_POLY_STIPPLE_OFFSET		BRW_3D(3, 1, 6)
 +#define BRW_3DSTATE_POLY_STIPPLE_PATTERN	BRW_3D(3, 1, 7)
 +#define BRW_3DSTATE_LINE_STIPPLE		BRW_3D(3, 1, 8)
 +#define BRW_3DSTATE_GLOBAL_DEPTH_OFFSET_CLAMP	BRW_3D(3, 1, 9)
 +/* These two are BLC and CTG only, not BW or CL */
 +#define BRW_3DSTATE_AA_LINE_PARAMS		BRW_3D(3, 1, 0xa)
 +#define BRW_3DSTATE_GS_SVB_INDEX		BRW_3D(3, 1, 0xb)
 +
 +#define BRW_PIPE_CONTROL			BRW_3D(3, 2, 0)
 +
 +#define BRW_3DPRIMITIVE				BRW_3D(3, 3, 0)
 +
 +#define PIPELINE_SELECT_3D		0
 +#define PIPELINE_SELECT_MEDIA		1
 +
 +#define UF0_CS_REALLOC			(1 << 13)
 +#define UF0_VFE_REALLOC			(1 << 12)
 +#define UF0_SF_REALLOC			(1 << 11)
 +#define UF0_CLIP_REALLOC		(1 << 10)
 +#define UF0_GS_REALLOC			(1 << 9)
 +#define UF0_VS_REALLOC			(1 << 8)
 +#define UF1_CLIP_FENCE_SHIFT		20
 +#define UF1_GS_FENCE_SHIFT		10
 +#define UF1_VS_FENCE_SHIFT		0
 +#define UF2_CS_FENCE_SHIFT		20
 +#define UF2_VFE_FENCE_SHIFT		10
 +#define UF2_SF_FENCE_SHIFT		0
 +
 +/* for BRW_STATE_BASE_ADDRESS */
 +#define BASE_ADDRESS_MODIFY		(1 << 0)
 +
 +/* for BRW_3DSTATE_PIPELINED_POINTERS */
 +#define BRW_GS_DISABLE		       0
 +#define BRW_GS_ENABLE		       1
 +#define BRW_CLIP_DISABLE	       0
 +#define BRW_CLIP_ENABLE		       1
 +
 +/* for BRW_PIPE_CONTROL */
 +#define BRW_PIPE_CONTROL_NOWRITE       (0 << 14)
 +#define BRW_PIPE_CONTROL_WRITE_QWORD   (1 << 14)
 +#define BRW_PIPE_CONTROL_WRITE_DEPTH   (2 << 14)
 +#define BRW_PIPE_CONTROL_WRITE_TIME    (3 << 14)
 +#define BRW_PIPE_CONTROL_DEPTH_STALL   (1 << 13)
 +#define BRW_PIPE_CONTROL_WC_FLUSH      (1 << 12)
 +#define BRW_PIPE_CONTROL_IS_FLUSH      (1 << 11)
 +#define BRW_PIPE_CONTROL_NOTIFY_ENABLE (1 << 8)
 +#define BRW_PIPE_CONTROL_GLOBAL_GTT    (1 << 2)
 +#define BRW_PIPE_CONTROL_LOCAL_PGTT    (0 << 2)
 +
 +/* VERTEX_BUFFER_STATE Structure */
 +#define VB0_BUFFER_INDEX_SHIFT		27
 +#define VB0_VERTEXDATA			(0 << 26)
 +#define VB0_INSTANCEDATA		(1 << 26)
 +#define VB0_BUFFER_PITCH_SHIFT		0
 +
 +/* VERTEX_ELEMENT_STATE Structure */
 +#define VE0_VERTEX_BUFFER_INDEX_SHIFT	27
 +#define VE0_VALID			(1 << 26)
 +#define VE0_FORMAT_SHIFT		16
 +#define VE0_OFFSET_SHIFT		0
 +#define VE1_VFCOMPONENT_0_SHIFT		28
 +#define VE1_VFCOMPONENT_1_SHIFT		24
 +#define VE1_VFCOMPONENT_2_SHIFT		20
 +#define VE1_VFCOMPONENT_3_SHIFT		16
 +#define VE1_DESTINATION_ELEMENT_OFFSET_SHIFT	0
 +
 +/* 3DPRIMITIVE bits */
 +#define BRW_3DPRIMITIVE_VERTEX_SEQUENTIAL (0 << 15)
 +#define BRW_3DPRIMITIVE_VERTEX_RANDOM	  (1 << 15)
 +/* Primitive types are in brw_defines.h */
 +#define BRW_3DPRIMITIVE_TOPOLOGY_SHIFT	  10
 +
 +#define BRW_SVG_CTL		       0x7400
 +
 +#define BRW_SVG_CTL_GS_BA	       (0 << 8)
 +#define BRW_SVG_CTL_SS_BA	       (1 << 8)
 +#define BRW_SVG_CTL_IO_BA	       (2 << 8)
 +#define BRW_SVG_CTL_GS_AUB	       (3 << 8)
 +#define BRW_SVG_CTL_IO_AUB	       (4 << 8)
 +#define BRW_SVG_CTL_SIP		       (5 << 8)
 +
 +#define BRW_SVG_RDATA		       0x7404
 +#define BRW_SVG_WORK_CTL	       0x7408
 +
 +#define BRW_VF_CTL		       0x7500
 +
 +#define BRW_VF_CTL_SNAPSHOT_COMPLETE		   (1 << 31)
 +#define BRW_VF_CTL_SNAPSHOT_MUX_SELECT_THREADID	   (0 << 8)
 +#define BRW_VF_CTL_SNAPSHOT_MUX_SELECT_VF_DEBUG	   (1 << 8)
 +#define BRW_VF_CTL_SNAPSHOT_TYPE_VERTEX_SEQUENCE   (0 << 4)
 +#define BRW_VF_CTL_SNAPSHOT_TYPE_VERTEX_INDEX	   (1 << 4)
 +#define BRW_VF_CTL_SKIP_INITIAL_PRIMITIVES	   (1 << 3)
 +#define BRW_VF_CTL_MAX_PRIMITIVES_LIMIT_ENABLE	   (1 << 2)
 +#define BRW_VF_CTL_VERTEX_RANGE_LIMIT_ENABLE	   (1 << 1)
 +#define BRW_VF_CTL_SNAPSHOT_ENABLE	     	   (1 << 0)
 +
 +#define BRW_VF_STRG_VAL		       0x7504
 +#define BRW_VF_STR_VL_OVR	       0x7508
 +#define BRW_VF_VC_OVR		       0x750c
 +#define BRW_VF_STR_PSKIP	       0x7510
 +#define BRW_VF_MAX_PRIM		       0x7514
 +#define BRW_VF_RDATA		       0x7518
 +
 +#define BRW_VS_CTL		       0x7600
 +#define BRW_VS_CTL_SNAPSHOT_COMPLETE		   (1 << 31)
 +#define BRW_VS_CTL_SNAPSHOT_MUX_VERTEX_0	   (0 << 8)
 +#define BRW_VS_CTL_SNAPSHOT_MUX_VERTEX_1	   (1 << 8)
 +#define BRW_VS_CTL_SNAPSHOT_MUX_VALID_COUNT	   (2 << 8)
 +#define BRW_VS_CTL_SNAPSHOT_MUX_VS_KERNEL_POINTER  (3 << 8)
 +#define BRW_VS_CTL_SNAPSHOT_ALL_THREADS		   (1 << 2)
 +#define BRW_VS_CTL_THREAD_SNAPSHOT_ENABLE	   (1 << 1)
 +#define BRW_VS_CTL_SNAPSHOT_ENABLE		   (1 << 0)
 +
 +#define BRW_VS_STRG_VAL		       0x7604
 +#define BRW_VS_RDATA		       0x7608
 +
 +#define BRW_SF_CTL		       0x7b00
 +#define BRW_SF_CTL_SNAPSHOT_COMPLETE		   (1 << 31)
 +#define BRW_SF_CTL_SNAPSHOT_MUX_VERTEX_0_FF_ID	   (0 << 8)
 +#define BRW_SF_CTL_SNAPSHOT_MUX_VERTEX_0_REL_COUNT (1 << 8)
 +#define BRW_SF_CTL_SNAPSHOT_MUX_VERTEX_1_FF_ID	   (2 << 8)
 +#define BRW_SF_CTL_SNAPSHOT_MUX_VERTEX_1_REL_COUNT (3 << 8)
 +#define BRW_SF_CTL_SNAPSHOT_MUX_VERTEX_2_FF_ID	   (4 << 8)
 +#define BRW_SF_CTL_SNAPSHOT_MUX_VERTEX_2_REL_COUNT (5 << 8)
 +#define BRW_SF_CTL_SNAPSHOT_MUX_VERTEX_COUNT	   (6 << 8)
 +#define BRW_SF_CTL_SNAPSHOT_MUX_SF_KERNEL_POINTER  (7 << 8)
 +#define BRW_SF_CTL_MIN_MAX_PRIMITIVE_RANGE_ENABLE  (1 << 4)
 +#define BRW_SF_CTL_DEBUG_CLIP_RECTANGLE_ENABLE	   (1 << 3)
 +#define BRW_SF_CTL_SNAPSHOT_ALL_THREADS		   (1 << 2)
 +#define BRW_SF_CTL_THREAD_SNAPSHOT_ENABLE	   (1 << 1)
 +#define BRW_SF_CTL_SNAPSHOT_ENABLE		   (1 << 0)
 +
 +#define BRW_SF_STRG_VAL		       0x7b04
 +#define BRW_SF_RDATA		       0x7b18
 +
 +#define BRW_WIZ_CTL		       0x7c00
 +#define BRW_WIZ_CTL_SNAPSHOT_COMPLETE		   (1 << 31)
 +#define BRW_WIZ_CTL_SUBSPAN_INSTANCE_SHIFT	   16
 +#define BRW_WIZ_CTL_SNAPSHOT_MUX_WIZ_KERNEL_POINTER   (0 << 8)
 +#define BRW_WIZ_CTL_SNAPSHOT_MUX_SUBSPAN_INSTANCE     (1 << 8)
 +#define BRW_WIZ_CTL_SNAPSHOT_MUX_PRIMITIVE_SEQUENCE   (2 << 8)
 +#define BRW_WIZ_CTL_SINGLE_SUBSPAN_DISPATCH	      (1 << 6)
 +#define BRW_WIZ_CTL_IGNORE_COLOR_SCOREBOARD_STALLS    (1 << 5)
 +#define BRW_WIZ_CTL_ENABLE_SUBSPAN_INSTANCE_COMPARE   (1 << 4)
 +#define BRW_WIZ_CTL_USE_UPSTREAM_SNAPSHOT_FLAG	      (1 << 3)
 +#define BRW_WIZ_CTL_SNAPSHOT_ALL_THREADS	      (1 << 2)
 +#define BRW_WIZ_CTL_THREAD_SNAPSHOT_ENABLE	      (1 << 1)
 +#define BRW_WIZ_CTL_SNAPSHOT_ENABLE		      (1 << 0)
 +
 +#define BRW_WIZ_STRG_VAL			      0x7c04
 +#define BRW_WIZ_RDATA				      0x7c18
 +
 +#define BRW_TS_CTL		       0x7e00
 +#define BRW_TS_CTL_SNAPSHOT_COMPLETE		   (1 << 31)
 +#define BRW_TS_CTL_SNAPSHOT_MESSAGE_ERROR	   (0 << 8)
 +#define BRW_TS_CTL_SNAPSHOT_INTERFACE_DESCRIPTOR   (3 << 8)
 +#define BRW_TS_CTL_SNAPSHOT_ALL_CHILD_THREADS	   (1 << 2)
 +#define BRW_TS_CTL_SNAPSHOT_ALL_ROOT_THREADS  	   (1 << 1)
 +#define BRW_TS_CTL_SNAPSHOT_ENABLE		   (1 << 0)
 +
 +#define BRW_TS_STRG_VAL		       0x7e04
 +#define BRW_TS_RDATA		       0x7e08
 +
 +#define BRW_TD_CTL		       0x8000
 +#define BRW_TD_CTL_MUX_SHIFT	       8
 +#define BRW_TD_CTL_EXTERNAL_HALT_R0_DEBUG_MATCH	   (1 << 7)
 +#define BRW_TD_CTL_FORCE_EXTERNAL_HALT		   (1 << 6)
 +#define BRW_TD_CTL_EXCEPTION_MASK_OVERRIDE	   (1 << 5)
 +#define BRW_TD_CTL_FORCE_THREAD_BREAKPOINT_ENABLE  (1 << 4)
 +#define BRW_TD_CTL_BREAKPOINT_ENABLE		   (1 << 2)
 +#define BRW_TD_CTL2		       0x8004
 +#define BRW_TD_CTL2_ILLEGAL_OPCODE_EXCEPTION_OVERRIDE (1 << 28)
 +#define BRW_TD_CTL2_MASKSTACK_EXCEPTION_OVERRIDE      (1 << 26)
 +#define BRW_TD_CTL2_SOFTWARE_EXCEPTION_OVERRIDE	      (1 << 25)
 +#define BRW_TD_CTL2_ACTIVE_THREAD_LIMIT_SHIFT	      16
 +#define BRW_TD_CTL2_ACTIVE_THREAD_LIMIT_ENABLE	      (1 << 8)
 +#define BRW_TD_CTL2_THREAD_SPAWNER_EXECUTION_MASK_ENABLE (1 << 7)
 +#define BRW_TD_CTL2_WIZ_EXECUTION_MASK_ENABLE	      (1 << 6)
 +#define BRW_TD_CTL2_SF_EXECUTION_MASK_ENABLE	      (1 << 5)
 +#define BRW_TD_CTL2_CLIPPER_EXECUTION_MASK_ENABLE     (1 << 4)
 +#define BRW_TD_CTL2_GS_EXECUTION_MASK_ENABLE	      (1 << 3)
 +#define BRW_TD_CTL2_VS_EXECUTION_MASK_ENABLE	      (1 << 0)
 +#define BRW_TD_VF_VS_EMSK	       0x8008
 +#define BRW_TD_GS_EMSK		       0x800c
 +#define BRW_TD_CLIP_EMSK	       0x8010
 +#define BRW_TD_SF_EMSK		       0x8014
 +#define BRW_TD_WIZ_EMSK		       0x8018
 +#define BRW_TD_0_6_EHTRG_VAL	       0x801c
 +#define BRW_TD_0_7_EHTRG_VAL	       0x8020
 +#define BRW_TD_0_6_EHTRG_MSK           0x8024
 +#define BRW_TD_0_7_EHTRG_MSK	       0x8028
 +#define BRW_TD_RDATA		       0x802c
 +#define BRW_TD_TS_EMSK		       0x8030
 +
 +#define BRW_EU_CTL		       0x8800
 +#define BRW_EU_CTL_SELECT_SHIFT	       16
 +#define BRW_EU_CTL_DATA_MUX_SHIFT      8
 +#define BRW_EU_ATT_0		       0x8810
 +#define BRW_EU_ATT_1		       0x8814
 +#define BRW_EU_ATT_DATA_0	       0x8820
 +#define BRW_EU_ATT_DATA_1	       0x8824
 +#define BRW_EU_ATT_CLR_0	       0x8830
 +#define BRW_EU_ATT_CLR_1	       0x8834
 +#define BRW_EU_RDATA		       0x8840
 +
 +/* End regs for broadwater */
  
  #define MAX_DISPLAY_PIPES	2
  
diff --cc src/i830_rotate.c
index 425eeef,716f425..aee04da
@@@ -576,15 -575,15 +576,15 @@@
        OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE);
        OUT_RING(0x00000000);
        /* draw rect */
-       OUT_RING(STATE3D_DRAWING_RECTANGLE);
 -      OUT_RING(0x7d800003);
 -      OUT_RING(0x00000000);
 -      OUT_RING(0x00000000);
 -      OUT_RING((pScrn->virtualX - 1) | (pScrn->virtualY - 1) << 16);
 -      OUT_RING(0x00000000);
 -      OUT_RING(0x00000000);
++      OUT_RING(_3DSTATE_DRAW_RECT_CMD);
 +      OUT_RING(0x00000000);	/* flags */
 +      OUT_RING(0x00000000);	/* ymin, xmin */
 +      OUT_RING((pScrn->virtualX - 1) | (pScrn->virtualY - 1) << 16); /* ymax, xmax */
 +      OUT_RING(0x00000000);	/* yorigin, xorigin */
 +      OUT_RING(MI_NOOP);
  
        /* front buffer */
-       OUT_RING(STATE3D_BUFFER_INFO);
 -      OUT_RING(0x7d8e0001);
++      OUT_RING(_3DSTATE_BUF_INFO_CMD);
        OUT_RING(0x03800000 | (((pI830->displayWidth * pI830->cpp) / 4) << 2));
        if (I830IsPrimary(pScrn))
  	 OUT_RING(pI830->FrontBuffer.Start);
diff --cc src/i830_video.c
index a056fdf,044d6c1..9a66f7f
@@@ -2134,1384 -1986,6 +2095,821 @@@
     OVERLAY_UPDATE;
  }
  
- /* Doesn't matter on the order for our purposes */
- typedef struct {
-    unsigned char red, green, blue, alpha;
- } intel_color_t;
- 
- /* Vertex format */
- typedef union {
-    struct {
-       float x, y, z, w;
-       intel_color_t color;
-       intel_color_t specular;
-       float u0, v0;
-       float u1, v1;
-       float u2, v2;
-       float u3, v3;
-    } v;
-    float f[24];
-    unsigned int  ui[24];
-    unsigned char ub4[24][4];
- } intelVertex, *intelVertexPtr;
- 
- static void draw_poly(CARD32 *vb,
-                       float verts[][2],
-                       float texcoords[][2],
- 		      float texcoords2[][2])
- {
-    int vertex_size;
-    intelVertex tmp;
-    int i, k;
- 
-    if (texcoords2 != NULL)
-       vertex_size = 10;
-    else
-       vertex_size = 8;
-    
-    /* initial constant vertex fields */
-    tmp.v.z = 1.0;
-    tmp.v.w = 1.0; 
-    tmp.v.color.red = 255;
-    tmp.v.color.green = 255;
-    tmp.v.color.blue = 255;
-    tmp.v.color.alpha = 255;
-    tmp.v.specular.red = 0;
-    tmp.v.specular.green = 0;
-    tmp.v.specular.blue = 0;
-    tmp.v.specular.alpha = 0;
- 
-    for (k = 0; k < 4; k++) {
-       tmp.v.x = verts[k][0];
-       tmp.v.y = verts[k][1];
-       tmp.v.u0 = texcoords[k][0];
-       tmp.v.v0 = texcoords[k][1];
-       if (texcoords2 != NULL) {
- 	 tmp.v.u1 = texcoords2[k][0];
- 	 tmp.v.v1 = texcoords2[k][1];
-       }
- 
-       for (i = 0 ; i < vertex_size ; i++)
-          vb[i] = tmp.ui[i];
- 
-       vb += vertex_size;
-    }
- }
- 
- union intfloat {
-    CARD32 ui;
-    float f;
- };
- 
- #define OUT_RING_F(x) do {						\
-    union intfloat _tmp;							\
-    _tmp.f = x;								\
-    OUT_RING(_tmp.ui);							\
- } while (0)
- 
- #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)
- 
- /* Move the dest_chan from src0 to dest, leaving the other channels alone */
- #define OUT_MOV_TO_CHANNEL(dest_type, dest_nr, src0_type, src0_nr,	\
- 			   dest_chan)					\
- do {									\
-    OUT_RING(A0_MOV | A0_DEST_CHANNEL_##dest_chan |			\
- 	    (REG_TYPE_##dest_type << A0_DEST_TYPE_SHIFT) |		\
- 	    (dest_nr << A0_DEST_NR_SHIFT) |				\
- 	    (REG_TYPE_##src0_type << A0_SRC0_TYPE_SHIFT) |		\
- 	    (src0_nr << 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));			\
-    OUT_RING(0);								\
- } while (0)
- 
- /* Dot3-product src0 and src1, storing the result in dest_chan of the dest.
-  * Saturates, in case we have out-of-range YUV values.
-  */
- #define OUT_DP3_TO_CHANNEL(dest_type, dest_nr, src0_type, src0_nr,	\
- 			   src1_type, src1_nr, dest_chan)		\
- do {									\
-    OUT_RING(A0_DP3 | A0_DEST_CHANNEL_##dest_chan | A0_DEST_SATURATE |	\
- 	    (REG_TYPE_##dest_type << A0_DEST_TYPE_SHIFT) |		\
- 	    (dest_nr << A0_DEST_NR_SHIFT) |				\
- 	    (REG_TYPE_##src0_type << A0_SRC0_TYPE_SHIFT) |		\
- 	    (src0_nr << 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_##src1_type << A1_SRC1_TYPE_SHIFT) |		\
- 	    (src1_nr << A1_SRC1_TYPE_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));			\
- } while (0)
- 
- static void
- I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
- 			 RegionPtr dstRegion,
- 			 short width, short height, int video_pitch,
- 			 int x1, int y1, int x2, int y2,
- 			 short src_w, short src_h, short drw_w, short drw_h,
- 			 DrawablePtr pDraw)
- {
-    I830Ptr pI830 = I830PTR(pScrn);
-    CARD32 format, ms3, s2;
-    BoxPtr pbox;
-    int nbox, dxo, dyo;
-    Bool planar;
- 
-    ErrorF("I915DisplayVideo: %dx%d (pitch %d)\n", width, height,
- 	  video_pitch);
- 
-    switch (id) {
-    case FOURCC_UYVY:
-    case FOURCC_YUY2:
-       planar = FALSE;
-       break;
-    case FOURCC_YV12:
-    case FOURCC_I420:
-       planar = TRUE;
-       break;
-    default:
-       ErrorF("Unknown format 0x%x\n", id);
-       planar = FALSE;
-       break;
-    }
- 
-    /* Tell the rotation code that we have stomped its invariant state by
-     * setting a high bit.  We don't use any invariant 3D state for video, so we
-     * don't have to worry about it ourselves.
-     */
-    *pI830->used3D |= 1 << 30;
- 
-    BEGIN_LP_RING(44);
- 
-    /* invarient state */
-    OUT_RING(MI_NOOP);
-    OUT_RING(STATE3D_ANTI_ALIASING |
- 	    LINE_CAP_WIDTH_MODIFY | LINE_CAP_WIDTH_1_0 |
- 	    LINE_WIDTH_MODIFY | LINE_WIDTH_1_0);
- 
-    OUT_RING(STATE3D_DFLT_DIFFUSE_CMD);
-    OUT_RING(0x00000000);
- 
-    OUT_RING(STATE3D_DFLT_SPEC_CMD);
-    OUT_RING(0x00000000);
- 
-    OUT_RING(STATE3D_DFLT_Z_CMD);
-    OUT_RING(0x00000000);
- 
-    OUT_RING(STATE3D_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(STATE3D_RASTERIZATION_RULES |
- 	    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(STATE3D_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(3) | 1);
-    OUT_RING(0x00000000); /* texture coordinate wrap */
- 
-    /* flush map & render cache */
-    OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE);
-    OUT_RING(0x00000000);
- 
-    /* draw rect -- just clipping */
-    OUT_RING(STATE3D_DRAWING_RECTANGLE);
-    OUT_RING(0x00000000);	/* flags */
-    OUT_RING(0x00000000);	/* ymin, xmin */
-    OUT_RING((pScrn->virtualX - 1) | (pScrn->virtualY - 1) << 16); /* ymax, xmax */
-    OUT_RING(0x00000000);	/* yorigin, xorigin */
-    OUT_RING(MI_NOOP);
- 
-    /* scissor */
-    OUT_RING(STATE3D_SCISSOR_ENABLE | DISABLE_SCISSOR_RECT);
-    OUT_RING(STATE3D_SCISSOR_RECTANGLE);
-    OUT_RING(0x00000000);	/* ymin, xmin */
-    OUT_RING(0x00000000);	/* ymax, xmax */
- 
-    OUT_RING(0x7c000003);	/* unknown command */
-    OUT_RING(0x7d070000);
-    OUT_RING(0x00000000);
-    OUT_RING(0x68000002);
- 
-    /* context setup */
-    OUT_RING(STATE3D_MODES_4 |
- 	    ENABLE_LOGIC_OP_FUNC | LOGIC_OP_FUNC(LOGICOP_COPY) |
- 	    ENABLE_STENCIL_WRITE_MASK | STENCIL_WRITE_MASK(0xff) |
- 	    ENABLE_STENCIL_TEST_MASK | STENCIL_TEST_MASK(0xff));
- 
-    OUT_RING(STATE3D_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) |
- 	    I1_LOAD_S(4) | I1_LOAD_S(5) | I1_LOAD_S(6) | 4);
-    s2 = S2_TEXCOORD_FMT(0, TEXCOORDFMT_2D);
-    if (planar)
-       s2 |= S2_TEXCOORD_FMT(1, TEXCOORDFMT_2D);
-    else
-       s2 |= S2_TEXCOORD_FMT(1, TEXCOORDFMT_NOT_PRESENT);
-    s2 |= 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(s2);
-    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(STATE3D_INDEPENDENT_ALPHA_BLEND |
- 	    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(STATE3D_CONST_BLEND_COLOR);
-    OUT_RING(0x00000000);
- 
-    OUT_RING(STATE3D_DEST_BUFFER_VARIABLES);
-    if (pI830->cpp == 2)
-       format = COLR_BUF_RGB565;
-    else
-       format = COLR_BUF_ARGB8888 | DEPTH_FRMT_24_FIXED_8_OTHER;
- 
-    OUT_RING(LOD_PRECLAMP_OGL |
-      DSTORG_HORIZ_BIAS(0x80) | DSTORG_VERT_BIAS(0x80) | format);
- 
-    OUT_RING(STATE3D_STIPPLE);
-    OUT_RING(0x00000000);
- 
-    /* front buffer, pitch, offset */
-    OUT_RING(STATE3D_BUFFER_INFO);
-    OUT_RING(BUFFERID_COLOR_BACK | BUFFER_USE_FENCES |
- 	    (((pI830->displayWidth * pI830->cpp) / 4) << 2));
-    OUT_RING(pI830->bufferOffset);
-    ADVANCE_LP_RING();
- 
-    if (!planar) {
-       BEGIN_LP_RING(20);
-       /* fragment program - texture blend replace. */
-       OUT_RING(STATE3D_PIXEL_SHADER_PROGRAM | 8);
-       OUT_DCL(S, 0);
-       OUT_DCL(T, 0);
-       OUT_TEXLD(OC, 0, 0, T, 0);
-       /* End fragment program */
- 
-       OUT_RING(STATE3D_SAMPLER_STATE | 3);
-       OUT_RING(0x00000001);
-       OUT_RING(SS2_COLORSPACE_CONVERSION |
- 	       (FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) |
- 	       (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT));
-       OUT_RING((TEXCOORDMODE_CLAMP_EDGE << SS3_TCX_ADDR_MODE_SHIFT) |
- 	       (TEXCOORDMODE_CLAMP_EDGE << SS3_TCY_ADDR_MODE_SHIFT));
-       OUT_RING(0x00000000);
- 
-       OUT_RING(STATE3D_MAP_STATE | 3);
-       OUT_RING(0x00000001);	/* texture map #1 */
-       OUT_RING(pPriv->YBuf0offset);
-       ms3 = MAPSURF_422;
-       switch (id) {
-       case FOURCC_YUY2:
- 	 ms3 |= MT_422_YCRCB_NORMAL;
- 	 break;
-       case FOURCC_UYVY:
- 	 ms3 |= MT_422_YCRCB_SWAPY;
- 	 break;
-       }
-       ms3 |= (height - 1) << MS3_HEIGHT_SHIFT;
-       ms3 |= (width - 1) << MS3_WIDTH_SHIFT;
-       if (!pI830->disableTiling)
- 	 ms3 |= MS3_USE_FENCE_REGS;
-       OUT_RING(ms3);
-       OUT_RING(((video_pitch / 4) - 1) << 21);
-       ADVANCE_LP_RING();
-    } else {
-       BEGIN_LP_RING(1 + 18 + (1 + 3*16) + 11 + 11);
-       OUT_RING(MI_NOOP);
-       /* For the planar formats, we set up three samplers -- one for each plane,
-        * in a Y8 format.  Because I couldn't get the special PLANAR_TO_PACKED
-        * shader setup to work, I did the manual pixel shader:
-        *
-        * y' = y - .0625
-        * u' = u - .5
-        * v' = v - .5;
-        *
-        * r = 1.1643 * y' + 0.0     * u' + 1.5958  * v'
-        * g = 1.1643 * y' - 0.39173 * u' - 0.81290 * v'
-        * b = 1.1643 * y' + 2.017   * u' + 0.0     * v'
-        *
-        * register assignment:
-        * r0 = (y',u',v',0)
-        * r1 = (y,y,y,y)
-        * r2 = (u,u,u,u)
-        * r3 = (v,v,v,v)
-        * OC = (r,g,b,1)
-        */
-       OUT_RING(STATE3D_PIXEL_SHADER_CONSTANTS | 16);
-       OUT_RING(0x000000f);	/* constants 0-3 */
-       /* constant 0: normalization offsets */
-       OUT_RING_F(-0.0625);
-       OUT_RING_F(-0.5);
-       OUT_RING_F(-0.5);
-       OUT_RING_F(0.0);
-       /* constant 1: r coefficients*/
-       OUT_RING_F(1.1643);
-       OUT_RING_F(0.0);
-       OUT_RING_F(1.5958);
-       OUT_RING_F(0.0);
-       /* constant 2: g coefficients */
-       OUT_RING_F(1.1643);
-       OUT_RING_F(-0.39173);
-       OUT_RING_F(-0.81290);
-       OUT_RING_F(0.0);
-       /* constant 3: b coefficients */
-       OUT_RING_F(1.1643);
-       OUT_RING_F(2.017);
-       OUT_RING_F(0.0);
-       OUT_RING_F(0.0);
- 
-       OUT_RING(STATE3D_PIXEL_SHADER_PROGRAM | (3 * 16 - 1));
-       /* Declare samplers */
-       OUT_DCL(S, 0);
-       OUT_DCL(S, 1);
-       OUT_DCL(S, 2);
-       OUT_DCL(T, 0);
-       OUT_DCL(T, 1);
- 
-       /* Load samplers to temporaries.  Y (sampler 0) gets the un-halved coords
-        * from t1.
-        */
-       OUT_TEXLD(R, 1, 0, T, 1);
-       OUT_TEXLD(R, 2, 1, T, 0);
-       OUT_TEXLD(R, 3, 2, T, 0);
- 
-       /* Move the sampled YUV data in R[123] to the first 3 channels of R0. */
-       OUT_MOV_TO_CHANNEL(R, 0, R, 1, X);
-       OUT_MOV_TO_CHANNEL(R, 0, R, 2, Y);
-       OUT_MOV_TO_CHANNEL(R, 0, R, 3, Z);
- 
-       /* Normalize the YUV data */
-       OUT_RING(A0_ADD | A0_DEST_CHANNEL_ALL |
- 	       (REG_TYPE_R << A0_DEST_TYPE_SHIFT) | (0 << A0_DEST_NR_SHIFT) |				\
- 	       (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_CONST << A1_SRC1_TYPE_SHIFT) | (0 << 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));
- 
-       /* dot-product the YUV data in R0 by the vectors of coefficients for
-        * calculating R, G, and B, storing the results in the R, G, or B channels
-        * of the output color.
-        */
-       OUT_DP3_TO_CHANNEL(OC, 0, R, 0, CONST, 1, X);
-       OUT_DP3_TO_CHANNEL(OC, 0, R, 0, CONST, 2, Y);
-       OUT_DP3_TO_CHANNEL(OC, 0, R, 0, CONST, 3, Z);
- 
-       /* Set alpha of the output to 1.0, by wiring W to 1 and not actually using
-        * the source.
-        */
-       OUT_RING(A0_MOV | A0_DEST_CHANNEL_W |
- 	       (REG_TYPE_OC << A0_DEST_TYPE_SHIFT) | (0 << A0_DEST_NR_SHIFT) |
- 	       (REG_TYPE_OC << 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_ONE << A1_SRC0_CHANNEL_W_SHIFT));
-       OUT_RING(0);
-       /* End fragment program */
- 
-       OUT_RING(STATE3D_SAMPLER_STATE | 9);
-       OUT_RING(0x00000007);
-       /* sampler 0 */
-       OUT_RING(0x00000000);
-       OUT_RING((FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) |
- 	       (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT));
-       OUT_RING((TEXCOORDMODE_CLAMP_EDGE << SS3_TCX_ADDR_MODE_SHIFT) |
- 	       (TEXCOORDMODE_CLAMP_EDGE << SS3_TCY_ADDR_MODE_SHIFT));
-       /* sampler 1 */
-       OUT_RING(0x00000000);
-       OUT_RING((FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) |
- 	       (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT));
-       OUT_RING((TEXCOORDMODE_CLAMP_EDGE << SS3_TCX_ADDR_MODE_SHIFT) |
- 	       (TEXCOORDMODE_CLAMP_EDGE << SS3_TCY_ADDR_MODE_SHIFT));
-       /* sampler 2 */
-       OUT_RING(0x00000000);
-       OUT_RING((FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) |
- 	       (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT));
-       OUT_RING((TEXCOORDMODE_CLAMP_EDGE << SS3_TCX_ADDR_MODE_SHIFT) |
- 	       (TEXCOORDMODE_CLAMP_EDGE << SS3_TCY_ADDR_MODE_SHIFT));
- 
-       OUT_RING(STATE3D_MAP_STATE | 9);
-       OUT_RING(0x00000007);
- 
-       OUT_RING(pPriv->YBuf0offset);
-       ms3 = MAPSURF_8BIT | MT_8BIT_I8;
-       ms3 |= (height - 1) << MS3_HEIGHT_SHIFT;
-       ms3 |= (width - 1) << MS3_WIDTH_SHIFT;
-       OUT_RING(ms3);
-       OUT_RING(((video_pitch * 2 / 4) - 1) << 21);
- 
-       OUT_RING(pPriv->UBuf0offset);
-       ms3 = MAPSURF_8BIT | MT_8BIT_I8;
-       ms3 |= (height / 2 - 1) << MS3_HEIGHT_SHIFT;
-       ms3 |= (width / 2 - 1) << MS3_WIDTH_SHIFT;
-       OUT_RING(ms3);
-       OUT_RING(((video_pitch / 4) - 1) << 21);
- 
-       OUT_RING(pPriv->VBuf0offset);
-       ms3 = MAPSURF_8BIT | MT_8BIT_I8;
-       ms3 |= (height / 2 - 1) << MS3_HEIGHT_SHIFT;
-       ms3 |= (width / 2 - 1) << MS3_WIDTH_SHIFT;
-       OUT_RING(ms3);
-       OUT_RING(((video_pitch / 4) - 1) << 21);
-       ADVANCE_LP_RING();
-    }
-    
-    {
-       BEGIN_LP_RING(2);
-       OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE);
-       OUT_RING(0x00000000);
-       ADVANCE_LP_RING();
-    }
- 
-    dxo = dstRegion->extents.x1;
-    dyo = dstRegion->extents.y1;
- 
-    pbox = REGION_RECTS(dstRegion);
-    nbox = REGION_NUM_RECTS(dstRegion);
-    while (nbox--)
-    {
-       int box_x1 = pbox->x1;
-       int box_y1 = pbox->y1;
-       int box_x2 = pbox->x2;
-       int box_y2 = pbox->y2;
-       int j;
-       float src_scale_x, src_scale_y;
-       CARD32 vb[40];
-       float verts[4][2], tex[4][2], tex2[4][2];
-       int vert_data_count;
- 
-       pbox++;
- 
-       src_scale_x = (float)src_w / (float)drw_w;
-       src_scale_y  = (float)src_h / (float)drw_h;
- 
-       if (!planar)
- 	 vert_data_count = 32;
-       else
- 	 vert_data_count = 40;
- 
-       BEGIN_LP_RING(vert_data_count + 8);
-       OUT_RING(MI_NOOP);
-       OUT_RING(MI_NOOP);
-       OUT_RING(MI_NOOP);
-       OUT_RING(MI_NOOP);
-       OUT_RING(MI_NOOP);
-       OUT_RING(MI_NOOP);
-       OUT_RING(MI_NOOP);
- 
-       /* vertex data */
-       OUT_RING(PRIMITIVE3D | PRIM3D_INLINE | PRIM3D_TRIFAN |
- 	       (vert_data_count - 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;
-       verts[3][0] = box_x1; verts[3][1] = box_y2;
- 
-       if (!planar) {
- 	 tex[0][0] = (box_x1 - dxo) * src_scale_x;
- 	 tex[0][1] = (box_y1 - dyo) * src_scale_y;
- 	 tex[1][0] = (box_x2 - dxo) * src_scale_x;
- 	 tex[1][1] = (box_y1 - dyo) * src_scale_y;
- 	 tex[2][0] = (box_x2 - dxo) * src_scale_x;
- 	 tex[2][1] = (box_y2 - dyo) * src_scale_y;
- 	 tex[3][0] = (box_x1 - dxo) * src_scale_x;
- 	 tex[3][1] = (box_y2 - dyo) * src_scale_y;
- 	 /* emit vertex buffer */
- 	 draw_poly(vb, verts, tex, NULL);
- 	 for (j = 0; j < vert_data_count; j++)
- 	    OUT_RING(vb[j]);
-       } else {
- 	 tex[0][0] = (box_x1 - dxo) * src_scale_x / 2.0;
- 	 tex[0][1] = (box_y1 - dyo) * src_scale_y / 2.0;
- 	 tex[1][0] = (box_x2 - dxo) * src_scale_x / 2.0;
- 	 tex[1][1] = (box_y1 - dyo) * src_scale_y / 2.0;
- 	 tex[2][0] = (box_x2 - dxo) * src_scale_x / 2.0;
- 	 tex[2][1] = (box_y2 - dyo) * src_scale_y / 2.0;
- 	 tex[3][0] = (box_x1 - dxo) * src_scale_x / 2.0;
- 	 tex[3][1] = (box_y2 - dyo) * src_scale_y / 2.0;
- 	 tex2[0][0] = (box_x1 - dxo) * src_scale_x;
- 	 tex2[0][1] = (box_y1 - dyo) * src_scale_y;
- 	 tex2[1][0] = (box_x2 - dxo) * src_scale_x;
- 	 tex2[1][1] = (box_y1 - dyo) * src_scale_y;
- 	 tex2[2][0] = (box_x2 - dxo) * src_scale_x;
- 	 tex2[2][1] = (box_y2 - dyo) * src_scale_y;
- 	 tex2[3][0] = (box_x1 - dxo) * src_scale_x;
- 	 tex2[3][1] = (box_y2 - dyo) * src_scale_y;
- 	 /* emit vertex buffer */
- 	 draw_poly(vb, verts, tex, tex2);
- 	 for (j = 0; j < vert_data_count; j++)
- 	    OUT_RING(vb[j]);
-       }
- 
-       ADVANCE_LP_RING();
-    }
- 
-    if (pI830->AccelInfoRec)
-       pI830->AccelInfoRec->NeedToSync = TRUE;
- }
- 
 +static const CARD32 sip_kernel_static[][4] = {
 +/*    wait (1) a0<1>UW a145<0,1,0>UW { align1 +  } */
 +    { 0x00000030, 0x20000108, 0x00001220, 0x00000000 },
 +/*    nop (4) g0<1>UD { align1 +  } */
 +    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
 +/*    nop (4) g0<1>UD { align1 +  } */
 +    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
 +/*    nop (4) g0<1>UD { align1 +  } */
 +    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
 +/*    nop (4) g0<1>UD { align1 +  } */
 +    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
 +/*    nop (4) g0<1>UD { align1 +  } */
 +    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
 +/*    nop (4) g0<1>UD { align1 +  } */
 +    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
 +/*    nop (4) g0<1>UD { align1 +  } */
 +    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
 +/*    nop (4) g0<1>UD { align1 +  } */
 +    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
 +/*    nop (4) g0<1>UD { align1 +  } */
 +    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
 +};
 +   
 +/*
 + * this program computes dA/dx and dA/dy for the texture coordinates along
 + * with the base texture coordinate. It was extracted from the Mesa driver.
 + * It uses about 10 GRF registers.
 + */
 +
 +#define SF_KERNEL_NUM_GRF  16
 +#define SF_MAX_THREADS	   1
 +
 +static const CARD32 sf_kernel_static[][4] = {
 +/*    send   0 (1) g6<1>F g1.12<0,1,0>F math mlen 1 rlen 1 { align1 +  } */
 +   { 0x00000031, 0x20c01fbd, 0x0000002c, 0x01110081 },
 +/*    send   0 (1) g6.4<1>F g1.20<0,1,0>F math mlen 1 rlen 1 { align1 +  } */
 +   { 0x00000031, 0x20c41fbd, 0x00000034, 0x01110081 },
 +/*    add (8) g7<1>F g4<8,8,1>F g3<8,8,1>F { align1 +  } */
 +   { 0x00600040, 0x20e077bd, 0x008d0080, 0x008d4060 },
 +/*    mul (1) g7<1>F g7<0,1,0>F g6<0,1,0>F { align1 +  } */
 +   { 0x00000041, 0x20e077bd, 0x000000e0, 0x000000c0 },
 +/*    mul (1) g7.4<1>F g7.4<0,1,0>F g6.4<0,1,0>F { align1 +  } */
 +   { 0x00000041, 0x20e477bd, 0x000000e4, 0x000000c4 },
 +/*    mov (8) m1<1>F g7<0,1,0>F { align1 +  } */
 +   { 0x00600001, 0x202003be, 0x000000e0, 0x00000000 },
 +/*    mov (8) m2<1>F g7.4<0,1,0>F { align1 +  } */
 +   { 0x00600001, 0x204003be, 0x000000e4, 0x00000000 },
 +/*    mov (8) m3<1>F g3<8,8,1>F { align1 +  } */
 +   { 0x00600001, 0x206003be, 0x008d0060, 0x00000000 },
 +/*    send   0 (8) a0<1>F g0<8,8,1>F urb mlen 4 rlen 0 write +0 transpose used complete EOT{ align1 +  } */
 +   { 0x00600031, 0x20001fbc, 0x008d0000, 0x8640c800 },
 +/*    nop (4) g0<1>UD { align1 +  } */
 +   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
 +/*    nop (4) g0<1>UD { align1 +  } */
 +   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
 +/*    nop (4) g0<1>UD { align1 +  } */
 +   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
 +/*    nop (4) g0<1>UD { align1 +  } */
 +   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
 +/*    nop (4) g0<1>UD { align1 +  } */
 +   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
 +/*    nop (4) g0<1>UD { align1 +  } */
 +   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
 +/*    nop (4) g0<1>UD { align1 +  } */
 +   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
 +/*    nop (4) g0<1>UD { align1 +  } */
 +   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
 +};
 +
 +/*
 + * Ok, this kernel picks up the required data flow values in g0 and g1
 + * and passes those along in m0 and m1. In m2-m9, it sticks constant
 + * values (bright pink).
 + */
 +
 +/* Our PS kernel uses less than 32 GRF registers (about 20) */
 +#define PS_KERNEL_NUM_GRF   32
 +#define PS_MAX_THREADS	   32
 +
 +#define BRW_GRF_BLOCKS(nreg)	((nreg + 15) / 16 - 1)
 +
 +static const CARD32 ps_kernel_static[][4] = {
 +#include "wm_prog.h"
 +};
 +
 +#define ALIGN(i,m)    (((i) + (m) - 1) & ~((m) - 1))
 +#define MIN(a,b) ((a) < (b) ? (a) : (b))
 +
 +#define WM_BINDING_TABLE_ENTRIES    2
 +
 +static CARD32 float_to_uint (float f) {
 +   union {CARD32 i; float f;} x;
 +   x.f = f;
 +   return x.i;
 +}
 +
 +static struct {
 +   CARD32   svg_ctl;
 +   char	    *name;
 +} svg_ctl_bits[] = {
 +   { BRW_SVG_CTL_GS_BA, "General State Base Address" },
 +   { BRW_SVG_CTL_SS_BA, "Surface State Base Address" },
 +   { BRW_SVG_CTL_IO_BA, "Indirect Object Base Address" },
 +   { BRW_SVG_CTL_GS_AUB, "Generate State Access Upper Bound" },
 +   { BRW_SVG_CTL_IO_AUB, "Indirect Object Access Upper Bound" },
 +   { BRW_SVG_CTL_SIP, "System Instruction Pointer" },
 +   { 0, 0 },
 +};
 +
 +static void
 +brw_debug (ScrnInfoPtr pScrn, char *when)
 +{
 +   I830Ptr pI830 = I830PTR(pScrn);
 +   int	    i;
 +   CARD32   v;
 +   
 +   I830Sync (pScrn);
 +   ErrorF("brw_debug: %s\n", when);
 +   for (i = 0; svg_ctl_bits[i].name; i++) {
 +      OUTREG(BRW_SVG_CTL, svg_ctl_bits[i].svg_ctl);
 +      v = INREG(BRW_SVG_RDATA);
 +      ErrorF("\t%34.34s: 0x%08x\n", svg_ctl_bits[i].name, v);
 +   }
 +}
 +
 +#define WATCH_SF 0
 +#define WATCH_WIZ 0
 +#define WATCH_STATS 0
 +
 +static void
 +BroadwaterDisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
 +			       RegionPtr dstRegion,
 +			       short width, short height, int video_pitch,
 +			       int x1, int y1, int x2, int y2,
 +			       short src_w, short src_h,
 +			       short drw_w, short drw_h,
 +			       DrawablePtr pDraw)
 +{
 +   I830Ptr pI830 = I830PTR(pScrn);
 +   CARD32 format, ms3, s2;
 +   BoxPtr pbox;
 +   int nbox, dxo, dyo;
 +   Bool planar;
 +   int urb_vs_start, urb_vs_size;
 +   int urb_gs_start, urb_gs_size;
 +   int urb_clip_start, urb_clip_size;
 +   int urb_sf_start, urb_sf_size;
 +   int urb_cs_start, urb_cs_size;
 +   struct brw_surface_state *dest_surf_state;
 +   struct brw_surface_state *src_surf_state;
 +   struct brw_sampler_state *src_sampler_state;
 +   struct brw_vs_unit_state *vs_state;
 +   struct brw_sf_unit_state *sf_state;
 +   struct brw_wm_unit_state *wm_state;
 +   struct brw_cc_unit_state *cc_state;
 +   struct brw_cc_viewport *cc_viewport;
 +   struct brw_instruction *sf_kernel;
 +   struct brw_instruction *ps_kernel;
 +   struct brw_instruction *sip_kernel;
 +   float *vb;
 +    CARD32 *binding_table;
 +   Bool first_output = TRUE;
 +   int dest_surf_offset, src_surf_offset, src_sampler_offset, vs_offset;
 +   int sf_offset, wm_offset, cc_offset, vb_offset, cc_viewport_offset;
 +   int wm_scratch_offset;
 +   int sf_kernel_offset, ps_kernel_offset, sip_kernel_offset;
 +   int binding_table_offset;
 +   int next_offset, total_state_size;
 +   int vb_size = (4 * 4) * 4; /* 4 DWORDS per vertex */
 +   char *state_base;
 +   int state_base_offset;
 +
 +#if 0
 +   ErrorF("BroadwaterDisplayVideoTextured: %dx%d (pitch %d)\n", width, height,
 +	  video_pitch);
 +#endif
 +
 +   /* enable debug */
 +   OUTREG (INST_PM,
 +	   (1 << (16 + 4)) |
 +	   (1 << 4));
 +#if 0
 +   ErrorF ("INST_PM 0x%08x\n", INREG(INST_PM));
 +#endif
 +   
 +   assert((id == FOURCC_UYVY) || (id == FOURCC_YUY2));
 +
 +   /* Tell the rotation code that we have stomped its invariant state by
 +    * setting a high bit.  We don't use any invariant 3D state for video, so we
 +    * don't have to worry about it ourselves.
 +    */
 +   *pI830->used3D |= 1 << 30;
 +
 +   next_offset = 0;
 +
 +   /* Set up our layout of state in framebuffer.  First the general state: */
 +   vs_offset = ALIGN(next_offset, 64);
 +   next_offset = vs_offset + sizeof(*vs_state);
 +   sf_offset = ALIGN(next_offset, 32);
 +   next_offset = sf_offset + sizeof(*sf_state);
 +   wm_offset = ALIGN(next_offset, 32);
 +   next_offset = wm_offset + sizeof(*wm_state);
 +   wm_scratch_offset = ALIGN(next_offset, 1024);
 +   next_offset = wm_scratch_offset + 1024 * PS_MAX_THREADS;
 +   cc_offset = ALIGN(next_offset, 32);
 +   next_offset = cc_offset + sizeof(*cc_state);
 +
 +   sf_kernel_offset = ALIGN(next_offset, 64);
 +   next_offset = sf_kernel_offset + sizeof (sf_kernel_static);
 +   ps_kernel_offset = ALIGN(next_offset, 64);
 +   next_offset = ps_kernel_offset + sizeof (ps_kernel_static);
 +   sip_kernel_offset = ALIGN(next_offset, 64);
 +   next_offset = sip_kernel_offset + sizeof (sip_kernel_static);
 +   cc_viewport_offset = ALIGN(next_offset, 32);
 +   next_offset = cc_viewport_offset + sizeof(*cc_viewport);
 +
 +   src_sampler_offset = ALIGN(next_offset, 32);
 +   next_offset = src_sampler_offset + sizeof(*src_sampler_state);
 +
 +   /* Align VB to native size of elements, for safety */
 +   vb_offset = ALIGN(next_offset, 8);
 +   next_offset = vb_offset + vb_size;
 +
 +   /* And then the general state: */
 +   dest_surf_offset = ALIGN(next_offset, 32);
 +   next_offset = dest_surf_offset + sizeof(*dest_surf_state);
 +   src_surf_offset = ALIGN(next_offset, 32);
 +   next_offset = src_surf_offset + sizeof(*src_surf_state);
 +   binding_table_offset = ALIGN(next_offset, 32);
 +   next_offset = binding_table_offset + (WM_BINDING_TABLE_ENTRIES * 4);
 +
 +   /* Allocate an area in framebuffer for our state layout we just set up */
 +   total_state_size = next_offset;
 +   assert (total_state_size < BRW_LINEAR_EXTRA);
 +
 +   /*
 +    * Use the extra space allocated at the end of the Xv buffer
 +    */
 +   state_base_offset = (pPriv->YBuf0offset + 
 +			pPriv->linear->size * pI830->cpp -
 +			BRW_LINEAR_EXTRA);
 +   state_base_offset = ALIGN(state_base_offset, 64);
 +
 +   state_base = (char *)(pI830->FbBase + state_base_offset);
 +   /* Set up our pointers to state structures in framebuffer.  It would probably
 +    * be a good idea to fill these structures out in system memory and then dump
 +    * them there, instead.
 +    */
 +   vs_state = (void *)(state_base + vs_offset);
 +   sf_state = (void *)(state_base + sf_offset);
 +   wm_state = (void *)(state_base + wm_offset);
 +   cc_state = (void *)(state_base + cc_offset);
 +   sf_kernel = (void *)(state_base + sf_kernel_offset);
 +   ps_kernel = (void *)(state_base + ps_kernel_offset);
 +   sip_kernel = (void *)(state_base + sip_kernel_offset);
 +   
 +   cc_viewport = (void *)(state_base + cc_viewport_offset);
 +   dest_surf_state = (void *)(state_base + dest_surf_offset);
 +   src_surf_state = (void *)(state_base + src_surf_offset);
 +   src_sampler_state = (void *)(state_base + src_sampler_offset);
 +   binding_table = (void *)(state_base + binding_table_offset);
 +   vb = (void *)(state_base + vb_offset);
 +
 +   /* For 3D, the VS must have 8, 12, 16, 24, or 32 VUEs allocated to it.
 +    * A VUE consists of a 256-bit vertex header followed by the vertex data,
 +    * which in our case is 4 floats (128 bits), thus a single 512-bit URB
 +    * entry.
 +    */
 +#define URB_VS_ENTRIES	      8
 +#define URB_VS_ENTRY_SIZE     1
 +   
 +#define URB_GS_ENTRIES	      0
 +#define URB_GS_ENTRY_SIZE     0
 +   
 +#define URB_CLIP_ENTRIES      0
 +#define URB_CLIP_ENTRY_SIZE   0
 +   
 +   /* The SF kernel we use outputs only 4 256-bit registers, leading to an
 +    * entry size of 2 512-bit URBs.  We don't need to have many entries to
 +    * output as we're generally working on large rectangles and don't care
 +    * about having WM threads running on different rectangles simultaneously.
 +    */
 +#define URB_SF_ENTRIES	      1
 +#define URB_SF_ENTRY_SIZE     2
 +
 +#define URB_CS_ENTRIES	      0
 +#define URB_CS_ENTRY_SIZE     0
 +   
 +   urb_vs_start = 0;
 +   urb_vs_size = URB_VS_ENTRIES * URB_VS_ENTRY_SIZE;
 +   urb_gs_start = urb_vs_start + urb_vs_size;
 +   urb_gs_size = URB_GS_ENTRIES * URB_GS_ENTRY_SIZE;
 +   urb_clip_start = urb_gs_start + urb_gs_size;
 +   urb_clip_size = URB_CLIP_ENTRIES * URB_CLIP_ENTRY_SIZE;
 +   urb_sf_start = urb_clip_start + urb_clip_size;
 +   urb_sf_size = URB_SF_ENTRIES * URB_SF_ENTRY_SIZE;
 +   urb_cs_start = urb_sf_start + urb_sf_size;
 +   urb_cs_size = URB_CS_ENTRIES * URB_CS_ENTRY_SIZE;
 +
 +   /* We'll be poking the state buffers that could be in use by the 3d hardware
 +    * here, but we should have synced the 3D engine already in I830PutImage.
 +    */
 +
 +   memset (cc_viewport, 0, sizeof (*cc_viewport));
 +   cc_viewport->min_depth = -1.e35;
 +   cc_viewport->max_depth = 1.e35;
 +
 +   /* Color calculator state */
 +   memset(cc_state, 0, sizeof(*cc_state));
 +   cc_state->cc0.stencil_enable = 0;   /* disable stencil */
 +   cc_state->cc2.depth_test = 0;       /* disable depth test */
 +   cc_state->cc2.logicop_enable = 1;   /* enable logic op */
 +   cc_state->cc3.ia_blend_enable = 1;  /* blend alpha just like colors */
 +   cc_state->cc3.blend_enable = 0;     /* disable color blend */
 +   cc_state->cc3.alpha_test = 0;       /* disable alpha test */
 +   cc_state->cc4.cc_viewport_state_offset = (state_base_offset + cc_viewport_offset) >> 5;
 +   cc_state->cc5.dither_enable = 0;    /* disable dither */
 +   cc_state->cc5.logicop_func = 0xc;   /* WHITE */
 +   cc_state->cc5.statistics_enable = 1;
 +   cc_state->cc5.ia_blend_function = BRW_BLENDFUNCTION_ADD;
 +   cc_state->cc5.ia_src_blend_factor = BRW_BLENDFACTOR_ONE;
 +   cc_state->cc5.ia_dest_blend_factor = BRW_BLENDFACTOR_ONE;
 +
 +   /* Upload system kernel */
 +   memcpy (sip_kernel, sip_kernel_static, sizeof (sip_kernel_static));
 +   
 +   /* Set up the state buffer for the destination surface */
 +   memset(dest_surf_state, 0, sizeof(*dest_surf_state));
 +   dest_surf_state->ss0.surface_type = BRW_SURFACE_2D;
 +   dest_surf_state->ss0.data_return_format = BRW_SURFACERETURNFORMAT_FLOAT32;
 +   if (pI830->cpp == 2) {
 +      dest_surf_state->ss0.surface_format = BRW_SURFACEFORMAT_B5G6R5_UNORM;
 +   } else {
 +      dest_surf_state->ss0.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
 +   }
 +   dest_surf_state->ss0.writedisable_alpha = 0;
 +   dest_surf_state->ss0.writedisable_red = 0;
 +   dest_surf_state->ss0.writedisable_green = 0;
 +   dest_surf_state->ss0.writedisable_blue = 0;
 +   dest_surf_state->ss0.color_blend = 1;
 +   dest_surf_state->ss0.vert_line_stride = 0;
 +   dest_surf_state->ss0.vert_line_stride_ofs = 0;
 +   dest_surf_state->ss0.mipmap_layout_mode = 0;
 +   dest_surf_state->ss0.render_cache_read_mode = 0;
 +   
 +   dest_surf_state->ss1.base_addr = pI830->FrontBuffer.Start;
 +   dest_surf_state->ss2.height = pScrn->virtualY - 1;
 +   dest_surf_state->ss2.width = pScrn->virtualX - 1;
 +   dest_surf_state->ss2.mip_count = 0;
 +   dest_surf_state->ss2.render_target_rotation = 0;
 +   dest_surf_state->ss3.pitch = (pI830->displayWidth * pI830->cpp) - 1;
 +
 +   /* Set up the source surface state buffer */
 +   memset(src_surf_state, 0, sizeof(*src_surf_state));
 +   src_surf_state->ss0.surface_type = BRW_SURFACE_2D;
 +/*   src_surf_state->ss0.data_return_format = BRW_SURFACERETURNFORMAT_FLOAT32; */
 +   switch (id) {
 +   case FOURCC_YUY2:
 +      src_surf_state->ss0.surface_format = BRW_SURFACEFORMAT_YCRCB_NORMAL;
 +      break;
 +   case FOURCC_UYVY:
 +      src_surf_state->ss0.surface_format = BRW_SURFACEFORMAT_YCRCB_SWAPY;
 +      break;
 +   }
 +   src_surf_state->ss0.writedisable_alpha = 0;
 +   src_surf_state->ss0.writedisable_red = 0;
 +   src_surf_state->ss0.writedisable_green = 0;
 +   src_surf_state->ss0.writedisable_blue = 0;
 +   src_surf_state->ss0.color_blend = 1;
 +   src_surf_state->ss0.vert_line_stride = 0;
 +   src_surf_state->ss0.vert_line_stride_ofs = 0;
 +   src_surf_state->ss0.mipmap_layout_mode = 0;
 +   src_surf_state->ss0.render_cache_read_mode = 0;
 +   
 +   src_surf_state->ss1.base_addr = pPriv->YBuf0offset;
 +   src_surf_state->ss2.width = width - 1;
 +   src_surf_state->ss2.height = height - 1;
 +   src_surf_state->ss2.mip_count = 0;
 +   src_surf_state->ss2.render_target_rotation = 0;
 +   src_surf_state->ss3.pitch = video_pitch - 1;
 +
 +   /* Set up a binding table for our two surfaces.  Only the PS will use it */
 +   /* XXX: are these offset from the right place? */
 +   binding_table[0] = state_base_offset + dest_surf_offset;
 +   binding_table[1] = state_base_offset + src_surf_offset;
 +
 +   /* Set up the packed YUV source sampler.  Doesn't do colorspace conversion.
 +    */
 +   memset(src_sampler_state, 0, sizeof(*src_sampler_state));
 +   src_sampler_state->ss0.min_filter = BRW_MAPFILTER_LINEAR;
 +   src_sampler_state->ss0.mag_filter = BRW_MAPFILTER_LINEAR;
 +   src_sampler_state->ss1.r_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
 +   src_sampler_state->ss1.s_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
 +   src_sampler_state->ss1.t_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
 +
 +   /* Set up the vertex shader to be disabled (passthrough) */
 +   memset(vs_state, 0, sizeof(*vs_state));
 +   vs_state->thread4.nr_urb_entries = URB_VS_ENTRIES;
 +   vs_state->thread4.urb_entry_allocation_size = URB_VS_ENTRY_SIZE - 1;
 +   vs_state->vs6.vs_enable = 0;
 +   vs_state->vs6.vert_cache_disable = 1;
 +
 +   /* Set up the SF kernel to do coord interp: for each attribute,
 +    * calculate dA/dx and dA/dy.  Hand these interpolation coefficients
 +    * back to SF which then hands pixels off to WM.
 +    */
 +
 +   memcpy (sf_kernel, sf_kernel_static, sizeof (sf_kernel_static));
 +   memset(sf_state, 0, sizeof(*sf_state));
 +#if 0
 +   ErrorF ("sf kernel: 0x%08x\n", state_base_offset + sf_kernel_offset);
 +#endif
 +   sf_state->thread0.kernel_start_pointer = 
 +	       (state_base_offset + sf_kernel_offset) >> 6;
 +   sf_state->thread0.grf_reg_count = BRW_GRF_BLOCKS(SF_KERNEL_NUM_GRF);
 +   sf_state->sf1.single_program_flow = 1; /* XXX */
 +   sf_state->sf1.binding_table_entry_count = 0;
 +   sf_state->sf1.thread_priority = 0;
 +   sf_state->sf1.floating_point_mode = 0; /* Mesa does this */
 +   sf_state->sf1.illegal_op_exception_enable = 1;
 +   sf_state->sf1.mask_stack_exception_enable = 1;
 +   sf_state->sf1.sw_exception_enable = 1;
 +   sf_state->thread2.per_thread_scratch_space = 0;
 +   sf_state->thread2.scratch_space_base_pointer = 0; /* not used in our kernel */
 +   sf_state->thread3.const_urb_entry_read_length = 0; /* no const URBs */
 +   sf_state->thread3.const_urb_entry_read_offset = 0; /* no const URBs */
 +   sf_state->thread3.urb_entry_read_length = 1; /* 1 URB per vertex */
 +   sf_state->thread3.urb_entry_read_offset = 0;
 +   sf_state->thread3.dispatch_grf_start_reg = 3;
 +   sf_state->thread4.max_threads = SF_MAX_THREADS - 1;
 +   sf_state->thread4.urb_entry_allocation_size = URB_SF_ENTRY_SIZE - 1;
 +   sf_state->thread4.nr_urb_entries = URB_SF_ENTRIES;
 +   sf_state->thread4.stats_enable = 1;
 +   sf_state->sf5.viewport_transform = FALSE; /* skip viewport */
 +   sf_state->sf6.cull_mode = BRW_CULLMODE_NONE;
 +   sf_state->sf6.scissor = 0;
 +   sf_state->sf7.trifan_pv = 2;
 +   sf_state->sf6.dest_org_vbias = 0x8;
 +   sf_state->sf6.dest_org_hbias = 0x8;
 +
 +   memcpy (ps_kernel, ps_kernel_static, sizeof (ps_kernel_static));
 +#if 0
 +   ErrorF ("ps kernel: 0x%08x\n", state_base_offset + ps_kernel_offset);
 +#endif
 +   memset (wm_state, 0, sizeof (*wm_state));
 +   wm_state->thread0.kernel_start_pointer = 
 +	    (state_base_offset + ps_kernel_offset) >> 6;
 +   wm_state->thread0.grf_reg_count = BRW_GRF_BLOCKS(PS_KERNEL_NUM_GRF);
 +   wm_state->thread1.single_program_flow = 1; /* XXX */
 +   wm_state->thread1.binding_table_entry_count = 2;
 +   /* Though we never use the scratch space in our WM kernel, it has to be
 +    * set, and the minimum allocation is 1024 bytes.
 +    */
 +   wm_state->thread2.scratch_space_base_pointer = (state_base_offset +
 +						   wm_scratch_offset) >> 10;
 +   wm_state->thread2.per_thread_scratch_space = 0; /* 1024 bytes */
 +   wm_state->thread3.dispatch_grf_start_reg = 3; /* XXX */
 +   wm_state->thread3.const_urb_entry_read_length = 0;
 +   wm_state->thread3.const_urb_entry_read_offset = 0;
 +   wm_state->thread3.urb_entry_read_length = 1; /* XXX */
 +   wm_state->thread3.urb_entry_read_offset = 0; /* XXX */
 +   wm_state->wm4.stats_enable = 1;
 +   wm_state->wm4.sampler_state_pointer = (state_base_offset + src_sampler_offset) >> 5;
 +   wm_state->wm4.sampler_count = 1; /* 1-4 samplers used */
 +   wm_state->wm5.max_threads = PS_MAX_THREADS - 1;
 +   wm_state->wm5.thread_dispatch_enable = 1;
 +   wm_state->wm5.enable_16_pix = 1;
 +   wm_state->wm5.enable_8_pix = 0;
 +   wm_state->wm5.early_depth_test = 1;
 +
 +   {
 +      BEGIN_LP_RING(2);
 +      OUT_RING(MI_FLUSH | 
 +	       MI_STATE_INSTRUCTION_CACHE_FLUSH |
 +	       BRW_MI_GLOBAL_SNAPSHOT_RESET);
 +      OUT_RING(MI_NOOP);
 +      ADVANCE_LP_RING();
 +   }
 +   
 +/*    brw_debug (pScrn, "before base address modify"); */
 +   { BEGIN_LP_RING(12);
 +   /* Match Mesa driver setup */
 +   OUT_RING(BRW_PIPELINE_SELECT | PIPELINE_SELECT_3D);
 +
 +   /* Mesa does this. Who knows... */
 +   OUT_RING(BRW_CS_URB_STATE | 0);
 +   OUT_RING((0 << 4) |	/* URB Entry Allocation Size */
 +	    (0 << 0));	/* Number of URB Entries */
 +   
 +   /* Zero out the two base address registers so all offsets are absolute */
 +   OUT_RING(BRW_STATE_BASE_ADDRESS | 4);
 +   OUT_RING(0 | BASE_ADDRESS_MODIFY);  /* Generate state base address */
 +   OUT_RING(0 | BASE_ADDRESS_MODIFY);  /* Surface state base address */
 +   OUT_RING(0 | BASE_ADDRESS_MODIFY);  /* media base addr, don't care */
 +   OUT_RING(0x10000000 | BASE_ADDRESS_MODIFY);  /* general state max addr, disabled */
 +   OUT_RING(0x10000000 | BASE_ADDRESS_MODIFY);  /* media object state max addr, disabled */
 +
 +   /* Set system instruction pointer */
 +   OUT_RING(BRW_STATE_SIP | 0);
 +   OUT_RING(state_base_offset + sip_kernel_offset); /* system instruction pointer */
 +      
 +   OUT_RING(MI_NOOP);
 +   ADVANCE_LP_RING(); }
 +   
 +/*   brw_debug (pScrn, "after base address modify"); */
 +
 +   { BEGIN_LP_RING(42);
 +   /* Enable VF statistics */
 +   OUT_RING(BRW_3DSTATE_VF_STATISTICS | 1);
 +   
 +   /* Pipe control */
 +   OUT_RING(BRW_PIPE_CONTROL |
 +	    BRW_PIPE_CONTROL_NOWRITE |
 +	    BRW_PIPE_CONTROL_IS_FLUSH |
 +	    2);
 +   OUT_RING(0);			       /* Destination address */
 +   OUT_RING(0);			       /* Immediate data low DW */
 +   OUT_RING(0);			       /* Immediate data high DW */
 +
 +   /* Binding table pointers */
 +   OUT_RING(BRW_3DSTATE_BINDING_TABLE_POINTERS | 4);
 +   OUT_RING(0); /* vs */
 +   OUT_RING(0); /* gs */
 +   OUT_RING(0); /* clip */
 +   OUT_RING(0); /* sf */
 +   /* Only the PS uses the binding table */
 +   OUT_RING(state_base_offset + binding_table_offset); /* ps */
 +   
 +   /* Blend constant color (magenta is fun) */
 +   OUT_RING(BRW_3DSTATE_CONSTANT_COLOR | 3);
 +   OUT_RING(float_to_uint (1.0));
 +   OUT_RING(float_to_uint (0.0));
 +   OUT_RING(float_to_uint (1.0));
 +   OUT_RING(float_to_uint (1.0));
 +   
 +   /* The drawing rectangle clipping is always on.  Set it to values that
 +    * shouldn't do any clipping.
 +    */
 +   OUT_RING(BRW_3DSTATE_DRAWING_RECTANGLE | 2);	/* XXX 3 for BLC or CTG */
 +   OUT_RING(0x00000000);	/* ymin, xmin */
 +   OUT_RING((pScrn->virtualX - 1) |
 +	    (pScrn->virtualY - 1) << 16); /* ymax, xmax */
 +   OUT_RING(0x00000000);	/* yorigin, xorigin */
 +
 +   /* skip the depth buffer */
 +   /* skip the polygon stipple */
 +   /* skip the polygon stipple offset */
 +   /* skip the line stipple */
 +   
 +   /* Set the pointers to the 3d pipeline state */
 +   OUT_RING(BRW_3DSTATE_PIPELINED_POINTERS | 5);
 +   OUT_RING(state_base_offset + vs_offset);  /* 32 byte aligned */
 +   OUT_RING(BRW_GS_DISABLE);		     /* disable GS, resulting in passthrough */
 +   OUT_RING(BRW_CLIP_DISABLE);		     /* disable CLIP, resulting in passthrough */
 +   OUT_RING(state_base_offset + sf_offset);  /* 32 byte aligned */
 +   OUT_RING(state_base_offset + wm_offset);  /* 32 byte aligned */
 +   OUT_RING(state_base_offset + cc_offset);  /* 64 byte aligned */
 +
 +   /* URB fence */
 +   OUT_RING(BRW_URB_FENCE |
 +	    UF0_CS_REALLOC |
 +	    UF0_SF_REALLOC |
 +	    UF0_CLIP_REALLOC |
 +	    UF0_GS_REALLOC |
 +	    UF0_VS_REALLOC |
 +	    1);
 +   OUT_RING(((urb_clip_start + urb_clip_size) << UF1_CLIP_FENCE_SHIFT) |
 +	    ((urb_gs_start + urb_gs_size) << UF1_GS_FENCE_SHIFT) |
 +	    ((urb_vs_start + urb_vs_size) << UF1_VS_FENCE_SHIFT));
 +   OUT_RING(((urb_cs_start + urb_cs_size) << UF2_CS_FENCE_SHIFT) |
 +	    ((urb_sf_start + urb_sf_size) << UF2_SF_FENCE_SHIFT));
 +
 +   /* Constant buffer state */
 +   OUT_RING(BRW_CS_URB_STATE | 0);
 +   OUT_RING(((URB_CS_ENTRY_SIZE - 1) << 4) | /* URB Entry Allocation Size */
 +	    (URB_CS_ENTRIES << 0));	     /* Number of URB Entries */
 +   
 +   /* Set up the pointer to our vertex buffer */
 +   OUT_RING(BRW_3DSTATE_VERTEX_BUFFERS | 2);
 +   OUT_RING((0 << VB0_BUFFER_INDEX_SHIFT) |
 +	    VB0_VERTEXDATA |
 +	    ((4 * 4) << VB0_BUFFER_PITCH_SHIFT)); /* four 32-bit floats per vertex */
 +   OUT_RING(state_base_offset + vb_offset);
 +   OUT_RING(3); /* four corners to our rectangle */
 +
 +   /* Set up our vertex elements, sourced from the single vertex buffer. */
 +   OUT_RING(BRW_3DSTATE_VERTEX_ELEMENTS | 3);
 +   /* offset 0: X,Y -> {X, Y, 1.0, 1.0} */
 +   OUT_RING((0 << VE0_VERTEX_BUFFER_INDEX_SHIFT) |
 +	    VE0_VALID |
 +	    (BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) |
 +	    (0 << VE0_OFFSET_SHIFT));
 +   OUT_RING((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) |
 +	    (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) |
 +	    (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT) |
 +	    (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT) |
 +	    (0 << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT));
 +   /* offset 8: S0, T0 -> {S0, T0, 1.0, 1.0} */
 +   OUT_RING((0 << VE0_VERTEX_BUFFER_INDEX_SHIFT) |
 +	    VE0_VALID |
 +	    (BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) |
 +	    (8 << VE0_OFFSET_SHIFT));
 +   OUT_RING((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) |
 +	    (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) |
 +	    (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT) |
 +	    (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT) |
 +	    (4 << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT));
 +
 +   OUT_RING(MI_NOOP);			/* pad to quadword */
 +   ADVANCE_LP_RING(); }
 +
 +   dxo = dstRegion->extents.x1;
 +   dyo = dstRegion->extents.y1;
 +
 +   pbox = REGION_RECTS(dstRegion);
 +   nbox = REGION_NUM_RECTS(dstRegion);
 +   while (nbox--)
 +   {
 +      int box_x1 = pbox->x1;
 +      int box_y1 = pbox->y1;
 +      int box_x2 = pbox->x2;
 +      int box_y2 = pbox->y2;
 +      int i;
 +      float src_scale_x, src_scale_y;
 +
 +      if (!first_output) {
 +	 /* Since we use the same little vertex buffer over and over, sync for
 +	  * subsequent rectangles.
 +	  */
 +	 if (pI830->AccelInfoRec && pI830->AccelInfoRec->NeedToSync) {
 +	    (*pI830->AccelInfoRec->Sync)(pScrn);
 +	    pI830->AccelInfoRec->NeedToSync = FALSE;
 +	 }
 +      }
 +
 +      pbox++;
 +
 +      /* Use normalized texture coordinates */
 +      src_scale_x = (float)1.0 / (float)drw_w;
 +      src_scale_y  = (float)1.0 / (float)drw_h;
 +
 +      i = 0;
 +      vb[i++] = (box_x2 - dxo) * src_scale_x;
 +      vb[i++] = (box_y2 - dyo) * src_scale_y;
 +      vb[i++] = (float) box_x2;
 +      vb[i++] = (float) box_y2;
 +
 +      vb[i++] = (box_x1 - dxo) * src_scale_x;
 +      vb[i++] = (box_y2 - dyo) * src_scale_y;
 +      vb[i++] = (float) box_x1;
 +      vb[i++] = (float) box_y2;
 +
 +      vb[i++] = (box_x1 - dxo) * src_scale_x;
 +      vb[i++] = (box_y1 - dyo) * src_scale_y;
 +      vb[i++] = (float) box_x1;
 +      vb[i++] = (float) box_y1;
 +
 +#if 0
 +      ErrorF ("before EU_ATT 0x%08x%08x EU_ATT_DATA 0x%08x%08x\n",
 +	      INREG(BRW_EU_ATT_1), INREG(BRW_EU_ATT_0),
 +	      INREG(BRW_EU_ATT_DATA_1), INREG(BRW_EU_ATT_DATA_0));
 +
 +      OUTREG(BRW_VF_CTL,
 +	     BRW_VF_CTL_SNAPSHOT_MUX_SELECT_THREADID |
 +	     BRW_VF_CTL_SNAPSHOT_TYPE_VERTEX_INDEX |
 +	     BRW_VF_CTL_SNAPSHOT_ENABLE);
 +      OUTREG(BRW_VF_STRG_VAL, 0);
 +#endif
 +      
 +#if 0
 +      OUTREG(BRW_VS_CTL,
 +	     BRW_VS_CTL_SNAPSHOT_ALL_THREADS |
 +	     BRW_VS_CTL_SNAPSHOT_MUX_VALID_COUNT |
 +	     BRW_VS_CTL_THREAD_SNAPSHOT_ENABLE);
 +      
 +      OUTREG(BRW_VS_STRG_VAL, 0);
 +#endif
 +      
 +#if WATCH_SF
 +      OUTREG(BRW_SF_CTL,
 +	     BRW_SF_CTL_SNAPSHOT_MUX_VERTEX_COUNT |
 +	     BRW_SF_CTL_SNAPSHOT_ALL_THREADS |
 +	     BRW_SF_CTL_THREAD_SNAPSHOT_ENABLE);
 +      OUTREG(BRW_SF_STRG_VAL, 0);
 +#endif
 +
 +#if WATCH_WIZ
 +      OUTREG(BRW_WIZ_CTL,
 +	     BRW_WIZ_CTL_SNAPSHOT_MUX_SUBSPAN_INSTANCE |
 +	     BRW_WIZ_CTL_SNAPSHOT_ALL_THREADS |
 +	     BRW_WIZ_CTL_SNAPSHOT_ENABLE);
 +      OUTREG(BRW_WIZ_STRG_VAL,
 +	     (box_x1) | (box_y1 << 16));
 +#endif
 +      
 +#if 0
 +      OUTREG(BRW_TS_CTL,
 +	     BRW_TS_CTL_SNAPSHOT_MESSAGE_ERROR |
 +	     BRW_TS_CTL_SNAPSHOT_ALL_CHILD_THREADS |
 +	     BRW_TS_CTL_SNAPSHOT_ALL_ROOT_THREADS |
 +	     BRW_TS_CTL_SNAPSHOT_ENABLE);
 +#endif
 +
 +      BEGIN_LP_RING(6);
 +      OUT_RING(BRW_3DPRIMITIVE | 
 +	       BRW_3DPRIMITIVE_VERTEX_SEQUENTIAL |
 +	       (_3DPRIM_RECTLIST << BRW_3DPRIMITIVE_TOPOLOGY_SHIFT) | 
 +	       (0 << 9) |  /* CTG - indirect vertex count */
 +	       4);
 +      OUT_RING(3); /* vertex count per instance */
 +      OUT_RING(0); /* start vertex offset */
 +      OUT_RING(1); /* single instance */
 +      OUT_RING(0); /* start instance location */
 +      OUT_RING(0); /* index buffer offset, ignored */
 +      ADVANCE_LP_RING();
 +
 +      int   j, k;
 +      CARD32	  ctl = 0, rdata;
 +      
 +#if 0
 +      for (j = 0; j < 100000; j++) {
 +	ctl = INREG(BRW_VF_CTL);
 +	 if (ctl & BRW_VF_CTL_SNAPSHOT_COMPLETE)
 +	    break;
 +      }
 +      
 +      rdata = INREG(BRW_VF_RDATA);
 +      OUTREG(BRW_VF_CTL, 0);
 +      ErrorF ("VF_CTL: 0x%08x VF_RDATA: 0x%08x\n", ctl, rdata);
 +#endif
 +
 +#if 0
 +      for (j = 0; j < 1000000; j++) {
 +	ctl = INREG(BRW_VS_CTL);
 +	 if (ctl & BRW_VS_CTL_SNAPSHOT_COMPLETE)
 +	    break;
 +      }
 +
 +      rdata = INREG(BRW_VS_RDATA);
 +      for (k = 0; k <= 3; k++) {
 +	 OUTREG(BRW_VS_CTL,
 +		BRW_VS_CTL_SNAPSHOT_COMPLETE |
 +		(k << 8));
 +	 rdata = INREG(BRW_VS_RDATA);
 +	 ErrorF ("VS_CTL: 0x%08x VS_RDATA(%d): 0x%08x\n", ctl, k, rdata);
 +      }
 +      
 +      OUTREG(BRW_VS_CTL, 0);
 +#endif
 +
 +#if WATCH_SF
 +      for (j = 0; j < 1000000; j++) {
 +	ctl = INREG(BRW_SF_CTL);
 +	 if (ctl & BRW_SF_CTL_SNAPSHOT_COMPLETE)
 +	    break;
 +      }
 +
 +      for (k = 0; k <= 7; k++) {
 +	 OUTREG(BRW_SF_CTL,
 +		BRW_SF_CTL_SNAPSHOT_COMPLETE |
 +		(k << 8));
 +	 rdata = INREG(BRW_SF_RDATA);
 +	 ErrorF ("SF_CTL: 0x%08x SF_RDATA(%d): 0x%08x\n", ctl, k, rdata);
 +      }
 +      
 +      OUTREG(BRW_SF_CTL, 0);
 +#endif
 +
 +#if WATCH_WIZ
 +      for (j = 0; j < 100000; j++) {
 +	ctl = INREG(BRW_WIZ_CTL);
 +	 if (ctl & BRW_WIZ_CTL_SNAPSHOT_COMPLETE)
 +	    break;
 +      }
 +      
 +      rdata = INREG(BRW_WIZ_RDATA);
 +      OUTREG(BRW_WIZ_CTL, 0);
 +      ErrorF ("WIZ_CTL: 0x%08x WIZ_RDATA: 0x%08x\n", ctl, rdata);
 +#endif
 +      
 +#if 0
 +      for (j = 0; j < 100000; j++) {
 +	ctl = INREG(BRW_TS_CTL);
 +	 if (ctl & BRW_TS_CTL_SNAPSHOT_COMPLETE)
 +	    break;
 +      }
 +      
 +      rdata = INREG(BRW_TS_RDATA);
 +      OUTREG(BRW_TS_CTL, 0);
 +      ErrorF ("TS_CTL: 0x%08x TS_RDATA: 0x%08x\n", ctl, rdata);
 +      
 +      ErrorF ("after EU_ATT 0x%08x%08x EU_ATT_DATA 0x%08x%08x\n",
 +	      INREG(BRW_EU_ATT_1), INREG(BRW_EU_ATT_0),
 +	      INREG(BRW_EU_ATT_DATA_1), INREG(BRW_EU_ATT_DATA_0));
 +#endif
 +
 +#if 0
 +      for (j = 0; j < 256; j++) {
 +	 OUTREG(BRW_TD_CTL, j << BRW_TD_CTL_MUX_SHIFT);
 +	 rdata = INREG(BRW_TD_RDATA);
 +	 ErrorF ("TD_RDATA(%d): 0x%08x\n", j, rdata);
 +      }
 +#endif
 +      first_output = FALSE;
 +      if (pI830->AccelInfoRec)
 +	 pI830->AccelInfoRec->NeedToSync = TRUE;
 +   }
 +
 +   if (pI830->AccelInfoRec)
 +      (*pI830->AccelInfoRec->Sync)(pScrn);
 +#if WATCH_STATS
 +   I830PrintErrorState (pScrn);
 +#endif
 +}
 +
  static FBLinearPtr
  I830AllocateMemory(ScrnInfoPtr pScrn, FBLinearPtr linear, int size)
  {
diff-tree bb6080735efc40e103e92b65d0c2f1f729156632 (from 3ca14275d13b1261b69b0e3fda90a112cb567472)
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Aug 9 12:21:16 2006 -0700

    Bump to 1.6.4 for release.

diff --git a/configure.ac b/configure.ac
index d9cf959..74e676b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -22,7 +22,7 @@
 
 AC_PREREQ(2.57)
 AC_INIT([xf86-video-i810],
-        1.6.3,
+        1.6.4,
         [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
         xf86-video-i810)
 
diff-tree 3ca14275d13b1261b69b0e3fda90a112cb567472 (from 309374f78df35207b1398e14bba986fb891f3643)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Wed Aug 9 10:35:57 2006 -0700

    Add missing headers to i810_drv_la_SOURCES

diff --git a/src/Makefile.am b/src/Makefile.am
index f97dc52..bea7b72 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -31,6 +31,9 @@ i810_drv_la_LDFLAGS = -module -avoid-ver
 i810_drv_ladir = @moduledir@/drivers
 
 i810_drv_la_SOURCES = \
+         brw_defines.h \
+         brw_structs.h \
+         wm_prog.h \
          common.h \
          i810_accel.c \
          i810_common.h \
diff-tree 309374f78df35207b1398e14bba986fb891f3643 (from dca9f856ca21e63abeb87e4ef2c40944c26d4429)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Wed Aug 9 10:30:41 2006 -0700

    Use double quotes to avoid sgml syntax error

diff --git a/README.sgml b/README.sgml
index 0ff713d..2f9abb7 100644
--- a/README.sgml
+++ b/README.sgml
@@ -69,7 +69,7 @@ section of your xorg.conf file are:
 </verb>
 
 In order to use most resolutions, it is necessary to install the
-'agpgart.o' module.  You will probably have to compile the module yourself
+"agpgart.o" module.  You will probably have to compile the module yourself
 (see the notes in the module).
 
 <sect>Driver Options
diff-tree dca9f856ca21e63abeb87e4ef2c40944c26d4429 (from b19ea222727ed47b69d28a03242c09d3a6ab2673)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Wed Aug 9 10:29:59 2006 -0700

    Reformat README

diff --git a/README b/README
index 46d6747..804f79d 100644
--- a/README
+++ b/README
@@ -1,8 +1,6 @@
-  $XFree86:
-  xc/programs/Xserver/hw/xfree86/doc/sgml/i810.sgml,v 1.4
-  2001/04/04 01:34:18 dawes Exp $ Information for i810 Users
-  Precision Insight, Inc.
-  3 March 2000
+  Information for Intel graphics driver users
+  Eric Anholt
+  206-08-04
   ____________________________________________________________
 
   Table of Contents
@@ -12,88 +10,85 @@
   2. Supported Hardware
   3. Features
   4. Technical Notes
-  5. Reported Working Video Cards
-  6. Configuration
-  7. Driver Options
-  8. Known Limitations
-  9. Author
+  5. Configuration
+  6. Driver Options
+  7. Known Limitations
+  8. Author
 
 
   ______________________________________________________________________
 
-  1.  Introduction
+  11..  IInnttrroodduuccttiioonn
 
-  This document provides a brief summary of the i810/i815 support
-  provided by the i810 driver.  Support for later chipsets is not
-  covered here.  More up to date information about the i810 driver can
-  be found in the i810(4) manual page.
+  This document provides a brief summary of the Intel graphics support
+  provided by the xf86-video-intel driver.  More information can also be
+  found in the i810(4) manual page.
 
 
-  2.  Supported Hardware
+  22..  SSuuppppoorrtteedd HHaarrddwwaarree
 
 
-  +o  Intel 810 motherboards:
+  +o  i810,
 
-     +o  i810,
+  +o  i810-dc100,
 
-     +o  i810-dc100,
+  +o  i810e
 
-     +o  i810e
+  +o  i815
 
-     +o  i815
+  +o  i830
 
+  +o  i845
 
+  +o  i852
 
-  3.  Features
+  +o  i855
 
+  +o  i915
 
-  +o  Full support for 8, 15, 16, and 24 bit pixel depths.
+  +o  i945
 
-  +o  Hardware cursor support to reduce sprite flicker.
+  +o  i965
 
-  +o  Hardware accelerated 2D drawing engine support for 8, 15, 16 and 24
-     bit pixel depths.
 
-  +o  Support for high resolution video modes up to 1600x1200.
 
-  +o  Fully programmable clock supported.
+  33..  FFeeaattuurreess
 
-  +o  Robust text mode restore for VT switching.
 
+  +o  Full support for 8, 15, 16, and 24 bit pixel depths.
 
+  +o  Hardware accelerated 2D drawing engine support for 8, 15, 16 and 24
+     bit pixel depths.
 
-  4.  Technical Notes
+  +o  Hardware accelerated 3D drawing using OpenGL and the DRI.
 
+  +o  Hardware cursor support to reduce sprite flicker.
 
-  +o  Hardware acceleration is not possible when using the framebuffer in
-     32 bit per pixel format, and this mode is not supported by this
-     driver.
+  +o  Textured video XV implementation on i915 through i965.
 
-  +o  Interlace modes cannot be supported.
+  +o  Hardware overlay XV implementation up through i945.
 
-  +o  This driver currently only works for Linux/ix86 and recent versions
-     of FreeBSD.  It requires the agpgart kernel support, which is
-     included in Linux kernels 2.3.42 and higher, and FreeBSD 4.1 and
-     higher.
+  +o  Screen resize and rotation on chipsets up through i945.
 
+  +o  Screen resize on i965.
 
 
-  5.  Reported Working Video Cards
 
+  44..  TTeecchhnniiccaall NNootteess
 
-  +o  Intel evaluation hardware - i810, i810-dc100, i810e and i815.
 
-  +o  Tyan Tomcat Motherboard.
+  +o  Interlace modes cannot be supported.
 
-  +o  HappyPC set-top box.
+  +o  This driver  requires kernel support for AGP, which is included in
+     Linux kernels 2.3.42 and higher, and FreeBSD 4.1 and higher.
 
 
 
-  6.  Configuration
+  55..  CCoonnffiigguurraattiioonn
 
   The driver auto-detects all device information necessary to initialize
-  the card.  The only lines you need in the "Device" section of your
-  xorg.conf file are:
+  the card.  The only lines you should need in the "Device" section of
+  your xorg.conf file are:
 
          Section "Device"
              Identifier "Intel i810"
@@ -101,54 +96,68 @@
          EndSection
 
 
-  or let xorgconfig do this for you.
 
-  However, if you have problems with auto-detection, you can specify:
+  In order to use most resolutions, it is necessary to install the
+  "agpgart.o" module.  You will probably have to compile the module
+  yourself (see the notes in the module).
 
-  +o  DacSpeed - in MHz
 
-  +o  MemBase  - physical address of the linear framebuffer
+  66..  DDrriivveerr OOppttiioonnss
 
-  +o  IOBase   - physical address of the memory mapped IO registers
+  Please refer to the i810(4) manual page for information on
+  configuration options.
 
-  In order to use most resolutions, it is necessary to install the (see
-  the notes in the module).
 
-  Note: the i810 driver detects whether your motherboard has display
-  cache video memory.  This memory is has reduced bandwidth compared to
-  normal system memory, and isn't used by the server.  The main function
-  of this memory is for ancillary buffers (eg. z buffer) in a
-  forthcoming 3d capable server.
 
+  77..  KKnnoowwnn LLiimmiittaattiioonnss
 
 
-  7.  Driver Options
+  +o  Many systems with Intel graphics have issues with setting video
+     modes at larger than some small maximum resolution.  This is not
+     fixed in the current release, but is being actively worked on in
+     the modesetting branch.
 
+  +o  Bug #5774: Some systems have issues with VT switching.  This should
+     be fixed with the modesetting brach integration.
 
-  +o  "NoAccel"  - Turn off hardware acceleration
+  +o  Bug #5817: Hotkey switching from LVDS to CRT breaks CRT output.
+     This is a known issue, but will not be fixed in the current
+     release.
 
+  +o  Bug #6635: Video is output from an incorrect offset in the
+     framebuffer.  This is expected to be fixed with the modesetting
+     branch integration.
 
-  +o  "SWCursor" - Request a software cursor (hardware is default)
+  +o  GL_EXT_texture_compression_s3tc is not supported.  We can't support
+     the extension due to patent restrictions on compression, but may be
+     able to support an option for partial extension support in the
+     future.  For now, this prevents Quake4 and some other games from
+     running.
 
-  +o  "Dac6Bit"  - Force the use of a 6 Bit Dac (8 Bit is the default)
+  +o  Some X Test Suite cases sometimes fail due to a timeout. These
+     cases include: Xt8/XtResizeWindow, Xt8/XtQueryGeometry,
+     Xt9/XtAppAddInput, Xt9/XtRemoveInput, Xt9/XtAppAddTimeOut,
+     Xt9/XtRemoveTimeOut, Xt9/XtAddGrab, Xt9/XtRemoveGrab.
 
+  +o  Some X Test Suite cases fail in 64-bit mode: Xlib9/XDrawArc,
+     XDrawImageString, XDrawLine, XDrawRectangle, XDrawSegments,
+     XFillArc, XFillPolygon, XFillRectangle, XPutImage,
+     Xt11/XtVaGetSubresources, XtSetSubvalues, and XtVaSetSubvalues.
 
-  8.  Known Limitations
+  +o  Some GLEAN test cases fail if DRI is enabled: pointAtten,
+     readPixSanity, texCombine, texCube, texEnv, texgen,
+     coloredTexPerf2, and coloredLitPerf2.
 
 
-  +o  No 3D support in this release.
 
-  +o  Running two X servers on different VTs is not supported at this
-     time.
+  88..  AAuutthhoorr
 
 
-
-  9.  Author
-
+  +o  Eric Anholt
 
   +o  Keith Whitwell
 
-  The X11R6.8 version of this driver originally came from XFree86 4.4
+  The X11R7.1 version of this driver originally came from XFree86 4.4
   rc2.
 
   The XFree86 version of this driver was donated to The XFree86 Project
@@ -160,7 +169,9 @@
 
 
 
-  http://www.precisioninsight.com
+  The X.Org version of this driver is maintained by Intel Corporation.
+
+  http://www.intellinuxgraphics.org
 
 
 
diff-tree b19ea222727ed47b69d28a03242c09d3a6ab2673 (from f8b47f607297e0591b63e5f25296af07ee74f433)
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Aug 9 10:01:29 2006 -0700

    Update the README.sgml file for the upcoming release.

diff --git a/README.sgml b/README.sgml
index 2aba95f..0ff713d 100644
--- a/README.sgml
+++ b/README.sgml
@@ -3,31 +3,31 @@
 ]>
 
 <article>
-<title>Information for i810 Users
-<author>Precision Insight, Inc.
-<date>3 March 2000
-<ident>
-$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/i810.sgml,v 1.4 2001/04/04 01:34:18 dawes Exp $
-</ident>
+<title>Information for Intel graphics driver users
+<author>Eric Anholt
+<date>206-08-04
 <toc>
 
 <sect>Introduction
 <p>
-This document provides a brief summary of the i810/i815 support provided
-by the i810 driver.  Support for later chipsets is not covered here.
-More up to date information about the i810 driver can be found in the
+This document provides a brief summary of the Intel graphics support provided
+by the xf86-video-intel driver.  More information can also be found in the
 <htmlurl name="i810(4)" url="i810.4.html"> manual page.
 
 <sect>Supported Hardware
 <p>
 <itemize>
-  <item>Intel 810 motherboards:
-	<itemize>
-	  <item>i810,
-	  <item>i810-dc100,
-	  <item>i810e
-	  <item>i815
-	</itemize>
+	<item>i810,
+  	<item>i810-dc100,
+	<item>i810e
+	<item>i815
+	<item>i830
+	<item>i845
+	<item>i852
+	<item>i855
+	<item>i915
+	<item>i945
+	<item>i965
 </itemize>
 
 
@@ -35,42 +35,31 @@ More up to date information about the i8
 <p>
 <itemize>
   <item>Full support for 8, 15, 16, and 24 bit pixel depths.
-  <item>Hardware cursor support to reduce sprite flicker.
   <item>Hardware accelerated 2D drawing engine support for 8, 15, 16 and
         24 bit pixel depths.
-  <item>Support for high resolution video modes up to 1600x1200.
-  <item>Fully programmable clock supported.
-  <item>Robust text mode restore for VT switching.
+  <item>Hardware accelerated 3D drawing using OpenGL and the DRI.
+  <item>Hardware cursor support to reduce sprite flicker.
+  <item>Textured video XV implementation on i915 through i965.
+  <item>Hardware overlay XV implementation up through i945.
+  <item>Screen resize and rotation on chipsets up through i945.
+  <item>Screen resize on i965.
 </itemize>
 
 
 <sect>Technical Notes
 <p>
 <itemize>
-  <item>Hardware acceleration is not possible when using the framebuffer
-	in 32 bit per pixel format, and this mode is not supported by
-	this driver.
   <item>Interlace modes cannot be supported.
-  <item>This driver currently only works for Linux/ix86 and recent versions
-	of FreeBSD.  It requires the agpgart kernel support, which is
+  <item>This driver  requires kernel support for AGP, which is
 	included in Linux kernels 2.3.42 and higher, and FreeBSD 4.1
 	and higher.
 </itemize>
 
 
-<sect>Reported Working Video Cards
-<p>
-<itemize>
-  <item>Intel evaluation hardware - i810, i810-dc100, i810e and i815.
-  <item>Tyan Tomcat Motherboard.
-  <item>HappyPC set-top box.
-</itemize>
-
-
 <sect>Configuration
 <p>
 The driver auto-detects all device information necessary to
-initialize the card.  The only lines you need in the "Device"
+initialize the card.  The only lines you should need in the "Device"
 section of your xorg.conf file are:
 <verb>
        Section "Device"
@@ -78,45 +67,51 @@ section of your xorg.conf file are:
            Driver     "i810"
        EndSection
 </verb>
-or let <tt>xorgconfig</tt> do this for you.
-
-However, if you have problems with auto-detection, you can specify:
-<itemize>
-  <item>DacSpeed - in MHz
-  <item>MemBase  - physical address of the linear framebuffer
-  <item>IOBase   - physical address of the memory mapped IO registers
-</itemize>
 
 In order to use most resolutions, it is necessary to install the
 'agpgart.o' module.  You will probably have to compile the module yourself
 (see the notes in the module).
 
-Note: the i810 driver detects whether your motherboard has display cache
-video memory.  This memory is has reduced bandwidth compared to normal
-system memory, and isn't used by the server.  The main function of this
-memory is for ancillary buffers (eg. z buffer) in a forthcoming 3d
-capable server.
-
-
 <sect>Driver Options
 <p>
-<itemize>
-  <item>"NoAccel"  - Turn off hardware acceleration
-  <item>"SWCursor" - Request a software cursor (hardware is default)
-  <item>"Dac6Bit"  - Force the use of a 6 Bit Dac (8 Bit is the default)
-</itemize>
+Please refer to the <htmlurl name="i810(4)" url="i810.4.html"> manual page
+for information on configuration options.
+
 
 <sect>Known Limitations
 <p>
 <itemize>
-  <item>No 3D support in this release.
-  <item>Running two X servers on different VTs is not supported at this time.
+  <item>Many systems with Intel graphics have issues with setting video modes
+at larger than some small maximum resolution.  This is not fixed in the current
+release, but is being actively worked on in the modesetting branch.
+  <item>Bug #5774: Some systems have issues with VT switching.  This should
+be fixed with the modesetting brach integration.
+  <item>Bug #5817: Hotkey switching from LVDS to CRT breaks CRT output.  This
+is a known issue, but will not be fixed in the current release.
+  <item>Bug #6635: Video is output from an incorrect offset in the framebuffer.
+This is expected to be fixed with the modesetting branch integration.
+  <item>GL_EXT_texture_compression_s3tc is not supported.  We can't support the
+extension due to patent restrictions on compression, but may be able to support
+an option for partial extension support in the future.  For now, this prevents
+Quake4 and some other games from running.
+  <item>Some X Test Suite cases sometimes fail due to a timeout. These cases
+include: Xt8/XtResizeWindow, Xt8/XtQueryGeometry, Xt9/XtAppAddInput,
+Xt9/XtRemoveInput, Xt9/XtAppAddTimeOut, Xt9/XtRemoveTimeOut, Xt9/XtAddGrab,
+Xt9/XtRemoveGrab.
+  <item>Some X Test Suite cases fail in 64-bit mode: Xlib9/XDrawArc,
+XDrawImageString, XDrawLine, XDrawRectangle, XDrawSegments, XFillArc,
+XFillPolygon, XFillRectangle, XPutImage, Xt11/XtVaGetSubresources,
+XtSetSubvalues, and XtVaSetSubvalues.
+  <item>Some GLEAN test cases fail if DRI is enabled: pointAtten,
+readPixSanity, texCombine, texCube, texEnv, texgen, coloredTexPerf2, and
+coloredLitPerf2.
 </itemize>
 
 
 <sect>Author
 <p>
 <itemize>
+   <item>Eric Anholt
    <item>Keith Whitwell
 </itemize>
 
@@ -129,8 +124,10 @@ The XFree86 version of this driver was d
     USA
 </verb>
 
-<htmlurl name="http://www.precisioninsight.com"
-          url="http://www.precisioninsight.com">
+The X.Org version of this driver is maintained by Intel Corporation.
+
+<htmlurl name="http://www.intellinuxgraphics.org"
+          url="http://www.intellinuxgraphics.org">
 
 
 </article>
diff-tree f8b47f607297e0591b63e5f25296af07ee74f433 (from d150b53d102c511f3c9245ef1f6fd36c12b01ca3)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Tue Aug 8 16:19:51 2006 -0700

    Update manual page to include i945 and later details.
    (cherry picked from 7833d0733bc146cf1ae7f588516c49797886b396 commit)

diff --git a/man/i810.man b/man/i810.man
index 099e1f8..d8c2cd2 100644
--- a/man/i810.man
+++ b/man/i810.man
@@ -17,30 +17,29 @@ i810 \- Intel 8xx integrated graphics ch
 is an __xservername__ driver for Intel integrated graphics chipsets.
 The driver supports depths 8, 15, 16 and 24.  All visual types are
 supported in depth 8.  For the i810/i815 other depths support the
-TrueColor and DirectColor visuals.  For the 830M and later, only the
+TrueColor and DirectColor visuals.  For the i830M and later, only the
 TrueColor visual is supported for depths greater than 8.  The driver
 supports hardware accelerated 3D via the Direct Rendering Infrastructure
 (DRI), but only in depth 16 for the i810/i815 and depths 16 and 24 for
 the 830M and later.
 .SH SUPPORTED HARDWARE
 .B i810
-supports the i810, i810-DC100, i810e, i815, 830M, 845G, 852GM, 855GM,
-865G, 915G and 915GM chipsets.
+supports the i810, i810-DC100, i810e, i815, i830M, 845G, 852GM, 855GM,
+865G, 915G, 915GM, 945G, 945GM, 965G, 965Q and 946GZ chipsets.
 
 .SH CONFIGURATION DETAILS
 Please refer to __xconfigfile__(__filemansuffix__) for general configuration
 details.  This section only covers configuration details specific to this
 driver.
 .PP
-The Intel 8xx family of integrated graphics chipsets has a unified memory
-architecture and uses system memory for video ram.  For the i810 and
+The Intel 8xx and 9xx families of integrated graphics chipsets has a unified
+memory architecture and uses system memory for video ram.  For the i810 and
 i815 family of chipset, operating system support for allocating system
-memory for video use is required in order to use this driver.  For the
-830M and later, this is required in order for the driver to use more
-video ram than has been pre-allocated at boot time by the BIOS.  This
-is usually achieved with an "agpgart" or "agp" kernel driver.  Linux,
-and recent versions of FreeBSD, OpenBSD and NetBSD have such kernel
-drivers available.
+memory for video use is required in order to use this driver.  For the 830M
+and later, this is required in order for the driver to use more video ram
+than has been pre-allocated at boot time by the BIOS.  This is usually
+achieved with an "agpgart" or "agp" kernel driver.  Linux, and recent
+versions of FreeBSD, OpenBSD and NetBSD have such kernel drivers available.
 .PP
 By default 8 Megabytes
 of system memory are used for graphics.  For the 830M and later, the
@@ -208,9 +207,11 @@ Default 0KB (off).
 .SH "SEE ALSO"
 __xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), xorgconfig(__appmansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__)
 .SH AUTHORS
-Authors include: Keith Whitwell, and also Jonathan Bian, Matthew J Sottek, 
+Authors include: Keith Whitwell, and also Jonathan Bian, Matthew J Sottek,
 Jeff Hartmann, Mark Vojkovich, Alan Hourihane, H. J. Lu.  830M and 845G
-support reworked for XFree86 4.3 by David Dawes and Keith Whitwell.
-852GM, 855GM, and 865G support added by David Dawes and Keith Whitwell.
-915G and 915GM support added by Alan Hourihane and Keith Whitwell.
-Dual Head, Clone and lid status support added by Alan Hourihane.
+support reworked for XFree86 4.3 by David Dawes and Keith Whitwell.  852GM,
+855GM, and 865G support added by David Dawes and Keith Whitwell.  915G,
+915GM, 945G, 945GM, 965G, 965Q and 946GZ support added by Alan Hourihane and
+Keith Whitwell.  Dual Head, Clone and lid status support added by Alan
+Hourihane. Textured video support for 915G and later chips added by Keith
+Packard and Eric Anholt.
diff-tree d150b53d102c511f3c9245ef1f6fd36c12b01ca3 (from parents)
Merge: bb65a4dc55b416437d61ccbee8b6056fe8e08357 bc5f56568021d8c63313e2b6bf30710e7516c04a
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Aug 8 15:51:58 2006 -0700

    Merge branch 'i965', adding i965G support.
    
    Conflicts:
    
    	src/i830_cursor.c
    	src/i830_driver.c

diff --cc src/i830_cursor.c
index 1657f7c,c835cae..dd3071e
@@@ -91,19 -91,24 +91,26 @@@
        temp = INREG(CURSOR_A_CONTROL);
        temp &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE | MCURSOR_MEM_TYPE_LOCAL |
  		MCURSOR_PIPE_SELECT);
 -      if(pI830->CursorIsARGB)
 -	 temp |= MCURSOR_GAMMA_ENABLE;
        temp |= CURSOR_MODE_DISABLE;
        temp |= (pI830->pipe << 28);
 +      if (pI830->CursorIsARGB)
 +         temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
 +      else
 +         temp |= CURSOR_MODE_64_4C_AX;
        /* Need to set control, then address. */
        OUTREG(CURSOR_A_CONTROL, temp);
-       if (pI830->CursorIsARGB)
-          OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Physical);
-       else
-          OUTREG(CURSOR_A_BASE, pI830->CursorMem->Physical);
+       if (pI830->CursorNeedsPhysical) {
+          if (pI830->CursorIsARGB)
+             OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Physical);
+          else
+             OUTREG(CURSOR_A_BASE, pI830->CursorMem->Physical);
+       } else {
+          if (pI830->CursorIsARGB)
+             OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Start);
+          else
+             OUTREG(CURSOR_A_BASE, pI830->CursorMem->Start);
+       }
 -      if (pI830->Clone) {
 +      if (pI830->Clone || pI830->MergedFB) {
           temp &= ~MCURSOR_PIPE_SELECT;
           temp |= (!pI830->pipe << 28);
           OUTREG(CURSOR_B_CONTROL, temp);
@@@ -595,11 -517,18 +624,18 @@@
        temp |= (pI830->pipe << 28); /* Connect to correct pipe */
        /* Need to set mode, then address. */
        OUTREG(CURSOR_A_CONTROL, temp);
-       if (pI830->CursorIsARGB)
-          OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Physical);
-       else
-          OUTREG(CURSOR_A_BASE, pI830->CursorMem->Physical);
+       if (pI830->CursorNeedsPhysical) {
+          if (pI830->CursorIsARGB)
+             OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Physical);
+          else
+             OUTREG(CURSOR_A_BASE, pI830->CursorMem->Physical);
+       } else {
+          if (pI830->CursorIsARGB)
+             OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Start);
+          else
+             OUTREG(CURSOR_A_BASE, pI830->CursorMem->Start);
+       }
 -      if (pI830->Clone) {
 +      if (pI830->Clone || pI830->MergedFB) {
           temp &= ~MCURSOR_PIPE_SELECT;
           temp |= (!pI830->pipe << 28);
           OUTREG(CURSOR_B_CONTROL, temp);
diff --cc src/i830_driver.c
index 5cbb280,a7e418b..62a62ab
@@@ -6078,37 -4191,30 +6150,56 @@@
  
     SetPipeAccess(pScrn);
  
 +   if (!pI830->MergedFB) {
 +      if (I830VESASetVBEMode(pScrn, mode, mp->vbeData.block) == FALSE) {
 +         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Set VBE Mode failed!\n");
 +         return FALSE;
 +      }
 +   }else {
 +      I830ModePrivatePtr s = (I830ModePrivatePtr)mp->merged.Second->Private;
 +      I830ModePrivatePtr f = (I830ModePrivatePtr)mp->merged.First->Private;
 +      int pipe = pI830->pipe; /* save current pipe */
 +
 +      SetBIOSPipe(pScrn, !pI830->pipe);
 +
 +      pI830->pipe = !pI830->pipe;
 +      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting mode on Pipe %s.\n", pI830->pipe ? "B" : "A");
 +
 +      if (I830VESASetVBEMode(pScrn, (s->vbeData.mode | 1<<15 | 1<<14), s->vbeData.block) == FALSE) {
 +         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Set VBE Mode failed!\n");
 +         return FALSE;
 +      }
 +
 +      pI830->pipe = pipe; /* restore current pipe */
 +      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting mode on Pipe %s.\n", pI830->pipe ? "B" : "A");
 +
 +      SetPipeAccess(pScrn);
 +
 +      if (I830VESASetVBEMode(pScrn, (f->vbeData.mode | 1<<15 | 1<<14), f->vbeData.block) == FALSE) {
 +         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Set VBE Mode failed!\n");
 +         return FALSE;
 +      }
 +   }
 +
+ #if 0
+    { /* I965G ENABLE TILING */
+       planeA = INREG(DSPACNTR) | 1<<10;
+       OUTREG(DSPACNTR, planeA);
+       /* flush the change. */
+       temp = INREG(DSPABASE);
+       OUTREG(DSPABASE, temp);
+    }
+ #else
+    { /* I965G DISABLE TILING */
+       planeA = INREG(DSPACNTR) & ~1<<10;
+       OUTREG(DSPACNTR, planeA);
+       /* flush the change. */
+       temp = INREG(DSPABASE);
+       OUTREG(DSPABASE, temp);
+       OUTREG(DSPASURF, INREG(DSPASURF));
+    }
+ #endif
+ 
 -   if (I830VESASetVBEMode(pScrn, mode, data->block) == FALSE) {
 -      xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Set VBE Mode failed!\n");
 -      return FALSE;
 -   }
 -
     /*
      * The BIOS may not set a scanline pitch that would require more video
      * memory than it's aware of.  We check for this later, and set it
@@@ -6293,25 -4428,13 +6413,29 @@@
  		    (int)(temp / pI830->cpp), pI830->displayWidth);
  	    OUTREG(stridereg, pI830->displayWidth * pI830->cpp);
           }
 -         OUTREG(sizereg, (pMode->HDisplay - 1) | ((pMode->VDisplay - 1) << 16));
 +
 +	 if (pI830->MergedFB) {
 +	    switch (pI830->SecondPosition) {
 +	       case PosRightOf:
 +	       case PosBelow:
 +                  OUTREG(DSPABASE, (CDMPTR.First->HDisplay - 1) | ((CDMPTR.First->VDisplay - 1) << 16));
 +                  OUTREG(DSPBBASE, (CDMPTR.Second->HDisplay - 1) | ((CDMPTR.Second->VDisplay - 1) << 16));
 +	          break;
 +	       case PosLeftOf:
 +	       case PosAbove:
 +                  OUTREG(DSPABASE, (CDMPTR.Second->HDisplay - 1) | ((CDMPTR.Second->VDisplay - 1) << 16));
 +                  OUTREG(DSPBBASE, (CDMPTR.First->HDisplay - 1) | ((CDMPTR.First->VDisplay - 1) << 16));
 +	          break;
 +	    }
 +         } else
 +            OUTREG(sizereg, (pMode->HDisplay - 1) | ((pMode->VDisplay - 1) << 16));
 +	 /* Trigger update */
  	 temp = INREG(basereg);
  	 OUTREG(basereg, temp);
+          if (IS_I965G(pI830)) {
+             temp = INREG(surfreg);
+             OUTREG(surfreg, temp);
+          }
        }
     }
  
diff-tree bc5f56568021d8c63313e2b6bf30710e7516c04a (from c3b3d479788fcea7e543f29acf83c85b8b148fbe)
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Aug 8 15:48:04 2006 -0700

    Intel bug #49: Fix video output at 32bpp by using B8G8R8A8 instead of B8G8R8X8.
    
    While here, don't overallocate video memory for the i965G state.

diff --git a/src/i830_video.c b/src/i830_video.c
index 64134df..940550d 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2960,7 +2960,7 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    if (pI830->cpp == 2) {
       dest_surf_state->ss0.surface_format = BRW_SURFACEFORMAT_B5G6R5_UNORM;
    } else {
-      dest_surf_state->ss0.surface_format = BRW_SURFACEFORMAT_B8G8R8X8_UNORM;
+      dest_surf_state->ss0.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
    }
    dest_surf_state->ss0.writedisable_alpha = 0;
    dest_surf_state->ss0.writedisable_red = 0;
@@ -3628,7 +3628,9 @@ I830PutImage(ScrnInfoPtr pScrn,
 
    /* size is multiplied by 2 because we have two buffers that are flipping */
    pPriv->linear = I830AllocateMemory(pScrn, pPriv->linear,
-		   extraLinear + (pPriv->doubleBuffer ? size * 2 : size) / pI830->cpp);
+				      (extraLinear +
+				       (pPriv->doubleBuffer ? size * 2 : size)) /
+				      pI830->cpp);
 
    if(!pPriv->linear || pPriv->linear->offset < (pScrn->virtualX * pScrn->virtualY))
       return BadAlloc;
diff-tree c3b3d479788fcea7e543f29acf83c85b8b148fbe (from bc12208f6e145ec29c3ebe38ae04dc2ebca1b4cc)
Author: Alan Hourihane <alanh at tungstengraphics.com>
Date:   Tue Aug 8 15:28:14 2006 -0700

    Intel bug #35: Fix accelerator syncing with DGA.
    
    Fixes glitches seen with Mark Vojkovich's "texture" demo.

diff --git a/src/i830_dga.c b/src/i830_dga.c
index 1129fa3..1a6e4e6 100644
--- a/src/i830_dga.c
+++ b/src/i830_dga.c
@@ -253,12 +253,25 @@ static void
 I830_Sync(ScrnInfoPtr pScrn)
 {
    I830Ptr pI830 = I830PTR(pScrn);
+   int flags = MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE;
 
    MARKER();
 
-   if (pI830->AccelInfoRec) {
-      (*pI830->AccelInfoRec->Sync) (pScrn);
-   }
+   if (pI830->noAccel) 
+      return;
+
+   if (IS_I965G(pI830))
+      flags = 0;
+
+   BEGIN_LP_RING(2);
+   OUT_RING(MI_FLUSH | flags);
+   OUT_RING(MI_NOOP);		/* pad to quadword */
+   ADVANCE_LP_RING();
+
+   I830WaitLpRing(pScrn, pI830->LpRing->mem.Size - 8, 0);
+
+   pI830->LpRing->space = pI830->LpRing->mem.Size - 8;
+   pI830->nextColorExpandBuf = 0;
 }
 
 static void
diff-tree bc12208f6e145ec29c3ebe38ae04dc2ebca1b4cc (from 0fd4831fdcf4c8f43d80c66e43eff8942f89b324)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Mon Aug 7 13:27:00 2006 +0800

    Disable error register dumping in dri TransitionTo2d. This's for
    debug which might confuse QA.

diff --git a/src/i830_dri.c b/src/i830_dri.c
index af0db25..445bbec 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -1390,9 +1390,6 @@ I830DRITransitionTo2d(ScreenPtr pScreen)
 
    pI830->have3DWindows = 0;
 
-   
-   I830PrintErrorState(pScrn);
-      
 }
 
 
diff-tree bb65a4dc55b416437d61ccbee8b6056fe8e08357 (from 37644293da751bfc7268c9fc74ecda1044607dee)
Author: Alan Hourihane <alanh at fairlite.demon.co.uk>
Date:   Tue Aug 8 14:51:18 2006 +0100

    bump to 1.6.3

diff --git a/configure.ac b/configure.ac
index b1141dc..d9cf959 100644
--- a/configure.ac
+++ b/configure.ac
@@ -22,7 +22,7 @@
 
 AC_PREREQ(2.57)
 AC_INIT([xf86-video-i810],
-        1.6.2,
+        1.6.3,
         [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
         xf86-video-i810)
 
diff --git a/src/i810.h b/src/i810.h
index 5a526fb..4237485 100644
--- a/src/i810.h
+++ b/src/i810.h
@@ -66,7 +66,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define I810_DRIVER_NAME "i810"
 #define I810_MAJOR_VERSION 1
 #define I810_MINOR_VERSION 6
-#define I810_PATCHLEVEL 2
+#define I810_PATCHLEVEL 3
 
 
 /* HWMC Surfaces */
diff-tree 37644293da751bfc7268c9fc74ecda1044607dee (from 3661d4df86db012682ab4b393287aa02e9fc8453)
Author: Alan Hourihane <alanh at fairlite.demon.co.uk>
Date:   Tue Aug 8 14:42:32 2006 +0100

    check for xineramaproto

diff --git a/configure.ac b/configure.ac
index fde8917..b1141dc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -54,6 +54,7 @@ AC_ARG_ENABLE(dri, AC_HELP_STRING([--dis
 
 
 # Checks for extensions
+XORG_DRIVER_CHECK_EXT(XINERAMA, xineramaproto)
 XORG_DRIVER_CHECK_EXT(RANDR, randrproto)
 XORG_DRIVER_CHECK_EXT(RENDER, renderproto)
 XORG_DRIVER_CHECK_EXT(XF86DRI, xextproto x11)
diff-tree 3661d4df86db012682ab4b393287aa02e9fc8453 (from 995b142f510d1daab3914d336f3c0d017a043b41)
Author: Alan Hourihane <alanh at fairlite.demon.co.uk>
Date:   Tue Aug 8 12:25:03 2006 +0100

    Re-enable monitor detect after a few fixups.

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 94a2c8f..5cbb280 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -285,7 +285,7 @@ static OptionInfoRec I830BIOSOptions[] =
 
 static void I830DisplayPowerManagementSet(ScrnInfoPtr pScrn,
 					  int PowerManagementMode, int flags);
-static void I830BIOSAdjustFrame(int scrnIndex, int x, int y, int flags);
+static void I830AdjustFrame(int scrnIndex, int x, int y, int flags);
 static Bool I830BIOSCloseScreen(int scrnIndex, ScreenPtr pScreen);
 static Bool I830BIOSSaveScreen(ScreenPtr pScreen, int unblack);
 static Bool I830BIOSEnterVT(int scrnIndex, int flags);
@@ -7171,7 +7171,7 @@ I830BIOSScreenInit(int scrnIndex, Screen
 	  if(!I830noPanoramiXExtension) {
 	     if(pI830->HaveNonRect) {
 		/* Reset the viewport (now eventually non-recangular) */
-		I830BIOSAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+		I830AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
 	     }
 	  }
       } else {
@@ -7231,7 +7231,7 @@ I830BIOSScreenInit(int scrnIndex, Screen
 }
 
 static void
-I830BIOSAdjustFrame(int scrnIndex, int x, int y, int flags)
+I830AdjustFrame(int scrnIndex, int x, int y, int flags)
 {
    ScrnInfoPtr pScrn;
    I830Ptr pI830;
@@ -7242,7 +7242,7 @@ I830BIOSAdjustFrame(int scrnIndex, int x
    pI830 = I830PTR(pScrn);
    pVbe = pI830->pVbe;
 
-   DPRINTF(PFX, "I830BIOSAdjustFrame: y = %d (+ %d), x = %d (+ %d)\n",
+   DPRINTF(PFX, "I830AdjustFrame: y = %d (+ %d), x = %d (+ %d)\n",
 	   x, pI830->xoffset, y, pI830->yoffset);
 
    /* Sync the engine before adjust frame */
@@ -7430,6 +7430,7 @@ I830DetectMonitorChange(ScrnInfoPtr pScr
    pDDCModule = xf86LoadSubModule(pScrn, "ddc");
 
    if (pI830->MergedFB) {
+      pI830->pVbe->ddc = DDC_UNCHECKED;
       SetBIOSPipe(pScrn, !pI830->pipe);
       monitor = vbeDoEDID(pI830->pVbe, pDDCModule);
       if ((pI830->pScrn_2->monitor->DDC = monitor) != NULL) {
@@ -7439,6 +7440,7 @@ I830DetectMonitorChange(ScrnInfoPtr pScr
       SetPipeAccess(pScrn);
    }
 
+   pI830->pVbe->ddc = DDC_UNCHECKED;
    monitor = vbeDoEDID(pI830->pVbe, pDDCModule);
    xf86UnloadSubModule(pDDCModule);
    if ((pScrn->monitor->DDC = monitor) != NULL) {
@@ -7470,7 +7472,7 @@ I830DetectMonitorChange(ScrnInfoPtr pScr
       return FALSE;
    }
 
-   if (pI830->MergedFB && DDCclock2 > 0) {
+   if (pI830->MergedFB) {
       SetBIOSPipe(pScrn, !pI830->pipe);
       xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 		 "Retrieving mode pool for second head.\n");
@@ -7486,7 +7488,7 @@ I830DetectMonitorChange(ScrnInfoPtr pScr
    }
 
    VBESetModeNames(pScrn->modePool);
-   if (pI830->MergedFB && DDCclock2 > 0)
+   if (pI830->MergedFB)
       VBESetModeNames(pI830->pScrn_2->modePool);
 
    if (pScrn->videoRam > (pI830->vbeInfo->TotalMemory * 64))
@@ -7501,7 +7503,7 @@ I830DetectMonitorChange(ScrnInfoPtr pScr
 			pScrn->display->virtualY,
 			memsize, LOOKUP_BEST_REFRESH);
 
-   if (pI830->MergedFB && DDCclock2 > 0) {
+   if (pI830->MergedFB) {
       VBEValidateModes(pI830->pScrn_2, pI830->pScrn_2->monitor->Modes, 
 		        pI830->pScrn_2->display->modes, NULL,
 			NULL, 0, MAX_DISPLAY_PITCH, 1,
@@ -7572,20 +7574,11 @@ I830DetectMonitorChange(ScrnInfoPtr pScr
       } while (p != NULL && p != pI830->pScrn_2->modes);
    }
 
-   pScrn->displayWidth = displayWidth; /* restore old displayWidth */
-
    xf86PruneDriverModes(pScrn);
 
-   if (pI830->MergedFB && DDCclock2 > 0) {
+   if (pI830->MergedFB)
       xf86PruneDriverModes(pI830->pScrn_2);
 
-      if (pI830->pScrn_2->modes == NULL) {
-         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n");
-         PreInitCleanup(pScrn);
-         return FALSE;
-      }
-   }
-
    if (pI830->MergedFB) {
       DisplayModePtr old_modes, cur_mode;
 
@@ -7606,8 +7599,6 @@ I830DetectMonitorChange(ScrnInfoPtr pScr
       }
    }
 
-   I830PrintModes(pScrn);
-
    if (!pI830->vesa->useDefaultRefresh)
       I830SetModeParameters(pScrn, pI830->pVbe);
 
@@ -7616,6 +7607,21 @@ I830DetectMonitorChange(ScrnInfoPtr pScr
     * and reconnecting monitors */
 
    pScrn->currentMode = pScrn->modes;
+
+   if (pI830->MergedFB) {
+      /* If no virtual dimension was given by the user,
+       * calculate a sane one now. Adapts pScrn->virtualX,
+       * pScrn->virtualY and pScrn->displayWidth.
+       */
+      I830RecalcDefaultVirtualSize(pScrn);
+
+      pScrn->modes = pScrn->modes->next;  /* We get the last from GenerateModeList(), skip to first */
+      pScrn->currentMode = pScrn->modes;
+      pI830->currentMode = pScrn->currentMode;
+   }
+
+   pScrn->displayWidth = displayWidth; /* restore old displayWidth */
+
    p = pScrn->modes;
    if (p == NULL)
       return FALSE;
@@ -7628,6 +7634,8 @@ I830DetectMonitorChange(ScrnInfoPtr pScr
       p = p->next;
    } while (p != NULL && p != pScrn->modes);
 
+   I830PrintModes(pScrn);
+
    /* Now readjust for panning if necessary */
    {
       pScrn->frameX0 = (pScrn->frameX0 + pScrn->frameX1 + 1 - pScrn->currentMode->HDisplay) / 2;
@@ -7765,13 +7773,8 @@ I830BIOSEnterVT(int scrnIndex, int flags
    ResetState(pScrn, FALSE);
    SetHWOperatingState(pScrn);
 
-#if 0
-   /* Disable this as it's clunky, and doesn't always work.
-    * The modesetting branch will deal with hotplug displays much better.
-    */
    if (!pI830->starting)
       I830DetectMonitorChange(pScrn);
-#endif
 	    
    if (!I830VESASetMode(pScrn, pScrn->currentMode))
       return FALSE;
@@ -8395,7 +8398,7 @@ I830CheckDevicesTimer(OsTimerPtr timer, 
             xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 			                       "Fixing display offsets.\n");
 
-            I830BIOSAdjustFrame(pScrn->pScreen->myNum, pScrn->frameX0, pScrn->frameY0, 0);
+            I830AdjustFrame(pScrn->pScreen->myNum, pScrn->frameX0, pScrn->frameY0, 0);
          }
       }
 
@@ -8419,7 +8422,7 @@ I830CheckDevicesTimer(OsTimerPtr timer, 
 
          pI830->currentMode = NULL;
          I830BIOSSwitchMode(pScrn->pScreen->myNum, pScrn->currentMode, 0);
-         I830BIOSAdjustFrame(pScrn->pScreen->myNum, pScrn->frameX0, pScrn->frameY0, 0);
+         I830AdjustFrame(pScrn->pScreen->myNum, pScrn->frameX0, pScrn->frameY0, 0);
 
          if (xf86IsEntityShared(pScrn->entityList[0])) {
 	    ScrnInfoPtr pScrn2;
@@ -8438,7 +8441,7 @@ I830CheckDevicesTimer(OsTimerPtr timer, 
 
             pI8302->currentMode = NULL;
             I830BIOSSwitchMode(pScrn2->pScreen->myNum, pScrn2->currentMode, 0);
-            I830BIOSAdjustFrame(pScrn2->pScreen->myNum, pScrn2->frameX0, pScrn2->frameY0, 0);
+            I830AdjustFrame(pScrn2->pScreen->myNum, pScrn2->frameX0, pScrn2->frameY0, 0);
 
  	    (*pScrn2->EnableDisableFBAccess) (pScrn2->pScreen->myNum, FALSE);
  	    (*pScrn2->EnableDisableFBAccess) (pScrn2->pScreen->myNum, TRUE);
@@ -8487,7 +8490,7 @@ I830InitpScrn(ScrnInfoPtr pScrn)
    pScrn->PreInit = I830BIOSPreInit;
    pScrn->ScreenInit = I830BIOSScreenInit;
    pScrn->SwitchMode = I830BIOSSwitchMode;
-   pScrn->AdjustFrame = I830BIOSAdjustFrame;
+   pScrn->AdjustFrame = I830AdjustFrame;
    pScrn->EnterVT = I830BIOSEnterVT;
    pScrn->LeaveVT = I830BIOSLeaveVT;
    pScrn->FreeScreen = I830BIOSFreeScreen;
diff-tree 995b142f510d1daab3914d336f3c0d017a043b41 (from 8e5844bbf9c8880c9eb6eff29b6db2db06b01933)
Author: Alan Hourihane <alanh at fairlite.demon.co.uk>
Date:   Tue Aug 8 12:01:39 2006 +0100

    Disable detecting of new monitors on VT switch.
    It's doesn't always work. The modesetting
    branch will deal with hotplug displays correctly.

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 84fb21a..94a2c8f 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -7765,9 +7765,13 @@ I830BIOSEnterVT(int scrnIndex, int flags
    ResetState(pScrn, FALSE);
    SetHWOperatingState(pScrn);
 
-   /* Detect monitor change and switch to suitable mode */
+#if 0
+   /* Disable this as it's clunky, and doesn't always work.
+    * The modesetting branch will deal with hotplug displays much better.
+    */
    if (!pI830->starting)
       I830DetectMonitorChange(pScrn);
+#endif
 	    
    if (!I830VESASetMode(pScrn, pScrn->currentMode))
       return FALSE;
diff-tree 8e5844bbf9c8880c9eb6eff29b6db2db06b01933 (from e4f63eaf5efb654121db148f2f8e32cc3b23b6b5)
Author: Alan Hourihane <alanh at fairlite.demon.co.uk>
Date:   Tue Aug 8 11:43:10 2006 +0100

    bump to 1.6.2 to indicate mergedfb support

diff --git a/configure.ac b/configure.ac
index b1d3524..fde8917 100644
--- a/configure.ac
+++ b/configure.ac
@@ -22,7 +22,7 @@
 
 AC_PREREQ(2.57)
 AC_INIT([xf86-video-i810],
-        1.6.1,
+        1.6.2,
         [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
         xf86-video-i810)
 
diff --git a/src/i810.h b/src/i810.h
index 740f38c..5a526fb 100644
--- a/src/i810.h
+++ b/src/i810.h
@@ -66,7 +66,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define I810_DRIVER_NAME "i810"
 #define I810_MAJOR_VERSION 1
 #define I810_MINOR_VERSION 6
-#define I810_PATCHLEVEL 1
+#define I810_PATCHLEVEL 2
 
 
 /* HWMC Surfaces */
diff --git a/src/i830_dri.h b/src/i830_dri.h
index 31232b8..b521489 100644
--- a/src/i830_dri.h
+++ b/src/i830_dri.h
@@ -10,7 +10,7 @@
 
 #define I830_MAJOR_VERSION 1
 #define I830_MINOR_VERSION 6
-#define I830_PATCHLEVEL 1
+#define I830_PATCHLEVEL 2
 
 #define I830_REG_SIZE 0x80000
 
diff-tree e4f63eaf5efb654121db148f2f8e32cc3b23b6b5 (from parents)
Merge: 633a683a4adcb9a44a54519fd7ff66aab2d12f97 e26f3e30b30a57ab4aad0267d689a9a5d7a5e877
Author: Alan Hourihane <alanh at fairlite.demon.co.uk>
Date:   Tue Aug 8 11:07:56 2006 +0100

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

diff-tree 633a683a4adcb9a44a54519fd7ff66aab2d12f97 (from e71108f1e05b7a8d8edd174eb64edd6cccacbcdc)
Author: Alan Hourihane <alanh at fairlite.demon.co.uk>
Date:   Tue Aug 8 10:23:29 2006 +0100

    Ensure palette is updated in mergedfb & clone modes

diff --git a/src/i830_cursor.c b/src/i830_cursor.c
index 1d7808b..1657f7c 100644
--- a/src/i830_cursor.c
+++ b/src/i830_cursor.c
@@ -116,9 +116,10 @@ I830InitHWCursor(ScrnInfoPtr pScrn)
       temp = INREG(CURSOR_CONTROL);
       temp &= ~(CURSOR_FORMAT_MASK | CURSOR_GAMMA_ENABLE |
 		CURSOR_ENABLE  | CURSOR_STRIDE_MASK);
-      temp |= (CURSOR_FORMAT_3C);
       if (pI830->CursorIsARGB)
-         temp |= CURSOR_GAMMA_ENABLE;
+         temp |= CURSOR_FORMAT_ARGB | CURSOR_GAMMA_ENABLE;
+      else 
+         temp |= CURSOR_FORMAT_3C;
       /* This initialises the format and leave the cursor disabled. */
       OUTREG(CURSOR_CONTROL, temp);
       /* Need to set address and size after disabling. */
@@ -588,7 +589,7 @@ I830ShowCursor(ScrnInfoPtr pScrn)
       temp = INREG(CURSOR_A_CONTROL);
       temp &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT | MCURSOR_GAMMA_ENABLE);
       if (pI830->CursorIsARGB)
-         temp |= CURSOR_MODE_64_ARGB_AX;
+         temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
       else
          temp |= CURSOR_MODE_64_4C_AX;
       temp |= (pI830->pipe << 28); /* Connect to correct pipe */
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 256ae22..84fb21a 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -3486,6 +3486,79 @@ I830LoadPalette(ScrnInfoPtr pScrn, int n
    DPRINTF(PFX, "I830LoadPalette: numColors: %d\n", numColors);
    pI830 = I830PTR(pScrn);
 
+   if (pI830->Clone || pI830->MergedFB) {
+      if (!pI830->pipe == 0) {
+         palreg = PALETTE_A;
+         dspreg = DSPACNTR;
+         dspbase = DSPABASE;
+      } else {
+         palreg = PALETTE_B;
+         dspreg = DSPBCNTR;
+         dspbase = DSPBBASE;
+      }
+   
+      /* To ensure gamma is enabled we need to turn off and on the plane */
+      temp = INREG(dspreg);
+      OUTREG(dspreg, temp & ~(1<<31));
+      OUTREG(dspbase, INREG(dspbase));
+      OUTREG(dspreg, temp | DISPPLANE_GAMMA_ENABLE);
+      OUTREG(dspbase, INREG(dspbase));
+
+      /* It seems that an initial read is needed. */
+      temp = INREG(palreg);
+
+      switch(pScrn->depth) {
+      case 15:
+       for (i = 0; i < numColors; i++) {
+         index = indices[i];
+         r = colors[index].red;
+         g = colors[index].green;
+         b = colors[index].blue;
+	 val = (r << 16) | (g << 8) | b;
+         for (j = 0; j < 8; j++) {
+	    OUTREG(palreg + index * 32 + (j * 4), val);
+         }
+       }
+       break;
+      case 16:
+       for (i = 0; i < numColors; i++) {
+         index = indices[i];
+	 r   = colors[index / 2].red;
+	 g   = colors[index].green;
+	 b   = colors[index / 2].blue;
+
+	 val = (r << 16) | (g << 8) | b;
+	 OUTREG(palreg + index * 16, val);
+	 OUTREG(palreg + index * 16 + 4, val);
+	 OUTREG(palreg + index * 16 + 8, val);
+	 OUTREG(palreg + index * 16 + 12, val);
+
+   	 if (index <= 31) {
+            r   = colors[index].red;
+	    g   = colors[(index * 2) + 1].green;
+	    b   = colors[index].blue;
+
+	    val = (r << 16) | (g << 8) | b;
+	    OUTREG(palreg + index * 32, val);
+	    OUTREG(palreg + index * 32 + 4, val);
+	    OUTREG(palreg + index * 32 + 8, val);
+	    OUTREG(palreg + index * 32 + 12, val);
+	 }
+       }
+       break;
+      default:
+       for(i = 0; i < numColors; i++) {
+	 index = indices[i];
+	 r = colors[index].red;
+	 g = colors[index].green;
+	 b = colors[index].blue;
+	 val = (r << 16) | (g << 8) | b;
+	 OUTREG(palreg + index * 4, val);
+       }
+       break;
+      }
+   }
+
    if (pI830->pipe == 0) {
       palreg = PALETTE_A;
       dspreg = DSPACNTR;
diff-tree 0fd4831fdcf4c8f43d80c66e43eff8942f89b324 (from 8d0a5138503586cbf980eb9464f2db91b72509c7)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Fri Aug 4 00:21:53 2006 -0700

    Disable dynamic front buffer mapping on i965.
    
    Moving front buffers should only be necessary for rotation.  Currently, the
    server isn't ready for it, and the method attempted to work around it caused
    crashes with DRI.  Since i965 doesn't support rotation yet, this should be
    harmless for now.

diff --git a/src/i830_dri.c b/src/i830_dri.c
index 00ff358..af0db25 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -664,21 +664,26 @@ I830DRIMapScreenRegions(ScrnInfoPtr pScr
 					     pScrn->virtualY * pI830->cpp);
 #endif
 
-   xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-              "[drm] Mapping front buffer\n");
-   if (drmAddMap(pI830->drmSubFD,
-                 (drm_handle_t)(sarea->front_offset + pI830->LinearAddr),
-                 sarea->front_size,
-		 DRM_AGP,
-                 0,
-                 (drmAddress) &sarea->front_handle) < 0) {
-      xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-                 "[drm] drmAddMap(front_handle) failed. Disabling DRI\n");
-      DRICloseScreen(pScreen);
-      return FALSE;
+   /* The I965G isn't ready for the front buffer mapping to be moved around,
+    * because of issues with rmmap, it seems.
+    */
+   if (!IS_I965G(pI830)) {
+      xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+		 "[drm] Mapping front buffer\n");
+      if (drmAddMap(pI830->drmSubFD,
+		    (drm_handle_t)(sarea->front_offset + pI830->LinearAddr),
+		    sarea->front_size,
+		    DRM_AGP,
+		    0,
+		    (drmAddress) &sarea->front_handle) < 0) {
+	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		    "[drm] drmAddMap(front_handle) failed. Disabling DRI\n");
+	 DRICloseScreen(pScreen);
+	 return FALSE;
+      }
+      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Front Buffer = 0x%08x\n",
+		 (int)sarea->front_handle);
    }
-   xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Front Buffer = 0x%08x\n",
-              (int)sarea->front_handle);
 
    if (drmAddMap(pI830->drmSubFD,
                  (drm_handle_t)(sarea->back_offset + pI830->LinearAddr),
diff-tree 8d0a5138503586cbf980eb9464f2db91b72509c7 (from aa69018c01d2fa963fb940718dbd653d6ca2c9eb)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Thu Aug 3 19:16:59 2006 -0700

    Add parenthesis so that IS_I965G doesn't make the test pass for 8-bit.

diff --git a/src/i830_video.c b/src/i830_video.c
index fca8230..64134df 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -508,7 +508,7 @@ I830InitVideo(ScreenPtr pScreen)
    /* Set up textured video if we can do it at this depth and we are on
     * supported hardware.
     */
-   if (pScrn->bitsPerPixel >= 16 && IS_I9XX(pI830) || IS_I965G(pI830)) {
+   if (pScrn->bitsPerPixel >= 16 && (IS_I9XX(pI830) || IS_I965G(pI830))) {
       texturedAdaptor = I830SetupImageVideoTextured(pScreen);
       if (texturedAdaptor != NULL) {
 	 adaptors[num_adaptors++] = texturedAdaptor;
diff-tree aa69018c01d2fa963fb940718dbd653d6ca2c9eb (from d15f87110807111ab7d71f1254ebe3dfef1fee80)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Thu Aug 3 19:12:15 2006 -0700

    Turn off video debugging now that it appears to work fine.

diff --git a/src/i830_video.c b/src/i830_video.c
index e3384dd..fca8230 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -1,4 +1,4 @@
-#define VIDEO_DEBUG 1
+#define VIDEO_DEBUG 0
 /***************************************************************************
  
 Copyright 2000 Intel Corporation.  All Rights Reserved. 
diff-tree d15f87110807111ab7d71f1254ebe3dfef1fee80 (from parents)
Merge: a79aa0d7b27b0b9b032472776d7dda410fd66a98 d56ffa5f35e3cf4262d66469052b2122fdb24027
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Thu Aug 3 19:08:34 2006 -0700

    Merge branch 'broadwater-video-rehash' into i965
    
    The previous merge wasn't done on a synced-up tree, and missed necessary
    changes.

diff-tree a79aa0d7b27b0b9b032472776d7dda410fd66a98 (from parents)
Merge: 760021e3983f7783900075b8c9603bd4fbe7e0a2 f9e94c17c55e4c75802d8574c908744e286e7843
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Thu Aug 3 17:58:56 2006 -0700

    Merge branch 'broadwater-video-rehash' into broadwater
    
    Conflicts:
    
    	src/Makefile.am
    	src/common.h
    	src/i810_driver.c
    	src/i810_reg.h
    	src/i830.h
    	src/i830_accel.c
    	src/i830_cursor.c
    	src/i830_dri.c
    	src/i830_dri.h
    	src/i830_driver.c
    	src/i830_memory.c
    	src/i830_rotate.c
    	src/i830_video.c

diff --cc src/i830_cursor.c
index 9f22a66,0475093..c835cae
@@@ -548,10 -544,10 +546,10 @@@
        }
     } else {
        temp = INREG(CURSOR_CONTROL);
 -      temp &= ~(CURSOR_FORMAT_MASK);
 +      temp &= ~(CURSOR_FORMAT_MASK | CURSOR_GAMMA_ENABLE);
        temp |= CURSOR_ENABLE;
        if (pI830->CursorIsARGB)
-          temp |= CURSOR_FORMAT_ARGB | CURSOR_GAMMA_ENABLE;
+          temp |= CURSOR_FORMAT_ARGB;
        else 
           temp |= CURSOR_FORMAT_3C;
        OUTREG(CURSOR_CONTROL, temp);
diff --cc src/i830_dri.c
index 5c47289,2eacc5b..00ff358
@@@ -81,9 -81,11 +81,11 @@@
  #include "i830.h"
  #include "i830_dri.h"
  
+ #include "dristruct.h"
+ 
  static char I830KernelDriverName[] = "i915";
  static char I830ClientDriverName[] = "i915";
 -static char BRWClientDriverName[] = "brw";
 +static char I965ClientDriverName[] = "i965";
  
  static Bool I830InitVisualConfigs(ScreenPtr pScreen);
  static Bool I830CreateContext(ScreenPtr pScreen, VisualPtr visual,
@@@ -493,13 -499,16 +499,16 @@@
     pDRIInfo->ddxDriverMajorVersion = I830_MAJOR_VERSION;
     pDRIInfo->ddxDriverMinorVersion = I830_MINOR_VERSION;
     pDRIInfo->ddxDriverPatchVersion = I830_PATCHLEVEL;
 -   pDRIInfo->frameBufferPhysicalAddress = (pointer) pI830->LinearAddr +
 +#if 1 /* Remove this soon - see bug 5714 */
 +   pDRIInfo->frameBufferPhysicalAddress = (char *) pI830->LinearAddr +
  					  pI830->FrontBuffer.Start;
 -#if 0
     pDRIInfo->frameBufferSize = ROUND_TO_PAGE(pScrn->displayWidth *
  					     pScrn->virtualY * pI830->cpp);
-    pDRIInfo->frameBufferStride = pScrn->displayWidth * pI830->cpp;
+ #else
+    /* For rotation we map a 0 length framebuffer as we remap ourselves later */
+    pDRIInfo->frameBufferSize = 0;
  #endif
+    pDRIInfo->frameBufferStride = pScrn->displayWidth * pI830->cpp;
     pDRIInfo->ddxDrawableTableEntry = I830_MAX_DRAWABLES;
  
     if (SAREA_MAX_DRAWABLES < I830_MAX_DRAWABLES)
diff --cc src/i830_driver.c
index d49e027,1e1e02d..a7e418b
@@@ -5343,7 -5325,11 +5398,11 @@@
        xf86DisableRandR(); /* Disable built-in RandR extension */
        shadowSetup(pScreen);
        /* support all rotations */
-       I830RandRInit(pScreen, RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_180 | RR_Rotate_270);
 -      if (IS_BROADWATER(pI830)) {
 -	 I830RandRInit(pScreen, RR_Rotate_0); /* only 0 degrees for Broadwater */
++      if (IS_I965G(pI830)) {
++	 I830RandRInit(pScreen, RR_Rotate_0); /* only 0 degrees for I965G */
+       } else {
+ 	 I830RandRInit(pScreen, RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_180 | RR_Rotate_270);
+       }
        pI830->PointerMoved = pScrn->PointerMoved;
        pScrn->PointerMoved = I830PointerMoved;
        pI830->CreateScreenResources = pScreen->CreateScreenResources;
diff --cc src/i830_rotate.c
index 716f425,e211b36..425eeef
@@@ -404,15 -410,15 +405,15 @@@
        if (pI830->disableTiling)
           use_fence = 0;
        else
-          use_fence = 4;
+          use_fence = MS3_USE_FENCE_REGS;
        
        if (pI830->cpp == 1)
 -         use_fence |= MAPSURF_8BIT;
 +	 use_fence |= MAPSURF_8BIT;
        else
        if (pI830->cpp == 2)
 -         use_fence |= MAPSURF_16BIT;
 +	 use_fence |= MAPSURF_16BIT;
        else
 -         use_fence |= 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();
diff --cc src/i830_video.c
index 300930d,e495042..3cd00fc
@@@ -453,27 -466,47 +475,47 @@@
     }
  #endif
  
-    if (pScrn->bitsPerPixel != 8) {
-       newAdaptor = I830SetupImageVideo(pScreen);
+    num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors);
+    /* Give our adaptor list enough space for the overlay and/or texture video
+     * adaptors.
+     */
+    newAdaptors = xalloc((num_adaptors + 2) * sizeof(XF86VideoAdaptorPtr *));
+    if (newAdaptors == NULL)
+       return;
+ 
+    memcpy(newAdaptors, adaptors, num_adaptors * sizeof(XF86VideoAdaptorPtr));
+    adaptors = newAdaptors;
+ 
+    /* Add the adaptors supported by our hardware.  First, set up the atoms
+     * that will be used by both output adaptors.
+     */
+    xvBrightness = MAKE_ATOM("XV_BRIGHTNESS");
+    xvContrast = MAKE_ATOM("XV_CONTRAST");
+ 
+    /* Set up overlay video if we can do it at this depth. */
 -   if (!IS_BROADWATER(pI830) && pScrn->bitsPerPixel != 8) {
++   if (!IS_I965G(pI830) && pScrn->bitsPerPixel != 8) {
+       overlayAdaptor = I830SetupImageVideoOverlay(pScreen);
+       if (overlayAdaptor != NULL) {
+ 	 adaptors[num_adaptors++] = overlayAdaptor;
+ 	 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Set up overlay video\n");
+       } else {
+ 	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ 		    "Failed to set up overlay video\n");
+       }
        I830InitOffscreenImages(pScreen);
     }
  
-    num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors);
- 
-    if (newAdaptor) {
-       if (!num_adaptors) {
- 	 num_adaptors = 1;
- 	 adaptors = &newAdaptor;
+    /* Set up textured video if we can do it at this depth and we are on
+     * supported hardware.
+     */
 -   if (pScrn->bitsPerPixel >= 16 && IS_I9XX(pI830) || IS_BROADWATER(pI830)) {
++   if (pScrn->bitsPerPixel >= 16 && IS_I9XX(pI830) || IS_I965G(pI830)) {
+       texturedAdaptor = I830SetupImageVideoTextured(pScreen);
+       if (texturedAdaptor != NULL) {
+ 	 adaptors[num_adaptors++] = texturedAdaptor;
+ 	 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Set up textured video\n");
        } else {
- 	 newAdaptors =			/* need to free this someplace */
- 	       xalloc((num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr *));
- 	 if (newAdaptors) {
- 	    memcpy(newAdaptors, adaptors, num_adaptors *
- 		   sizeof(XF86VideoAdaptorPtr));
- 	    newAdaptors[num_adaptors] = newAdaptor;
- 	    adaptors = newAdaptors;
- 	    num_adaptors++;
- 	 }
+ 	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ 		    "Failed to set up textured video\n");
        }
     }
  
@@@ -1985,48 -3572,63 +3581,63 @@@
     case FOURCC_I420:
        srcPitch = (width + 3) & ~3;
        srcPitch2 = ((width >> 1) + 3) & ~3;
- #if 1
-       if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
-          dstPitch = ((height / 2) + 63) & ~63;
-          size = dstPitch * width * 3;
-       } else {
-          dstPitch = ((width / 2) + 63) & ~63;	/* of chroma */
-          size = dstPitch * height * 3;
+       if (pPriv->textured) {
+ 	 destId = FOURCC_YUY2;
        }
- #else
+       break;
+    case FOURCC_UYVY:
+    case FOURCC_YUY2:
+    default:
+       srcPitch = width << 1;
+       break;
+    }
+ 
+    /* Only needs to be DWORD-aligned for textured on i915, but overlay has
+     * stricter requirements.
+     */
+    if (pPriv->textured) {
+       pitchAlignMask = 3;
+    } else {
 -      if (IS_BROADWATER(pI830))
++      if (IS_I965G(pI830))
+ 	 pitchAlignMask = 255;
+       else
+ 	 pitchAlignMask = 63;
+    }
+ 
+    /* Determine the desired destination pitch (representing the chroma's pitch,
+     * in the planar case.
+     */
+    switch (destId) {
+    case FOURCC_YV12:
+    case FOURCC_I420:
        if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
-          dstPitch = ((height / 2) + 255) & ~255;
+          dstPitch = ((height / 2) + pitchAlignMask) & ~pitchAlignMask;
           size = dstPitch * width * 3;
        } else {
-          dstPitch = ((width / 2) + 255) & ~255;	/* of chroma */
+          dstPitch = ((width / 2) + pitchAlignMask) & ~pitchAlignMask;
           size = dstPitch * height * 3;
        }
- #endif
        break;
     case FOURCC_UYVY:
     case FOURCC_YUY2:
     default:
-       srcPitch = width << 1;
- #if 1
        if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
-          dstPitch = ((height << 1) + 63) & ~63;
+          dstPitch = ((height << 1) + pitchAlignMask) & ~pitchAlignMask;
           size = dstPitch * width;
        } else {
-          dstPitch = ((width << 1) + 63) & ~63;	/* of chroma */
+          dstPitch = ((width << 1) + pitchAlignMask) & ~pitchAlignMask;
           size = dstPitch * height;
        }
- #else
-       if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
-          dstPitch = ((height << 1) + 255) & ~255;
-          size = dstPitch * width;
-       } else {
-          dstPitch = ((width << 1) + 255) & ~255;	/* of chroma */
-          size = dstPitch * height;
-       }
- #endif
        break;
     }
+ #if 0
     ErrorF("srcPitch: %d, dstPitch: %d, size: %d\n", srcPitch, dstPitch, size);
+ #endif
+ 
 -   if (IS_BROADWATER(pI830))
++   if (IS_I965G(pI830))
+       extraLinear = BRW_LINEAR_EXTRA;
+    else
+       extraLinear = 0;
  
     /* size is multiplied by 2 because we have two buffers that are flipping */
     pPriv->linear = I830AllocateMemory(pScrn, pPriv->linear,
@@@ -2103,15 -3728,24 +3737,24 @@@
        break;
     }
  
-    /* update cliplist */
-    if (!RegionsEqual(&pPriv->clip, clipBoxes)) {
-       REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes);
-       xf86XVFillKeyHelper(pScreen, pPriv->colorKey, clipBoxes);
-    }
- 
-    I830DisplayVideo(pScrn, id, width, height, dstPitch,
- 		    x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h);
+    if (!pPriv->textured) {
+       /* update cliplist */
+       if (!RegionsEqual(&pPriv->clip, clipBoxes)) {
+  	REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes);
+ 	 xf86XVFillKeyHelper(pScreen, pPriv->colorKey, clipBoxes);
+       }
  
+       I830DisplayVideo(pScrn, destId, width, height, dstPitch,
+ 		       x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h);
 -   } else if (IS_BROADWATER(pI830)) {
++   } else if (IS_I965G(pI830)) {
+       BroadwaterDisplayVideoTextured (pScrn, pPriv, destId, clipBoxes, width, height,
+ 				      dstPitch, x1, y1, x2, y2,
+ 				      src_w, src_h, drw_w, drw_h, pDraw);
+    } else {
+       I915DisplayVideoTextured(pScrn, pPriv, destId, clipBoxes, width, height,
+ 			       dstPitch, x1, y1, x2, y2,
+ 			       src_w, src_h, drw_w, drw_h, pDraw);
+    }
     pPriv->videoStatus = CLIENT_VIDEO_ON;
  
     return Success;
diff-tree 760021e3983f7783900075b8c9603bd4fbe7e0a2 (from e26f3e30b30a57ab4aad0267d689a9a5d7a5e877)
Author: Alan Hourihane <alanh at tungstengraphics.com>
Date:   Thu Aug 3 17:08:39 2006 -0700

    Add current Tungsten Graphics code drop for i965 support.

diff --git a/src/common.h b/src/common.h
index 31e67b9..1e3327c 100644
--- a/src/common.h
+++ b/src/common.h
@@ -277,6 +277,26 @@ extern int I810_DEBUG;
 #define PCI_CHIP_I945_GM_BRIDGE 0x27A0
 #endif
 
+#ifndef PCI_CHIP_I965_G_1
+#define PCI_CHIP_I965_G_1		0x2982
+#define PCI_CHIP_I965_G_1_BRIDGE 	0x2980
+#endif
+
+#ifndef PCI_CHIP_I965_Q
+#define PCI_CHIP_I965_Q		0x2992
+#define PCI_CHIP_I965_Q_BRIDGE 	0x2990
+#endif
+
+#ifndef PCI_CHIP_I965_G
+#define PCI_CHIP_I965_G		0x29A2
+#define PCI_CHIP_I965_G_BRIDGE 	0x29A0
+#endif
+
+#ifndef PCI_CHIP_I946_GZ
+#define PCI_CHIP_I946_GZ		0x2972
+#define PCI_CHIP_I946_GZ_BRIDGE 	0x2970
+#endif
+
 #define IS_I810(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I810 ||	\
 			pI810->PciInfo->chipType == PCI_CHIP_I810_DC100 || \
 			pI810->PciInfo->chipType == PCI_CHIP_I810_E)
@@ -292,7 +312,8 @@ extern int I810_DEBUG;
 #define IS_I915GM(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I915_GM)
 #define IS_I945G(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I945_G)
 #define IS_I945GM(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I945_GM)
-#define IS_I9XX(pI810) (IS_I915G(pI810) || IS_I915GM(pI810) || IS_I945G(pI810) || IS_I945GM(pI810))
+#define IS_I965G(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I965_G || pI810->PciInfo->chipType == PCI_CHIP_I965_G_1 || pI810->PciInfo->chipType == PCI_CHIP_I965_Q || pI810->PciInfo->chipType == PCI_CHIP_I946_GZ)
+#define IS_I9XX(pI810) (IS_I915G(pI810) || IS_I915GM(pI810) || IS_I945G(pI810) || IS_I945GM(pI810) || IS_I965G(pI810))
 
 #define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810) || IS_I915GM(pI810) || IS_I945GM(pI810))
 
diff --git a/src/i810_driver.c b/src/i810_driver.c
index 7d854df..cef6d18 100644
--- a/src/i810_driver.c
+++ b/src/i810_driver.c
@@ -140,6 +140,10 @@ static SymTabRec I810Chipsets[] = {
    {PCI_CHIP_I915_GM,		"915GM"},
    {PCI_CHIP_I945_G,		"945G"},
    {PCI_CHIP_I945_GM,		"945GM"},
+   {PCI_CHIP_I965_G,		"965G"},
+   {PCI_CHIP_I965_G_1,		"965G"},
+   {PCI_CHIP_I965_Q,		"965Q"},
+   {PCI_CHIP_I946_GZ,		"946GZ"},
    {-1,				NULL}
 };
 
@@ -159,6 +163,10 @@ static PciChipsets I810PciChipsets[] = {
    {PCI_CHIP_I915_GM,		PCI_CHIP_I915_GM,	RES_SHARED_VGA},
    {PCI_CHIP_I945_G,		PCI_CHIP_I945_G,	RES_SHARED_VGA},
    {PCI_CHIP_I945_GM,		PCI_CHIP_I945_GM,	RES_SHARED_VGA},
+   {PCI_CHIP_I965_G,		PCI_CHIP_I965_G,	RES_SHARED_VGA},
+   {PCI_CHIP_I965_G_1,		PCI_CHIP_I965_G_1,	RES_SHARED_VGA},
+   {PCI_CHIP_I965_Q,		PCI_CHIP_I965_Q,	RES_SHARED_VGA},
+   {PCI_CHIP_I946_GZ,		PCI_CHIP_I946_GZ,	RES_SHARED_VGA},
    {-1,				-1, RES_UNDEFINED }
 };
 
@@ -578,6 +586,10 @@ I810Probe(DriverPtr drv, int flags)
 	    case PCI_CHIP_I915_GM:
 	    case PCI_CHIP_I945_G:
 	    case PCI_CHIP_I945_GM:
+	    case PCI_CHIP_I965_G:
+	    case PCI_CHIP_I965_G_1:
+	    case PCI_CHIP_I965_Q:
+	    case PCI_CHIP_I946_GZ:
     	       xf86SetEntitySharable(usedChips[i]);
 
     	       /* Allocate an entity private if necessary */		
diff --git a/src/i810_reg.h b/src/i810_reg.h
index e52375f..ffa53d3 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -293,8 +293,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define STATE_VAR_UPDATE_DISABLE     0x02
 #define PAL_STIP_DISABLE             0x01
 
-#define INST_DONE                0x2090
-#define INST_PS                  0x20c4
 
 #define MEMMODE                  0x20dc
 
@@ -303,6 +301,66 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
  */
 #define IPEIR                  0x2088
 #define IPEHR                  0x208C
+#define INST_DONE                0x2090
+#define INST_PS                  0x20c4
+#define IPEIR_I965                  0x2064 /* i965 */
+#define IPEHR_I965                  0x2068 /* i965 */
+#define INST_DONE_I965              0x206c
+#define INST_PS_I965                0x2070
+#define ACTHD                 0x2074
+#define DMA_FADD_P             0x2078
+#define INST_DONE_1              0x207c
+
+#define CACHE_MODE_0           0x2120
+#define CACHE_MODE_1           0x2124
+#define MI_ARB_STATE           0x20e4
+
+#define WIZ_CTL                0x7c00
+#define WIZ_CTL_SINGLE_SUBSPAN  (1<<6)
+#define WIZ_CTL_IGNORE_STALLS  (1<<5)
+
+#define SVG_WORK_CTL           0x7408
+
+#define TS_CTL                 0x7e00
+#define TS_MUX_ERR_CODE        (0<<8)
+#define TS_MUX_URB_0           (1<<8)
+#define TS_MUX_DISPATCH_ID_0   (10<<8)
+#define TS_MUX_ERR_CODE_VALID  (15<<8)
+#define TS_MUX_TID_0           (16<<8)
+#define TS_MUX_EUID_0          (18<<8)
+#define TS_MUX_FFID_0          (22<<8)
+#define TS_MUX_EOT             (26<<8)
+#define TS_MUX_SIDEBAND_0      (27<<8)
+#define TS_SNAP_ALL_CHILD      (1<<2)
+#define TS_SNAP_ALL_ROOT       (1<<1)
+#define TS_SNAP_ENABLE         (1<<0)
+
+#define TS_DEBUG_DATA          0x7e0c
+
+#define TD_CTL                 0x8000
+#define TD_CTL2                0x8004
+
+
+#define ECOSKPD 0x21d0
+#define EXCC    0x2028
+
+/* I965 debug regs:
+ */
+#define IA_VERTICES_COUNT_QW   0x2310
+#define IA_PRIMITIVES_COUNT_QW 0x2318
+#define VS_INVOCATION_COUNT_QW 0x2320
+#define GS_INVOCATION_COUNT_QW 0x2328
+#define GS_PRIMITIVES_COUNT_QW 0x2330
+#define CL_INVOCATION_COUNT_QW 0x2338
+#define CL_PRIMITIVES_COUNT_QW 0x2340
+#define PS_INVOCATION_COUNT_QW 0x2348
+#define PS_DEPTH_COUNT_QW      0x2350
+#define TIMESTAMP_QW           0x2358
+#define CLKCMP_QW              0x2360
+
+
+
+
 
 
 /* General error reporting regs, p296
@@ -366,6 +424,13 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define FENCE            0x2000
 #define FENCE_NR         8
 
+#define FENCE_NEW        0x3000
+#define FENCE_NEW_NR     16
+
+#define FENCE_LINEAR     0
+#define FENCE_XMAJOR	 1
+#define FENCE_YMAJOR  	 2
+
 #define I915G_FENCE_START_MASK	0x0ff00000
 
 #define I830_FENCE_START_MASK	0x07f80000
@@ -772,6 +837,12 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define DSPBPOS			0x7118C
 #define DSPBSIZE		0x71190
 
+#define DSPASURF		0x7019C
+#define DSPATILEOFF		0x701A4
+
+#define DSPBSURF		0x7119C
+#define DSPBTILEOFF		0x711A4
+
 /* Various masks for reserved bits, etc. */
 #define I830_FWATER1_MASK        (~((1<<11)|(1<<10)|(1<<9)|      \
         (1<<8)|(1<<26)|(1<<25)|(1<<24)|(1<<5)|(1<<4)|(1<<3)|    \
diff --git a/src/i830.h b/src/i830.h
index 14e921d..0234ff5 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];
 } I830RegRec, *I830RegPtr;
 
 typedef struct {
@@ -238,6 +238,12 @@ 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;
@@ -377,6 +383,9 @@ typedef struct _I830Rec {
    Bool devicePresence;
 
    OsTimerPtr devicesTimer;
+
+   CARD32 savedAsurf;
+   CARD32 savedBsurf;
 } I830Rec;
 
 #define I830PTR(p) ((I830Ptr)((p)->driverPrivate))
diff --git a/src/i830_accel.c b/src/i830_accel.c
index a11f64b..aa43cbe 100644
--- a/src/i830_accel.c
+++ b/src/i830_accel.c
@@ -133,6 +133,7 @@ void
 I830Sync(ScrnInfoPtr pScrn)
 {
    I830Ptr pI830 = I830PTR(pScrn);
+   int flags = MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE;
 
    if (I810_DEBUG & (DEBUG_VERBOSE_ACCEL | DEBUG_VERBOSE_SYNC))
       ErrorF("I830Sync\n");
@@ -147,13 +148,17 @@ I830Sync(ScrnInfoPtr pScrn)
 
    if (pI830->entityPrivate && !pI830->entityPrivate->RingRunning) return;
 
+   if (IS_I965G(pI830))
+      flags = 0;
+
    /* Send a flush instruction and then wait till the ring is empty.
     * This is stronger than waiting for the blitter to finish as it also
     * flushes the internal graphics caches.
     */
+   
    {
       BEGIN_LP_RING(2);
-      OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE);
+      OUT_RING(MI_FLUSH | flags);
       OUT_RING(MI_NOOP);		/* pad to quadword */
       ADVANCE_LP_RING();
    }
@@ -168,9 +173,13 @@ void
 I830EmitFlush(ScrnInfoPtr pScrn)
 {
    I830Ptr pI830 = I830PTR(pScrn);
+   int flags = MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE;
+
+   if (IS_I965G(pI830))
+      flags = 0;
 
    BEGIN_LP_RING(2);
-   OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE);
+   OUT_RING(MI_FLUSH | flags);
    OUT_RING(MI_NOOP);		/* pad to quadword */
    ADVANCE_LP_RING();
 }
@@ -386,6 +395,28 @@ I830AccelInit(ScreenPtr pScreen)
    return XAAInit(pScreen, infoPtr);
 }
 
+static unsigned int
+CheckTiling(ScrnInfoPtr pScrn)
+{
+   I830Ptr pI830 = I830PTR(pScrn);
+   unsigned int tiled = 0;
+
+    /* Check tiling */
+   if (IS_I965G(pI830)) {
+      if (pI830->bufferOffset == pScrn->fbOffset && pI830->front_tiled == FENCE_XMAJOR)
+         tiled = 1;
+      if (pI830->bufferOffset == pI830->RotatedMem.Start && pI830->rotated_tiled == FENCE_XMAJOR)
+         tiled = 1;
+      if (pI830->bufferOffset == pI830->BackBuffer.Start && pI830->back_tiled == FENCE_XMAJOR)
+         tiled = 1;
+      /* not really supported as it's always YMajor tiled */
+      if (pI830->bufferOffset == pI830->DepthBuffer.Start && pI830->depth_tiled == FENCE_XMAJOR)
+         tiled = 1;
+   }
+
+   return tiled;
+}
+
 void
 I830SetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
 		      unsigned int planemask)
@@ -439,6 +470,9 @@ I830SubsequentSolidFillRect(ScrnInfoPtr 
 
       ADVANCE_LP_RING();
    }
+
+   if (IS_I965G(pI830))
+      I830EmitFlush(pScrn);
 }
 
 void
@@ -473,6 +507,7 @@ I830SubsequentScreenToScreenCopy(ScrnInf
 {
    I830Ptr pI830 = I830PTR(pScrn);
    int dst_x2, dst_y2;
+   unsigned int tiled = CheckTiling(pScrn);
 
    if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
       ErrorF("I830SubsequentScreenToScreenCopy %d,%d - %d,%d %dx%d\n",
@@ -481,14 +516,18 @@ I830SubsequentScreenToScreenCopy(ScrnInf
    dst_x2 = dst_x1 + w;
    dst_y2 = dst_y1 + h;
 
+   if (tiled)
+      pI830->BR[13] = ((pI830->BR[13] & 0xFFFF) >> 2) | 
+					(pI830->BR[13] & 0xFFFF0000);
+
    {
       BEGIN_LP_RING(8);
 
       if (pScrn->bitsPerPixel == 32) {
 	 OUT_RING(XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
-		  XY_SRC_COPY_BLT_WRITE_RGB);
+		  XY_SRC_COPY_BLT_WRITE_RGB | tiled << 15 | tiled << 11);
       } else {
-	 OUT_RING(XY_SRC_COPY_BLT_CMD);
+	 OUT_RING(XY_SRC_COPY_BLT_CMD | tiled << 15 | tiled << 11);
       }
       OUT_RING(pI830->BR[13]);
       OUT_RING((dst_y1 << 16) | (dst_x1 & 0xffff));
@@ -500,6 +539,9 @@ I830SubsequentScreenToScreenCopy(ScrnInf
 
       ADVANCE_LP_RING();
    }
+
+   if (IS_I965G(pI830))
+      I830EmitFlush(pScrn);
 }
 
 static void
@@ -541,6 +583,7 @@ I830SubsequentMono8x8PatternFillRect(Scr
 {
    I830Ptr pI830 = I830PTR(pScrn);
    int x1, x2, y1, y2;
+   unsigned int tiled = CheckTiling(pScrn);
 
    x1 = x;
    x2 = x + w;
@@ -550,16 +593,22 @@ I830SubsequentMono8x8PatternFillRect(Scr
    if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
       ErrorF("I830SubsequentMono8x8PatternFillRect\n");
 
+   if (tiled)
+      pI830->BR[13] = ((pI830->BR[13] & 0xFFFF) >> 2) | 
+					(pI830->BR[13] & 0xFFFF0000);
+
    {
       BEGIN_LP_RING(10);
 
       if (pScrn->bitsPerPixel == 32) {
 	 OUT_RING(XY_MONO_PAT_BLT_CMD | XY_MONO_PAT_BLT_WRITE_ALPHA |
 		  XY_MONO_PAT_BLT_WRITE_RGB |
+		  tiled << 11 |
 		  ((patty << 8) & XY_MONO_PAT_VERT_SEED) |
 		  ((pattx << 12) & XY_MONO_PAT_HORT_SEED));
       } else {
 	 OUT_RING(XY_MONO_PAT_BLT_CMD |
+		  tiled << 11 |
 		  ((patty << 8) & XY_MONO_PAT_VERT_SEED) |
 		  ((pattx << 12) & XY_MONO_PAT_HORT_SEED));
       }
@@ -574,6 +623,9 @@ I830SubsequentMono8x8PatternFillRect(Scr
       OUT_RING(0);
       ADVANCE_LP_RING();
    }
+
+   if (IS_I965G(pI830))
+      I830EmitFlush(pScrn);
 }
 
 static void
@@ -649,6 +701,7 @@ static void
 I830SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
 {
    I830Ptr pI830 = I830PTR(pScrn);
+   unsigned int tiled = CheckTiling(pScrn);
 
    if (pI830->init == 0) {
       pI830->BR[12] = (pI830->AccelInfoRec->ScanlineColorExpandBuffers[0] -
@@ -666,14 +719,19 @@ I830SubsequentColorExpandScanline(ScrnIn
       ErrorF("I830SubsequentColorExpandScanline %d (addr %x)\n",
 	     bufno, pI830->BR[12]);
 
+   if (tiled)
+      pI830->BR[13] = ((pI830->BR[13] & 0xFFFF) >> 2) | 
+					(pI830->BR[13] & 0xFFFF0000);
+
    {
       BEGIN_LP_RING(8);
 
       if (pScrn->bitsPerPixel == 32) {
 	 OUT_RING(XY_MONO_SRC_BLT_CMD | XY_MONO_SRC_BLT_WRITE_ALPHA |
+		  tiled << 11 |
 		  XY_MONO_SRC_BLT_WRITE_RGB);
       } else {
-	 OUT_RING(XY_MONO_SRC_BLT_CMD);
+	 OUT_RING(XY_MONO_SRC_BLT_CMD | tiled << 11);
       }
       OUT_RING(pI830->BR[13]);
       OUT_RING(0);			/* x1 = 0, y1 = 0 */
@@ -690,6 +748,9 @@ I830SubsequentColorExpandScanline(ScrnIn
     */
    pI830->BR[9] += pScrn->displayWidth * pI830->cpp;
    I830GetNextScanlineColorExpandBuffer(pScrn);
+
+   if (IS_I965G(pI830))
+      I830EmitFlush(pScrn);
 }
 
 #if DO_SCANLINE_IMAGE_WRITE
@@ -741,6 +802,7 @@ static void
 I830SubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno)
 {
    I830Ptr pI830 = I830PTR(pScrn);
+   unsigned int tiled = CheckTiling(pScrn);
 
    if (pI830->init == 0) {
       pI830->BR[12] = (pI830->AccelInfoRec->ScanlineColorExpandBuffers[0] -
@@ -763,9 +825,10 @@ I830SubsequentImageWriteScanline(ScrnInf
 
       if (pScrn->bitsPerPixel == 32) {
 	 OUT_RING(XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
+		  tiled << 11 |
 		  XY_SRC_COPY_BLT_WRITE_RGB);
       } else {
-	 OUT_RING(XY_SRC_COPY_BLT_CMD);
+	 OUT_RING(XY_SRC_COPY_BLT_CMD | tiled << 11);
       }
       OUT_RING(pI830->BR[13]);
       OUT_RING(0);			/* x1 = 0, y1 = 0 */
diff --git a/src/i830_common.h b/src/i830_common.h
index a27bc01..c3ef4cd 100644
--- a/src/i830_common.h
+++ b/src/i830_common.h
@@ -84,7 +84,7 @@ typedef struct {
 	drmTextureRegion texList[I830_NR_TEX_REGIONS+1];
         int last_upload;	/* last time texture was uploaded */
         int last_enqueue;	/* last time a buffer was enqueued */
-	int last_dispatch;	/* age of the most recently dispatched buffer */
+	volatile int last_dispatch;	/* age of the most recently dispatched buffer */
 	int ctxOwner;		/* last context to upload state */
 	int texAge;
         int pf_enabled;		/* is pageflipping allowed? */
@@ -115,6 +115,12 @@ typedef struct {
 	int rotated_size;
 	int rotated_pitch;
 	int virtualX, virtualY;
+
+        unsigned int front_tiled;
+        unsigned int back_tiled;
+        unsigned int depth_tiled;
+        unsigned int rotated_tiled;
+        unsigned int rotated2_tiled;
 } drmI830Sarea;
 
 /* Flags for perf_boxes
diff --git a/src/i830_cursor.c b/src/i830_cursor.c
index e465b98..9f22a66 100644
--- a/src/i830_cursor.c
+++ b/src/i830_cursor.c
@@ -91,32 +91,46 @@ I830InitHWCursor(ScrnInfoPtr pScrn)
       temp = INREG(CURSOR_A_CONTROL);
       temp &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE | MCURSOR_MEM_TYPE_LOCAL |
 		MCURSOR_PIPE_SELECT);
+      if(pI830->CursorIsARGB)
+	 temp |= MCURSOR_GAMMA_ENABLE;
       temp |= CURSOR_MODE_DISABLE;
       temp |= (pI830->pipe << 28);
-      if(pI830->CursorIsARGB)
-         temp |= MCURSOR_GAMMA_ENABLE;
       /* Need to set control, then address. */
       OUTREG(CURSOR_A_CONTROL, temp);
-      if (pI830->CursorIsARGB)
-         OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Physical);
-      else
-         OUTREG(CURSOR_A_BASE, pI830->CursorMem->Physical);
+      if (pI830->CursorNeedsPhysical) {
+         if (pI830->CursorIsARGB)
+            OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Physical);
+         else
+            OUTREG(CURSOR_A_BASE, pI830->CursorMem->Physical);
+      } else {
+         if (pI830->CursorIsARGB)
+            OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Start);
+         else
+            OUTREG(CURSOR_A_BASE, pI830->CursorMem->Start);
+      }
       if (pI830->Clone) {
          temp &= ~MCURSOR_PIPE_SELECT;
          temp |= (!pI830->pipe << 28);
          OUTREG(CURSOR_B_CONTROL, temp);
-         if (pI830->CursorIsARGB)
-            OUTREG(CURSOR_B_BASE, pI830->CursorMemARGB->Physical);
-         else
-            OUTREG(CURSOR_B_BASE, pI830->CursorMem->Physical);
+         if (pI830->CursorNeedsPhysical) {
+            if (pI830->CursorIsARGB)
+               OUTREG(CURSOR_B_BASE, pI830->CursorMemARGB->Physical);
+            else
+               OUTREG(CURSOR_B_BASE, pI830->CursorMem->Physical);
+	 } else {
+            if (pI830->CursorIsARGB)
+               OUTREG(CURSOR_B_BASE, pI830->CursorMemARGB->Start);
+            else
+               OUTREG(CURSOR_B_BASE, pI830->CursorMem->Start);
+	 }
       }
    } else {
       temp = INREG(CURSOR_CONTROL);
       temp &= ~(CURSOR_FORMAT_MASK | CURSOR_GAMMA_ENABLE |
 		CURSOR_ENABLE  | CURSOR_STRIDE_MASK);
       temp |= (CURSOR_FORMAT_3C);
-      if (pI830->CursorIsARGB)
-         temp |= CURSOR_GAMMA_ENABLE;
+      if(pI830->CursorIsARGB)
+	 temp |= CURSOR_GAMMA_ENABLE;
       /* This initialises the format and leave the cursor disabled. */
       OUTREG(CURSOR_CONTROL, temp);
       /* Need to set address and size after disabling. */
@@ -451,15 +465,29 @@ I830SetCursorPosition(ScrnInfoPtr pScrn,
 
    /* have to upload the base for the new position */
    if (IS_I9XX(pI830)) {
-      if (pI830->CursorIsARGB)
-         OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Physical);
-      else
-         OUTREG(CURSOR_A_BASE, pI830->CursorMem->Physical);
-      if (pI830->Clone) {
+      if (pI830->CursorNeedsPhysical) {
          if (pI830->CursorIsARGB)
-            OUTREG(CURSOR_B_BASE, pI830->CursorMemARGB->Physical);
+            OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Physical);
          else
-            OUTREG(CURSOR_B_BASE, pI830->CursorMem->Physical);
+            OUTREG(CURSOR_A_BASE, pI830->CursorMem->Physical);
+      } else {
+         if (pI830->CursorIsARGB)
+            OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Start);
+         else
+            OUTREG(CURSOR_A_BASE, pI830->CursorMem->Start);
+      }
+      if (pI830->Clone) {
+         if (pI830->CursorNeedsPhysical) {
+            if (pI830->CursorIsARGB)
+               OUTREG(CURSOR_B_BASE, pI830->CursorMemARGB->Physical);
+            else
+               OUTREG(CURSOR_B_BASE, pI830->CursorMem->Physical);
+	 } else {
+            if (pI830->CursorIsARGB)
+               OUTREG(CURSOR_B_BASE, pI830->CursorMemARGB->Start);
+            else
+               OUTREG(CURSOR_B_BASE, pI830->CursorMem->Start);
+	 }
       }
    }
 }
@@ -483,7 +511,7 @@ I830ShowCursor(ScrnInfoPtr pScrn)
    pI830->cursorOn = TRUE;
    if (IS_MOBILE(pI830) || IS_I9XX(pI830)) {
       temp = INREG(CURSOR_A_CONTROL);
-      temp &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT);
+      temp &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE | MCURSOR_PIPE_SELECT);
       if (pI830->CursorIsARGB)
          temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
       else
@@ -491,22 +519,36 @@ I830ShowCursor(ScrnInfoPtr pScrn)
       temp |= (pI830->pipe << 28); /* Connect to correct pipe */
       /* Need to set mode, then address. */
       OUTREG(CURSOR_A_CONTROL, temp);
-      if (pI830->CursorIsARGB)
-         OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Physical);
-      else
-         OUTREG(CURSOR_A_BASE, pI830->CursorMem->Physical);
+      if (pI830->CursorNeedsPhysical) {
+         if (pI830->CursorIsARGB)
+            OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Physical);
+         else
+            OUTREG(CURSOR_A_BASE, pI830->CursorMem->Physical);
+      } else {
+         if (pI830->CursorIsARGB)
+            OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Start);
+         else
+            OUTREG(CURSOR_A_BASE, pI830->CursorMem->Start);
+      }
       if (pI830->Clone) {
          temp &= ~MCURSOR_PIPE_SELECT;
          temp |= (!pI830->pipe << 28);
          OUTREG(CURSOR_B_CONTROL, temp);
-         if (pI830->CursorIsARGB)
-            OUTREG(CURSOR_B_BASE, pI830->CursorMemARGB->Physical);
-         else
-            OUTREG(CURSOR_B_BASE, pI830->CursorMem->Physical);
+         if (pI830->CursorNeedsPhysical) {
+            if (pI830->CursorIsARGB)
+               OUTREG(CURSOR_B_BASE, pI830->CursorMemARGB->Physical);
+            else
+               OUTREG(CURSOR_B_BASE, pI830->CursorMem->Physical);
+	 } else {
+            if (pI830->CursorIsARGB)
+               OUTREG(CURSOR_B_BASE, pI830->CursorMemARGB->Start);
+            else
+               OUTREG(CURSOR_B_BASE, pI830->CursorMem->Start);
+	 }
       }
    } else {
       temp = INREG(CURSOR_CONTROL);
-      temp &= ~(CURSOR_FORMAT_MASK);
+      temp &= ~(CURSOR_FORMAT_MASK | CURSOR_GAMMA_ENABLE);
       temp |= CURSOR_ENABLE;
       if (pI830->CursorIsARGB)
          temp |= CURSOR_FORMAT_ARGB | CURSOR_GAMMA_ENABLE;
@@ -531,7 +573,7 @@ I830HideCursor(ScrnInfoPtr pScrn)
    pI830->cursorOn = FALSE;
    if (IS_MOBILE(pI830) || IS_I9XX(pI830)) {
       temp = INREG(CURSOR_A_CONTROL);
-      temp &= ~(CURSOR_MODE|MCURSOR_GAMMA_ENABLE);
+      temp &= ~CURSOR_MODE;
       temp |= CURSOR_MODE_DISABLE;
       OUTREG(CURSOR_A_CONTROL, temp);
       /* This is needed to flush the above change. */
@@ -548,7 +590,7 @@ I830HideCursor(ScrnInfoPtr pScrn)
       }
    } else {
       temp = INREG(CURSOR_CONTROL);
-      temp &= ~(CURSOR_ENABLE|CURSOR_GAMMA_ENABLE);
+      temp &= ~CURSOR_ENABLE;
       OUTREG(CURSOR_CONTROL, temp);
    }
 }
diff --git a/src/i830_dri.c b/src/i830_dri.c
index 7c5f795..5c47289 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -83,6 +83,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 static char I830KernelDriverName[] = "i915";
 static char I830ClientDriverName[] = "i915";
+static char I965ClientDriverName[] = "i965";
 
 static Bool I830InitVisualConfigs(ScreenPtr pScreen);
 static Bool I830CreateContext(ScreenPtr pScreen, VisualPtr visual,
@@ -475,7 +476,11 @@ I830DRIScreenInit(ScreenPtr pScreen)
    pI830->LockHeld = 0;
 
    pDRIInfo->drmDriverName = I830KernelDriverName;
-   pDRIInfo->clientDriverName = I830ClientDriverName;
+   if (IS_I965G(pI830))
+      pDRIInfo->clientDriverName = I965ClientDriverName;
+   else 
+      pDRIInfo->clientDriverName = I830ClientDriverName;
+
    if (xf86LoaderCheckSymbol("DRICreatePCIBusID")) {
       pDRIInfo->busIdString = DRICreatePCIBusID(pI830->PciInfo);
    } else {
@@ -488,7 +493,7 @@ I830DRIScreenInit(ScreenPtr pScreen)
    pDRIInfo->ddxDriverMajorVersion = I830_MAJOR_VERSION;
    pDRIInfo->ddxDriverMinorVersion = I830_MINOR_VERSION;
    pDRIInfo->ddxDriverPatchVersion = I830_PATCHLEVEL;
-#if 1 /* temporary until this gets removed from the libdri layer */
+#if 1 /* Remove this soon - see bug 5714 */
    pDRIInfo->frameBufferPhysicalAddress = (char *) pI830->LinearAddr +
 					  pI830->FrontBuffer.Start;
    pDRIInfo->frameBufferSize = ROUND_TO_PAGE(pScrn->displayWidth *
@@ -623,12 +628,17 @@ I830DRIMapScreenRegions(ScrnInfoPtr pScr
    ScreenPtr pScreen = pScrn->pScreen;
    I830Ptr pI830 = I830PTR(pScrn);
 
+#if 1 /* Remove this soon - see bug 5714 */
+   pI830->pDRIInfo->frameBufferSize = ROUND_TO_PAGE(pScrn->displayWidth *
+					     pScrn->virtualY * pI830->cpp);
+#endif
+
    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
               "[drm] Mapping front buffer\n");
    if (drmAddMap(pI830->drmSubFD,
                  (drm_handle_t)(sarea->front_offset + pI830->LinearAddr),
                  sarea->front_size,
-                 DRM_FRAME_BUFFER,  /*DRM_AGP,*/
+		 DRM_AGP,
                  0,
                  (drmAddress) &sarea->front_handle) < 0) {
       xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
@@ -684,12 +694,10 @@ I830DRIUnmapScreenRegions(ScrnInfoPtr pS
 {
    I830Ptr pI830 = I830PTR(pScrn);
 
-#if 1
    if (sarea->front_handle) {
       drmRmMap(pI830->drmSubFD, sarea->front_handle);
       sarea->front_handle = 0;
    }
-#endif
    if (sarea->back_handle) {
       drmRmMap(pI830->drmSubFD, sarea->back_handle);
       sarea->back_handle = 0;
@@ -785,7 +793,6 @@ I830DRIDoMappings(ScreenPtr pScreen)
       /* screen mappings probably failed */
       xf86DrvMsg(pScreen->myNum, X_ERROR,
 		 "[drm] drmAddMap(screen mappings) failed. Disabling DRI\n");
-      DRICloseScreen(pScreen);
       return FALSE;
    }
 
@@ -824,9 +831,6 @@ I830DRIDoMappings(ScreenPtr pScreen)
    pI830DRI->mem = pScrn->videoRam * 1024;
    pI830DRI->cpp = pI830->cpp;
 
-   pI830DRI->fbOffset = pI830->FrontBuffer.Start;
-   pI830DRI->fbStride = pI830->backPitch;
-
    pI830DRI->bitsPerPixel = pScrn->bitsPerPixel;
 
    pI830DRI->sarea_priv_offset = sizeof(XF86DRISAREARec);
@@ -1166,8 +1170,10 @@ I830DRIMoveBuffers(WindowPtr pParent, DD
 
       I830SelectBuffer(pScrn, I830_SELECT_BACK);
       I830SubsequentScreenToScreenCopy(pScrn, x1, y1, destx, desty, w, h);
-      I830SelectBuffer(pScrn, I830_SELECT_DEPTH);
-      I830SubsequentScreenToScreenCopy(pScrn, x1, y1, destx, desty, w, h);
+      if (!IS_I965G(pI830)) {
+         I830SelectBuffer(pScrn, I830_SELECT_DEPTH);
+         I830SubsequentScreenToScreenCopy(pScrn, x1, y1, destx, desty, w, h);
+      }
    }
    I830SelectBuffer(pScrn, I830_SELECT_FRONT);
    I830EmitFlush(pScrn);
@@ -1362,6 +1368,14 @@ I830UpdateDRIBuffers(ScrnInfoPtr pScrn, 
 
    I830DRIUnmapScreenRegions(pScrn, sarea);
 
+   sarea->front_tiled = pI830->front_tiled;
+   sarea->back_tiled = pI830->back_tiled;
+   sarea->depth_tiled = pI830->depth_tiled;
+   sarea->rotated_tiled = pI830->rotated_tiled;
+#if 0
+   sarea->rotated2_tiled = pI830->rotated2_tiled;
+#endif
+
    if (pI830->rotation == RR_Rotate_0) {
       sarea->front_offset = pI830->FrontBuffer.Start;
       /* Don't use FrontBuffer.Size here as it includes the pixmap cache area
@@ -1421,7 +1435,8 @@ I830UpdateDRIBuffers(ScrnInfoPtr pScrn, 
 
    success = I830DRIMapScreenRegions(pScrn, sarea);
 
-   I830InitTextureHeap(pScrn, sarea);
+   if (success)
+      I830InitTextureHeap(pScrn, sarea);
 
    return success;
 }
diff --git a/src/i830_dri.h b/src/i830_dri.h
index 31232b8..11987d1 100644
--- a/src/i830_dri.h
+++ b/src/i830_dri.h
@@ -18,21 +18,6 @@ typedef struct _I830DRIRec {
    drm_handle_t regs;
    drmSize regsSize;
 
-   drmSize backbufferSize;
-   drm_handle_t backbuffer;
-
-   drmSize depthbufferSize;
-   drm_handle_t depthbuffer;
-
-   drmSize rotatedSize;
-   drm_handle_t rotatedbuffer;
-
-   drm_handle_t textures;
-   int textureSize;
-
-   drm_handle_t agp_buffers;
-   drmSize agp_buf_size;
-
    int deviceID;
    int width;
    int height;
@@ -40,21 +25,6 @@ typedef struct _I830DRIRec {
    int cpp;
    int bitsPerPixel;
 
-   int fbOffset;
-   int fbStride;
-
-   int backOffset;
-   int backPitch;
-
-   int depthOffset;
-   int depthPitch;
-
-   int rotatedOffset;
-   int rotatedPitch;
-
-   int logTextureGranularity;
-   int textureOffset;
-
    int irq;
    int sarea_priv_offset;
 } I830DRIRec, *I830DRIPtr;
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 5ce88e1..d49e027 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -150,6 +150,11 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
  *    09/2005 Alan Hourihane
  *        - Add Intel(R) 945GM support.
  *
+ *    10/2005 Alan Hourihane, Keith Whitwell, Brian Paul
+ *        - Added Rotation support
+ *
+ *    12/2005 Alan Hourihane, Keith Whitwell
+ *        - Add Intel(R) 965G support.
  */
 
 #ifdef HAVE_CONFIG_H
@@ -204,6 +209,10 @@ static SymTabRec I830BIOSChipsets[] = {
    {PCI_CHIP_I915_GM,		"915GM"},
    {PCI_CHIP_I945_G,		"945G"},
    {PCI_CHIP_I945_GM,		"945GM"},
+   {PCI_CHIP_I965_G,		"965G"},
+   {PCI_CHIP_I965_G_1,		"965G"},
+   {PCI_CHIP_I965_Q,		"965Q"},
+   {PCI_CHIP_I946_GZ,		"946GZ"},
    {-1,				NULL}
 };
 
@@ -217,6 +226,10 @@ static PciChipsets I830BIOSPciChipsets[]
    {PCI_CHIP_I915_GM,		PCI_CHIP_I915_GM,	RES_SHARED_VGA},
    {PCI_CHIP_I945_G,		PCI_CHIP_I945_G,	RES_SHARED_VGA},
    {PCI_CHIP_I945_GM,		PCI_CHIP_I945_GM,	RES_SHARED_VGA},
+   {PCI_CHIP_I965_G,		PCI_CHIP_I965_G,	RES_SHARED_VGA},
+   {PCI_CHIP_I965_G_1,		PCI_CHIP_I965_G_1,	RES_SHARED_VGA},
+   {PCI_CHIP_I965_Q,		PCI_CHIP_I965_Q,	RES_SHARED_VGA},
+   {PCI_CHIP_I946_GZ,		PCI_CHIP_I946_GZ,	RES_SHARED_VGA},
    {-1,				-1,			RES_UNDEFINED}
 };
 
@@ -272,7 +285,7 @@ static OptionInfoRec I830BIOSOptions[] =
 
 static void I830DisplayPowerManagementSet(ScrnInfoPtr pScrn,
 					  int PowerManagementMode, int flags);
-static void I830BIOSAdjustFrame(int scrnIndex, int x, int y, int flags);
+static void I830AdjustFrame(int scrnIndex, int x, int y, int flags);
 static Bool I830BIOSCloseScreen(int scrnIndex, ScreenPtr pScreen);
 static Bool I830BIOSSaveScreen(ScreenPtr pScreen, int unblack);
 static Bool I830BIOSEnterVT(int scrnIndex, int flags);
@@ -1441,8 +1454,11 @@ I830DetectMemory(ScrnInfoPtr pScrn)
    gmch_ctrl = pciReadWord(bridge, I830_GMCH_CTRL);
 
    /* We need to reduce the stolen size, by the GTT and the popup.
-    * The GTT varying according the the FbMapSize and the popup is 4KB */
-   range = (pI830->FbMapSize / (1024*1024)) + 4;
+    * The GTT varying according the the FbMapSize and the popup is 4KB. */
+   if (IS_I965G(pI830))
+      range = 512 + 4; /* Fixed 512KB size for i965 */
+   else
+      range = (pI830->FbMapSize / MB(1)) + 4;
 
    if (IS_I85X(pI830) || IS_I865G(pI830) || IS_I9XX(pI830)) {
       switch (gmch_ctrl & I830_GMCH_GMS_MASK) {
@@ -1859,7 +1875,7 @@ I830LoadPalette(ScrnInfoPtr pScrn, int n
    unsigned char r, g, b;
    CARD32 val, temp;
    int palreg;
-   int dspreg, dspbase;
+   int dspreg, dspbase, dspsurf;
 
    DPRINTF(PFX, "I830LoadPalette: numColors: %d\n", numColors);
    pI830 = I830PTR(pScrn);
@@ -1868,10 +1884,12 @@ I830LoadPalette(ScrnInfoPtr pScrn, int n
       palreg = PALETTE_A;
       dspreg = DSPACNTR;
       dspbase = DSPABASE;
+      dspsurf = DSPASURF;
    } else {
       palreg = PALETTE_B;
       dspreg = DSPBCNTR;
       dspbase = DSPBBASE;
+      dspsurf = DSPBSURF;
    }
 
    /* To ensure gamma is enabled we need to turn off and on the plane */
@@ -1880,6 +1898,8 @@ I830LoadPalette(ScrnInfoPtr pScrn, int n
    OUTREG(dspbase, INREG(dspbase));
    OUTREG(dspreg, temp | DISPPLANE_GAMMA_ENABLE);
    OUTREG(dspbase, INREG(dspbase));
+   if (IS_I965G(pI830)) 
+      OUTREG(dspsurf, INREG(dspsurf));
 
    /* It seems that an initial read is needed. */
    temp = INREG(palreg);
@@ -2287,6 +2307,16 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int f
    case PCI_CHIP_I945_GM:
       chipname = "945GM";
       break;
+   case PCI_CHIP_I965_G:
+   case PCI_CHIP_I965_G_1:
+      chipname = "965G";
+      break;
+   case PCI_CHIP_I965_Q:
+      chipname = "965Q";
+      break;
+   case PCI_CHIP_I946_GZ:
+      chipname = "946GZ";
+      break;
    default:
       chipname = "unknown chipset";
       break;
@@ -3054,6 +3084,9 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int f
    else
       pI830->CursorNeedsPhysical = FALSE;
 
+   if (IS_I965G(pI830))
+      pI830->CursorNeedsPhysical = FALSE;
+
    /* Force ring buffer to be in low memory for all chipsets */
    pI830->NeedRingBufferLow = TRUE;
 
@@ -3608,8 +3641,12 @@ CheckInheritedState(ScrnInfoPtr pScrn)
    }
 
 #if 0
-   if (errors)
-      I830PrintErrorState(pScrn);
+   if (errors) {
+      if (IS_I965G(pI830))
+         I965PrintErrorState(pScrn);
+      else
+         I830PrintErrorState(pScrn);
+   }
 #endif
 
    if (fatal)
@@ -3639,8 +3676,15 @@ ResetState(ScrnInfoPtr pScrn, Bool flush
       pI830->entityPrivate->RingRunning = 0;
 
    /* Reset the fence registers to 0 */
-   for (i = 0; i < 8; i++)
-      OUTREG(FENCE + i * 4, 0);
+   if (IS_I965G(pI830)) {
+      for (i = 0; i < FENCE_NEW_NR; i++) {
+	 OUTREG(FENCE_NEW + i * 8, 0);
+	 OUTREG(FENCE_NEW + 4 + i * 8, 0);
+      }
+   } else {
+      for (i = 0; i < FENCE_NR; i++)
+         OUTREG(FENCE + i * 4, 0);
+   }
 
    /* Flush the ring buffer (if enabled), then disable it. */
    if (pI830->AccelInfoRec != NULL && flush) {
@@ -3670,10 +3714,21 @@ SetFenceRegs(ScrnInfoPtr pScrn)
 
    if (!I830IsPrimary(pScrn)) return;
 
-   for (i = 0; i < 8; i++) {
-      OUTREG(FENCE + i * 4, pI830->ModeReg.Fence[i]);
-      if (I810_DEBUG & DEBUG_VERBOSE_VGA)
-	 ErrorF("Fence Register : %x\n", pI830->ModeReg.Fence[i]);
+   if (IS_I965G(pI830)) {
+      for (i = 0; i < FENCE_NEW_NR; i++) {
+         OUTREG(FENCE_NEW + i * 8, pI830->ModeReg.Fence[i]);
+         OUTREG(FENCE_NEW + 4 + i * 8, pI830->ModeReg.Fence[i+FENCE_NEW_NR]);
+         if (I810_DEBUG & DEBUG_VERBOSE_VGA) {
+	    ErrorF("Fence Start Register : %x\n", pI830->ModeReg.Fence[i]);
+	    ErrorF("Fence End Register : %x\n", pI830->ModeReg.Fence[i+FENCE_NEW_NR]);
+         }
+      }
+   } else {
+      for (i = 0; i < FENCE_NR; i++) {
+         OUTREG(FENCE + i * 4, pI830->ModeReg.Fence[i]);
+         if (I810_DEBUG & DEBUG_VERBOSE_VGA)
+	    ErrorF("Fence Register : %x\n", pI830->ModeReg.Fence[i]);
+      }
    }
 }
 
@@ -3774,6 +3829,12 @@ SaveHWState(ScrnInfoPtr pScrn)
    vgaHWSave(pScrn, vgaReg, VGA_SR_FONTS);
 
    pVesa = pI830->vesa;
+
+   if (IS_I965G(pI830)) {
+      pI830->savedAsurf = INREG(DSPASURF);
+      pI830->savedBsurf = INREG(DSPBSURF);
+   }
+
    /*
     * This save/restore method doesn't work for 845G BIOS, or for some
     * other platforms.  Enable it in all cases.
@@ -3826,9 +3887,6 @@ RestoreHWState(ScrnInfoPtr pScrn)
 
    DPRINTF(PFX, "RestoreHWState\n");
 
-#ifdef XF86DRI
-   I830DRISetVBlankInterrupt (pScrn, FALSE);
-#endif
    if (I830IsPrimary(pScrn) && pI830->pipe != pI830->origPipe)
       SetBIOSPipe(pScrn, pI830->origPipe);
    else
@@ -3887,6 +3945,11 @@ RestoreHWState(ScrnInfoPtr pScrn)
 
    VBESetDisplayStart(pVbe, pVesa->x, pVesa->y, TRUE);
 
+   if (IS_I965G(pI830)) {
+      OUTREG(DSPASURF, pI830->savedAsurf);
+      OUTREG(DSPBSURF, pI830->savedBsurf);
+   }
+
    vgaHWRestore(pScrn, vgaReg, VGA_SR_FONTS);
    vgaHWLock(hwp);
 
@@ -4118,6 +4181,25 @@ I830VESASetMode(ScrnInfoPtr pScrn, Displ
 
    SetPipeAccess(pScrn);
 
+#if 0
+   { /* I965G ENABLE TILING */
+      planeA = INREG(DSPACNTR) | 1<<10;
+      OUTREG(DSPACNTR, planeA);
+      /* flush the change. */
+      temp = INREG(DSPABASE);
+      OUTREG(DSPABASE, temp);
+   }
+#else
+   { /* I965G DISABLE TILING */
+      planeA = INREG(DSPACNTR) & ~1<<10;
+      OUTREG(DSPACNTR, planeA);
+      /* flush the change. */
+      temp = INREG(DSPABASE);
+      OUTREG(DSPABASE, temp);
+      OUTREG(DSPASURF, INREG(DSPASURF));
+   }
+#endif
+
    if (I830VESASetVBEMode(pScrn, mode, data->block) == FALSE) {
       xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Set VBE Mode failed!\n");
       return FALSE;
@@ -4182,6 +4264,10 @@ I830VESASetMode(ScrnInfoPtr pScrn, Displ
       /* flush the change. */
       temp = INREG(DSPABASE);
       OUTREG(DSPABASE, temp);
+      if (IS_I965G(pI830)) {
+         temp = INREG(DSPASURF);
+         OUTREG(DSPASURF, temp);
+      }
    }
    if (pI830->planeEnabled[1]) {
       xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Enabling plane B.\n");
@@ -4192,6 +4278,10 @@ I830VESASetMode(ScrnInfoPtr pScrn, Displ
       /* flush the change. */
       temp = INREG(DSPBADDR);
       OUTREG(DSPBADDR, temp);
+      if (IS_I965G(pI830)) {
+         temp = INREG(DSPBSURF);
+         OUTREG(DSPBSURF, temp);
+      }
    }
 
    planeA = INREG(DSPACNTR);
@@ -4224,6 +4314,7 @@ I830VESASetMode(ScrnInfoPtr pScrn, Displ
          CARD32 stridereg = !pI830->pipe ? DSPASTRIDE : DSPBSTRIDE;
          CARD32 basereg = !pI830->pipe ? DSPABASE : DSPBBASE;
          CARD32 sizereg = !pI830->pipe ? DSPASIZE : DSPBSIZE;
+         CARD32 surfreg = !pI830->pipe ? DSPASURF : DSPBSURF;
          I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
 
          temp = INREG(stridereg);
@@ -4237,12 +4328,17 @@ I830VESASetMode(ScrnInfoPtr pScrn, Displ
          /* Trigger update */
          temp = INREG(basereg);
          OUTREG(basereg, temp);
+         if (IS_I965G(pI830)) {
+            temp = INREG(surfreg);
+            OUTREG(surfreg, temp);
+         }
 
          if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) {
             I830Ptr pI8302 = I830PTR(pI830->entityPrivate->pScrn_2);
             stridereg = pI830->pipe ? DSPASTRIDE : DSPBSTRIDE;
             basereg = pI830->pipe ? DSPABASE : DSPBBASE;
             sizereg = pI830->pipe ? DSPASIZE : DSPBSIZE;
+            surfreg = pI830->pipe ? DSPASURF : DSPBSURF;
 
             temp = INREG(stridereg);
             if (temp / pI8302->cpp != (CARD32)(pI8302->displayWidth)) {
@@ -4255,11 +4351,16 @@ I830VESASetMode(ScrnInfoPtr pScrn, Displ
             /* Trigger update */
             temp = INREG(basereg);
             OUTREG(basereg, temp);
+            if (IS_I965G(pI830)) {
+               temp = INREG(surfreg);
+               OUTREG(surfreg, temp);
+            }
          }
       } else {
          CARD32 stridereg = pI830->pipe ? DSPASTRIDE : DSPBSTRIDE;
          CARD32 basereg = pI830->pipe ? DSPABASE : DSPBBASE;
          CARD32 sizereg = pI830->pipe ? DSPASIZE : DSPBSIZE;
+         CARD32 surfreg = pI830->pipe ? DSPASURF : DSPBSURF;
          I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
          I830Ptr pI8302 = I830PTR(pI830->entityPrivate->pScrn_2);
 
@@ -4274,10 +4375,15 @@ I830VESASetMode(ScrnInfoPtr pScrn, Displ
          /* Trigger update */
          temp = INREG(basereg);
          OUTREG(basereg, temp);
+         if (IS_I965G(pI830)) {
+            temp = INREG(surfreg);
+            OUTREG(surfreg, temp);
+         }
 
          stridereg = !pI830->pipe ? DSPASTRIDE : DSPBSTRIDE;
          basereg = !pI830->pipe ? DSPABASE : DSPBBASE;
          sizereg = !pI830->pipe ? DSPASIZE : DSPBSIZE;
+         surfreg = !pI830->pipe ? DSPASURF : DSPBSURF;
 
          temp = INREG(stridereg);
          if (temp / pI8302->cpp != ((CARD32)pI8302->displayWidth)) {
@@ -4290,12 +4396,17 @@ I830VESASetMode(ScrnInfoPtr pScrn, Displ
          /* Trigger update */
          temp = INREG(basereg);
          OUTREG(basereg, temp);
+         if (IS_I965G(pI830)) {
+            temp = INREG(surfreg);
+            OUTREG(surfreg, temp);
+         }
       }
    } else {
       for (i = 0; i < pI830->availablePipes; i++) {
          CARD32 stridereg = i ? DSPBSTRIDE : DSPASTRIDE;
          CARD32 basereg = i ? DSPBBASE : DSPABASE;
          CARD32 sizereg = i ? DSPBSIZE : DSPASIZE;
+         CARD32 surfreg = i ? DSPBSURF : DSPASURF;
 
          if (!pI830->planeEnabled[i])
 	    continue;
@@ -4308,9 +4419,12 @@ I830VESASetMode(ScrnInfoPtr pScrn, Displ
 	    OUTREG(stridereg, pI830->displayWidth * pI830->cpp);
          }
          OUTREG(sizereg, (pMode->HDisplay - 1) | ((pMode->VDisplay - 1) << 16));
-	 /* Trigger update */
 	 temp = INREG(basereg);
 	 OUTREG(basereg, temp);
+         if (IS_I965G(pI830)) {
+            temp = INREG(surfreg);
+            OUTREG(surfreg, temp);
+         }
       }
    }
 
@@ -4413,9 +4527,13 @@ I830VESASetMode(ScrnInfoPtr pScrn, Displ
    SetHWOperatingState(pScrn);
 #endif
 
-#ifdef XF86DRI
-   I830DRISetVBlankInterrupt (pScrn, TRUE);
+#if 0
+   if (IS_I965G(pI830))
+      I965PrintErrorState(pScrn);
+   else
+      I830PrintErrorState(pScrn);
 #endif
+
 #ifdef XF86DRI
    if (didLock)
       I830DRIUnlock(pScrn);
@@ -4469,6 +4587,59 @@ I830PrintErrorState(ScrnInfoPtr pScrn)
 	  INREG16(HWSTAM), INREG16(IER), INREG16(IMR), INREG16(IIR));
 }
 
+void
+I965PrintErrorState(ScrnInfoPtr pScrn)
+{
+   I830Ptr pI830 = I830PTR(pScrn);
+
+   ErrorF("pgetbl_ctl: 0x%lx pgetbl_err: 0x%lx\n",
+	  INREG(PGETBL_CTL), INREG(PGE_ERR));
+
+   ErrorF("ipeir: %lx iphdr: %lx\n", INREG(IPEIR_I965), INREG(IPEHR_I965));
+
+   ErrorF("LP ring tail: %lx head: %lx len: %lx start %lx\n",
+	  INREG(LP_RING + RING_TAIL),
+	  INREG(LP_RING + RING_HEAD) & HEAD_ADDR,
+	  INREG(LP_RING + RING_LEN), INREG(LP_RING + RING_START));
+
+   ErrorF("Err ID (eir): %x Err Status (esr): %x Err Mask (emr): %x\n",
+	  INREG(EIR), INREG(ESR), INREG(EMR));
+
+   ErrorF("instdone: %x instdone_1: %x\n", INREG(INST_DONE_I965), INREG(INST_DONE_1));
+   ErrorF("instpm: %x\n", INREG(INST_PM));
+
+   ErrorF("memmode: %lx instps: %lx\n", INREG(MEMMODE), INREG(INST_PS_I965));
+
+   ErrorF("HW Status mask (hwstam): %x\nIRQ enable (ier): %x imr: %x iir: %x\n",
+	  INREG(HWSTAM), INREG(IER), INREG(IMR), INREG(IIR));
+
+   ErrorF("acthd: %lx dma_fadd_p: %lx\n", INREG(ACTHD), INREG(DMA_FADD_P));
+   ErrorF("ecoskpd: %lx excc: %lx\n", INREG(ECOSKPD), INREG(EXCC));
+
+   ErrorF("cache_mode: %x/%x\n", INREG(CACHE_MODE_0), INREG(CACHE_MODE_1));
+   ErrorF("mi_arb_state: %x\n", INREG(MI_ARB_STATE));
+
+   ErrorF("IA_VERTICES_COUNT_QW %x/%x\n", INREG(IA_VERTICES_COUNT_QW), INREG(IA_VERTICES_COUNT_QW+4));
+   ErrorF("IA_PRIMITIVES_COUNT_QW %x/%x\n", INREG(IA_PRIMITIVES_COUNT_QW), INREG(IA_PRIMITIVES_COUNT_QW+4));
+
+   ErrorF("VS_INVOCATION_COUNT_QW %x/%x\n", INREG(VS_INVOCATION_COUNT_QW), INREG(VS_INVOCATION_COUNT_QW+4));
+
+   ErrorF("GS_INVOCATION_COUNT_QW %x/%x\n", INREG(GS_INVOCATION_COUNT_QW), INREG(GS_INVOCATION_COUNT_QW+4));
+   ErrorF("GS_PRIMITIVES_COUNT_QW %x/%x\n", INREG(GS_PRIMITIVES_COUNT_QW), INREG(GS_PRIMITIVES_COUNT_QW+4));
+
+   ErrorF("CL_INVOCATION_COUNT_QW %x/%x\n", INREG(CL_INVOCATION_COUNT_QW), INREG(CL_INVOCATION_COUNT_QW+4));
+   ErrorF("CL_PRIMITIVES_COUNT_QW %x/%x\n", INREG(CL_PRIMITIVES_COUNT_QW), INREG(CL_PRIMITIVES_COUNT_QW+4));
+
+   ErrorF("PS_INVOCATION_COUNT_QW %x/%x\n", INREG(PS_INVOCATION_COUNT_QW), INREG(PS_INVOCATION_COUNT_QW+4));
+   ErrorF("PS_DEPTH_COUNT_QW %x/%x\n", INREG(PS_DEPTH_COUNT_QW), INREG(PS_DEPTH_COUNT_QW+4));
+
+   ErrorF("WIZ_CTL %x\n", INREG(WIZ_CTL));
+   ErrorF("TS_CTL %x  TS_DEBUG_DATA %x\n", INREG(TS_CTL), INREG(TS_DEBUG_DATA));
+   ErrorF("TD_CTL %x / %x\n", INREG(TD_CTL), INREG(TD_CTL2));
+
+   
+}
+
 #ifdef I830DEBUG
 static void
 dump_DSPACNTR(ScrnInfoPtr pScrn)
@@ -4762,6 +4933,9 @@ IntelEmitInvarientState(ScrnInfoPtr pScr
    I830Ptr pI830 = I830PTR(pScrn);
    CARD32 ctx_addr;
 
+   if (pI830->noAccel)
+      return;
+
    ctx_addr = pI830->ContextMem.Start;
    /* Align to a 2k boundry */
    ctx_addr = ((ctx_addr + 2048 - 1) / 2048) * 2048;
@@ -4775,10 +4949,13 @@ IntelEmitInvarientState(ScrnInfoPtr pScr
       ADVANCE_LP_RING();
    }
 
-   if (IS_I9XX(pI830))
-      I915EmitInvarientState(pScrn);
-   else
-      I830EmitInvarientState(pScrn);
+   if (!IS_I965G(pI830))
+   {
+      if (IS_I9XX(pI830))
+         I915EmitInvarientState(pScrn);
+      else
+         I830EmitInvarientState(pScrn);
+   }
 }
 
 static Bool
@@ -5183,6 +5360,20 @@ I830BIOSScreenInit(int scrnIndex, Screen
    I830_dump_registers(pScrn);
 #endif
 
+   if (IS_I965G(pI830)) {
+      /* turn off clock gating */
+#if 0
+      OUTREG(0x6204, 0x70804000);
+      OUTREG(0x6208, 0x00000001);
+#else
+      OUTREG(0x6204, 0x70000000);
+#endif
+      /* Enable DAP stateless accesses.  
+       * Required for all i965 steppings.
+       */
+      OUTREG(SVG_WORK_CTL, 0x00000010);
+   }
+
    pI830->starting = FALSE;
    pI830->closing = FALSE;
    pI830->suspended = FALSE;
@@ -5214,7 +5405,7 @@ I830BIOSScreenInit(int scrnIndex, Screen
 }
 
 static void
-I830BIOSAdjustFrame(int scrnIndex, int x, int y, int flags)
+I830AdjustFrame(int scrnIndex, int x, int y, int flags)
 {
    ScrnInfoPtr pScrn;
    I830Ptr pI830;
@@ -5225,7 +5416,7 @@ I830BIOSAdjustFrame(int scrnIndex, int x
    pI830 = I830PTR(pScrn);
    pVbe = pI830->pVbe;
 
-   DPRINTF(PFX, "I830BIOSAdjustFrame: y = %d (+ %d), x = %d (+ %d)\n",
+   DPRINTF(PFX, "I830AdjustFrame: y = %d (+ %d), x = %d (+ %d)\n",
 	   x, pI830->xoffset, y, pI830->yoffset);
 
    /* Sync the engine before adjust frame */
@@ -5248,16 +5439,36 @@ I830BIOSAdjustFrame(int scrnIndex, int x
 
    if (pI830->Clone) {
       if (!pI830->pipe == 0) {
-         OUTREG(DSPABASE, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
+         if (!IS_I965G(pI830)) {
+            OUTREG(DSPABASE, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
+         } else {
+            OUTREG(DSPABASE, 0);
+            OUTREG(DSPASURF, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
+         }
       } else {
-         OUTREG(DSPBBASE, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
+         if (!IS_I965G(pI830)) {
+            OUTREG(DSPBBASE, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
+         } else {
+            OUTREG(DSPBBASE, 0);
+            OUTREG(DSPBSURF, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
+         }
       }
    }
 
    if (pI830->pipe == 0) {
-      OUTREG(DSPABASE, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
+      if (!IS_I965G(pI830)) {
+         OUTREG(DSPABASE, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
+      } else {
+         OUTREG(DSPABASE, 0);
+         OUTREG(DSPASURF, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
+      }
    } else {
-      OUTREG(DSPBBASE, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
+      if (!IS_I965G(pI830)) {
+         OUTREG(DSPBBASE, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
+      } else {
+         OUTREG(DSPBBASE, 0);
+         OUTREG(DSPBSURF, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
+      }
    }
 }
 
@@ -5332,6 +5543,8 @@ I830BIOSLeaveVT(int scrnIndex, int flags
 #ifdef XF86DRI
    if (pI830->directRenderingOpen) {
       DRILock(screenInfo.screens[pScrn->scrnIndex], 0);
+   
+      I830DRISetVBlankInterrupt (pScrn, FALSE);
       
       drmCtlUninstHandler(pI830->drmSubFD);
    }
@@ -5653,12 +5866,21 @@ I830BIOSEnterVT(int scrnIndex, int flags
 #ifdef XF86DRI
    if (pI830->directRenderingEnabled) {
       if (!pI830->starting) {
+         ScreenPtr pScreen = pScrn->pScreen;
+         drmI830Sarea *sarea = (drmI830Sarea *) DRIGetSAREAPrivate(pScreen);
+         int i;
+
 	 I830DRIResume(screenInfo.screens[scrnIndex]);
+         I830DRISetVBlankInterrupt (pScrn, TRUE);
       
 	 I830RefreshRing(pScrn);
 	 I830Sync(pScrn);
 	 DO_RING_IDLE();
 
+	 sarea->texAge++;
+	 for(i = 0; i < I830_NR_TEX_REGIONS+1 ; i++)
+	    sarea->texList[i].age = sarea->texAge;
+
 	 DPRINTF(PFX, "calling dri unlock\n");
 	 DRIUnlock(screenInfo.screens[pScrn->scrnIndex]);
       }
@@ -5718,7 +5940,8 @@ I830BIOSSwitchMode(int scrnIndex, Displa
     * The extra WindowTable check detects a rotation at startup.
     */
    if ( (!WindowTable[pScrn->scrnIndex] || pspix->devPrivate.ptr == NULL) &&
-         !pI830->DGAactive && (pScrn->PointerMoved == I830PointerMoved) ) {
+         !pI830->DGAactive && (pScrn->PointerMoved == I830PointerMoved) &&
+	 !IS_I965G(pI830)) {
       if (!I830Rotate(pScrn, mode))
          ret = FALSE;
    }
@@ -5754,7 +5977,7 @@ I830BIOSSaveScreen(ScreenPtr pScreen, in
    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
    I830Ptr pI830 = I830PTR(pScrn);
    Bool on = xf86IsUnblank(mode);
-   CARD32 temp, ctrl, base;
+   CARD32 temp, ctrl, base, surf;
 
    DPRINTF(PFX, "I830BIOSSaveScreen: %d, on is %s\n", mode, BOOLTOSTRING(on));
 
@@ -5762,9 +5985,11 @@ I830BIOSSaveScreen(ScreenPtr pScreen, in
       if (pI830->pipe == 0) {
 	 ctrl = DSPACNTR;
 	 base = DSPABASE;
+	 surf = DSPASURF;
       } else {
 	 ctrl = DSPBCNTR;
 	 base = DSPBADDR;
+	 surf = DSPBSURF;
       }
       if (pI830->planeEnabled[pI830->pipe]) {
 	 temp = INREG(ctrl);
@@ -5776,6 +6001,10 @@ I830BIOSSaveScreen(ScreenPtr pScreen, in
 	 /* Flush changes */
 	 temp = INREG(base);
 	 OUTREG(base, temp);
+	 if (IS_I965G(pI830)) {
+            temp = INREG(surf);
+            OUTREG(surf, temp);
+         }
       }
 
       if (pI830->CursorInfoRec && !pI830->SWCursor && pI830->cursorOn) {
@@ -6240,16 +6469,23 @@ I830CheckDevicesTimer(OsTimerPtr timer, 
             offset = pI8301->FrontBuffer2.Start + ((pScrn->frameY0 * pI830->displayWidth + pScrn->frameX0) * pI830->cpp);
 	 }
 
-         if (pI830->pipe == 0)
-            adjust = INREG(DSPABASE);
-         else 
-            adjust = INREG(DSPBBASE);
+         if (IS_I965G(pI830)) {
+            if (pI830->pipe == 0)
+               adjust = INREG(DSPASURF);
+            else 
+               adjust = INREG(DSPBSURF);
+         } else {
+            if (pI830->pipe == 0)
+               adjust = INREG(DSPABASE);
+            else 
+               adjust = INREG(DSPBBASE);
+         }
 
          if (adjust != offset) {
             xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 			                       "Fixing display offsets.\n");
 
-            I830BIOSAdjustFrame(pScrn->pScreen->myNum, pScrn->frameX0, pScrn->frameY0, 0);
+            I830AdjustFrame(pScrn->pScreen->myNum, pScrn->frameX0, pScrn->frameY0, 0);
          }
       }
 
@@ -6274,7 +6510,7 @@ I830CheckDevicesTimer(OsTimerPtr timer, 
 
          pI830->currentMode = NULL;
          I830BIOSSwitchMode(pScrn->pScreen->myNum, pScrn->currentMode, 0);
-         I830BIOSAdjustFrame(pScrn->pScreen->myNum, pScrn->frameX0, pScrn->frameY0, 0);
+         I830AdjustFrame(pScrn->pScreen->myNum, pScrn->frameX0, pScrn->frameY0, 0);
 
          if (xf86IsEntityShared(pScrn->entityList[0])) {
 	    ScrnInfoPtr pScrn2;
@@ -6293,7 +6529,7 @@ I830CheckDevicesTimer(OsTimerPtr timer, 
 
             pI8302->currentMode = NULL;
             I830BIOSSwitchMode(pScrn2->pScreen->myNum, pScrn2->currentMode, 0);
-            I830BIOSAdjustFrame(pScrn2->pScreen->myNum, pScrn2->frameX0, pScrn2->frameY0, 0);
+            I830AdjustFrame(pScrn2->pScreen->myNum, pScrn2->frameX0, pScrn2->frameY0, 0);
 
  	    (*pScrn2->EnableDisableFBAccess) (pScrn2->pScreen->myNum, FALSE);
  	    (*pScrn2->EnableDisableFBAccess) (pScrn2->pScreen->myNum, TRUE);
@@ -6342,7 +6578,7 @@ I830InitpScrn(ScrnInfoPtr pScrn)
    pScrn->PreInit = I830BIOSPreInit;
    pScrn->ScreenInit = I830BIOSScreenInit;
    pScrn->SwitchMode = I830BIOSSwitchMode;
-   pScrn->AdjustFrame = I830BIOSAdjustFrame;
+   pScrn->AdjustFrame = I830AdjustFrame;
    pScrn->EnterVT = I830BIOSEnterVT;
    pScrn->LeaveVT = I830BIOSLeaveVT;
    pScrn->FreeScreen = I830BIOSFreeScreen;
diff --git a/src/i830_memory.c b/src/i830_memory.c
index 433aa47..f4a6325 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -498,7 +498,7 @@ I830AllocateRotatedBuffer(ScrnInfoPtr pS
    alloced = 0;
    if (tileable) {
       align = GetBestTileAlignment(size);
-      for (align = GetBestTileAlignment(size); align >= KB(512); align >>= 1) {
+      for (align = GetBestTileAlignment(size); align >= (IS_I9XX(pI830) ? MB(1) : KB(512)); align >>= 1) {
 	 alloced = I830AllocVidMem(pScrn, &(pI830->RotatedMem),
 				   &(pI830->StolenPool), size, align,
 				   flags | FROM_ANYWHERE | ALLOCATE_AT_TOP |
@@ -563,7 +563,7 @@ I830AllocateRotated2Buffer(ScrnInfoPtr p
    alloced = 0;
    if (tileable) {
       align = GetBestTileAlignment(size);
-      for (align = GetBestTileAlignment(size); align >= KB(512); align >>= 1) {
+      for (align = GetBestTileAlignment(size); align >= (IS_I9XX(pI830) ? MB(1) : KB(512)); align >>= 1) {
 	 alloced = I830AllocVidMem(pScrn, &(pI830->RotatedMem2),
 				   &(pI830->StolenPool), size, align,
 				   flags | FROM_ANYWHERE | ALLOCATE_AT_TOP |
@@ -731,7 +731,10 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, 
          tileable = !(flags & ALLOC_NO_TILING) && pI8302->allowPageFlip &&
 		 IsTileable(pI830Ent->pScrn_2->displayWidth * pI8302->cpp);
          if (tileable) {
-	    align = KB(512);
+            if (IS_I9XX(pI830))
+               align = MB(1);
+            else
+	       align = KB(512);
 	    alignflags = ALIGN_BOTH_ENDS;
          } else {
 	    align = KB(64);
@@ -823,7 +826,10 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, 
       tileable = !(flags & ALLOC_NO_TILING) && pI830->allowPageFlip &&
 		 IsTileable(pScrn->displayWidth * pI830->cpp);
       if (tileable) {
-	 align = KB(512);
+         if (IS_I9XX(pI830))
+            align = MB(1);
+         else
+	    align = KB(512);
 	 alignflags = ALIGN_BOTH_ENDS;
       } else {
 	 align = KB(64);
@@ -909,7 +915,10 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, 
 	 tileable = !(flags & ALLOC_NO_TILING) && pI830->allowPageFlip &&
 		 IsTileable(pScrn->displayWidth * pI830->cpp);
 	 if (tileable) {
-	    align = KB(512);
+            if (IS_I9XX(pI830))
+               align = MB(1);
+            else
+	       align = KB(512);
 	    alignflags = ALIGN_BOTH_ENDS;
 	 } else {
 	    align = KB(64);
@@ -1147,7 +1156,7 @@ I830AllocateBackBuffer(ScrnInfoPtr pScrn
    alloced = 0;
    if (tileable) {
       align = GetBestTileAlignment(size);
-      for (align = GetBestTileAlignment(size); align >= KB(512); align >>= 1) {
+      for (align = GetBestTileAlignment(size); align >= (IS_I9XX(pI830) ? MB(1) : KB(512)); align >>= 1) {
 	 alloced = I830AllocVidMem(pScrn, &(pI830->BackBuffer),
 				   &(pI830->StolenPool), size, align,
 				   flags | FROM_ANYWHERE | ALLOCATE_AT_TOP |
@@ -1210,7 +1219,7 @@ I830AllocateDepthBuffer(ScrnInfoPtr pScr
    alloced = 0;
    if (tileable) {
       align = GetBestTileAlignment(size);
-      for (align = GetBestTileAlignment(size); align >= KB(512); align >>= 1) {
+      for (align = GetBestTileAlignment(size); align >= (IS_I9XX(pI830) ? MB(1) : KB(512)); align >>= 1) {
 	 alloced = I830AllocVidMem(pScrn, &(pI830->DepthBuffer),
 				   &(pI830->StolenPool), size, align,
 				   flags | FROM_ANYWHERE | ALLOCATE_AT_TOP |
@@ -1644,7 +1653,7 @@ SetFence(ScrnInfoPtr pScrn, int nr, unsi
 }
 
 static Bool
-MakeTiles(ScrnInfoPtr pScrn, I830MemRange *pMem)
+MakeTiles(ScrnInfoPtr pScrn, I830MemRange *pMem, unsigned int fence)
 {
    I830Ptr pI830 = I830PTR(pScrn);
    int pitch, ntiles, i;
@@ -1662,6 +1671,31 @@ MakeTiles(ScrnInfoPtr pScrn, I830MemRang
    }
 
    pitch = pScrn->displayWidth * pI830->cpp;
+
+   if (IS_I965G(pI830)) {
+      I830RegPtr i830Reg = &pI830->ModeReg;
+
+      switch (fence) {
+         case FENCE_XMAJOR:
+            i830Reg->Fence[nextTile] = (((pitch / 128) - 1) << 2) | pMem->Start | 1;
+            break;
+         case FENCE_YMAJOR:
+            /* YMajor can be 128B aligned but the current code dictates
+             * otherwise. This isn't a problem apart from memory waste.
+             * FIXME */
+            i830Reg->Fence[nextTile] = (((pitch / 128) - 1) << 2) | pMem->Start | 1;
+	    i830Reg->Fence[nextTile] |= (1<<1);
+            break;
+         default:
+         case FENCE_LINEAR:
+            break;
+      }
+
+      i830Reg->Fence[nextTile+FENCE_NEW_NR] = pMem->End;
+      nextTile++;
+      return TRUE;
+   }
+
    /*
     * Simply try to break the region up into at most four pieces of size
     * equal to the alignment.
@@ -1703,20 +1737,27 @@ I830SetupMemoryTiling(ScrnInfoPtr pScrn)
       return;
    }
 
+   pI830->front_tiled = FENCE_LINEAR;
+   pI830->back_tiled = FENCE_LINEAR;
+   pI830->depth_tiled = FENCE_LINEAR;
+   pI830->rotated_tiled = FENCE_LINEAR;
+   pI830->rotated2_tiled = FENCE_LINEAR;
+
    if (pI830->allowPageFlip) {
       if (pI830->allowPageFlip && pI830->FrontBuffer.Alignment >= KB(512)) {
-	 if (MakeTiles(pScrn, &(pI830->FrontBuffer))) {
+	 if (MakeTiles(pScrn, &(pI830->FrontBuffer), FENCE_XMAJOR)) {
 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-		       "Activating tiled memory for the FRONT buffer\n");
+		       "Activating tiled memory for the front buffer\n");
+            pI830->front_tiled = FENCE_XMAJOR;
 	 } else {
 	    pI830->allowPageFlip = FALSE;
 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-		       "MakeTiles failed for the FRONT buffer\n");
+		       "MakeTiles failed for the front buffer\n");
 	 }
       } else {
 	 pI830->allowPageFlip = FALSE;
 	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-		 "Alignment bad for the FRONT buffer\n");
+		 "Alignment bad for the front buffer\n");
       }
    }
 
@@ -1727,9 +1768,10 @@ I830SetupMemoryTiling(ScrnInfoPtr pScrn)
     * value.
     */
    if (pI830->BackBuffer.Alignment >= KB(512)) {
-      if (MakeTiles(pScrn, &(pI830->BackBuffer))) {
+      if (MakeTiles(pScrn, &(pI830->BackBuffer), FENCE_XMAJOR)) {
 	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 		    "Activating tiled memory for the back buffer.\n");
+         pI830->back_tiled = FENCE_XMAJOR;
       } else {
 	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 		    "MakeTiles failed for the back buffer.\n");
@@ -1738,9 +1780,10 @@ I830SetupMemoryTiling(ScrnInfoPtr pScrn)
    }
 
    if (pI830->DepthBuffer.Alignment >= KB(512)) {
-      if (MakeTiles(pScrn, &(pI830->DepthBuffer))) {
+      if (MakeTiles(pScrn, &(pI830->DepthBuffer), FENCE_YMAJOR)) {
 	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-		    "Activating tiled memory for the depth buffer.\n");
+	 	    "Activating tiled memory for the depth buffer.\n");
+         pI830->depth_tiled = FENCE_YMAJOR;
       } else {
 	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 		    "MakeTiles failed for the depth buffer.\n");
@@ -1748,9 +1791,10 @@ I830SetupMemoryTiling(ScrnInfoPtr pScrn)
    }
 	
    if (pI830->RotatedMem.Alignment >= KB(512)) {
-      if (MakeTiles(pScrn, &(pI830->RotatedMem))) {
+      if (MakeTiles(pScrn, &(pI830->RotatedMem), FENCE_XMAJOR)) {
 	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 		    "Activating tiled memory for the rotated buffer.\n");
+         pI830->rotated_tiled = FENCE_XMAJOR;
       } else {
 	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 		    "MakeTiles failed for the rotated buffer.\n");
@@ -1759,9 +1803,10 @@ I830SetupMemoryTiling(ScrnInfoPtr pScrn)
 
 #if 0
    if (pI830->RotatedMem2.Alignment >= KB(512)) {
-      if (MakeTiles(pScrn, &(pI830->RotatedMem2))) {
+      if (MakeTiles(pScrn, &(pI830->RotatedMem2), FENCE_XMAJOR)) {
 	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 		    "Activating tiled memory for the rotated2 buffer.\n");
+         pI830->rotated2_tiled = FENCE_XMAJOR;
       } else {
 	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 		    "MakeTiles failed for the rotated buffer.\n");
diff --git a/src/i830_video.c b/src/i830_video.c
index a608a7e..300930d 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -157,7 +157,10 @@ Edummy(const char *dummy, ...)
 	 OUT_RING(MI_NOOP);						\
 	 OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_CONTINUE);		\
       }									\
-      OUT_RING(pI830->OverlayMem->Physical | OFC_UPDATE); 		\
+      if (IS_I965G(pI830)) 					\
+         OUT_RING(pI830->OverlayMem->Start | OFC_UPDATE); 		\
+      else								\
+	 OUT_RING(pI830->OverlayMem->Physical | OFC_UPDATE);		\
       ADVANCE_LP_RING();						\
       ErrorF("OVERLAY_UPDATE\n");					\
    } while(0)
@@ -172,11 +175,17 @@ Edummy(const char *dummy, ...)
 	 OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);	\
 	 OUT_RING(MI_NOOP);						\
 	 OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_CONTINUE);		\
-         OUT_RING(pI830->OverlayMem->Physical | OFC_UPDATE); 		\
+         if (IS_I965G(pI830)) 					\
+            OUT_RING(pI830->OverlayMem->Start | OFC_UPDATE); 		\
+         else								\
+	    OUT_RING(pI830->OverlayMem->Physical | OFC_UPDATE);		\
 	 OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);	\
 	 OUT_RING(MI_NOOP);						\
 	 OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_OFF);		\
-         OUT_RING(pI830->OverlayMem->Physical | OFC_UPDATE); 		\
+         if (IS_I965G(pI830)) 					\
+            OUT_RING(pI830->OverlayMem->Start | OFC_UPDATE); 		\
+         else								\
+	    OUT_RING(pI830->OverlayMem->Physical | OFC_UPDATE);		\
 	 OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);	\
 	 OUT_RING(MI_NOOP);						\
 	 ADVANCE_LP_RING();						\
@@ -334,18 +343,18 @@ typedef struct {
    CARD32 OCONFIG;
    CARD32 OCMD;
    CARD32 RESERVED1;			/* 0x6C */
-   CARD32 AWINPOS;
-   CARD32 AWINSZ;
-   CARD32 RESERVED2;			/* 0x78 */
-   CARD32 RESERVED3;			/* 0x7C */
-   CARD32 RESERVED4;			/* 0x80 */
-   CARD32 RESERVED5;			/* 0x84 */
-   CARD32 RESERVED6;			/* 0x88 */
-   CARD32 RESERVED7;			/* 0x8C */
-   CARD32 RESERVED8;			/* 0x90 */
-   CARD32 RESERVED9;			/* 0x94 */
-   CARD32 RESERVEDA;			/* 0x98 */
-   CARD32 RESERVEDB;			/* 0x9C */
+   CARD32 OSTART_0Y; 		/* for i965 */
+   CARD32 OSTART_1Y;		/* for i965 */
+   CARD32 OSTART_0U;
+   CARD32 OSTART_0V;
+   CARD32 OSTART_1U;
+   CARD32 OSTART_1V;
+   CARD32 OTILEOFF_0Y;
+   CARD32 OTILEOFF_1Y;
+   CARD32 OTILEOFF_0U;
+   CARD32 OTILEOFF_0V;
+   CARD32 OTILEOFF_1U;
+   CARD32 OTILEOFF_1V;
    CARD32 FASTHSCALE;			/* 0xA0 */
    CARD32 UVSCALEV;			/* 0xA4 */
 
@@ -501,8 +510,10 @@ I830ResetVideo(ScrnInfoPtr pScrn)
    overlay->SHEIGHT = 0;
    overlay->OCLRC0 = (pPriv->contrast << 18) | (pPriv->brightness & 0xff);
    overlay->OCLRC1 = 0x00000080;	/* saturation: bypass */
+#if 0
    overlay->AWINPOS = 0;
    overlay->AWINSZ = 0;
+#endif
    overlay->FASTHSCALE = 0;
 
    /*
@@ -1647,14 +1658,31 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int 
 			dstBox->x2, dstBox->y2);
 
    /* buffer locations */
-   overlay->OBUF_0Y = pPriv->YBuf0offset;
-   overlay->OBUF_0U = pPriv->UBuf0offset;
-   overlay->OBUF_0V = pPriv->VBuf0offset;
-
-   if(pPriv->doubleBuffer) {
-      overlay->OBUF_1Y = pPriv->YBuf1offset;
-      overlay->OBUF_1U = pPriv->UBuf1offset;
-      overlay->OBUF_1V = pPriv->VBuf1offset;
+   if (IS_I965G(pI830))
+   {
+      overlay->OBUF_0Y = 0;
+      overlay->OBUF_0U = 0;
+      overlay->OBUF_0V = 0;
+      overlay->OSTART_0Y = pPriv->YBuf0offset;
+      overlay->OSTART_0U = pPriv->UBuf0offset;
+      overlay->OSTART_0V = pPriv->VBuf0offset;
+      if(pPriv->doubleBuffer) {
+         overlay->OBUF_1Y = 0;
+         overlay->OBUF_1U = 0;
+         overlay->OBUF_1V = 0;
+         overlay->OSTART_1Y = pPriv->YBuf1offset;
+         overlay->OSTART_1U = pPriv->UBuf1offset;
+         overlay->OSTART_1V = pPriv->VBuf1offset;
+      }
+   } else {
+      overlay->OBUF_0Y = pPriv->YBuf0offset;
+      overlay->OBUF_0U = pPriv->UBuf0offset;
+      overlay->OBUF_0V = pPriv->VBuf0offset;
+      if(pPriv->doubleBuffer) {
+         overlay->OBUF_1Y = pPriv->YBuf1offset;
+         overlay->OBUF_1U = pPriv->UBuf1offset;
+         overlay->OBUF_1V = pPriv->VBuf1offset;
+      }
    }
 
    ErrorF("Buffers: Y0: 0x%lx, U0: 0x%lx, V0: 0x%lx\n", overlay->OBUF_0Y,
@@ -1967,10 +1995,10 @@ I830PutImage(ScrnInfoPtr pScrn,
       }
 #else
       if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
-         dstPitch = ((height / 2) + 511) & ~511;
+         dstPitch = ((height / 2) + 255) & ~255;
          size = dstPitch * width * 3;
       } else {
-         dstPitch = ((width / 2) + 511) & ~511;	/* of chroma */
+         dstPitch = ((width / 2) + 255) & ~255;	/* of chroma */
          size = dstPitch * height * 3;
       }
 #endif
@@ -1989,10 +2017,10 @@ I830PutImage(ScrnInfoPtr pScrn,
       }
 #else
       if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
-         dstPitch = ((height << 1) + 511) & ~511;
+         dstPitch = ((height << 1) + 255) & ~255;
          size = dstPitch * width;
       } else {
-         dstPitch = ((width << 1) + 511) & ~511;	/* of chroma */
+         dstPitch = ((width << 1) + 255) & ~255;	/* of chroma */
          size = dstPitch * height;
       }
 #endif
@@ -2526,27 +2554,29 @@ I830VideoSwitchModeAfter(ScrnInfoPtr pSc
       }
    }
 
-   if (pPriv->pipe == 0) {
-      if (INREG(PIPEACONF) & PIPEACONF_DOUBLE_WIDE) {
-         xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-	   "Disabling XVideo output because Pipe A is in double-wide mode.\n");
-         pPriv->overlayOK = FALSE;
-      } else if (!pPriv->overlayOK) {
-         xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-	   "Re-enabling XVideo output because Pipe A is now in single-wide mode.\n");
-         pPriv->overlayOK = TRUE;
+   if (!IS_I965G(pI830)) {
+      if (pPriv->pipe == 0) {
+         if (INREG(PIPEACONF) & PIPEACONF_DOUBLE_WIDE) {
+            xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+	    "Disabling XVideo output because Pipe A is in double-wide mode.\n");
+            pPriv->overlayOK = FALSE;
+         } else if (!pPriv->overlayOK) {
+            xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+	    "Re-enabling XVideo output because Pipe A is now in single-wide mode.\n");
+            pPriv->overlayOK = TRUE;
+         }
       }
-   }
 
-   if (pPriv->pipe == 1) {
-      if (INREG(PIPEBCONF) & PIPEBCONF_DOUBLE_WIDE) {
-         xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-	   "Disabling XVideo output because Pipe B is in double-wide mode.\n");
-         pPriv->overlayOK = FALSE;
-      } else if (!pPriv->overlayOK) {
-         xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-	   "Re-enabling XVideo output because Pipe B is now in single-wide mode.\n");
-         pPriv->overlayOK = TRUE;
+      if (pPriv->pipe == 1) {
+         if (INREG(PIPEBCONF) & PIPEBCONF_DOUBLE_WIDE) {
+            xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+   	    "Disabling XVideo output because Pipe B is in double-wide mode.\n");
+            pPriv->overlayOK = FALSE;
+         } else if (!pPriv->overlayOK) {
+            xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+	    "Re-enabling XVideo output because Pipe B is now in single-wide mode.\n");
+            pPriv->overlayOK = TRUE;
+         }
       }
    }
 
diff-tree d56ffa5f35e3cf4262d66469052b2122fdb24027 (from 4525379d95ff292d7322e1a7a516c0bedd1f7543)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Thu Aug 3 16:03:50 2006 -0700

    Bump PS_MAX_THREADS to 32 now that the program doesn't fail.

diff --git a/src/i830_video.c b/src/i830_video.c
index 7a426db..107818b 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2695,7 +2695,7 @@ static const CARD32 sf_kernel_static[][4
 
 /* Our PS kernel uses less than 32 GRF registers (about 20) */
 #define PS_KERNEL_NUM_GRF   32
-#define PS_MAX_THREADS	   1
+#define PS_MAX_THREADS	   32
 
 #define BRW_GRF_BLOCKS(nreg)	((nreg + 15) / 16 - 1)
 
diff-tree 4525379d95ff292d7322e1a7a516c0bedd1f7543 (from ad2c70b4121121f1fb53190ea49edf2323c804a9)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Thu Aug 3 16:03:15 2006 -0700

    Make the sampler's payload be the WM payload rather than uninitialized data.
    
    The sampler's payload happens to be in the same format as the WM payload,
    though most of the fields are ignored.
    
    This appears to fix the program in the presence of multiple PS threads.

diff --git a/src/wm_prog.h b/src/wm_prog.h
index a8391c4..297ddcb 100644
--- a/src/wm_prog.h
+++ b/src/wm_prog.h
@@ -95,8 +95,8 @@
    { 0x00600001, 0x206003be, 0x008d00c0, 0x00000000 },
 /*    mov (8) m4<1>F g7<8,8,1>F { align1 +  } */
    { 0x00600001, 0x208003be, 0x008d00e0, 0x00000000 },
-/*    send   0 (16) g12<1>UW g8<8,8,1>UW sampler mlen 5 rlen 8 { align1 +  } */
-   { 0x00800031, 0x21801d29, 0x008d0100, 0x02580001 },
+/*    send   0 (16) g12<1>UW g0<8,8,1>UW sampler mlen 5 rlen 8 { align1 +  } */
+   { 0x00800031, 0x21801d29, 0x008d0000, 0x02580001 },
 /*    mov (8) g19<1>UW g19<8,8,1>UW { align1 +  } */
    { 0x00600001, 0x22600129, 0x008d0260, 0x00000000 },
 /*    add (8) g14<1>F g14<8,8,1>F -0.0627451{ align1 +  } */
diff-tree ad2c70b4121121f1fb53190ea49edf2323c804a9 (from f9e94c17c55e4c75802d8574c908744e286e7843)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Thu Aug 3 12:47:19 2006 -0700

    Remove some stale XXX-prefixed comments.

diff --git a/src/i830_video.c b/src/i830_video.c
index e495042..7a426db 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -3058,19 +3058,6 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    sf_state->sf6.dest_org_vbias = 0x8;
    sf_state->sf6.dest_org_hbias = 0x8;
 
-   /* XXX: Set up the PS kernel (dispatched by WM) for converting YUV to RGB.
-    * The 3D driver does this as:
-    *
-	 CONST C0 = { -.5, -.0625,  -.5, 1.164 }
-	 CONST C1 = { 1.596, -0.813, 2.018, -.391 }
-	 UYV     = TEX ...
-	 UYV.xyz = ADD UYV,     C0
-	 UYV.y   = MUL UYV.y,   C0.w
-	 RGB.xyz = MAD UYV.xxz, C1,   UYV.y
-	 RGB.y   = MAD UYV.z,   C1.w, RGB.y
-    *
-    */
-
    memcpy (ps_kernel, ps_kernel_static, sizeof (ps_kernel_static));
 #if 0
    ErrorF ("ps kernel: 0x%08x\n", state_base_offset + ps_kernel_offset);
@@ -3088,13 +3075,13 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
 						   wm_scratch_offset) >> 10;
    wm_state->thread2.per_thread_scratch_space = 0; /* 1024 bytes */
    wm_state->thread3.dispatch_grf_start_reg = 3; /* XXX */
+   wm_state->thread3.const_urb_entry_read_length = 0;
+   wm_state->thread3.const_urb_entry_read_offset = 0;
    wm_state->thread3.urb_entry_read_length = 1; /* XXX */
-   wm_state->thread3.const_urb_entry_read_length = 0; /* XXX */
-   wm_state->thread3.const_urb_entry_read_offset = 0; /* XXX */
    wm_state->thread3.urb_entry_read_offset = 0; /* XXX */
    wm_state->wm4.stats_enable = 1;
    wm_state->wm4.sampler_state_pointer = (state_base_offset + src_sampler_offset) >> 5;
-   wm_state->wm4.sampler_count = 1; /* XXX 1-4 samplers used */
+   wm_state->wm4.sampler_count = 1; /* 1-4 samplers used */
    wm_state->wm5.max_threads = PS_MAX_THREADS - 1;
    wm_state->wm5.thread_dispatch_enable = 1;
    wm_state->wm5.enable_16_pix = 1;
diff-tree f9e94c17c55e4c75802d8574c908744e286e7843 (from aefa6fdfc5300546caeb64ace14a7854d3dc7dae)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Wed Aug 2 21:18:19 2006 -0700

    Set the WM scratch space that we had already allocated.
    
    It appears to be required, even if the kernel doesn't use any scratch space.

diff --git a/src/i830_video.c b/src/i830_video.c
index 6ded126..e495042 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -3081,8 +3081,12 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    wm_state->thread0.grf_reg_count = BRW_GRF_BLOCKS(PS_KERNEL_NUM_GRF);
    wm_state->thread1.single_program_flow = 1; /* XXX */
    wm_state->thread1.binding_table_entry_count = 2;
-   wm_state->thread2.scratch_space_base_pointer = 0; /* XXX */
-   wm_state->thread2.per_thread_scratch_space = 0; /* XXX */
+   /* Though we never use the scratch space in our WM kernel, it has to be
+    * set, and the minimum allocation is 1024 bytes.
+    */
+   wm_state->thread2.scratch_space_base_pointer = (state_base_offset +
+						   wm_scratch_offset) >> 10;
+   wm_state->thread2.per_thread_scratch_space = 0; /* 1024 bytes */
    wm_state->thread3.dispatch_grf_start_reg = 3; /* XXX */
    wm_state->thread3.urb_entry_read_length = 1; /* XXX */
    wm_state->thread3.const_urb_entry_read_length = 0; /* XXX */
diff-tree aefa6fdfc5300546caeb64ace14a7854d3dc7dae (from 7a64e14624514ef31f6fa9f15e8804c45f930212)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Wed Aug 2 21:14:14 2006 -0700

    Clean up GRF allocation (which was wrong at 16-register boundaries).
    
    Also use PS_MAX_THREADS rather than hard-coding 1 thread, and remove the dead
    SF_KERNEL_NUM_URB macro.

diff --git a/src/i830_video.c b/src/i830_video.c
index 76b35fc..6ded126 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2643,16 +2643,12 @@ static const CARD32 sip_kernel_static[][
    
 /*
  * this program computes dA/dx and dA/dy for the texture coordinates along
- * with the base texture coordinate. It was extracted from the Mesa driver
+ * with the base texture coordinate. It was extracted from the Mesa driver.
+ * It uses about 10 GRF registers.
  */
 
-#define SF_KERNEL_NUM_GRF  10
-#define SF_KERNEL_NUM_URB  8
-#if 0
-#define SF_MAX_THREADS	   MIN(12, URB_SF_ENTRIES / 2)
-#else
+#define SF_KERNEL_NUM_GRF  16
 #define SF_MAX_THREADS	   1
-#endif
 
 static const CARD32 sf_kernel_static[][4] = {
 /*    send   0 (1) g6<1>F g1.12<0,1,0>F math mlen 1 rlen 1 { align1 +  } */
@@ -2697,17 +2693,11 @@ static const CARD32 sf_kernel_static[][4
  * values (bright pink).
  */
 
-/*
- * I am reasonably sure these values are bogus
- * but, they do appear to work. Learning precisely what
- * values belong here should improve performance by
- * increasing the number of threads that will be able to run
- * in parallel.
- */
+/* Our PS kernel uses less than 32 GRF registers (about 20) */
+#define PS_KERNEL_NUM_GRF   32
+#define PS_MAX_THREADS	   1
 
-#define PS_KERNEL_NUM_GRF   20
-#define PS_KERNEL_NUM_URB   8
-#define PS_MAX_THREADS	   1 /* MIN(12, PS_KERNEL_NUM_URB / 2) */
+#define BRW_GRF_BLOCKS(nreg)	((nreg + 15) / 16 - 1)
 
 static const CARD32 ps_kernel_static[][4] = {
 #include "wm_prog.h"
@@ -3042,7 +3032,7 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
 #endif
    sf_state->thread0.kernel_start_pointer = 
 	       (state_base_offset + sf_kernel_offset) >> 6;
-   sf_state->thread0.grf_reg_count = ((SF_KERNEL_NUM_GRF & ~15) / 16);
+   sf_state->thread0.grf_reg_count = BRW_GRF_BLOCKS(SF_KERNEL_NUM_GRF);
    sf_state->sf1.single_program_flow = 1; /* XXX */
    sf_state->sf1.binding_table_entry_count = 0;
    sf_state->sf1.thread_priority = 0;
@@ -3088,7 +3078,7 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    memset (wm_state, 0, sizeof (*wm_state));
    wm_state->thread0.kernel_start_pointer = 
 	    (state_base_offset + ps_kernel_offset) >> 6;
-   wm_state->thread0.grf_reg_count = ((PS_KERNEL_NUM_GRF & ~15) / 16);
+   wm_state->thread0.grf_reg_count = BRW_GRF_BLOCKS(PS_KERNEL_NUM_GRF);
    wm_state->thread1.single_program_flow = 1; /* XXX */
    wm_state->thread1.binding_table_entry_count = 2;
    wm_state->thread2.scratch_space_base_pointer = 0; /* XXX */
@@ -3101,7 +3091,7 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    wm_state->wm4.stats_enable = 1;
    wm_state->wm4.sampler_state_pointer = (state_base_offset + src_sampler_offset) >> 5;
    wm_state->wm4.sampler_count = 1; /* XXX 1-4 samplers used */
-   wm_state->wm5.max_threads = 0;   /* XXX should be PS_MAX_THREADS */
+   wm_state->wm5.max_threads = PS_MAX_THREADS - 1;
    wm_state->wm5.thread_dispatch_enable = 1;
    wm_state->wm5.enable_16_pix = 1;
    wm_state->wm5.enable_8_pix = 0;
diff-tree 7a64e14624514ef31f6fa9f15e8804c45f930212 (from bc6a2bb7576a7c1e7971f6d1e0b893b2ada1aaa3)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Wed Aug 2 20:48:13 2006 -0700

    Crank down the SF allocation and comment on why this is a fine lower limit.

diff --git a/src/i830_video.c b/src/i830_video.c
index 5e5c937..76b35fc 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2905,8 +2905,13 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
 #define URB_CLIP_ENTRIES      0
 #define URB_CLIP_ENTRY_SIZE   0
    
-#define URB_SF_ENTRIES	      8
-#define URB_SF_ENTRY_SIZE     11
+   /* The SF kernel we use outputs only 4 256-bit registers, leading to an
+    * entry size of 2 512-bit URBs.  We don't need to have many entries to
+    * output as we're generally working on large rectangles and don't care
+    * about having WM threads running on different rectangles simultaneously.
+    */
+#define URB_SF_ENTRIES	      1
+#define URB_SF_ENTRY_SIZE     2
 
 #define URB_CS_ENTRIES	      0
 #define URB_CS_ENTRY_SIZE     0
diff-tree bc6a2bb7576a7c1e7971f6d1e0b893b2ada1aaa3 (from defe2795429484ffe4c1438bafb86bb5e5469ba9)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Wed Aug 2 20:34:57 2006 -0700

    Remove the clip URB allocation.
    
    Previously, the VS was misconfigured and exceeding its allocation, which the
    (unused) clip was providing padding for.

diff --git a/src/i830_video.c b/src/i830_video.c
index f2b12b8..5e5c937 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2902,8 +2902,8 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
 #define URB_GS_ENTRIES	      0
 #define URB_GS_ENTRY_SIZE     0
    
-#define URB_CLIP_ENTRIES      6
-#define URB_CLIP_ENTRY_SIZE   5
+#define URB_CLIP_ENTRIES      0
+#define URB_CLIP_ENTRY_SIZE   0
    
 #define URB_SF_ENTRIES	      8
 #define URB_SF_ENTRY_SIZE     11
diff-tree defe2795429484ffe4c1438bafb86bb5e5469ba9 (from b57ccb682cb3dea3e26c6f1b0c709e63dfde0d31)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Wed Aug 2 20:32:41 2006 -0700

    Correct the VS setup, and allocate a correct, minimal number of URB entries.
    
    The VS number of URB entries and URB entry size are always used, even when
    the VS is disabled.  Similarly, the cache enable bit is always used.

diff --git a/src/i830_video.c b/src/i830_video.c
index a8ffca7..f2b12b8 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2891,10 +2891,12 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    binding_table = (void *)(state_base + binding_table_offset);
    vb = (void *)(state_base + vb_offset);
 
-   /* Set up a default static partitioning of the URB, which is supposed to
-    * allow anything we would want to do, at potentially lower performance.
+   /* For 3D, the VS must have 8, 12, 16, 24, or 32 VUEs allocated to it.
+    * A VUE consists of a 256-bit vertex header followed by the vertex data,
+    * which in our case is 4 floats (128 bits), thus a single 512-bit URB
+    * entry.
     */
-#define URB_VS_ENTRIES	      3
+#define URB_VS_ENTRIES	      8
 #define URB_VS_ENTRY_SIZE     1
    
 #define URB_GS_ENTRIES	      0
@@ -3018,7 +3020,10 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
 
    /* Set up the vertex shader to be disabled (passthrough) */
    memset(vs_state, 0, sizeof(*vs_state));
+   vs_state->thread4.nr_urb_entries = URB_VS_ENTRIES;
+   vs_state->thread4.urb_entry_allocation_size = URB_VS_ENTRY_SIZE - 1;
    vs_state->vs6.vs_enable = 0;
+   vs_state->vs6.vert_cache_disable = 1;
 
    /* Set up the SF kernel to do coord interp: for each attribute,
     * calculate dA/dx and dA/dy.  Hand these interpolation coefficients
diff-tree b57ccb682cb3dea3e26c6f1b0c709e63dfde0d31 (from 82037a12758c41a304f2e0bbd033d3345cccbe1a)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Wed Aug 2 19:46:15 2006 -0700

    Replace the SF max threads setting with a define for easier tweaking.
    
    Tweak it to 1 for now.

diff --git a/src/i830_video.c b/src/i830_video.c
index 97c9d27..a8ffca7 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2648,7 +2648,11 @@ static const CARD32 sip_kernel_static[][
 
 #define SF_KERNEL_NUM_GRF  10
 #define SF_KERNEL_NUM_URB  8
+#if 0
+#define SF_MAX_THREADS	   MIN(12, URB_SF_ENTRIES / 2)
+#else
 #define SF_MAX_THREADS	   1
+#endif
 
 static const CARD32 sf_kernel_static[][4] = {
 /*    send   0 (1) g6<1>F g1.12<0,1,0>F math mlen 1 rlen 1 { align1 +  } */
@@ -3043,7 +3047,7 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    sf_state->thread3.urb_entry_read_length = 1; /* 1 URB per vertex */
    sf_state->thread3.urb_entry_read_offset = 0;
    sf_state->thread3.dispatch_grf_start_reg = 3;
-   sf_state->thread4.max_threads = MIN(12, URB_SF_ENTRIES / 2) - 1;
+   sf_state->thread4.max_threads = SF_MAX_THREADS - 1;
    sf_state->thread4.urb_entry_allocation_size = URB_SF_ENTRY_SIZE - 1;
    sf_state->thread4.nr_urb_entries = URB_SF_ENTRIES;
    sf_state->thread4.stats_enable = 1;
diff-tree 82037a12758c41a304f2e0bbd033d3345cccbe1a (from 1d45668d7a42bfa5d7f5bfb68d8bae38bda0936b)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Wed Aug 2 19:33:28 2006 -0700

    Remove CS URB allocation since we don't use any constants.

diff --git a/src/i830_video.c b/src/i830_video.c
index 9308323..97c9d27 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2902,8 +2902,8 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
 #define URB_SF_ENTRIES	      8
 #define URB_SF_ENTRY_SIZE     11
 
-#define URB_CS_ENTRIES	      2
-#define URB_CS_ENTRY_SIZE     32
+#define URB_CS_ENTRIES	      0
+#define URB_CS_ENTRY_SIZE     0
    
    urb_vs_start = 0;
    urb_vs_size = URB_VS_ENTRIES * URB_VS_ENTRY_SIZE;
diff-tree 1d45668d7a42bfa5d7f5bfb68d8bae38bda0936b (from a076d35bed6f13cf943a0f8948176aa0c999e2da)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Wed Aug 2 19:18:20 2006 -0700

    We only need 3 vertices to fit in the URB, since we only dispatch 3.

diff --git a/src/i830_video.c b/src/i830_video.c
index 769c45f..9308323 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2890,7 +2890,7 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    /* Set up a default static partitioning of the URB, which is supposed to
     * allow anything we would want to do, at potentially lower performance.
     */
-#define URB_VS_ENTRIES	      8
+#define URB_VS_ENTRIES	      3
 #define URB_VS_ENTRY_SIZE     1
    
 #define URB_GS_ENTRIES	      0
diff-tree a076d35bed6f13cf943a0f8948176aa0c999e2da (from befa655168fb8dcb6806592eb44f7ac49f191822)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Wed Aug 2 19:16:03 2006 -0700

    No GS URB allocation is necessary when the function is disabled.

diff --git a/src/i830_video.c b/src/i830_video.c
index 9ae9ce5..769c45f 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2893,8 +2893,8 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
 #define URB_VS_ENTRIES	      8
 #define URB_VS_ENTRY_SIZE     1
    
-#define URB_GS_ENTRIES	      4
-#define URB_GS_ENTRY_SIZE     5
+#define URB_GS_ENTRIES	      0
+#define URB_GS_ENTRY_SIZE     0
    
 #define URB_CLIP_ENTRIES      6
 #define URB_CLIP_ENTRY_SIZE   5
diff-tree befa655168fb8dcb6806592eb44f7ac49f191822 (from 33acbdca0a0f82725e5bf7887b325726403a6ffd)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Wed Aug 2 19:11:38 2006 -0700

    Reduce URB_VS_ENTRY_SIZE to 1 as our vertices are under 8 floats.

diff --git a/src/i830_video.c b/src/i830_video.c
index df66151..9ae9ce5 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2891,7 +2891,7 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
     * allow anything we would want to do, at potentially lower performance.
     */
 #define URB_VS_ENTRIES	      8
-#define URB_VS_ENTRY_SIZE     5
+#define URB_VS_ENTRY_SIZE     1
    
 #define URB_GS_ENTRIES	      4
 #define URB_GS_ENTRY_SIZE     5
diff-tree 33acbdca0a0f82725e5bf7887b325726403a6ffd (from aafa48cb85cd03c735fb968a4275c19e1a68cd02)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Wed Aug 2 19:09:19 2006 -0700

    Remove the VS kernel and binding table.
    
    The VS URB entries have to remain as they're used to store the VF output which
    isn't modified by a VS program.

diff --git a/src/i830_video.c b/src/i830_video.c
index 1b22e11..df66151 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2641,33 +2641,6 @@ static const CARD32 sip_kernel_static[][
     { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
 };
    
-static const CARD32 vs_kernel_static[][4] = {
-   /*    mov (8) m1<1>F g1<8,8,1>F { align1 +  } */
-   { 0x00600001, 0x202003be, 0x008d0020, 0x00000000 },
-   /*    mov (1) g0.8<1>D 0 { align1 mask_disable +  } */
-   { 0x00000201, 0x200810e5, 0x00000000, 0x00000000 },
-   /*    send   0 (8) a0<1>UW g0<8,8,1>F write mlen 3 rlen 0 { align1 +  } */
-   { 0x00600031, 0x20001fa8, 0x008d0000, 0x053003ff },
-   /*    send   0 (8) a0<1>F g0<8,8,1>F urb mlen 2 rlen 0 write +0 noswizzle used complete EOT{ align1 +  } */
-   { 0x00600031, 0x20001fbc, 0x008d0000, 0x8620c000 },
-   /*    nop (4) g0<1>UD { align1 +  } */
-   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-   /*    nop (4) g0<1>UD { align1 +  } */
-   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-   /*    nop (4) g0<1>UD { align1 +  } */
-   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-   /*    nop (4) g0<1>UD { align1 +  } */
-   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-   /*    nop (4) g0<1>UD { align1 +  } */
-   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-   /*    nop (4) g0<1>UD { align1 +  } */
-   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-   /*    nop (4) g0<1>UD { align1 +  } */
-   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-   /*    nop (4) g0<1>UD { align1 +  } */
-   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-};
-   
 /*
  * this program computes dA/dx and dA/dy for the texture coordinates along
  * with the base texture coordinate. It was extracted from the Mesa driver
@@ -2807,7 +2780,6 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    struct brw_wm_unit_state *wm_state;
    struct brw_cc_unit_state *cc_state;
    struct brw_cc_viewport *cc_viewport;
-   struct brw_instruction *vs_kernel;
    struct brw_instruction *sf_kernel;
    struct brw_instruction *ps_kernel;
    struct brw_instruction *sip_kernel;
@@ -2817,7 +2789,6 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    int dest_surf_offset, src_surf_offset, src_sampler_offset, vs_offset;
    int sf_offset, wm_offset, cc_offset, vb_offset, cc_viewport_offset;
    int wm_scratch_offset;
-   int vs_kernel_offset;
    int sf_kernel_offset, ps_kernel_offset, sip_kernel_offset;
    int binding_table_offset;
    int next_offset, total_state_size;
@@ -2825,15 +2796,6 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    char *state_base;
    int state_base_offset;
 
-    int vs_scratch_offset;
-#define VS_SCRATCH_SIZE	1024
-#define VS_SCRATCH_NUM (VS_SCRATCH_SIZE / sizeof (float))
-    char *vs_scratch;
-    int vs_scratch_surface_state_offset;
-    struct brw_surface_state *vs_scratch_surface_state;
-    int vs_binding_table_offset;
-    CARD32 *vs_binding_table;
-
 #if 0
    ErrorF("BroadwaterDisplayVideoTextured: %dx%d (pitch %d)\n", width, height,
 	  video_pitch);
@@ -2875,15 +2837,6 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    next_offset = ps_kernel_offset + sizeof (ps_kernel_static);
    sip_kernel_offset = ALIGN(next_offset, 64);
    next_offset = sip_kernel_offset + sizeof (sip_kernel_static);
-   vs_kernel_offset = ALIGN(next_offset, 64);
-   next_offset = vs_kernel_offset + sizeof (vs_kernel_static);
-   vs_scratch_offset = ALIGN(next_offset, 1024);
-   next_offset = vs_scratch_offset + VS_SCRATCH_SIZE;
-   vs_scratch_surface_state_offset = ALIGN(next_offset, 32);
-   next_offset = vs_scratch_surface_state_offset + sizeof (struct brw_surface_state);
-   vs_binding_table_offset = ALIGN(next_offset, 32);
-   next_offset = vs_binding_table_offset + 1 * 4;
-   
    cc_viewport_offset = ALIGN(next_offset, 32);
    next_offset = cc_viewport_offset + sizeof(*cc_viewport);
 
@@ -2926,10 +2879,6 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    sf_kernel = (void *)(state_base + sf_kernel_offset);
    ps_kernel = (void *)(state_base + ps_kernel_offset);
    sip_kernel = (void *)(state_base + sip_kernel_offset);
-   vs_kernel = (void *)(state_base + vs_kernel_offset);
-   vs_scratch = (void *)(state_base + vs_scratch_offset);
-   vs_scratch_surface_state = (void *)(state_base + vs_scratch_surface_state_offset);
-   vs_binding_table = (void *)(state_base + vs_binding_table_offset);
    
    cc_viewport = (void *)(state_base + cc_viewport_offset);
    dest_surf_state = (void *)(state_base + dest_surf_offset);
@@ -3064,30 +3013,8 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    src_sampler_state->ss1.t_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
 
    /* Set up the vertex shader to be disabled (passthrough) */
-   vs_binding_table[0] = state_base_offset + vs_scratch_surface_state_offset;
-   memset (vs_scratch_surface_state, 0, sizeof (*vs_scratch_surface_state));
-   vs_scratch_surface_state->ss0.surface_type = BRW_SURFACE_BUFFER;
-   vs_scratch_surface_state->ss0.surface_format = BRW_SURFACEFORMAT_R32_FLOAT;
-   vs_scratch_surface_state->ss1.base_addr = state_base_offset + vs_scratch_offset;
-   vs_scratch_surface_state->ss2.height = (VS_SCRATCH_NUM - 1) >> 7;
-   vs_scratch_surface_state->ss2.width = (VS_SCRATCH_NUM - 1) & 0x7f;
-   vs_scratch_surface_state->ss3.pitch = 3;
-   
-   memcpy(vs_kernel, vs_kernel_static, sizeof (vs_kernel_static));
-   
    memset(vs_state, 0, sizeof(*vs_state));
-#if 0
-   ErrorF ("vs kernel: 0x%08x\n", state_base_offset + vs_kernel_offset);
-#endif
-   vs_state->thread0.kernel_start_pointer =
-	    (state_base_offset + vs_kernel_offset) >> 6;
-   vs_state->thread0.grf_reg_count = 1;
-   vs_state->thread1.single_program_flow = 1;
-   vs_state->thread4.nr_urb_entries = URB_VS_ENTRIES;
-   vs_state->thread4.urb_entry_allocation_size = URB_VS_ENTRY_SIZE - 1;
-   vs_state->thread4.stats_enable = 1;
    vs_state->vs6.vs_enable = 0;
-   vs_state->vs6.vert_cache_disable = 1;
 
    /* Set up the SF kernel to do coord interp: for each attribute,
     * calculate dA/dx and dA/dy.  Hand these interpolation coefficients
@@ -3217,7 +3144,7 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
 
    /* Binding table pointers */
    OUT_RING(BRW_3DSTATE_BINDING_TABLE_POINTERS | 4);
-   OUT_RING(state_base_offset + vs_binding_table_offset); /* vs */
+   OUT_RING(0); /* vs */
    OUT_RING(0); /* gs */
    OUT_RING(0); /* clip */
    OUT_RING(0); /* sf */
@@ -3354,10 +3281,6 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
       vb[i++] = (float) box_y1;
 
 #if 0
-      memset (vs_scratch, 1, VS_SCRATCH_SIZE);
-#endif
-      
-#if 0
       ErrorF ("before EU_ATT 0x%08x%08x EU_ATT_DATA 0x%08x%08x\n",
 	      INREG(BRW_EU_ATT_1), INREG(BRW_EU_ATT_0),
 	      INREG(BRW_EU_ATT_DATA_1), INREG(BRW_EU_ATT_DATA_0));
@@ -3448,13 +3371,6 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
       }
       
       OUTREG(BRW_VS_CTL, 0);
-      for (j = 0; j < 32; j += 8)
-	 ErrorF (" vs_scratch(%2d): %02x %02x %02x %02x  %02x %02x %02x %02x\n",
-		 j,
-		 vs_scratch[j+0], vs_scratch[j+1],
-		 vs_scratch[j+2], vs_scratch[j+3], 
-		 vs_scratch[j+4], vs_scratch[j+5],
-		 vs_scratch[j+6], vs_scratch[j+7]);
 #endif
 
 #if WATCH_SF
diff-tree aafa48cb85cd03c735fb968a4275c19e1a68cd02 (from bc2c842d93de04d48c7de60482814db346bd0b78)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Wed Aug 2 18:26:26 2006 -0700

    Fix wm prog to correct the ordering of the Cr and Cb channels.

diff --git a/src/wm_prog.h b/src/wm_prog.h
index 0d0c36a..a8391c4 100644
--- a/src/wm_prog.h
+++ b/src/wm_prog.h
@@ -101,46 +101,46 @@
    { 0x00600001, 0x22600129, 0x008d0260, 0x00000000 },
 /*    add (8) g14<1>F g14<8,8,1>F -0.0627451{ align1 +  } */
    { 0x00600040, 0x21c07fbd, 0x008d01c0, 0xbd808081 },
-/*    add (8) g16<1>F g16<8,8,1>F -0.501961{ align1 +  } */
-   { 0x00600040, 0x22007fbd, 0x008d0200, 0xbf008081 },
 /*    add (8) g12<1>F g12<8,8,1>F -0.501961{ align1 +  } */
    { 0x00600040, 0x21807fbd, 0x008d0180, 0xbf008081 },
+/*    add (8) g16<1>F g16<8,8,1>F -0.501961{ align1 +  } */
+   { 0x00600040, 0x22007fbd, 0x008d0200, 0xbf008081 },
 /*    mul (8) g14<1>F g14<8,8,1>F 1.164{ align1 +  } */
    { 0x00600041, 0x21c07fbd, 0x008d01c0, 0x3f94fdf4 },
-/*    mul (8) a0<1>F g16<8,8,1>F 1.596{ align1 +  } */
-   { 0x00600041, 0x20007fbc, 0x008d0200, 0x3fcc49ba },
+/*    mul (8) a0<1>F g12<8,8,1>F 1.596{ align1 +  } */
+   { 0x00600041, 0x20007fbc, 0x008d0180, 0x3fcc49ba },
 /*    mac (8) m2<1>F g14<8,8,1>F 1{ align1 + Saturate  } */
    { 0x80600048, 0x20407fbe, 0x008d01c0, 0x3f800000 },
-/*    mul (8) a0<1>F g16<8,8,1>F -0.813{ align1 +  } */
-   { 0x00600041, 0x20007fbc, 0x008d0200, 0xbf5020c5 },
-/*    mac (8) a0<1>F g12<8,8,1>F -0.392{ align1 +  } */
-   { 0x00600048, 0x20007fbc, 0x008d0180, 0xbec8b439 },
+/*    mul (8) a0<1>F g12<8,8,1>F -0.813{ align1 +  } */
+   { 0x00600041, 0x20007fbc, 0x008d0180, 0xbf5020c5 },
+/*    mac (8) a0<1>F g16<8,8,1>F -0.392{ align1 +  } */
+   { 0x00600048, 0x20007fbc, 0x008d0200, 0xbec8b439 },
 /*    mac (8) m3<1>F g14<8,8,1>F 1{ align1 + Saturate  } */
    { 0x80600048, 0x20607fbe, 0x008d01c0, 0x3f800000 },
-/*    mul (8) a0<1>F g12<8,8,1>F 2.017{ align1 +  } */
-   { 0x00600041, 0x20007fbc, 0x008d0180, 0x40011687 },
+/*    mul (8) a0<1>F g16<8,8,1>F 2.017{ align1 +  } */
+   { 0x00600041, 0x20007fbc, 0x008d0200, 0x40011687 },
 /*    mac (8) m4<1>F g14<8,8,1>F 1{ align1 + Saturate  } */
    { 0x80600048, 0x20807fbe, 0x008d01c0, 0x3f800000 },
 /*    add (8) g15<1>F g15<8,8,1>F -0.0627451{ align1 +  } */
    { 0x00600040, 0x21e07fbd, 0x008d01e0, 0xbd808081 },
-/*    add (8) g17<1>F g17<8,8,1>F -0.501961{ align1 +  } */
-   { 0x00600040, 0x22207fbd, 0x008d0220, 0xbf008081 },
 /*    add (8) g13<1>F g13<8,8,1>F -0.501961{ align1 +  } */
    { 0x00600040, 0x21a07fbd, 0x008d01a0, 0xbf008081 },
+/*    add (8) g17<1>F g17<8,8,1>F -0.501961{ align1 +  } */
+   { 0x00600040, 0x22207fbd, 0x008d0220, 0xbf008081 },
 /*    mul (8) g15<1>F g15<8,8,1>F 1.164{ align1 +  } */
    { 0x00600041, 0x21e07fbd, 0x008d01e0, 0x3f94fdf4 },
-/*    mul (8) a0<1>F g17<8,8,1>F 1.596{ align1 +  } */
-   { 0x00600041, 0x20007fbc, 0x008d0220, 0x3fcc49ba },
+/*    mul (8) a0<1>F g13<8,8,1>F 1.596{ align1 +  } */
+   { 0x00600041, 0x20007fbc, 0x008d01a0, 0x3fcc49ba },
 /*    mac (8) m6<1>F g15<8,8,1>F 1{ align1 + Saturate  } */
    { 0x80600048, 0x20c07fbe, 0x008d01e0, 0x3f800000 },
-/*    mul (8) a0<1>F g17<8,8,1>F -0.813{ align1 +  } */
-   { 0x00600041, 0x20007fbc, 0x008d0220, 0xbf5020c5 },
-/*    mac (8) a0<1>F g13<8,8,1>F -0.392{ align1 +  } */
-   { 0x00600048, 0x20007fbc, 0x008d01a0, 0xbec8b439 },
+/*    mul (8) a0<1>F g13<8,8,1>F -0.813{ align1 +  } */
+   { 0x00600041, 0x20007fbc, 0x008d01a0, 0xbf5020c5 },
+/*    mac (8) a0<1>F g17<8,8,1>F -0.392{ align1 +  } */
+   { 0x00600048, 0x20007fbc, 0x008d0220, 0xbec8b439 },
 /*    mac (8) m7<1>F g15<8,8,1>F 1{ align1 + Saturate  } */
    { 0x80600048, 0x20e07fbe, 0x008d01e0, 0x3f800000 },
-/*    mul (8) a0<1>F g13<8,8,1>F 2.017{ align1 +  } */
-   { 0x00600041, 0x20007fbc, 0x008d01a0, 0x40011687 },
+/*    mul (8) a0<1>F g17<8,8,1>F 2.017{ align1 +  } */
+   { 0x00600041, 0x20007fbc, 0x008d0220, 0x40011687 },
 /*    mac (8) m8<1>F g15<8,8,1>F 1{ align1 + Saturate  } */
    { 0x80600048, 0x21007fbe, 0x008d01e0, 0x3f800000 },
 /*    mov (8) m1<1>UD g1<8,8,1>UD { align1 mask_disable +  } */
diff-tree bc2c842d93de04d48c7de60482814db346bd0b78 (from 524460ea1f02bb6e8e2239d7763334666012cec4)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Wed Aug 2 18:10:01 2006 -0700

    Allocate space for the 965's state at the end of the video buffer.
    
    Fixes corruption in the first few lines of the video.
    
    Based on 1b506798d98d911be733543da2c40cb451a28912

diff --git a/src/i830_video.c b/src/i830_video.c
index 8d95a34..1b22e11 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -133,6 +133,11 @@ static Atom xvGamma0, xvGamma1, xvGamma2
 #define IMAGE_MAX_WIDTH_LEGACY	1024
 #define IMAGE_MAX_HEIGHT_LEGACY	1080
 
+/*
+ * Broadwater requires a bit of extra video memory for state information
+ */
+#define BRW_LINEAR_EXTRA	(32*1024)
+
 #if !VIDEO_DEBUG
 #define ErrorF Edummy
 static void
@@ -2817,7 +2822,6 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    int binding_table_offset;
    int next_offset, total_state_size;
    int vb_size = (4 * 4) * 4; /* 4 DWORDS per vertex */
-   FBLinearPtr state_area;
    char *state_base;
    int state_base_offset;
 
@@ -2900,15 +2904,16 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
 
    /* Allocate an area in framebuffer for our state layout we just set up */
    total_state_size = next_offset;
-   state_area = I830AllocateMemory(pScrn, NULL, (total_state_size + 64) /
-				   pI830->cpp);
-   if (state_area == NULL) {
-      ErrorF("Failed to allocate %d bytes for state\n", total_state_size);
-      return;
-   }
+   assert (total_state_size < BRW_LINEAR_EXTRA);
 
-   state_base_offset = pI830->FrontBuffer.Start + pPriv->linear->offset * pI830->cpp;
+   /*
+    * Use the extra space allocated at the end of the Xv buffer
+    */
+   state_base_offset = (pPriv->YBuf0offset + 
+			pPriv->linear->size * pI830->cpp -
+			BRW_LINEAR_EXTRA);
    state_base_offset = ALIGN(state_base_offset, 64);
+
    state_base = (char *)(pI830->FbBase + state_base_offset);
    /* Set up our pointers to state structures in framebuffer.  It would probably
     * be a good idea to fill these structures out in system memory and then dump
@@ -3515,7 +3520,6 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
 #if WATCH_STATS
    I830PrintErrorState (pScrn);
 #endif
-   xf86FreeOffscreenLinear(state_area);
 }
 
 static FBLinearPtr
@@ -3594,6 +3598,7 @@ I830PutImage(ScrnInfoPtr pScrn,
    int top, left, npixels, nlines, size, loops;
    BoxRec dstBox;
    int pitchAlignMask;
+   int extraLinear;
 
    DPRINTF(PFX, "I830PutImage: src: (%d,%d)(%d,%d), dst: (%d,%d)(%d,%d)\n"
 	   "width %d, height %d\n", src_x, src_y, src_w, src_h, drw_x, drw_y,
@@ -3696,9 +3701,14 @@ I830PutImage(ScrnInfoPtr pScrn,
    ErrorF("srcPitch: %d, dstPitch: %d, size: %d\n", srcPitch, dstPitch, size);
 #endif
 
+   if (IS_BROADWATER(pI830))
+      extraLinear = BRW_LINEAR_EXTRA;
+   else
+      extraLinear = 0;
+
    /* size is multiplied by 2 because we have two buffers that are flipping */
    pPriv->linear = I830AllocateMemory(pScrn, pPriv->linear,
-		   (pPriv->doubleBuffer ? size * 2 : size) / pI830->cpp);
+		   extraLinear + (pPriv->doubleBuffer ? size * 2 : size) / pI830->cpp);
 
    if(!pPriv->linear || pPriv->linear->offset < (pScrn->virtualX * pScrn->virtualY))
       return BadAlloc;
diff-tree 524460ea1f02bb6e8e2239d7763334666012cec4 (from ba896c779c697e1d7458028798ec49013bd9da9f)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Wed Aug 2 17:47:55 2006 -0700

    Updated WM kernel to load video and do colorspace conversion.

diff --git a/src/wm_prog.h b/src/wm_prog.h
index 9fe775c..0d0c36a 100644
--- a/src/wm_prog.h
+++ b/src/wm_prog.h
@@ -1,36 +1,148 @@
 /* wm_program */
-/*    mov (8) g2<1>F g1.8<0,1,0>UW { align1 +  } */
-   { 0x00600001, 0x2040013d, 0x00000028, 0x00000000 },
-/*    add (8) g2<1>F g2<8,8,1>F g1<0,1,0>F { align1 +  } */
-   { 0x00600040, 0x204077bd, 0x008d0040, 0x00004020 },
-/*    mul (8) g2<1>F g2<8,8,1>F g10<0,1,0>F { align1 +  } */
-   { 0x00600041, 0x204077bd, 0x008d0040, 0x00000140 },
-/*    add (8) g2<1>F g2<8,8,1>F g12<0,1,0>F { align1 +  } */
-   { 0x00600040, 0x204077bd, 0x008d0040, 0x00000180 },
-/*    mov (8) g3<1>F g1.10<0,1,0>UW { align1 +  } */
-   { 0x00600001, 0x2060013d, 0x0000002a, 0x00000000 },
-/*    add (8) g3<1>F g3<8,8,1>F g1.4<0,1,0>F { align1 +  } */
-   { 0x00600040, 0x206077bd, 0x008d0060, 0x00004024 },
-/*    mul (8) g3<1>F g3<8,8,1>F g11<0,1,0>F { align1 +  } */
-   { 0x00600041, 0x206077bd, 0x008d0060, 0x00000160 },
-/*    add (8) g3<1>F g3<8,8,1>F g12.4<0,1,0>F { align1 +  } */
-   { 0x00600040, 0x206077bd, 0x008d0060, 0x00000184 },
-/*    mov (8) m2<1>F g2<8,8,1>F { align1 +  } */
-   { 0x00600001, 0x204003be, 0x008d0040, 0x00000000 },
-/*    mov (8) m3<1>F g3<8,8,1>F { align1 +  } */
-   { 0x00600001, 0x206003be, 0x008d0060, 0x00000000 },
-/*    mov (8) m4<1>F 0{ align1 +  } */
-   { 0x00600001, 0x208073fe, 0x00000000, 0x00000000 },
-/*    mov (8) m5<1>F 1{ align1 +  } */
-   { 0x00600001, 0x20a073fe, 0x00000000, 0x3f800000 },
-/*    mov (8) m6<1>F g2<8,8,1>F { align1 +  } */
-   { 0x00600001, 0x20c003be, 0x008d0040, 0x00000000 },
-/*    mov (8) m7<1>F g3<8,8,1>F { align1 +  } */
-   { 0x00600001, 0x20e003be, 0x008d0060, 0x00000000 },
-/*    mov (8) m8<1>F 0{ align1 +  } */
-   { 0x00600001, 0x210073fe, 0x00000000, 0x00000000 },
-/*    mov (8) m9<1>F 1{ align1 +  } */
-   { 0x00600001, 0x212073fe, 0x00000000, 0x3f800000 },
+/*    mov (1) g4<1>F g1.8<0,1,0>UW { align1 +  } */
+   { 0x00000001, 0x2080013d, 0x00000028, 0x00000000 },
+/*    add (1) g4.4<1>F g1.8<0,1,0>UW 1 { align1 +  } */
+   { 0x00000040, 0x20840d3d, 0x00000028, 0x00000001 },
+/*    mov (1) g4.8<1>F g1.8<0,1,0>UW { align1 +  } */
+   { 0x00000001, 0x2088013d, 0x00000028, 0x00000000 },
+/*    add (1) g4.12<1>F g1.8<0,1,0>UW 1 { align1 +  } */
+   { 0x00000040, 0x208c0d3d, 0x00000028, 0x00000001 },
+/*    mov (1) g6<1>F g1.10<0,1,0>UW { align1 +  } */
+   { 0x00000001, 0x20c0013d, 0x0000002a, 0x00000000 },
+/*    mov (1) g6.4<1>F g1.10<0,1,0>UW { align1 +  } */
+   { 0x00000001, 0x20c4013d, 0x0000002a, 0x00000000 },
+/*    add (1) g6.8<1>F g1.10<0,1,0>UW 1 { align1 +  } */
+   { 0x00000040, 0x20c80d3d, 0x0000002a, 0x00000001 },
+/*    add (1) g6.12<1>F g1.10<0,1,0>UW 1 { align1 +  } */
+   { 0x00000040, 0x20cc0d3d, 0x0000002a, 0x00000001 },
+/*    mov (1) g4.16<1>F g1.12<0,1,0>UW { align1 +  } */
+   { 0x00000001, 0x2090013d, 0x0000002c, 0x00000000 },
+/*    add (1) g4.20<1>F g1.12<0,1,0>UW 1 { align1 +  } */
+   { 0x00000040, 0x20940d3d, 0x0000002c, 0x00000001 },
+/*    mov (1) g4.24<1>F g1.12<0,1,0>UW { align1 +  } */
+   { 0x00000001, 0x2098013d, 0x0000002c, 0x00000000 },
+/*    add (1) g4.28<1>F g1.12<0,1,0>UW 1 { align1 +  } */
+   { 0x00000040, 0x209c0d3d, 0x0000002c, 0x00000001 },
+/*    mov (1) g6.16<1>F g1.14<0,1,0>UW { align1 +  } */
+   { 0x00000001, 0x20d0013d, 0x0000002e, 0x00000000 },
+/*    mov (1) g6.20<1>F g1.14<0,1,0>UW { align1 +  } */
+   { 0x00000001, 0x20d4013d, 0x0000002e, 0x00000000 },
+/*    add (1) g6.24<1>F g1.14<0,1,0>UW 1 { align1 +  } */
+   { 0x00000040, 0x20d80d3d, 0x0000002e, 0x00000001 },
+/*    add (1) g6.28<1>F g1.14<0,1,0>UW 1 { align1 +  } */
+   { 0x00000040, 0x20dc0d3d, 0x0000002e, 0x00000001 },
+/*    mov (1) g5<1>F g1.16<0,1,0>UW { align1 +  } */
+   { 0x00000001, 0x20a0013d, 0x00000030, 0x00000000 },
+/*    add (1) g5.4<1>F g1.16<0,1,0>UW 1 { align1 +  } */
+   { 0x00000040, 0x20a40d3d, 0x00000030, 0x00000001 },
+/*    mov (1) g5.8<1>F g1.16<0,1,0>UW { align1 +  } */
+   { 0x00000001, 0x20a8013d, 0x00000030, 0x00000000 },
+/*    add (1) g5.12<1>F g1.16<0,1,0>UW 1 { align1 +  } */
+   { 0x00000040, 0x20ac0d3d, 0x00000030, 0x00000001 },
+/*    mov (1) g7<1>F g1.18<0,1,0>UW { align1 +  } */
+   { 0x00000001, 0x20e0013d, 0x00000032, 0x00000000 },
+/*    mov (1) g7.4<1>F g1.18<0,1,0>UW { align1 +  } */
+   { 0x00000001, 0x20e4013d, 0x00000032, 0x00000000 },
+/*    add (1) g7.8<1>F g1.18<0,1,0>UW 1 { align1 +  } */
+   { 0x00000040, 0x20e80d3d, 0x00000032, 0x00000001 },
+/*    add (1) g7.12<1>F g1.18<0,1,0>UW 1 { align1 +  } */
+   { 0x00000040, 0x20ec0d3d, 0x00000032, 0x00000001 },
+/*    mov (1) g5.16<1>F g1.20<0,1,0>UW { align1 +  } */
+   { 0x00000001, 0x20b0013d, 0x00000034, 0x00000000 },
+/*    add (1) g5.20<1>F g1.20<0,1,0>UW 1 { align1 +  } */
+   { 0x00000040, 0x20b40d3d, 0x00000034, 0x00000001 },
+/*    mov (1) g5.24<1>F g1.20<0,1,0>UW { align1 +  } */
+   { 0x00000001, 0x20b8013d, 0x00000034, 0x00000000 },
+/*    add (1) g5.28<1>F g1.20<0,1,0>UW 1 { align1 +  } */
+   { 0x00000040, 0x20bc0d3d, 0x00000034, 0x00000001 },
+/*    mov (1) g7.16<1>F g1.22<0,1,0>UW { align1 +  } */
+   { 0x00000001, 0x20f0013d, 0x00000036, 0x00000000 },
+/*    mov (1) g7.20<1>F g1.22<0,1,0>UW { align1 +  } */
+   { 0x00000001, 0x20f4013d, 0x00000036, 0x00000000 },
+/*    add (1) g7.24<1>F g1.22<0,1,0>UW 1 { align1 +  } */
+   { 0x00000040, 0x20f80d3d, 0x00000036, 0x00000001 },
+/*    add (1) g7.28<1>F g1.22<0,1,0>UW 1 { align1 +  } */
+   { 0x00000040, 0x20fc0d3d, 0x00000036, 0x00000001 },
+/*    add (8) g4<1>F g4<8,8,1>F g1<0,1,0>F { align1 +  } */
+   { 0x00600040, 0x208077bd, 0x008d0080, 0x00004020 },
+/*    add (8) g5<1>F g5<8,8,1>F g1<0,1,0>F { align1 +  } */
+   { 0x00600040, 0x20a077bd, 0x008d00a0, 0x00004020 },
+/*    mul (8) g4<1>F g4<8,8,1>F g3<0,1,0>F { align1 +  } */
+   { 0x00600041, 0x208077bd, 0x008d0080, 0x00000060 },
+/*    mul (8) g5<1>F g5<8,8,1>F g3<0,1,0>F { align1 +  } */
+   { 0x00600041, 0x20a077bd, 0x008d00a0, 0x00000060 },
+/*    add (8) g4<1>F g4<8,8,1>F g3.12<0,1,0>F { align1 +  } */
+   { 0x00600040, 0x208077bd, 0x008d0080, 0x0000006c },
+/*    add (8) g5<1>F g5<8,8,1>F g3.12<0,1,0>F { align1 +  } */
+   { 0x00600040, 0x20a077bd, 0x008d00a0, 0x0000006c },
+/*    add (8) g6<1>F g6<8,8,1>F g1.4<0,1,0>F { align1 +  } */
+   { 0x00600040, 0x20c077bd, 0x008d00c0, 0x00004024 },
+/*    add (8) g7<1>F g7<8,8,1>F g1.4<0,1,0>F { align1 +  } */
+   { 0x00600040, 0x20e077bd, 0x008d00e0, 0x00004024 },
+/*    mul (8) g6<1>F g6<8,8,1>F g3.20<0,1,0>F { align1 +  } */
+   { 0x00600041, 0x20c077bd, 0x008d00c0, 0x00000074 },
+/*    mul (8) g7<1>F g7<8,8,1>F g3.20<0,1,0>F { align1 +  } */
+   { 0x00600041, 0x20e077bd, 0x008d00e0, 0x00000074 },
+/*    add (8) g6<1>F g6<8,8,1>F g3.28<0,1,0>F { align1 +  } */
+   { 0x00600040, 0x20c077bd, 0x008d00c0, 0x0000007c },
+/*    add (8) g7<1>F g7<8,8,1>F g3.28<0,1,0>F { align1 +  } */
+   { 0x00600040, 0x20e077bd, 0x008d00e0, 0x0000007c },
+/*    mov (8) m1<1>F g4<8,8,1>F { align1 +  } */
+   { 0x00600001, 0x202003be, 0x008d0080, 0x00000000 },
+/*    mov (8) m2<1>F g5<8,8,1>F { align1 +  } */
+   { 0x00600001, 0x204003be, 0x008d00a0, 0x00000000 },
+/*    mov (8) m3<1>F g6<8,8,1>F { align1 +  } */
+   { 0x00600001, 0x206003be, 0x008d00c0, 0x00000000 },
+/*    mov (8) m4<1>F g7<8,8,1>F { align1 +  } */
+   { 0x00600001, 0x208003be, 0x008d00e0, 0x00000000 },
+/*    send   0 (16) g12<1>UW g8<8,8,1>UW sampler mlen 5 rlen 8 { align1 +  } */
+   { 0x00800031, 0x21801d29, 0x008d0100, 0x02580001 },
+/*    mov (8) g19<1>UW g19<8,8,1>UW { align1 +  } */
+   { 0x00600001, 0x22600129, 0x008d0260, 0x00000000 },
+/*    add (8) g14<1>F g14<8,8,1>F -0.0627451{ align1 +  } */
+   { 0x00600040, 0x21c07fbd, 0x008d01c0, 0xbd808081 },
+/*    add (8) g16<1>F g16<8,8,1>F -0.501961{ align1 +  } */
+   { 0x00600040, 0x22007fbd, 0x008d0200, 0xbf008081 },
+/*    add (8) g12<1>F g12<8,8,1>F -0.501961{ align1 +  } */
+   { 0x00600040, 0x21807fbd, 0x008d0180, 0xbf008081 },
+/*    mul (8) g14<1>F g14<8,8,1>F 1.164{ align1 +  } */
+   { 0x00600041, 0x21c07fbd, 0x008d01c0, 0x3f94fdf4 },
+/*    mul (8) a0<1>F g16<8,8,1>F 1.596{ align1 +  } */
+   { 0x00600041, 0x20007fbc, 0x008d0200, 0x3fcc49ba },
+/*    mac (8) m2<1>F g14<8,8,1>F 1{ align1 + Saturate  } */
+   { 0x80600048, 0x20407fbe, 0x008d01c0, 0x3f800000 },
+/*    mul (8) a0<1>F g16<8,8,1>F -0.813{ align1 +  } */
+   { 0x00600041, 0x20007fbc, 0x008d0200, 0xbf5020c5 },
+/*    mac (8) a0<1>F g12<8,8,1>F -0.392{ align1 +  } */
+   { 0x00600048, 0x20007fbc, 0x008d0180, 0xbec8b439 },
+/*    mac (8) m3<1>F g14<8,8,1>F 1{ align1 + Saturate  } */
+   { 0x80600048, 0x20607fbe, 0x008d01c0, 0x3f800000 },
+/*    mul (8) a0<1>F g12<8,8,1>F 2.017{ align1 +  } */
+   { 0x00600041, 0x20007fbc, 0x008d0180, 0x40011687 },
+/*    mac (8) m4<1>F g14<8,8,1>F 1{ align1 + Saturate  } */
+   { 0x80600048, 0x20807fbe, 0x008d01c0, 0x3f800000 },
+/*    add (8) g15<1>F g15<8,8,1>F -0.0627451{ align1 +  } */
+   { 0x00600040, 0x21e07fbd, 0x008d01e0, 0xbd808081 },
+/*    add (8) g17<1>F g17<8,8,1>F -0.501961{ align1 +  } */
+   { 0x00600040, 0x22207fbd, 0x008d0220, 0xbf008081 },
+/*    add (8) g13<1>F g13<8,8,1>F -0.501961{ align1 +  } */
+   { 0x00600040, 0x21a07fbd, 0x008d01a0, 0xbf008081 },
+/*    mul (8) g15<1>F g15<8,8,1>F 1.164{ align1 +  } */
+   { 0x00600041, 0x21e07fbd, 0x008d01e0, 0x3f94fdf4 },
+/*    mul (8) a0<1>F g17<8,8,1>F 1.596{ align1 +  } */
+   { 0x00600041, 0x20007fbc, 0x008d0220, 0x3fcc49ba },
+/*    mac (8) m6<1>F g15<8,8,1>F 1{ align1 + Saturate  } */
+   { 0x80600048, 0x20c07fbe, 0x008d01e0, 0x3f800000 },
+/*    mul (8) a0<1>F g17<8,8,1>F -0.813{ align1 +  } */
+   { 0x00600041, 0x20007fbc, 0x008d0220, 0xbf5020c5 },
+/*    mac (8) a0<1>F g13<8,8,1>F -0.392{ align1 +  } */
+   { 0x00600048, 0x20007fbc, 0x008d01a0, 0xbec8b439 },
+/*    mac (8) m7<1>F g15<8,8,1>F 1{ align1 + Saturate  } */
+   { 0x80600048, 0x20e07fbe, 0x008d01e0, 0x3f800000 },
+/*    mul (8) a0<1>F g13<8,8,1>F 2.017{ align1 +  } */
+   { 0x00600041, 0x20007fbc, 0x008d01a0, 0x40011687 },
+/*    mac (8) m8<1>F g15<8,8,1>F 1{ align1 + Saturate  } */
+   { 0x80600048, 0x21007fbe, 0x008d01e0, 0x3f800000 },
 /*    mov (8) m1<1>UD g1<8,8,1>UD { align1 mask_disable +  } */
    { 0x00600201, 0x20200022, 0x008d0020, 0x00000000 },
 /*    send   0 (16) a0<1>UW g0<8,8,1>UW write mlen 10 rlen 0 EOT{ align1 +  } */
@@ -51,3 +163,4 @@
    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
 /*    nop (4) g0<1>UD { align1 +  } */
    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+
diff-tree ba896c779c697e1d7458028798ec49013bd9da9f (from 21b62df7c34217be5dd95985c35e33be11c25846)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Wed Aug 2 17:47:37 2006 -0700

    Updated grf/urb state for WM.

diff --git a/src/i830_video.c b/src/i830_video.c
index a3f8b62..8d95a34 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -3147,8 +3147,8 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    wm_state->thread1.binding_table_entry_count = 2;
    wm_state->thread2.scratch_space_base_pointer = 0; /* XXX */
    wm_state->thread2.per_thread_scratch_space = 0; /* XXX */
-   wm_state->thread3.dispatch_grf_start_reg = 10; /* XXX */
-   wm_state->thread3.urb_entry_read_length = 3; /* XXX */
+   wm_state->thread3.dispatch_grf_start_reg = 3; /* XXX */
+   wm_state->thread3.urb_entry_read_length = 1; /* XXX */
    wm_state->thread3.const_urb_entry_read_length = 0; /* XXX */
    wm_state->thread3.const_urb_entry_read_offset = 0; /* XXX */
    wm_state->thread3.urb_entry_read_offset = 0; /* XXX */
diff-tree 21b62df7c34217be5dd95985c35e33be11c25846 (from 5d3424492f9586a4c5a28962a9757f48f2c12e83)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Wed Aug 2 17:36:49 2006 -0700

    Move the WM kernel to a separate file.

diff --git a/src/i830_video.c b/src/i830_video.c
index 01a028d..a3f8b62 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2728,58 +2728,7 @@ static const CARD32 sf_kernel_static[][4
 #define PS_MAX_THREADS	   1 /* MIN(12, PS_KERNEL_NUM_URB / 2) */
 
 static const CARD32 ps_kernel_static[][4] = {
-/*    mov (8) g2<1>F g1.8<0,1,0>UW { align1 +  } */
-   { 0x00600001, 0x2040013d, 0x00000028, 0x00000000 },
-/*    add (8) g2<1>F g2<8,8,1>F g1<0,1,0>F { align1 +  } */
-   { 0x00600040, 0x204077bd, 0x008d0040, 0x00004020 },
-/*    mul (8) g2<1>F g2<8,8,1>F g10<0,1,0>F { align1 +  } */
-   { 0x00600041, 0x204077bd, 0x008d0040, 0x00000140 },
-/*    add (8) g2<1>F g2<8,8,1>F g12<0,1,0>F { align1 +  } */
-   { 0x00600040, 0x204077bd, 0x008d0040, 0x00000180 },
-/*    mov (8) g3<1>F g1.10<0,1,0>UW { align1 +  } */
-   { 0x00600001, 0x2060013d, 0x0000002a, 0x00000000 },
-/*    add (8) g3<1>F g3<8,8,1>F g1.4<0,1,0>F { align1 +  } */
-   { 0x00600040, 0x206077bd, 0x008d0060, 0x00004024 },
-/*    mul (8) g3<1>F g3<8,8,1>F g11<0,1,0>F { align1 +  } */
-   { 0x00600041, 0x206077bd, 0x008d0060, 0x00000160 },
-/*    add (8) g3<1>F g3<8,8,1>F g12.4<0,1,0>F { align1 +  } */
-   { 0x00600040, 0x206077bd, 0x008d0060, 0x00000184 },
-/*    mov (8) m2<1>F g2<8,8,1>F { align1 +  } */
-   { 0x00600001, 0x204003be, 0x008d0040, 0x00000000 },
-/*    mov (8) m3<1>F g3<8,8,1>F { align1 +  } */
-   { 0x00600001, 0x206003be, 0x008d0060, 0x00000000 },
-/*    mov (8) m4<1>F 0{ align1 +  } */
-   { 0x00600001, 0x208073fe, 0x00000000, 0x00000000 },
-/*    mov (8) m5<1>F 1{ align1 +  } */
-   { 0x00600001, 0x20a073fe, 0x00000000, 0x3f800000 },
-/*    mov (8) m6<1>F g2<8,8,1>F { align1 +  } */
-   { 0x00600001, 0x20c003be, 0x008d0040, 0x00000000 },
-/*    mov (8) m7<1>F g3<8,8,1>F { align1 +  } */
-   { 0x00600001, 0x20e003be, 0x008d0060, 0x00000000 },
-/*    mov (8) m8<1>F 0{ align1 +  } */
-   { 0x00600001, 0x210073fe, 0x00000000, 0x00000000 },
-/*    mov (8) m9<1>F 1{ align1 +  } */
-   { 0x00600001, 0x212073fe, 0x00000000, 0x3f800000 },
-/*    mov (8) m1<1>UD g1<8,8,1>UD { align1 mask_disable +  } */
-   { 0x00600201, 0x20200022, 0x008d0020, 0x00000000 },
-/*    send   0 (16) a0<1>UW g0<8,8,1>UW write mlen 10 rlen 0 EOT{ align1 +  } */
-   { 0x00800031, 0x20001d28, 0x008d0000, 0x85a04800 },
-/*    nop (4) g0<1>UD { align1 +  } */
-   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-/*    nop (4) g0<1>UD { align1 +  } */
-   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-/*    nop (4) g0<1>UD { align1 +  } */
-   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-/*    nop (4) g0<1>UD { align1 +  } */
-   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-/*    nop (4) g0<1>UD { align1 +  } */
-   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-/*    nop (4) g0<1>UD { align1 +  } */
-   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-/*    nop (4) g0<1>UD { align1 +  } */
-   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-/*    nop (4) g0<1>UD { align1 +  } */
-   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+#include "wm_prog.h"
 };
 
 #define ALIGN(i,m)    (((i) + (m) - 1) & ~((m) - 1))
diff --git a/src/wm_prog.h b/src/wm_prog.h
new file mode 100644
index 0000000..9fe775c
--- /dev/null
+++ b/src/wm_prog.h
@@ -0,0 +1,53 @@
+/* wm_program */
+/*    mov (8) g2<1>F g1.8<0,1,0>UW { align1 +  } */
+   { 0x00600001, 0x2040013d, 0x00000028, 0x00000000 },
+/*    add (8) g2<1>F g2<8,8,1>F g1<0,1,0>F { align1 +  } */
+   { 0x00600040, 0x204077bd, 0x008d0040, 0x00004020 },
+/*    mul (8) g2<1>F g2<8,8,1>F g10<0,1,0>F { align1 +  } */
+   { 0x00600041, 0x204077bd, 0x008d0040, 0x00000140 },
+/*    add (8) g2<1>F g2<8,8,1>F g12<0,1,0>F { align1 +  } */
+   { 0x00600040, 0x204077bd, 0x008d0040, 0x00000180 },
+/*    mov (8) g3<1>F g1.10<0,1,0>UW { align1 +  } */
+   { 0x00600001, 0x2060013d, 0x0000002a, 0x00000000 },
+/*    add (8) g3<1>F g3<8,8,1>F g1.4<0,1,0>F { align1 +  } */
+   { 0x00600040, 0x206077bd, 0x008d0060, 0x00004024 },
+/*    mul (8) g3<1>F g3<8,8,1>F g11<0,1,0>F { align1 +  } */
+   { 0x00600041, 0x206077bd, 0x008d0060, 0x00000160 },
+/*    add (8) g3<1>F g3<8,8,1>F g12.4<0,1,0>F { align1 +  } */
+   { 0x00600040, 0x206077bd, 0x008d0060, 0x00000184 },
+/*    mov (8) m2<1>F g2<8,8,1>F { align1 +  } */
+   { 0x00600001, 0x204003be, 0x008d0040, 0x00000000 },
+/*    mov (8) m3<1>F g3<8,8,1>F { align1 +  } */
+   { 0x00600001, 0x206003be, 0x008d0060, 0x00000000 },
+/*    mov (8) m4<1>F 0{ align1 +  } */
+   { 0x00600001, 0x208073fe, 0x00000000, 0x00000000 },
+/*    mov (8) m5<1>F 1{ align1 +  } */
+   { 0x00600001, 0x20a073fe, 0x00000000, 0x3f800000 },
+/*    mov (8) m6<1>F g2<8,8,1>F { align1 +  } */
+   { 0x00600001, 0x20c003be, 0x008d0040, 0x00000000 },
+/*    mov (8) m7<1>F g3<8,8,1>F { align1 +  } */
+   { 0x00600001, 0x20e003be, 0x008d0060, 0x00000000 },
+/*    mov (8) m8<1>F 0{ align1 +  } */
+   { 0x00600001, 0x210073fe, 0x00000000, 0x00000000 },
+/*    mov (8) m9<1>F 1{ align1 +  } */
+   { 0x00600001, 0x212073fe, 0x00000000, 0x3f800000 },
+/*    mov (8) m1<1>UD g1<8,8,1>UD { align1 mask_disable +  } */
+   { 0x00600201, 0x20200022, 0x008d0020, 0x00000000 },
+/*    send   0 (16) a0<1>UW g0<8,8,1>UW write mlen 10 rlen 0 EOT{ align1 +  } */
+   { 0x00800031, 0x20001d28, 0x008d0000, 0x85a04800 },
+/*    nop (4) g0<1>UD { align1 +  } */
+   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
diff-tree 5d3424492f9586a4c5a28962a9757f48f2c12e83 (from 3f158fd610a3363a23daa7205bcd9f213686cf1c)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Wed Aug 2 17:34:12 2006 -0700

    Replace SF kernel with the one from broadwater-video HEAD.

diff --git a/src/i830_video.c b/src/i830_video.c
index 33e716f..01a028d 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2673,50 +2673,24 @@ static const CARD32 vs_kernel_static[][4
 #define SF_MAX_THREADS	   1
 
 static const CARD32 sf_kernel_static[][4] = {
-#if 1
-/*    send   0 (4) g6<1>F g1.12<4,4,1>F math mlen 1 rlen 1 { align1 +  } */
-   { 0x00400031, 0x20c01fbd, 0x0069002c, 0x01110081 },
+/*    send   0 (1) g6<1>F g1.12<0,1,0>F math mlen 1 rlen 1 { align1 +  } */
+   { 0x00000031, 0x20c01fbd, 0x0000002c, 0x01110081 },
+/*    send   0 (1) g6.4<1>F g1.20<0,1,0>F math mlen 1 rlen 1 { align1 +  } */
+   { 0x00000031, 0x20c41fbd, 0x00000034, 0x01110081 },
 /*    add (8) g7<1>F g4<8,8,1>F g3<8,8,1>F { align1 +  } */
    { 0x00600040, 0x20e077bd, 0x008d0080, 0x008d4060 },
 /*    mul (1) g7<1>F g7<0,1,0>F g6<0,1,0>F { align1 +  } */
    { 0x00000041, 0x20e077bd, 0x000000e0, 0x000000c0 },
-/*    mov (1) g7.4<1>F g6.12<0,1,0>F { align1 +  } */
-   { 0x00000001, 0x20e403bd, 0x000000cc, 0x00000000 },
+/*    mul (1) g7.4<1>F g7.4<0,1,0>F g6.4<0,1,0>F { align1 +  } */
+   { 0x00000041, 0x20e477bd, 0x000000e4, 0x000000c4 },
 /*    mov (8) m1<1>F g7<0,1,0>F { align1 +  } */
    { 0x00600001, 0x202003be, 0x000000e0, 0x00000000 },
 /*    mov (8) m2<1>F g7.4<0,1,0>F { align1 +  } */
    { 0x00600001, 0x204003be, 0x000000e4, 0x00000000 },
 /*    mov (8) m3<1>F g3<8,8,1>F { align1 +  } */
    { 0x00600001, 0x206003be, 0x008d0060, 0x00000000 },
-/*    send   0 (8) a0<1>F g0<8,8,1>F urb mlen 4 rlen 0 write +0 noswizzle used complete EOT{ align1 +  } */
-   { 0x00600031, 0x20001fbc, 0x008d0000, 0x8640c000 },
-/*    nop (4) g0<1>UD { align1 +  } */
-   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-/*    nop (4) g0<1>UD { align1 +  } */
-   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-/*    nop (4) g0<1>UD { align1 +  } */
-   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-/*    nop (4) g0<1>UD { align1 +  } */
-   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-/*    nop (4) g0<1>UD { align1 +  } */
-   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-/*    nop (4) g0<1>UD { align1 +  } */
-   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-/*    nop (4) g0<1>UD { align1 +  } */
-   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-/*    nop (4) g0<1>UD { align1 +  } */
-   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-
-#endif
-#if 0
-/*    mov (8) m1<1>F 0.00138889{ align1 +  } */
-   { 0x00600001, 0x202073fe, 0x00000000, 0x3ab60b61 },
-/*    mov (8) m2<1>F 0.00208333{ align1 +  } */
-   { 0x00600001, 0x204073fe, 0x00000000, 0x3b088889 },
-/*    mov (8) m3<1>F g3<8,8,1>F { align1 +  } */
-   { 0x00600001, 0x206003be, 0x008d0060, 0x00000000 },
-/*    send   0 (8) a0<1>F g0<8,8,1>F urb mlen 4 rlen 0 write +0 noswizzle used complete EOT{ align1 +  } */
-   { 0x00600031, 0x20001fbc, 0x008d0000, 0x8640c000 },
+/*    send   0 (8) a0<1>F g0<8,8,1>F urb mlen 4 rlen 0 write +0 transpose used complete EOT{ align1 +  } */
+   { 0x00600031, 0x20001fbc, 0x008d0000, 0x8640c800 },
 /*    nop (4) g0<1>UD { align1 +  } */
    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
 /*    nop (4) g0<1>UD { align1 +  } */
@@ -2733,62 +2707,6 @@ static const CARD32 sf_kernel_static[][4
    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
 /*    nop (4) g0<1>UD { align1 +  } */
    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-#endif
-
-#if 0
-/*    send   0 (1) g6<1>F g1.8<0,1,0>F math mlen 1 rlen 1 { align1 +  } */
-    { 0x00000031, 0x20c01fbd, 0x00000028, 0x01110081 },
-/*    mov (2) g3.8<1>F g2<2,2,1>F { align1 +  } */
-    { 0x00200001, 0x206803bd, 0x00450040, 0x00000000 },
-/*    mov (2) g4.8<1>F g2.8<2,2,1>F { align1 +  } */
-    { 0x00200001, 0x208803bd, 0x00450048, 0x00000000 },
-/*    mov (2) g5.8<1>F g2.16<2,2,1>F { align1 +  } */
-    { 0x00200001, 0x20a803bd, 0x00450050, 0x00000000 },
-/*    mov (1) a48<1>UW 240 { align1 +  } */
-    { 0x00000001, 0x26002168, 0x00000000, 0x000000f0 },
-/*    mul (8) g3<1>F g3<8,8,1>F g2.4<0,1,0>F { align1 predreg+  } */
-    { 0x00610041, 0x206077bd, 0x008d0060, 0x00000044 },
-/*    mul (8) g4<1>F g4<8,8,1>F g2.12<0,1,0>F { align1 predreg+  } */
-    { 0x00610041, 0x208077bd, 0x008d0080, 0x0000004c },
-/*    mul (8) g5<1>F g5<8,8,1>F g2.20<0,1,0>F { align1 predreg+  } */
-    { 0x00610041, 0x20a077bd, 0x008d00a0, 0x00000054 },
-/*    add (8) g7<1>F g4<8,8,1>F g3<8,8,1>F { align1 +  } */
-    { 0x00600040, 0x20e077bd, 0x008d0080, 0x008d4060 },
-/*    add (8) g8<1>F g5<8,8,1>F g3<8,8,1>F { align1 +  } */
-    { 0x00600040, 0x210077bd, 0x008d00a0, 0x008d4060 },
-/*    mul (8) a0<1>F g7<8,8,1>F g1.24<0,1,0>F { align1 +  } */
-    { 0x00600041, 0x200077bc, 0x008d00e0, 0x00000038 },
-/*    mac (8) g9<1>F g8<8,8,1>F g1.20<0,1,0>F { align1 +  } */
-    { 0x00600048, 0x212077bd, 0x008d0100, 0x00004034 },
-/*    mul (8) m1<1>F g9<8,8,1>F g6<0,1,0>F { align1 +  } */
-    { 0x00600041, 0x202077be, 0x008d0120, 0x000000c0 },
-/*    mul (8) a0<1>F g8<8,8,1>F g1.12<0,1,0>F { align1 +  } */
-    { 0x00600041, 0x200077bc, 0x008d0100, 0x0000002c },
-/*    mac (8) g9<1>F g7<8,8,1>F g1.16<0,1,0>F { align1 +  } */
-    { 0x00600048, 0x212077bd, 0x008d00e0, 0x00004030 },
-/*    mul (8) m2<1>F g9<8,8,1>F g6<0,1,0>F { align1 +  } */
-    { 0x00600041, 0x204077be, 0x008d0120, 0x000000c0 },
-/*    mov (8) m3<1>F g3<8,8,1>F { align1 +  } */
-    { 0x00600001, 0x206003be, 0x008d0060, 0x00000000 },
-/*    send   0 (8) a0<1>F g0<8,8,1>F urb mlen 4 rlen 0 write +0 transpose used complete EOT{ align1 +  } */
-    { 0x00600031, 0x20001fbc, 0x008d0000, 0x8640c800 },
-/*    nop (4) g0<1>UD { align1 +  } */
-    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-/*    nop (4) g0<1>UD { align1 +  } */
-    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-/*    nop (4) g0<1>UD { align1 +  } */
-    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-/*    nop (4) g0<1>UD { align1 +  } */
-    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-/*    nop (4) g0<1>UD { align1 +  } */
-    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-/*    nop (4) g0<1>UD { align1 +  } */
-    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-/*    nop (4) g0<1>UD { align1 +  } */
-    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-/*    nop (4) g0<1>UD { align1 +  } */
-    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-#endif
 };
 
 /*
diff-tree e71108f1e05b7a8d8edd174eb64edd6cccacbcdc (from a91a4f95c664f6905fef61dab251707bf2548bb8)
Author: Alan Hourihane <alanh at fairlite.demon.co.uk>
Date:   Fri Jul 28 10:32:12 2006 +0100

    Fix DGA with MergedFB
    Turn off rotation support when MergedFB enabled

diff --git a/src/i830_dga.c b/src/i830_dga.c
index 1129fa3..122e881 100644
--- a/src/i830_dga.c
+++ b/src/i830_dga.c
@@ -99,6 +99,31 @@ I830DGAInit(ScreenPtr pScreen)
 
    while (pMode) {
 
+	if(pI830->MergedFB) {
+	   Bool nogood = FALSE;
+	   /* Filter out all meta modes that would require driver-side panning */
+	   switch(((I830ModePrivatePtr)pMode->Private)->merged.SecondPosition) {
+	   case PosRightOf:
+	   case PosLeftOf:
+	      if( (((I830ModePrivatePtr)pMode->Private)->merged.First->VDisplay !=
+		   ((I830ModePrivatePtr)pMode->Private)->merged.Second->VDisplay)	||
+		  (((I830ModePrivatePtr)pMode->Private)->merged.First->VDisplay != pMode->VDisplay) )
+		 nogood = TRUE;
+	      break;
+	   default:
+	      if( (((I830ModePrivatePtr)pMode->Private)->merged.First->HDisplay !=
+		   ((I830ModePrivatePtr)pMode->Private)->merged.Second->HDisplay)	||
+		  (((I830ModePrivatePtr)pMode->Private)->merged.First->HDisplay != pMode->HDisplay) )
+		 nogood = TRUE;
+	   }
+	   if(nogood) {
+	      xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+			"DGA: MetaMode %dx%d not suitable for DGA, skipping\n",
+			pMode->HDisplay, pMode->VDisplay);
+	      goto mode_nogood;
+	   }
+	}
+
       newmodes = xrealloc(modes, (num + 1) * sizeof(DGAModeRec));
 
       if (!newmodes) {
@@ -155,6 +180,7 @@ I830DGAInit(ScreenPtr pScreen)
       currentMode->maxViewportY = currentMode->imageHeight -
 	    currentMode->viewportHeight;
 
+mode_nogood:
       pMode = pMode->next;
       if (pMode == firstMode)
 	 break;
diff --git a/src/i830_driver.c b/src/i830_driver.c
index d32efa3..256ae22 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -7088,22 +7088,6 @@ I830BIOSScreenInit(int scrnIndex, Screen
    pI830->CloseScreen = pScreen->CloseScreen;
    pScreen->CloseScreen = I830BIOSCloseScreen;
 
-   if (!pI830->MergedFB && pI830->shadowReq.minorversion >= 1) {
-      /* Rotation */
-      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "RandR enabled, ignore the following RandR disabled message.\n");
-      xf86DisableRandR(); /* Disable built-in RandR extension */
-      shadowSetup(pScreen);
-      /* support all rotations */
-      I830RandRInit(pScreen, RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_180 | RR_Rotate_270);
-      pI830->PointerMoved = pScrn->PointerMoved;
-      pScrn->PointerMoved = I830PointerMoved;
-      pI830->CreateScreenResources = pScreen->CreateScreenResources;
-      pScreen->CreateScreenResources = I830CreateScreenResources;
-   } else {
-      /* Rotation */
-      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "libshadow is version %d.%d.%d, required 1.1.0 or greater for rotation.\n",pI830->shadowReq.majorversion,pI830->shadowReq.minorversion,pI830->shadowReq.patchlevel);
-   }
-
    if (pI830->MergedFB) {
       pI830->PointerMoved = pScrn->PointerMoved;
       pScrn->PointerMoved = I830MergedPointerMoved;
@@ -7120,6 +7104,20 @@ I830BIOSScreenInit(int scrnIndex, Screen
       } else {
 	  pI830->MouseRestrictions = FALSE;
       }
+   } else if (pI830->shadowReq.minorversion >= 1) {
+      /* Rotation */
+      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "RandR enabled, ignore the following RandR disabled message.\n");
+      xf86DisableRandR(); /* Disable built-in RandR extension */
+      shadowSetup(pScreen);
+      /* support all rotations */
+      I830RandRInit(pScreen, RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_180 | RR_Rotate_270);
+      pI830->PointerMoved = pScrn->PointerMoved;
+      pScrn->PointerMoved = I830PointerMoved;
+      pI830->CreateScreenResources = pScreen->CreateScreenResources;
+      pScreen->CreateScreenResources = I830CreateScreenResources;
+   } else {
+      /* Rotation */
+      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "libshadow is version %d.%d.%d, required 1.1.0 or greater for rotation.\n",pI830->shadowReq.majorversion,pI830->shadowReq.minorversion,pI830->shadowReq.patchlevel);
    }
 
    if (serverGeneration == 1)
diff-tree a91a4f95c664f6905fef61dab251707bf2548bb8 (from ac3ad32f667b306e771617d784648f7111743f1a)
Author: Alan Hourihane <alanh at fairlite.demon.co.uk>
Date:   Thu Jul 27 16:11:48 2006 +0100

    Fix pipe reversal for Xv

diff --git a/src/i830_video.c b/src/i830_video.c
index 762bddf..b252ac9 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -1495,21 +1495,21 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int 
          case PosBelow:
             if ((w2 > 0 && w1 == 0) ||
                 (h2 > 0 && h1 == 0)) {
-               pPriv->pipe = pI830->pipe;
+               pPriv->pipe = !pI830->pipe;
                dstBox->x1 = dstBox2.x1;
                dstBox->y1 = dstBox2.y1;
                dstBox->x2 = dstBox2.x2;
                dstBox->y2 = dstBox2.y2;
             } else 
-               pPriv->pipe = !pI830->pipe;
+               pPriv->pipe = pI830->pipe;
             break;
          case PosLeftOf:
          case PosAbove:
             if ((w1 > 0 && w2 == 0) ||
                 (h1 > 0 && h2 == 0)) { 
-               pPriv->pipe = !pI830->pipe;
-            } else {
                pPriv->pipe = pI830->pipe;
+            } else {
+               pPriv->pipe = !pI830->pipe;
                dstBox->x1 = dstBox2.x1;
                dstBox->y1 = dstBox2.y1;
                dstBox->x2 = dstBox2.x2;
diff-tree ac3ad32f667b306e771617d784648f7111743f1a (from e786e2f9f3a4df31702736db6f68a44c9ebba546)
Author: Alan Hourihane <alanh at fairlite.demon.co.uk>
Date:   Thu Jul 27 15:28:42 2006 +0100

    Calculate allowable refresh rates on the private
    mode data for each independent screen in mergedfb.
    
    Lots of other fixes too.

diff --git a/src/i830_cursor.c b/src/i830_cursor.c
index 3786120..1d7808b 100644
--- a/src/i830_cursor.c
+++ b/src/i830_cursor.c
@@ -432,8 +432,8 @@ I830SetCursorPositionMerged(ScrnInfoPtr 
    temp2 |= ((x2 & CURSOR_POS_MASK) << CURSOR_X_SHIFT);
    temp2 |= ((y2 & CURSOR_POS_MASK) << CURSOR_Y_SHIFT);
 
-   OUTREG(CURSOR_A_POSITION, temp2);
-   OUTREG(CURSOR_B_POSITION, temp);
+   OUTREG(CURSOR_A_POSITION, temp);
+   OUTREG(CURSOR_B_POSITION, temp2);
 
    if (pI830->cursorOn) {
       if (hide)
diff --git a/src/i830_driver.c b/src/i830_driver.c
index eb85131..d32efa3 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -742,9 +742,6 @@ I830GenerateModeListFromLargestModes(Scr
      * common mode for First and Second (if available). Additionally, and
      * regardless if the above, we produce a clone mode consisting of
      * the largest common mode (if available) in order to use DGA.
-     * - Clone: If the (global) SecondPosition is Clone, we use the
-     * largest common mode if available, otherwise the first two modes
-     * in each list.
      */
 
     switch(pos) {
@@ -1222,7 +1219,7 @@ I830MergedPointerMoved(int scrnIndex, in
      pScrn2->frameY1   = pScrn2->frameY0   + CDMPTR.Second->VDisplay - 1;
 
      /* No need to update pScrn1->frame?1, done above */
-    if (!pI830->pipe == 0) {
+    if (pI830->pipe == 0) {
        OUTREG(DSPABASE, pI830->FrontBuffer.Start + ((pI830->FirstframeY0 * pScrn1->displayWidth + pI830->FirstframeX0) * pI830->cpp));
        OUTREG(DSPBBASE, pI830->FrontBuffer.Start + ((pScrn2->frameY0 * pScrn1->displayWidth + pScrn2->frameX0) * pI830->cpp));
     } else {
@@ -5150,8 +5147,7 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int f
    }
 
    if (pI830->MergedFB) {
-      DisplayModePtr old_modes;
-      DisplayModePtr cur_mode;
+      DisplayModePtr old_modes, cur_mode;
 
       xf86PruneDriverModes(pI830->pScrn_2);
 
@@ -5915,12 +5911,18 @@ I830VESASetVBEMode(ScrnInfoPtr pScrn, in
    else
       Mon = pI830->MonType2;
 
+
    /* Now recheck refresh operations we can use */
    pI830->useExtendedRefresh = FALSE;
    pI830->vesa->useDefaultRefresh = FALSE;
 
-   if (Mon != PIPE_CRT)
+   if (Mon != PIPE_CRT) {
+      xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+		    "A non-CRT device is attached to pipe %c.\n"
+		    "\tNo refresh rate overrides will be attempted.\n",
+		    PIPE_NAME(pI830->pipe));
       pI830->vesa->useDefaultRefresh = TRUE;
+   }
 
    mode |= 1 << 11;
    if (pI830->vesa->useDefaultRefresh)
@@ -6011,13 +6013,24 @@ I830VESASetMode(ScrnInfoPtr pScrn, Displ
    }else {
       I830ModePrivatePtr s = (I830ModePrivatePtr)mp->merged.Second->Private;
       I830ModePrivatePtr f = (I830ModePrivatePtr)mp->merged.First->Private;
+      int pipe = pI830->pipe; /* save current pipe */
+
       SetBIOSPipe(pScrn, !pI830->pipe);
-      if (I830VESASetVBEMode(pScrn, (f->vbeData.mode | 1<<15 | 1<<14), f->vbeData.block) == FALSE) {
+
+      pI830->pipe = !pI830->pipe;
+      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting mode on Pipe %s.\n", pI830->pipe ? "B" : "A");
+
+      if (I830VESASetVBEMode(pScrn, (s->vbeData.mode | 1<<15 | 1<<14), s->vbeData.block) == FALSE) {
          xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Set VBE Mode failed!\n");
          return FALSE;
       }
+
+      pI830->pipe = pipe; /* restore current pipe */
+      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting mode on Pipe %s.\n", pI830->pipe ? "B" : "A");
+
       SetPipeAccess(pScrn);
-      if (I830VESASetVBEMode(pScrn, (s->vbeData.mode | 1<<15 | 1<<14), s->vbeData.block) == FALSE) {
+
+      if (I830VESASetVBEMode(pScrn, (f->vbeData.mode | 1<<15 | 1<<14), f->vbeData.block) == FALSE) {
          xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Set VBE Mode failed!\n");
          return FALSE;
       }
@@ -7170,7 +7183,7 @@ I830BIOSAdjustFrame(int scrnIndex, int x
    if (pI830->MergedFB) {
       I830AdjustFrameMerged(scrnIndex, x, y, flags);
 
-      if (!pI830->pipe == 0) {
+      if (pI830->pipe == 0) {
          OUTREG(DSPABASE, pI830->FrontBuffer.Start + ((pI830->FirstframeY0 * pScrn->displayWidth + pI830->FirstframeX0) * pI830->cpp));
          OUTREG(DSPBBASE, pI830->FrontBuffer.Start + ((pI830->pScrn_2->frameY0 * pScrn->displayWidth + pI830->pScrn_2->frameX0) * pI830->cpp));
       } else {
@@ -7344,21 +7357,29 @@ I830DetectMonitorChange(ScrnInfoPtr pScr
 
    /* Re-read EDID */
    pDDCModule = xf86LoadSubModule(pScrn, "ddc");
+
+   if (pI830->MergedFB) {
+      SetBIOSPipe(pScrn, !pI830->pipe);
+      monitor = vbeDoEDID(pI830->pVbe, pDDCModule);
+      if ((pI830->pScrn_2->monitor->DDC = monitor) != NULL) {
+         xf86PrintEDID(monitor);
+         xf86SetDDCproperties(pScrn, monitor);
+      } 
+      SetPipeAccess(pScrn);
+   }
+
    monitor = vbeDoEDID(pI830->pVbe, pDDCModule);
    xf86UnloadSubModule(pDDCModule);
    if ((pScrn->monitor->DDC = monitor) != NULL) {
       xf86PrintEDID(monitor);
       xf86SetDDCproperties(pScrn, monitor);
-   } else 
-      /* No DDC, so get out of here, and continue to use the current settings */
-      return FALSE; 
+   } 
 
-   if (!(DDCclock = I830UseDDC(pScrn)))
-      return FALSE;
+   DDCclock = I830UseDDC(pScrn);
 
+   /* Check if DDC exists on the second head, if not don't abort. */
    if (pI830->MergedFB)
-      if (!(DDCclock2 = I830UseDDC(pScrn)))
-         return FALSE;
+      DDCclock2 = I830UseDDC(pI830->pScrn_2);
 
    /* Revalidate the modes */
 
@@ -7378,7 +7399,7 @@ I830DetectMonitorChange(ScrnInfoPtr pScr
       return FALSE;
    }
 
-   if (pI830->MergedFB) {
+   if (pI830->MergedFB && DDCclock2 > 0) {
       SetBIOSPipe(pScrn, !pI830->pipe);
       xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 		 "Retrieving mode pool for second head.\n");
@@ -7394,7 +7415,7 @@ I830DetectMonitorChange(ScrnInfoPtr pScr
    }
 
    VBESetModeNames(pScrn->modePool);
-   if (pI830->MergedFB)
+   if (pI830->MergedFB && DDCclock2 > 0)
       VBESetModeNames(pI830->pScrn_2->modePool);
 
    if (pScrn->videoRam > (pI830->vbeInfo->TotalMemory * 64))
@@ -7409,7 +7430,7 @@ I830DetectMonitorChange(ScrnInfoPtr pScr
 			pScrn->display->virtualY,
 			memsize, LOOKUP_BEST_REFRESH);
 
-   if (pI830->MergedFB) {
+   if (pI830->MergedFB && DDCclock2 > 0) {
       VBEValidateModes(pI830->pScrn_2, pI830->pScrn_2->monitor->Modes, 
 		        pI830->pScrn_2->display->modes, NULL,
 			NULL, 0, MAX_DISPLAY_PITCH, 1,
@@ -7450,7 +7471,7 @@ I830DetectMonitorChange(ScrnInfoPtr pScr
    }
 
    /* Only use this if we've got DDC available */
-   if (DDCclock2 > 0) {
+   if (pI830->MergedFB && DDCclock2 > 0) {
       p = pI830->pScrn_2->modes;
       if (p == NULL)
          return FALSE;
@@ -7484,10 +7505,7 @@ I830DetectMonitorChange(ScrnInfoPtr pScr
 
    xf86PruneDriverModes(pScrn);
 
-   if (pI830->MergedFB) {
-      DisplayModePtr old_modes;
-      DisplayModePtr cur_mode;
-
+   if (pI830->MergedFB && DDCclock2 > 0) {
       xf86PruneDriverModes(pI830->pScrn_2);
 
       if (pI830->pScrn_2->modes == NULL) {
@@ -7495,6 +7513,10 @@ I830DetectMonitorChange(ScrnInfoPtr pScr
          PreInitCleanup(pScrn);
          return FALSE;
       }
+   }
+
+   if (pI830->MergedFB) {
+      DisplayModePtr old_modes, cur_mode;
 
       old_modes = pScrn->modes;
       cur_mode = pScrn->currentMode;
diff --git a/src/i830_modes.c b/src/i830_modes.c
index 7d71396..7d14519 100644
--- a/src/i830_modes.c
+++ b/src/i830_modes.c
@@ -674,23 +674,31 @@ I830GetModePool(ScrnInfoPtr pScrn, vbeIn
 void
 I830SetModeParameters(ScrnInfoPtr pScrn, vbeInfoPtr pVbe)
 {
-    DisplayModePtr pMode;
+    I830Ptr pI830 = I830PTR(pScrn);
+    DisplayModePtr pMode = pScrn->modes;
+    DisplayModePtr ppMode = pScrn->modes;
     I830ModePrivatePtr mp = NULL;
 
-    pMode = pScrn->modes;
     do {
 	int clock;
+        
+        mp = (I830ModePrivatePtr) pMode->Private;
 
+        if (pI830->MergedFB) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%s\n", pScrn->monitor->id);
+            ppMode = (DisplayModePtr) mp->merged.First;
+            mp = (I830ModePrivatePtr) mp->merged.First->Private;
+        }
 	mp->vbeData.block = xcalloc(sizeof(VbeCRTCInfoBlock), 1);
-	mp->vbeData.block->HorizontalTotal = pMode->HTotal;
-	mp->vbeData.block->HorizontalSyncStart = pMode->HSyncStart;
-	mp->vbeData.block->HorizontalSyncEnd = pMode->HSyncEnd;
-	mp->vbeData.block->VerticalTotal = pMode->VTotal;
-	mp->vbeData.block->VerticalSyncStart = pMode->VSyncStart;
-	mp->vbeData.block->VerticalSyncEnd = pMode->VSyncEnd;
-	mp->vbeData.block->Flags = ((pMode->Flags & V_NHSYNC) ? CRTC_NHSYNC : 0) |
-				 ((pMode->Flags & V_NVSYNC) ? CRTC_NVSYNC : 0);
-	mp->vbeData.block->PixelClock = pMode->Clock * 1000;
+	mp->vbeData.block->HorizontalTotal = ppMode->HTotal;
+	mp->vbeData.block->HorizontalSyncStart = ppMode->HSyncStart;
+	mp->vbeData.block->HorizontalSyncEnd = ppMode->HSyncEnd;
+	mp->vbeData.block->VerticalTotal = ppMode->VTotal;
+	mp->vbeData.block->VerticalSyncStart = ppMode->VSyncStart;
+	mp->vbeData.block->VerticalSyncEnd = ppMode->VSyncEnd;
+	mp->vbeData.block->Flags = ((ppMode->Flags & V_NHSYNC) ? CRTC_NHSYNC : 0) |
+				 ((ppMode->Flags & V_NVSYNC) ? CRTC_NVSYNC : 0);
+	mp->vbeData.block->PixelClock = ppMode->Clock * 1000;
 	/* XXX May not have this. */
 	clock = VBEGetPixelClock(pVbe, mp->vbeData.mode, mp->vbeData.block->PixelClock);
 	if (clock)
@@ -701,26 +709,78 @@ I830SetModeParameters(ScrnInfoPtr pScrn,
 		(double)clock / 1000000.0);
 #endif
 	mp->vbeData.mode |= (1 << 11);
-	if (pMode->VRefresh != 0) {
-	    mp->vbeData.block->RefreshRate = pMode->VRefresh * 100;
+	if (ppMode->VRefresh != 0) {
+	    mp->vbeData.block->RefreshRate = ppMode->VRefresh * 100;
 	} else {
 	    mp->vbeData.block->RefreshRate = (int)(((double)(mp->vbeData.block->PixelClock)/
-                       (double)(pMode->HTotal * pMode->VTotal)) * 100);
+                       (double)(ppMode->HTotal * ppMode->VTotal)) * 100);
 	}
 	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 		       "Attempting to use %2.2fHz refresh for mode \"%s\" (%x)\n",
-		       (float)(((double)(mp->vbeData.block->PixelClock) / (double)(pMode->HTotal * pMode->VTotal))), pMode->name, mp->vbeData.mode);
+		       (float)(((double)(mp->vbeData.block->PixelClock) / (double)(ppMode->HTotal * ppMode->VTotal))), ppMode->name, mp->vbeData.mode);
 #ifdef DEBUG
 	ErrorF("Video Modeline: ID: 0x%x Name: %s %i %i %i %i - "
 	       "  %i %i %i %i %.2f MHz Refresh: %.2f Hz\n",
-	       mp->vbeData.mode, pMode->name, pMode->HDisplay, pMode->HSyncStart,
-	       pMode->HSyncEnd, pMode->HTotal, pMode->VDisplay,
-	       pMode->VSyncStart,pMode->VSyncEnd,pMode->VTotal,
+	       mp->vbeData.mode, ppMode->name, ppMode->HDisplay, ppMode->HSyncStart,
+	       ppMode->HSyncEnd, ppMode->HTotal, ppMode->VDisplay,
+	       ppMode->VSyncStart,ppMode->VSyncEnd,ppMode->VTotal,
 	       (double)mp->vbeData.block->PixelClock/1000000.0,
 	       (double)mp->vbeData.block->RefreshRate/100);
 #endif
-	pMode = pMode->next;
+	pMode = ppMode = pMode->next;
     } while (pMode != pScrn->modes);
+
+    if (pI830->MergedFB) {
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%s\n", pI830->pScrn_2->monitor->id);
+    pMode = pScrn->modes;
+    	do {
+	    int clock;
+
+            mp = (I830ModePrivatePtr) pMode->Private;
+            ppMode = (DisplayModePtr) mp->merged.Second;
+            mp = (I830ModePrivatePtr) mp->merged.Second->Private;
+
+	    mp->vbeData.block = xcalloc(sizeof(VbeCRTCInfoBlock), 1);
+	    mp->vbeData.block->HorizontalTotal = ppMode->HTotal;
+	    mp->vbeData.block->HorizontalSyncStart = ppMode->HSyncStart;
+	    mp->vbeData.block->HorizontalSyncEnd = ppMode->HSyncEnd;
+	    mp->vbeData.block->VerticalTotal = ppMode->VTotal;
+	    mp->vbeData.block->VerticalSyncStart = ppMode->VSyncStart;
+	    mp->vbeData.block->VerticalSyncEnd = ppMode->VSyncEnd;
+	    mp->vbeData.block->Flags = ((ppMode->Flags & V_NHSYNC) ? CRTC_NHSYNC : 0) |
+				 ((ppMode->Flags & V_NVSYNC) ? CRTC_NVSYNC : 0);
+	    mp->vbeData.block->PixelClock = ppMode->Clock * 1000;
+	    /* XXX May not have this. */
+	    clock = VBEGetPixelClock(pVbe, mp->vbeData.mode, mp->vbeData.block->PixelClock);
+	    if (clock)
+	        mp->vbeData.block->PixelClock = clock;
+#ifdef DEBUG
+	    ErrorF("Setting clock %.2fMHz, closest is %.2fMHz\n",
+		(double)mp->vbeData.block->PixelClock / 1000000.0, 
+		(double)clock / 1000000.0);
+#endif
+	    mp->vbeData.mode |= (1 << 11);
+	    if (ppMode->VRefresh != 0) {
+	        mp->vbeData.block->RefreshRate = ppMode->VRefresh * 100;
+	    } else {
+	        mp->vbeData.block->RefreshRate = (int)(((double)(mp->vbeData.block->PixelClock)/
+                       (double)(ppMode->HTotal * ppMode->VTotal)) * 100);
+	    }
+	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+		       "Attempting to use %2.2fHz refresh for mode \"%s\" (%x)\n",
+		       (float)(((double)(mp->vbeData.block->PixelClock) / (double)(ppMode->HTotal * ppMode->VTotal))), ppMode->name, mp->vbeData.mode);
+#ifdef DEBUG
+	    ErrorF("Video Modeline: ID: 0x%x Name: %s %i %i %i %i - "
+	       "  %i %i %i %i %.2f MHz Refresh: %.2f Hz\n",
+	       mp->vbeData.mode, ppMode->name, ppMode->HDisplay, ppMode->HSyncStart,
+	       ppMode->HSyncEnd, ppMode->HTotal, ppMode->VDisplay,
+	       ppMode->VSyncStart,ppMode->VSyncEnd,ppMode->VTotal,
+	       (double)mp->vbeData.block->PixelClock/1000000.0,
+	       (double)mp->vbeData.block->RefreshRate/100);
+#endif
+	    pMode = ppMode = pMode->next;
+        } while (pMode != pScrn->modes);
+    }
 }
 
 void
diff-tree e786e2f9f3a4df31702736db6f68a44c9ebba546 (from 8e6e990db34d63174670512f494fa9adb44786f5)
Author: Alan Hourihane <alanh at fairlite.demon.co.uk>
Date:   Wed Jul 26 16:45:38 2006 +0100

    When detecting new monitors in mergedfb renew the modepool.

diff --git a/src/i830.h b/src/i830.h
index 8a93f78..8b39aa9 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -246,7 +246,7 @@ typedef struct _I830Rec {
    I830MemRange *OverlayMem;
    I830MemRange LinearMem;
 #endif
-   unsigned int LinearAlloc;
+   int LinearAlloc;
 
    Bool MergedFB;
    ScrnInfoPtr pScrn_2;
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 4e370b8..eb85131 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -161,6 +161,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #endif
 
 #include <string.h>
+#include <stdio.h>
 #include <unistd.h>
 #include <stdlib.h>
 
@@ -1313,14 +1314,6 @@ I830AdjustFrameMerged(int scrnIndex, int
     pScrn1->frameY1   = pScrn1->frameY0   + pI830->currentMode->VDisplay  - 1;
     pScrn1->frameX1 += FirstXOffs + SecondXOffs;
     pScrn1->frameY1 += FirstYOffs + SecondYOffs;
-
-    if (!pI830->pipe == 0) {
-       OUTREG(DSPABASE, pI830->FrontBuffer.Start + ((pI830->FirstframeY0 * pScrn1->displayWidth + pI830->FirstframeX0) * pI830->cpp));
-       OUTREG(DSPBBASE, pI830->FrontBuffer.Start + ((pScrn2->frameY0 * pScrn1->displayWidth + pScrn2->frameX0) * pI830->cpp));
-    } else {
-       OUTREG(DSPBBASE, pI830->FrontBuffer.Start + ((pI830->FirstframeY0 * pScrn1->displayWidth + pI830->FirstframeX0) * pI830->cpp));
-       OUTREG(DSPABASE, pI830->FrontBuffer.Start + ((pScrn2->frameY0 * pScrn1->displayWidth + pScrn2->frameX0) * pI830->cpp));
-    }
 }
 
 /* Pseudo-Xinerama extension for MergedFB mode */
@@ -1377,7 +1370,6 @@ I830UpdateXineramaScreenInfo(ScrnInfoPtr
           DisplayModePtr p = currentMode->next;
           DisplayModePtr i = ((I830ModePrivatePtr)currentMode->Private)->merged.First;
           DisplayModePtr j = ((I830ModePrivatePtr)currentMode->Private)->merged.Second;
-          int pos = ((I830ModePrivatePtr)currentMode->Private)->merged.SecondPosition;
 
           if((currentMode->HDisplay <= realvirtX) && (currentMode->VDisplay <= realvirtY) &&
 	     (i->HDisplay <= realvirtX) && (j->HDisplay <= realvirtX) &&
@@ -4125,8 +4117,11 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int f
    pI830->LinearAlloc = 0;
    if (xf86GetOptValInteger(pI830->Options, OPTION_LINEARALLOC,
 			    &(pI830->LinearAlloc))) {
-      xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Allocating %dKbytes of memory\n",
+      if (pI830->LinearAlloc > 0)
+         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Allocating %dKbytes of memory\n",
 		 pI830->LinearAlloc);
+      else 
+         pI830->LinearAlloc = 0;
    }
 
    pI830->fixedPipe = -1;
@@ -5115,7 +5110,6 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int f
       } while (p != NULL && p != pScrn->modes);
    }
 
-
    /* Only use this if we've got DDC available */
    if (DDCclock2 > 0) {
       p = pI830->pScrn_2->modes;
@@ -5995,7 +5989,7 @@ I830VESASetMode(ScrnInfoPtr pScrn, Displ
    didLock = I830DRILock(pScrn);
 #endif
 
-   if (pI830->Clone || pI830->MergedFB) {
+   if (pI830->Clone) {
       pI830->CloneHDisplay = pMode->HDisplay;
       pI830->CloneVDisplay = pMode->VDisplay;
    }
@@ -6214,15 +6208,21 @@ I830VESASetMode(ScrnInfoPtr pScrn, Displ
 	    OUTREG(stridereg, pI830->displayWidth * pI830->cpp);
          }
 
-#if 0
 	 if (pI830->MergedFB) {
-            if (i == 0)
-               OUTREG(sizereg, (CDMPTR.First->HDisplay - 1) | ((CDMPTR.First->VDisplay - 1) << 16));
-	    else 
-               OUTREG(sizereg, (CDMPTR.Second->HDisplay - 1) | ((CDMPTR.Second->VDisplay - 1) << 16));
+	    switch (pI830->SecondPosition) {
+	       case PosRightOf:
+	       case PosBelow:
+                  OUTREG(DSPABASE, (CDMPTR.First->HDisplay - 1) | ((CDMPTR.First->VDisplay - 1) << 16));
+                  OUTREG(DSPBBASE, (CDMPTR.Second->HDisplay - 1) | ((CDMPTR.Second->VDisplay - 1) << 16));
+	          break;
+	       case PosLeftOf:
+	       case PosAbove:
+                  OUTREG(DSPABASE, (CDMPTR.Second->HDisplay - 1) | ((CDMPTR.Second->VDisplay - 1) << 16));
+                  OUTREG(DSPBBASE, (CDMPTR.First->HDisplay - 1) | ((CDMPTR.First->VDisplay - 1) << 16));
+	          break;
+	    }
          } else
             OUTREG(sizereg, (pMode->HDisplay - 1) | ((pMode->VDisplay - 1) << 16));
-#endif
 	 /* Trigger update */
 	 temp = INREG(basereg);
 	 OUTREG(basereg, temp);
@@ -7169,6 +7169,15 @@ I830BIOSAdjustFrame(int scrnIndex, int x
 
    if (pI830->MergedFB) {
       I830AdjustFrameMerged(scrnIndex, x, y, flags);
+
+      if (!pI830->pipe == 0) {
+         OUTREG(DSPABASE, pI830->FrontBuffer.Start + ((pI830->FirstframeY0 * pScrn->displayWidth + pI830->FirstframeX0) * pI830->cpp));
+         OUTREG(DSPBBASE, pI830->FrontBuffer.Start + ((pI830->pScrn_2->frameY0 * pScrn->displayWidth + pI830->pScrn_2->frameX0) * pI830->cpp));
+      } else {
+         OUTREG(DSPBBASE, pI830->FrontBuffer.Start + ((pI830->FirstframeY0 * pScrn->displayWidth + pI830->FirstframeX0) * pI830->cpp));
+         OUTREG(DSPABASE, pI830->FrontBuffer.Start + ((pI830->pScrn_2->frameY0 * pScrn->displayWidth + pI830->pScrn_2->frameX0) * pI830->cpp));
+      }
+
       return;
    }
 
@@ -7323,7 +7332,7 @@ I830DetectMonitorChange(ScrnInfoPtr pScr
    pointer pDDCModule = NULL;
    DisplayModePtr p, pMon;
    int memsize;
-   int DDCclock = 0;
+   int DDCclock = 0, DDCclock2 = 0;
    int displayWidth = pScrn->displayWidth;
    int curHDisplay = pScrn->currentMode->HDisplay;
    int curVDisplay = pScrn->currentMode->VDisplay;
@@ -7347,12 +7356,18 @@ I830DetectMonitorChange(ScrnInfoPtr pScr
    if (!(DDCclock = I830UseDDC(pScrn)))
       return FALSE;
 
+   if (pI830->MergedFB)
+      if (!(DDCclock2 = I830UseDDC(pScrn)))
+         return FALSE;
+
    /* Revalidate the modes */
 
    /*
     * Note: VBE modes (> 0x7f) won't work with Intel's extended BIOS
     * functions.  
     */
+   SetPipeAccess(pScrn);
+
    pScrn->modePool = I830GetModePool(pScrn, pI830->pVbe, pI830->vbeInfo);
 
    if (!pScrn->modePool) {
@@ -7363,8 +7378,24 @@ I830DetectMonitorChange(ScrnInfoPtr pScr
       return FALSE;
    }
 
-   SetPipeAccess(pScrn);
+   if (pI830->MergedFB) {
+      SetBIOSPipe(pScrn, !pI830->pipe);
+      xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+		 "Retrieving mode pool for second head.\n");
+      pI830->pScrn_2->modePool = I830GetModePool(pI830->pScrn_2, pI830->pVbe, pI830->vbeInfo);
+
+      if (!pI830->pScrn_2->modePool) {
+         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		 "No Video BIOS modes for chosen depth.\n");
+         PreInitCleanup(pScrn);
+         return FALSE;
+      }
+      SetPipeAccess(pScrn);
+   }
+
    VBESetModeNames(pScrn->modePool);
+   if (pI830->MergedFB)
+      VBESetModeNames(pI830->pScrn_2->modePool);
 
    if (pScrn->videoRam > (pI830->vbeInfo->TotalMemory * 64))
       memsize = pI830->vbeInfo->TotalMemory * 64;
@@ -7378,6 +7409,16 @@ I830DetectMonitorChange(ScrnInfoPtr pScr
 			pScrn->display->virtualY,
 			memsize, LOOKUP_BEST_REFRESH);
 
+   if (pI830->MergedFB) {
+      VBEValidateModes(pI830->pScrn_2, pI830->pScrn_2->monitor->Modes, 
+		        pI830->pScrn_2->display->modes, NULL,
+			NULL, 0, MAX_DISPLAY_PITCH, 1,
+			0, MAX_DISPLAY_HEIGHT,
+			pScrn->display->virtualX,
+			pScrn->display->virtualY,
+			memsize, LOOKUP_BEST_REFRESH);
+   }
+
    if (DDCclock > 0) {
       p = pScrn->modes;
       if (p == NULL)
@@ -7408,9 +7449,70 @@ I830DetectMonitorChange(ScrnInfoPtr pScr
       } while (p != NULL && p != pScrn->modes);
    }
 
+   /* Only use this if we've got DDC available */
+   if (DDCclock2 > 0) {
+      p = pI830->pScrn_2->modes;
+      if (p == NULL)
+         return FALSE;
+      do {
+         int Clock = 100000000; /* incredible value */
+
+	 if (p->status == MODE_OK) {
+            for (pMon = pI830->pScrn_2->monitor->Modes; pMon != NULL; pMon = pMon->next) {
+               if ((pMon->HDisplay != p->HDisplay) ||
+                   (pMon->VDisplay != p->VDisplay) ||
+                   (pMon->Flags & (V_INTERLACE | V_DBLSCAN | V_CLKDIV2)))
+                   continue;
+
+               /* Find lowest supported Clock for this resolution */
+               if (Clock > pMon->Clock)
+                  Clock = pMon->Clock;
+            } 
+
+            if (Clock != 100000000 && DDCclock2 < 2550 && Clock / 1000.0 > DDCclock2) {
+               ErrorF("(%s,%s) mode clock %gMHz exceeds DDC maximum %dMHz\n",
+		   p->name, pI830->pScrn_2->monitor->id,
+		   Clock/1000.0, DDCclock2);
+               p->status = MODE_BAD;
+            } 
+ 	 }
+         p = p->next;
+      } while (p != NULL && p != pI830->pScrn_2->modes);
+   }
+
    pScrn->displayWidth = displayWidth; /* restore old displayWidth */
 
    xf86PruneDriverModes(pScrn);
+
+   if (pI830->MergedFB) {
+      DisplayModePtr old_modes;
+      DisplayModePtr cur_mode;
+
+      xf86PruneDriverModes(pI830->pScrn_2);
+
+      if (pI830->pScrn_2->modes == NULL) {
+         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n");
+         PreInitCleanup(pScrn);
+         return FALSE;
+      }
+
+      old_modes = pScrn->modes;
+      cur_mode = pScrn->currentMode;
+
+      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "MergedFB: Generating mode list\n");
+
+      pScrn->modes = I830GenerateModeList(pScrn, pI830->MetaModes,
+					  old_modes, pI830->pScrn_2->modes,
+					  pI830->SecondPosition);
+
+      if(!pScrn->modes) {
+          xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes. Disabling MergedFB.\n");
+	  pScrn->modes = old_modes;
+	  pScrn->currentMode = cur_mode;
+	  pI830->MergedFB = FALSE;
+      }
+   }
+
    I830PrintModes(pScrn);
 
    if (!pI830->vesa->useDefaultRefresh)
@@ -7458,6 +7560,9 @@ I830DetectMonitorChange(ScrnInfoPtr pScr
       }
    }
 
+   if (pI830->MergedFB)
+      I830AdjustFrameMerged(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+
    return TRUE;
 }
 
diff --git a/src/i830_modes.c b/src/i830_modes.c
index 383b23c..7d71396 100644
--- a/src/i830_modes.c
+++ b/src/i830_modes.c
@@ -675,7 +675,7 @@ void
 I830SetModeParameters(ScrnInfoPtr pScrn, vbeInfoPtr pVbe)
 {
     DisplayModePtr pMode;
-    I830ModePrivatePtr mp;
+    I830ModePrivatePtr mp = NULL;
 
     pMode = pScrn->modes;
     do {
diff-tree 8e6e990db34d63174670512f494fa9adb44786f5 (from fd19b12793f09b6714468556ace875ef36ed9e1c)
Author: Alan Hourihane <alanh at fairlite.demon.co.uk>
Date:   Wed Jul 26 10:48:47 2006 +0100

    Update Xvideo to deal with MergedFB modes.

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 784fd23..4e370b8 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -3724,7 +3724,7 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int f
    int flags24;
    int defmon = 0;
    int i, n;
-   int DDCclock = 0;
+   int DDCclock = 0, DDCclock2 = 0;
    char *s;
    DisplayModePtr p, pMon;
    xf86MonPtr monitor = NULL;
@@ -4996,6 +4996,9 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int f
 
    DDCclock = I830UseDDC(pScrn);
 
+   if (pI830->MergedFB)
+      DDCclock2 = I830UseDDC(pI830->pScrn_2);
+
    /*
     * Note: VBE modes (> 0x7f) won't work with Intel's extended BIOS
     * functions. 
@@ -5112,6 +5115,38 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int f
       } while (p != NULL && p != pScrn->modes);
    }
 
+
+   /* Only use this if we've got DDC available */
+   if (DDCclock2 > 0) {
+      p = pI830->pScrn_2->modes;
+      if (p == NULL)
+         return FALSE;
+      do {
+         int Clock = 100000000; /* incredible value */
+
+	 if (p->status == MODE_OK) {
+            for (pMon = pI830->pScrn_2->monitor->Modes; pMon != NULL; pMon = pMon->next) {
+               if ((pMon->HDisplay != p->HDisplay) ||
+                   (pMon->VDisplay != p->VDisplay) ||
+                   (pMon->Flags & (V_INTERLACE | V_DBLSCAN | V_CLKDIV2)))
+                   continue;
+
+               /* Find lowest supported Clock for this resolution */
+               if (Clock > pMon->Clock)
+                  Clock = pMon->Clock;
+            } 
+
+            if (Clock != 100000000 && DDCclock2 < 2550 && Clock / 1000.0 > DDCclock2) {
+               ErrorF("(%s,%s) mode clock %gMHz exceeds DDC maximum %dMHz\n",
+		   p->name, pI830->pScrn_2->monitor->id,
+		   Clock/1000.0, DDCclock2);
+               p->status = MODE_BAD;
+            } 
+ 	 }
+         p = p->next;
+      } while (p != NULL && p != pI830->pScrn_2->modes);
+   }
+
    xf86PruneDriverModes(pScrn);
 
    if (pScrn->modes == NULL) {
diff --git a/src/i830_video.c b/src/i830_video.c
index a608a7e..762bddf 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -1400,6 +1400,7 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int 
    unsigned int swidth;
    unsigned int mask, shift, offsety, offsetu;
    int tmp;
+   BoxRec dstBox2;
 
    ErrorF("I830DisplayVideo: %dx%d (pitch %d)\n", width, height,
 	   dstPitch);
@@ -1411,21 +1412,24 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int 
    CompareOverlay(pI830, (CARD32 *) overlay, 0x100);
 #endif
 
-   /* When in dual head with different bpp setups we need to refresh the
-    * color key, so let's reset the video parameters and refresh here */
-   if (pI830->entityPrivate)
-      I830ResetVideo(pScrn);
-
-   /* Ensure overlay is turned on with OVERLAY_ENABLE at 0 */
-   if (!*pI830->overlayOn)
-      OVERLAY_UPDATE;
-
    switch (pI830->rotation) {
 	case RR_Rotate_0:
-		dstBox->x1 -= pScrn->frameX0;
-		dstBox->x2 -= pScrn->frameX0;
-		dstBox->y1 -= pScrn->frameY0;
-		dstBox->y2 -= pScrn->frameY0;
+                if (pI830->MergedFB) {
+		   memcpy(&dstBox2, dstBox, sizeof(BoxRec));
+		   dstBox->x1 -= pI830->FirstframeX0;
+		   dstBox->x2 -= pI830->FirstframeX0;
+		   dstBox->y1 -= pI830->FirstframeY0;
+		   dstBox->y2 -= pI830->FirstframeY0;
+		   dstBox2.x1 -= pI830->pScrn_2->frameX0;
+		   dstBox2.x2 -= pI830->pScrn_2->frameX0;
+		   dstBox2.y1 -= pI830->pScrn_2->frameY0;
+		   dstBox2.y2 -= pI830->pScrn_2->frameY0;
+                } else {
+		   dstBox->x1 -= pScrn->frameX0;
+		   dstBox->x2 -= pScrn->frameX0;
+		   dstBox->y1 -= pScrn->frameY0;
+		   dstBox->y2 -= pScrn->frameY0;
+                }
 		break;
 	case RR_Rotate_90:
 		tmp = dstBox->x1;
@@ -1459,6 +1463,72 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int 
 		break;
    }
 
+   if (pI830->MergedFB) {
+      I830ModePrivatePtr mp = (I830ModePrivatePtr)pScrn->currentMode->Private;
+      int w1, h1, w2, h2;
+
+      /* Clip the video to the independent modes of the merged screens */
+      if (dstBox->x1 > mp->merged.First->HDisplay) dstBox->x1 = mp->merged.First->HDisplay - 1;
+      if (dstBox->x2 > mp->merged.First->HDisplay) dstBox->x2 = mp->merged.First->HDisplay - 1;
+      if (dstBox2.x1 > mp->merged.Second->HDisplay) dstBox2.x1 = mp->merged.Second->HDisplay - 1;
+      if (dstBox2.x2 > mp->merged.Second->HDisplay) dstBox2.x2 = mp->merged.Second->HDisplay - 1;
+      if (dstBox->y1 > mp->merged.First->VDisplay) dstBox->y1 = mp->merged.First->VDisplay - 1;
+      if (dstBox->y2 > mp->merged.First->VDisplay) dstBox->y2 = mp->merged.First->VDisplay - 1;
+      if (dstBox2.y1 > mp->merged.Second->VDisplay) dstBox2.y1 = mp->merged.Second->VDisplay - 1;
+      if (dstBox2.y2 > mp->merged.Second->VDisplay) dstBox2.y2 = mp->merged.Second->VDisplay - 1;
+      if (dstBox->y1 < 0) dstBox->y1 = 0;
+      if (dstBox->y2 < 0) dstBox->y2 = 0;
+      if (dstBox->x1 < 0) dstBox->x1 = 0;
+      if (dstBox->x2 < 0) dstBox->x2 = 0;
+      if (dstBox2.y1 < 0) dstBox2.y1 = 0;
+      if (dstBox2.y2 < 0) dstBox2.y2 = 0;
+      if (dstBox2.x1 < 0) dstBox2.x1 = 0;
+      if (dstBox2.x2 < 0) dstBox2.x2 = 0;
+
+      w1 = dstBox->x2 - dstBox->x1;
+      w2 = dstBox2.x2 - dstBox2.x1;
+      h1 = dstBox->y2 - dstBox->y1;
+      h2 = dstBox2.y2 - dstBox2.y1;
+
+      switch (pI830->SecondPosition) {
+         case PosRightOf:
+         case PosBelow:
+            if ((w2 > 0 && w1 == 0) ||
+                (h2 > 0 && h1 == 0)) {
+               pPriv->pipe = pI830->pipe;
+               dstBox->x1 = dstBox2.x1;
+               dstBox->y1 = dstBox2.y1;
+               dstBox->x2 = dstBox2.x2;
+               dstBox->y2 = dstBox2.y2;
+            } else 
+               pPriv->pipe = !pI830->pipe;
+            break;
+         case PosLeftOf:
+         case PosAbove:
+            if ((w1 > 0 && w2 == 0) ||
+                (h1 > 0 && h2 == 0)) { 
+               pPriv->pipe = !pI830->pipe;
+            } else {
+               pPriv->pipe = pI830->pipe;
+               dstBox->x1 = dstBox2.x1;
+               dstBox->y1 = dstBox2.y1;
+               dstBox->x2 = dstBox2.x2;
+               dstBox->y2 = dstBox2.y2;
+            }
+            break;
+      }
+   }
+
+   /* When in dual head with different bpp setups we need to refresh the
+    * color key, so let's reset the video parameters and refresh here.
+    * In MergedFB mode, we may need to flip pipes too. */
+   if (pI830->entityPrivate || pI830->MergedFB)
+      I830ResetVideo(pScrn);
+
+   /* Ensure overlay is turned on with OVERLAY_ENABLE at 0 */
+   if (!*pI830->overlayOn)
+      OVERLAY_UPDATE;
+
    /* Fix up the dstBox if outside the visible screen */
    {
       int offset_x = (dstBox->x1 < 0) ? -dstBox->x1 : 0;
@@ -1522,7 +1592,7 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int 
       /* Keep the engine happy and clip to the real vertical size just
        * in case an LFP is in use and it's not at it's native resolution.
        */
-      int vactive = pI830->pipe ? (INREG(VTOTAL_B) & 0x7FF) : (INREG(VTOTAL_A) & 0x7FF);
+      int vactive = pPriv->pipe ? (INREG(VTOTAL_B) & 0x7FF) : (INREG(VTOTAL_A) & 0x7FF);
 
       vactive += 1;
 
@@ -2553,10 +2623,10 @@ I830VideoSwitchModeAfter(ScrnInfoPtr pSc
    /* Check we have an LFP connected */
    if ((pPriv->pipe == 1 && pI830->operatingDevices & (PIPE_LFP << 8)) ||
        (pPriv->pipe == 0 && pI830->operatingDevices & PIPE_LFP) ) {
-      size = pI830->pipe ? INREG(PIPEBSRC) : INREG(PIPEASRC);
+      size = pPriv->pipe ? INREG(PIPEBSRC) : INREG(PIPEASRC);
       hsize = (size >> 16) & 0x7FF;
       vsize = size & 0x7FF;
-      active = pI830->pipe ? (INREG(VTOTAL_B) & 0x7FF) : (INREG(VTOTAL_A) & 0x7FF);
+      active = pPriv->pipe ? (INREG(VTOTAL_B) & 0x7FF) : (INREG(VTOTAL_A) & 0x7FF);
 
       if (vsize < active && hsize > 1024)
          I830SetOneLineModeRatio(pScrn);
diff-tree e26f3e30b30a57ab4aad0267d689a9a5d7a5e877 (from b919db75d2f6dc1019f981534b0d5d87c6029727)
Author: Alan Hourihane <alanh at fairlite.demon.co.uk>
Date:   Wed Jul 26 09:17:52 2006 +0100

    Fix a build problem

diff --git a/src/i830_3d.c b/src/i830_3d.c
index 0efd6e4..debad7c 100644
--- a/src/i830_3d.c
+++ b/src/i830_3d.c
@@ -29,6 +29,7 @@
 #include "config.h"
 #endif
 
+#include "xf86.h"
 #include "i830.h"
 
 #include "i830_reg.h"
diff --git a/src/i915_3d.c b/src/i915_3d.c
index d8edb18..b1f30ef 100644
--- a/src/i915_3d.c
+++ b/src/i915_3d.c
@@ -29,6 +29,7 @@
 #include "config.h"
 #endif
 
+#include "xf86.h"
 #include "i830.h"
 
 #include "i915_reg.h"
diff-tree b919db75d2f6dc1019f981534b0d5d87c6029727 (from 84805167ab8a422966355b9753bfcb4dad802413)
Author: Alan Hourihane <alanh at fairlite.demon.co.uk>
Date:   Wed Jul 26 09:07:19 2006 +0100

    Bump to 1.6.1

diff --git a/configure.ac b/configure.ac
index 82d3e55..b1d3524 100644
--- a/configure.ac
+++ b/configure.ac
@@ -22,7 +22,7 @@
 
 AC_PREREQ(2.57)
 AC_INIT([xf86-video-i810],
-        1.6.0,
+        1.6.1,
         [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
         xf86-video-i810)
 
diff --git a/src/i810.h b/src/i810.h
index 044eb60..740f38c 100644
--- a/src/i810.h
+++ b/src/i810.h
@@ -66,7 +66,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define I810_DRIVER_NAME "i810"
 #define I810_MAJOR_VERSION 1
 #define I810_MINOR_VERSION 6
-#define I810_PATCHLEVEL 0
+#define I810_PATCHLEVEL 1
 
 
 /* HWMC Surfaces */
diff --git a/src/i830_dri.h b/src/i830_dri.h
index 4f356d1..31232b8 100644
--- a/src/i830_dri.h
+++ b/src/i830_dri.h
@@ -10,7 +10,7 @@
 
 #define I830_MAJOR_VERSION 1
 #define I830_MINOR_VERSION 6
-#define I830_PATCHLEVEL 0
+#define I830_PATCHLEVEL 1
 
 #define I830_REG_SIZE 0x80000
 
diff-tree fd19b12793f09b6714468556ace875ef36ed9e1c (from 84805167ab8a422966355b9753bfcb4dad802413)
Author: Alan Hourihane <alanh at fairlite.demon.co.uk>
Date:   Tue Jul 25 11:14:11 2006 +0100

    Add mergedfb support to the intel driver with
    additional pseudo-Xinerama support.

diff --git a/src/i830.h b/src/i830.h
index 14e921d..8a93f78 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -56,6 +56,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #include "xf86xv.h"
 #include "xf86int10.h"
 #include "vbe.h"
+#include "vbeModes.h"
 #include "vgaHW.h"
 #include "randrstr.h"
 
@@ -70,6 +71,11 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 
 #include "common.h"
 
+#define NEED_REPLIES				/* ? */
+#define EXTENSION_PROC_ARGS void *
+#include "extnsionst.h" 			/* required */
+#include <X11/extensions/panoramiXproto.h> 	/* required */
+
 /* I830 Video BIOS support */
 
 /*
@@ -93,7 +99,6 @@ typedef struct _VESARec {
    int statePage, stateSize, stateMode, stateRefresh;
    CARD32 *savedPal;
    int savedScanlinePitch;
-   xf86MonPtr monitor;
    /* Don't try to set the refresh rate for any modes. */
    Bool useDefaultRefresh;
    /* display start */
@@ -155,6 +160,29 @@ typedef struct {
 #endif
 } I830EntRec, *I830EntPtr;
 
+typedef struct _MergedDisplayModeRec {
+    DisplayModePtr First;
+    DisplayModePtr Second;
+    int    SecondPosition;
+} I830MergedDisplayModeRec, *I830MergedDisplayModePtr;
+
+typedef struct _I830XineramaData {
+    int x;
+    int y;
+    int width;
+    int height;
+} I830XineramaData;
+
+typedef struct _ModePrivateRec {
+    I830MergedDisplayModeRec merged;
+    VbeModeInfoData vbeData;
+} I830ModePrivateRec, *I830ModePrivatePtr;
+
+typedef struct _region {
+    int x0,x1,y0,y1;
+} region;
+
+
 typedef struct _I830Rec {
    unsigned char *MMIOBase;
    unsigned char *FbBase;
@@ -219,6 +247,24 @@ typedef struct _I830Rec {
    I830MemRange LinearMem;
 #endif
    unsigned int LinearAlloc;
+
+   Bool MergedFB;
+   ScrnInfoPtr pScrn_2;
+   char	*SecondHSync;
+   char	*SecondVRefresh;
+   char	*MetaModes;
+   int SecondPosition;
+   int FirstXOffs, FirstYOffs, SecondXOffs, SecondYOffs;
+   int FirstframeX0, FirstframeX1, FirstframeY0, FirstframeY1;
+   int MBXNR1XMAX, MBXNR1YMAX, MBXNR2XMAX, MBXNR2YMAX;
+   Bool	NonRect, HaveNonRect, HaveOffsRegions, MouseRestrictions;
+   int maxFirst_X1, maxFirst_X2, maxFirst_Y1, maxFirst_Y2;
+   int maxSecond_X1, maxSecond_X2, maxSecond_Y1, maxSecond_Y2;
+   region NonRectDead, OffDead1, OffDead2;
+   Bool	IntelXinerama;
+   Bool	SecondIsScrn0;
+   ExtensionEntry *XineramaExtEntry;
+   int I830XineramaVX, I830XineramaVY;
   
    XF86ModReqInfo shadowReq; /* to test for later libshadow */
    I830MemRange RotatedMem;
diff --git a/src/i830_cursor.c b/src/i830_cursor.c
index e465b98..3786120 100644
--- a/src/i830_cursor.c
+++ b/src/i830_cursor.c
@@ -93,15 +93,17 @@ I830InitHWCursor(ScrnInfoPtr pScrn)
 		MCURSOR_PIPE_SELECT);
       temp |= CURSOR_MODE_DISABLE;
       temp |= (pI830->pipe << 28);
-      if(pI830->CursorIsARGB)
-         temp |= MCURSOR_GAMMA_ENABLE;
+      if (pI830->CursorIsARGB)
+         temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
+      else
+         temp |= CURSOR_MODE_64_4C_AX;
       /* Need to set control, then address. */
       OUTREG(CURSOR_A_CONTROL, temp);
       if (pI830->CursorIsARGB)
          OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Physical);
       else
          OUTREG(CURSOR_A_BASE, pI830->CursorMem->Physical);
-      if (pI830->Clone) {
+      if (pI830->Clone || pI830->MergedFB) {
          temp &= ~MCURSOR_PIPE_SELECT;
          temp |= (!pI830->pipe << 28);
          OUTREG(CURSOR_B_CONTROL, temp);
@@ -357,6 +359,102 @@ static void I830LoadCursorARGB (ScrnInfo
 }
 #endif
 
+#define CDMPTR    ((I830ModePrivatePtr)pI830->currentMode->Private)->merged
+
+static void
+I830SetCursorPositionMerged(ScrnInfoPtr pScrn, int x, int y)
+{
+   I830Ptr pI830 = I830PTR(pScrn);
+   ScrnInfoPtr    pScrn2 = pI830->pScrn_2;
+   DisplayModePtr mode1 = CDMPTR.First;
+   Bool hide = FALSE, show = FALSE;
+   DisplayModePtr mode2 = CDMPTR.Second;
+   int x1, y1, x2, y2;
+   int total_y1 = pScrn->frameY1 - pScrn->frameY0;
+   int total_y2 = pScrn2->frameY1 - pScrn2->frameY0;
+   CARD32 temp = 0, temp2 = 0;
+
+   x += pScrn->frameX0;
+   y += pScrn->frameY0;
+
+   x1 = x - pI830->FirstframeX0;
+   y1 = y - pI830->FirstframeY0;
+
+   x2 = x - pScrn2->frameX0;
+   y2 = y - pScrn2->frameY0;
+
+   if (y1 > total_y1)
+      y1 = total_y1;
+   if (y2 > total_y2)                  
+      y2 = total_y2;
+
+   /* move cursor offscreen */
+   if (y1 >= 0 && y2 >= mode2->VDisplay) {
+      y2 = -I810_CURSOR_Y;  
+   } else if (y2 >= 0 && y1 >= mode1->VDisplay) {
+      y1 = -I810_CURSOR_Y;  
+   }
+   if (x1 >= 0 && x2 >= mode2->HDisplay) {
+      x2 = -I810_CURSOR_X;  
+   } else if (x2 >= 0 && x1 >= mode1->HDisplay) {
+      x1 = -I810_CURSOR_X;  
+   }
+
+   /* Clamp the cursor position to the visible screen area */
+   if (x1 >= mode1->HDisplay) x1 = mode1->HDisplay - 1;
+   if (y1 >= mode1->VDisplay) y1 = mode1->VDisplay - 1;
+   if (x1 <= -I810_CURSOR_X) x1 = -I810_CURSOR_X + 1;
+   if (y1 <= -I810_CURSOR_Y) y1 = -I810_CURSOR_Y + 1;
+   if (x2 >= mode2->HDisplay) x2 = mode2->HDisplay - 1;
+   if (y2 >= mode2->VDisplay) y2 = mode2->VDisplay - 1;
+   if (x2 <= -I810_CURSOR_X) x2 = -I810_CURSOR_X + 1;
+   if (y2 <= -I810_CURSOR_Y) y2 = -I810_CURSOR_Y + 1;
+
+   if (x1 < 0) {
+      temp |= (CURSOR_POS_SIGN << CURSOR_X_SHIFT);
+      x1 = -x1;
+   }
+   if (y1 < 0) {
+      temp |= (CURSOR_POS_SIGN << CURSOR_Y_SHIFT);
+      y1 = -y1;
+   }
+   if (x2 < 0) {
+      temp2 |= (CURSOR_POS_SIGN << CURSOR_X_SHIFT);
+      x2 = -x2;
+   }
+   if (y2 < 0) {
+      temp2 |= (CURSOR_POS_SIGN << CURSOR_Y_SHIFT);
+      y2 = -y2;
+   }
+
+   temp |= ((x1 & CURSOR_POS_MASK) << CURSOR_X_SHIFT);
+   temp |= ((y1 & CURSOR_POS_MASK) << CURSOR_Y_SHIFT);
+   temp2 |= ((x2 & CURSOR_POS_MASK) << CURSOR_X_SHIFT);
+   temp2 |= ((y2 & CURSOR_POS_MASK) << CURSOR_Y_SHIFT);
+
+   OUTREG(CURSOR_A_POSITION, temp2);
+   OUTREG(CURSOR_B_POSITION, temp);
+
+   if (pI830->cursorOn) {
+      if (hide)
+	 pI830->CursorInfoRec->HideCursor(pScrn);
+      else if (show)
+	 pI830->CursorInfoRec->ShowCursor(pScrn);
+      pI830->cursorOn = TRUE;
+   }
+
+   /* have to upload the base for the new position */
+   if (IS_I9XX(pI830)) {
+      if (pI830->CursorIsARGB) {
+         OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Physical);
+         OUTREG(CURSOR_B_BASE, pI830->CursorMemARGB->Physical);
+      } else {
+         OUTREG(CURSOR_A_BASE, pI830->CursorMem->Physical);
+         OUTREG(CURSOR_B_BASE, pI830->CursorMem->Physical);
+      }
+   }
+}
+
 static void
 I830SetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
 {
@@ -369,6 +467,11 @@ I830SetCursorPosition(ScrnInfoPtr pScrn,
    static Bool outsideViewport = FALSE;
 #endif
 
+   if (pI830->MergedFB) {
+      I830SetCursorPositionMerged(pScrn, x, y);
+      return;
+   }
+
    oldx += pScrn->frameX0; /* undo what xf86HWCurs did */
    oldy += pScrn->frameY0;
 
@@ -483,9 +586,9 @@ I830ShowCursor(ScrnInfoPtr pScrn)
    pI830->cursorOn = TRUE;
    if (IS_MOBILE(pI830) || IS_I9XX(pI830)) {
       temp = INREG(CURSOR_A_CONTROL);
-      temp &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT);
+      temp &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT | MCURSOR_GAMMA_ENABLE);
       if (pI830->CursorIsARGB)
-         temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
+         temp |= CURSOR_MODE_64_ARGB_AX;
       else
          temp |= CURSOR_MODE_64_4C_AX;
       temp |= (pI830->pipe << 28); /* Connect to correct pipe */
@@ -495,7 +598,7 @@ I830ShowCursor(ScrnInfoPtr pScrn)
          OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Physical);
       else
          OUTREG(CURSOR_A_BASE, pI830->CursorMem->Physical);
-      if (pI830->Clone) {
+      if (pI830->Clone || pI830->MergedFB) {
          temp &= ~MCURSOR_PIPE_SELECT;
          temp |= (!pI830->pipe << 28);
          OUTREG(CURSOR_B_CONTROL, temp);
@@ -506,7 +609,7 @@ I830ShowCursor(ScrnInfoPtr pScrn)
       }
    } else {
       temp = INREG(CURSOR_CONTROL);
-      temp &= ~(CURSOR_FORMAT_MASK);
+      temp &= ~(CURSOR_FORMAT_MASK | CURSOR_GAMMA_ENABLE);
       temp |= CURSOR_ENABLE;
       if (pI830->CursorIsARGB)
          temp |= CURSOR_FORMAT_ARGB | CURSOR_GAMMA_ENABLE;
@@ -539,7 +642,7 @@ I830HideCursor(ScrnInfoPtr pScrn)
          OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Physical);
       else
          OUTREG(CURSOR_A_BASE, pI830->CursorMem->Physical);
-      if (pI830->Clone) {
+      if (pI830->Clone || pI830->MergedFB) {
          OUTREG(CURSOR_B_CONTROL, temp);
          if (pI830->CursorIsARGB)
             OUTREG(CURSOR_B_BASE, pI830->CursorMemARGB->Physical);
@@ -570,7 +673,7 @@ I830SetCursorColors(ScrnInfoPtr pScrn, i
    OUTREG(CURSOR_A_PALETTE1, fg & 0x00ffffff);
    OUTREG(CURSOR_A_PALETTE2, fg & 0x00ffffff);
    OUTREG(CURSOR_A_PALETTE3, bg & 0x00ffffff);
-   if (pI830->Clone) {
+   if (pI830->Clone || pI830->MergedFB) {
       OUTREG(CURSOR_B_PALETTE0, bg & 0x00ffffff);
       OUTREG(CURSOR_B_PALETTE1, fg & 0x00ffffff);
       OUTREG(CURSOR_B_PALETTE2, fg & 0x00ffffff);
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 5ce88e1..784fd23 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -178,10 +178,10 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include <X11/extensions/randr.h>
 #include "fb.h"
 #include "miscstruct.h"
+#include "dixstruct.h"
 #include "xf86xv.h"
 #include <X11/extensions/Xv.h>
 #include "vbe.h"
-#include "vbeModes.h"
 #include "shadow.h"
 #include "i830.h"
 
@@ -244,7 +244,13 @@ typedef enum {
    OPTION_CHECKDEVICES,
    OPTION_FIXEDPIPE,
    OPTION_ROTATE,
-   OPTION_LINEARALLOC
+   OPTION_LINEARALLOC,
+   OPTION_MERGEDFB,
+   OPTION_METAMODES,
+   OPTION_SECONDHSYNC,
+   OPTION_SECONDVREFRESH,
+   OPTION_SECONDPOSITION,
+   OPTION_INTELXINERAMA
 } I830Opts;
 
 static OptionInfoRec I830BIOSOptions[] = {
@@ -266,6 +272,12 @@ static OptionInfoRec I830BIOSOptions[] =
    {OPTION_FIXEDPIPE,   "FixedPipe",    OPTV_ANYSTR, 	{0},	FALSE},
    {OPTION_ROTATE,      "Rotate",       OPTV_ANYSTR,    {0},    FALSE},
    {OPTION_LINEARALLOC, "LinearAlloc",  OPTV_INTEGER,   {0},    FALSE},
+   {OPTION_MERGEDFB, 	"MergedFB",	OPTV_BOOLEAN,	{0},	FALSE},
+   {OPTION_METAMODES, 	"MetaModes",	OPTV_STRING,	{0},	FALSE},
+   {OPTION_SECONDHSYNC,	"SecondMonitorHorizSync",OPTV_STRING,	{0}, FALSE },
+   {OPTION_SECONDVREFRESH,"SecondMonitorVertRefresh",OPTV_STRING,{0}, FALSE },
+   {OPTION_SECONDPOSITION,"SecondPosition",OPTV_STRING,	{0},	FALSE },
+   {OPTION_INTELXINERAMA,"MergedXinerama",OPTV_BOOLEAN,	{0},	TRUE},
    {-1,			NULL,		OPTV_NONE,	{0},	FALSE}
 };
 /* *INDENT-ON* */
@@ -283,9 +295,24 @@ static Bool SetPipeAccess(ScrnInfoPtr pS
 
 extern int I830EntityIndex;
 
+static Bool 		I830noPanoramiXExtension = TRUE;
+static int		I830XineramaNumScreens = 0;
+static I830XineramaData	*I830XineramadataPtr = NULL;
+static int		I830XineramaGeneration;
+
+static int I830ProcXineramaQueryVersion(ClientPtr client);
+static int I830ProcXineramaGetState(ClientPtr client);
+static int I830ProcXineramaGetScreenCount(ClientPtr client);
+static int I830ProcXineramaGetScreenSize(ClientPtr client);
+static int I830ProcXineramaIsActive(ClientPtr client);
+static int I830ProcXineramaQueryScreens(ClientPtr client);
+static int I830SProcXineramaDispatch(ClientPtr client);
+
 /* temporary */
 extern void xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y);
 
+static const char *SecondMonitorName = "MergedFBMonitor";
+
 
 #ifdef I830DEBUG
 void
@@ -354,11 +381,9 @@ I830BIOSFreeRec(ScrnInfoPtr pScrn)
    if (mode) {
       do {
 	 if (mode->Private) {
-	    VbeModeInfoData *data = (VbeModeInfoData *) mode->Private;
+	    I830ModePrivatePtr mp = (I830ModePrivatePtr) mode->Private;
 
-	    if (data->block)
-	       xfree(data->block);
-	    xfree(data);
+	    xfree(mp);
 	    mode->Private = NULL;
 	 }
 	 mode = mode->next;
@@ -373,8 +398,6 @@ I830BIOSFreeRec(ScrnInfoPtr pScrn)
    }
 
    pVesa = pI830->vesa;
-   if (pVesa->monitor)
-      xfree(pVesa->monitor);
    if (pVesa->savedPal)
       xfree(pVesa->savedPal);
    xfree(pVesa);
@@ -383,6 +406,1613 @@ I830BIOSFreeRec(ScrnInfoPtr pScrn)
    pScrn->driverPrivate = NULL;
 }
 
+static Bool
+InRegion(int x, int y, region r)
+{
+    return (r.x0 <= x) && (x <= r.x1) && (r.y0 <= y) && (y <= r.y1);
+}
+
+static int
+I830StrToRanges(range *r, char *s, int max)
+{
+   float num = 0.0;
+   int rangenum = 0;
+   Bool gotdash = FALSE;
+   Bool nextdash = FALSE;
+   char *strnum = NULL;
+   do {
+      switch(*s) {
+      case '0':
+      case '1':
+      case '2':
+      case '3':
+      case '4':
+      case '5':
+      case '6':
+      case '7':
+      case '8':
+      case '9':
+      case '.':
+         if(strnum == NULL) {
+            strnum = s;
+            gotdash = nextdash;
+            nextdash = FALSE;
+         }
+         break;
+      case '-':
+      case ' ':
+      case 0:
+         if(strnum == NULL) break;
+         sscanf(strnum, "%f", &num);
+	 strnum = NULL;
+         if(gotdash) {
+            r[rangenum - 1].hi = num;
+         } else {
+            r[rangenum].lo = num;
+            r[rangenum].hi = num;
+            rangenum++;
+         }
+         if(*s == '-') nextdash = (rangenum != 0);
+	 else if(rangenum >= max) return rangenum;
+         break;
+      default:
+         return 0;
+      }
+
+   } while(*(s++) != 0);
+
+   return rangenum;
+}
+
+/* Calculate the vertical refresh rate from a mode */
+static float
+I830CalcVRate(DisplayModePtr mode)
+{
+   float hsync, refresh = 0;
+
+   if(mode->HSync > 0.0)
+       	hsync = mode->HSync;
+   else if(mode->HTotal > 0)
+       	hsync = (float)mode->Clock / (float)mode->HTotal;
+   else
+       	hsync = 0.0;
+
+   if(mode->VTotal > 0)
+       	refresh = hsync * 1000.0 / mode->VTotal;
+
+   if(mode->Flags & V_INTERLACE)
+       	refresh *= 2.0;
+
+   if(mode->Flags & V_DBLSCAN)
+       	refresh /= 2.0;
+
+   if(mode->VScan > 1)
+        refresh /= mode->VScan;
+
+   if(mode->VRefresh > 0.0)
+	refresh = mode->VRefresh;
+
+   if(hsync == 0.0 || refresh == 0.0) return 0.0;
+
+   return refresh;
+}
+
+/* Copy and link two modes (i, j) for mergedfb mode
+ * (Code base taken from mga driver)
+ *
+ * - Copy mode i, merge j to copy of i, link the result to dest
+ * - Link i and j in private record.
+ * - If dest is NULL, return value is copy of i linked to itself.
+ * - For mergedfb auto-config, we only check the dimension
+ *   against virtualX/Y, if they were user-provided.
+ * - No special treatment required for CRTxxOffs.
+ * - Provide fake dotclock in order to distinguish between similar
+ *   looking MetaModes (for RandR and VidMode extensions)
+ * - Set unique VRefresh of dest mode for RandR
+ */
+static DisplayModePtr
+I830CopyModeNLink(ScrnInfoPtr pScrn, DisplayModePtr dest,
+                 DisplayModePtr i, DisplayModePtr j,
+		 int pos)
+{
+    DisplayModePtr mode;
+    int dx = 0,dy = 0;
+
+    if(!((mode = xalloc(sizeof(DisplayModeRec))))) return dest;
+    memcpy(mode, i, sizeof(DisplayModeRec));
+    if(!((mode->Private = xalloc(sizeof(I830ModePrivateRec))))) {
+       xfree(mode);
+       return dest;
+    }
+    ((I830ModePrivatePtr)mode->Private)->merged.First = i;
+    ((I830ModePrivatePtr)mode->Private)->merged.Second = j;
+    ((I830ModePrivatePtr)mode->Private)->merged.SecondPosition = pos;
+    if (((I830ModePrivatePtr)i->Private)->vbeData.mode > 0x30) {
+       ((I830ModePrivatePtr)mode->Private)->vbeData.mode = ((I830ModePrivatePtr)i->Private)->vbeData.mode;
+       ((I830ModePrivatePtr)mode->Private)->vbeData.data = ((I830ModePrivatePtr)i->Private)->vbeData.data;
+    } else {
+       ((I830ModePrivatePtr)mode->Private)->vbeData.mode = ((I830ModePrivatePtr)j->Private)->vbeData.mode;
+       ((I830ModePrivatePtr)mode->Private)->vbeData.data = ((I830ModePrivatePtr)j->Private)->vbeData.data;
+    }
+    mode->PrivSize = sizeof(I830ModePrivateRec);
+
+    switch(pos) {
+    case PosLeftOf:
+    case PosRightOf:
+       if(!(pScrn->display->virtualX)) {
+          dx = i->HDisplay + j->HDisplay;
+       } else {
+          dx = min(pScrn->virtualX, i->HDisplay + j->HDisplay);
+       }
+       dx -= mode->HDisplay;
+       if(!(pScrn->display->virtualY)) {
+          dy = max(i->VDisplay, j->VDisplay);
+       } else {
+          dy = min(pScrn->virtualY, max(i->VDisplay, j->VDisplay));
+       }
+       dy -= mode->VDisplay;
+       break;
+    case PosAbove:
+    case PosBelow:
+       if(!(pScrn->display->virtualY)) {
+          dy = i->VDisplay + j->VDisplay;
+       } else {
+          dy = min(pScrn->virtualY, i->VDisplay + j->VDisplay);
+       }
+       dy -= mode->VDisplay;
+       if(!(pScrn->display->virtualX)) {
+          dx = max(i->HDisplay, j->HDisplay);
+       } else {
+          dx = min(pScrn->virtualX, max(i->HDisplay, j->HDisplay));
+       }
+       dx -= mode->HDisplay;
+       break;
+    }
+    mode->HDisplay += dx;
+    mode->HSyncStart += dx;
+    mode->HSyncEnd += dx;
+    mode->HTotal += dx;
+    mode->VDisplay += dy;
+    mode->VSyncStart += dy;
+    mode->VSyncEnd += dy;
+    mode->VTotal += dy;
+
+    mode->type = M_T_DEFAULT;
+
+    /* Set up as user defined (ie fake that the mode has been named in the
+     * Modes-list in the screen section; corrects cycling with CTRL-ALT-[-+]
+     * when source mode has not been listed there.)
+     */
+    mode->type |= M_T_USERDEF;
+
+    /* Set the VRefresh field (in order to make RandR use it for the rates). We
+     * simply set this to the refresh rate for the First mode (since Second will
+     * mostly be LCD or TV anyway).
+     */
+    mode->VRefresh = I830CalcVRate(i);
+
+    if( ((mode->HDisplay * ((pScrn->bitsPerPixel + 7) / 8) * mode->VDisplay) > (pScrn->videoRam * 1024)) ||
+	(mode->HDisplay > 4088) ||
+	(mode->VDisplay > 4096) ) {
+
+       xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		"Skipped \"%s\" (%dx%d), not enough video RAM or beyond hardware specs\n",
+		mode->name, mode->HDisplay, mode->VDisplay);
+       xfree(mode->Private);
+       xfree(mode);
+
+       return dest;
+    }
+
+    /* Now see if the resulting mode would be discarded as a "size" by the
+     * RandR extension, and increase its clock by 1000 in case it does.
+     */
+    if(dest) {
+       DisplayModePtr t = dest;
+       do {
+          if((t->HDisplay == mode->HDisplay) &&
+	     (t->VDisplay == mode->VDisplay) &&
+	     ((int)(t->VRefresh + .5) == (int)(mode->VRefresh + .5))) {
+	     mode->VRefresh += 1000.0;
+	  }
+	  t = t->next;
+       } while((t) && (t != dest));
+    }
+
+    /* Provide a fake but unique DotClock in order to trick the vidmode
+     * extension to allow selecting among a number of modes whose merged result
+     * looks identical but consists of different modes for First and Second
+     */
+    mode->Clock = (int)(mode->VRefresh * 1000.0);
+
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+	"Merged \"%s\" (%dx%d) and \"%s\" (%dx%d) to %dx%d (%d)\n",
+	i->name, i->HDisplay, i->VDisplay, j->name, j->HDisplay, j->VDisplay,
+	mode->HDisplay, mode->VDisplay, (int)mode->VRefresh);
+
+    mode->next = mode;
+    mode->prev = mode;
+
+    if(dest) {
+       mode->next = dest->next; 	/* Insert node after "dest" */
+       dest->next->prev = mode;
+       mode->prev = dest;
+       dest->next = mode;
+    }
+
+    return mode;
+}
+
+/* Helper function to find a mode from a given name
+ * (Code base taken from mga driver)
+ */
+static DisplayModePtr
+I830GetModeFromName(char* str, DisplayModePtr i)
+{
+    DisplayModePtr c = i;
+    if(!i) return NULL;
+    do {
+       if(strcmp(str, c->name) == 0) return c;
+       c = c->next;
+    } while(c != i);
+    return NULL;
+}
+
+static DisplayModePtr
+I830FindWidestTallestMode(DisplayModePtr i, Bool tallest)
+{
+    DisplayModePtr c = i, d = NULL;
+    int max = 0;
+    if(!i) return NULL;
+    do {
+       if(tallest) {
+          if(c->VDisplay > max) {
+	     max = c->VDisplay;
+	     d = c;
+          }
+       } else {
+          if(c->HDisplay > max) {
+	     max = c->HDisplay;
+	     d = c;
+          }
+       }
+       c = c->next;
+    } while(c != i);
+    return d;
+}
+
+static void
+I830FindWidestTallestCommonMode(DisplayModePtr i, DisplayModePtr j, Bool tallest,
+				DisplayModePtr *a, DisplayModePtr *b)
+{
+    DisplayModePtr c = i, d;
+    int max = 0;
+    Bool foundone;
+
+    (*a) = (*b) = NULL;
+
+    if(!i || !j) return;
+
+    do {
+       d = j;
+       foundone = FALSE;
+       do {
+	  if( (c->HDisplay == d->HDisplay) &&
+	      (c->VDisplay == d->VDisplay) ) {
+	     foundone = TRUE;
+	     break;
+	  }
+	  d = d->next;
+       } while(d != j);
+       if(foundone) {
+	  if(tallest) {
+	     if(c->VDisplay > max) {
+		max = c->VDisplay;
+		(*a) = c;
+		(*b) = d;
+	     }
+	  } else {
+	     if(c->HDisplay > max) {
+		max = c->HDisplay;
+		(*a) = c;
+		(*b) = d;
+	     }
+	  }
+       }
+       c = c->next;
+    } while(c != i);
+}
+
+static DisplayModePtr
+I830GenerateModeListFromLargestModes(ScrnInfoPtr pScrn,
+		    DisplayModePtr i, DisplayModePtr j,
+		    int pos)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+    DisplayModePtr mode1 = NULL;
+    DisplayModePtr mode2 = NULL;
+    DisplayModePtr mode3 = NULL;
+    DisplayModePtr mode4 = NULL;
+    DisplayModePtr result = NULL;
+
+    /* Now build a default list of MetaModes.
+     * - Non-clone: If the user enabled NonRectangular, we use the
+     * largest mode for each First and Second. If not, we use the largest
+     * common mode for First and Second (if available). Additionally, and
+     * regardless if the above, we produce a clone mode consisting of
+     * the largest common mode (if available) in order to use DGA.
+     * - Clone: If the (global) SecondPosition is Clone, we use the
+     * largest common mode if available, otherwise the first two modes
+     * in each list.
+     */
+
+    switch(pos) {
+    case PosLeftOf:
+    case PosRightOf:
+       mode1 = I830FindWidestTallestMode(i, FALSE);
+       mode2 = I830FindWidestTallestMode(j, FALSE);
+       I830FindWidestTallestCommonMode(i, j, FALSE, &mode3, &mode4);
+       break;
+    case PosAbove:
+    case PosBelow:
+       mode1 = I830FindWidestTallestMode(i, TRUE);
+       mode2 = I830FindWidestTallestMode(j, TRUE);
+       I830FindWidestTallestCommonMode(i, j, TRUE, &mode3, &mode4);
+       break;
+    }
+
+    if(mode3 && mode4 && !pI830->NonRect) {
+       mode1 = mode3;
+       mode2 = mode2;
+    }
+
+    if(mode1 && mode2) {
+       result = I830CopyModeNLink(pScrn, result, mode1, mode2, pos);
+    }
+
+    return result;
+}
+
+/* Generate the merged-fb mode modelist
+ * (Taken from mga driver)
+ */
+static DisplayModePtr
+I830GenerateModeListFromMetaModes(ScrnInfoPtr pScrn, char* str,
+		    DisplayModePtr i, DisplayModePtr j,
+		    int pos)
+{
+    char* strmode = str;
+    char modename[256];
+    Bool gotdash = FALSE;
+    char gotsep = 0;
+    int p; 
+    DisplayModePtr mode1 = NULL;
+    DisplayModePtr mode2 = NULL;
+    DisplayModePtr result = NULL;
+    int myslen;
+
+    do {
+        switch(*str) {
+        case 0:
+        case '-':
+	case '+':
+        case ' ':
+	case ',':
+	case ';':
+           if(strmode != str) {
+
+              myslen = str - strmode;
+              if(myslen > 255) myslen = 255;
+  	      strncpy(modename, strmode, myslen);
+  	      modename[myslen] = 0;
+
+              if(gotdash) {
+                 if(mode1 == NULL) {
+  	             xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+  	                        "Error parsing MetaModes parameter\n");
+  	             return NULL;
+  	         }
+                 mode2 = I830GetModeFromName(modename, j);
+                 if(!mode2) {
+                    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+                        "Mode \"%s\" is not a supported mode for Second\n", modename);
+                    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+                        "\t(Skipping metamode \"%s%c%s\")\n", mode1->name, gotsep, modename);
+                    mode1 = NULL;
+		    gotsep = 0;
+                 }
+              } else {
+                 mode1 = I830GetModeFromName(modename, i);
+                 if(!mode1) {
+                    char* tmps = str;
+                    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+                        "Mode \"%s\" is not a supported mode for First\n", modename);
+                    while(*tmps == ' ' || *tmps == ';') tmps++;
+                    /* skip the next mode */
+  	            if(*tmps == '-' || *tmps == '+' || *tmps == ',') {
+                       tmps++;
+		       /* skip spaces */
+		       while(*tmps == ' ' || *tmps == ';') tmps++;
+		       /* skip modename */
+		       while(*tmps && *tmps != ' ' && *tmps != ';' && *tmps != '-' && *tmps != '+' && *tmps != ',') tmps++;
+  	               myslen = tmps - strmode;
+  	               if(myslen > 255) myslen = 255;
+  	               strncpy(modename,strmode,myslen);
+  	               modename[myslen] = 0;
+                       str = tmps - 1;
+                    }
+                    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+                        "\t(Skipping metamode \"%s\")\n", modename);
+                    mode1 = NULL;
+		    gotsep = 0;
+                 }
+              }
+              gotdash = FALSE;
+           }
+           strmode = str + 1;
+           gotdash |= (*str == '-' || *str == '+' || *str == ',');
+	   if (*str == '-' || *str == '+' || *str == ',')
+  	      gotsep = *str;
+
+           if(*str != 0) break;
+	   /* Fall through otherwise */
+
+        default:
+           if(!gotdash && mode1) {
+              p = pos ;
+              if(!mode2) {
+                 xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+                     "Mode \"%s\" is not a supported mode for Second\n", mode1->name);
+                 xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+                     "\t(Skipping metamode \"%s\")\n", modename);
+                 mode1 = NULL;
+              } else {
+                 result = I830CopyModeNLink(pScrn, result, mode1, mode2, p);
+                 mode1 = NULL;
+                 mode2 = NULL;
+              }
+	      gotsep = 0;
+           }
+           break;
+
+        }
+
+    } while(*(str++) != 0);
+     
+    return result;
+}
+
+static DisplayModePtr
+I830GenerateModeList(ScrnInfoPtr pScrn, char* str,
+		    DisplayModePtr i, DisplayModePtr j,
+		    int pos)
+{
+   I830Ptr pI830 = I830PTR(pScrn);
+
+   if(str != NULL) {
+      return(I830GenerateModeListFromMetaModes(pScrn, str, i, j, pos));
+   } else {
+      xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+	"No MetaModes given, linking %s modes by default\n",
+	   (pI830->NonRect ?
+		(((pos == PosLeftOf) || (pos == PosRightOf)) ? "widest" :  "tallest")
+		:
+		(((pos == PosLeftOf) || (pos == PosRightOf)) ? "widest common" :  "tallest common")) );
+      return(I830GenerateModeListFromLargestModes(pScrn, i, j, pos));
+   }
+}
+
+static void
+I830RecalcDefaultVirtualSize(ScrnInfoPtr pScrn)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+    DisplayModePtr mode, bmode;
+    int maxh, maxv;
+    static const char *str = "MergedFB: Virtual %s %d\n";
+    static const char *errstr = "Virtual %s to small for given SecondPosition offset\n";
+
+    mode = bmode = pScrn->modes;
+    maxh = maxv = 0;
+    do {
+       if(mode->HDisplay > maxh) maxh = mode->HDisplay;
+       if(mode->VDisplay > maxv) maxv = mode->VDisplay;
+       mode = mode->next;
+    } while(mode != bmode);
+
+    maxh += pI830->FirstXOffs + pI830->SecondXOffs;
+    maxv += pI830->FirstYOffs + pI830->SecondYOffs;
+
+    if(!(pScrn->display->virtualX)) {
+       if(maxh > 4088) {
+	  xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		"Virtual width with SecondPosition offset beyond hardware specs\n");
+	  pI830->FirstXOffs = pI830->SecondXOffs = 0;
+	  maxh -= (pI830->FirstXOffs + pI830->SecondXOffs);
+       }
+       pScrn->virtualX = maxh;
+       pScrn->displayWidth = maxh;
+       xf86DrvMsg(pScrn->scrnIndex, X_PROBED, str, "width", maxh);
+    } else {
+       if(maxh < pScrn->display->virtualX) {
+	  xf86DrvMsg(pScrn->scrnIndex, X_ERROR, errstr, "width");
+	  pI830->FirstXOffs = pI830->SecondXOffs = 0;
+       }
+    }
+
+    if(!(pScrn->display->virtualY)) {
+       pScrn->virtualY = maxv;
+       xf86DrvMsg(pScrn->scrnIndex, X_PROBED, str, "height", maxv);
+    } else {
+       if(maxv < pScrn->display->virtualY) {
+	  xf86DrvMsg(pScrn->scrnIndex, X_ERROR, errstr, "height");
+	  pI830->FirstYOffs = pI830->SecondYOffs = 0;
+       }
+    }
+}
+
+#define SDMPTR(x) ((I830ModePrivatePtr)x->currentMode->Private)->merged
+#define CDMPTR    ((I830ModePrivatePtr)pI830->currentMode->Private)->merged
+
+#define BOUND(test,low,hi) 			\
+    {						\
+	if((test) < (low)) (test) = (low);	\
+	if((test) > (hi))  (test) = (hi);	\
+    }
+
+#define REBOUND(low,hi,test)		\
+    {					\
+	if((test) < (low)) {		\
+		(hi) += (test)-(low);	\
+		(low) = (test); 	\
+	}				\
+	if((test) > (hi)) {		\
+		(low) += (test)-(hi);	\
+		(hi) = (test); 		\
+	}				\
+    }
+
+
+static void
+I830MergedPointerMoved(int scrnIndex, int x, int y)
+{
+  ScrnInfoPtr	pScrn1 = xf86Screens[scrnIndex];
+  I830Ptr	pI830 = I830PTR(pScrn1);
+  ScrnInfoPtr	pScrn2 = pI830->pScrn_2;
+  region	out, in1, in2, f2, f1;
+  int		deltax, deltay;
+  int		temp1, temp2;
+  int		old1x0, old1y0, old2x0, old2y0;
+  int		FirstXOffs = 0, FirstYOffs = 0, SecondXOffs = 0, SecondYOffs = 0;
+  int		HVirt = pScrn1->virtualX;
+  int		VVirt = pScrn1->virtualY;
+  int		sigstate;
+  Bool		doit = FALSE, HaveNonRect = FALSE, HaveOffsRegions = FALSE;
+  int           pos = ((I830MergedDisplayModePtr)pI830->currentMode->Private)->SecondPosition;
+
+  if(pI830->DGAactive) {
+     return;
+     /* DGA: There is no cursor and no panning while DGA is active. */
+  } else {
+     FirstXOffs = pI830->FirstXOffs;
+     FirstYOffs = pI830->FirstYOffs;
+     SecondXOffs = pI830->SecondXOffs;
+     SecondYOffs = pI830->SecondYOffs;
+     HaveNonRect = pI830->HaveNonRect;
+     HaveOffsRegions = pI830->HaveOffsRegions;
+  }
+
+  /* Check if the pointer is inside our dead areas */
+  if((pI830->MouseRestrictions) && !I830noPanoramiXExtension) {
+     if(HaveNonRect) {
+	if(InRegion(x, y, pI830->NonRectDead)) {
+	   switch(pos) {
+	   case PosLeftOf:
+	   case PosRightOf: y = pI830->NonRectDead.y0 - 1;
+			    doit = TRUE;
+			    break;
+	   case PosAbove:
+	   case PosBelow:   x = pI830->NonRectDead.x0 - 1;
+			    doit = TRUE;
+	   default:	    break;
+	   }
+	}
+     }
+     if(HaveOffsRegions) {
+	if(InRegion(x, y, pI830->OffDead1)) {
+	   switch(pos) {
+	   case PosLeftOf:
+	   case PosRightOf: y = pI830->OffDead1.y1;
+			    doit = TRUE;
+			    break;
+	   case PosAbove:
+	   case PosBelow:   x = pI830->OffDead1.x1;
+			    doit = TRUE;
+	   default:	    break;
+	   }
+	} else if(InRegion(x, y, pI830->OffDead2)) {
+	   switch(pos) {
+	   case PosLeftOf:
+	   case PosRightOf: y = pI830->OffDead2.y0 - 1;
+			    doit = TRUE;
+			    break;
+	   case PosAbove:
+	   case PosBelow:   x = pI830->OffDead2.x0 - 1;
+			    doit = TRUE;
+	   default:	    break;
+	   }
+	}
+     }
+     if(doit) {
+	UpdateCurrentTime();
+	sigstate = xf86BlockSIGIO();
+	miPointerAbsoluteCursor(x, y, currentTime.milliseconds);
+	xf86UnblockSIGIO(sigstate);
+	return;
+     }
+  }
+
+  f1.x0 = old1x0 = pI830->FirstframeX0;
+  f1.x1 = pI830->FirstframeX1;
+  f1.y0 = old1y0 = pI830->FirstframeY0;
+  f1.y1 = pI830->FirstframeY1;
+  f2.x0 = old2x0 = pScrn2->frameX0;
+  f2.x1 = pScrn2->frameX1;
+  f2.y0 = old2y0 = pScrn2->frameY0;
+  f2.y1 = pScrn2->frameY1;
+
+  /* Define the outer region. Crossing this causes all frames to move */
+  out.x0 = pScrn1->frameX0;
+  out.x1 = pScrn1->frameX1;
+  out.y0 = pScrn1->frameY0;
+  out.y1 = pScrn1->frameY1;
+
+  /*
+   * Define the inner sliding window. Being outsize both frames but
+   * inside the outer clipping window will slide corresponding frame
+   */
+  in1 = out;
+  in2 = out;
+  switch(pos) {
+     case PosLeftOf:
+        in1.x0 = f1.x0;
+        in2.x1 = f2.x1;
+        break;
+     case PosRightOf:
+        in1.x1 = f1.x1;
+        in2.x0 = f2.x0;
+        break;
+     case PosBelow:
+        in1.y1 = f1.y1;
+        in2.y0 = f2.y0;
+        break;
+     case PosAbove:
+        in1.y0 = f1.y0;
+        in2.y1 = f2.y1;
+        break;
+  }
+
+  deltay = 0;
+  deltax = 0;
+
+  if(InRegion(x, y, out)) {	/* inside outer region */
+
+     if(InRegion(x, y, in1) && !InRegion(x, y, f1)) {
+	REBOUND(f1.x0, f1.x1, x);
+	REBOUND(f1.y0, f1.y1, y);
+	deltax = 1;
+     }
+     if(InRegion(x, y, in2) && !InRegion(x, y, f2)) {
+	REBOUND(f2.x0, f2.x1, x);
+	REBOUND(f2.y0, f2.y1, y);
+	deltax = 1;
+     }
+
+  } else {			/* outside outer region */
+
+     if(out.x0 > x) {
+	deltax = x - out.x0;
+     }
+     if(out.x1 < x) {
+	deltax = x - out.x1;
+     }
+     if(deltax) {
+	pScrn1->frameX0 += deltax;
+	pScrn1->frameX1 += deltax;
+	f1.x0 += deltax;
+	f1.x1 += deltax;
+	f2.x0 += deltax;
+	f2.x1 += deltax;
+     }
+
+     if(out.y0 > y) {
+	deltay = y - out.y0;
+     }
+     if(out.y1 < y) {
+	deltay = y - out.y1;
+     }
+     if(deltay) {
+	pScrn1->frameY0 += deltay;
+	pScrn1->frameY1 += deltay;
+	f1.y0 += deltay;
+	f1.y1 += deltay;
+	f2.y0 += deltay;
+	f2.y1 += deltay;
+     }
+
+     switch(pos) {
+	case PosLeftOf:
+	   if(x >= f1.x0) { REBOUND(f1.y0, f1.y1, y); }
+	   if(x <= f2.x1) { REBOUND(f2.y0, f2.y1, y); }
+	   break;
+	case PosRightOf:
+	   if(x <= f1.x1) { REBOUND(f1.y0, f1.y1, y); }
+	   if(x >= f2.x0) { REBOUND(f2.y0, f2.y1, y); }
+	   break;
+	case PosBelow:
+	   if(y <= f1.y1) { REBOUND(f1.x0, f1.x1, x); }
+	   if(y >= f2.y0) { REBOUND(f2.x0, f2.x1, x); }
+	   break;
+	case PosAbove:
+	   if(y >= f1.y0) { REBOUND(f1.x0, f1.x1, x); }
+	   if(y <= f2.y1) { REBOUND(f2.x0, f2.x1, x); }
+	   break;
+     }
+
+  }
+
+  if(deltax || deltay) {
+     pI830->FirstframeX0 = f1.x0;
+     pI830->FirstframeY0 = f1.y0;
+     pScrn2->frameX0 = f2.x0;
+     pScrn2->frameY0 = f2.y0;
+
+     switch(pos) {
+	case PosLeftOf:
+	case PosRightOf:
+	   if(FirstYOffs || SecondYOffs || HaveNonRect) {
+	      if(pI830->FirstframeY0 != old1y0) {
+	         if(pI830->FirstframeY0 < FirstYOffs)
+	            pI830->FirstframeY0 = FirstYOffs;
+
+	         temp1 = pI830->FirstframeY0 + CDMPTR.First->VDisplay;
+	         temp2 = min((VVirt - SecondYOffs), (FirstYOffs + pI830->MBXNR1YMAX));
+	         if(temp1 > temp2)
+	            pI830->FirstframeY0 -= (temp1 - temp2);
+	      }
+	      if(pScrn2->frameY0 != old2y0) {
+	         if(pScrn2->frameY0 < SecondYOffs)
+	            pScrn2->frameY0 = SecondYOffs;
+
+	         temp1 = pScrn2->frameY0 + CDMPTR.Second->VDisplay;
+	         temp2 = min((VVirt - FirstYOffs), (SecondYOffs + pI830->MBXNR2YMAX));
+	         if(temp1 > temp2)
+	            pScrn2->frameY0 -= (temp1 - temp2);
+	      }
+	   }
+	   break;
+	case PosBelow:
+	case PosAbove:
+	   if(FirstXOffs || SecondXOffs || HaveNonRect) {
+	      if(pI830->FirstframeX0 != old1x0) {
+	         if(pI830->FirstframeX0 < FirstXOffs)
+	            pI830->FirstframeX0 = FirstXOffs;
+
+	         temp1 = pI830->FirstframeX0 + CDMPTR.First->HDisplay;
+	         temp2 = min((HVirt - SecondXOffs), (FirstXOffs + pI830->MBXNR1XMAX));
+	         if(temp1 > temp2)
+	            pI830->FirstframeX0 -= (temp1 - temp2);
+	      }
+	      if(pScrn2->frameX0 != old2x0) {
+	         if(pScrn2->frameX0 < SecondXOffs)
+	            pScrn2->frameX0 = SecondXOffs;
+
+	         temp1 = pScrn2->frameX0 + CDMPTR.Second->HDisplay;
+	         temp2 = min((HVirt - FirstXOffs), (SecondXOffs + pI830->MBXNR2XMAX));
+	         if(temp1 > temp2)
+	            pScrn2->frameX0 -= (temp1 - temp2);
+	      }
+	   }
+	   break;
+     }
+
+     pI830->FirstframeX1 = pI830->FirstframeX0 + CDMPTR.First->HDisplay - 1;
+     pI830->FirstframeY1 = pI830->FirstframeY0 + CDMPTR.First->VDisplay - 1;
+     pScrn2->frameX1   = pScrn2->frameX0   + CDMPTR.Second->HDisplay - 1;
+     pScrn2->frameY1   = pScrn2->frameY0   + CDMPTR.Second->VDisplay - 1;
+
+     /* No need to update pScrn1->frame?1, done above */
+    if (!pI830->pipe == 0) {
+       OUTREG(DSPABASE, pI830->FrontBuffer.Start + ((pI830->FirstframeY0 * pScrn1->displayWidth + pI830->FirstframeX0) * pI830->cpp));
+       OUTREG(DSPBBASE, pI830->FrontBuffer.Start + ((pScrn2->frameY0 * pScrn1->displayWidth + pScrn2->frameX0) * pI830->cpp));
+    } else {
+       OUTREG(DSPBBASE, pI830->FrontBuffer.Start + ((pI830->FirstframeY0 * pScrn1->displayWidth + pI830->FirstframeX0) * pI830->cpp));
+       OUTREG(DSPABASE, pI830->FrontBuffer.Start + ((pScrn2->frameY0 * pScrn1->displayWidth + pScrn2->frameX0) * pI830->cpp));
+    }
+  }
+}
+
+static void
+I830AdjustFrameMerged(int scrnIndex, int x, int y, int flags)
+{
+    ScrnInfoPtr pScrn1 = xf86Screens[scrnIndex];
+    I830Ptr pI830 = I830PTR(pScrn1);
+    ScrnInfoPtr pScrn2 = pI830->pScrn_2;
+    int HTotal = pI830->currentMode->HDisplay;
+    int VTotal = pI830->currentMode->VDisplay;
+    int HMax = HTotal;
+    int VMax = VTotal;
+    int HVirt = pScrn1->virtualX;
+    int VVirt = pScrn1->virtualY;
+    int x1 = x, x2 = x;
+    int y1 = y, y2 = y;
+    int FirstXOffs = 0, FirstYOffs = 0, SecondXOffs = 0, SecondYOffs = 0;
+    int MBXNR1XMAX = 65536, MBXNR1YMAX = 65536, MBXNR2XMAX = 65536, MBXNR2YMAX = 65536;
+
+    if(pI830->DGAactive) {
+       HVirt = pScrn1->displayWidth;
+       VVirt = pScrn1->virtualY;
+    } else {
+       FirstXOffs = pI830->FirstXOffs;
+       FirstYOffs = pI830->FirstYOffs;
+       SecondXOffs = pI830->SecondXOffs;
+       SecondYOffs = pI830->SecondYOffs;
+       MBXNR1XMAX = pI830->MBXNR1XMAX;
+       MBXNR1YMAX = pI830->MBXNR1YMAX;
+       MBXNR2XMAX = pI830->MBXNR2XMAX;
+       MBXNR2YMAX = pI830->MBXNR2YMAX;
+    }
+
+    BOUND(x, 0, HVirt - HTotal);
+    BOUND(y, 0, VVirt - VTotal);
+    BOUND(x1, FirstXOffs, min(HVirt, MBXNR1XMAX + FirstXOffs) - min(HTotal, MBXNR1XMAX) - SecondXOffs);
+    BOUND(y1, FirstYOffs, min(VVirt, MBXNR1YMAX + FirstYOffs) - min(VTotal, MBXNR1YMAX) - SecondYOffs);
+    BOUND(x2, SecondXOffs, min(HVirt, MBXNR2XMAX + SecondXOffs) - min(HTotal, MBXNR2XMAX) - FirstXOffs);
+    BOUND(y2, SecondYOffs, min(VVirt, MBXNR2YMAX + SecondYOffs) - min(VTotal, MBXNR2YMAX) - FirstYOffs);
+
+    switch(SDMPTR(pScrn1).SecondPosition) {
+        case PosLeftOf:
+            pScrn2->frameX0 = x2;
+            BOUND(pScrn2->frameY0,   y2, y2 + min(VMax, MBXNR2YMAX) - CDMPTR.Second->VDisplay);
+            pI830->FirstframeX0 = x1 + CDMPTR.Second->HDisplay;
+            BOUND(pI830->FirstframeY0, y1, y1 + min(VMax, MBXNR1YMAX) - CDMPTR.First->VDisplay);
+            break;
+        case PosRightOf:
+            pI830->FirstframeX0 = x1;
+            BOUND(pI830->FirstframeY0, y1, y1 + min(VMax, MBXNR1YMAX) - CDMPTR.First->VDisplay);
+            pScrn2->frameX0 = x2 + CDMPTR.First->HDisplay;
+            BOUND(pScrn2->frameY0,   y2, y2 + min(VMax, MBXNR2YMAX) - CDMPTR.Second->VDisplay);
+            break;
+        case PosAbove:
+            BOUND(pScrn2->frameX0,   x2, x2 + min(HMax, MBXNR2XMAX) - CDMPTR.Second->HDisplay);
+            pScrn2->frameY0 = y2;
+            BOUND(pI830->FirstframeX0, x1, x1 + min(HMax, MBXNR1XMAX) - CDMPTR.First->HDisplay);
+            pI830->FirstframeY0 = y1 + CDMPTR.Second->VDisplay;
+            break;
+        case PosBelow:
+            BOUND(pI830->FirstframeX0, x1, x1 + min(HMax, MBXNR1XMAX) - CDMPTR.First->HDisplay);
+            pI830->FirstframeY0 = y1;
+            BOUND(pScrn2->frameX0,   x2, x2 + min(HMax, MBXNR2XMAX) - CDMPTR.Second->HDisplay);
+            pScrn2->frameY0 = y2 + CDMPTR.First->VDisplay;
+            break;
+    }
+
+    BOUND(pI830->FirstframeX0, 0, HVirt - CDMPTR.First->HDisplay);
+    BOUND(pI830->FirstframeY0, 0, VVirt - CDMPTR.First->VDisplay);
+    BOUND(pScrn2->frameX0,   0, HVirt - CDMPTR.Second->HDisplay);
+    BOUND(pScrn2->frameY0,   0, VVirt - CDMPTR.Second->VDisplay);
+
+    pScrn1->frameX0 = x;
+    pScrn1->frameY0 = y;
+
+    pI830->FirstframeX1 = pI830->FirstframeX0 + CDMPTR.First->HDisplay - 1;
+    pI830->FirstframeY1 = pI830->FirstframeY0 + CDMPTR.First->VDisplay - 1;
+    pScrn2->frameX1   = pScrn2->frameX0   + CDMPTR.Second->HDisplay - 1;
+    pScrn2->frameY1   = pScrn2->frameY0   + CDMPTR.Second->VDisplay - 1;
+
+    pScrn1->frameX1   = pScrn1->frameX0   + pI830->currentMode->HDisplay  - 1;
+    pScrn1->frameY1   = pScrn1->frameY0   + pI830->currentMode->VDisplay  - 1;
+    pScrn1->frameX1 += FirstXOffs + SecondXOffs;
+    pScrn1->frameY1 += FirstYOffs + SecondYOffs;
+
+    if (!pI830->pipe == 0) {
+       OUTREG(DSPABASE, pI830->FrontBuffer.Start + ((pI830->FirstframeY0 * pScrn1->displayWidth + pI830->FirstframeX0) * pI830->cpp));
+       OUTREG(DSPBBASE, pI830->FrontBuffer.Start + ((pScrn2->frameY0 * pScrn1->displayWidth + pScrn2->frameX0) * pI830->cpp));
+    } else {
+       OUTREG(DSPBBASE, pI830->FrontBuffer.Start + ((pI830->FirstframeY0 * pScrn1->displayWidth + pI830->FirstframeX0) * pI830->cpp));
+       OUTREG(DSPABASE, pI830->FrontBuffer.Start + ((pScrn2->frameY0 * pScrn1->displayWidth + pScrn2->frameX0) * pI830->cpp));
+    }
+}
+
+/* Pseudo-Xinerama extension for MergedFB mode */
+static void
+I830UpdateXineramaScreenInfo(ScrnInfoPtr pScrn1)
+{
+    I830Ptr pI830 = I830PTR(pScrn1);
+    int scrnnum1 = 0, scrnnum2 = 1;
+    int x1=0, x2=0, y1=0, y2=0, h1=0, h2=0, w1=0, w2=0;
+    int realvirtX, realvirtY;
+    DisplayModePtr currentMode, firstMode;
+    Bool infochanged = FALSE;
+    Bool usenonrect = pI830->NonRect;
+    const char *rectxine = "\t... setting up rectangular Xinerama layout\n";
+
+    pI830->MBXNR1XMAX = pI830->MBXNR1YMAX = pI830->MBXNR2XMAX = pI830->MBXNR2YMAX = 65536;
+    pI830->HaveNonRect = pI830->HaveOffsRegions = FALSE;
+
+    if(!pI830->MergedFB) return;
+
+    if(I830noPanoramiXExtension) return;
+
+    if(!I830XineramadataPtr) return;
+
+    if(pI830->SecondIsScrn0) {
+       scrnnum1 = 1;
+       scrnnum2 = 0;
+    }
+
+    /* Attention: Usage of RandR may lead to virtual X and Y dimensions
+     * actually smaller than our MetaModes. To avoid this, we calculate
+     * the max* fields here (and not somewhere else, like in CopyNLink)
+     *
+     * *** Note: RandR is disabled if one of CRTxxOffs is non-zero.
+     */
+
+    /* "Real" virtual: Virtual without the Offset */
+    realvirtX = pScrn1->virtualX - pI830->FirstXOffs - pI830->SecondXOffs;
+    realvirtY = pScrn1->virtualY - pI830->FirstYOffs - pI830->SecondYOffs;
+
+    if((pI830->I830XineramaVX != pScrn1->virtualX) || (pI830->I830XineramaVY != pScrn1->virtualY)) {
+
+       if(!(pScrn1->modes)) return;
+
+       pI830->maxFirst_X1 = pI830->maxFirst_X2 = 0;
+       pI830->maxFirst_Y1 = pI830->maxFirst_Y2 = 0;
+       pI830->maxSecond_X1 = pI830->maxSecond_X2 = 0;
+       pI830->maxSecond_Y1 = pI830->maxSecond_Y2 = 0;
+
+       currentMode = firstMode = pScrn1->modes;
+
+       do {
+
+          DisplayModePtr p = currentMode->next;
+          DisplayModePtr i = ((I830ModePrivatePtr)currentMode->Private)->merged.First;
+          DisplayModePtr j = ((I830ModePrivatePtr)currentMode->Private)->merged.Second;
+          int pos = ((I830ModePrivatePtr)currentMode->Private)->merged.SecondPosition;
+
+          if((currentMode->HDisplay <= realvirtX) && (currentMode->VDisplay <= realvirtY) &&
+	     (i->HDisplay <= realvirtX) && (j->HDisplay <= realvirtX) &&
+	     (i->VDisplay <= realvirtY) && (j->VDisplay <= realvirtY)) {
+
+		if(pI830->maxFirst_X1 == i->HDisplay) {
+		   if(pI830->maxFirst_X2 < j->HDisplay) {
+		      pI830->maxFirst_X2 = j->HDisplay;   /* Widest Second mode displayed with widest CRT1 mode */
+		   }
+		} else if(pI830->maxFirst_X1 < i->HDisplay) {
+		   pI830->maxFirst_X1 = i->HDisplay;      /* Widest CRT1 mode */
+		   pI830->maxFirst_X2 = j->HDisplay;
+		}
+		if(pI830->maxSecond_X2 == j->HDisplay) {
+		   if(pI830->maxSecond_X1 < i->HDisplay) {
+		      pI830->maxSecond_X1 = i->HDisplay;   /* Widest First mode displayed with widest Second mode */
+		   }
+		} else if(pI830->maxSecond_X2 < j->HDisplay) {
+		   pI830->maxSecond_X2 = j->HDisplay;      /* Widest Second mode */
+		   pI830->maxSecond_X1 = i->HDisplay;
+		}
+		if(pI830->maxFirst_Y1 == i->VDisplay) {   /* Same as above, but tallest instead of widest */
+		   if(pI830->maxFirst_Y2 < j->VDisplay) {
+		      pI830->maxFirst_Y2 = j->VDisplay;
+		   }
+		} else if(pI830->maxFirst_Y1 < i->VDisplay) {
+		   pI830->maxFirst_Y1 = i->VDisplay;
+		   pI830->maxFirst_Y2 = j->VDisplay;
+		}
+		if(pI830->maxSecond_Y2 == j->VDisplay) {
+		   if(pI830->maxSecond_Y1 < i->VDisplay) {
+		      pI830->maxSecond_Y1 = i->VDisplay;
+		   }
+		} else if(pI830->maxSecond_Y2 < j->VDisplay) {
+		   pI830->maxSecond_Y2 = j->VDisplay;
+		   pI830->maxSecond_Y1 = i->VDisplay;
+		}
+	  }
+	  currentMode = p;
+
+       } while((currentMode) && (currentMode != firstMode));
+
+       pI830->I830XineramaVX = pScrn1->virtualX;
+       pI830->I830XineramaVY = pScrn1->virtualY;
+       infochanged = TRUE;
+
+    }
+
+    if((usenonrect) && pI830->maxFirst_X1) {
+       switch(pI830->SecondPosition) {
+       case PosLeftOf:
+       case PosRightOf:
+	  if((pI830->maxFirst_Y1 != realvirtY) && (pI830->maxSecond_Y2 != realvirtY)) {
+	     usenonrect = FALSE;
+	  }
+	  break;
+       case PosAbove:
+       case PosBelow:
+	  if((pI830->maxFirst_X1 != realvirtX) && (pI830->maxSecond_X2 != realvirtX)) {
+	     usenonrect = FALSE;
+	  }
+	  break;
+       }
+       if(infochanged && !usenonrect) {
+	  xf86DrvMsg(pScrn1->scrnIndex, X_INFO,
+			"Virtual screen size does not match maximum display modes...\n");
+	  xf86DrvMsg(pScrn1->scrnIndex, X_INFO, rectxine);
+
+       }
+    } else if(infochanged && usenonrect) {
+       usenonrect = FALSE;
+       xf86DrvMsg(pScrn1->scrnIndex, X_INFO,
+		"Only clone modes available for this virtual screen size...\n");
+       xf86DrvMsg(pScrn1->scrnIndex, X_INFO, rectxine);
+    }
+
+    if(pI830->maxFirst_X1) {		/* Means we have at least one non-clone mode */
+       switch(pI830->SecondPosition) {
+       case PosLeftOf:
+	  x1 = min(pI830->maxFirst_X2, pScrn1->virtualX - pI830->maxFirst_X1);
+	  if(x1 < 0) x1 = 0;
+	  y1 = pI830->FirstYOffs;
+	  w1 = pScrn1->virtualX - x1;
+	  h1 = realvirtY;
+	  if((usenonrect) && (pI830->maxFirst_Y1 != realvirtY)) {
+	     h1 = pI830->MBXNR1YMAX = pI830->maxFirst_Y1;
+	     pI830->NonRectDead.x0 = x1;
+	     pI830->NonRectDead.x1 = x1 + w1 - 1;
+	     pI830->NonRectDead.y0 = y1 + h1;
+	     pI830->NonRectDead.y1 = pScrn1->virtualY - 1;
+	     pI830->HaveNonRect = TRUE;
+	  }
+	  x2 = 0;
+	  y2 = pI830->SecondYOffs;
+	  w2 = max(pI830->maxSecond_X2, pScrn1->virtualX - pI830->maxSecond_X1);
+	  if(w2 > pScrn1->virtualX) w2 = pScrn1->virtualX;
+	  h2 = realvirtY;
+	  if((usenonrect) && (pI830->maxSecond_Y2 != realvirtY)) {
+	     h2 = pI830->MBXNR2YMAX = pI830->maxSecond_Y2;
+	     pI830->NonRectDead.x0 = x2;
+	     pI830->NonRectDead.x1 = x2 + w2 - 1;
+	     pI830->NonRectDead.y0 = y2 + h2;
+	     pI830->NonRectDead.y1 = pScrn1->virtualY - 1;
+	     pI830->HaveNonRect = TRUE;
+	  }
+	  break;
+       case PosRightOf:
+	  x1 = 0;
+	  y1 = pI830->FirstYOffs;
+	  w1 = max(pI830->maxFirst_X1, pScrn1->virtualX - pI830->maxFirst_X2);
+	  if(w1 > pScrn1->virtualX) w1 = pScrn1->virtualX;
+	  h1 = realvirtY;
+	  if((usenonrect) && (pI830->maxFirst_Y1 != realvirtY)) {
+	     h1 = pI830->MBXNR1YMAX = pI830->maxFirst_Y1;
+	     pI830->NonRectDead.x0 = x1;
+	     pI830->NonRectDead.x1 = x1 + w1 - 1;
+	     pI830->NonRectDead.y0 = y1 + h1;
+	     pI830->NonRectDead.y1 = pScrn1->virtualY - 1;
+	     pI830->HaveNonRect = TRUE;
+	  }
+	  x2 = min(pI830->maxSecond_X1, pScrn1->virtualX - pI830->maxSecond_X2);
+	  if(x2 < 0) x2 = 0;
+	  y2 = pI830->SecondYOffs;
+	  w2 = pScrn1->virtualX - x2;
+	  h2 = realvirtY;
+	  if((usenonrect) && (pI830->maxSecond_Y2 != realvirtY)) {
+	     h2 = pI830->MBXNR2YMAX = pI830->maxSecond_Y2;
+	     pI830->NonRectDead.x0 = x2;
+	     pI830->NonRectDead.x1 = x2 + w2 - 1;
+	     pI830->NonRectDead.y0 = y2 + h2;
+	     pI830->NonRectDead.y1 = pScrn1->virtualY - 1;
+	     pI830->HaveNonRect = TRUE;
+	  }
+	  break;
+       case PosAbove:
+	  x1 = pI830->FirstXOffs;
+	  y1 = min(pI830->maxFirst_Y2, pScrn1->virtualY - pI830->maxFirst_Y1);
+	  if(y1 < 0) y1 = 0;
+	  w1 = realvirtX;
+	  h1 = pScrn1->virtualY - y1;
+	  if((usenonrect) && (pI830->maxFirst_X1 != realvirtX)) {
+	     w1 = pI830->MBXNR1XMAX = pI830->maxFirst_X1;
+	     pI830->NonRectDead.x0 = x1 + w1;
+	     pI830->NonRectDead.x1 = pScrn1->virtualX - 1;
+	     pI830->NonRectDead.y0 = y1;
+	     pI830->NonRectDead.y1 = y1 + h1 - 1;
+	     pI830->HaveNonRect = TRUE;
+	  }
+	  x2 = pI830->SecondXOffs;
+	  y2 = 0;
+	  w2 = realvirtX;
+	  h2 = max(pI830->maxSecond_Y2, pScrn1->virtualY - pI830->maxSecond_Y1);
+	  if(h2 > pScrn1->virtualY) h2 = pScrn1->virtualY;
+	  if((usenonrect) && (pI830->maxSecond_X2 != realvirtX)) {
+	     w2 = pI830->MBXNR2XMAX = pI830->maxSecond_X2;
+	     pI830->NonRectDead.x0 = x2 + w2;
+	     pI830->NonRectDead.x1 = pScrn1->virtualX - 1;
+	     pI830->NonRectDead.y0 = y2;
+	     pI830->NonRectDead.y1 = y2 + h2 - 1;
+	     pI830->HaveNonRect = TRUE;
+	  }
+	  break;
+       case PosBelow:
+	  x1 = pI830->FirstXOffs;
+	  y1 = 0;
+	  w1 = realvirtX;
+	  h1 = max(pI830->maxFirst_Y1, pScrn1->virtualY - pI830->maxFirst_Y2);
+	  if(h1 > pScrn1->virtualY) h1 = pScrn1->virtualY;
+	  if((usenonrect) && (pI830->maxFirst_X1 != realvirtX)) {
+	     w1 = pI830->MBXNR1XMAX = pI830->maxFirst_X1;
+	     pI830->NonRectDead.x0 = x1 + w1;
+	     pI830->NonRectDead.x1 = pScrn1->virtualX - 1;
+	     pI830->NonRectDead.y0 = y1;
+	     pI830->NonRectDead.y1 = y1 + h1 - 1;
+	     pI830->HaveNonRect = TRUE;
+	  }
+	  x2 = pI830->SecondXOffs;
+	  y2 = min(pI830->maxSecond_Y1, pScrn1->virtualY - pI830->maxSecond_Y2);
+	  if(y2 < 0) y2 = 0;
+	  w2 = realvirtX;
+	  h2 = pScrn1->virtualY - y2;
+	  if((usenonrect) && (pI830->maxSecond_X2 != realvirtX)) {
+	     w2 = pI830->MBXNR2XMAX = pI830->maxSecond_X2;
+	     pI830->NonRectDead.x0 = x2 + w2;
+	     pI830->NonRectDead.x1 = pScrn1->virtualX - 1;
+	     pI830->NonRectDead.y0 = y2;
+	     pI830->NonRectDead.y1 = y2 + h2 - 1;
+	     pI830->HaveNonRect = TRUE;
+	  }
+       default:
+	  break;
+       }
+
+       switch(pI830->SecondPosition) {
+       case PosLeftOf:
+       case PosRightOf:
+	  if(pI830->FirstYOffs) {
+	     pI830->OffDead1.x0 = x1;
+	     pI830->OffDead1.x1 = x1 + w1 - 1;
+	     pI830->OffDead1.y0 = 0;
+	     pI830->OffDead1.y1 = y1 - 1;
+	     pI830->OffDead2.x0 = x2;
+	     pI830->OffDead2.x1 = x2 + w2 - 1;
+	     pI830->OffDead2.y0 = y2 + h2;
+	     pI830->OffDead2.y1 = pScrn1->virtualY - 1;
+	     pI830->HaveOffsRegions = TRUE;
+	  } else if(pI830->SecondYOffs) {
+	     pI830->OffDead1.x0 = x2;
+	     pI830->OffDead1.x1 = x2 + w2 - 1;
+	     pI830->OffDead1.y0 = 0;
+	     pI830->OffDead1.y1 = y2 - 1;
+	     pI830->OffDead2.x0 = x1;
+	     pI830->OffDead2.x1 = x1 + w1 - 1;
+	     pI830->OffDead2.y0 = y1 + h1;
+	     pI830->OffDead2.y1 = pScrn1->virtualY - 1;
+	     pI830->HaveOffsRegions = TRUE;
+	  }
+	  break;
+       case PosAbove:
+       case PosBelow:
+	  if(pI830->FirstXOffs) {
+	     pI830->OffDead1.x0 = x2 + w2;
+	     pI830->OffDead1.x1 = pScrn1->virtualX - 1;
+	     pI830->OffDead1.y0 = y2;
+	     pI830->OffDead1.y1 = y2 + h2 - 1;
+	     pI830->OffDead2.x0 = 0;
+	     pI830->OffDead2.x1 = x1 - 1;
+	     pI830->OffDead2.y0 = y1;
+	     pI830->OffDead2.y1 = y1 + h1 - 1;
+	     pI830->HaveOffsRegions = TRUE;
+	  } else if(pI830->SecondXOffs) {
+	     pI830->OffDead1.x0 = x1 + w1;
+	     pI830->OffDead1.x1 = pScrn1->virtualX - 1;
+	     pI830->OffDead1.y0 = y1;
+	     pI830->OffDead1.y1 = y1 + h1 - 1;
+	     pI830->OffDead2.x0 = 0;
+	     pI830->OffDead2.x1 = x2 - 1;
+	     pI830->OffDead2.y0 = y2;
+	     pI830->OffDead2.y1 = y2 + h2 - 1;
+	     pI830->HaveOffsRegions = TRUE;
+	  }
+       default:
+	  break;
+       }
+
+    }
+
+    I830XineramadataPtr[scrnnum1].x = x1;
+    I830XineramadataPtr[scrnnum1].y = y1;
+    I830XineramadataPtr[scrnnum1].width = w1;
+    I830XineramadataPtr[scrnnum1].height = h1;
+    I830XineramadataPtr[scrnnum2].x = x2;
+    I830XineramadataPtr[scrnnum2].y = y2;
+    I830XineramadataPtr[scrnnum2].width = w2;
+    I830XineramadataPtr[scrnnum2].height = h2;
+
+    if(infochanged) {
+       xf86DrvMsg(pScrn1->scrnIndex, X_INFO,
+	  "Pseudo-Xinerama: First (Screen %d) (%d,%d)-(%d,%d)\n",
+	  scrnnum1, x1, y1, w1+x1-1, h1+y1-1);
+       xf86DrvMsg(pScrn1->scrnIndex, X_INFO,
+	  "Pseudo-Xinerama: Second (Screen %d) (%d,%d)-(%d,%d)\n",
+	  scrnnum2, x2, y2, w2+x2-1, h2+y2-1);
+       if(pI830->HaveNonRect) {
+	  xf86DrvMsg(pScrn1->scrnIndex, X_INFO,
+		"Pseudo-Xinerama: Inaccessible area (%d,%d)-(%d,%d)\n",
+		pI830->NonRectDead.x0, pI830->NonRectDead.y0,
+		pI830->NonRectDead.x1, pI830->NonRectDead.y1);
+       }
+       if(pI830->HaveOffsRegions) {
+	  xf86DrvMsg(pScrn1->scrnIndex, X_INFO,
+		"Pseudo-Xinerama: Inaccessible offset area (%d,%d)-(%d,%d)\n",
+		pI830->OffDead1.x0, pI830->OffDead1.y0,
+		pI830->OffDead1.x1, pI830->OffDead1.y1);
+	  xf86DrvMsg(pScrn1->scrnIndex, X_INFO,
+		"Pseudo-Xinerama: Inaccessible offset area (%d,%d)-(%d,%d)\n",
+		pI830->OffDead2.x0, pI830->OffDead2.y0,
+		pI830->OffDead2.x1, pI830->OffDead2.y1);
+       }
+       if(pI830->HaveNonRect || pI830->HaveOffsRegions) {
+	  xf86DrvMsg(pScrn1->scrnIndex, X_INFO,
+		"Mouse restriction for inaccessible areas is %s\n",
+		pI830->MouseRestrictions ? "enabled" : "disabled");
+       }
+    }
+}
+
+/* Proc */
+
+int
+I830ProcXineramaQueryVersion(ClientPtr client)
+{
+    xPanoramiXQueryVersionReply	  rep;
+    register int		  n;
+
+    REQUEST_SIZE_MATCH(xPanoramiXQueryVersionReq);
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    rep.majorVersion = 1;
+    rep.minorVersion = 0;
+    if(client->swapped) {
+        swaps(&rep.sequenceNumber, n);
+        swapl(&rep.length, n);
+        swaps(&rep.majorVersion, n);
+        swaps(&rep.minorVersion, n);
+    }
+    WriteToClient(client, sizeof(xPanoramiXQueryVersionReply), (char *)&rep);
+    return (client->noClientException);
+}
+
+int
+I830ProcXineramaGetState(ClientPtr client)
+{
+    REQUEST(xPanoramiXGetStateReq);
+    WindowPtr			pWin;
+    xPanoramiXGetStateReply	rep;
+    register int		n;
+
+    REQUEST_SIZE_MATCH(xPanoramiXGetStateReq);
+    pWin = LookupWindow(stuff->window, client);
+    if(!pWin) return BadWindow;
+
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    rep.state = !I830noPanoramiXExtension;
+    if(client->swapped) {
+       swaps (&rep.sequenceNumber, n);
+       swapl (&rep.length, n);
+       swaps (&rep.state, n);
+    }
+    WriteToClient(client, sizeof(xPanoramiXGetStateReply), (char *)&rep);
+    return client->noClientException;
+}
+
+int
+I830ProcXineramaGetScreenCount(ClientPtr client)
+{
+    REQUEST(xPanoramiXGetScreenCountReq);
+    WindowPtr				pWin;
+    xPanoramiXGetScreenCountReply	rep;
+    register int			n;
+
+    REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq);
+    pWin = LookupWindow(stuff->window, client);
+    if(!pWin) return BadWindow;
+
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    rep.ScreenCount = I830XineramaNumScreens;
+    if(client->swapped) {
+       swaps(&rep.sequenceNumber, n);
+       swapl(&rep.length, n);
+       swaps(&rep.ScreenCount, n);
+    }
+    WriteToClient(client, sizeof(xPanoramiXGetScreenCountReply), (char *)&rep);
+    return client->noClientException;
+}
+
+int
+I830ProcXineramaGetScreenSize(ClientPtr client)
+{
+    REQUEST(xPanoramiXGetScreenSizeReq);
+    WindowPtr				pWin;
+    xPanoramiXGetScreenSizeReply	rep;
+    register int			n;
+
+    REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq);
+    pWin = LookupWindow (stuff->window, client);
+    if(!pWin)  return BadWindow;
+
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    rep.width  = I830XineramadataPtr[stuff->screen].width;
+    rep.height = I830XineramadataPtr[stuff->screen].height;
+    if(client->swapped) {
+       swaps(&rep.sequenceNumber, n);
+       swapl(&rep.length, n);
+       swaps(&rep.width, n);
+       swaps(&rep.height, n);
+    }
+    WriteToClient(client, sizeof(xPanoramiXGetScreenSizeReply), (char *)&rep);
+    return client->noClientException;
+}
+
+int
+I830ProcXineramaIsActive(ClientPtr client)
+{
+    xXineramaIsActiveReply	rep;
+
+    REQUEST_SIZE_MATCH(xXineramaIsActiveReq);
+
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    rep.state = !I830noPanoramiXExtension;
+    if(client->swapped) {
+	register int n;
+	swaps(&rep.sequenceNumber, n);
+	swapl(&rep.length, n);
+	swapl(&rep.state, n);
+    }
+    WriteToClient(client, sizeof(xXineramaIsActiveReply), (char *) &rep);
+    return client->noClientException;
+}
+
+int
+I830ProcXineramaQueryScreens(ClientPtr client)
+{
+    xXineramaQueryScreensReply	rep;
+
+    REQUEST_SIZE_MATCH(xXineramaQueryScreensReq);
+
+    rep.type = X_Reply;
+    rep.sequenceNumber = client->sequence;
+    rep.number = (I830noPanoramiXExtension) ? 0 : I830XineramaNumScreens;
+    rep.length = rep.number * sz_XineramaScreenInfo >> 2;
+    if(client->swapped) {
+       register int n;
+       swaps(&rep.sequenceNumber, n);
+       swapl(&rep.length, n);
+       swapl(&rep.number, n);
+    }
+    WriteToClient(client, sizeof(xXineramaQueryScreensReply), (char *)&rep);
+
+    if(!I830noPanoramiXExtension) {
+       xXineramaScreenInfo scratch;
+       int i;
+
+       for(i = 0; i < I830XineramaNumScreens; i++) {
+	  scratch.x_org  = I830XineramadataPtr[i].x;
+	  scratch.y_org  = I830XineramadataPtr[i].y;
+	  scratch.width  = I830XineramadataPtr[i].width;
+	  scratch.height = I830XineramadataPtr[i].height;
+	  if(client->swapped) {
+	     register int n;
+	     swaps(&scratch.x_org, n);
+	     swaps(&scratch.y_org, n);
+	     swaps(&scratch.width, n);
+	     swaps(&scratch.height, n);
+	  }
+	  WriteToClient(client, sz_XineramaScreenInfo, (char *)&scratch);
+       }
+    }
+
+    return client->noClientException;
+}
+
+static int
+I830ProcXineramaDispatch(ClientPtr client)
+{
+    REQUEST(xReq);
+    switch (stuff->data) {
+	case X_PanoramiXQueryVersion:
+	     return I830ProcXineramaQueryVersion(client);
+	case X_PanoramiXGetState:
+	     return I830ProcXineramaGetState(client);
+	case X_PanoramiXGetScreenCount:
+	     return I830ProcXineramaGetScreenCount(client);
+	case X_PanoramiXGetScreenSize:
+	     return I830ProcXineramaGetScreenSize(client);
+	case X_XineramaIsActive:
+	     return I830ProcXineramaIsActive(client);
+	case X_XineramaQueryScreens:
+	     return I830ProcXineramaQueryScreens(client);
+    }
+    return BadRequest;
+}
+
+/* SProc */
+
+static int
+I830SProcXineramaQueryVersion (ClientPtr client)
+{
+    REQUEST(xPanoramiXQueryVersionReq);
+    register int n;
+    swaps(&stuff->length,n);
+    REQUEST_SIZE_MATCH (xPanoramiXQueryVersionReq);
+    return I830ProcXineramaQueryVersion(client);
+}
+
+static int
+I830SProcXineramaGetState(ClientPtr client)
+{
+    REQUEST(xPanoramiXGetStateReq);
+    register int n;
+    swaps (&stuff->length, n);
+    REQUEST_SIZE_MATCH(xPanoramiXGetStateReq);
+    return I830ProcXineramaGetState(client);
+}
+
+static int
+I830SProcXineramaGetScreenCount(ClientPtr client)
+{
+    REQUEST(xPanoramiXGetScreenCountReq);
+    register int n;
+    swaps (&stuff->length, n);
+    REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq);
+    return I830ProcXineramaGetScreenCount(client);
+}
+
+static int
+I830SProcXineramaGetScreenSize(ClientPtr client)
+{
+    REQUEST(xPanoramiXGetScreenSizeReq);
+    register int n;
+    swaps (&stuff->length, n);
+    REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq);
+    return I830ProcXineramaGetScreenSize(client);
+}
+
+static int
+I830SProcXineramaIsActive(ClientPtr client)
+{
+    REQUEST(xXineramaIsActiveReq);
+    register int n;
+    swaps (&stuff->length, n);
+    REQUEST_SIZE_MATCH(xXineramaIsActiveReq);
+    return I830ProcXineramaIsActive(client);
+}
+
+static int
+I830SProcXineramaQueryScreens(ClientPtr client)
+{
+    REQUEST(xXineramaQueryScreensReq);
+    register int n;
+    swaps (&stuff->length, n);
+    REQUEST_SIZE_MATCH(xXineramaQueryScreensReq);
+    return I830ProcXineramaQueryScreens(client);
+}
+
+int
+I830SProcXineramaDispatch(ClientPtr client)
+{
+    REQUEST(xReq);
+    switch (stuff->data) {
+	case X_PanoramiXQueryVersion:
+	     return I830SProcXineramaQueryVersion(client);
+	case X_PanoramiXGetState:
+	     return I830SProcXineramaGetState(client);
+	case X_PanoramiXGetScreenCount:
+	     return I830SProcXineramaGetScreenCount(client);
+	case X_PanoramiXGetScreenSize:
+	     return I830SProcXineramaGetScreenSize(client);
+	case X_XineramaIsActive:
+	     return I830SProcXineramaIsActive(client);
+	case X_XineramaQueryScreens:
+	     return I830SProcXineramaQueryScreens(client);
+    }
+    return BadRequest;
+}
+
+static void
+I830XineramaResetProc(ExtensionEntry* extEntry)
+{
+    /* Called by CloseDownExtensions() */
+    if(I830XineramadataPtr) {
+       Xfree(I830XineramadataPtr);
+       I830XineramadataPtr = NULL;
+    }
+}
+
+static void
+I830XineramaExtensionInit(ScrnInfoPtr pScrn)
+{
+    I830Ptr	pI830 = I830PTR(pScrn);
+    Bool	success = FALSE;
+
+    if(!(I830XineramadataPtr)) {
+
+       if(!pI830->MergedFB) {
+	  I830noPanoramiXExtension = TRUE;
+	  pI830->MouseRestrictions = FALSE;
+	  return;
+       }
+
+#ifdef PANORAMIX
+       if(!noPanoramiXExtension) {
+	  xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+	     "Xinerama active, not initializing Intel Pseudo-Xinerama\n");
+	  I830noPanoramiXExtension = TRUE;
+	  pI830->MouseRestrictions = FALSE;
+	  return;
+       }
+#endif
+
+       if(I830noPanoramiXExtension) {
+	  xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+	      "Intel Pseudo-Xinerama disabled\n");
+	  pI830->MouseRestrictions = FALSE;
+	  return;
+       }
+
+       I830XineramaNumScreens = 2;
+
+       while(I830XineramaGeneration != serverGeneration) {
+
+	  pI830->XineramaExtEntry = AddExtension(PANORAMIX_PROTOCOL_NAME, 0,0,
+					I830ProcXineramaDispatch,
+					I830SProcXineramaDispatch,
+					I830XineramaResetProc,
+					StandardMinorOpcode);
+
+	  if(!pI830->XineramaExtEntry) break;
+
+	  if(!(I830XineramadataPtr = (I830XineramaData *)
+	        xcalloc(I830XineramaNumScreens, sizeof(I830XineramaData)))) break;
+
+	  I830XineramaGeneration = serverGeneration;
+	  success = TRUE;
+       }
+
+       if(!success) {
+          xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+	      "Failed to initialize Intel Pseudo-Xinerama extension\n");
+	  I830noPanoramiXExtension = TRUE;
+	  pI830->MouseRestrictions = FALSE;
+	  return;
+       }
+
+       xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+	  "Intel Pseudo-Xinerama extension initialized\n");
+
+       pI830->I830XineramaVX = 0;
+       pI830->I830XineramaVY = 0;
+
+    }
+
+    I830UpdateXineramaScreenInfo(pScrn);
+
+}
+
 static void
 I830BIOSProbeDDC(ScrnInfoPtr pScrn, int index)
 {
@@ -926,7 +2556,7 @@ SetPipeAccess(ScrnInfoPtr pScrn)
    I830Ptr pI830 = I830PTR(pScrn);
 
    /* Don't try messing with the pipe, unless we're dual head */
-   if (xf86IsEntityShared(pScrn->entityList[0]) || pI830->Clone || pI830->origPipe != pI830->pipe) {
+   if (xf86IsEntityShared(pScrn->entityList[0]) || pI830->Clone || pI830->MergedFB || pI830->origPipe != pI830->pipe) {
       if (!SetBIOSPipe(pScrn, pI830->pipe))
          return FALSE;
    }
@@ -951,10 +2581,12 @@ I830Set640x480(ScrnInfoPtr pScrn)
 	 m = 0x50;
 	 break;
    }
+
    m |= (1 << 15) | (1 << 14);
    if (VBESetVBEMode(pI830->pVbe, m, NULL))
 	   return TRUE;
 
+
    /* if the first failed, let's try the next - usually 800x600 */
    m = 0x32;
    switch (pScrn->depth) {
@@ -967,6 +2599,7 @@ I830Set640x480(ScrnInfoPtr pScrn)
 	 break;
    }
    m |= (1 << 15) | (1 << 14);
+
    if (VBESetVBEMode(pI830->pVbe, m, NULL))
 	   return TRUE;
 
@@ -1262,7 +2895,7 @@ static const char *displayDevices[] = {
    "TV",
    "DFP (digital flat panel)",
    "LFP (local flat panel)",
-   "CRT2 (second CRT)",
+   "Second (second CRT)",
    "TV2 (second TV)",
    "DFP2 (second digital flat panel)",
    "LFP2 (second local flat panel)",
@@ -2094,6 +3727,7 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int f
    int DDCclock = 0;
    char *s;
    DisplayModePtr p, pMon;
+   xf86MonPtr monitor = NULL;
    pointer pDDCModule = NULL, pVBEModule = NULL;
    Bool enable;
    const char *chipname;
@@ -2505,6 +4139,12 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int f
          pI830->fixedPipe = 1;
    }
 
+   pI830->MergedFB =
+      xf86ReturnOptValBool(pI830->Options, OPTION_MERGEDFB, FALSE);
+
+   pI830->IntelXinerama =
+      xf86ReturnOptValBool(pI830->Options, OPTION_INTELXINERAMA, TRUE);
+
    pI830->MonType1 = PIPE_NONE;
    pI830->MonType2 = PIPE_NONE;
    pI830->specifiedMonitor = FALSE;
@@ -2531,7 +4171,7 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int f
                pI830->MonType1 |= PIPE_DFP;
             else if (strcmp(sub, "LFP") == 0)
                pI830->MonType1 |= PIPE_LFP;
-            else if (strcmp(sub, "CRT2") == 0)
+            else if (strcmp(sub, "Second") == 0)
                pI830->MonType1 |= PIPE_CRT2;
             else if (strcmp(sub, "TV2") == 0)
                pI830->MonType1 |= PIPE_TV2;
@@ -2560,7 +4200,7 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int f
                pI830->MonType2 |= PIPE_DFP;
             else if (strcmp(sub, "LFP") == 0)
                pI830->MonType2 |= PIPE_LFP;
-            else if (strcmp(sub, "CRT2") == 0)
+            else if (strcmp(sub, "Second") == 0)
                pI830->MonType2 |= PIPE_CRT2;
             else if (strcmp(sub, "TV2") == 0)
                pI830->MonType2 |= PIPE_TV2;
@@ -2591,7 +4231,8 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int f
       pI830->specifiedMonitor = TRUE;
    }
 
-   if (xf86ReturnOptValBool(pI830->Options, OPTION_CLONE, FALSE)) {
+   if (!pI830->MergedFB &&
+       xf86ReturnOptValBool(pI830->Options, OPTION_CLONE, FALSE)) {
       if (pI830->availablePipes == 1) {
          xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 
  		 "Can't enable Clone Mode because this is a single pipe device\n");
@@ -2622,17 +4263,18 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int f
       return FALSE;
    }
 
-   if ((pI830->entityPrivate && I830IsPrimary(pScrn)) || pI830->Clone) {
+   if ((pI830->entityPrivate && I830IsPrimary(pScrn)) || pI830->Clone ||
+	pI830->MergedFB) {
       if ((!xf86GetOptValString(pI830->Options, OPTION_MONITOR_LAYOUT))) {
 	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "You must have a MonitorLayout "
-	 		"defined for use in a DualHead or Clone setup.\n");
+	 		"defined for use in a DualHead, Clone or MergedFB setup.\n");
          PreInitCleanup(pScrn);
          return FALSE;
       }
          
       if (pI830->MonType1 == PIPE_NONE || pI830->MonType2 == PIPE_NONE) {
          xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Monitor 1 or Monitor 2 "
-	 		"cannot be type NONE in Dual or Clone setup.\n");
+	 		"cannot be type NONE in DualHead, Clone or MergedFB setup.\n");
          PreInitCleanup(pScrn);
          return FALSE;
       }
@@ -2860,6 +4502,80 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int f
    }
 #endif
 
+   if (pI830->MergedFB) {
+      pI830->pScrn_2 = xalloc(sizeof(ScrnInfoRec));
+
+      if(!pI830->pScrn_2) {
+	 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Failed to allocate memory for MergedFB mode. Disabling.\n");
+	 pI830->MergedFB = FALSE;
+      } else {
+         memcpy(pI830->pScrn_2, pScrn, sizeof(ScrnInfoRec));
+      }
+      if((s = (char *)xf86GetOptValString(pI830->Options, OPTION_SECONDPOSITION))) {
+	 int result;
+	 int ival;
+	 Bool valid = FALSE;
+	 char *tempstr = xalloc(strlen(s) + 1);
+	 result = sscanf(s, "%s %d", tempstr, &ival);
+	 if(result >= 1) {
+ 	    if(!xf86NameCmp(tempstr,"LeftOf")) {
+	       pI830->SecondPosition = PosLeftOf;
+	       valid = TRUE;
+	       if(result == 2) {
+	          if(ival < 0) pI830->FirstYOffs = -ival;
+	          else pI830->SecondYOffs = ival;
+	       }
+	       pI830->SecondIsScrn0 = TRUE;
+	    } else if(!xf86NameCmp(tempstr,"RightOf")) {
+	       pI830->SecondPosition = PosRightOf;
+	       valid = TRUE;
+	       if(result == 2) {
+	          if(ival < 0) pI830->FirstYOffs = -ival;
+	          else pI830->SecondYOffs = ival;
+	       }
+	       pI830->SecondIsScrn0 = FALSE;
+ 	    } else if(!xf86NameCmp(tempstr,"Above")) {
+	       pI830->SecondPosition = PosAbove;
+	       valid = TRUE;
+	       if(result == 2) {
+	          if(ival < 0) pI830->FirstXOffs = -ival;
+	          else pI830->SecondXOffs = ival;
+	       }
+	       pI830->SecondIsScrn0 = FALSE;
+	    } else if(!xf86NameCmp(tempstr,"Below")) {
+	       pI830->SecondPosition = PosBelow;
+  	       valid = TRUE;
+	       if(result == 2) {
+	          if(ival < 0) pI830->FirstXOffs = -ival;
+	          else pI830->SecondXOffs = ival;
+	       }
+	       pI830->SecondIsScrn0 = TRUE;
+	    }
+         }
+         if(!valid) {
+  	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+		    "Valid parameters are: \"RightOf\", \"LeftOf\", \"Above\" or \"Below\"\n");
+         }
+         xfree(tempstr);
+      }
+      if((s = (char *)xf86GetOptValString(pI830->Options, OPTION_METAMODES))) {
+         pI830->MetaModes = xalloc(strlen(s) + 1);
+	 if(pI830->MetaModes) 
+	    memcpy(pI830->MetaModes, s, strlen(s) + 1);
+      }
+      if((s = (char *)xf86GetOptValString(pI830->Options, OPTION_SECONDHSYNC))) {
+         pI830->SecondHSync = xalloc(strlen(s) + 1);
+	 if(pI830->SecondHSync)
+	    memcpy(pI830->SecondHSync, s, strlen(s) + 1);
+      }
+      if((s = (char *)xf86GetOptValString(pI830->Options, OPTION_SECONDVREFRESH))) {
+	 pI830->SecondVRefresh = xalloc(strlen(s) + 1);
+	 if(pI830->SecondVRefresh) 
+	    memcpy(pI830->SecondVRefresh, s, strlen(s) + 1);
+      }
+   }
+
+
    /*
     * If the driver can do gamma correction, it should call xf86SetGamma() here.
     */
@@ -2927,7 +4643,8 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int f
 
       /* Override */
       if (pI830->fixedPipe != -1) {
-         if (xf86IsEntityShared(pScrn->entityList[0]) || pI830->Clone) {
+         if (xf86IsEntityShared(pScrn->entityList[0]) || pI830->Clone || 
+	     pI830->MergedFB) {
             pI830->pipe = pI830->fixedPipe; 
             xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 	        "Fixed Pipe setting primary to pipe %s.\n", 
@@ -2949,9 +4666,11 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int f
    
       pI830->operatingDevices = (pI830->MonType2 << 8) | pI830->MonType1;
 
-      if (!xf86IsEntityShared(pScrn->entityList[0]) && !pI830->Clone) {
-	  /* If we're not dual head or clone, turn off the second head,
-          * if monitorlayout is also specified. */
+      if (!xf86IsEntityShared(pScrn->entityList[0]) && !pI830->Clone &&
+	  !pI830->MergedFB) {
+	  /* If we're not dual head, clone or mergedfb, turn off the
+           * second head if monitorlayout is also specified. 
+	   */
 
          if (pI830->pipe == 0)
             pI830->operatingDevices = pI830->MonType1;
@@ -3103,12 +4822,74 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int f
 
    pDDCModule = xf86LoadSubModule(pScrn, "ddc");
 
-   pI830->vesa->monitor = vbeDoEDID(pI830->pVbe, pDDCModule);
+   monitor = vbeDoEDID(pI830->pVbe, pDDCModule);
 
-   if ((pScrn->monitor->DDC = pI830->vesa->monitor) != NULL) {
-      xf86PrintEDID(pI830->vesa->monitor);
-      xf86SetDDCproperties(pScrn, pI830->vesa->monitor);
+   if ((pScrn->monitor->DDC = monitor) != NULL) {
+      xf86PrintEDID(monitor);
+      xf86SetDDCproperties(pScrn, monitor);
+   }
+
+   if(pI830->MergedFB) {
+      pI830->pScrn_2->monitor = xalloc(sizeof(MonRec));
+      if(pI830->pScrn_2->monitor) {
+	 DisplayModePtr tempm = NULL, currentm = NULL, newm = NULL;
+	 memcpy(pI830->pScrn_2->monitor, pScrn->monitor, sizeof(MonRec));
+	 pI830->pScrn_2->monitor->DDC = NULL;
+	 pI830->pScrn_2->monitor->Modes = NULL;
+	 pI830->pScrn_2->monitor->id = (char *)SecondMonitorName;
+	 tempm = pScrn->monitor->Modes;
+	 while(tempm) {
+	    if(!(newm = xalloc(sizeof(DisplayModeRec)))) break;
+	    memcpy(newm, tempm, sizeof(DisplayModeRec));
+	    if(!(newm->name = xalloc(strlen(tempm->name) + 1))) {
+	       xfree(newm);
+	       break;
+	    }
+	    strcpy(newm->name, tempm->name);
+	    if(!pI830->pScrn_2->monitor->Modes) 
+	       pI830->pScrn_2->monitor->Modes = newm;
+	    if(currentm) {
+	       currentm->next = newm;
+	       newm->prev = currentm;
+	    }
+	    currentm = newm;
+	    tempm = tempm->next;
+	 }
+	 if(pI830->SecondHSync) {
+	    pI830->pScrn_2->monitor->nHsync =
+	    	I830StrToRanges(pI830->pScrn_2->monitor->hsync, pI830->SecondHSync, MAX_HSYNC);
+	 }
+	 if(pI830->SecondVRefresh) {
+	    pI830->pScrn_2->monitor->nVrefresh =
+		I830StrToRanges(pI830->pScrn_2->monitor->vrefresh, pI830->SecondVRefresh, MAX_VREFRESH);
+	 }
+         SetBIOSPipe(pScrn, !pI830->pipe);
+         pI830->pVbe->ddc = DDC_UNCHECKED;
+	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+		"Probing DDC data for second head\n");
+	 if((monitor = vbeDoEDID(pI830->pVbe, pDDCModule))) {
+	    xf86PrintEDID(monitor);
+	    xf86SetDDCproperties(pI830->pScrn_2, monitor);
+	    pI830->pScrn_2->monitor->DDC = monitor;
+	    /* use DDC data if no ranges in config file */
+	    if(!pI830->SecondHSync) {
+	       pI830->pScrn_2->monitor->nHsync = 0;
+	    }
+	    if(!pI830->SecondVRefresh) {
+	       pI830->pScrn_2->monitor->nVrefresh = 0;
+	    }
+	 }
+	 SetPipeAccess(pScrn);
+      } else {
+         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+	      "Failed to allocate memory for second monitor.\n");
+	 if(pI830->pScrn_2) 
+            xfree(pI830->pScrn_2);
+	 pI830->pScrn_2 = NULL;
+	 pI830->MergedFB = FALSE;
+      }
    }
+
    xf86UnloadSubModule(pDDCModule);
 
    /* XXX Move this to a header. */
@@ -3135,7 +4916,8 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int f
 
    pI830->useExtendedRefresh = FALSE;
 
-   if (xf86IsEntityShared(pScrn->entityList[0]) || pI830->Clone) {
+   if (xf86IsEntityShared(pScrn->entityList[0]) || pI830->Clone || 
+       pI830->MergedFB) {
       int pipe =
 	  (pI830->operatingDevices >> PIPE_SHIFT(pI830->pipe)) & PIPE_ACTIVE_MASK;
       if (pipe & ~PIPE_CRT_ACTIVE) {
@@ -3227,6 +5009,21 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int f
       return FALSE;
    }
 
+   if (pI830->MergedFB) {
+      SetBIOSPipe(pScrn, !pI830->pipe);
+      xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+		 "Retrieving mode pool for second head.\n");
+      pI830->pScrn_2->modePool = I830GetModePool(pI830->pScrn_2, pI830->pVbe, pI830->vbeInfo);
+
+      if (!pI830->pScrn_2->modePool) {
+         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		 "No Video BIOS modes for chosen depth.\n");
+         PreInitCleanup(pScrn);
+         return FALSE;
+      }
+      SetPipeAccess(pScrn);
+   }
+
    /* This may look a little weird, but to notify that we're using the
     * default hsync/vrefresh we need to unset what we just set .....
     */
@@ -3244,6 +5041,9 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int f
 
    SetPipeAccess(pScrn);
    VBESetModeNames(pScrn->modePool);
+   if (pI830->MergedFB)
+      VBESetModeNames(pI830->pScrn_2->modePool);
+
 
    /*
     * XXX DDC information: There's code in xf86ValidateModes
@@ -3267,6 +5067,20 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int f
       return FALSE;
    }
 
+   if (pI830->MergedFB) {
+      n = VBEValidateModes(pI830->pScrn_2, NULL, pI830->pScrn_2->display->modes, NULL,
+			NULL, 0, MAX_DISPLAY_PITCH, 1,
+			0, MAX_DISPLAY_HEIGHT,
+			pScrn->display->virtualX,
+			pScrn->display->virtualY,
+			memsize, LOOKUP_BEST_REFRESH);
+      if (n <= 0) {
+         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n");
+         PreInitCleanup(pScrn);
+         return FALSE;
+      }
+   }
+
    /* Only use this if we've got DDC available */
    if (DDCclock > 0) {
       p = pScrn->modes;
@@ -3306,14 +5120,43 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int f
       return FALSE;
    }
 
+   if (pI830->MergedFB) {
+      DisplayModePtr old_modes;
+      DisplayModePtr cur_mode;
+
+      xf86PruneDriverModes(pI830->pScrn_2);
+
+      if (pI830->pScrn_2->modes == NULL) {
+         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n");
+         PreInitCleanup(pScrn);
+         return FALSE;
+      }
+
+      old_modes = pScrn->modes;
+      cur_mode = pScrn->currentMode;
+
+      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "MergedFB: Generating mode list\n");
+
+      pScrn->modes = I830GenerateModeList(pScrn, pI830->MetaModes,
+					  old_modes, pI830->pScrn_2->modes,
+					  pI830->SecondPosition);
+
+      if(!pScrn->modes) {
+          xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes. Disabling MergedFB.\n");
+	  pScrn->modes = old_modes;
+	  pScrn->currentMode = cur_mode;
+	  pI830->MergedFB = FALSE;
+      }
+   }
+
    /* Now we check the VESA BIOS's displayWidth and reset if necessary */
    p = pScrn->modes;
    do {
-      VbeModeInfoData *data = (VbeModeInfoData *) p->Private;
+      I830ModePrivatePtr mp = (I830ModePrivatePtr) p->Private;
       VbeModeInfoBlock *modeInfo;
 
       /* Get BytesPerScanline so we can reset displayWidth */
-      if ((modeInfo = VBEGetModeInfo(pI830->pVbe, data->mode))) {
+      if ((modeInfo = VBEGetModeInfo(pI830->pVbe, mp->vbeData.mode))) {
          if (pScrn->displayWidth < modeInfo->BytesPerScanline / pI830->cpp) {
             xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Correcting stride (%d -> %d)\n", pScrn->displayWidth, modeInfo->BytesPerScanline);
 	    pScrn->displayWidth = modeInfo->BytesPerScanline / pI830->cpp;
@@ -3324,6 +5167,18 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int f
 
    pScrn->currentMode = pScrn->modes;
 
+   if (pI830->MergedFB) {
+      /* If no virtual dimension was given by the user,
+       * calculate a sane one now. Adapts pScrn->virtualX,
+       * pScrn->virtualY and pScrn->displayWidth.
+       */
+      I830RecalcDefaultVirtualSize(pScrn);
+
+      pScrn->modes = pScrn->modes->next;  /* We get the last from GenerateModeList(), skip to first */
+      pScrn->currentMode = pScrn->modes;
+      pI830->currentMode = pScrn->currentMode;
+   }
+
 #ifndef USE_PITCHES
 #define USE_PITCHES 1
 #endif
@@ -3953,7 +5808,8 @@ I830VESASetVBEMode(ScrnInfoPtr pScrn, in
 	  pScrn->virtualY * pI830->displayWidth * pI830->cpp);
 #endif
 
-   if (pI830->Clone && pI830->CloneHDisplay && pI830->CloneVDisplay &&
+   if (pI830->Clone && 
+	pI830->CloneHDisplay && pI830->CloneVDisplay &&
        !pI830->preinit && !pI830->closing) {
       VbeCRTCInfoBlock newblock;
       int newmode = mode;
@@ -4087,7 +5943,7 @@ I830VESASetMode(ScrnInfoPtr pScrn, Displ
 {
    I830Ptr pI830 = I830PTR(pScrn);
    vbeInfoPtr pVbe = pI830->pVbe;
-   VbeModeInfoData *data = (VbeModeInfoData *) pMode->Private;
+   I830ModePrivatePtr mp = (I830ModePrivatePtr) pMode->Private;
    int mode, i;
    CARD32 planeA, planeB, temp;
    int refresh = 60;
@@ -4098,13 +5954,13 @@ I830VESASetMode(ScrnInfoPtr pScrn, Displ
    DPRINTF(PFX, "I830VESASetMode\n");
 
    /* Always Enable Linear Addressing */
-   mode = data->mode | (1 << 15) | (1 << 14);
+   mode = mp->vbeData.mode | (1 << 15) | (1 << 14);
 
 #ifdef XF86DRI
    didLock = I830DRILock(pScrn);
 #endif
 
-   if (pI830->Clone) {
+   if (pI830->Clone || pI830->MergedFB) {
       pI830->CloneHDisplay = pMode->HDisplay;
       pI830->CloneVDisplay = pMode->VDisplay;
    }
@@ -4118,9 +5974,24 @@ I830VESASetMode(ScrnInfoPtr pScrn, Displ
 
    SetPipeAccess(pScrn);
 
-   if (I830VESASetVBEMode(pScrn, mode, data->block) == FALSE) {
-      xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Set VBE Mode failed!\n");
-      return FALSE;
+   if (!pI830->MergedFB) {
+      if (I830VESASetVBEMode(pScrn, mode, mp->vbeData.block) == FALSE) {
+         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Set VBE Mode failed!\n");
+         return FALSE;
+      }
+   }else {
+      I830ModePrivatePtr s = (I830ModePrivatePtr)mp->merged.Second->Private;
+      I830ModePrivatePtr f = (I830ModePrivatePtr)mp->merged.First->Private;
+      SetBIOSPipe(pScrn, !pI830->pipe);
+      if (I830VESASetVBEMode(pScrn, (f->vbeData.mode | 1<<15 | 1<<14), f->vbeData.block) == FALSE) {
+         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Set VBE Mode failed!\n");
+         return FALSE;
+      }
+      SetPipeAccess(pScrn);
+      if (I830VESASetVBEMode(pScrn, (s->vbeData.mode | 1<<15 | 1<<14), s->vbeData.block) == FALSE) {
+         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Set VBE Mode failed!\n");
+         return FALSE;
+      }
    }
 
    /*
@@ -4128,8 +5999,8 @@ I830VESASetMode(ScrnInfoPtr pScrn, Displ
     * memory than it's aware of.  We check for this later, and set it
     * explicitly if necessary.
     */
-   if (data->data->XResolution != pI830->displayWidth) {
-      if (pI830->Clone) {
+   if (mp->vbeData.data->XResolution != pI830->displayWidth) {
+      if (pI830->Clone || pI830->MergedFB) {
          SetBIOSPipe(pScrn, !pI830->pipe);
          VBESetLogicalScanline(pVbe, pI830->displayWidth);
       }
@@ -4138,7 +6009,7 @@ I830VESASetMode(ScrnInfoPtr pScrn, Displ
    }
 
    if (pScrn->bitsPerPixel >= 8 && pI830->vbeInfo->Capabilities[0] & 0x01) {
-      if (pI830->Clone) {
+      if (pI830->Clone || pI830->MergedFB) {
          SetBIOSPipe(pScrn, !pI830->pipe);
          VBESetGetDACPaletteFormat(pVbe, 8);
       }
@@ -4307,7 +6178,16 @@ I830VESASetMode(ScrnInfoPtr pScrn, Displ
 		    (int)(temp / pI830->cpp), pI830->displayWidth);
 	    OUTREG(stridereg, pI830->displayWidth * pI830->cpp);
          }
-         OUTREG(sizereg, (pMode->HDisplay - 1) | ((pMode->VDisplay - 1) << 16));
+
+#if 0
+	 if (pI830->MergedFB) {
+            if (i == 0)
+               OUTREG(sizereg, (CDMPTR.First->HDisplay - 1) | ((CDMPTR.First->VDisplay - 1) << 16));
+	    else 
+               OUTREG(sizereg, (CDMPTR.Second->HDisplay - 1) | ((CDMPTR.Second->VDisplay - 1) << 16));
+         } else
+            OUTREG(sizereg, (pMode->HDisplay - 1) | ((pMode->VDisplay - 1) << 16));
+#endif
 	 /* Trigger update */
 	 temp = INREG(basereg);
 	 OUTREG(basereg, temp);
@@ -5160,7 +7040,7 @@ I830BIOSScreenInit(int scrnIndex, Screen
    pI830->CloseScreen = pScreen->CloseScreen;
    pScreen->CloseScreen = I830BIOSCloseScreen;
 
-   if (pI830->shadowReq.minorversion >= 1) {
+   if (!pI830->MergedFB && pI830->shadowReq.minorversion >= 1) {
       /* Rotation */
       xf86DrvMsg(pScrn->scrnIndex, X_INFO, "RandR enabled, ignore the following RandR disabled message.\n");
       xf86DisableRandR(); /* Disable built-in RandR extension */
@@ -5176,6 +7056,24 @@ I830BIOSScreenInit(int scrnIndex, Screen
       xf86DrvMsg(pScrn->scrnIndex, X_INFO, "libshadow is version %d.%d.%d, required 1.1.0 or greater for rotation.\n",pI830->shadowReq.majorversion,pI830->shadowReq.minorversion,pI830->shadowReq.patchlevel);
    }
 
+   if (pI830->MergedFB) {
+      pI830->PointerMoved = pScrn->PointerMoved;
+      pScrn->PointerMoved = I830MergedPointerMoved;
+
+      if(pI830->IntelXinerama) {
+	  I830noPanoramiXExtension = FALSE;
+	  I830XineramaExtensionInit(pScrn);
+	  if(!I830noPanoramiXExtension) {
+	     if(pI830->HaveNonRect) {
+		/* Reset the viewport (now eventually non-recangular) */
+		I830BIOSAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+	     }
+	  }
+      } else {
+	  pI830->MouseRestrictions = FALSE;
+      }
+   }
+
    if (serverGeneration == 1)
       xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
 
@@ -5234,6 +7132,11 @@ I830BIOSAdjustFrame(int scrnIndex, int x
       pI830->AccelInfoRec->NeedToSync = FALSE;
    }
 
+   if (pI830->MergedFB) {
+      I830AdjustFrameMerged(scrnIndex, x, y, flags);
+      return;
+   }
+
    if (I830IsPrimary(pScrn))
       Start = pI830->FrontBuffer.Start;
    else {
@@ -5316,7 +7219,7 @@ I830BIOSLeaveVT(int scrnIndex, int flags
    I830VideoSwitchModeBefore(pScrn, NULL);
 #endif
 
-   if (pI830->Clone) {
+   if (pI830->Clone || pI830->MergedFB) {
       /* Ensure we don't try and setup modes on a clone head */
       pI830->CloneHDisplay = 0;
       pI830->CloneVDisplay = 0;
@@ -5389,6 +7292,7 @@ I830DetectMonitorChange(ScrnInfoPtr pScr
    int displayWidth = pScrn->displayWidth;
    int curHDisplay = pScrn->currentMode->HDisplay;
    int curVDisplay = pScrn->currentMode->VDisplay;
+   xf86MonPtr monitor = NULL;
 
    DPRINTF(PFX, "Detect Monitor Change\n");
    
@@ -5396,13 +7300,11 @@ I830DetectMonitorChange(ScrnInfoPtr pScr
 
    /* Re-read EDID */
    pDDCModule = xf86LoadSubModule(pScrn, "ddc");
-   if (pI830->vesa->monitor)
-      xfree(pI830->vesa->monitor);
-   pI830->vesa->monitor = vbeDoEDID(pI830->pVbe, pDDCModule);
+   monitor = vbeDoEDID(pI830->pVbe, pDDCModule);
    xf86UnloadSubModule(pDDCModule);
-   if ((pScrn->monitor->DDC = pI830->vesa->monitor) != NULL) {
-      xf86PrintEDID(pI830->vesa->monitor);
-      xf86SetDDCproperties(pScrn, pI830->vesa->monitor);
+   if ((pScrn->monitor->DDC = monitor) != NULL) {
+      xf86PrintEDID(monitor);
+      xf86SetDDCproperties(pScrn, monitor);
    } else 
       /* No DDC, so get out of here, and continue to use the current settings */
       return FALSE; 
@@ -5745,6 +7647,13 @@ I830BIOSSwitchMode(int scrnIndex, Displa
 #endif
    }
 
+   /* Since RandR (indirectly) uses SwitchMode(), we need to
+    * update our Xinerama info here, too, in case of resizing
+    */
+   if(pI830->MergedFB) {
+      I830UpdateXineramaScreenInfo(pScrn);
+   }
+
    return ret;
 }
 
@@ -5797,7 +7706,7 @@ I830DisplayPowerManagementSet(ScrnInfoPt
    I830Ptr pI830 = I830PTR(pScrn);
    vbeInfoPtr pVbe = pI830->pVbe;
 
-   if (pI830->Clone) {
+   if (pI830->Clone || pI830->MergedFB) {
       SetBIOSPipe(pScrn, !pI830->pipe);
       if (xf86LoaderCheckSymbol("VBEDPMSSet")) {
          VBEDPMSSet(pVbe, PowerManagementMode);
@@ -6257,7 +8166,6 @@ I830CheckDevicesTimer(OsTimerPtr timer, 
          ScreenPtr   pCursorScreen;
          int x = 0, y = 0;
 
-
          pCursorScreen = miPointerCurrentScreen();
          if (pScrn->pScreen == pCursorScreen)
             miPointerPosition(&x, &y);
diff --git a/src/i830_modes.c b/src/i830_modes.c
index 97e40e0..383b23c 100644
--- a/src/i830_modes.c
+++ b/src/i830_modes.c
@@ -42,8 +42,6 @@
 #include <string.h>
 
 #include "xf86.h"
-#include "vbe.h"
-#include "vbeModes.h"
 #include "i830.h"
 
 #include <math.h>
@@ -363,7 +361,11 @@ CheckMode(ScrnInfoPtr pScrn, vbeInfoPtr 
     CARD16 major, minor;
     VbeModeInfoBlock *mode;
     DisplayModePtr p = NULL, pMode = NULL;
+#if 0
     VbeModeInfoData *data;
+#else
+    I830ModePrivatePtr data;
+#endif
     Bool modeOK = FALSE;
     ModeStatus status = MODE_OK;
 
@@ -602,12 +604,21 @@ CheckMode(ScrnInfoPtr pScrn, vbeInfoPtr 
     pMode->HDisplay = mode->XResolution;
     pMode->VDisplay = mode->YResolution;
 
+#if 0
     data = xnfcalloc(sizeof(VbeModeInfoData), 1);
     data->mode = id;
     data->data = mode;
     pMode->PrivSize = sizeof(VbeModeInfoData);
     pMode->Private = (INT32*)data;
+#else
+    data = xnfcalloc(sizeof(I830ModePrivateRec), 1);
+    data->vbeData.mode = id;
+    data->vbeData.data = mode;
+    pMode->PrivSize = sizeof(I830ModePrivateRec);
+    pMode->Private = (INT32*)data;
+#endif
     pMode->next = NULL;
+
     return pMode;
 }
 
@@ -664,50 +675,49 @@ void
 I830SetModeParameters(ScrnInfoPtr pScrn, vbeInfoPtr pVbe)
 {
     DisplayModePtr pMode;
-    VbeModeInfoData *data;
+    I830ModePrivatePtr mp;
 
     pMode = pScrn->modes;
     do {
 	int clock;
 
-	data = (VbeModeInfoData*)pMode->Private;
-	data->block = xcalloc(sizeof(VbeCRTCInfoBlock), 1);
-	data->block->HorizontalTotal = pMode->HTotal;
-	data->block->HorizontalSyncStart = pMode->HSyncStart;
-	data->block->HorizontalSyncEnd = pMode->HSyncEnd;
-	data->block->VerticalTotal = pMode->VTotal;
-	data->block->VerticalSyncStart = pMode->VSyncStart;
-	data->block->VerticalSyncEnd = pMode->VSyncEnd;
-	data->block->Flags = ((pMode->Flags & V_NHSYNC) ? CRTC_NHSYNC : 0) |
+	mp->vbeData.block = xcalloc(sizeof(VbeCRTCInfoBlock), 1);
+	mp->vbeData.block->HorizontalTotal = pMode->HTotal;
+	mp->vbeData.block->HorizontalSyncStart = pMode->HSyncStart;
+	mp->vbeData.block->HorizontalSyncEnd = pMode->HSyncEnd;
+	mp->vbeData.block->VerticalTotal = pMode->VTotal;
+	mp->vbeData.block->VerticalSyncStart = pMode->VSyncStart;
+	mp->vbeData.block->VerticalSyncEnd = pMode->VSyncEnd;
+	mp->vbeData.block->Flags = ((pMode->Flags & V_NHSYNC) ? CRTC_NHSYNC : 0) |
 				 ((pMode->Flags & V_NVSYNC) ? CRTC_NVSYNC : 0);
-	data->block->PixelClock = pMode->Clock * 1000;
+	mp->vbeData.block->PixelClock = pMode->Clock * 1000;
 	/* XXX May not have this. */
-	clock = VBEGetPixelClock(pVbe, data->mode, data->block->PixelClock);
+	clock = VBEGetPixelClock(pVbe, mp->vbeData.mode, mp->vbeData.block->PixelClock);
 	if (clock)
-	    data->block->PixelClock = clock;
+	    mp->vbeData.block->PixelClock = clock;
 #ifdef DEBUG
 	ErrorF("Setting clock %.2fMHz, closest is %.2fMHz\n",
-		(double)data->block->PixelClock / 1000000.0, 
+		(double)mp->vbeData.block->PixelClock / 1000000.0, 
 		(double)clock / 1000000.0);
 #endif
-	data->mode |= (1 << 11);
+	mp->vbeData.mode |= (1 << 11);
 	if (pMode->VRefresh != 0) {
-	    data->block->RefreshRate = pMode->VRefresh * 100;
+	    mp->vbeData.block->RefreshRate = pMode->VRefresh * 100;
 	} else {
-	    data->block->RefreshRate = (int)(((double)(data->block->PixelClock)/
+	    mp->vbeData.block->RefreshRate = (int)(((double)(mp->vbeData.block->PixelClock)/
                        (double)(pMode->HTotal * pMode->VTotal)) * 100);
 	}
 	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 		       "Attempting to use %2.2fHz refresh for mode \"%s\" (%x)\n",
-		       (float)(((double)(data->block->PixelClock) / (double)(pMode->HTotal * pMode->VTotal))), pMode->name, data->mode);
+		       (float)(((double)(mp->vbeData.block->PixelClock) / (double)(pMode->HTotal * pMode->VTotal))), pMode->name, mp->vbeData.mode);
 #ifdef DEBUG
 	ErrorF("Video Modeline: ID: 0x%x Name: %s %i %i %i %i - "
 	       "  %i %i %i %i %.2f MHz Refresh: %.2f Hz\n",
-	       data->mode, pMode->name, pMode->HDisplay, pMode->HSyncStart,
+	       mp->vbeData.mode, pMode->name, pMode->HDisplay, pMode->HSyncStart,
 	       pMode->HSyncEnd, pMode->HTotal, pMode->VDisplay,
 	       pMode->VSyncStart,pMode->VSyncEnd,pMode->VTotal,
-	       (double)data->block->PixelClock/1000000.0,
-	       (double)data->block->RefreshRate/100);
+	       (double)mp->vbeData.block->PixelClock/1000000.0,
+	       (double)mp->vbeData.block->RefreshRate/100);
 #endif
 	pMode = pMode->next;
     } while (pMode != pScrn->modes);
diff-tree 32f1199937e92b9100aba52cbbb97157014e3182 (from baf65ce98abcdd21dff2531a43bb9c5044732c28)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Mon Jul 24 15:42:15 2006 +0800

    remove an extra '-'

diff --git a/src/i915_video.c b/src/i915_video.c
index e05ad72..0833d50 100644
--- a/src/i915_video.c
+++ b/src/i915_video.c
@@ -359,7 +359,7 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
        */
       i915_fs_dp3_masked(FS_OC, MASK_X | MASK_SATURATE,
                         i915_fs_operand_reg(FS_R0),
--                        i915_fs_operand_reg(FS_C1));
+                        i915_fs_operand_reg(FS_C1));
       i915_fs_dp3_masked(FS_OC, MASK_Y | MASK_SATURATE,
                         i915_fs_operand_reg(FS_R0),
                         i915_fs_operand_reg(FS_C2));
diff-tree baf65ce98abcdd21dff2531a43bb9c5044732c28 (from bb81e8d6c777a5e16b8193c07667fbee8e21203e)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Tue Jul 18 19:42:37 2006 -0400

    Re-convert i915 video to new fragment shader API.
    
    Although in the history of this branch it had happened before, this time it's
    for real.

diff --git a/src/i915_video.c b/src/i915_video.c
index 8d687a1..e05ad72 100644
--- a/src/i915_video.c
+++ b/src/i915_video.c
@@ -37,6 +37,7 @@
 #include "i830.h"
 #include "i830_video.h"
 #include "i915_reg.h"
+#include "i915_3d.h"
 
 union intfloat {
    CARD32 ui;
@@ -49,68 +50,6 @@ union intfloat {
    OUT_RING(_tmp.ui);							\
 } while (0)
 
-#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)
-
-/* Move the dest_chan from src0 to dest, leaving the other channels alone */
-#define OUT_MOV_TO_CHANNEL(dest_type, dest_nr, src0_type, src0_nr,	\
-			   dest_chan)					\
-do {									\
-   OUT_RING(A0_MOV | A0_DEST_CHANNEL_##dest_chan |			\
-	    (REG_TYPE_##dest_type << A0_DEST_TYPE_SHIFT) |		\
-	    (dest_nr << A0_DEST_NR_SHIFT) |				\
-	    (REG_TYPE_##src0_type << A0_SRC0_TYPE_SHIFT) |		\
-	    (src0_nr << 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));			\
-   OUT_RING(0);								\
-} while (0)
-
-/* Dot3-product src0 and src1, storing the result in dest_chan of the dest.
- * Saturates, in case we have out-of-range YUV values.
- */
-#define OUT_DP3_TO_CHANNEL(dest_type, dest_nr, src0_type, src0_nr,	\
-			   src1_type, src1_nr, dest_chan)		\
-do {									\
-   OUT_RING(A0_DP3 | A0_DEST_CHANNEL_##dest_chan | A0_DEST_SATURATE |	\
-	    (REG_TYPE_##dest_type << A0_DEST_TYPE_SHIFT) |		\
-	    (dest_nr << A0_DEST_NR_SHIFT) |				\
-	    (REG_TYPE_##src0_type << A0_SRC0_TYPE_SHIFT) |		\
-	    (src0_nr << 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_##src1_type << A1_SRC1_TYPE_SHIFT) |		\
-	    (src1_nr << A1_SRC1_TYPE_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));			\
-} while (0)
 
 void
 I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
@@ -261,14 +200,9 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
    ADVANCE_LP_RING();
 
    if (!planar) {
-      BEGIN_LP_RING(20);
-      /* fragment program - texture blend replace. */
-      OUT_RING(_3DSTATE_PIXEL_SHADER_PROGRAM | 8);
-      OUT_DCL(S, 0);
-      OUT_DCL(T, 0);
-      OUT_TEXLD(OC, 0, 0, T, 0);
-      /* End fragment program */
+      FS_LOCALS(3);
 
+      BEGIN_LP_RING(10);
       OUT_RING(_3DSTATE_SAMPLER_STATE | 3);
       OUT_RING(0x00000001);
       OUT_RING(SS2_COLORSPACE_CONVERSION |
@@ -297,8 +231,16 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
       OUT_RING(ms3);
       OUT_RING(((video_pitch / 4) - 1) << 21);
       ADVANCE_LP_RING();
+
+      FS_BEGIN();
+      i915_fs_dcl(FS_S0);
+      i915_fs_dcl(FS_T0);
+      i915_fs_texld(FS_OC, FS_S0, FS_T0);
+      FS_END();
    } else {
-      BEGIN_LP_RING(1 + 18 + (1 + 3*16) + 11 + 11);
+      FS_LOCALS(16);
+
+      BEGIN_LP_RING(1 + 18 + 11 + 11);
       OUT_RING(MI_NOOP);
       /* For the planar formats, we set up three samplers -- one for each plane,
        * in a Y8 format.  Because I couldn't get the special PLANAR_TO_PACKED
@@ -342,61 +284,6 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
       OUT_RING_F(0.0);
       OUT_RING_F(0.0);
 
-      OUT_RING(_3DSTATE_PIXEL_SHADER_PROGRAM | (3 * 16 - 1));
-      /* Declare samplers */
-      OUT_DCL(S, 0);
-      OUT_DCL(S, 1);
-      OUT_DCL(S, 2);
-      OUT_DCL(T, 0);
-      OUT_DCL(T, 1);
-
-      /* Load samplers to temporaries.  Y (sampler 0) gets the un-halved coords
-       * from t1.
-       */
-      OUT_TEXLD(R, 1, 0, T, 1);
-      OUT_TEXLD(R, 2, 1, T, 0);
-      OUT_TEXLD(R, 3, 2, T, 0);
-
-      /* Move the sampled YUV data in R[123] to the first 3 channels of R0. */
-      OUT_MOV_TO_CHANNEL(R, 0, R, 1, X);
-      OUT_MOV_TO_CHANNEL(R, 0, R, 2, Y);
-      OUT_MOV_TO_CHANNEL(R, 0, R, 3, Z);
-
-      /* Normalize the YUV data */
-      OUT_RING(A0_ADD | A0_DEST_CHANNEL_ALL |
-	       (REG_TYPE_R << A0_DEST_TYPE_SHIFT) | (0 << A0_DEST_NR_SHIFT) |				\
-	       (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_CONST << A1_SRC1_TYPE_SHIFT) | (0 << 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));
-
-      /* dot-product the YUV data in R0 by the vectors of coefficients for
-       * calculating R, G, and B, storing the results in the R, G, or B channels
-       * of the output color.
-       */
-      OUT_DP3_TO_CHANNEL(OC, 0, R, 0, CONST, 1, X);
-      OUT_DP3_TO_CHANNEL(OC, 0, R, 0, CONST, 2, Y);
-      OUT_DP3_TO_CHANNEL(OC, 0, R, 0, CONST, 3, Z);
-
-      /* Set alpha of the output to 1.0, by wiring W to 1 and not actually using
-       * the source.
-       */
-      OUT_RING(A0_MOV | A0_DEST_CHANNEL_W |
-	       (REG_TYPE_OC << A0_DEST_TYPE_SHIFT) | (0 << A0_DEST_NR_SHIFT) |
-	       (REG_TYPE_OC << 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_ONE << A1_SRC0_CHANNEL_W_SHIFT));
-      OUT_RING(0);
-      /* End fragment program */
-
       OUT_RING(_3DSTATE_SAMPLER_STATE | 9);
       OUT_RING(0x00000007);
       /* sampler 0 */
@@ -442,6 +329,48 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
       OUT_RING(ms3);
       OUT_RING(((video_pitch / 4) - 1) << 21);
       ADVANCE_LP_RING();
+
+      FS_BEGIN();
+      /* Declare samplers */
+      i915_fs_dcl(FS_S0);
+      i915_fs_dcl(FS_S1);
+      i915_fs_dcl(FS_S2);
+      i915_fs_dcl(FS_T0);
+      i915_fs_dcl(FS_T1);
+
+      /* Load samplers to temporaries.  Y (sampler 0) gets the un-halved coords-
+       * from t1.
+       */
+      i915_fs_texld(FS_R1, FS_S0, FS_T1);
+      i915_fs_texld(FS_R2, FS_S1, FS_T0);
+      i915_fs_texld(FS_R3, FS_S2, FS_T0);
+
+      /* Move the sampled YUV data in R[123] to the first 3 channels of R0. */
+      i915_fs_mov_masked(FS_R0, MASK_X, i915_fs_operand_reg(FS_R1));
+      i915_fs_mov_masked(FS_R0, MASK_Y, i915_fs_operand_reg(FS_R2));
+      i915_fs_mov_masked(FS_R0, MASK_Z, i915_fs_operand_reg(FS_R3));
+
+      /* Normalize the YUV data */
+      i915_fs_add(FS_R0, i915_fs_operand_reg(FS_R0),
+                 i915_fs_operand_reg(FS_C0));
+      /* dot-product the YUV data in R0 by the vectors of coefficients for
+       * calculating R, G, and B, storing the results in the R, G, or B channels
+       * of the output color.
+       */
+      i915_fs_dp3_masked(FS_OC, MASK_X | MASK_SATURATE,
+                        i915_fs_operand_reg(FS_R0),
+-                        i915_fs_operand_reg(FS_C1));
+      i915_fs_dp3_masked(FS_OC, MASK_Y | MASK_SATURATE,
+                        i915_fs_operand_reg(FS_R0),
+                        i915_fs_operand_reg(FS_C2));
+      i915_fs_dp3_masked(FS_OC, MASK_Z | MASK_SATURATE,
+                        i915_fs_operand_reg(FS_R0),
+                        i915_fs_operand_reg(FS_C3));
+      /* Set alpha of the output to 1.0, by wiring W to 1 and not actually using
+       * the source.
+       */
+      i915_fs_mov_masked(FS_OC, MASK_W, i915_fs_operand_one());
+      FS_END();
    }
    
    {
diff-tree bb81e8d6c777a5e16b8193c07667fbee8e21203e (from parents)
Merge: 2a1b3cfccb7de53f7ce8f9e4816e4278afb1fcab 84805167ab8a422966355b9753bfcb4dad802413
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Tue Jul 18 19:23:21 2006 -0400

    Merge branch 'master' into textured-video
    
    This moves the i915 textured video implementation into i915_video.c to avoid
    conflicts in register definitions with i830_reg.h when we use i915_reg.h.
    This also means that i810_reg.h's i915 3D regs definitions are removed and
    replaced with i915_reg.h usage.
    
    Conflicts:
    
    	src/i830_rotate.c

diff --cc src/Makefile.am
index c64c203,f97dc52..bf4ded4
@@@ -53,8 -53,13 +53,15 @@@
           i830_memory.c \
           i830_modes.c \
           i830_video.c \
++         i830_video.h \
           i830_rotate.c \
- 	 i830_randr.c
+ 	 i830_randr.c \
+ 	 i830_3d.c \
+ 	 i830_reg.h \
+ 	 i915_3d.c \
+ 	 i915_3d.h \
 -	 i915_reg.h
++	 i915_reg.h \
++	 i915_video.c
  
  if DRI
  i810_drv_la_SOURCES += \
diff --cc src/i810_reg.h
index 0ed7ff6,e52375f..2c5e271
@@@ -869,624 -866,15 +866,12 @@@
  #define XY_MONO_SRC_BLT_WRITE_ALPHA	(1<<21)
  #define XY_MONO_SRC_BLT_WRITE_RGB	(1<<20)
  
--/* 3d state */
- #define STATE3D_ANTI_ALIASING		(CMD_3D | (0x06<<24))
- #define LINE_CAP_WIDTH_MODIFY		(1 << 16)
- #define LINE_CAP_WIDTH_1_0		(0x1 << 14)
- #define LINE_WIDTH_MODIFY		(1 << 8)
- #define LINE_WIDTH_1_0			(0x1 << 6)
- 
- #define STATE3D_RASTERIZATION_RULES	(CMD_3D | (0x07<<24))
- #define ENABLE_POINT_RASTER_RULE	(1<<15)
- #define OGL_POINT_RASTER_RULE		(1<<13)
- #define ENABLE_TEXKILL_3D_4D            (1<<10)
- #define TEXKILL_3D                      (0<<9)
- #define TEXKILL_4D                      (1<<9)
- #define ENABLE_LINE_STRIP_PROVOKE_VRTX	(1<<8)
- #define ENABLE_TRI_FAN_PROVOKE_VRTX	(1<<5)
- #define LINE_STRIP_PROVOKE_VRTX(x)	((x)<<6)
- #define TRI_FAN_PROVOKE_VRTX(x) 	((x)<<3)
- 
- #define STATE3D_INDEPENDENT_ALPHA_BLEND	(CMD_3D | (0x0b<<24))
- #define IAB_MODIFY_ENABLE	        (1<<23)
- #define IAB_ENABLE       	        (1<<22)
- #define IAB_MODIFY_FUNC         	(1<<21)
- #define IAB_FUNC_SHIFT          	16
- #define IAB_MODIFY_SRC_FACTOR   	(1<<11)
- #define IAB_SRC_FACTOR_SHIFT		6
- #define IAB_SRC_FACTOR_MASK		(BLENDFACT_MASK<<6)
- #define IAB_MODIFY_DST_FACTOR	        (1<<5)
- #define IAB_DST_FACTOR_SHIFT		0
- #define IAB_DST_FACTOR_MASK		(BLENDFACT_MASK<<0)
- 
- #define BLENDFUNC_ADD			0x0
- #define BLENDFUNC_SUBTRACT		0x1
- #define BLENDFUNC_REVERSE_SUBTRACT	0x2
- #define BLENDFUNC_MIN			0x3
- #define BLENDFUNC_MAX			0x4
- #define BLENDFUNC_MASK			0x7
- 
- #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 STATE3D_MODES_4			(CMD_3D | (0x0d<<24))
- #define ENABLE_LOGIC_OP_FUNC		(1<<23)
- #define LOGIC_OP_FUNC(x)		((x)<<18)
- #define LOGICOP_MASK			(0xf<<18)
- #define MODE4_ENABLE_STENCIL_TEST_MASK	((1<<17)|(0xff00))
- #define ENABLE_STENCIL_TEST_MASK	(1<<17)
- #define STENCIL_TEST_MASK(x)		((x)<<8)
- #define MODE4_ENABLE_STENCIL_WRITE_MASK	((1<<16)|(0x00ff))
- #define ENABLE_STENCIL_WRITE_MASK	(1<<16)
- #define STENCIL_WRITE_MASK(x)		((x)&0xff)
- 
- #define LOGICOP_CLEAR			0
- #define LOGICOP_NOR			0x1
- #define LOGICOP_AND_INV 		0x2
- #define LOGICOP_COPY_INV		0x3
- #define LOGICOP_AND_RVRSE		0x4
- #define LOGICOP_INV			0x5
- #define LOGICOP_XOR			0x6
- #define LOGICOP_NAND			0x7
- #define LOGICOP_AND			0x8
- #define LOGICOP_EQUIV			0x9
- #define LOGICOP_NOOP			0xa
- #define LOGICOP_OR_INV			0xb
- #define LOGICOP_COPY			0xc
- #define LOGICOP_OR_RVRSE		0xd
- #define LOGICOP_OR			0xe
- #define LOGICOP_SET			0xf
- 
- #define STATE3D_COORD_SET_BINDINGS	(CMD_3D | (0x16<<24))
- #define CSB_TCB(iunit,eunit)		((eunit) << ((iunit) * 3))
- 
- #define STATE3D_SCISSOR_ENABLE		(CMD_3D | (0x1c<<24)|(0x10<<19))
- #define ENABLE_SCISSOR_RECT		((1<<1) | 1)
- #define DISABLE_SCISSOR_RECT		((1<<1) | 0)
- 
- #define STATE3D_MAP_STATE		(CMD_3D | (0x1d<<24)|(0x00<<16))
- 
- #define MS1_MAPMASK_SHIFT               0
- #define MS1_MAPMASK_MASK                (0x8fff<<0)
- 
- #define MS2_UNTRUSTED_SURFACE           (1<<31)
- #define MS2_ADDRESS_MASK                0xfffffffc
- #define MS2_VERTICAL_LINE_STRIDE        (1<<1)
- #define MS2_VERTICAL_OFFSET             (1<<1)
- 
- #define MS3_HEIGHT_SHIFT              21
- #define MS3_WIDTH_SHIFT               10
- #define MS3_PALETTE_SELECT            (1<<9)
- #define MS3_MAPSURF_FORMAT_SHIFT      7
- #define MS3_MAPSURF_FORMAT_MASK       (0x7<<7)
- #define    MAPSURF_8BIT		 	   (1<<7)
- #define    MAPSURF_16BIT		   (2<<7)
- #define    MAPSURF_32BIT		   (3<<7)
- #define    MAPSURF_422			   (5<<7)
- #define    MAPSURF_COMPRESSED		   (6<<7)
- #define    MAPSURF_4BIT_INDEXED		   (7<<7)
- #define MS3_MT_FORMAT_MASK         (0x7 << 3)
- #define MS3_MT_FORMAT_SHIFT        3
- #define    MT_4BIT_IDX_ARGB8888	           (7<<3) /* SURFACE_4BIT_INDEXED */
- #define    MT_8BIT_I8		           (0<<3) /* SURFACE_8BIT */
- #define    MT_8BIT_L8		           (1<<3)
- #define    MT_8BIT_A8		           (4<<3)
- #define    MT_8BIT_MONO8	           (5<<3)
- #define    MT_16BIT_RGB565 		   (0<<3) /* SURFACE_16BIT */
- #define    MT_16BIT_ARGB1555		   (1<<3)
- #define    MT_16BIT_ARGB4444		   (2<<3)
- #define    MT_16BIT_AY88		   (3<<3)
- #define    MT_16BIT_88DVDU	           (5<<3)
- #define    MT_16BIT_BUMP_655LDVDU	   (6<<3)
- #define    MT_16BIT_I16	                   (7<<3)
- #define    MT_16BIT_L16	                   (8<<3)
- #define    MT_16BIT_A16	                   (9<<3)
- #define    MT_32BIT_ARGB8888		   (0<<3) /* SURFACE_32BIT */
- #define    MT_32BIT_ABGR8888		   (1<<3)
- #define    MT_32BIT_XRGB8888		   (2<<3)
- #define    MT_32BIT_XBGR8888		   (3<<3)
- #define    MT_32BIT_QWVU8888		   (4<<3)
- #define    MT_32BIT_AXVU8888		   (5<<3)
- #define    MT_32BIT_LXVU8888	           (6<<3)
- #define    MT_32BIT_XLVU8888	           (7<<3)
- #define    MT_32BIT_ARGB2101010	           (8<<3)
- #define    MT_32BIT_ABGR2101010	           (9<<3)
- #define    MT_32BIT_AWVU2101010	           (0xA<<3)
- #define    MT_32BIT_GR1616	           (0xB<<3)
- #define    MT_32BIT_VU1616	           (0xC<<3)
- #define    MT_32BIT_xI824	           (0xD<<3)
- #define    MT_32BIT_xA824	           (0xE<<3)
- #define    MT_32BIT_xL824	           (0xF<<3)
- #define    MT_422_YCRCB_SWAPY	           (0<<3) /* SURFACE_422 */
- #define    MT_422_YCRCB_NORMAL	           (1<<3)
- #define    MT_422_YCRCB_SWAPUV	           (2<<3)
- #define    MT_422_YCRCB_SWAPUVY	           (3<<3)
- #define    MT_COMPRESS_DXT1		   (0<<3) /* SURFACE_COMPRESSED */
- #define    MT_COMPRESS_DXT2_3	           (1<<3)
- #define    MT_COMPRESS_DXT4_5	           (2<<3)
- #define    MT_COMPRESS_FXT1		   (3<<3)
- #define    MT_COMPRESS_DXT1_RGB		   (4<<3)
- #define MS3_USE_FENCE_REGS              (1<<2)
- #define MS3_TILED_SURFACE             (1<<1)
- #define MS3_TILE_WALK                 (1<<0)
- 
- #define MS4_PITCH_SHIFT                 21
- #define MS4_CUBE_FACE_ENA_NEGX          (1<<20)
- #define MS4_CUBE_FACE_ENA_POSX          (1<<19)
- #define MS4_CUBE_FACE_ENA_NEGY          (1<<18)
- #define MS4_CUBE_FACE_ENA_POSY          (1<<17)
- #define MS4_CUBE_FACE_ENA_NEGZ          (1<<16)
- #define MS4_CUBE_FACE_ENA_POSZ          (1<<15)
- #define MS4_CUBE_FACE_ENA_MASK          (0x3f<<15)
- #define MS4_MAX_LOD_SHIFT		9
- #define MS4_MAX_LOD_MASK		(0x3f<<9)
- #define MS4_MIP_LAYOUT_LEGACY           (0<<8)
- #define MS4_MIP_LAYOUT_BELOW_LPT        (0<<8)
- #define MS4_MIP_LAYOUT_RIGHT_LPT        (1<<8)
- #define MS4_VOLUME_DEPTH_SHIFT          0    
- #define MS4_VOLUME_DEPTH_MASK           (0xff<<0)
- 
- #define STATE3D_SAMPLER_STATE		(CMD_3D | (0x1d<<24)|(0x01<<16))
- 
- #define SS1_MAPMASK_SHIFT               0
- #define SS1_MAPMASK_MASK                (0x8fff<<0)
- 
- #define SS2_REVERSE_GAMMA_ENABLE        (1<<31)
- #define SS2_PLANAR_TO_PACKED_ENABLE     (1<<30)
- #define SS2_COLORSPACE_CONVERSION       (1<<29)
- #define SS2_CHROMAKEY_SHIFT             27
- #define SS2_BASE_MIP_LEVEL_SHIFT        22
- #define SS2_BASE_MIP_LEVEL_MASK         (0x1f<<22)
- #define SS2_MIP_FILTER_SHIFT            20
- #define SS2_MIP_FILTER_MASK             (0x3<<20)
- #define   MIPFILTER_NONE       	0
- #define   MIPFILTER_NEAREST	1
- #define   MIPFILTER_LINEAR	3
- #define SS2_MAG_FILTER_SHIFT          17
- #define SS2_MAG_FILTER_MASK           (0x7<<17)
- #define   FILTER_NEAREST	0
- #define   FILTER_LINEAR		1
- #define   FILTER_ANISOTROPIC	2
- #define   FILTER_4X4_1    	3
- #define   FILTER_4X4_2    	4
- #define   FILTER_4X4_FLAT 	5
- #define   FILTER_6X5_MONO   	6 /* XXX - check */
- #define SS2_MIN_FILTER_SHIFT          14
- #define SS2_MIN_FILTER_MASK           (0x7<<14)
- #define SS2_LOD_BIAS_SHIFT            5
- #define SS2_LOD_BIAS_ONE              (0x10<<5)
- #define SS2_LOD_BIAS_MASK             (0x1ff<<5)
- /* Shadow requires:
-  *  MT_X8{I,L,A}24 or MT_{I,L,A}16 texture format
-  *  FILTER_4X4_x  MIN and MAG filters
-  */
- #define SS2_SHADOW_ENABLE             (1<<4)
- #define SS2_MAX_ANISO_MASK            (1<<3)
- #define SS2_MAX_ANISO_2               (0<<3)
- #define SS2_MAX_ANISO_4               (1<<3)
- #define SS2_SHADOW_FUNC_SHIFT         0
- #define SS2_SHADOW_FUNC_MASK          (0x7<<0)
- /* SS2_SHADOW_FUNC values: see COMPAREFUNC_* */
- 
- #define SS3_MIN_LOD_SHIFT            24
- #define SS3_MIN_LOD_ONE              (0x10<<24)
- #define SS3_MIN_LOD_MASK             (0xff<<24)
- #define SS3_KILL_PIXEL_ENABLE        (1<<17)
- #define SS3_TCX_ADDR_MODE_SHIFT      12
- #define SS3_TCX_ADDR_MODE_MASK       (0x7<<12)
- #define   TEXCOORDMODE_WRAP		0
- #define   TEXCOORDMODE_MIRROR		1
- #define   TEXCOORDMODE_CLAMP_EDGE	2
- #define   TEXCOORDMODE_CUBE       	3
- #define   TEXCOORDMODE_CLAMP_BORDER	4
- #define   TEXCOORDMODE_MIRROR_ONCE      5
- #define SS3_TCY_ADDR_MODE_SHIFT      9
- #define SS3_TCY_ADDR_MODE_MASK       (0x7<<9)
- #define SS3_TCZ_ADDR_MODE_SHIFT      6
- #define SS3_TCZ_ADDR_MODE_MASK       (0x7<<6)
- #define SS3_NORMALIZED_COORDS        (1<<5)
- #define SS3_TEXTUREMAP_INDEX_SHIFT   1
- #define SS3_TEXTUREMAP_INDEX_MASK    (0xf<<1)
- #define SS3_DEINTERLACER_ENABLE      (1<<0)
- 
- #define SS4_BORDER_COLOR_MASK        (~0)
- 
- #define STATE3D_LOAD_STATE_IMMEDIATE_1	(CMD_3D | (0x1d<<24)|(0x04<<16))
- #define I1_LOAD_S(n)				(1 << (4 + n))
- 
- #define S0_VB_OFFSET_MASK              0xffffffc
- #define S0_AUTO_CACHE_INV_DISABLE      (1<<0)
- 
- #define S1_VERTEX_WIDTH_SHIFT          24
- #define S1_VERTEX_WIDTH_MASK           (0x3f<<24)
- #define S1_VERTEX_PITCH_SHIFT          16
- #define S1_VERTEX_PITCH_MASK           (0x3f<<16)
- 
- #define TEXCOORDFMT_2D                 0x0
- #define TEXCOORDFMT_3D                 0x1
- #define TEXCOORDFMT_4D                 0x2
- #define TEXCOORDFMT_1D                 0x3
- #define TEXCOORDFMT_2D_16              0x4
- #define TEXCOORDFMT_4D_16              0x5
- #define TEXCOORDFMT_NOT_PRESENT        0xf
- #define S2_TEXCOORD_FMT0_MASK            0xf
- #define S2_TEXCOORD_FMT1_SHIFT           4
- #define S2_TEXCOORD_FMT(unit, type)    ((type)<<(unit*4))
- #define S2_TEXCOORD_NONE               (~0)
- 
- /* S3 not interesting */
- 
- #define S4_POINT_WIDTH_SHIFT           23
- #define S4_POINT_WIDTH_MASK            (0x1ff<<23)
- #define S4_LINE_WIDTH_SHIFT            19
- #define S4_LINE_WIDTH_ONE              (0x2<<19)
- #define S4_LINE_WIDTH_MASK             (0xf<<19)
- #define S4_FLATSHADE_ALPHA             (1<<18)
- #define S4_FLATSHADE_FOG               (1<<17)
- #define S4_FLATSHADE_SPECULAR          (1<<16)
- #define S4_FLATSHADE_COLOR             (1<<15)
- #define S4_CULLMODE_BOTH	       (0<<13)
- #define S4_CULLMODE_NONE	       (1<<13)
- #define S4_CULLMODE_CW		       (2<<13)
- #define S4_CULLMODE_CCW		       (3<<13)
- #define S4_CULLMODE_MASK	       (3<<13)
- #define S4_VFMT_POINT_WIDTH            (1<<12)
- #define S4_VFMT_SPEC_FOG               (1<<11)
- #define S4_VFMT_COLOR                  (1<<10)
- #define S4_VFMT_DEPTH_OFFSET           (1<<9)
- #define S4_VFMT_XYZ     	       (1<<6)
- #define S4_VFMT_XYZW     	       (2<<6)
- #define S4_VFMT_XY     		       (3<<6)
- #define S4_VFMT_XYW     	       (4<<6)
- #define S4_VFMT_XYZW_MASK              (7<<6)
- #define S4_FORCE_DEFAULT_DIFFUSE       (1<<5)
- #define S4_FORCE_DEFAULT_SPECULAR      (1<<4)
- #define S4_LOCAL_DEPTH_OFFSET_ENABLE   (1<<3)
- #define S4_VFMT_FOG_PARAM              (1<<2)
- #define S4_SPRITE_POINT_ENABLE         (1<<1)
- #define S4_LINE_ANTIALIAS_ENABLE       (1<<0)
- 
- #define S4_VFMT_MASK (S4_VFMT_POINT_WIDTH   | 	\
- 		      S4_VFMT_SPEC_FOG      |	\
- 		      S4_VFMT_COLOR         |	\
- 		      S4_VFMT_DEPTH_OFFSET  |	\
- 		      S4_VFMT_XYZW_MASK     |	\
- 		      S4_VFMT_FOG_PARAM)
- 
- 
- #define S5_WRITEDISABLE_ALPHA          (1<<31)
- #define S5_WRITEDISABLE_RED            (1<<30)
- #define S5_WRITEDISABLE_GREEN          (1<<29)
- #define S5_WRITEDISABLE_BLUE           (1<<28)
- #define S5_WRITEDISABLE_MASK           (0xf<<28)
- #define S5_FORCE_DEFAULT_POINT_SIZE    (1<<27)
- #define S5_LAST_PIXEL_ENABLE           (1<<26)
- #define S5_GLOBAL_DEPTH_OFFSET_ENABLE  (1<<25)
- #define S5_FOG_ENABLE                  (1<<24)
- #define S5_STENCIL_REF_SHIFT           16
- #define S5_STENCIL_REF_MASK            (0xff<<16)
- #define S5_STENCIL_TEST_FUNC_SHIFT     13
- #define S5_STENCIL_TEST_FUNC_MASK      (0x7<<13)
- #define S5_STENCIL_FAIL_SHIFT          10
- #define S5_STENCIL_FAIL_MASK           (0x7<<10)
- #define S5_STENCIL_PASS_Z_FAIL_SHIFT   7
- #define S5_STENCIL_PASS_Z_FAIL_MASK    (0x7<<7)
- #define S5_STENCIL_PASS_Z_PASS_SHIFT   4
- #define S5_STENCIL_PASS_Z_PASS_MASK    (0x7<<4)
- #define S5_STENCIL_WRITE_ENABLE        (1<<3)
- #define S5_STENCIL_TEST_ENABLE         (1<<2)
- #define S5_COLOR_DITHER_ENABLE         (1<<1)
- #define S5_LOGICOP_ENABLE              (1<<0)
- 
- 
- #define S6_ALPHA_TEST_ENABLE           (1<<31)
- #define S6_ALPHA_TEST_FUNC_SHIFT       28
- #define S6_ALPHA_TEST_FUNC_MASK        (0x7<<28)
- #define S6_ALPHA_REF_SHIFT             20
- #define S6_ALPHA_REF_MASK              (0xff<<20)
- #define S6_DEPTH_TEST_ENABLE           (1<<19)
- #define S6_DEPTH_TEST_FUNC_SHIFT       16
- #define S6_DEPTH_TEST_FUNC_MASK        (0x7<<16)
- #define S6_CBUF_BLEND_ENABLE           (1<<15)
- #define S6_CBUF_BLEND_FUNC_SHIFT       12
- #define S6_CBUF_BLEND_FUNC_MASK        (0x7<<12)
- #define S6_CBUF_SRC_BLEND_FACT_SHIFT   8
- #define S6_CBUF_SRC_BLEND_FACT_MASK    (0xf<<8)
- #define S6_CBUF_DST_BLEND_FACT_SHIFT   4
- #define S6_CBUF_DST_BLEND_FACT_MASK    (0xf<<4)
- #define S6_DEPTH_WRITE_ENABLE          (1<<3)
- #define S6_COLOR_WRITE_ENABLE          (1<<2)
- #define S6_TRISTRIP_PV_SHIFT           0
- #define S6_TRISTRIP_PV_MASK            (0x3<<0)
- 
- #define S7_DEPTH_OFFSET_CONST_MASK     ~0
- 
- #define STATE3D_PIXEL_SHADER_PROGRAM	(CMD_3D | (0x1d<<24)|(0x05<<16))
- 
- #define REG_TYPE_R                 0 /* temporary regs, no need to
- 				      * dcl, must be written before
- 				      * read -- Preserved between
- 				      * phases. 
- 				      */
- #define REG_TYPE_T                 1 /* Interpolated values, must be
- 				      * dcl'ed before use.
- 				      *
- 				      * 0..7: texture coord,
- 				      * 8: diffuse spec,
- 				      * 9: specular color,
- 				      * 10: fog parameter in w.
- 				      */
- #define REG_TYPE_CONST             2 /* Restriction: only one const
- 				      * can be referenced per
- 				      * instruction, though it may be
- 				      * selected for multiple inputs.
- 				      * Constants not initialized
- 				      * default to zero.
- 				      */
- #define REG_TYPE_S                 3 /* sampler */
- #define REG_TYPE_OC                4 /* output color (rgba) */
- #define REG_TYPE_OD                5 /* output depth (w), xyz are
- 				      * temporaries.  If not written,
- 				      * interpolated depth is used?
- 				      */
- #define REG_TYPE_U                 6 /* unpreserved temporaries */
- #define REG_TYPE_MASK              0x7
- #define REG_NR_MASK                0xf
- 
- 
- /* REG_TYPE_T:
-  */
- #define T_TEX0     0
- #define T_TEX1     1
- #define T_TEX2     2
- #define T_TEX3     3
- #define T_TEX4     4
- #define T_TEX5     5
- #define T_TEX6     6
- #define T_TEX7     7
- #define T_DIFFUSE  8
- #define T_SPECULAR 9
- #define T_FOG_W    10		/* interpolated fog is in W coord */
- 
- /* Arithmetic instructions */
- 
- /* .replicate_swizzle == selection and replication of a particular
-  * scalar channel, ie., .xxxx, .yyyy, .zzzz or .wwww 
-  */
- #define A0_NOP    (0x0<<24)		/* no operation */
- #define A0_ADD    (0x1<<24)		/* dst = src0 + src1 */
- #define A0_MOV    (0x2<<24)		/* dst = src0 */
- #define A0_MUL    (0x3<<24)		/* dst = src0 * src1 */
- #define A0_MAD    (0x4<<24)		/* dst = src0 * src1 + src2 */
- #define A0_DP2ADD (0x5<<24)		/* dst.xyzw = src0.xy dot src1.xy + src2.replicate_swizzle */
- #define A0_DP3    (0x6<<24)		/* dst.xyzw = src0.xyz dot src1.xyz */
- #define A0_DP4    (0x7<<24)		/* dst.xyzw = src0.xyzw dot src1.xyzw */
- #define A0_FRC    (0x8<<24)		/* dst = src0 - floor(src0) */
- #define A0_RCP    (0x9<<24)		/* dst.xyzw = 1/(src0.replicate_swizzle) */
- #define A0_RSQ    (0xa<<24)		/* dst.xyzw = 1/(sqrt(abs(src0.replicate_swizzle))) */
- #define A0_EXP    (0xb<<24)		/* dst.xyzw = exp2(src0.replicate_swizzle) */
- #define A0_LOG    (0xc<<24)		/* dst.xyzw = log2(abs(src0.replicate_swizzle)) */
- #define A0_CMP    (0xd<<24)		/* dst = (src0 >= 0.0) ? src1 : src2 */
- #define A0_MIN    (0xe<<24)		/* dst = (src0 < src1) ? src0 : src1 */
- #define A0_MAX    (0xf<<24)		/* dst = (src0 >= src1) ? src0 : src1 */
- #define A0_FLR    (0x10<<24)		/* dst = floor(src0) */
- #define A0_MOD    (0x11<<24)		/* dst = src0 fmod 1.0 */
- #define A0_TRC    (0x12<<24)		/* dst = int(src0) */
- #define A0_SGE    (0x13<<24)		/* dst = src0 >= src1 ? 1.0 : 0.0 */
- #define A0_SLT    (0x14<<24)		/* dst = src0 < src1 ? 1.0 : 0.0 */
- #define A0_DEST_SATURATE                 (1<<22)
- #define A0_DEST_TYPE_SHIFT                19
- /* Allow: R, OC, OD, U */
- #define A0_DEST_NR_SHIFT                 14
- /* Allow R: 0..15, OC,OD: 0..0, U: 0..2 */
- #define A0_DEST_CHANNEL_X                (1<<10)
- #define A0_DEST_CHANNEL_Y                (2<<10)
- #define A0_DEST_CHANNEL_Z                (4<<10)
- #define A0_DEST_CHANNEL_W                (8<<10)
- #define A0_DEST_CHANNEL_ALL              (0xf<<10)
- #define A0_DEST_CHANNEL_SHIFT            10
- #define A0_SRC0_TYPE_SHIFT               7
- #define A0_SRC0_NR_SHIFT                 2
- 
- #define A0_DEST_CHANNEL_XY              (A0_DEST_CHANNEL_X|A0_DEST_CHANNEL_Y)
- #define A0_DEST_CHANNEL_XYZ             (A0_DEST_CHANNEL_XY|A0_DEST_CHANNEL_Z)
- 
- 
- #define SRC_X        0
- #define SRC_Y        1
- #define SRC_Z        2
- #define SRC_W        3
- #define SRC_ZERO     4
- #define SRC_ONE      5
- 
- #define A1_SRC0_CHANNEL_X_NEGATE         (1<<31)
- #define A1_SRC0_CHANNEL_X_SHIFT          28
- #define A1_SRC0_CHANNEL_Y_NEGATE         (1<<27)
- #define A1_SRC0_CHANNEL_Y_SHIFT          24
- #define A1_SRC0_CHANNEL_Z_NEGATE         (1<<23)
- #define A1_SRC0_CHANNEL_Z_SHIFT          20
- #define A1_SRC0_CHANNEL_W_NEGATE         (1<<19)
- #define A1_SRC0_CHANNEL_W_SHIFT          16
- #define A1_SRC1_TYPE_SHIFT               13
- #define A1_SRC1_NR_SHIFT                 8
- #define A1_SRC1_CHANNEL_X_NEGATE         (1<<7)
- #define A1_SRC1_CHANNEL_X_SHIFT          4
- #define A1_SRC1_CHANNEL_Y_NEGATE         (1<<3)
- #define A1_SRC1_CHANNEL_Y_SHIFT          0
- 
- #define A2_SRC1_CHANNEL_Z_NEGATE         (1<<31)
- #define A2_SRC1_CHANNEL_Z_SHIFT          28
- #define A2_SRC1_CHANNEL_W_NEGATE         (1<<27)
- #define A2_SRC1_CHANNEL_W_SHIFT          24
- #define A2_SRC2_TYPE_SHIFT               21
- #define A2_SRC2_NR_SHIFT                 16
- #define A2_SRC2_CHANNEL_X_NEGATE         (1<<15)
- #define A2_SRC2_CHANNEL_X_SHIFT          12
- #define A2_SRC2_CHANNEL_Y_NEGATE         (1<<11)
- #define A2_SRC2_CHANNEL_Y_SHIFT          8
- #define A2_SRC2_CHANNEL_Z_NEGATE         (1<<7)
- #define A2_SRC2_CHANNEL_Z_SHIFT          4
- #define A2_SRC2_CHANNEL_W_NEGATE         (1<<3)
- #define A2_SRC2_CHANNEL_W_SHIFT          0
- 
- 
- 
- /* Texture instructions */
- #define T0_TEXLD     (0x15<<24)	/* Sample texture using predeclared
- 				 * sampler and address, and output
- 				 * filtered texel data to destination
- 				 * register */
- #define T0_TEXLDP    (0x16<<24)	/* Same as texld but performs a
- 				 * perspective divide of the texture
- 				 * coordinate .xyz values by .w before
- 				 * sampling. */
- #define T0_TEXLDB    (0x17<<24)	/* Same as texld but biases the
- 				 * computed LOD by w.  Only S4.6 two's
- 				 * comp is used.  This implies that a
- 				 * float to fixed conversion is
- 				 * done. */
- #define T0_TEXKILL   (0x18<<24)	/* Does not perform a sampling
- 				 * operation.  Simply kills the pixel
- 				 * if any channel of the address
- 				 * register is < 0.0. */
- #define T0_DEST_TYPE_SHIFT                19
- /* Allow: R, OC, OD, U */
- /* Note: U (unpreserved) regs do not retain their values between
-  * phases (cannot be used for feedback) 
-  *
-  * Note: oC and OD registers can only be used as the destination of a
-  * texture instruction once per phase (this is an implementation
-  * restriction). 
-  */
- #define T0_DEST_NR_SHIFT                 14
- /* Allow R: 0..15, OC,OD: 0..0, U: 0..2 */
- #define T0_SAMPLER_NR_SHIFT              0 /* This field ignored for TEXKILL */
- #define T0_SAMPLER_NR_MASK               (0xf<<0)
- 
- #define T1_ADDRESS_REG_TYPE_SHIFT        24 /* Reg to use as texture coord */
- /* Allow R, T, OC, OD -- R, OC, OD are 'dependent' reads, new program phase */
- #define T1_ADDRESS_REG_NR_SHIFT          17
- #define T2_MBZ                           0
- 
- /* Declaration instructions */
- #define D0_DCL       (0x19<<24)	/* Declare a t (interpolated attrib)
- 				 * register or an s (sampler)
- 				 * register. */
- #define D0_SAMPLE_TYPE_SHIFT              22
- #define D0_SAMPLE_TYPE_2D                 (0x0<<22)
- #define D0_SAMPLE_TYPE_CUBE               (0x1<<22)
- #define D0_SAMPLE_TYPE_VOLUME             (0x2<<22)
- #define D0_SAMPLE_TYPE_MASK               (0x3<<22)
- 
- #define D0_TYPE_SHIFT                19
- /* Allow: T, S */
- #define D0_NR_SHIFT                  14
- /* Allow T: 0..10, S: 0..15 */
- #define D0_CHANNEL_X                (1<<10)
- #define D0_CHANNEL_Y                (2<<10)
- #define D0_CHANNEL_Z                (4<<10)
- #define D0_CHANNEL_W                (8<<10)
- #define D0_CHANNEL_ALL              (0xf<<10)
- #define D0_CHANNEL_NONE             (0<<10)
- 
- #define D0_CHANNEL_XY               (D0_CHANNEL_X|D0_CHANNEL_Y)
- #define D0_CHANNEL_XYZ              (D0_CHANNEL_XY|D0_CHANNEL_Z)
- /* End description of STATE3D_PIXEL_SHADER_PROGRAM */
- 
- #define STATE3D_PIXEL_SHADER_CONSTANTS	(CMD_3D | (0x1d<<24)|(0x06<<16))
- 
- #define STATE3D_DRAWING_RECTANGLE	(CMD_3D | (0x1d<<24)|(0x80<<16)|3)
- 
- #define STATE3D_SCISSOR_RECTANGLE	(CMD_3D | (0x1d<<24)|(0x81<<16)|1)
- 
- #define STATE3D_STIPPLE			(CMD_3D | (0x1d<<24)|(0x83<<16))
- #define ST1_ENABLE               (1<<16)
- #define ST1_MASK                 (0xffff)
- 
- #define STATE3D_DEST_BUFFER_VARIABLES	(CMD_3D | (0x1d<<24)|(0x85<<16))
- #define TEX_DEFAULT_COLOR_OGL           (0<<30)
- #define TEX_DEFAULT_COLOR_D3D           (1<<30)
- #define ZR_EARLY_DEPTH                  (1<<29)
- #define LOD_PRECLAMP_OGL                (1<<28)
- #define LOD_PRECLAMP_D3D                (0<<28)
- #define DITHER_FULL_ALWAYS              (0<<26)
- #define DITHER_FULL_ON_FB_BLEND         (1<<26)
- #define DITHER_CLAMPED_ALWAYS           (2<<26)
- #define LINEAR_GAMMA_BLEND_32BPP        (1<<25)
- #define DEBUG_DISABLE_ENH_DITHER        (1<<24)
- #define DSTORG_HORIZ_BIAS(x)		((x)<<20)
- #define DSTORG_VERT_BIAS(x)		((x)<<16)
- #define COLOR_4_2_2_CHNL_WRT_ALL	0
- #define COLOR_4_2_2_CHNL_WRT_Y		(1<<12)
- #define COLOR_4_2_2_CHNL_WRT_CR		(2<<12)
- #define COLOR_4_2_2_CHNL_WRT_CB		(3<<12)
- #define COLOR_4_2_2_CHNL_WRT_CRCB	(4<<12)
- #define COLR_BUF_8BIT			0
- #define COLR_BUF_RGB555 		(1<<8)
- #define COLR_BUF_RGB565 		(2<<8)
- #define COLR_BUF_ARGB8888		(3<<8)
- #define DEPTH_FRMT_16_FIXED		0
- #define DEPTH_FRMT_16_FLOAT		(1<<2)
- #define DEPTH_FRMT_24_FIXED_8_OTHER	(2<<2)
- #define VERT_LINE_STRIDE_1		(1<<1)
- #define VERT_LINE_STRIDE_0		(0<<1)
- #define VERT_LINE_STRIDE_OFS_1		1
- #define VERT_LINE_STRIDE_OFS_0		0
- 
- #define STATE3D_CONST_BLEND_COLOR	(CMD_3D | (0x1d<<24)|(0x88<<16))
- 
  #define STATE3D_FOG_MODE		((3<<29)|(0x1d<<24)|(0x89<<16)|2)
  #define FOG_MODE_VERTEX 		(1<<31)
--#define STATE3D_MAP_COORD_TRANSFORM	((3<<29)|(0x1d<<24)|(0x8c<<16))
- 
- #define STATE3D_BUFFER_INFO		(CMD_3D | (0x1d<<24)|(0x8e<<16)|1)
- #define BUFFERID_COLOR_BACK		(3 << 24)
- #define BUFFERID_COLOR_AUX		(4 << 24)
- #define BUFFERID_MC_INTRA_CORR		(5 << 24)
- #define BUFFERID_DEPTH			(7 << 24)
- #define BUFFER_USE_FENCES		(1 << 23)
- 
- #define STATE3D_DFLT_Z_CMD		(CMD_3D | (0x1d<<24)|(0x98<<16))
- 
- #define STATE3D_DFLT_DIFFUSE_CMD	(CMD_3D | (0x1d<<24)|(0x99<<16))
- 
- #define STATE3D_DFLT_SPEC_CMD		(CMD_3D | (0x1d<<24)|(0x9a<<16))
- 
- #define PRIMITIVE3D			(CMD_3D | (0x1f<<24))
- #define PRIM3D_INLINE		(0<<23)
- #define PRIM3D_INDIRECT		(1<<23)
- #define PRIM3D_TRILIST		(0x0<<18)
- #define PRIM3D_TRISTRIP 	(0x1<<18)
- #define PRIM3D_TRISTRIP_RVRSE	(0x2<<18)
- #define PRIM3D_TRIFAN		(0x3<<18)
- #define PRIM3D_POLY		(0x4<<18)
- #define PRIM3D_LINELIST 	(0x5<<18)
- #define PRIM3D_LINESTRIP	(0x6<<18)
- #define PRIM3D_RECTLIST 	(0x7<<18)
- #define PRIM3D_POINTLIST	(0x8<<18)
- #define PRIM3D_DIB		(0x9<<18)
- #define PRIM3D_CLEAR_RECT	(0xa<<18)
- #define PRIM3D_ZONE_INIT	(0xd<<18)
- #define PRIM3D_MASK		(0x1f<<18)
- 
 +
  #define DISABLE_TEX_TRANSFORM		(1<<28)
  #define TEXTURE_SET(x)			(x<<29)
 -#define STATE3D_RASTERIZATION_RULES	((3<<29)|(0x07<<24))
 -#define POINT_RASTER_ENABLE		(1<<15)
 -#define POINT_RASTER_OGL		(1<<13)
 +
  #define STATE3D_VERTEX_TRANSFORM	((3<<29)|(0x1d<<24)|(0x8b<<16))
  #define DISABLE_VIEWPORT_TRANSFORM	(1<<31)
  #define DISABLE_PERSPECTIVE_DIVIDE	(1<<29)
diff --cc src/i830_video.c
index 37dcaa7,a608a7e..044d6c1
@@@ -77,6 -77,6 +77,7 @@@
  #include "regionstr.h"
  #include "randrstr.h"
  #include "i830.h"
++#include "i830_video.h"
  #include "xf86xv.h"
  #include <X11/extensions/Xv.h>
  #include "xaa.h"
@@@ -369,46 -360,45 +370,6 @@@
     CARD16 RESERVEDG[0x100 / 2 - N_HORIZ_UV_TAPS * N_PHASES];
  } I830OverlayRegRec, *I830OverlayRegPtr;
  
--typedef struct {
--   CARD32 YBuf0offset;
--   CARD32 UBuf0offset;
--   CARD32 VBuf0offset;
--
--   CARD32 YBuf1offset;
--   CARD32 UBuf1offset;
--   CARD32 VBuf1offset;
--
--   unsigned char currentBuf;
--
--   int brightness;
--   int contrast;
--   int pipe;
--   int doubleBuffer;
--
--   RegionRec clip;
--   CARD32 colorKey;
--
--   CARD32 gamma0;
--   CARD32 gamma1;
--   CARD32 gamma2;
--   CARD32 gamma3;
--   CARD32 gamma4;
--   CARD32 gamma5;
--
--   CARD32 videoStatus;
--   Time offTime;
--   Time freeTime;
--   FBLinearPtr linear;
--
--   Bool overlayOK;
--   int oneLineMode;
--   int scaleRatio;
-    Bool textured;
--} I830PortPrivRec, *I830PortPrivPtr;
--
--#define GET_PORT_PRIVATE(pScrn) \
--   (I830PortPrivPtr)((I830PTR(pScrn))->adaptor->pPortPrivates[0].ptr)
--
  #if VIDEO_DEBUG
  static void
  CompareOverlay(I830Ptr pI830, CARD32 * overlay, int size)
diff --cc src/i830_video.h
index 0000000,0000000..9e11641
new file mode 100644
@@@ -1,0 -1,0 +1,76 @@@
++/***************************************************************************
++ 
++Copyright 2000 Intel Corporation.  All Rights Reserved. 
++
++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, sub license, 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 NON-INFRINGEMENT. 
++IN NO EVENT SHALL INTEL, AND/OR ITS SUPPLIERS 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.
++
++**************************************************************************/
++
++#include "xf86.h"
++#include "xf86_OSproc.h"
++
++typedef struct {
++   CARD32 YBuf0offset;
++   CARD32 UBuf0offset;
++   CARD32 VBuf0offset;
++
++   CARD32 YBuf1offset;
++   CARD32 UBuf1offset;
++   CARD32 VBuf1offset;
++
++   unsigned char currentBuf;
++
++   int brightness;
++   int contrast;
++   int pipe;
++   int doubleBuffer;
++
++   RegionRec clip;
++   CARD32 colorKey;
++
++   CARD32 gamma0;
++   CARD32 gamma1;
++   CARD32 gamma2;
++   CARD32 gamma3;
++   CARD32 gamma4;
++   CARD32 gamma5;
++
++   CARD32 videoStatus;
++   Time offTime;
++   Time freeTime;
++   FBLinearPtr linear;
++
++   Bool overlayOK;
++   int oneLineMode;
++   int scaleRatio;
++   Bool textured;
++} I830PortPrivRec, *I830PortPrivPtr;
++
++#define GET_PORT_PRIVATE(pScrn) \
++   (I830PortPrivPtr)((I830PTR(pScrn))->adaptor->pPortPrivates[0].ptr)
++
++void I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv,
++			      int id, RegionPtr dstRegion, short width,
++			      short height, int video_pitch,
++			      int x1, int y1, int x2, int y2,
++			      short src_w, short src_h,
++			      short drw_w, short drw_h,
++			      DrawablePtr pDraw);
diff --cc src/i915_video.c
index 0000000,0000000..8d687a1
new file mode 100644
@@@ -1,0 -1,0 +1,538 @@@
++/*
++ * 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>
++ *
++ */
++
++#ifdef HAVE_CONFIG_H
++#include "config.h"
++#endif
++
++#include "xf86.h"
++#include "xf86_OSproc.h"
++#include "xf86xv.h"
++#include "fourcc.h"
++
++#include "i830.h"
++#include "i830_video.h"
++#include "i915_reg.h"
++
++union intfloat {
++   CARD32 ui;
++   float f;
++};
++
++#define OUT_RING_F(x) do {						\
++   union intfloat _tmp;							\
++   _tmp.f = x;								\
++   OUT_RING(_tmp.ui);							\
++} while (0)
++
++#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)
++
++/* Move the dest_chan from src0 to dest, leaving the other channels alone */
++#define OUT_MOV_TO_CHANNEL(dest_type, dest_nr, src0_type, src0_nr,	\
++			   dest_chan)					\
++do {									\
++   OUT_RING(A0_MOV | A0_DEST_CHANNEL_##dest_chan |			\
++	    (REG_TYPE_##dest_type << A0_DEST_TYPE_SHIFT) |		\
++	    (dest_nr << A0_DEST_NR_SHIFT) |				\
++	    (REG_TYPE_##src0_type << A0_SRC0_TYPE_SHIFT) |		\
++	    (src0_nr << 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));			\
++   OUT_RING(0);								\
++} while (0)
++
++/* Dot3-product src0 and src1, storing the result in dest_chan of the dest.
++ * Saturates, in case we have out-of-range YUV values.
++ */
++#define OUT_DP3_TO_CHANNEL(dest_type, dest_nr, src0_type, src0_nr,	\
++			   src1_type, src1_nr, dest_chan)		\
++do {									\
++   OUT_RING(A0_DP3 | A0_DEST_CHANNEL_##dest_chan | A0_DEST_SATURATE |	\
++	    (REG_TYPE_##dest_type << A0_DEST_TYPE_SHIFT) |		\
++	    (dest_nr << A0_DEST_NR_SHIFT) |				\
++	    (REG_TYPE_##src0_type << A0_SRC0_TYPE_SHIFT) |		\
++	    (src0_nr << 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_##src1_type << A1_SRC1_TYPE_SHIFT) |		\
++	    (src1_nr << A1_SRC1_TYPE_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));			\
++} while (0)
++
++void
++I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
++			 RegionPtr dstRegion,
++			 short width, short height, int video_pitch,
++			 int x1, int y1, int x2, int y2,
++			 short src_w, short src_h, short drw_w, short drw_h,
++			 DrawablePtr pDraw)
++{
++   I830Ptr pI830 = I830PTR(pScrn);
++   CARD32 format, ms3, s2;
++   BoxPtr pbox;
++   int nbox, dxo, dyo;
++   Bool planar;
++
++   ErrorF("I915DisplayVideo: %dx%d (pitch %d)\n", width, height,
++	  video_pitch);
++
++   switch (id) {
++   case FOURCC_UYVY:
++   case FOURCC_YUY2:
++      planar = FALSE;
++      break;
++   case FOURCC_YV12:
++   case FOURCC_I420:
++      planar = TRUE;
++      break;
++   default:
++      ErrorF("Unknown format 0x%x\n", id);
++      planar = FALSE;
++      break;
++   }
++
++   /* Tell the rotation code that we have stomped its invariant state by
++    * setting a high bit.  We don't use any invariant 3D state for video, so we
++    * don't have to worry about it ourselves.
++    */
++   *pI830->used3D |= 1 << 30;
++
++   BEGIN_LP_RING(44);
++
++   /* invarient state */
++   OUT_RING(MI_NOOP);
++   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(_3DSTATE_DFLT_SPEC_CMD);
++   OUT_RING(0x00000000);
++
++   OUT_RING(_3DSTATE_DFLT_Z_CMD);
++   OUT_RING(0x00000000);
++
++   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); /* texture coordinate wrap */
++
++   /* flush map & render cache */
++   OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE);
++   OUT_RING(0x00000000);
++
++   /* draw rect -- just clipping */
++   OUT_RING(_3DSTATE_DRAW_RECT_CMD);
++   OUT_RING(0x00000000);	/* flags */
++   OUT_RING(0x00000000);	/* ymin, xmin */
++   OUT_RING((pScrn->virtualX - 1) |
++	    (pScrn->virtualY - 1) << 16); /* ymax, xmax */
++   OUT_RING(0x00000000);	/* yorigin, xorigin */
++   OUT_RING(MI_NOOP);
++
++   /* scissor */
++   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);	/* unknown command */
++   OUT_RING(0x7d070000);
++   OUT_RING(0x00000000);
++   OUT_RING(0x68000002);
++
++   /* context setup */
++   OUT_RING(_3DSTATE_MODES_4_CMD |
++	    ENABLE_LOGIC_OP_FUNC | LOGIC_OP_FUNC(LOGICOP_COPY) |
++	    ENABLE_STENCIL_WRITE_MASK | STENCIL_WRITE_MASK(0xff) |
++	    ENABLE_STENCIL_TEST_MASK | STENCIL_TEST_MASK(0xff));
++
++   OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) |
++	    I1_LOAD_S(4) | I1_LOAD_S(5) | I1_LOAD_S(6) | 4);
++   s2 = S2_TEXCOORD_FMT(0, TEXCOORDFMT_2D);
++   if (planar)
++      s2 |= S2_TEXCOORD_FMT(1, TEXCOORDFMT_2D);
++   else
++      s2 |= S2_TEXCOORD_FMT(1, TEXCOORDFMT_NOT_PRESENT);
++   s2 |= 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(s2);
++   OUT_RING((1 << S4_POINT_WIDTH_SHIFT) | S4_LINE_WIDTH_ONE |
++	    S4_CULLMODE_NONE | S4_VFMT_XY);
++   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 == 2)
++      format = COLR_BUF_RGB565;
++   else
++      format = COLR_BUF_ARGB8888 | DEPTH_FRMT_24_FIXED_8_OTHER;
++
++   OUT_RING(LOD_PRECLAMP_OGL |
++     DSTORG_HORT_BIAS(0x80) | DSTORG_VERT_BIAS(0x80) | format);
++
++   OUT_RING(_3DSTATE_STIPPLE);
++   OUT_RING(0x00000000);
++
++   /* front buffer, pitch, offset */
++   OUT_RING(_3DSTATE_BUF_INFO_CMD);
++   OUT_RING(BUF_3D_ID_COLOR_BACK | BUF_3D_USE_FENCE |
++	    (((pI830->displayWidth * pI830->cpp) / 4) << 2));
++   OUT_RING(pI830->bufferOffset);
++   ADVANCE_LP_RING();
++
++   if (!planar) {
++      BEGIN_LP_RING(20);
++      /* fragment program - texture blend replace. */
++      OUT_RING(_3DSTATE_PIXEL_SHADER_PROGRAM | 8);
++      OUT_DCL(S, 0);
++      OUT_DCL(T, 0);
++      OUT_TEXLD(OC, 0, 0, T, 0);
++      /* End fragment program */
++
++      OUT_RING(_3DSTATE_SAMPLER_STATE | 3);
++      OUT_RING(0x00000001);
++      OUT_RING(SS2_COLORSPACE_CONVERSION |
++	       (FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) |
++	       (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT));
++      OUT_RING((TEXCOORDMODE_CLAMP_EDGE << SS3_TCX_ADDR_MODE_SHIFT) |
++	       (TEXCOORDMODE_CLAMP_EDGE << SS3_TCY_ADDR_MODE_SHIFT));
++      OUT_RING(0x00000000);
++
++      OUT_RING(_3DSTATE_MAP_STATE | 3);
++      OUT_RING(0x00000001);	/* texture map #1 */
++      OUT_RING(pPriv->YBuf0offset);
++      ms3 = MAPSURF_422;
++      switch (id) {
++      case FOURCC_YUY2:
++	 ms3 |= MT_422_YCRCB_NORMAL;
++	 break;
++      case FOURCC_UYVY:
++	 ms3 |= MT_422_YCRCB_SWAPY;
++	 break;
++      }
++      ms3 |= (height - 1) << MS3_HEIGHT_SHIFT;
++      ms3 |= (width - 1) << MS3_WIDTH_SHIFT;
++      if (!pI830->disableTiling)
++	 ms3 |= MS3_USE_FENCE_REGS;
++      OUT_RING(ms3);
++      OUT_RING(((video_pitch / 4) - 1) << 21);
++      ADVANCE_LP_RING();
++   } else {
++      BEGIN_LP_RING(1 + 18 + (1 + 3*16) + 11 + 11);
++      OUT_RING(MI_NOOP);
++      /* For the planar formats, we set up three samplers -- one for each plane,
++       * in a Y8 format.  Because I couldn't get the special PLANAR_TO_PACKED
++       * shader setup to work, I did the manual pixel shader:
++       *
++       * y' = y - .0625
++       * u' = u - .5
++       * v' = v - .5;
++       *
++       * r = 1.1643 * y' + 0.0     * u' + 1.5958  * v'
++       * g = 1.1643 * y' - 0.39173 * u' - 0.81290 * v'
++       * b = 1.1643 * y' + 2.017   * u' + 0.0     * v'
++       *
++       * register assignment:
++       * r0 = (y',u',v',0)
++       * r1 = (y,y,y,y)
++       * r2 = (u,u,u,u)
++       * r3 = (v,v,v,v)
++       * OC = (r,g,b,1)
++       */
++      OUT_RING(_3DSTATE_PIXEL_SHADER_CONSTANTS | 16);
++      OUT_RING(0x000000f);	/* constants 0-3 */
++      /* constant 0: normalization offsets */
++      OUT_RING_F(-0.0625);
++      OUT_RING_F(-0.5);
++      OUT_RING_F(-0.5);
++      OUT_RING_F(0.0);
++      /* constant 1: r coefficients*/
++      OUT_RING_F(1.1643);
++      OUT_RING_F(0.0);
++      OUT_RING_F(1.5958);
++      OUT_RING_F(0.0);
++      /* constant 2: g coefficients */
++      OUT_RING_F(1.1643);
++      OUT_RING_F(-0.39173);
++      OUT_RING_F(-0.81290);
++      OUT_RING_F(0.0);
++      /* constant 3: b coefficients */
++      OUT_RING_F(1.1643);
++      OUT_RING_F(2.017);
++      OUT_RING_F(0.0);
++      OUT_RING_F(0.0);
++
++      OUT_RING(_3DSTATE_PIXEL_SHADER_PROGRAM | (3 * 16 - 1));
++      /* Declare samplers */
++      OUT_DCL(S, 0);
++      OUT_DCL(S, 1);
++      OUT_DCL(S, 2);
++      OUT_DCL(T, 0);
++      OUT_DCL(T, 1);
++
++      /* Load samplers to temporaries.  Y (sampler 0) gets the un-halved coords
++       * from t1.
++       */
++      OUT_TEXLD(R, 1, 0, T, 1);
++      OUT_TEXLD(R, 2, 1, T, 0);
++      OUT_TEXLD(R, 3, 2, T, 0);
++
++      /* Move the sampled YUV data in R[123] to the first 3 channels of R0. */
++      OUT_MOV_TO_CHANNEL(R, 0, R, 1, X);
++      OUT_MOV_TO_CHANNEL(R, 0, R, 2, Y);
++      OUT_MOV_TO_CHANNEL(R, 0, R, 3, Z);
++
++      /* Normalize the YUV data */
++      OUT_RING(A0_ADD | A0_DEST_CHANNEL_ALL |
++	       (REG_TYPE_R << A0_DEST_TYPE_SHIFT) | (0 << A0_DEST_NR_SHIFT) |				\
++	       (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_CONST << A1_SRC1_TYPE_SHIFT) | (0 << 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));
++
++      /* dot-product the YUV data in R0 by the vectors of coefficients for
++       * calculating R, G, and B, storing the results in the R, G, or B channels
++       * of the output color.
++       */
++      OUT_DP3_TO_CHANNEL(OC, 0, R, 0, CONST, 1, X);
++      OUT_DP3_TO_CHANNEL(OC, 0, R, 0, CONST, 2, Y);
++      OUT_DP3_TO_CHANNEL(OC, 0, R, 0, CONST, 3, Z);
++
++      /* Set alpha of the output to 1.0, by wiring W to 1 and not actually using
++       * the source.
++       */
++      OUT_RING(A0_MOV | A0_DEST_CHANNEL_W |
++	       (REG_TYPE_OC << A0_DEST_TYPE_SHIFT) | (0 << A0_DEST_NR_SHIFT) |
++	       (REG_TYPE_OC << 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_ONE << A1_SRC0_CHANNEL_W_SHIFT));
++      OUT_RING(0);
++      /* End fragment program */
++
++      OUT_RING(_3DSTATE_SAMPLER_STATE | 9);
++      OUT_RING(0x00000007);
++      /* sampler 0 */
++      OUT_RING(0x00000000);
++      OUT_RING((FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) |
++	       (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT));
++      OUT_RING((TEXCOORDMODE_CLAMP_EDGE << SS3_TCX_ADDR_MODE_SHIFT) |
++	       (TEXCOORDMODE_CLAMP_EDGE << SS3_TCY_ADDR_MODE_SHIFT));
++      /* sampler 1 */
++      OUT_RING(0x00000000);
++      OUT_RING((FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) |
++	       (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT));
++      OUT_RING((TEXCOORDMODE_CLAMP_EDGE << SS3_TCX_ADDR_MODE_SHIFT) |
++	       (TEXCOORDMODE_CLAMP_EDGE << SS3_TCY_ADDR_MODE_SHIFT));
++      /* sampler 2 */
++      OUT_RING(0x00000000);
++      OUT_RING((FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) |
++	       (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT));
++      OUT_RING((TEXCOORDMODE_CLAMP_EDGE << SS3_TCX_ADDR_MODE_SHIFT) |
++	       (TEXCOORDMODE_CLAMP_EDGE << SS3_TCY_ADDR_MODE_SHIFT));
++
++      OUT_RING(_3DSTATE_MAP_STATE | 9);
++      OUT_RING(0x00000007);
++
++      OUT_RING(pPriv->YBuf0offset);
++      ms3 = MAPSURF_8BIT | MT_8BIT_I8;
++      ms3 |= (height - 1) << MS3_HEIGHT_SHIFT;
++      ms3 |= (width - 1) << MS3_WIDTH_SHIFT;
++      OUT_RING(ms3);
++      OUT_RING(((video_pitch * 2 / 4) - 1) << 21);
++
++      OUT_RING(pPriv->UBuf0offset);
++      ms3 = MAPSURF_8BIT | MT_8BIT_I8;
++      ms3 |= (height / 2 - 1) << MS3_HEIGHT_SHIFT;
++      ms3 |= (width / 2 - 1) << MS3_WIDTH_SHIFT;
++      OUT_RING(ms3);
++      OUT_RING(((video_pitch / 4) - 1) << 21);
++
++      OUT_RING(pPriv->VBuf0offset);
++      ms3 = MAPSURF_8BIT | MT_8BIT_I8;
++      ms3 |= (height / 2 - 1) << MS3_HEIGHT_SHIFT;
++      ms3 |= (width / 2 - 1) << MS3_WIDTH_SHIFT;
++      OUT_RING(ms3);
++      OUT_RING(((video_pitch / 4) - 1) << 21);
++      ADVANCE_LP_RING();
++   }
++   
++   {
++      BEGIN_LP_RING(2);
++      OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE);
++      OUT_RING(0x00000000);
++      ADVANCE_LP_RING();
++   }
++
++   dxo = dstRegion->extents.x1;
++   dyo = dstRegion->extents.y1;
++
++   pbox = REGION_RECTS(dstRegion);
++   nbox = REGION_NUM_RECTS(dstRegion);
++   while (nbox--)
++   {
++      int box_x1 = pbox->x1;
++      int box_y1 = pbox->y1;
++      int box_x2 = pbox->x2;
++      int box_y2 = pbox->y2;
++      float src_scale_x, src_scale_y;
++      int vert_data_count;
++
++      pbox++;
++
++      src_scale_x = (float)src_w / (float)drw_w;
++      src_scale_y  = (float)src_h / (float)drw_h;
++
++      if (!planar)
++	 vert_data_count = 12;
++      else
++	 vert_data_count = 18;
++
++      BEGIN_LP_RING(vert_data_count + 8);
++      OUT_RING(MI_NOOP);
++      OUT_RING(MI_NOOP);
++      OUT_RING(MI_NOOP);
++      OUT_RING(MI_NOOP);
++      OUT_RING(MI_NOOP);
++      OUT_RING(MI_NOOP);
++      OUT_RING(MI_NOOP);
++
++      /* vertex data - rect list consists of bottom right, bottom left, and top
++       * left vertices.
++       */
++      OUT_RING(PRIM3D_INLINE | PRIM3D_RECTLIST |
++	       (vert_data_count - 1));
++
++      /* bottom right */
++      OUT_RING_F(box_x2);
++      OUT_RING_F(box_y2);
++      if (!planar) {
++	 OUT_RING_F((box_x2 - dxo) * src_scale_x);
++	 OUT_RING_F((box_y2 - dyo) * src_scale_y);
++      } else {
++	 OUT_RING_F((box_x2 - dxo) * src_scale_x / 2.0);
++	 OUT_RING_F((box_y2 - dyo) * src_scale_y / 2.0);
++	 OUT_RING_F((box_x2 - dxo) * src_scale_x);
++	 OUT_RING_F((box_y2 - dyo) * src_scale_y);
++      }
++
++      /* bottom left */
++      OUT_RING_F(box_x1);
++      OUT_RING_F(box_y2);
++      if (!planar) {
++	 OUT_RING_F((box_x1 - dxo) * src_scale_x);
++	 OUT_RING_F((box_y2 - dyo) * src_scale_y);
++      } else {
++	 OUT_RING_F((box_x1 - dxo) * src_scale_x / 2.0);
++	 OUT_RING_F((box_y2 - dyo) * src_scale_y / 2.0);
++	 OUT_RING_F((box_x1 - dxo) * src_scale_x);
++	 OUT_RING_F((box_y2 - dyo) * src_scale_y);
++      }
++
++      /* top left */
++      OUT_RING_F(box_x1);
++      OUT_RING_F(box_y1);
++      if (!planar) {
++	 OUT_RING_F((box_x1 - dxo) * src_scale_x);
++	 OUT_RING_F((box_y1 - dyo) * src_scale_y);
++      } else {
++	 OUT_RING_F((box_x1 - dxo) * src_scale_x / 2.0);
++	 OUT_RING_F((box_y1 - dyo) * src_scale_y / 2.0);
++	 OUT_RING_F((box_x1 - dxo) * src_scale_x);
++	 OUT_RING_F((box_y1 - dyo) * src_scale_y);
++      }
++
++      ADVANCE_LP_RING();
++   }
++
++   if (pI830->AccelInfoRec)
++      pI830->AccelInfoRec->NeedToSync = TRUE;
++}
++
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;
    }
diff-tree e7723a4e5725147d3bd9ba22c5a3314b0556e440 (from parents)
Merge: 5111b883480a5a9cc82200f2684cba67b515aa73 dae9cb7712d5d8f88697ca83808c59af08364c0e
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Mon Jun 26 16:04:33 2006 +0200

    Merge branch 'origin'

diff-tree dae9cb7712d5d8f88697ca83808c59af08364c0e (from 5a1b68993f3a3a2e8dcd428a7118e29c36703cd6)
Author: Alan Coopersmith <alan.coopersmith at sun.com>
Date:   Thu Jun 22 15:07:16 2006 -0700

    Provide definitions of __FUNCTION__ for non-gcc compilers

diff --git a/src/common.h b/src/common.h
index a6e4ca3..31e67b9 100644
--- a/src/common.h
+++ b/src/common.h
@@ -39,13 +39,18 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #ifndef _INTEL_COMMON_H_
 #define _INTEL_COMMON_H_
 
-#ifdef __GNUC__
+/* Provide substitutes for gcc's __FUNCTION__ on other compilers */
+#ifndef __GNUC__
+# if defined(__STDC__) && (__STDC_VERSION__>=199901L) /* C99 */
+#  define __FUNCTION__ __func__
+# else
+#  define __FUNCTION__ ""
+# endif
+#endif
+
+
 #define PFX __FILE__,__LINE__,__FUNCTION__
 #define FUNCTION_NAME __FUNCTION__
-#else
-#define PFX __FILE__,__LINE__,""
-#define FUNCTION_NAME ""
-#endif
 
 #ifdef I830DEBUG
 #define MARKER() ErrorF("\n### %s:%d: >>> %s <<< ###\n\n", \
diff-tree 5a1b68993f3a3a2e8dcd428a7118e29c36703cd6 (from 16b310823bacab6be4947da234b3a081b0a3cd62)
Author: Alan Hourihane <alanh at fairlite.demon.co.uk>
Date:   Wed Jun 21 08:41:16 2006 +0100

    Fix build without DRI

diff --git a/src/Makefile.am b/src/Makefile.am
index ef8fc64..2745e8c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -55,16 +55,16 @@ i810_drv_la_SOURCES = \
          i830_video.c \
          i830_rotate.c \
 	 i830_randr.c \
+	 i830_3d.c \
 	 i830_reg.h \
+	 i915_3d.c \
 	 i915_reg.h
 
 if DRI
 i810_drv_la_SOURCES += \
-	 i830_3d.c \
          i810_dri.c \
          i810_dri.h \
          i830_dri.c \
          i810_hwmc.c \
-	 i915_3d.c \
          i830_dri.h 
 endif
diff --git a/src/i830.h b/src/i830.h
index 4fc3987..ac95e36 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -395,6 +395,8 @@ extern void I830Sync(ScrnInfoPtr pScrn);
 extern void I830InitHWCursor(ScrnInfoPtr pScrn);
 extern Bool I830CursorInit(ScreenPtr pScreen);
 extern void IntelEmitInvarientState(ScrnInfoPtr pScrn);
+extern void I830EmitInvarientState(ScrnInfoPtr pScrn);
+extern void I915EmitInvarientState(ScrnInfoPtr pScrn);
 extern void I830SelectBuffer(ScrnInfoPtr pScrn, int buffer);
 
 extern void I830RefreshRing(ScrnInfoPtr pScrn);
diff --git a/src/i830_3d.c b/src/i830_3d.c
index 547e556..0efd6e4 100644
--- a/src/i830_3d.c
+++ b/src/i830_3d.c
@@ -30,7 +30,6 @@
 #endif
 
 #include "i830.h"
-#include "i830_dri.h"
 
 #include "i830_reg.h"
 
diff --git a/src/i830_dri.c b/src/i830_dri.c
index 7c65f65..6f9a3ee 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -1182,35 +1182,6 @@ I830DRIMoveBuffers(WindowPtr pParent, DD
    pI830->AccelInfoRec->NeedToSync = TRUE;
 }
 
-extern I830EmitInvarientState(ScrnInfoPtr pScrn);
-extern I915EmitInvarientState(ScrnInfoPtr pScrn);
-
-/* Initialize the first context */
-void
-IntelEmitInvarientState(ScrnInfoPtr pScrn)
-{
-   I830Ptr pI830 = I830PTR(pScrn);
-   CARD32 ctx_addr;
-
-   ctx_addr = pI830->ContextMem.Start;
-   /* Align to a 2k boundry */
-   ctx_addr = ((ctx_addr + 2048 - 1) / 2048) * 2048;
-
-   {
-      BEGIN_LP_RING(2);
-      OUT_RING(MI_SET_CONTEXT);
-      OUT_RING(ctx_addr |
-	       CTXT_NO_RESTORE |
-	       CTXT_PALETTE_SAVE_DISABLE | CTXT_PALETTE_RESTORE_DISABLE);
-      ADVANCE_LP_RING();
-   }
-
-   if (IS_I9XX(pI830))
-      I915EmitInvarientState(pScrn);
-   else
-      I830EmitInvarientState(pScrn);
-}
-
 /* Use callbacks from dri.c to support pageflipping mode for a single
  * 3d context without need for any specific full-screen extension.
  *
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 907b204..80a46a4 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -4755,6 +4755,32 @@ I830InitFBManager(
    return ret;
 }
 
+/* Initialize the first context */
+void
+IntelEmitInvarientState(ScrnInfoPtr pScrn)
+{
+   I830Ptr pI830 = I830PTR(pScrn);
+   CARD32 ctx_addr;
+
+   ctx_addr = pI830->ContextMem.Start;
+   /* Align to a 2k boundry */
+   ctx_addr = ((ctx_addr + 2048 - 1) / 2048) * 2048;
+
+   {
+      BEGIN_LP_RING(2);
+      OUT_RING(MI_SET_CONTEXT);
+      OUT_RING(ctx_addr |
+	       CTXT_NO_RESTORE |
+	       CTXT_PALETTE_SAVE_DISABLE | CTXT_PALETTE_RESTORE_DISABLE);
+      ADVANCE_LP_RING();
+   }
+
+   if (IS_I9XX(pI830))
+      I915EmitInvarientState(pScrn);
+   else
+      I830EmitInvarientState(pScrn);
+}
+
 static Bool
 I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
 {
diff --git a/src/i915_3d.c b/src/i915_3d.c
index f6e7219..d8edb18 100644
--- a/src/i915_3d.c
+++ b/src/i915_3d.c
@@ -30,7 +30,6 @@
 #endif
 
 #include "i830.h"
-#include "i830_dri.h"
 
 #include "i915_reg.h"
 
diff-tree 16b310823bacab6be4947da234b3a081b0a3cd62 (from 8a6edba33213911cc2210b5e903428b81d45862f)
Author: Matthieu Herrb <matthieu at deville.herrb.com>
Date:   Wed Jun 21 00:12:27 2006 +0200

    Fix build without DRI

diff --git a/src/Makefile.am b/src/Makefile.am
index 2745e8c..ef8fc64 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -55,16 +55,16 @@ i810_drv_la_SOURCES = \
          i830_video.c \
          i830_rotate.c \
 	 i830_randr.c \
-	 i830_3d.c \
 	 i830_reg.h \
-	 i915_3d.c \
 	 i915_reg.h
 
 if DRI
 i810_drv_la_SOURCES += \
+	 i830_3d.c \
          i810_dri.c \
          i810_dri.h \
          i830_dri.c \
          i810_hwmc.c \
+	 i915_3d.c \
          i830_dri.h 
 endif
diff-tree 8a6edba33213911cc2210b5e903428b81d45862f (from a73ab7f0e6e3b0462e05c0031ffd602ed3e2bcd4)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Mon Jun 19 13:47:28 2006 -0700

    Set vblank interrupt configuration to match pipe configuration
    
    New i915 drm ioctl (in version 1.5) allows the X server to select
    which pipe drives vblank interrupts. Use this to drive from the 'preferred'
    pipe. Yes, per-window vblanks would be nice in a shared fb environment.
    Maybe someday.
    (cherry picked from 2fb375b665f4802819b89f2277fd6154006c11ee commit)

diff --git a/src/i830.h b/src/i830.h
index 4fa3328..4fc3987 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -427,6 +427,7 @@ extern void I830DRIUnmapScreenRegions(Sc
 extern Bool I830DRIMapScreenRegions(ScrnInfoPtr pScrn, drmI830Sarea *sarea);
 extern void I830DRIUnlock(ScrnInfoPtr pScrn);
 extern Bool I830DRILock(ScrnInfoPtr pScrn);
+extern Bool I830DRISetVBlankInterrupt (ScrnInfoPtr pScrn, Bool on);
 #endif
 
 extern Bool I830AccelInit(ScreenPtr pScreen);
diff --git a/src/i830_common.h b/src/i830_common.h
index 41b5cc3..a27bc01 100644
--- a/src/i830_common.h
+++ b/src/i830_common.h
@@ -52,6 +52,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define DRM_I830_INIT_HEAP                0x0a
 #define DRM_I830_CMDBUFFER                0x0b
 #define DRM_I830_DESTROY_HEAP             0x0c
+#define DRM_I830_SET_VBLANK_PIPE	  0x0d
+#define DRM_I830_GET_VBLANK_PIPE	  0x0e
+
 
 typedef struct {
    enum {
@@ -193,5 +196,11 @@ typedef struct {
 	int region;
 } drmI830MemDestroyHeap;
 
+#define	DRM_I830_VBLANK_PIPE_A	1
+#define	DRM_I830_VBLANK_PIPE_B	2
+
+typedef struct {
+	int pipe;
+} drmI830VBlankPipe;
 
 #endif /* _I830_DRM_H_ */
diff --git a/src/i830_dri.c b/src/i830_dri.c
index ed5e685..7c65f65 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -1454,6 +1454,31 @@ I830UpdateDRIBuffers(ScrnInfoPtr pScrn, 
 }
 
 Bool
+I830DRISetVBlankInterrupt (ScrnInfoPtr pScrn, Bool on)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+    drmI830VBlankPipe pipe;
+
+    if (pI830->directRenderingEnabled && pI830->drmMinor >= 5) {
+	if (on) {
+	    if (pI830->planeEnabled[1])
+		pipe.pipe = DRM_I830_VBLANK_PIPE_B;
+	    else
+		pipe.pipe = DRM_I830_VBLANK_PIPE_A;
+	} else {
+	    pipe.pipe = 0;
+	}
+	if (drmCommandWrite(pI830->drmSubFD, DRM_I830_SET_VBLANK_PIPE,
+			    &pipe, sizeof (pipe))) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "I830 Vblank Pipe Setup Failed\n");
+	    return FALSE;
+	}
+    }
+
+    return TRUE;
+}
+
+Bool
 I830DRILock(ScrnInfoPtr pScrn)
 {
    I830Ptr pI830 = I830PTR(pScrn);
diff --git a/src/i830_driver.c b/src/i830_driver.c
index a4b891b..907b204 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -3826,6 +3826,9 @@ RestoreHWState(ScrnInfoPtr pScrn)
 
    DPRINTF(PFX, "RestoreHWState\n");
 
+#ifdef XF86DRI
+   I830DRISetVBlankInterrupt (pScrn, FALSE);
+#endif
    if (I830IsPrimary(pScrn) && pI830->pipe != pI830->origPipe)
       SetBIOSPipe(pScrn, pI830->origPipe);
    else
@@ -4411,6 +4414,9 @@ I830VESASetMode(ScrnInfoPtr pScrn, Displ
 #endif
 
 #ifdef XF86DRI
+   I830DRISetVBlankInterrupt (pScrn, TRUE);
+#endif
+#ifdef XF86DRI
    if (didLock)
       I830DRIUnlock(pScrn);
 #endif
diff-tree a73ab7f0e6e3b0462e05c0031ffd602ed3e2bcd4 (from 1fe3dd38eb613475d62140850e64767defed7d34)
Author: Alan Hourihane <alanh at fairlite.demon.co.uk>
Date:   Mon Jun 19 11:35:42 2006 +0100

    additions for rotation fixes

diff --git a/src/Makefile.am b/src/Makefile.am
index c64c203..2745e8c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -54,7 +54,11 @@ i810_drv_la_SOURCES = \
          i830_modes.c \
          i830_video.c \
          i830_rotate.c \
-	 i830_randr.c
+	 i830_randr.c \
+	 i830_3d.c \
+	 i830_reg.h \
+	 i915_3d.c \
+	 i915_reg.h
 
 if DRI
 i810_drv_la_SOURCES += \
diff --git a/src/i830.h b/src/i830.h
index d227662..4fa3328 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -394,7 +394,7 @@ extern void I830PrintErrorState(ScrnInfo
 extern void I830Sync(ScrnInfoPtr pScrn);
 extern void I830InitHWCursor(ScrnInfoPtr pScrn);
 extern Bool I830CursorInit(ScreenPtr pScreen);
-extern void I830EmitInvarientState(ScrnInfoPtr pScrn);
+extern void IntelEmitInvarientState(ScrnInfoPtr pScrn);
 extern void I830SelectBuffer(ScrnInfoPtr pScrn, int buffer);
 
 extern void I830RefreshRing(ScrnInfoPtr pScrn);
diff --git a/src/i830_dri.c b/src/i830_dri.c
index 13d2cfd..ed5e685 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -1182,14 +1182,16 @@ I830DRIMoveBuffers(WindowPtr pParent, DD
    pI830->AccelInfoRec->NeedToSync = TRUE;
 }
 
+extern I830EmitInvarientState(ScrnInfoPtr pScrn);
+extern I915EmitInvarientState(ScrnInfoPtr pScrn);
+
 /* Initialize the first context */
 void
-I830EmitInvarientState(ScrnInfoPtr pScrn)
+IntelEmitInvarientState(ScrnInfoPtr pScrn)
 {
    I830Ptr pI830 = I830PTR(pScrn);
    CARD32 ctx_addr;
 
-
    ctx_addr = pI830->ContextMem.Start;
    /* Align to a 2k boundry */
    ctx_addr = ((ctx_addr + 2048 - 1) / 2048) * 2048;
@@ -1202,6 +1204,11 @@ I830EmitInvarientState(ScrnInfoPtr pScrn
 	       CTXT_PALETTE_SAVE_DISABLE | CTXT_PALETTE_RESTORE_DISABLE);
       ADVANCE_LP_RING();
    }
+
+   if (IS_I9XX(pI830))
+      I915EmitInvarientState(pScrn);
+   else
+      I830EmitInvarientState(pScrn);
 }
 
 /* Use callbacks from dri.c to support pageflipping mode for a single
diff --git a/src/i830_driver.c b/src/i830_driver.c
index e43e355..a4b891b 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -5107,12 +5107,13 @@ I830BIOSScreenInit(int scrnIndex, Screen
    }
 #endif
 
+   /* Setup 3D engine, needed for rotation too */
+   IntelEmitInvarientState(pScrn);
+
 #ifdef XF86DRI
    if (pI830->directRenderingEnabled) {
       pI830->directRenderingOpen = TRUE;
       xf86DrvMsg(pScrn->scrnIndex, X_INFO, "direct rendering: Enabled\n");
-      /* Setup 3D engine */
-      I830EmitInvarientState(pScrn);
    } else {
       if (driDisabled)
 	 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "direct rendering: Disabled\n");
@@ -5622,7 +5623,6 @@ I830BIOSEnterVT(int scrnIndex, int flags
       if (!pI830->starting) {
 	 I830DRIResume(screenInfo.screens[scrnIndex]);
       
-	 I830EmitInvarientState(pScrn);
 	 I830RefreshRing(pScrn);
 	 I830Sync(pScrn);
 	 DO_RING_IDLE();
@@ -5634,6 +5634,9 @@ I830BIOSEnterVT(int scrnIndex, int flags
    }
 #endif
 
+   /* Needed for rotation */
+   IntelEmitInvarientState(pScrn);
+
    if (pI830->checkDevices)
       pI830->devicesTimer = TimerSet(NULL, 0, 1000, I830CheckDevicesTimer, pScrn);
 
diff-tree 1fe3dd38eb613475d62140850e64767defed7d34 (from 3592b432b48d51d2273c1e1064f85e656fbba130)
Author: Alan Hourihane <alanh at fairlite.demon.co.uk>
Date:   Mon Jun 19 11:27:28 2006 +0100

    Set some invarient state, cures some problems with
    rotation at startup.
    
    This mimicks the 3D drivers setup.

diff --git a/src/i830_3d.c b/src/i830_3d.c
new file mode 100644
index 0000000..547e556
--- /dev/null
+++ b/src/i830_3d.c
@@ -0,0 +1,131 @@
+/**************************************************************************
+ * 
+ * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * 
+ * 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, sub license, 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 NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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.
+ * 
+ **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "i830.h"
+#include "i830_dri.h"
+
+#include "i830_reg.h"
+
+#define CMD_3D (0x3<<29)
+
+void I830EmitInvarientState( ScrnInfoPtr pScrn )
+{
+   I830Ptr pI830 = I830PTR(pScrn);
+
+   BEGIN_LP_RING(38);
+
+   OUT_RING(_3DSTATE_MAP_CUBE | MAP_UNIT(0));
+   OUT_RING(_3DSTATE_MAP_CUBE | MAP_UNIT(1));
+   OUT_RING(_3DSTATE_MAP_CUBE | MAP_UNIT(2));
+   OUT_RING(_3DSTATE_MAP_CUBE | MAP_UNIT(3));
+
+   OUT_RING(_3DSTATE_DFLT_DIFFUSE_CMD);
+   OUT_RING(0);
+
+   OUT_RING(_3DSTATE_DFLT_SPEC_CMD);
+   OUT_RING(0);
+
+   OUT_RING(_3DSTATE_DFLT_Z_CMD);
+   OUT_RING(0);
+
+   OUT_RING(_3DSTATE_FOG_MODE_CMD);
+   OUT_RING(FOGFUNC_ENABLE |
+	     FOG_LINEAR_CONST | 
+	     FOGSRC_INDEX_Z | 
+	     ENABLE_FOG_DENSITY);
+   OUT_RING(0);
+   OUT_RING(0);
+
+
+   OUT_RING(_3DSTATE_MAP_TEX_STREAM_CMD |
+	     MAP_UNIT(0) |
+	     DISABLE_TEX_STREAM_BUMP |
+	     ENABLE_TEX_STREAM_COORD_SET |
+	     TEX_STREAM_COORD_SET(0) |
+	     ENABLE_TEX_STREAM_MAP_IDX | TEX_STREAM_MAP_IDX(0));
+   OUT_RING(_3DSTATE_MAP_TEX_STREAM_CMD |
+	     MAP_UNIT(1) |
+	     DISABLE_TEX_STREAM_BUMP |
+	     ENABLE_TEX_STREAM_COORD_SET |
+	     TEX_STREAM_COORD_SET(1) |
+	     ENABLE_TEX_STREAM_MAP_IDX | TEX_STREAM_MAP_IDX(1));
+   OUT_RING(_3DSTATE_MAP_TEX_STREAM_CMD |
+	     MAP_UNIT(2) |
+	     DISABLE_TEX_STREAM_BUMP |
+	     ENABLE_TEX_STREAM_COORD_SET |
+	     TEX_STREAM_COORD_SET(2) |
+	     ENABLE_TEX_STREAM_MAP_IDX | TEX_STREAM_MAP_IDX(2));
+   OUT_RING(_3DSTATE_MAP_TEX_STREAM_CMD |
+	     MAP_UNIT(3) |
+	     DISABLE_TEX_STREAM_BUMP |
+	     ENABLE_TEX_STREAM_COORD_SET |
+	     TEX_STREAM_COORD_SET(3) |
+	     ENABLE_TEX_STREAM_MAP_IDX | TEX_STREAM_MAP_IDX(3));
+
+   OUT_RING(_3DSTATE_MAP_COORD_TRANSFORM);
+   OUT_RING(DISABLE_TEX_TRANSFORM | TEXTURE_SET(0));
+   OUT_RING(_3DSTATE_MAP_COORD_TRANSFORM);
+   OUT_RING(DISABLE_TEX_TRANSFORM | TEXTURE_SET(1));
+   OUT_RING(_3DSTATE_MAP_COORD_TRANSFORM);
+   OUT_RING(DISABLE_TEX_TRANSFORM | TEXTURE_SET(2));
+   OUT_RING(_3DSTATE_MAP_COORD_TRANSFORM);
+   OUT_RING(DISABLE_TEX_TRANSFORM | TEXTURE_SET(3));
+
+   OUT_RING(_3DSTATE_RASTER_RULES_CMD |
+	     ENABLE_POINT_RASTER_RULE |
+	     OGL_POINT_RASTER_RULE |
+	     ENABLE_LINE_STRIP_PROVOKE_VRTX |
+	     ENABLE_TRI_FAN_PROVOKE_VRTX |
+	     ENABLE_TRI_STRIP_PROVOKE_VRTX |
+	     LINE_STRIP_PROVOKE_VRTX(1) |
+	     TRI_FAN_PROVOKE_VRTX(2) | 
+	     TRI_STRIP_PROVOKE_VRTX(2));
+
+   OUT_RING(_3DSTATE_SCISSOR_ENABLE_CMD | 
+	     DISABLE_SCISSOR_RECT);
+
+   OUT_RING(_3DSTATE_SCISSOR_RECT_0_CMD);
+   OUT_RING(0);
+   OUT_RING(0);
+
+   OUT_RING(_3DSTATE_VERTEX_TRANSFORM);
+   OUT_RING(DISABLE_VIEWPORT_TRANSFORM | DISABLE_PERSPECTIVE_DIVIDE);
+
+   OUT_RING(_3DSTATE_W_STATE_CMD);
+   OUT_RING(MAGIC_W_STATE_DWORD1);
+   OUT_RING(0x3f800000 /* 1.0 in IEEE float */ );
+
+
+   OUT_RING(_3DSTATE_COLOR_FACTOR_CMD);
+   OUT_RING(0x80808080);	/* .5 required in alpha for GL_DOT3_RGBA_EXT */
+
+   ADVANCE_LP_RING();
+}
diff --git a/src/i830_reg.h b/src/i830_reg.h
new file mode 100644
index 0000000..be12e76
--- /dev/null
+++ b/src/i830_reg.h
@@ -0,0 +1,637 @@
+/**************************************************************************
+ * 
+ * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * 
+ * 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, sub license, 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 NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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.
+ * 
+ **************************************************************************/
+
+
+#ifndef _I830_REG_H_
+#define _I830_REG_H_
+
+#define I830_SET_FIELD( var, mask, value ) (var &= ~(mask), var |= value)
+
+#define _3DSTATE_AA_CMD			(CMD_3D | (0x06<<24))
+#define AA_LINE_ECAAR_WIDTH_ENABLE	(1<<16)
+#define AA_LINE_ECAAR_WIDTH_0_5 	0
+#define AA_LINE_ECAAR_WIDTH_1_0		(1<<14)
+#define AA_LINE_ECAAR_WIDTH_2_0 	(2<<14)
+#define AA_LINE_ECAAR_WIDTH_4_0 	(3<<14)
+#define AA_LINE_REGION_WIDTH_ENABLE	(1<<8)
+#define AA_LINE_REGION_WIDTH_0_5	0
+#define AA_LINE_REGION_WIDTH_1_0	(1<<6)
+#define AA_LINE_REGION_WIDTH_2_0	(2<<6)
+#define AA_LINE_REGION_WIDTH_4_0	(3<<6)
+#define AA_LINE_ENABLE			((1<<1) | 1)
+#define AA_LINE_DISABLE			(1<<1)
+
+#define _3DSTATE_BUF_INFO_CMD	(CMD_3D | (0x1d<<24) | (0x8e<<16) | 1)
+/* Dword 1 */
+#define BUF_3D_ID_COLOR_BACK	(0x3<<24)
+#define BUF_3D_ID_DEPTH 	(0x7<<24)
+#define BUF_3D_USE_FENCE	(1<<23)
+#define BUF_3D_TILED_SURFACE	(1<<22)
+#define BUF_3D_TILE_WALK_X	0
+#define BUF_3D_TILE_WALK_Y	(1<<21)
+#define BUF_3D_PITCH(x)         (((x)/4)<<2)
+/* Dword 2 */
+#define BUF_3D_ADDR(x)		((x) & ~0x3)
+
+
+#define _3DSTATE_COLOR_FACTOR_CMD	(CMD_3D | (0x1d<<24) | (0x1<<16))
+
+#define _3DSTATE_COLOR_FACTOR_N_CMD(stage)	(CMD_3D | (0x1d<<24) | \
+					         ((0x90+(stage))<<16))
+
+#define _3DSTATE_CONST_BLEND_COLOR_CMD	(CMD_3D | (0x1d<<24) | (0x88<<16))
+
+#define _3DSTATE_DFLT_DIFFUSE_CMD	(CMD_3D | (0x1d<<24) | (0x99<<16))
+
+#define _3DSTATE_DFLT_SPEC_CMD		(CMD_3D | (0x1d<<24) | (0x9a<<16))
+
+#define _3DSTATE_DFLT_Z_CMD		(CMD_3D | (0x1d<<24) | (0x98<<16))
+
+
+#define _3DSTATE_DST_BUF_VARS_CMD	(CMD_3D | (0x1d<<24) | (0x85<<16))
+/* Dword 1 */
+#define DSTORG_HORT_BIAS(x)		((x)<<20)
+#define DSTORG_VERT_BIAS(x)		((x)<<16)
+#define COLOR_4_2_2_CHNL_WRT_ALL	0
+#define COLOR_4_2_2_CHNL_WRT_Y		(1<<12)
+#define COLOR_4_2_2_CHNL_WRT_CR		(2<<12)
+#define COLOR_4_2_2_CHNL_WRT_CB		(3<<12)
+#define COLOR_4_2_2_CHNL_WRT_CRCB	(4<<12)
+#define COLR_BUF_8BIT			0
+#define COLR_BUF_RGB555 		(1<<8)
+#define COLR_BUF_RGB565 		(2<<8)
+#define COLR_BUF_ARGB8888		(3<<8)
+#define DEPTH_IS_Z			0
+#define DEPTH_IS_W			(1<<6)
+#define DEPTH_FRMT_16_FIXED		0
+#define DEPTH_FRMT_16_FLOAT		(1<<2)
+#define DEPTH_FRMT_24_FIXED_8_OTHER	(2<<2)
+#define DEPTH_FRMT_24_FLOAT_8_OTHER	(3<<2)
+#define VERT_LINE_STRIDE_1		(1<<1)
+#define VERT_LINE_STRIDE_0		0
+#define VERT_LINE_STRIDE_OFS_1		1
+#define VERT_LINE_STRIDE_OFS_0		0
+
+
+#define _3DSTATE_DRAW_RECT_CMD		(CMD_3D|(0x1d<<24)|(0x80<<16)|3)
+/* Dword 1 */
+#define DRAW_RECT_DIS_DEPTH_OFS 	(1<<30)
+#define DRAW_DITHER_OFS_X(x)		((x)<<26)
+#define DRAW_DITHER_OFS_Y(x)		((x)<<24)
+/* Dword 2 */
+#define DRAW_YMIN(x)			((x)<<16)
+#define DRAW_XMIN(x)			(x)
+/* Dword 3 */
+#define DRAW_YMAX(x)			((x)<<16)
+#define DRAW_XMAX(x)			(x)
+/* Dword 4 */
+#define DRAW_YORG(x)			((x)<<16)
+#define DRAW_XORG(x)			(x)
+
+
+#define _3DSTATE_ENABLES_1_CMD		(CMD_3D|(0x3<<24))
+#define ENABLE_LOGIC_OP_MASK		((1<<23)|(1<<22))
+#define ENABLE_LOGIC_OP 		((1<<23)|(1<<22))
+#define DISABLE_LOGIC_OP		(1<<23)
+#define ENABLE_STENCIL_TEST		((1<<21)|(1<<20))
+#define DISABLE_STENCIL_TEST		(1<<21)
+#define ENABLE_DEPTH_BIAS		((1<<11)|(1<<10))
+#define DISABLE_DEPTH_BIAS		(1<<11)
+#define ENABLE_SPEC_ADD_MASK		((1<<9)|(1<<8))
+#define ENABLE_SPEC_ADD 		((1<<9)|(1<<8))
+#define DISABLE_SPEC_ADD		(1<<9)
+#define ENABLE_DIS_FOG_MASK		((1<<7)|(1<<6))
+#define ENABLE_FOG			((1<<7)|(1<<6))
+#define DISABLE_FOG			(1<<7)
+#define ENABLE_DIS_ALPHA_TEST_MASK	((1<<5)|(1<<4))
+#define ENABLE_ALPHA_TEST		((1<<5)|(1<<4))
+#define DISABLE_ALPHA_TEST		(1<<5)
+#define ENABLE_DIS_CBLEND_MASK		((1<<3)|(1<<2))
+#define ENABLE_COLOR_BLEND		((1<<3)|(1<<2))
+#define DISABLE_COLOR_BLEND		(1<<3)
+#define ENABLE_DIS_DEPTH_TEST_MASK	((1<<1)|1)
+#define ENABLE_DEPTH_TEST		((1<<1)|1)
+#define DISABLE_DEPTH_TEST		(1<<1)
+
+/* _3DSTATE_ENABLES_2, p138 */
+#define _3DSTATE_ENABLES_2_CMD		(CMD_3D|(0x4<<24))
+#define ENABLE_STENCIL_WRITE		((1<<21)|(1<<20))
+#define DISABLE_STENCIL_WRITE		(1<<21)
+#define ENABLE_TEX_CACHE		((1<<17)|(1<<16))
+#define DISABLE_TEX_CACHE		(1<<17)
+#define ENABLE_DITHER			((1<<9)|(1<<8))
+#define DISABLE_DITHER			(1<<9)
+#define ENABLE_COLOR_MASK		(1<<10)
+#define WRITEMASK_ALPHA			(1<<7)
+#define WRITEMASK_ALPHA_SHIFT		7
+#define WRITEMASK_RED			(1<<6)
+#define WRITEMASK_RED_SHIFT		6
+#define WRITEMASK_GREEN 		(1<<5)
+#define WRITEMASK_GREEN_SHIFT		5
+#define WRITEMASK_BLUE			(1<<4)
+#define WRITEMASK_BLUE_SHIFT		4
+#define WRITEMASK_MASK			((1<<4)|(1<<5)|(1<<6)|(1<<7))
+#define ENABLE_COLOR_WRITE		((1<<3)|(1<<2))
+#define DISABLE_COLOR_WRITE		(1<<3)
+#define ENABLE_DIS_DEPTH_WRITE_MASK	0x3
+#define ENABLE_DEPTH_WRITE		((1<<1)|1)
+#define DISABLE_DEPTH_WRITE		(1<<1)
+
+/* _3DSTATE_FOG_COLOR, p139 */
+#define _3DSTATE_FOG_COLOR_CMD		(CMD_3D|(0x15<<24))
+#define FOG_COLOR_RED(x)		((x)<<16)
+#define FOG_COLOR_GREEN(x)		((x)<<8)
+#define FOG_COLOR_BLUE(x)		(x)
+
+/* _3DSTATE_FOG_MODE, p140 */
+#define _3DSTATE_FOG_MODE_CMD		(CMD_3D|(0x1d<<24)|(0x89<<16)|2)
+/* Dword 1 */
+#define FOGFUNC_ENABLE			(1<<31)
+#define FOGFUNC_VERTEX			0
+#define FOGFUNC_PIXEL_EXP		(1<<28)
+#define FOGFUNC_PIXEL_EXP2		(2<<28)
+#define FOGFUNC_PIXEL_LINEAR		(3<<28)
+#define FOGSRC_INDEX_Z			(1<<27)
+#define FOGSRC_INDEX_W			((1<<27)|(1<<25))
+#define FOG_LINEAR_CONST		(1<<24)
+#define FOG_CONST_1(x)			((x)<<4)
+#define ENABLE_FOG_DENSITY		(1<<23)
+/* Dword 2 */
+#define FOG_CONST_2(x)			(x)
+/* Dword 3 */
+#define FOG_DENSITY(x)			(x)
+
+/* _3DSTATE_INDEPENDENT_ALPHA_BLEND, p142 */
+#define _3DSTATE_INDPT_ALPHA_BLEND_CMD	(CMD_3D|(0x0b<<24))
+#define ENABLE_INDPT_ALPHA_BLEND	((1<<23)|(1<<22))
+#define DISABLE_INDPT_ALPHA_BLEND	(1<<23)
+#define ALPHA_BLENDFUNC_MASK		0x3f0000
+#define ENABLE_ALPHA_BLENDFUNC		(1<<21)
+#define ABLENDFUNC_ADD			0
+#define ABLENDFUNC_SUB			(1<<16)
+#define ABLENDFUNC_RVSE_SUB		(2<<16)
+#define ABLENDFUNC_MIN			(3<<16)
+#define ABLENDFUNC_MAX			(4<<16)
+#define SRC_DST_ABLEND_MASK		0xfff
+#define ENABLE_SRC_ABLEND_FACTOR	(1<<11)
+#define SRC_ABLEND_FACT(x)		((x)<<6)
+#define ENABLE_DST_ABLEND_FACTOR	(1<<5)
+#define DST_ABLEND_FACT(x)		(x)
+
+
+/* _3DSTATE_MAP_BLEND_ARG, p152 */
+#define _3DSTATE_MAP_BLEND_ARG_CMD(stage)	(CMD_3D|(0x0e<<24)|((stage)<<20))
+
+#define TEXPIPE_COLOR			0
+#define TEXPIPE_ALPHA			(1<<18)
+#define TEXPIPE_KILL			(2<<18)
+#define TEXBLEND_ARG0			0
+#define TEXBLEND_ARG1			(1<<15)
+#define TEXBLEND_ARG2			(2<<15)
+#define TEXBLEND_ARG3			(3<<15)
+#define TEXBLENDARG_MODIFY_PARMS	(1<<6)
+#define TEXBLENDARG_REPLICATE_ALPHA 	(1<<5)
+#define TEXBLENDARG_INV_ARG 		(1<<4)
+#define TEXBLENDARG_ONE 		0
+#define TEXBLENDARG_FACTOR		0x01
+#define TEXBLENDARG_ACCUM		0x02
+#define TEXBLENDARG_DIFFUSE		0x03
+#define TEXBLENDARG_SPEC		0x04
+#define TEXBLENDARG_CURRENT		0x05
+#define TEXBLENDARG_TEXEL0		0x06
+#define TEXBLENDARG_TEXEL1		0x07
+#define TEXBLENDARG_TEXEL2		0x08
+#define TEXBLENDARG_TEXEL3		0x09
+#define TEXBLENDARG_FACTOR_N		0x0e
+
+/* _3DSTATE_MAP_BLEND_OP, p155 */
+#define _3DSTATE_MAP_BLEND_OP_CMD(stage)	(CMD_3D|(0x0d<<24)|((stage)<<20))
+#if 0
+#   define TEXPIPE_COLOR		0
+#   define TEXPIPE_ALPHA		(1<<18)
+#   define TEXPIPE_KILL			(2<<18)
+#endif
+#define ENABLE_TEXOUTPUT_WRT_SEL	(1<<17)
+#define TEXOP_OUTPUT_CURRENT		0
+#define TEXOP_OUTPUT_ACCUM		(1<<15)
+#define ENABLE_TEX_CNTRL_STAGE		((1<<12)|(1<<11))
+#define DISABLE_TEX_CNTRL_STAGE		(1<<12)
+#define TEXOP_SCALE_SHIFT		9
+#define TEXOP_SCALE_1X			(0 << TEXOP_SCALE_SHIFT)
+#define TEXOP_SCALE_2X			(1 << TEXOP_SCALE_SHIFT)
+#define TEXOP_SCALE_4X			(2 << TEXOP_SCALE_SHIFT)
+#define TEXOP_MODIFY_PARMS		(1<<8)
+#define TEXOP_LAST_STAGE		(1<<7)
+#define TEXBLENDOP_KILLPIXEL		0x02
+#define TEXBLENDOP_ARG1 		0x01
+#define TEXBLENDOP_ARG2 		0x02
+#define TEXBLENDOP_MODULATE		0x03
+#define TEXBLENDOP_ADD			0x06
+#define TEXBLENDOP_ADDSIGNED		0x07
+#define TEXBLENDOP_BLEND		0x08
+#define TEXBLENDOP_BLEND_AND_ADD	0x09
+#define TEXBLENDOP_SUBTRACT		0x0a
+#define TEXBLENDOP_DOT3 		0x0b
+#define TEXBLENDOP_DOT4 		0x0c
+#define TEXBLENDOP_MODULATE_AND_ADD	0x0d
+#define TEXBLENDOP_MODULATE_2X_AND_ADD	0x0e
+#define TEXBLENDOP_MODULATE_4X_AND_ADD	0x0f
+
+/* _3DSTATE_MAP_BUMP_TABLE, p160 TODO */
+/* _3DSTATE_MAP_COLOR_CHROMA_KEY, p161 TODO */
+
+#define _3DSTATE_MAP_COORD_TRANSFORM	((3<<29)|(0x1d<<24)|(0x8c<<16))
+#define DISABLE_TEX_TRANSFORM		(1<<28)
+#define TEXTURE_SET(x)			(x<<29)
+
+#define _3DSTATE_VERTEX_TRANSFORM	((3<<29)|(0x1d<<24)|(0x8b<<16))
+#define DISABLE_VIEWPORT_TRANSFORM	(1<<31)
+#define DISABLE_PERSPECTIVE_DIVIDE	(1<<29)
+
+
+/* _3DSTATE_MAP_COORD_SET_BINDINGS, p162 */
+#define _3DSTATE_MAP_COORD_SETBIND_CMD	(CMD_3D|(0x1d<<24)|(0x02<<16))
+#define TEXBIND_MASK3			((1<<15)|(1<<14)|(1<<13)|(1<<12))
+#define TEXBIND_MASK2			((1<<11)|(1<<10)|(1<<9)|(1<<8))
+#define TEXBIND_MASK1			((1<<7)|(1<<6)|(1<<5)|(1<<4))
+#define TEXBIND_MASK0			((1<<3)|(1<<2)|(1<<1)|1)
+
+#define TEXBIND_SET3(x) 		((x)<<12)
+#define TEXBIND_SET2(x) 		((x)<<8)
+#define TEXBIND_SET1(x) 		((x)<<4)
+#define TEXBIND_SET0(x) 		(x)
+
+#define TEXCOORDSRC_KEEP		0
+#define TEXCOORDSRC_DEFAULT		0x01
+#define TEXCOORDSRC_VTXSET_0		0x08
+#define TEXCOORDSRC_VTXSET_1		0x09
+#define TEXCOORDSRC_VTXSET_2		0x0a
+#define TEXCOORDSRC_VTXSET_3		0x0b
+#define TEXCOORDSRC_VTXSET_4		0x0c
+#define TEXCOORDSRC_VTXSET_5		0x0d
+#define TEXCOORDSRC_VTXSET_6		0x0e
+#define TEXCOORDSRC_VTXSET_7		0x0f
+
+#define MAP_UNIT(unit)			((unit)<<16)
+#define MAP_UNIT_MASK			(0x7<<16)
+
+/* _3DSTATE_MAP_COORD_SETS, p164 */
+#define _3DSTATE_MAP_COORD_SET_CMD	(CMD_3D|(0x1c<<24)|(0x01<<19))
+#define ENABLE_TEXCOORD_PARAMS		(1<<15)
+#define TEXCOORDS_ARE_NORMAL		(1<<14)
+#define TEXCOORDS_ARE_IN_TEXELUNITS	0
+#define TEXCOORDTYPE_CARTESIAN		0
+#define TEXCOORDTYPE_HOMOGENEOUS	(1<<11)
+#define TEXCOORDTYPE_VECTOR		(2<<11)
+#define TEXCOORDTYPE_MASK	        (0x7<<11)
+#define ENABLE_ADDR_V_CNTL		(1<<7)
+#define ENABLE_ADDR_U_CNTL		(1<<3)
+#define TEXCOORD_ADDR_V_MODE(x) 	((x)<<4)
+#define TEXCOORD_ADDR_U_MODE(x) 	(x)
+#define TEXCOORDMODE_WRAP		0
+#define TEXCOORDMODE_MIRROR		1
+#define TEXCOORDMODE_CLAMP		2
+#define TEXCOORDMODE_WRAP_SHORTEST	3
+#define TEXCOORDMODE_CLAMP_BORDER	4
+#define TEXCOORD_ADDR_V_MASK		0x70
+#define TEXCOORD_ADDR_U_MASK		0x7
+
+/* _3DSTATE_MAP_CUBE, p168 TODO */
+#define _3DSTATE_MAP_CUBE		(CMD_3D|(0x1c<<24)|(0x0a<<19))
+#define CUBE_NEGX_ENABLE                (1<<5)
+#define CUBE_POSX_ENABLE                (1<<4)
+#define CUBE_NEGY_ENABLE                (1<<3)
+#define CUBE_POSY_ENABLE                (1<<2)
+#define CUBE_NEGZ_ENABLE                (1<<1)
+#define CUBE_POSZ_ENABLE                (1<<0)
+
+
+/* _3DSTATE_MODES_1, p190 */
+#define _3DSTATE_MODES_1_CMD		(CMD_3D|(0x08<<24))
+#define BLENDFUNC_MASK			0x3f0000
+#define ENABLE_COLR_BLND_FUNC		(1<<21)
+#define BLENDFUNC_ADD			0
+#define BLENDFUNC_SUB			(1<<16)
+#define BLENDFUNC_RVRSE_SUB		(2<<16)
+#define BLENDFUNC_MIN			(3<<16)
+#define BLENDFUNC_MAX			(4<<16)
+#define SRC_DST_BLND_MASK		0xfff
+#define ENABLE_SRC_BLND_FACTOR		(1<<11)
+#define ENABLE_DST_BLND_FACTOR		(1<<5)
+#define SRC_BLND_FACT(x)		((x)<<6)
+#define DST_BLND_FACT(x)		(x)
+
+
+/* _3DSTATE_MODES_2, p192 */
+#define _3DSTATE_MODES_2_CMD		(CMD_3D|(0x0f<<24))
+#define ENABLE_GLOBAL_DEPTH_BIAS	(1<<22)
+#define GLOBAL_DEPTH_BIAS(x)		((x)<<14)
+#define ENABLE_ALPHA_TEST_FUNC		(1<<13)
+#define ENABLE_ALPHA_REF_VALUE		(1<<8)
+#define ALPHA_TEST_FUNC(x)		((x)<<9)
+#define ALPHA_REF_VALUE(x)		(x)
+
+#define ALPHA_TEST_REF_MASK		0x3fff
+
+/* _3DSTATE_MODES_3, p193 */
+#define _3DSTATE_MODES_3_CMD		(CMD_3D|(0x02<<24))
+#define DEPTH_TEST_FUNC_MASK		0x1f0000
+#define ENABLE_DEPTH_TEST_FUNC		(1<<20)
+/* Uses COMPAREFUNC */
+#define DEPTH_TEST_FUNC(x)		((x)<<16)
+#define ENABLE_ALPHA_SHADE_MODE 	(1<<11)
+#define ENABLE_FOG_SHADE_MODE		(1<<9)
+#define ENABLE_SPEC_SHADE_MODE		(1<<7)
+#define ENABLE_COLOR_SHADE_MODE 	(1<<5)
+#define ALPHA_SHADE_MODE(x)		((x)<<10)
+#define FOG_SHADE_MODE(x)		((x)<<8)
+#define SPEC_SHADE_MODE(x)		((x)<<6)
+#define COLOR_SHADE_MODE(x)		((x)<<4)
+#define CULLMODE_MASK			0xf
+#define ENABLE_CULL_MODE		(1<<3)
+#define CULLMODE_BOTH			0
+#define CULLMODE_NONE			1
+#define CULLMODE_CW			2
+#define CULLMODE_CCW			3
+
+#define SHADE_MODE_LINEAR		0
+#define SHADE_MODE_FLAT 		0x1
+
+/* _3DSTATE_MODES_4, p195 */
+#define _3DSTATE_MODES_4_CMD		(CMD_3D|(0x16<<24))
+#define ENABLE_LOGIC_OP_FUNC		(1<<23)
+#define LOGIC_OP_FUNC(x)		((x)<<18)
+#define LOGICOP_MASK			((1<<18)|(1<<19)|(1<<20)|(1<<21))
+#define LOGICOP_CLEAR			0
+#define LOGICOP_NOR			0x1
+#define LOGICOP_AND_INV 		0x2
+#define LOGICOP_COPY_INV		0x3
+#define LOGICOP_AND_RVRSE		0x4
+#define LOGICOP_INV			0x5
+#define LOGICOP_XOR			0x6
+#define LOGICOP_NAND			0x7
+#define LOGICOP_AND			0x8
+#define LOGICOP_EQUIV			0x9
+#define LOGICOP_NOOP			0xa
+#define LOGICOP_OR_INV			0xb
+#define LOGICOP_COPY			0xc
+#define LOGICOP_OR_RVRSE		0xd
+#define LOGICOP_OR			0xe
+#define LOGICOP_SET			0xf
+#define MODE4_ENABLE_STENCIL_TEST_MASK	((1<<17)|(0xff00))
+#define ENABLE_STENCIL_TEST_MASK	(1<<17)
+#define STENCIL_TEST_MASK(x)		((x)<<8)
+#define MODE4_ENABLE_STENCIL_WRITE_MASK	((1<<16)|(0x00ff))
+#define ENABLE_STENCIL_WRITE_MASK	(1<<16)
+#define STENCIL_WRITE_MASK(x)		((x)&0xff)
+
+/* _3DSTATE_MODES_5, p196 */
+#define _3DSTATE_MODES_5_CMD		(CMD_3D|(0x0c<<24))
+#define ENABLE_SPRITE_POINT_TEX 	(1<<23)
+#define SPRITE_POINT_TEX_ON		(1<<22)
+#define SPRITE_POINT_TEX_OFF		0
+#define FLUSH_RENDER_CACHE		(1<<18)
+#define FLUSH_TEXTURE_CACHE		(1<<16)
+#define FIXED_LINE_WIDTH_MASK		0xfc00
+#define ENABLE_FIXED_LINE_WIDTH 	(1<<15)
+#define FIXED_LINE_WIDTH(x)		((x)<<10)
+#define FIXED_POINT_WIDTH_MASK		0x3ff
+#define ENABLE_FIXED_POINT_WIDTH	(1<<9)
+#define FIXED_POINT_WIDTH(x)		(x)
+
+/* _3DSTATE_RASTERIZATION_RULES, p198 */
+#define _3DSTATE_RASTER_RULES_CMD	(CMD_3D|(0x07<<24))
+#define ENABLE_POINT_RASTER_RULE	(1<<15)
+#define OGL_POINT_RASTER_RULE		(1<<13)
+#define ENABLE_LINE_STRIP_PROVOKE_VRTX	(1<<8)
+#define ENABLE_TRI_FAN_PROVOKE_VRTX	(1<<5)
+#define ENABLE_TRI_STRIP_PROVOKE_VRTX	(1<<2)
+#define LINE_STRIP_PROVOKE_VRTX(x)	((x)<<6)
+#define TRI_FAN_PROVOKE_VRTX(x) 	((x)<<3)
+#define TRI_STRIP_PROVOKE_VRTX(x)	(x)
+
+/* _3DSTATE_SCISSOR_ENABLE, p200 */
+#define _3DSTATE_SCISSOR_ENABLE_CMD	(CMD_3D|(0x1c<<24)|(0x10<<19))
+#define ENABLE_SCISSOR_RECT		((1<<1) | 1)
+#define DISABLE_SCISSOR_RECT		(1<<1)
+
+/* _3DSTATE_SCISSOR_RECTANGLE_0, p201 */
+#define _3DSTATE_SCISSOR_RECT_0_CMD	(CMD_3D|(0x1d<<24)|(0x81<<16)|1)
+/* Dword 1 */
+#define SCISSOR_RECT_0_YMIN(x)		((x)<<16)
+#define SCISSOR_RECT_0_XMIN(x)		(x)
+/* Dword 2 */
+#define SCISSOR_RECT_0_YMAX(x)		((x)<<16)
+#define SCISSOR_RECT_0_XMAX(x)		(x)
+
+/* _3DSTATE_STENCIL_TEST, p202 */
+#define _3DSTATE_STENCIL_TEST_CMD	(CMD_3D|(0x09<<24))
+#define ENABLE_STENCIL_PARMS		(1<<23)
+#define STENCIL_OPS_MASK		(0xffc000)
+#define STENCIL_FAIL_OP(x)		((x)<<20)
+#define STENCIL_PASS_DEPTH_FAIL_OP(x)	((x)<<17)
+#define STENCIL_PASS_DEPTH_PASS_OP(x)	((x)<<14)
+
+#define ENABLE_STENCIL_TEST_FUNC_MASK	((1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9))
+#define ENABLE_STENCIL_TEST_FUNC	(1<<13)
+/* Uses COMPAREFUNC */
+#define STENCIL_TEST_FUNC(x)		((x)<<9)
+#define STENCIL_REF_VALUE_MASK		((1<<8)|0xff)
+#define ENABLE_STENCIL_REF_VALUE	(1<<8)
+#define STENCIL_REF_VALUE(x)		(x)
+
+/* _3DSTATE_VERTEX_FORMAT, p204 */
+#define _3DSTATE_VFT0_CMD	(CMD_3D|(0x05<<24))
+#define VFT0_POINT_WIDTH	(1<<12)
+#define VFT0_TEX_COUNT_MASK    	(7<<8)
+#define VFT0_TEX_COUNT_SHIFT    8
+#define VFT0_TEX_COUNT(x) 	((x)<<8)
+#define VFT0_SPEC		(1<<7)
+#define VFT0_DIFFUSE		(1<<6)
+#define VFT0_DEPTH_OFFSET  	(1<<5)
+#define VFT0_XYZ		(1<<1)
+#define VFT0_XYZW		(2<<1)
+#define VFT0_XY			(3<<1)
+#define VFT0_XYW		(4<<1)
+#define VFT0_XYZW_MASK          (7<<1)
+
+/* _3DSTATE_VERTEX_FORMAT_2, p206 */
+#define _3DSTATE_VFT1_CMD	(CMD_3D|(0x0a<<24))
+#define VFT1_TEX7_FMT(x)	((x)<<14)
+#define VFT1_TEX6_FMT(x)	((x)<<12)
+#define VFT1_TEX5_FMT(x)	((x)<<10)
+#define VFT1_TEX4_FMT(x)	((x)<<8)
+#define VFT1_TEX3_FMT(x)	((x)<<6)
+#define VFT1_TEX2_FMT(x)	((x)<<4)
+#define VFT1_TEX1_FMT(x)	((x)<<2)
+#define VFT1_TEX0_FMT(x)	(x)
+#define VFT1_TEX0_MASK          3
+#define VFT1_TEX1_SHIFT         2
+#define TEXCOORDFMT_2D		0
+#define TEXCOORDFMT_3D		1
+#define TEXCOORDFMT_4D		2
+#define TEXCOORDFMT_1D		3
+
+/*New stuff picked up along the way */
+
+#define MLC_LOD_BIAS_MASK ((1<<7)-1)
+
+
+/* _3DSTATE_VERTEX_TRANSFORM, p207 */
+#define _3DSTATE_VERTEX_TRANS_CMD	(CMD_3D|(0x1d<<24)|(0x8b<<16)|0)
+#define _3DSTATE_VERTEX_TRANS_MTX_CMD	(CMD_3D|(0x1d<<24)|(0x8b<<16)|6)
+/* Dword 1 */
+#define ENABLE_VIEWPORT_TRANSFORM	((1<<31)|(1<<30))
+#define DISABLE_VIEWPORT_TRANSFORM	(1<<31)
+#define ENABLE_PERSP_DIVIDE		((1<<29)|(1<<28))
+#define DISABLE_PERSP_DIVIDE		(1<<29)
+#define VRTX_TRANS_LOAD_MATRICES	0x7421
+#define VRTX_TRANS_NO_LOAD_MATRICES	0x0000
+/* Dword 2 -> 7  are matrix elements */
+
+/* _3DSTATE_W_STATE, p209 */
+#define _3DSTATE_W_STATE_CMD		(CMD_3D|(0x1d<<24)|(0x8d<<16)|1)
+/* Dword 1 */
+#define MAGIC_W_STATE_DWORD1		0x00000008
+/* Dword 2 */
+#define WFAR_VALUE(x)			(x)
+
+
+/* Stipple command, carried over from the i810, apparently:
+ */
+#define _3DSTATE_STIPPLE           ((0x3<<29)|(0x1d<<24)|(0x83<<16))
+#define ST1_ENABLE               (1<<16)
+#define ST1_MASK                 (0xffff)
+
+
+
+#define _3DSTATE_LOAD_STATE_IMMEDIATE_2      ((0x3<<29)|(0x1d<<24)|(0x03<<16))
+#define LOAD_TEXTURE_MAP0                   (1<<11)
+#define LOAD_GLOBAL_COLOR_FACTOR            (1<<6)
+
+#define TM0S0_ADDRESS_MASK              0xfffffffc
+#define TM0S0_USE_FENCE                 (1<<1)
+
+#define TM0S1_HEIGHT_SHIFT              21
+#define TM0S1_WIDTH_SHIFT               10
+#define TM0S1_PALETTE_SELECT            (1<<9)
+#define TM0S1_MAPSURF_FORMAT_MASK       (0x7 << 6)
+#define TM0S1_MAPSURF_FORMAT_SHIFT      6
+#define    MAPSURF_8BIT_INDEXED		   (0<<6)
+#define    MAPSURF_8BIT		 	   (1<<6)
+#define    MAPSURF_16BIT		   (2<<6)
+#define    MAPSURF_32BIT		   (3<<6)
+#define    MAPSURF_411			   (4<<6)
+#define    MAPSURF_422			   (5<<6)
+#define    MAPSURF_COMPRESSED		   (6<<6)
+#define    MAPSURF_4BIT_INDEXED		   (7<<6)
+#define TM0S1_MT_FORMAT_MASK         (0x7 << 3)
+#define TM0S1_MT_FORMAT_SHIFT        3
+#define    MT_4BIT_IDX_ARGB8888	           (7<<3) /* SURFACE_4BIT_INDEXED */
+#define    MT_8BIT_IDX_RGB565	           (0<<3) /* SURFACE_8BIT_INDEXED */
+#define    MT_8BIT_IDX_ARGB1555	           (1<<3)
+#define    MT_8BIT_IDX_ARGB4444	           (2<<3)
+#define    MT_8BIT_IDX_AY88		   (3<<3)
+#define    MT_8BIT_IDX_ABGR8888	           (4<<3)
+#define    MT_8BIT_IDX_BUMP_88DVDU 	   (5<<3)
+#define    MT_8BIT_IDX_BUMP_655LDVDU	   (6<<3)
+#define    MT_8BIT_IDX_ARGB8888	           (7<<3)
+#define    MT_8BIT_I8		           (0<<3) /* SURFACE_8BIT */
+#define    MT_8BIT_L8		           (1<<3)
+#define    MT_16BIT_RGB565 		   (0<<3) /* SURFACE_16BIT */
+#define    MT_16BIT_ARGB1555		   (1<<3)
+#define    MT_16BIT_ARGB4444		   (2<<3)
+#define    MT_16BIT_AY88		   (3<<3)
+#define    MT_16BIT_DIB_ARGB1555_8888      (4<<3)
+#define    MT_16BIT_BUMP_88DVDU	           (5<<3)
+#define    MT_16BIT_BUMP_655LDVDU	   (6<<3)
+#define    MT_16BIT_DIB_RGB565_8888	   (7<<3)
+#define    MT_32BIT_ARGB8888		   (0<<3) /* SURFACE_32BIT */
+#define    MT_32BIT_ABGR8888		   (1<<3)
+#define    MT_32BIT_BUMP_XLDVDU_8888	   (6<<3)
+#define    MT_32BIT_DIB_8888		   (7<<3)
+#define    MT_411_YUV411		   (0<<3) /* SURFACE_411 */
+#define    MT_422_YCRCB_SWAPY	           (0<<3) /* SURFACE_422 */
+#define    MT_422_YCRCB_NORMAL	           (1<<3)
+#define    MT_422_YCRCB_SWAPUV	           (2<<3)
+#define    MT_422_YCRCB_SWAPUVY	           (3<<3)
+#define    MT_COMPRESS_DXT1		   (0<<3) /* SURFACE_COMPRESSED */
+#define    MT_COMPRESS_DXT2_3	           (1<<3)
+#define    MT_COMPRESS_DXT4_5	           (2<<3)
+#define    MT_COMPRESS_FXT1		   (3<<3)
+#define TM0S1_COLORSPACE_CONVERSION     (1 << 2)
+#define TM0S1_TILED_SURFACE             (1 << 1)
+#define TM0S1_TILE_WALK                 (1 << 0)
+
+#define TM0S2_PITCH_SHIFT               21
+#define TM0S2_CUBE_FACE_ENA_SHIFT       15
+#define TM0S2_CUBE_FACE_ENA_MASK        (1<<15)
+#define TM0S2_MAP_FORMAT                (1<<14)
+#define TM0S2_VERTICAL_LINE_STRIDE      (1<<13)
+#define TM0S2_VERITCAL_LINE_STRIDE_OFF  (1<<12)
+#define TM0S2_OUTPUT_CHAN_SHIFT         10
+#define TM0S2_OUTPUT_CHAN_MASK          (3<<10)
+
+#define TM0S3_MIP_FILTER_MASK           (0x3<<30)
+#define TM0S3_MIP_FILTER_SHIFT          30
+#define MIPFILTER_NONE		0
+#define MIPFILTER_NEAREST	1
+#define MIPFILTER_LINEAR	3
+#define TM0S3_MAG_FILTER_MASK           (0x3<<28)
+#define TM0S3_MAG_FILTER_SHIFT          28
+#define TM0S3_MIN_FILTER_MASK           (0x3<<26)
+#define TM0S3_MIN_FILTER_SHIFT          26
+#define FILTER_NEAREST		0
+#define FILTER_LINEAR		1
+#define FILTER_ANISOTROPIC	2
+
+#define TM0S3_LOD_BIAS_SHIFT		17
+#define TM0S3_LOD_BIAS_MASK		(0x1ff<<17)
+#define TM0S3_MAX_MIP_SHIFT		9
+#define TM0S3_MAX_MIP_MASK		(0xff<<9)
+#define TM0S3_MIN_MIP_SHIFT		3
+#define TM0S3_MIN_MIP_MASK		(0x3f<<3)
+#define TM0S3_KILL_PIXEL		(1<<2)
+#define TM0S3_KEYED_FILTER		(1<<1)
+#define TM0S3_CHROMA_KEY		(1<<0)
+
+
+/* _3DSTATE_MAP_TEXEL_STREAM, p188 */
+#define _3DSTATE_MAP_TEX_STREAM_CMD	(CMD_3D|(0x1c<<24)|(0x05<<19))
+#define DISABLE_TEX_STREAM_BUMP 	(1<<12)
+#define ENABLE_TEX_STREAM_BUMP		((1<<12)|(1<<11))
+#define TEX_MODIFY_UNIT_0		0
+#define TEX_MODIFY_UNIT_1		(1<<8)
+#define ENABLE_TEX_STREAM_COORD_SET	(1<<7)
+#define TEX_STREAM_COORD_SET(x) 	((x)<<4)
+#define ENABLE_TEX_STREAM_MAP_IDX	(1<<3)
+#define TEX_STREAM_MAP_IDX(x)		(x)
+
+
+#define FLUSH_MAP_CACHE    (1<<0)
+
+#endif
diff --git a/src/i915_3d.c b/src/i915_3d.c
new file mode 100644
index 0000000..f6e7219
--- /dev/null
+++ b/src/i915_3d.c
@@ -0,0 +1,107 @@
+/**************************************************************************
+ * 
+ * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * 
+ * 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, sub license, 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 NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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.
+ * 
+ **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "i830.h"
+#include "i830_dri.h"
+
+#include "i915_reg.h"
+
+void I915EmitInvarientState( ScrnInfoPtr pScrn )
+{
+   I830Ptr pI830 = I830PTR(pScrn);
+
+   BEGIN_LP_RING(20);
+
+   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(0);
+
+   OUT_RING(_3DSTATE_DFLT_SPEC_CMD);
+   OUT_RING(0);
+
+   OUT_RING(_3DSTATE_DFLT_Z_CMD);
+   OUT_RING(0);
+
+   /* Don't support texture crossbar yet */
+   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_POINT_RASTER_RULE |
+	     OGL_POINT_RASTER_RULE |
+	     ENABLE_LINE_STRIP_PROVOKE_VRTX |
+	     ENABLE_TRI_FAN_PROVOKE_VRTX |
+	     LINE_STRIP_PROVOKE_VRTX(1) |
+	     TRI_FAN_PROVOKE_VRTX(2) | 
+	     ENABLE_TEXKILL_3D_4D |
+	     TEXKILL_4D);
+
+   /* Need to initialize this to zero.
+    */
+   OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | 
+	     I1_LOAD_S(3) |
+	     (1));
+   OUT_RING(0);
+ 
+   /* XXX: Use this */
+   OUT_RING(_3DSTATE_SCISSOR_ENABLE_CMD | 
+	     DISABLE_SCISSOR_RECT);
+
+   OUT_RING(_3DSTATE_SCISSOR_RECT_0_CMD);
+   OUT_RING(0);
+   OUT_RING(0);
+
+   OUT_RING(_3DSTATE_DEPTH_SUBRECT_DISABLE);
+
+   OUT_RING(_3DSTATE_LOAD_INDIRECT | 0); /* disable indirect state */
+   OUT_RING(0);
+
+   /* Don't support twosided stencil yet */
+   OUT_RING(_3DSTATE_BACKFACE_STENCIL_OPS |
+	     BFO_ENABLE_STENCIL_TWO_SIDE |
+	     0 );
+
+   OUT_RING(0);
+   
+   ADVANCE_LP_RING();
+}
diff --git a/src/i915_reg.h b/src/i915_reg.h
new file mode 100644
index 0000000..886ae81
--- /dev/null
+++ b/src/i915_reg.h
@@ -0,0 +1,831 @@
+/**************************************************************************
+ * 
+ * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * 
+ * 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, sub license, 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 NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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.
+ * 
+ **************************************************************************/
+
+
+#ifndef _I915_REG_H_
+#define _I915_REG_H_
+
+#define I915_SET_FIELD( var, mask, value ) (var &= ~(mask), var |= value)
+
+#define CMD_3D (0x3<<29)
+
+#define PRIM3D_INLINE		(CMD_3D | (0x1f<<24))
+#define PRIM3D_TRILIST		(0x0<<18)
+#define PRIM3D_TRISTRIP 	(0x1<<18)
+#define PRIM3D_TRISTRIP_RVRSE	(0x2<<18)
+#define PRIM3D_TRIFAN		(0x3<<18)
+#define PRIM3D_POLY		(0x4<<18)
+#define PRIM3D_LINELIST 	(0x5<<18)
+#define PRIM3D_LINESTRIP	(0x6<<18)
+#define PRIM3D_RECTLIST 	(0x7<<18)
+#define PRIM3D_POINTLIST	(0x8<<18)
+#define PRIM3D_DIB		(0x9<<18)
+#define PRIM3D_CLEAR_RECT	(0xa<<18)
+#define PRIM3D_ZONE_INIT	(0xd<<18)
+#define PRIM3D_MASK		(0x1f<<18)
+
+/* p137 */
+#define _3DSTATE_AA_CMD			(CMD_3D | (0x06<<24))
+#define AA_LINE_ECAAR_WIDTH_ENABLE	(1<<16)
+#define AA_LINE_ECAAR_WIDTH_0_5 	0
+#define AA_LINE_ECAAR_WIDTH_1_0		(1<<14)
+#define AA_LINE_ECAAR_WIDTH_2_0 	(2<<14)
+#define AA_LINE_ECAAR_WIDTH_4_0 	(3<<14)
+#define AA_LINE_REGION_WIDTH_ENABLE	(1<<8)
+#define AA_LINE_REGION_WIDTH_0_5	0
+#define AA_LINE_REGION_WIDTH_1_0	(1<<6)
+#define AA_LINE_REGION_WIDTH_2_0	(2<<6)
+#define AA_LINE_REGION_WIDTH_4_0	(3<<6)
+
+/* 3DSTATE_BACKFACE_STENCIL_OPS, p138*/
+#define _3DSTATE_BACKFACE_STENCIL_OPS    (CMD_3D | (0x8<<24))
+#define BFO_ENABLE_STENCIL_REF          (1<<23)
+#define BFO_STENCIL_REF_SHIFT           15
+#define BFO_STENCIL_REF_MASK            (0xff<<15)
+#define BFO_ENABLE_STENCIL_FUNCS        (1<<14)
+#define BFO_STENCIL_TEST_SHIFT          11
+#define BFO_STENCIL_TEST_MASK           (0x7<<11)
+#define BFO_STENCIL_FAIL_SHIFT          8
+#define BFO_STENCIL_FAIL_MASK           (0x7<<8)
+#define BFO_STENCIL_PASS_Z_FAIL_SHIFT   5
+#define BFO_STENCIL_PASS_Z_FAIL_MASK    (0x7<<5)
+#define BFO_STENCIL_PASS_Z_PASS_SHIFT   2
+#define BFO_STENCIL_PASS_Z_PASS_MASK    (0x7<<2)
+#define BFO_ENABLE_STENCIL_TWO_SIDE     (1<<1)
+#define BFO_STENCIL_TWO_SIDE            (1<<0)
+
+
+/* 3DSTATE_BACKFACE_STENCIL_MASKS, p140 */
+#define _3DSTATE_BACKFACE_STENCIL_MASKS    (CMD_3D | (0x9<<24))
+#define BFM_ENABLE_STENCIL_TEST_MASK      (1<<17)
+#define BFM_ENABLE_STENCIL_WRITE_MASK     (1<<16)
+#define BFM_STENCIL_TEST_MASK_SHIFT       8
+#define BFM_STENCIL_TEST_MASK_MASK        (0xff<<8)
+#define BFM_STENCIL_WRITE_MASK_SHIFT      0
+#define BFM_STENCIL_WRITE_MASK_MASK       (0xff<<0)
+
+
+
+/* 3DSTATE_BIN_CONTROL p141 */
+
+/* p143 */
+#define _3DSTATE_BUF_INFO_CMD	(CMD_3D | (0x1d<<24) | (0x8e<<16) | 1)
+/* Dword 1 */
+#define BUF_3D_ID_COLOR_BACK	(0x3<<24)
+#define BUF_3D_ID_DEPTH 	(0x7<<24)
+#define BUF_3D_USE_FENCE	(1<<23)
+#define BUF_3D_TILED_SURFACE	(1<<22)
+#define BUF_3D_TILE_WALK_X	0
+#define BUF_3D_TILE_WALK_Y	(1<<21)
+#define BUF_3D_PITCH(x)         (((x)/4)<<2)
+/* Dword 2 */
+#define BUF_3D_ADDR(x)		((x) & ~0x3)
+
+
+/* 3DSTATE_CHROMA_KEY */
+
+/* 3DSTATE_CLEAR_PARAMETERS, p150 */
+
+/* 3DSTATE_CONSTANT_BLEND_COLOR, p153 */
+#define _3DSTATE_CONST_BLEND_COLOR_CMD	(CMD_3D | (0x1d<<24) | (0x88<<16))
+
+
+
+/* 3DSTATE_COORD_SET_BINDINGS, p154 */
+#define _3DSTATE_COORD_SET_BINDINGS      (CMD_3D | (0x16<<24))
+#define CSB_TCB(iunit, eunit)           ((eunit)<<(iunit*3))
+
+/* p156 */
+#define _3DSTATE_DFLT_DIFFUSE_CMD	(CMD_3D | (0x1d<<24) | (0x99<<16))
+
+/* p157 */
+#define _3DSTATE_DFLT_SPEC_CMD		(CMD_3D | (0x1d<<24) | (0x9a<<16))
+
+/* p158 */
+#define _3DSTATE_DFLT_Z_CMD		(CMD_3D | (0x1d<<24) | (0x98<<16))
+
+
+/* 3DSTATE_DEPTH_OFFSET_SCALE, p159 */
+#define _3DSTATE_DEPTH_OFFSET_SCALE       (CMD_3D | (0x1d<<24) | (0x97<<16))
+/* scale in dword 1 */
+
+
+/* 3DSTATE_DEPTH_SUBRECT_DISABLE, p160 */
+#define _3DSTATE_DEPTH_SUBRECT_DISABLE    (CMD_3D | (0x1c<<24) | (0x11<19) | 0x2)
+
+/* p161 */
+#define _3DSTATE_DST_BUF_VARS_CMD	(CMD_3D | (0x1d<<24) | (0x85<<16))
+/* Dword 1 */
+#define TEX_DEFAULT_COLOR_OGL           (0<<30)
+#define TEX_DEFAULT_COLOR_D3D           (1<<30)
+#define ZR_EARLY_DEPTH                  (1<<29)
+#define LOD_PRECLAMP_OGL                (1<<28)
+#define LOD_PRECLAMP_D3D                (0<<28)
+#define DITHER_FULL_ALWAYS              (0<<26)
+#define DITHER_FULL_ON_FB_BLEND         (1<<26)
+#define DITHER_CLAMPED_ALWAYS           (2<<26)
+#define LINEAR_GAMMA_BLEND_32BPP        (1<<25)
+#define DEBUG_DISABLE_ENH_DITHER        (1<<24)
+#define DSTORG_HORT_BIAS(x)		((x)<<20)
+#define DSTORG_VERT_BIAS(x)		((x)<<16)
+#define COLOR_4_2_2_CHNL_WRT_ALL	0
+#define COLOR_4_2_2_CHNL_WRT_Y		(1<<12)
+#define COLOR_4_2_2_CHNL_WRT_CR		(2<<12)
+#define COLOR_4_2_2_CHNL_WRT_CB		(3<<12)
+#define COLOR_4_2_2_CHNL_WRT_CRCB	(4<<12)
+#define COLR_BUF_8BIT			0
+#define COLR_BUF_RGB555 		(1<<8)
+#define COLR_BUF_RGB565 		(2<<8)
+#define COLR_BUF_ARGB8888		(3<<8)
+#define DEPTH_FRMT_16_FIXED		0
+#define DEPTH_FRMT_16_FLOAT		(1<<2)
+#define DEPTH_FRMT_24_FIXED_8_OTHER	(2<<2)
+#define VERT_LINE_STRIDE_1		(1<<1)
+#define VERT_LINE_STRIDE_0		(0<<1)
+#define VERT_LINE_STRIDE_OFS_1		1
+#define VERT_LINE_STRIDE_OFS_0		0
+
+/* p166 */
+#define _3DSTATE_DRAW_RECT_CMD		(CMD_3D|(0x1d<<24)|(0x80<<16)|3)
+/* Dword 1 */
+#define DRAW_RECT_DIS_DEPTH_OFS 	(1<<30)
+#define DRAW_DITHER_OFS_X(x)		((x)<<26)
+#define DRAW_DITHER_OFS_Y(x)		((x)<<24)
+/* Dword 2 */
+#define DRAW_YMIN(x)			((x)<<16)
+#define DRAW_XMIN(x)			(x)
+/* Dword 3 */
+#define DRAW_YMAX(x)			((x)<<16)
+#define DRAW_XMAX(x)			(x)
+/* Dword 4 */
+#define DRAW_YORG(x)			((x)<<16)
+#define DRAW_XORG(x)			(x)
+
+
+/* 3DSTATE_FILTER_COEFFICIENTS_4X4, p170 */
+
+/* 3DSTATE_FILTER_COEFFICIENTS_6X5, p172 */
+
+
+/* _3DSTATE_FOG_COLOR, p173 */
+#define _3DSTATE_FOG_COLOR_CMD		(CMD_3D|(0x15<<24))
+#define FOG_COLOR_RED(x)		((x)<<16)
+#define FOG_COLOR_GREEN(x)		((x)<<8)
+#define FOG_COLOR_BLUE(x)		(x)
+
+/* _3DSTATE_FOG_MODE, p174 */
+#define _3DSTATE_FOG_MODE_CMD		(CMD_3D|(0x1d<<24)|(0x89<<16)|2)
+/* Dword 1 */
+#define FMC1_FOGFUNC_MODIFY_ENABLE	(1<<31)
+#define FMC1_FOGFUNC_VERTEX		(0<<28)
+#define FMC1_FOGFUNC_PIXEL_EXP		(1<<28)
+#define FMC1_FOGFUNC_PIXEL_EXP2		(2<<28)
+#define FMC1_FOGFUNC_PIXEL_LINEAR	(3<<28)
+#define FMC1_FOGFUNC_MASK		(3<<28)
+#define FMC1_FOGINDEX_MODIFY_ENABLE     (1<<27)
+#define FMC1_FOGINDEX_Z		        (0<<25)
+#define FMC1_FOGINDEX_W   		(1<<25)
+#define FMC1_C1_C2_MODIFY_ENABLE	(1<<24)
+#define FMC1_DENSITY_MODIFY_ENABLE	(1<<23)
+#define FMC1_C1_ONE      	        (1<<13)
+#define FMC1_C1_MASK		        (0xffff<<4)
+/* Dword 2 */
+#define FMC2_C2_ONE		        (1<<16)
+/* Dword 3 */
+#define FMC3_D_ONE      		(1<<16)
+
+
+
+/* _3DSTATE_INDEPENDENT_ALPHA_BLEND, p177 */
+#define _3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD	(CMD_3D|(0x0b<<24))
+#define IAB_MODIFY_ENABLE	        (1<<23)
+#define IAB_ENABLE       	        (1<<22)
+#define IAB_MODIFY_FUNC         	(1<<21)
+#define IAB_FUNC_SHIFT          	16
+#define IAB_MODIFY_SRC_FACTOR   	(1<<11)
+#define IAB_SRC_FACTOR_SHIFT		6
+#define IAB_SRC_FACTOR_MASK		(BLENDFACT_MASK<<6)
+#define IAB_MODIFY_DST_FACTOR	        (1<<5)
+#define IAB_DST_FACTOR_SHIFT		0
+#define IAB_DST_FACTOR_MASK		(BLENDFACT_MASK<<0)
+
+
+#define BLENDFUNC_ADD			0x0
+#define BLENDFUNC_SUBTRACT		0x1
+#define BLENDFUNC_REVERSE_SUBTRACT	0x2
+#define BLENDFUNC_MIN			0x3
+#define BLENDFUNC_MAX			0x4
+#define BLENDFUNC_MASK			0x7
+
+/* 3DSTATE_LOAD_INDIRECT, p180 */
+
+#define _3DSTATE_LOAD_INDIRECT	        (CMD_3D|(0x1d<<24)|(0x7<<16))
+#define LI0_STATE_STATIC_INDIRECT       (0x01<<8)
+#define LI0_STATE_DYNAMIC_INDIRECT      (0x02<<8)
+#define LI0_STATE_SAMPLER               (0x04<<8)
+#define LI0_STATE_MAP                   (0x08<<8)
+#define LI0_STATE_PROGRAM               (0x10<<8)
+#define LI0_STATE_CONSTANTS             (0x20<<8)
+
+#define SIS0_BUFFER_ADDRESS(x)          ((x)&~0x3)
+#define SIS0_FORCE_LOAD                 (1<<1)
+#define SIS0_BUFFER_VALID               (1<<0)
+#define SIS1_BUFFER_LENGTH(x)           ((x)&0xff)
+
+#define DIS0_BUFFER_ADDRESS(x)          ((x)&~0x3)
+#define DIS0_BUFFER_RESET               (1<<1)
+#define DIS0_BUFFER_VALID               (1<<0)
+
+#define SSB0_BUFFER_ADDRESS(x)          ((x)&~0x3)
+#define SSB0_FORCE_LOAD                 (1<<1)
+#define SSB0_BUFFER_VALID               (1<<0)
+#define SSB1_BUFFER_LENGTH(x)           ((x)&0xff)
+
+#define MSB0_BUFFER_ADDRESS(x)          ((x)&~0x3)
+#define MSB0_FORCE_LOAD                 (1<<1)
+#define MSB0_BUFFER_VALID               (1<<0)
+#define MSB1_BUFFER_LENGTH(x)           ((x)&0xff)
+
+#define PSP0_BUFFER_ADDRESS(x)          ((x)&~0x3)
+#define PSP0_FORCE_LOAD                 (1<<1)
+#define PSP0_BUFFER_VALID               (1<<0)
+#define PSP1_BUFFER_LENGTH(x)           ((x)&0xff)
+
+#define PSC0_BUFFER_ADDRESS(x)          ((x)&~0x3)
+#define PSC0_FORCE_LOAD                 (1<<1)
+#define PSC0_BUFFER_VALID               (1<<0)
+#define PSC1_BUFFER_LENGTH(x)           ((x)&0xff)
+
+
+
+
+
+/* _3DSTATE_RASTERIZATION_RULES */
+#define _3DSTATE_RASTER_RULES_CMD	(CMD_3D|(0x07<<24))
+#define ENABLE_POINT_RASTER_RULE	(1<<15)
+#define OGL_POINT_RASTER_RULE		(1<<13)
+#define ENABLE_TEXKILL_3D_4D            (1<<10)
+#define TEXKILL_3D                      (0<<9)
+#define TEXKILL_4D                      (1<<9)
+#define ENABLE_LINE_STRIP_PROVOKE_VRTX	(1<<8)
+#define ENABLE_TRI_FAN_PROVOKE_VRTX	(1<<5)
+#define LINE_STRIP_PROVOKE_VRTX(x)	((x)<<6)
+#define TRI_FAN_PROVOKE_VRTX(x) 	((x)<<3)
+
+/* _3DSTATE_SCISSOR_ENABLE, p256 */
+#define _3DSTATE_SCISSOR_ENABLE_CMD	(CMD_3D|(0x1c<<24)|(0x10<<19))
+#define ENABLE_SCISSOR_RECT		((1<<1) | 1)
+#define DISABLE_SCISSOR_RECT		(1<<1)
+
+/* _3DSTATE_SCISSOR_RECTANGLE_0, p257 */
+#define _3DSTATE_SCISSOR_RECT_0_CMD	(CMD_3D|(0x1d<<24)|(0x81<<16)|1)
+/* Dword 1 */
+#define SCISSOR_RECT_0_YMIN(x)		((x)<<16)
+#define SCISSOR_RECT_0_XMIN(x)		(x)
+/* Dword 2 */
+#define SCISSOR_RECT_0_YMAX(x)		((x)<<16)
+#define SCISSOR_RECT_0_XMAX(x)		(x)
+
+/* p189 */
+#define _3DSTATE_LOAD_STATE_IMMEDIATE_1   ((0x3<<29)|(0x1d<<24)|(0x04<<16))
+#define I1_LOAD_S(n)                      (1<<(4+n))
+
+#define S0_VB_OFFSET_MASK              0xffffffc
+#define S0_AUTO_CACHE_INV_DISABLE      (1<<0)
+
+#define S1_VERTEX_WIDTH_SHIFT          24
+#define S1_VERTEX_WIDTH_MASK           (0x3f<<24)
+#define S1_VERTEX_PITCH_SHIFT          16
+#define S1_VERTEX_PITCH_MASK           (0x3f<<16)
+
+#define TEXCOORDFMT_2D                 0x0
+#define TEXCOORDFMT_3D                 0x1
+#define TEXCOORDFMT_4D                 0x2
+#define TEXCOORDFMT_1D                 0x3
+#define TEXCOORDFMT_2D_16              0x4
+#define TEXCOORDFMT_4D_16              0x5
+#define TEXCOORDFMT_NOT_PRESENT        0xf
+#define S2_TEXCOORD_FMT0_MASK            0xf
+#define S2_TEXCOORD_FMT1_SHIFT           4
+#define S2_TEXCOORD_FMT(unit, type)    ((type)<<(unit*4))
+#define S2_TEXCOORD_NONE               (~0)
+
+/* S3 not interesting */
+
+#define S4_POINT_WIDTH_SHIFT           23
+#define S4_POINT_WIDTH_MASK            (0x1ff<<23)
+#define S4_LINE_WIDTH_SHIFT            19
+#define S4_LINE_WIDTH_ONE              (0x2<<19)
+#define S4_LINE_WIDTH_MASK             (0xf<<19)
+#define S4_FLATSHADE_ALPHA             (1<<18)
+#define S4_FLATSHADE_FOG               (1<<17)
+#define S4_FLATSHADE_SPECULAR          (1<<16)
+#define S4_FLATSHADE_COLOR             (1<<15)
+#define S4_CULLMODE_BOTH	       (0<<13)
+#define S4_CULLMODE_NONE	       (1<<13)
+#define S4_CULLMODE_CW		       (2<<13)
+#define S4_CULLMODE_CCW		       (3<<13)
+#define S4_CULLMODE_MASK	       (3<<13)
+#define S4_VFMT_POINT_WIDTH            (1<<12)
+#define S4_VFMT_SPEC_FOG               (1<<11)
+#define S4_VFMT_COLOR                  (1<<10)
+#define S4_VFMT_DEPTH_OFFSET           (1<<9)
+#define S4_VFMT_XYZ     	       (1<<6)
+#define S4_VFMT_XYZW     	       (2<<6)
+#define S4_VFMT_XY     		       (3<<6)
+#define S4_VFMT_XYW     	       (4<<6)
+#define S4_VFMT_XYZW_MASK              (7<<6)
+#define S4_FORCE_DEFAULT_DIFFUSE       (1<<5)
+#define S4_FORCE_DEFAULT_SPECULAR      (1<<4)
+#define S4_LOCAL_DEPTH_OFFSET_ENABLE   (1<<3)
+#define S4_VFMT_FOG_PARAM              (1<<2)
+#define S4_SPRITE_POINT_ENABLE         (1<<1)
+#define S4_LINE_ANTIALIAS_ENABLE       (1<<0)
+
+#define S4_VFMT_MASK (S4_VFMT_POINT_WIDTH   | 	\
+		      S4_VFMT_SPEC_FOG      |	\
+		      S4_VFMT_COLOR         |	\
+		      S4_VFMT_DEPTH_OFFSET  |	\
+		      S4_VFMT_XYZW_MASK     |	\
+		      S4_VFMT_FOG_PARAM)
+
+
+#define S5_WRITEDISABLE_ALPHA          (1<<31)
+#define S5_WRITEDISABLE_RED            (1<<30)
+#define S5_WRITEDISABLE_GREEN          (1<<29)
+#define S5_WRITEDISABLE_BLUE           (1<<28)
+#define S5_WRITEDISABLE_MASK           (0xf<<28)
+#define S5_FORCE_DEFAULT_POINT_SIZE    (1<<27)
+#define S5_LAST_PIXEL_ENABLE           (1<<26)
+#define S5_GLOBAL_DEPTH_OFFSET_ENABLE  (1<<25)
+#define S5_FOG_ENABLE                  (1<<24)
+#define S5_STENCIL_REF_SHIFT           16
+#define S5_STENCIL_REF_MASK            (0xff<<16)
+#define S5_STENCIL_TEST_FUNC_SHIFT     13
+#define S5_STENCIL_TEST_FUNC_MASK      (0x7<<13)
+#define S5_STENCIL_FAIL_SHIFT          10
+#define S5_STENCIL_FAIL_MASK           (0x7<<10)
+#define S5_STENCIL_PASS_Z_FAIL_SHIFT   7
+#define S5_STENCIL_PASS_Z_FAIL_MASK    (0x7<<7)
+#define S5_STENCIL_PASS_Z_PASS_SHIFT   4
+#define S5_STENCIL_PASS_Z_PASS_MASK    (0x7<<4)
+#define S5_STENCIL_WRITE_ENABLE        (1<<3)
+#define S5_STENCIL_TEST_ENABLE         (1<<2)
+#define S5_COLOR_DITHER_ENABLE         (1<<1)
+#define S5_LOGICOP_ENABLE              (1<<0)
+
+
+#define S6_ALPHA_TEST_ENABLE           (1<<31)
+#define S6_ALPHA_TEST_FUNC_SHIFT       28
+#define S6_ALPHA_TEST_FUNC_MASK        (0x7<<28)
+#define S6_ALPHA_REF_SHIFT             20
+#define S6_ALPHA_REF_MASK              (0xff<<20)
+#define S6_DEPTH_TEST_ENABLE           (1<<19)
+#define S6_DEPTH_TEST_FUNC_SHIFT       16
+#define S6_DEPTH_TEST_FUNC_MASK        (0x7<<16)
+#define S6_CBUF_BLEND_ENABLE           (1<<15)
+#define S6_CBUF_BLEND_FUNC_SHIFT       12
+#define S6_CBUF_BLEND_FUNC_MASK        (0x7<<12)
+#define S6_CBUF_SRC_BLEND_FACT_SHIFT   8
+#define S6_CBUF_SRC_BLEND_FACT_MASK    (0xf<<8)
+#define S6_CBUF_DST_BLEND_FACT_SHIFT   4
+#define S6_CBUF_DST_BLEND_FACT_MASK    (0xf<<4)
+#define S6_DEPTH_WRITE_ENABLE          (1<<3)
+#define S6_COLOR_WRITE_ENABLE          (1<<2)
+#define S6_TRISTRIP_PV_SHIFT           0
+#define S6_TRISTRIP_PV_MASK            (0x3<<0)
+
+#define S7_DEPTH_OFFSET_CONST_MASK     ~0
+
+/* 3DSTATE_MAP_DEINTERLACER_PARAMETERS */
+/* 3DSTATE_MAP_PALETTE_LOAD_32, p206 */
+
+
+/* _3DSTATE_MODES_4, p218 */
+#define _3DSTATE_MODES_4_CMD		(CMD_3D|(0x0d<<24))
+#define ENABLE_LOGIC_OP_FUNC		(1<<23)
+#define LOGIC_OP_FUNC(x)		((x)<<18)
+#define LOGICOP_MASK			(0xf<<18)
+#define MODE4_ENABLE_STENCIL_TEST_MASK	((1<<17)|(0xff00))
+#define ENABLE_STENCIL_TEST_MASK	(1<<17)
+#define STENCIL_TEST_MASK(x)		((x)<<8)
+#define MODE4_ENABLE_STENCIL_WRITE_MASK	((1<<16)|(0x00ff))
+#define ENABLE_STENCIL_WRITE_MASK	(1<<16)
+#define STENCIL_WRITE_MASK(x)		((x)&0xff)
+
+/* _3DSTATE_MODES_5, p220 */
+#define _3DSTATE_MODES_5_CMD		(CMD_3D|(0x0c<<24))
+#define PIPELINE_FLUSH_RENDER_CACHE	(1<<18)
+#define PIPELINE_FLUSH_TEXTURE_CACHE	(1<<16)
+
+
+/* p221 */
+#define _3DSTATE_PIXEL_SHADER_CONSTANTS  (CMD_3D|(0x1d<<24)|(0x6<<16))
+#define PS1_REG(n)                      (1<<(n))
+#define PS2_CONST_X(n)                  (n)
+#define PS3_CONST_Y(n)                  (n)
+#define PS4_CONST_Z(n)                  (n)
+#define PS5_CONST_W(n)                  (n)
+
+/* p222 */
+
+
+#define I915_MAX_TEX_INDIRECT 4
+#define I915_MAX_TEX_INSN     32     
+#define I915_MAX_ALU_INSN     64
+#define I915_MAX_DECL_INSN    27
+#define I915_MAX_TEMPORARY    16
+
+
+/* Each instruction is 3 dwords long, though most don't require all
+ * this space.  Maximum of 123 instructions.  Smaller maxes per insn
+ * type.
+ */
+#define _3DSTATE_PIXEL_SHADER_PROGRAM    (CMD_3D|(0x1d<<24)|(0x5<<16))
+
+#define REG_TYPE_R                 0 /* temporary regs, no need to
+				      * dcl, must be written before
+				      * read -- Preserved between
+				      * phases. 
+				      */
+#define REG_TYPE_T                 1 /* Interpolated values, must be
+				      * dcl'ed before use.
+				      *
+				      * 0..7: texture coord,
+				      * 8: diffuse spec,
+				      * 9: specular color,
+				      * 10: fog parameter in w.
+				      */
+#define REG_TYPE_CONST             2 /* Restriction: only one const
+				      * can be referenced per
+				      * instruction, though it may be
+				      * selected for multiple inputs.
+				      * Constants not initialized
+				      * default to zero.
+				      */
+#define REG_TYPE_S                 3 /* sampler */
+#define REG_TYPE_OC                4 /* output color (rgba) */
+#define REG_TYPE_OD                5 /* output depth (w), xyz are
+				      * temporaries.  If not written,
+				      * interpolated depth is used?
+				      */
+#define REG_TYPE_U                 6 /* unpreserved temporaries */
+#define REG_TYPE_MASK              0x7
+#define REG_NR_MASK                0xf
+
+
+/* REG_TYPE_T:
+ */
+#define T_TEX0     0
+#define T_TEX1     1
+#define T_TEX2     2
+#define T_TEX3     3
+#define T_TEX4     4
+#define T_TEX5     5
+#define T_TEX6     6
+#define T_TEX7     7
+#define T_DIFFUSE  8
+#define T_SPECULAR 9
+#define T_FOG_W    10		/* interpolated fog is in W coord */
+
+/* Arithmetic instructions */
+
+/* .replicate_swizzle == selection and replication of a particular
+ * scalar channel, ie., .xxxx, .yyyy, .zzzz or .wwww 
+ */
+#define A0_NOP    (0x0<<24)		/* no operation */
+#define A0_ADD    (0x1<<24)		/* dst = src0 + src1 */
+#define A0_MOV    (0x2<<24)		/* dst = src0 */
+#define A0_MUL    (0x3<<24)		/* dst = src0 * src1 */
+#define A0_MAD    (0x4<<24)		/* dst = src0 * src1 + src2 */
+#define A0_DP2ADD (0x5<<24)		/* dst.xyzw = src0.xy dot src1.xy + src2.replicate_swizzle */
+#define A0_DP3    (0x6<<24)		/* dst.xyzw = src0.xyz dot src1.xyz */
+#define A0_DP4    (0x7<<24)		/* dst.xyzw = src0.xyzw dot src1.xyzw */
+#define A0_FRC    (0x8<<24)		/* dst = src0 - floor(src0) */
+#define A0_RCP    (0x9<<24)		/* dst.xyzw = 1/(src0.replicate_swizzle) */
+#define A0_RSQ    (0xa<<24)		/* dst.xyzw = 1/(sqrt(abs(src0.replicate_swizzle))) */
+#define A0_EXP    (0xb<<24)		/* dst.xyzw = exp2(src0.replicate_swizzle) */
+#define A0_LOG    (0xc<<24)		/* dst.xyzw = log2(abs(src0.replicate_swizzle)) */
+#define A0_CMP    (0xd<<24)		/* dst = (src0 >= 0.0) ? src1 : src2 */
+#define A0_MIN    (0xe<<24)		/* dst = (src0 < src1) ? src0 : src1 */
+#define A0_MAX    (0xf<<24)		/* dst = (src0 >= src1) ? src0 : src1 */
+#define A0_FLR    (0x10<<24)		/* dst = floor(src0) */
+#define A0_MOD    (0x11<<24)		/* dst = src0 fmod 1.0 */
+#define A0_TRC    (0x12<<24)		/* dst = int(src0) */
+#define A0_SGE    (0x13<<24)		/* dst = src0 >= src1 ? 1.0 : 0.0 */
+#define A0_SLT    (0x14<<24)		/* dst = src0 < src1 ? 1.0 : 0.0 */
+#define A0_DEST_SATURATE                 (1<<22)
+#define A0_DEST_TYPE_SHIFT                19
+/* Allow: R, OC, OD, U */
+#define A0_DEST_NR_SHIFT                 14
+/* Allow R: 0..15, OC,OD: 0..0, U: 0..2 */
+#define A0_DEST_CHANNEL_X                (1<<10)
+#define A0_DEST_CHANNEL_Y                (2<<10)
+#define A0_DEST_CHANNEL_Z                (4<<10)
+#define A0_DEST_CHANNEL_W                (8<<10)
+#define A0_DEST_CHANNEL_ALL              (0xf<<10)
+#define A0_DEST_CHANNEL_SHIFT            10
+#define A0_SRC0_TYPE_SHIFT               7
+#define A0_SRC0_NR_SHIFT                 2
+
+#define A0_DEST_CHANNEL_XY              (A0_DEST_CHANNEL_X|A0_DEST_CHANNEL_Y)
+#define A0_DEST_CHANNEL_XYZ             (A0_DEST_CHANNEL_XY|A0_DEST_CHANNEL_Z)
+
+
+#define SRC_X        0
+#define SRC_Y        1
+#define SRC_Z        2
+#define SRC_W        3
+#define SRC_ZERO     4
+#define SRC_ONE      5
+
+#define A1_SRC0_CHANNEL_X_NEGATE         (1<<31)
+#define A1_SRC0_CHANNEL_X_SHIFT          28
+#define A1_SRC0_CHANNEL_Y_NEGATE         (1<<27)
+#define A1_SRC0_CHANNEL_Y_SHIFT          24
+#define A1_SRC0_CHANNEL_Z_NEGATE         (1<<23)
+#define A1_SRC0_CHANNEL_Z_SHIFT          20
+#define A1_SRC0_CHANNEL_W_NEGATE         (1<<19)
+#define A1_SRC0_CHANNEL_W_SHIFT          16
+#define A1_SRC1_TYPE_SHIFT               13
+#define A1_SRC1_NR_SHIFT                 8
+#define A1_SRC1_CHANNEL_X_NEGATE         (1<<7)
+#define A1_SRC1_CHANNEL_X_SHIFT          4
+#define A1_SRC1_CHANNEL_Y_NEGATE         (1<<3)
+#define A1_SRC1_CHANNEL_Y_SHIFT          0
+
+#define A2_SRC1_CHANNEL_Z_NEGATE         (1<<31)
+#define A2_SRC1_CHANNEL_Z_SHIFT          28
+#define A2_SRC1_CHANNEL_W_NEGATE         (1<<27)
+#define A2_SRC1_CHANNEL_W_SHIFT          24
+#define A2_SRC2_TYPE_SHIFT               21
+#define A2_SRC2_NR_SHIFT                 16
+#define A2_SRC2_CHANNEL_X_NEGATE         (1<<15)
+#define A2_SRC2_CHANNEL_X_SHIFT          12
+#define A2_SRC2_CHANNEL_Y_NEGATE         (1<<11)
+#define A2_SRC2_CHANNEL_Y_SHIFT          8
+#define A2_SRC2_CHANNEL_Z_NEGATE         (1<<7)
+#define A2_SRC2_CHANNEL_Z_SHIFT          4
+#define A2_SRC2_CHANNEL_W_NEGATE         (1<<3)
+#define A2_SRC2_CHANNEL_W_SHIFT          0
+
+
+
+/* Texture instructions */
+#define T0_TEXLD     (0x15<<24)	/* Sample texture using predeclared
+				 * sampler and address, and output
+				 * filtered texel data to destination
+				 * register */
+#define T0_TEXLDP    (0x16<<24)	/* Same as texld but performs a
+				 * perspective divide of the texture
+				 * coordinate .xyz values by .w before
+				 * sampling. */
+#define T0_TEXLDB    (0x17<<24)	/* Same as texld but biases the
+				 * computed LOD by w.  Only S4.6 two's
+				 * comp is used.  This implies that a
+				 * float to fixed conversion is
+				 * done. */
+#define T0_TEXKILL   (0x18<<24)	/* Does not perform a sampling
+				 * operation.  Simply kills the pixel
+				 * if any channel of the address
+				 * register is < 0.0. */
+#define T0_DEST_TYPE_SHIFT                19
+/* Allow: R, OC, OD, U */
+/* Note: U (unpreserved) regs do not retain their values between
+ * phases (cannot be used for feedback) 
+ *
+ * Note: oC and OD registers can only be used as the destination of a
+ * texture instruction once per phase (this is an implementation
+ * restriction). 
+ */
+#define T0_DEST_NR_SHIFT                 14
+/* Allow R: 0..15, OC,OD: 0..0, U: 0..2 */
+#define T0_SAMPLER_NR_SHIFT              0 /* This field ignored for TEXKILL */
+#define T0_SAMPLER_NR_MASK               (0xf<<0)
+
+#define T1_ADDRESS_REG_TYPE_SHIFT        24 /* Reg to use as texture coord */
+/* Allow R, T, OC, OD -- R, OC, OD are 'dependent' reads, new program phase */
+#define T1_ADDRESS_REG_NR_SHIFT          17
+#define T2_MBZ                           0
+
+/* Declaration instructions */
+#define D0_DCL       (0x19<<24)	/* Declare a t (interpolated attrib)
+				 * register or an s (sampler)
+				 * register. */
+#define D0_SAMPLE_TYPE_SHIFT              22
+#define D0_SAMPLE_TYPE_2D                 (0x0<<22)
+#define D0_SAMPLE_TYPE_CUBE               (0x1<<22)
+#define D0_SAMPLE_TYPE_VOLUME             (0x2<<22)
+#define D0_SAMPLE_TYPE_MASK               (0x3<<22)
+
+#define D0_TYPE_SHIFT                19
+/* Allow: T, S */
+#define D0_NR_SHIFT                  14
+/* Allow T: 0..10, S: 0..15 */
+#define D0_CHANNEL_X                (1<<10)
+#define D0_CHANNEL_Y                (2<<10)
+#define D0_CHANNEL_Z                (4<<10)
+#define D0_CHANNEL_W                (8<<10)
+#define D0_CHANNEL_ALL              (0xf<<10)
+#define D0_CHANNEL_NONE             (0<<10)
+
+#define D0_CHANNEL_XY               (D0_CHANNEL_X|D0_CHANNEL_Y)
+#define D0_CHANNEL_XYZ              (D0_CHANNEL_XY|D0_CHANNEL_Z)
+
+/* I915 Errata: Do not allow (xz), (xw), (xzw) combinations for diffuse
+ * or specular declarations. 
+ *
+ * For T dcls, only allow: (x), (xy), (xyz), (w), (xyzw) 
+ *
+ * Must be zero for S (sampler) dcls
+ */
+#define D1_MBZ                          0
+#define D2_MBZ                          0
+
+
+
+/* p207 */
+#define _3DSTATE_MAP_STATE               (CMD_3D|(0x1d<<24)|(0x0<<16))
+
+#define MS1_MAPMASK_SHIFT               0
+#define MS1_MAPMASK_MASK                (0x8fff<<0)
+
+#define MS2_UNTRUSTED_SURFACE           (1<<31)
+#define MS2_ADDRESS_MASK                0xfffffffc
+#define MS2_VERTICAL_LINE_STRIDE        (1<<1)
+#define MS2_VERTICAL_OFFSET             (1<<1)
+
+#define MS3_HEIGHT_SHIFT              21
+#define MS3_WIDTH_SHIFT               10
+#define MS3_PALETTE_SELECT            (1<<9)
+#define MS3_MAPSURF_FORMAT_SHIFT      7
+#define MS3_MAPSURF_FORMAT_MASK       (0x7<<7)
+#define    MAPSURF_8BIT		 	   (1<<7)
+#define    MAPSURF_16BIT		   (2<<7)
+#define    MAPSURF_32BIT		   (3<<7)
+#define    MAPSURF_422			   (5<<7)
+#define    MAPSURF_COMPRESSED		   (6<<7)
+#define    MAPSURF_4BIT_INDEXED		   (7<<7)
+#define MS3_MT_FORMAT_MASK         (0x7 << 3)
+#define MS3_MT_FORMAT_SHIFT        3
+#define    MT_4BIT_IDX_ARGB8888	           (7<<3) /* SURFACE_4BIT_INDEXED */
+#define    MT_8BIT_I8		           (0<<3) /* SURFACE_8BIT */
+#define    MT_8BIT_L8		           (1<<3)
+#define    MT_8BIT_A8		           (4<<3)
+#define    MT_8BIT_MONO8	           (5<<3)
+#define    MT_16BIT_RGB565 		   (0<<3) /* SURFACE_16BIT */
+#define    MT_16BIT_ARGB1555		   (1<<3)
+#define    MT_16BIT_ARGB4444		   (2<<3)
+#define    MT_16BIT_AY88		   (3<<3)
+#define    MT_16BIT_88DVDU	           (5<<3)
+#define    MT_16BIT_BUMP_655LDVDU	   (6<<3)
+#define    MT_16BIT_I16	                   (7<<3)
+#define    MT_16BIT_L16	                   (8<<3)
+#define    MT_16BIT_A16	                   (9<<3)
+#define    MT_32BIT_ARGB8888		   (0<<3) /* SURFACE_32BIT */
+#define    MT_32BIT_ABGR8888		   (1<<3)
+#define    MT_32BIT_XRGB8888		   (2<<3)
+#define    MT_32BIT_XBGR8888		   (3<<3)
+#define    MT_32BIT_QWVU8888		   (4<<3)
+#define    MT_32BIT_AXVU8888		   (5<<3)
+#define    MT_32BIT_LXVU8888	           (6<<3)
+#define    MT_32BIT_XLVU8888	           (7<<3)
+#define    MT_32BIT_ARGB2101010	           (8<<3)
+#define    MT_32BIT_ABGR2101010	           (9<<3)
+#define    MT_32BIT_AWVU2101010	           (0xA<<3)
+#define    MT_32BIT_GR1616	           (0xB<<3)
+#define    MT_32BIT_VU1616	           (0xC<<3)
+#define    MT_32BIT_xI824	           (0xD<<3)
+#define    MT_32BIT_xA824	           (0xE<<3)
+#define    MT_32BIT_xL824	           (0xF<<3)
+#define    MT_422_YCRCB_SWAPY	           (0<<3) /* SURFACE_422 */
+#define    MT_422_YCRCB_NORMAL	           (1<<3)
+#define    MT_422_YCRCB_SWAPUV	           (2<<3)
+#define    MT_422_YCRCB_SWAPUVY	           (3<<3)
+#define    MT_COMPRESS_DXT1		   (0<<3) /* SURFACE_COMPRESSED */
+#define    MT_COMPRESS_DXT2_3	           (1<<3)
+#define    MT_COMPRESS_DXT4_5	           (2<<3)
+#define    MT_COMPRESS_FXT1		   (3<<3)
+#define    MT_COMPRESS_DXT1_RGB		   (4<<3)
+#define MS3_USE_FENCE_REGS              (1<<2)
+#define MS3_TILED_SURFACE             (1<<1)
+#define MS3_TILE_WALK                 (1<<0)
+
+#define MS4_PITCH_SHIFT                 21
+#define MS4_CUBE_FACE_ENA_NEGX          (1<<20)
+#define MS4_CUBE_FACE_ENA_POSX          (1<<19)
+#define MS4_CUBE_FACE_ENA_NEGY          (1<<18)
+#define MS4_CUBE_FACE_ENA_POSY          (1<<17)
+#define MS4_CUBE_FACE_ENA_NEGZ          (1<<16)
+#define MS4_CUBE_FACE_ENA_POSZ          (1<<15)
+#define MS4_CUBE_FACE_ENA_MASK          (0x3f<<15)
+#define MS4_MAX_LOD_SHIFT		9
+#define MS4_MAX_LOD_MASK		(0x3f<<9)
+#define MS4_MIP_LAYOUT_LEGACY           (0<<8)
+#define MS4_MIP_LAYOUT_BELOW_LPT        (0<<8)
+#define MS4_MIP_LAYOUT_RIGHT_LPT        (1<<8)
+#define MS4_VOLUME_DEPTH_SHIFT          0    
+#define MS4_VOLUME_DEPTH_MASK           (0xff<<0)
+
+/* p244 */
+#define _3DSTATE_SAMPLER_STATE         (CMD_3D|(0x1d<<24)|(0x1<<16))
+
+#define SS1_MAPMASK_SHIFT               0
+#define SS1_MAPMASK_MASK                (0x8fff<<0)
+
+#define SS2_REVERSE_GAMMA_ENABLE        (1<<31)
+#define SS2_PACKED_TO_PLANAR_ENABLE     (1<<30)
+#define SS2_COLORSPACE_CONVERSION       (1<<29)
+#define SS2_CHROMAKEY_SHIFT             27
+#define SS2_BASE_MIP_LEVEL_SHIFT        22
+#define SS2_BASE_MIP_LEVEL_MASK         (0x1f<<22)
+#define SS2_MIP_FILTER_SHIFT            20
+#define SS2_MIP_FILTER_MASK             (0x3<<20)
+#define   MIPFILTER_NONE       	0
+#define   MIPFILTER_NEAREST	1
+#define   MIPFILTER_LINEAR	3
+#define SS2_MAG_FILTER_SHIFT          17
+#define SS2_MAG_FILTER_MASK           (0x7<<17)
+#define   FILTER_NEAREST	0
+#define   FILTER_LINEAR		1
+#define   FILTER_ANISOTROPIC	2
+#define   FILTER_4X4_1    	3
+#define   FILTER_4X4_2    	4
+#define   FILTER_4X4_FLAT 	5
+#define   FILTER_6X5_MONO   	6 /* XXX - check */
+#define SS2_MIN_FILTER_SHIFT          14
+#define SS2_MIN_FILTER_MASK           (0x7<<14)
+#define SS2_LOD_BIAS_SHIFT            5
+#define SS2_LOD_BIAS_ONE              (0x10<<5)
+#define SS2_LOD_BIAS_MASK             (0x1ff<<5)
+/* Shadow requires:
+ *  MT_X8{I,L,A}24 or MT_{I,L,A}16 texture format
+ *  FILTER_4X4_x  MIN and MAG filters
+ */
+#define SS2_SHADOW_ENABLE             (1<<4)
+#define SS2_MAX_ANISO_MASK            (1<<3)
+#define SS2_MAX_ANISO_2               (0<<3)
+#define SS2_MAX_ANISO_4               (1<<3)
+#define SS2_SHADOW_FUNC_SHIFT         0
+#define SS2_SHADOW_FUNC_MASK          (0x7<<0)
+/* SS2_SHADOW_FUNC values: see COMPAREFUNC_* */
+
+#define SS3_MIN_LOD_SHIFT            24
+#define SS3_MIN_LOD_ONE              (0x10<<24)
+#define SS3_MIN_LOD_MASK             (0xff<<24)
+#define SS3_KILL_PIXEL_ENABLE        (1<<17)
+#define SS3_TCX_ADDR_MODE_SHIFT      12
+#define SS3_TCX_ADDR_MODE_MASK       (0x7<<12)
+#define   TEXCOORDMODE_WRAP		0
+#define   TEXCOORDMODE_MIRROR		1
+#define   TEXCOORDMODE_CLAMP_EDGE	2
+#define   TEXCOORDMODE_CUBE       	3
+#define   TEXCOORDMODE_CLAMP_BORDER	4
+#define   TEXCOORDMODE_MIRROR_ONCE      5
+#define SS3_TCY_ADDR_MODE_SHIFT      9
+#define SS3_TCY_ADDR_MODE_MASK       (0x7<<9)
+#define SS3_TCZ_ADDR_MODE_SHIFT      6
+#define SS3_TCZ_ADDR_MODE_MASK       (0x7<<6)
+#define SS3_NORMALIZED_COORDS        (1<<5)
+#define SS3_TEXTUREMAP_INDEX_SHIFT   1
+#define SS3_TEXTUREMAP_INDEX_MASK    (0xf<<1)
+#define SS3_DEINTERLACER_ENABLE      (1<<0)
+
+#define SS4_BORDER_COLOR_MASK        (~0)
+
+/* 3DSTATE_SPAN_STIPPLE, p258
+ */
+#define _3DSTATE_STIPPLE           ((0x3<<29)|(0x1d<<24)|(0x83<<16))
+#define ST1_ENABLE               (1<<16)
+#define ST1_MASK                 (0xffff)
+
+
+#define FLUSH_MAP_CACHE    (1<<0)
+#define FLUSH_RENDER_CACHE (1<<1)
+
+
+#endif
diff-tree 3592b432b48d51d2273c1e1064f85e656fbba130 (from a50610b7719bfe800c3496c17d0ba77739167b35)
Author: Alan Hourihane <alanh at fairlite.demon.co.uk>
Date:   Tue Jun 13 21:42:53 2006 +0100

    fix 8bpp & 16bpp rotation modes for i8xx
    series chips

diff --git a/src/i830_rotate.c b/src/i830_rotate.c
index e4a8064..4d7237f 100644
--- a/src/i830_rotate.c
+++ b/src/i830_rotate.c
@@ -574,9 +574,9 @@ I830UpdateRotate (ScreenPtr      pScreen
 	 OUT_RING(pI8301->RotatedMem2.Start | use_fence);
 
       if (pI830->cpp == 1)
-         OUT_RING(0x00 | (pScreen->height - 1) << 21 | (pScreen->width - 1) << 10);
-      else if (pI830->cpp == 2)
          OUT_RING(0x40 | (pScreen->height - 1) << 21 | (pScreen->width - 1) << 10);
+      else if (pI830->cpp == 2)
+         OUT_RING(0x80 | (pScreen->height - 1) << 21 | (pScreen->width - 1) << 10);
       else
          OUT_RING(0xc0 | (pScreen->height - 1) << 21 | (pScreen->width - 1) << 10);
 
diff-tree a50610b7719bfe800c3496c17d0ba77739167b35 (from f02268b2091c9a785d26e82bcb35a8b713463072)
Author: Alan Hourihane <alanh at fairlite.demon.co.uk>
Date:   Mon Jun 12 13:53:20 2006 +0100

    Use 800x600 mode to double check

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 2d02c48..e43e355 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -956,17 +956,14 @@ I830Set640x480(ScrnInfoPtr pScrn)
 	   return TRUE;
 
    /* if the first failed, let's try the next - usually 800x600 */
-   m = 0x31;
-
+   m = 0x32;
    switch (pScrn->depth) {
    case 15:
-	 m = 0x42;
-	 break;
    case 16:
-	 m = 0x43;
+	 m = 0x42;
 	 break;
    case 24:
-	 m = 0x51;
+	 m = 0x52;
 	 break;
    }
    m |= (1 << 15) | (1 << 14);
diff-tree f02268b2091c9a785d26e82bcb35a8b713463072 (from 672c3d18dbb405095e465126053ff887d891409e)
Author: Alan Hourihane <alanh at fairlite.demon.co.uk>
Date:   Mon Jun 12 12:16:58 2006 +0100

    Don't rely on register check to find out
    if we're resuming - it's not reliable.
    
    But then, neither is the BIOS, but it's
    the best we can hope for until Eric's work
    is complete.
    
    Try setting another mode to cater for some
    broken BIOS' too.

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 062d035..2d02c48 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -952,7 +952,28 @@ I830Set640x480(ScrnInfoPtr pScrn)
 	 break;
    }
    m |= (1 << 15) | (1 << 14);
-   return VBESetVBEMode(pI830->pVbe, m, NULL);
+   if (VBESetVBEMode(pI830->pVbe, m, NULL))
+	   return TRUE;
+
+   /* if the first failed, let's try the next - usually 800x600 */
+   m = 0x31;
+
+   switch (pScrn->depth) {
+   case 15:
+	 m = 0x42;
+	 break;
+   case 16:
+	 m = 0x43;
+	 break;
+   case 24:
+	 m = 0x51;
+	 break;
+   }
+   m |= (1 << 15) | (1 << 14);
+   if (VBESetVBEMode(pI830->pVbe, m, NULL))
+	   return TRUE;
+
+   return FALSE;
 }
 
 /* This is needed for SetDisplayDevices to work correctly on I915G.
@@ -5535,9 +5556,7 @@ I830BIOSEnterVT(int scrnIndex, int flags
       * the Video BIOS with our saved devices, and only when that fails,
       * we'll warm boot it.
       */
-     /* Check Pipe conf registers or possibly HTOTAL/VTOTAL for 0x00000000)*/
-      CARD32 temp = pI830->pipe ? INREG(PIPEBCONF) : INREG(PIPEACONF);
-      if (!I830Set640x480(pScrn) || !(temp & 0x80000000)) {
+      if (!I830Set640x480(pScrn)) {
          xf86Int10InfoPtr pInt;
 
          xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
diff-tree 672c3d18dbb405095e465126053ff887d891409e (from 6812b5382077e5d3f421aceeeb2f337e9b3f570e)
Author: Alan Hourihane <alanh at fairlite.demon.co.uk>
Date:   Mon Jun 12 10:02:06 2006 +0100

    Only mark rotation flags after initial screen setup.
    Fixes bug #7053

diff --git a/src/i830_dri.h b/src/i830_dri.h
index e511ac7..4f356d1 100644
--- a/src/i830_dri.h
+++ b/src/i830_dri.h
@@ -9,8 +9,8 @@
 #define I830_MAX_DRAWABLES 256
 
 #define I830_MAJOR_VERSION 1
-#define I830_MINOR_VERSION 5
-#define I830_PATCHLEVEL 1
+#define I830_MINOR_VERSION 6
+#define I830_PATCHLEVEL 0
 
 #define I830_REG_SIZE 0x80000
 
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 0f5c66c..062d035 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -4748,28 +4748,6 @@ I830BIOSScreenInit(int scrnIndex, Screen
    hwp = VGAHWPTR(pScrn);
 
    pScrn->displayWidth = pI830->displayWidth;
-   switch (pI830->InitialRotation) {
-      case 0:
-         xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Rotating to 0 degrees\n");
-         pI830->rotation = RR_Rotate_0;
-         break;
-      case 90:
-         xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Rotating to 90 degrees\n");
-         pI830->rotation = RR_Rotate_90;
-         break;
-      case 180:
-         xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Rotating to 180 degrees\n");
-         pI830->rotation = RR_Rotate_180;
-         break;
-      case 270:
-         xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Rotating to 270 degrees\n");
-         pI830->rotation = RR_Rotate_270;
-         break;
-      default:
-         xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Bad rotation setting - defaulting to 0 degrees\n");
-         pI830->rotation = RR_Rotate_0;
-         break;
-   }
 
    if (I830IsPrimary(pScrn)) {
       /* Rotated Buffer */
@@ -5158,6 +5136,29 @@ I830BIOSScreenInit(int scrnIndex, Screen
    pI830->closing = FALSE;
    pI830->suspended = FALSE;
 
+   switch (pI830->InitialRotation) {
+      case 0:
+         xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Rotating to 0 degrees\n");
+         pI830->rotation = RR_Rotate_0;
+         break;
+      case 90:
+         xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Rotating to 90 degrees\n");
+         pI830->rotation = RR_Rotate_90;
+         break;
+      case 180:
+         xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Rotating to 180 degrees\n");
+         pI830->rotation = RR_Rotate_180;
+         break;
+      case 270:
+         xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Rotating to 270 degrees\n");
+         pI830->rotation = RR_Rotate_270;
+         break;
+      default:
+         xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Bad rotation setting - defaulting to 0 degrees\n");
+         pI830->rotation = RR_Rotate_0;
+         break;
+   }
+
    return TRUE;
 }
 
diff-tree 6812b5382077e5d3f421aceeeb2f337e9b3f570e (from f97895efd5532cca145b6f224f9615739b1e8f26)
Author: Dave Airlie <airlied at linux.ie>
Date:   Fri Jun 2 12:22:14 2006 +1000

    intel: fix VT switch DRI locking
    
    The DRI locking is incorrect at VT switch, due to reference counting
    inside the driver. Just call the DRI directly.

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 5462d6c..0f5c66c 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -5279,7 +5279,7 @@ I830BIOSLeaveVT(int scrnIndex, int flags
 
 #ifdef XF86DRI
    if (pI830->directRenderingOpen) {
-      I830DRILock(pScrn);
+      DRILock(screenInfo.screens[pScrn->scrnIndex], 0);
       
       drmCtlUninstHandler(pI830->drmSubFD);
    }
@@ -5611,7 +5611,7 @@ I830BIOSEnterVT(int scrnIndex, int flags
 	 DO_RING_IDLE();
 
 	 DPRINTF(PFX, "calling dri unlock\n");
-	 I830DRIUnlock(pScrn);
+	 DRIUnlock(screenInfo.screens[pScrn->scrnIndex]);
       }
       pI830->LockHeld = 0;
    }
diff-tree 3f158fd610a3363a23daa7205bcd9f213686cf1c (from bb0ad04d46eba2fed57a888ff960d2436ec7d70d)
Author: Keith his master's voice Packard <keithp at bw.jf.intel.com>
Date:   Mon May 29 18:05:57 2006 -0700

    Nice texture coordinate gradient, broken slightly in y

diff --git a/src/i830_video.c b/src/i830_video.c
index 6e507aa..33e716f 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2673,6 +2673,69 @@ static const CARD32 vs_kernel_static[][4
 #define SF_MAX_THREADS	   1
 
 static const CARD32 sf_kernel_static[][4] = {
+#if 1
+/*    send   0 (4) g6<1>F g1.12<4,4,1>F math mlen 1 rlen 1 { align1 +  } */
+   { 0x00400031, 0x20c01fbd, 0x0069002c, 0x01110081 },
+/*    add (8) g7<1>F g4<8,8,1>F g3<8,8,1>F { align1 +  } */
+   { 0x00600040, 0x20e077bd, 0x008d0080, 0x008d4060 },
+/*    mul (1) g7<1>F g7<0,1,0>F g6<0,1,0>F { align1 +  } */
+   { 0x00000041, 0x20e077bd, 0x000000e0, 0x000000c0 },
+/*    mov (1) g7.4<1>F g6.12<0,1,0>F { align1 +  } */
+   { 0x00000001, 0x20e403bd, 0x000000cc, 0x00000000 },
+/*    mov (8) m1<1>F g7<0,1,0>F { align1 +  } */
+   { 0x00600001, 0x202003be, 0x000000e0, 0x00000000 },
+/*    mov (8) m2<1>F g7.4<0,1,0>F { align1 +  } */
+   { 0x00600001, 0x204003be, 0x000000e4, 0x00000000 },
+/*    mov (8) m3<1>F g3<8,8,1>F { align1 +  } */
+   { 0x00600001, 0x206003be, 0x008d0060, 0x00000000 },
+/*    send   0 (8) a0<1>F g0<8,8,1>F urb mlen 4 rlen 0 write +0 noswizzle used complete EOT{ align1 +  } */
+   { 0x00600031, 0x20001fbc, 0x008d0000, 0x8640c000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+
+#endif
+#if 0
+/*    mov (8) m1<1>F 0.00138889{ align1 +  } */
+   { 0x00600001, 0x202073fe, 0x00000000, 0x3ab60b61 },
+/*    mov (8) m2<1>F 0.00208333{ align1 +  } */
+   { 0x00600001, 0x204073fe, 0x00000000, 0x3b088889 },
+/*    mov (8) m3<1>F g3<8,8,1>F { align1 +  } */
+   { 0x00600001, 0x206003be, 0x008d0060, 0x00000000 },
+/*    send   0 (8) a0<1>F g0<8,8,1>F urb mlen 4 rlen 0 write +0 noswizzle used complete EOT{ align1 +  } */
+   { 0x00600031, 0x20001fbc, 0x008d0000, 0x8640c000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+#endif
+
+#if 0
 /*    send   0 (1) g6<1>F g1.8<0,1,0>F math mlen 1 rlen 1 { align1 +  } */
     { 0x00000031, 0x20c01fbd, 0x00000028, 0x01110081 },
 /*    mov (2) g3.8<1>F g2<2,2,1>F { align1 +  } */
@@ -2725,27 +2788,58 @@ static const CARD32 sf_kernel_static[][4
     { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
 /*    nop (4) g0<1>UD { align1 +  } */
     { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+#endif
 };
 
+/*
+ * Ok, this kernel picks up the required data flow values in g0 and g1
+ * and passes those along in m0 and m1. In m2-m9, it sticks constant
+ * values (bright pink).
+ */
+
+/*
+ * I am reasonably sure these values are bogus
+ * but, they do appear to work. Learning precisely what
+ * values belong here should improve performance by
+ * increasing the number of threads that will be able to run
+ * in parallel.
+ */
+
 #define PS_KERNEL_NUM_GRF   20
 #define PS_KERNEL_NUM_URB   8
 #define PS_MAX_THREADS	   1 /* MIN(12, PS_KERNEL_NUM_URB / 2) */
 
 static const CARD32 ps_kernel_static[][4] = {
-/*    mov (8) m2<1>F 1{ align1 +  } */
-   { 0x00600001, 0x204073fe, 0x00000000, 0x3f800000 },
-/*    mov (8) m3<1>F 0.5{ align1 +  } */
-   { 0x00600001, 0x206073fe, 0x00000000, 0x3f000000 },
-/*    mov (8) m4<1>F 0.75{ align1 +  } */
-   { 0x00600001, 0x208073fe, 0x00000000, 0x3f400000 },
+/*    mov (8) g2<1>F g1.8<0,1,0>UW { align1 +  } */
+   { 0x00600001, 0x2040013d, 0x00000028, 0x00000000 },
+/*    add (8) g2<1>F g2<8,8,1>F g1<0,1,0>F { align1 +  } */
+   { 0x00600040, 0x204077bd, 0x008d0040, 0x00004020 },
+/*    mul (8) g2<1>F g2<8,8,1>F g10<0,1,0>F { align1 +  } */
+   { 0x00600041, 0x204077bd, 0x008d0040, 0x00000140 },
+/*    add (8) g2<1>F g2<8,8,1>F g12<0,1,0>F { align1 +  } */
+   { 0x00600040, 0x204077bd, 0x008d0040, 0x00000180 },
+/*    mov (8) g3<1>F g1.10<0,1,0>UW { align1 +  } */
+   { 0x00600001, 0x2060013d, 0x0000002a, 0x00000000 },
+/*    add (8) g3<1>F g3<8,8,1>F g1.4<0,1,0>F { align1 +  } */
+   { 0x00600040, 0x206077bd, 0x008d0060, 0x00004024 },
+/*    mul (8) g3<1>F g3<8,8,1>F g11<0,1,0>F { align1 +  } */
+   { 0x00600041, 0x206077bd, 0x008d0060, 0x00000160 },
+/*    add (8) g3<1>F g3<8,8,1>F g12.4<0,1,0>F { align1 +  } */
+   { 0x00600040, 0x206077bd, 0x008d0060, 0x00000184 },
+/*    mov (8) m2<1>F g2<8,8,1>F { align1 +  } */
+   { 0x00600001, 0x204003be, 0x008d0040, 0x00000000 },
+/*    mov (8) m3<1>F g3<8,8,1>F { align1 +  } */
+   { 0x00600001, 0x206003be, 0x008d0060, 0x00000000 },
+/*    mov (8) m4<1>F 0{ align1 +  } */
+   { 0x00600001, 0x208073fe, 0x00000000, 0x00000000 },
 /*    mov (8) m5<1>F 1{ align1 +  } */
    { 0x00600001, 0x20a073fe, 0x00000000, 0x3f800000 },
-/*    mov (8) m6<1>F 1{ align1 +  } */
-   { 0x00600001, 0x20c073fe, 0x00000000, 0x3f800000 },
-/*    mov (8) m7<1>F 0.5{ align1 +  } */
-   { 0x00600001, 0x20e073fe, 0x00000000, 0x3f000000 },
-/*    mov (8) m8<1>F 0.75{ align1 +  } */
-   { 0x00600001, 0x210073fe, 0x00000000, 0x3f400000 },
+/*    mov (8) m6<1>F g2<8,8,1>F { align1 +  } */
+   { 0x00600001, 0x20c003be, 0x008d0040, 0x00000000 },
+/*    mov (8) m7<1>F g3<8,8,1>F { align1 +  } */
+   { 0x00600001, 0x20e003be, 0x008d0060, 0x00000000 },
+/*    mov (8) m8<1>F 0{ align1 +  } */
+   { 0x00600001, 0x210073fe, 0x00000000, 0x00000000 },
 /*    mov (8) m9<1>F 1{ align1 +  } */
    { 0x00600001, 0x212073fe, 0x00000000, 0x3f800000 },
 /*    mov (8) m1<1>UD g1<8,8,1>UD { align1 mask_disable +  } */
@@ -2810,6 +2904,10 @@ brw_debug (ScrnInfoPtr pScrn, char *when
    }
 }
 
+#define WATCH_SF 0
+#define WATCH_WIZ 0
+#define WATCH_STATS 0
+
 static void
 BroadwaterDisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
 			       RegionPtr dstRegion,
@@ -2874,7 +2972,9 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    OUTREG (INST_PM,
 	   (1 << (16 + 4)) |
 	   (1 << 4));
+#if 0
    ErrorF ("INST_PM 0x%08x\n", INREG(INST_PM));
+#endif
    
    assert((id == FOURCC_UYVY) || (id == FOURCC_YUY2));
 
@@ -3051,7 +3151,7 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    /* Set up the source surface state buffer */
    memset(src_surf_state, 0, sizeof(*src_surf_state));
    src_surf_state->ss0.surface_type = BRW_SURFACE_2D;
-   src_surf_state->ss0.data_return_format = BRW_SURFACERETURNFORMAT_FLOAT32;
+/*   src_surf_state->ss0.data_return_format = BRW_SURFACERETURNFORMAT_FLOAT32; */
    switch (id) {
    case FOURCC_YUY2:
       src_surf_state->ss0.surface_format = BRW_SURFACEFORMAT_YCRCB_NORMAL;
@@ -3104,7 +3204,9 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    memcpy(vs_kernel, vs_kernel_static, sizeof (vs_kernel_static));
    
    memset(vs_state, 0, sizeof(*vs_state));
+#if 0
    ErrorF ("vs kernel: 0x%08x\n", state_base_offset + vs_kernel_offset);
+#endif
    vs_state->thread0.kernel_start_pointer =
 	    (state_base_offset + vs_kernel_offset) >> 6;
    vs_state->thread0.grf_reg_count = 1;
@@ -3122,25 +3224,29 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
 
    memcpy (sf_kernel, sf_kernel_static, sizeof (sf_kernel_static));
    memset(sf_state, 0, sizeof(*sf_state));
+#if 0
    ErrorF ("sf kernel: 0x%08x\n", state_base_offset + sf_kernel_offset);
+#endif
    sf_state->thread0.kernel_start_pointer = 
 	       (state_base_offset + sf_kernel_offset) >> 6;
    sf_state->thread0.grf_reg_count = ((SF_KERNEL_NUM_GRF & ~15) / 16);
    sf_state->sf1.single_program_flow = 1; /* XXX */
    sf_state->sf1.binding_table_entry_count = 0;
    sf_state->sf1.thread_priority = 0;
-   sf_state->sf1.floating_point_mode = 1; /* Mesa does this */
+   sf_state->sf1.floating_point_mode = 0; /* Mesa does this */
    sf_state->sf1.illegal_op_exception_enable = 1;
    sf_state->sf1.mask_stack_exception_enable = 1;
    sf_state->sf1.sw_exception_enable = 1;
    sf_state->thread2.per_thread_scratch_space = 0;
    sf_state->thread2.scratch_space_base_pointer = 0; /* not used in our kernel */
-   sf_state->thread3.urb_entry_read_length = 1; /* XXX */
-   sf_state->thread3.urb_entry_read_offset = 1; /* XXX */
-   sf_state->thread3.dispatch_grf_start_reg = 3; /* XXX */
-   sf_state->thread4.nr_urb_entries = URB_SF_ENTRIES;
-   sf_state->thread4.urb_entry_allocation_size = URB_SF_ENTRY_SIZE - 1;
+   sf_state->thread3.const_urb_entry_read_length = 0; /* no const URBs */
+   sf_state->thread3.const_urb_entry_read_offset = 0; /* no const URBs */
+   sf_state->thread3.urb_entry_read_length = 1; /* 1 URB per vertex */
+   sf_state->thread3.urb_entry_read_offset = 0;
+   sf_state->thread3.dispatch_grf_start_reg = 3;
    sf_state->thread4.max_threads = MIN(12, URB_SF_ENTRIES / 2) - 1;
+   sf_state->thread4.urb_entry_allocation_size = URB_SF_ENTRY_SIZE - 1;
+   sf_state->thread4.nr_urb_entries = URB_SF_ENTRIES;
    sf_state->thread4.stats_enable = 1;
    sf_state->sf5.viewport_transform = FALSE; /* skip viewport */
    sf_state->sf6.cull_mode = BRW_CULLMODE_NONE;
@@ -3163,7 +3269,9 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
     */
 
    memcpy (ps_kernel, ps_kernel_static, sizeof (ps_kernel_static));
+#if 0
    ErrorF ("ps kernel: 0x%08x\n", state_base_offset + ps_kernel_offset);
+#endif
    memset (wm_state, 0, sizeof (*wm_state));
    wm_state->thread0.kernel_start_pointer = 
 	    (state_base_offset + ps_kernel_offset) >> 6;
@@ -3173,13 +3281,13 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    wm_state->thread2.scratch_space_base_pointer = 0; /* XXX */
    wm_state->thread2.per_thread_scratch_space = 0; /* XXX */
    wm_state->thread3.dispatch_grf_start_reg = 10; /* XXX */
-   wm_state->thread3.urb_entry_read_length = 2; /* XXX */
+   wm_state->thread3.urb_entry_read_length = 3; /* XXX */
    wm_state->thread3.const_urb_entry_read_length = 0; /* XXX */
    wm_state->thread3.const_urb_entry_read_offset = 0; /* XXX */
    wm_state->thread3.urb_entry_read_offset = 0; /* XXX */
    wm_state->wm4.stats_enable = 1;
    wm_state->wm4.sampler_state_pointer = (state_base_offset + src_sampler_offset) >> 5;
-   wm_state->wm4.sampler_count = 0; /* XXX 1-4 samplers used */
+   wm_state->wm4.sampler_count = 1; /* XXX 1-4 samplers used */
    wm_state->wm5.max_threads = 0;   /* XXX should be PS_MAX_THREADS */
    wm_state->wm5.thread_dispatch_enable = 1;
    wm_state->wm5.enable_16_pix = 1;
@@ -3330,7 +3438,6 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    dxo = dstRegion->extents.x1;
    dyo = dstRegion->extents.y1;
 
-   ErrorF ("region origin %d, %d\n", dxo, dyo);
    pbox = REGION_RECTS(dstRegion);
    nbox = REGION_NUM_RECTS(dstRegion);
    while (nbox--)
@@ -3354,8 +3461,9 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
 
       pbox++;
 
-      src_scale_x = (float)src_w / (float)drw_w;
-      src_scale_y  = (float)src_h / (float)drw_h;
+      /* Use normalized texture coordinates */
+      src_scale_x = (float)1.0 / (float)drw_w;
+      src_scale_y  = (float)1.0 / (float)drw_h;
 
       i = 0;
       vb[i++] = (box_x2 - dxo) * src_scale_x;
@@ -3373,8 +3481,11 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
       vb[i++] = (float) box_x1;
       vb[i++] = (float) box_y1;
 
+#if 0
       memset (vs_scratch, 1, VS_SCRATCH_SIZE);
+#endif
       
+#if 0
       ErrorF ("before EU_ATT 0x%08x%08x EU_ATT_DATA 0x%08x%08x\n",
 	      INREG(BRW_EU_ATT_1), INREG(BRW_EU_ATT_0),
 	      INREG(BRW_EU_ATT_DATA_1), INREG(BRW_EU_ATT_DATA_0));
@@ -3384,6 +3495,7 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
 	     BRW_VF_CTL_SNAPSHOT_TYPE_VERTEX_INDEX |
 	     BRW_VF_CTL_SNAPSHOT_ENABLE);
       OUTREG(BRW_VF_STRG_VAL, 0);
+#endif
       
 #if 0
       OUTREG(BRW_VS_CTL,
@@ -3394,18 +3506,22 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
       OUTREG(BRW_VS_STRG_VAL, 0);
 #endif
       
+#if WATCH_SF
       OUTREG(BRW_SF_CTL,
 	     BRW_SF_CTL_SNAPSHOT_MUX_VERTEX_COUNT |
 	     BRW_SF_CTL_SNAPSHOT_ALL_THREADS |
 	     BRW_SF_CTL_THREAD_SNAPSHOT_ENABLE);
       OUTREG(BRW_SF_STRG_VAL, 0);
-      
+#endif
+
+#if WATCH_WIZ
       OUTREG(BRW_WIZ_CTL,
 	     BRW_WIZ_CTL_SNAPSHOT_MUX_SUBSPAN_INSTANCE |
 	     BRW_WIZ_CTL_SNAPSHOT_ALL_THREADS |
 	     BRW_WIZ_CTL_SNAPSHOT_ENABLE);
       OUTREG(BRW_WIZ_STRG_VAL,
 	     (box_x1) | (box_y1 << 16));
+#endif
       
 #if 0
       OUTREG(BRW_TS_CTL,
@@ -3431,6 +3547,7 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
       int   j, k;
       CARD32	  ctl = 0, rdata;
       
+#if 0
       for (j = 0; j < 100000; j++) {
 	ctl = INREG(BRW_VF_CTL);
 	 if (ctl & BRW_VF_CTL_SNAPSHOT_COMPLETE)
@@ -3440,6 +3557,7 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
       rdata = INREG(BRW_VF_RDATA);
       OUTREG(BRW_VF_CTL, 0);
       ErrorF ("VF_CTL: 0x%08x VF_RDATA: 0x%08x\n", ctl, rdata);
+#endif
 
 #if 0
       for (j = 0; j < 1000000; j++) {
@@ -3467,6 +3585,7 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
 		 vs_scratch[j+6], vs_scratch[j+7]);
 #endif
 
+#if WATCH_SF
       for (j = 0; j < 1000000; j++) {
 	ctl = INREG(BRW_SF_CTL);
 	 if (ctl & BRW_SF_CTL_SNAPSHOT_COMPLETE)
@@ -3482,7 +3601,9 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
       }
       
       OUTREG(BRW_SF_CTL, 0);
+#endif
 
+#if WATCH_WIZ
       for (j = 0; j < 100000; j++) {
 	ctl = INREG(BRW_WIZ_CTL);
 	 if (ctl & BRW_WIZ_CTL_SNAPSHOT_COMPLETE)
@@ -3492,7 +3613,9 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
       rdata = INREG(BRW_WIZ_RDATA);
       OUTREG(BRW_WIZ_CTL, 0);
       ErrorF ("WIZ_CTL: 0x%08x WIZ_RDATA: 0x%08x\n", ctl, rdata);
+#endif
       
+#if 0
       for (j = 0; j < 100000; j++) {
 	ctl = INREG(BRW_TS_CTL);
 	 if (ctl & BRW_TS_CTL_SNAPSHOT_COMPLETE)
@@ -3506,6 +3629,7 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
       ErrorF ("after EU_ATT 0x%08x%08x EU_ATT_DATA 0x%08x%08x\n",
 	      INREG(BRW_EU_ATT_1), INREG(BRW_EU_ATT_0),
 	      INREG(BRW_EU_ATT_DATA_1), INREG(BRW_EU_ATT_DATA_0));
+#endif
 
 #if 0
       for (j = 0; j < 256; j++) {
@@ -3521,7 +3645,9 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
 
    if (pI830->AccelInfoRec)
       (*pI830->AccelInfoRec->Sync)(pScrn);
+#if WATCH_STATS
    I830PrintErrorState (pScrn);
+#endif
    xf86FreeOffscreenLinear(state_area);
 }
 
diff-tree bb0ad04d46eba2fed57a888ff960d2436ec7d70d (from ddf3e5b2737399dca6d401f91db51a51f93b6373)
Author: Keith his master's voice Packard <keithp at bw.jf.intel.com>
Date:   Sun May 28 22:59:58 2006 -0700

    Ok, finally something sensible up on the screen.
    Replace PS kernel with constant data source (pink).
    Dodge g0/g1 so URB data doesn't land on top of thread data.
    Flip source/dest coordinates (dunno why they're fetched this way).

diff --git a/src/i830_video.c b/src/i830_video.c
index ee4f2a2..6e507aa 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2727,29 +2727,29 @@ static const CARD32 sf_kernel_static[][4
     { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
 };
 
-#define PS_KERNEL_NUM_GRF   10
+#define PS_KERNEL_NUM_GRF   20
 #define PS_KERNEL_NUM_URB   8
 #define PS_MAX_THREADS	   1 /* MIN(12, PS_KERNEL_NUM_URB / 2) */
 
 static const CARD32 ps_kernel_static[][4] = {
-/*    mov (8) m2<1>F g2<16,16,1>UW { align1 +  } */
-   { 0x00600001, 0x2040013e, 0x00b10040, 0x00000000 },
-/*    mov (8) m6<1>F g3<16,16,1>UW { align1 sechalf +  } */
-   { 0x00601001, 0x20c0013e, 0x00b10060, 0x00000000 },
-/*    mov (8) m3<1>F g3<16,16,1>UW { align1 +  } */
-   { 0x00600001, 0x2060013e, 0x00b10060, 0x00000000 },
-/*    mov (8) m7<1>F g4<16,16,1>UW { align1 sechalf +  } */
-   { 0x00601001, 0x20e0013e, 0x00b10080, 0x00000000 },
-/*    mov (8) m4<1>F g4<16,16,1>UW { align1 +  } */
-   { 0x00600001, 0x2080013e, 0x00b10080, 0x00000000 },
-/*    mov (8) m8<1>F g5<16,16,1>UW { align1 sechalf +  } */
-   { 0x00601001, 0x2100013e, 0x00b100a0, 0x00000000 },
-/*    mov (8) m5<1>F g5<16,16,1>UW { align1 +  } */
-   { 0x00600001, 0x20a0013e, 0x00b100a0, 0x00000000 },
-/*    mov (8) m9<1>F g6<16,16,1>UW { align1 sechalf +  } */
-   { 0x00601001, 0x2120013e, 0x00b100c0, 0x00000000 },
-/*    mov (8) m1<1>F g1<8,8,1>F { align1 mask_disable +  } */
-   { 0x00600201, 0x202003be, 0x008d0020, 0x00000000 },
+/*    mov (8) m2<1>F 1{ align1 +  } */
+   { 0x00600001, 0x204073fe, 0x00000000, 0x3f800000 },
+/*    mov (8) m3<1>F 0.5{ align1 +  } */
+   { 0x00600001, 0x206073fe, 0x00000000, 0x3f000000 },
+/*    mov (8) m4<1>F 0.75{ align1 +  } */
+   { 0x00600001, 0x208073fe, 0x00000000, 0x3f400000 },
+/*    mov (8) m5<1>F 1{ align1 +  } */
+   { 0x00600001, 0x20a073fe, 0x00000000, 0x3f800000 },
+/*    mov (8) m6<1>F 1{ align1 +  } */
+   { 0x00600001, 0x20c073fe, 0x00000000, 0x3f800000 },
+/*    mov (8) m7<1>F 0.5{ align1 +  } */
+   { 0x00600001, 0x20e073fe, 0x00000000, 0x3f000000 },
+/*    mov (8) m8<1>F 0.75{ align1 +  } */
+   { 0x00600001, 0x210073fe, 0x00000000, 0x3f400000 },
+/*    mov (8) m9<1>F 1{ align1 +  } */
+   { 0x00600001, 0x212073fe, 0x00000000, 0x3f800000 },
+/*    mov (8) m1<1>UD g1<8,8,1>UD { align1 mask_disable +  } */
+   { 0x00600201, 0x20200022, 0x008d0020, 0x00000000 },
 /*    send   0 (16) a0<1>UW g0<8,8,1>UW write mlen 10 rlen 0 EOT{ align1 +  } */
    { 0x00800031, 0x20001d28, 0x008d0000, 0x85a04800 },
 /*    nop (4) g0<1>UD { align1 +  } */
@@ -3008,13 +3008,16 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    cc_state->cc0.stencil_enable = 0;   /* disable stencil */
    cc_state->cc2.depth_test = 0;       /* disable depth test */
    cc_state->cc2.logicop_enable = 1;   /* enable logic op */
-   cc_state->cc3.ia_blend_enable = 0;  /* blend alpha just like colors */
+   cc_state->cc3.ia_blend_enable = 1;  /* blend alpha just like colors */
    cc_state->cc3.blend_enable = 0;     /* disable color blend */
    cc_state->cc3.alpha_test = 0;       /* disable alpha test */
    cc_state->cc4.cc_viewport_state_offset = (state_base_offset + cc_viewport_offset) >> 5;
    cc_state->cc5.dither_enable = 0;    /* disable dither */
-   cc_state->cc5.logicop_func = 0xc;   /* COPYPEN */
+   cc_state->cc5.logicop_func = 0xc;   /* WHITE */
    cc_state->cc5.statistics_enable = 1;
+   cc_state->cc5.ia_blend_function = BRW_BLENDFUNCTION_ADD;
+   cc_state->cc5.ia_src_blend_factor = BRW_BLENDFACTOR_ONE;
+   cc_state->cc5.ia_dest_blend_factor = BRW_BLENDFACTOR_ONE;
 
    /* Upload system kernel */
    memcpy (sip_kernel, sip_kernel_static, sizeof (sip_kernel_static));
@@ -3165,17 +3168,18 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    wm_state->thread0.kernel_start_pointer = 
 	    (state_base_offset + ps_kernel_offset) >> 6;
    wm_state->thread0.grf_reg_count = ((PS_KERNEL_NUM_GRF & ~15) / 16);
-   wm_state->thread1.single_program_flow = 0; /* XXX */
+   wm_state->thread1.single_program_flow = 1; /* XXX */
    wm_state->thread1.binding_table_entry_count = 2;
    wm_state->thread2.scratch_space_base_pointer = 0; /* XXX */
    wm_state->thread2.per_thread_scratch_space = 0; /* XXX */
-   wm_state->thread3.dispatch_grf_start_reg = 0; /* XXX */
-   wm_state->thread3.urb_entry_read_length = 4; /* XXX */
+   wm_state->thread3.dispatch_grf_start_reg = 10; /* XXX */
+   wm_state->thread3.urb_entry_read_length = 2; /* XXX */
    wm_state->thread3.const_urb_entry_read_length = 0; /* XXX */
+   wm_state->thread3.const_urb_entry_read_offset = 0; /* XXX */
    wm_state->thread3.urb_entry_read_offset = 0; /* XXX */
    wm_state->wm4.stats_enable = 1;
    wm_state->wm4.sampler_state_pointer = (state_base_offset + src_sampler_offset) >> 5;
-   wm_state->wm4.sampler_count = 1; /* 1-4 samplers used */
+   wm_state->wm4.sampler_count = 0; /* XXX 1-4 samplers used */
    wm_state->wm5.max_threads = 0;   /* XXX should be PS_MAX_THREADS */
    wm_state->wm5.thread_dispatch_enable = 1;
    wm_state->wm5.enable_16_pix = 1;
@@ -3326,6 +3330,7 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    dxo = dstRegion->extents.x1;
    dyo = dstRegion->extents.y1;
 
+   ErrorF ("region origin %d, %d\n", dxo, dyo);
    pbox = REGION_RECTS(dstRegion);
    nbox = REGION_NUM_RECTS(dstRegion);
    while (nbox--)
@@ -3347,30 +3352,26 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
 	 }
       }
 
-      /* just paint 4 pixels */
-      box_x2 = box_x1 + 2;
-      box_y2 = box_y1 + 2;
-
       pbox++;
 
       src_scale_x = (float)src_w / (float)drw_w;
       src_scale_y  = (float)src_h / (float)drw_h;
 
       i = 0;
-      vb[i++] = (float) box_x2;
-      vb[i++] = (float) box_y2;
       vb[i++] = (box_x2 - dxo) * src_scale_x;
       vb[i++] = (box_y2 - dyo) * src_scale_y;
-
-      vb[i++] = (float) box_x1;
+      vb[i++] = (float) box_x2;
       vb[i++] = (float) box_y2;
+
       vb[i++] = (box_x1 - dxo) * src_scale_x;
       vb[i++] = (box_y2 - dyo) * src_scale_y;
-
       vb[i++] = (float) box_x1;
-      vb[i++] = (float) box_y1;
+      vb[i++] = (float) box_y2;
+
       vb[i++] = (box_x1 - dxo) * src_scale_x;
       vb[i++] = (box_y1 - dyo) * src_scale_y;
+      vb[i++] = (float) box_x1;
+      vb[i++] = (float) box_y1;
 
       memset (vs_scratch, 1, VS_SCRATCH_SIZE);
       
diff-tree ddf3e5b2737399dca6d401f91db51a51f93b6373 (from 2e16c79dc2f24b0a04111aa6236a44870c6c64df)
Author: Keith his master's voice Packard <keithp at bw.jf.intel.com>
Date:   Sun May 28 21:03:39 2006 -0700

    Using tiny rectangle, still locks up in pixel shader program somehow

diff --git a/src/i830_video.c b/src/i830_video.c
index 956cbbe..ee4f2a2 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2732,7 +2732,6 @@ static const CARD32 sf_kernel_static[][4
 #define PS_MAX_THREADS	   1 /* MIN(12, PS_KERNEL_NUM_URB / 2) */
 
 static const CARD32 ps_kernel_static[][4] = {
-#if 1
 /*    mov (8) m2<1>F g2<16,16,1>UW { align1 +  } */
    { 0x00600001, 0x2040013e, 0x00b10040, 0x00000000 },
 /*    mov (8) m6<1>F g3<16,16,1>UW { align1 sechalf +  } */
@@ -2751,9 +2750,6 @@ static const CARD32 ps_kernel_static[][4
    { 0x00601001, 0x2120013e, 0x00b100c0, 0x00000000 },
 /*    mov (8) m1<1>F g1<8,8,1>F { align1 mask_disable +  } */
    { 0x00600201, 0x202003be, 0x008d0020, 0x00000000 },
-#endif
-/*    wait (1) a0<1>UW a145<0,1,0>UW { align1 +  } */
-    { 0x00000030, 0x20000108, 0x00001220, 0x00000000 },
 /*    send   0 (16) a0<1>UW g0<8,8,1>UW write mlen 10 rlen 0 EOT{ align1 +  } */
    { 0x00800031, 0x20001d28, 0x008d0000, 0x85a04800 },
 /*    nop (4) g0<1>UD { align1 +  } */
@@ -3169,7 +3165,7 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    wm_state->thread0.kernel_start_pointer = 
 	    (state_base_offset + ps_kernel_offset) >> 6;
    wm_state->thread0.grf_reg_count = ((PS_KERNEL_NUM_GRF & ~15) / 16);
-   wm_state->thread1.single_program_flow = 1; /* XXX */
+   wm_state->thread1.single_program_flow = 0; /* XXX */
    wm_state->thread1.binding_table_entry_count = 2;
    wm_state->thread2.scratch_space_base_pointer = 0; /* XXX */
    wm_state->thread2.per_thread_scratch_space = 0; /* XXX */
@@ -3351,6 +3347,10 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
 	 }
       }
 
+      /* just paint 4 pixels */
+      box_x2 = box_x1 + 2;
+      box_y2 = box_y1 + 2;
+
       pbox++;
 
       src_scale_x = (float)src_w / (float)drw_w;
@@ -3384,7 +3384,7 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
 	     BRW_VF_CTL_SNAPSHOT_ENABLE);
       OUTREG(BRW_VF_STRG_VAL, 0);
       
-#if 1
+#if 0
       OUTREG(BRW_VS_CTL,
 	     BRW_VS_CTL_SNAPSHOT_ALL_THREADS |
 	     BRW_VS_CTL_SNAPSHOT_MUX_VALID_COUNT |
@@ -3417,7 +3417,7 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
       BEGIN_LP_RING(6);
       OUT_RING(BRW_3DPRIMITIVE | 
 	       BRW_3DPRIMITIVE_VERTEX_SEQUENTIAL |
-	       (_3DPRIM_TRILIST << BRW_3DPRIMITIVE_TOPOLOGY_SHIFT) | 
+	       (_3DPRIM_RECTLIST << BRW_3DPRIMITIVE_TOPOLOGY_SHIFT) | 
 	       (0 << 9) |  /* CTG - indirect vertex count */
 	       4);
       OUT_RING(3); /* vertex count per instance */
@@ -3440,7 +3440,7 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
       OUTREG(BRW_VF_CTL, 0);
       ErrorF ("VF_CTL: 0x%08x VF_RDATA: 0x%08x\n", ctl, rdata);
 
-#if 1
+#if 0
       for (j = 0; j < 1000000; j++) {
 	ctl = INREG(BRW_VS_CTL);
 	 if (ctl & BRW_VS_CTL_SNAPSHOT_COMPLETE)
@@ -3457,6 +3457,13 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
       }
       
       OUTREG(BRW_VS_CTL, 0);
+      for (j = 0; j < 32; j += 8)
+	 ErrorF (" vs_scratch(%2d): %02x %02x %02x %02x  %02x %02x %02x %02x\n",
+		 j,
+		 vs_scratch[j+0], vs_scratch[j+1],
+		 vs_scratch[j+2], vs_scratch[j+3], 
+		 vs_scratch[j+4], vs_scratch[j+5],
+		 vs_scratch[j+6], vs_scratch[j+7]);
 #endif
 
       for (j = 0; j < 1000000; j++) {
@@ -3499,13 +3506,6 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
 	      INREG(BRW_EU_ATT_1), INREG(BRW_EU_ATT_0),
 	      INREG(BRW_EU_ATT_DATA_1), INREG(BRW_EU_ATT_DATA_0));
 
-      for (j = 0; j < 32; j += 8)
-	 ErrorF (" vs_scratch(%2d): %02x %02x %02x %02x  %02x %02x %02x %02x\n",
-		 j,
-		 vs_scratch[j+0], vs_scratch[j+1],
-		 vs_scratch[j+2], vs_scratch[j+3], 
-		 vs_scratch[j+4], vs_scratch[j+5],
-		 vs_scratch[j+6], vs_scratch[j+7]);
 #if 0
       for (j = 0; j < 256; j++) {
 	 OUTREG(BRW_TD_CTL, j << BRW_TD_CTL_MUX_SHIFT);
diff-tree 2e16c79dc2f24b0a04111aa6236a44870c6c64df (from 79a514412bda7e38e018c105a603970c4a9d758a)
Author: Keith his master's voice Packard <keithp at bw.jf.intel.com>
Date:   Sun May 28 20:31:23 2006 -0700

    Lots more debug code. Appears to execute pixel shader thread now though. hurray!

diff --git a/src/i830_video.c b/src/i830_video.c
index bbbcd41..956cbbe 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2632,27 +2632,35 @@ static const CARD32 sip_kernel_static[][
     { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
 /*    nop (4) g0<1>UD { align1 +  } */
     { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
 };
    
 static const CARD32 vs_kernel_static[][4] = {
-/*    wait (1) a0<1>UW a145<0,1,0>UW { align1 +  } */
-    { 0x00000030, 0x20000108, 0x00001220, 0x00000000 },
-/*    nop (4) g0<1>UD { align1 +  } */
-    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-/*    nop (4) g0<1>UD { align1 +  } */
-    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-/*    nop (4) g0<1>UD { align1 +  } */
-    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-/*    nop (4) g0<1>UD { align1 +  } */
-    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-/*    nop (4) g0<1>UD { align1 +  } */
-    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-/*    nop (4) g0<1>UD { align1 +  } */
-    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-/*    nop (4) g0<1>UD { align1 +  } */
-    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-/*    nop (4) g0<1>UD { align1 +  } */
-    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+   /*    mov (8) m1<1>F g1<8,8,1>F { align1 +  } */
+   { 0x00600001, 0x202003be, 0x008d0020, 0x00000000 },
+   /*    mov (1) g0.8<1>D 0 { align1 mask_disable +  } */
+   { 0x00000201, 0x200810e5, 0x00000000, 0x00000000 },
+   /*    send   0 (8) a0<1>UW g0<8,8,1>F write mlen 3 rlen 0 { align1 +  } */
+   { 0x00600031, 0x20001fa8, 0x008d0000, 0x053003ff },
+   /*    send   0 (8) a0<1>F g0<8,8,1>F urb mlen 2 rlen 0 write +0 noswizzle used complete EOT{ align1 +  } */
+   { 0x00600031, 0x20001fbc, 0x008d0000, 0x8620c000 },
+   /*    nop (4) g0<1>UD { align1 +  } */
+   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+   /*    nop (4) g0<1>UD { align1 +  } */
+   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+   /*    nop (4) g0<1>UD { align1 +  } */
+   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+   /*    nop (4) g0<1>UD { align1 +  } */
+   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+   /*    nop (4) g0<1>UD { align1 +  } */
+   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+   /*    nop (4) g0<1>UD { align1 +  } */
+   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+   /*    nop (4) g0<1>UD { align1 +  } */
+   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+   /*    nop (4) g0<1>UD { align1 +  } */
+   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
 };
    
 /*
@@ -2665,9 +2673,6 @@ static const CARD32 vs_kernel_static[][4
 #define SF_MAX_THREADS	   1
 
 static const CARD32 sf_kernel_static[][4] = {
-/*    wait (1) a0<1>UW a145<0,1,0>UW { align1 +  } */
-    { 0x00000030, 0x20000108, 0x00001220, 0x00000000 },
-#if 0
 /*    send   0 (1) g6<1>F g1.8<0,1,0>F math mlen 1 rlen 1 { align1 +  } */
     { 0x00000031, 0x20c01fbd, 0x00000028, 0x01110081 },
 /*    mov (2) g3.8<1>F g2<2,2,1>F { align1 +  } */
@@ -2702,7 +2707,6 @@ static const CARD32 sf_kernel_static[][4
     { 0x00600041, 0x204077be, 0x008d0120, 0x000000c0 },
 /*    mov (8) m3<1>F g3<8,8,1>F { align1 +  } */
     { 0x00600001, 0x206003be, 0x008d0060, 0x00000000 },
-#endif
 /*    send   0 (8) a0<1>F g0<8,8,1>F urb mlen 4 rlen 0 write +0 transpose used complete EOT{ align1 +  } */
     { 0x00600031, 0x20001fbc, 0x008d0000, 0x8640c800 },
 /*    nop (4) g0<1>UD { align1 +  } */
@@ -2728,7 +2732,7 @@ static const CARD32 sf_kernel_static[][4
 #define PS_MAX_THREADS	   1 /* MIN(12, PS_KERNEL_NUM_URB / 2) */
 
 static const CARD32 ps_kernel_static[][4] = {
-#if 0
+#if 1
 /*    mov (8) m2<1>F g2<16,16,1>UW { align1 +  } */
    { 0x00600001, 0x2040013e, 0x00b10040, 0x00000000 },
 /*    mov (8) m6<1>F g3<16,16,1>UW { align1 sechalf +  } */
@@ -2748,6 +2752,8 @@ static const CARD32 ps_kernel_static[][4
 /*    mov (8) m1<1>F g1<8,8,1>F { align1 mask_disable +  } */
    { 0x00600201, 0x202003be, 0x008d0020, 0x00000000 },
 #endif
+/*    wait (1) a0<1>UW a145<0,1,0>UW { align1 +  } */
+    { 0x00000030, 0x20000108, 0x00001220, 0x00000000 },
 /*    send   0 (16) a0<1>UW g0<8,8,1>UW write mlen 10 rlen 0 EOT{ align1 +  } */
    { 0x00800031, 0x20001d28, 0x008d0000, 0x85a04800 },
 /*    nop (4) g0<1>UD { align1 +  } */
@@ -2839,7 +2845,8 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    struct brw_instruction *sf_kernel;
    struct brw_instruction *ps_kernel;
    struct brw_instruction *sip_kernel;
-   CARD32 *vb, *binding_table;
+   float *vb;
+    CARD32 *binding_table;
    Bool first_output = TRUE;
    int dest_surf_offset, src_surf_offset, src_sampler_offset, vs_offset;
    int sf_offset, wm_offset, cc_offset, vb_offset, cc_viewport_offset;
@@ -2853,6 +2860,15 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    char *state_base;
    int state_base_offset;
 
+    int vs_scratch_offset;
+#define VS_SCRATCH_SIZE	1024
+#define VS_SCRATCH_NUM (VS_SCRATCH_SIZE / sizeof (float))
+    char *vs_scratch;
+    int vs_scratch_surface_state_offset;
+    struct brw_surface_state *vs_scratch_surface_state;
+    int vs_binding_table_offset;
+    CARD32 *vs_binding_table;
+
 #if 0
    ErrorF("BroadwaterDisplayVideoTextured: %dx%d (pitch %d)\n", width, height,
 	  video_pitch);
@@ -2894,6 +2910,12 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    next_offset = sip_kernel_offset + sizeof (sip_kernel_static);
    vs_kernel_offset = ALIGN(next_offset, 64);
    next_offset = vs_kernel_offset + sizeof (vs_kernel_static);
+   vs_scratch_offset = ALIGN(next_offset, 1024);
+   next_offset = vs_scratch_offset + VS_SCRATCH_SIZE;
+   vs_scratch_surface_state_offset = ALIGN(next_offset, 32);
+   next_offset = vs_scratch_surface_state_offset + sizeof (struct brw_surface_state);
+   vs_binding_table_offset = ALIGN(next_offset, 32);
+   next_offset = vs_binding_table_offset + 1 * 4;
    
    cc_viewport_offset = ALIGN(next_offset, 32);
    next_offset = cc_viewport_offset + sizeof(*cc_viewport);
@@ -2936,7 +2958,12 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    sf_kernel = (void *)(state_base + sf_kernel_offset);
    ps_kernel = (void *)(state_base + ps_kernel_offset);
    sip_kernel = (void *)(state_base + sip_kernel_offset);
-cc_viewport = (void *)(state_base + cc_viewport_offset);
+   vs_kernel = (void *)(state_base + vs_kernel_offset);
+   vs_scratch = (void *)(state_base + vs_scratch_offset);
+   vs_scratch_surface_state = (void *)(state_base + vs_scratch_surface_state_offset);
+   vs_binding_table = (void *)(state_base + vs_binding_table_offset);
+   
+   cc_viewport = (void *)(state_base + cc_viewport_offset);
    dest_surf_state = (void *)(state_base + dest_surf_offset);
    src_surf_state = (void *)(state_base + src_surf_offset);
    src_sampler_state = (void *)(state_base + src_sampler_offset);
@@ -3066,9 +3093,19 @@ cc_viewport = (void *)(state_base + cc_v
    src_sampler_state->ss1.t_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
 
    /* Set up the vertex shader to be disabled (passthrough) */
+   vs_binding_table[0] = state_base_offset + vs_scratch_surface_state_offset;
+   memset (vs_scratch_surface_state, 0, sizeof (*vs_scratch_surface_state));
+   vs_scratch_surface_state->ss0.surface_type = BRW_SURFACE_BUFFER;
+   vs_scratch_surface_state->ss0.surface_format = BRW_SURFACEFORMAT_R32_FLOAT;
+   vs_scratch_surface_state->ss1.base_addr = state_base_offset + vs_scratch_offset;
+   vs_scratch_surface_state->ss2.height = (VS_SCRATCH_NUM - 1) >> 7;
+   vs_scratch_surface_state->ss2.width = (VS_SCRATCH_NUM - 1) & 0x7f;
+   vs_scratch_surface_state->ss3.pitch = 3;
+   
    memcpy(vs_kernel, vs_kernel_static, sizeof (vs_kernel_static));
    
    memset(vs_state, 0, sizeof(*vs_state));
+   ErrorF ("vs kernel: 0x%08x\n", state_base_offset + vs_kernel_offset);
    vs_state->thread0.kernel_start_pointer =
 	    (state_base_offset + vs_kernel_offset) >> 6;
    vs_state->thread0.grf_reg_count = 1;
@@ -3076,7 +3113,7 @@ cc_viewport = (void *)(state_base + cc_v
    vs_state->thread4.nr_urb_entries = URB_VS_ENTRIES;
    vs_state->thread4.urb_entry_allocation_size = URB_VS_ENTRY_SIZE - 1;
    vs_state->thread4.stats_enable = 1;
-   vs_state->vs6.vs_enable = 1;
+   vs_state->vs6.vs_enable = 0;
    vs_state->vs6.vert_cache_disable = 1;
 
    /* Set up the SF kernel to do coord interp: for each attribute,
@@ -3174,7 +3211,7 @@ cc_viewport = (void *)(state_base + cc_v
    OUT_RING(0 | BASE_ADDRESS_MODIFY);  /* Surface state base address */
    OUT_RING(0 | BASE_ADDRESS_MODIFY);  /* media base addr, don't care */
    OUT_RING(0x10000000 | BASE_ADDRESS_MODIFY);  /* general state max addr, disabled */
-   OUT_RING(1); /* media object state max addr, disabled */
+   OUT_RING(0x10000000 | BASE_ADDRESS_MODIFY);  /* media object state max addr, disabled */
 
    /* Set system instruction pointer */
    OUT_RING(BRW_STATE_SIP | 0);
@@ -3200,7 +3237,7 @@ cc_viewport = (void *)(state_base + cc_v
 
    /* Binding table pointers */
    OUT_RING(BRW_3DSTATE_BINDING_TABLE_POINTERS | 4);
-   OUT_RING(0); /* vs */
+   OUT_RING(state_base_offset + vs_binding_table_offset); /* vs */
    OUT_RING(0); /* gs */
    OUT_RING(0); /* clip */
    OUT_RING(0); /* sf */
@@ -3271,8 +3308,8 @@ cc_viewport = (void *)(state_base + cc_v
 	    VE0_VALID |
 	    (BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) |
 	    (0 << VE0_OFFSET_SHIFT));
-   OUT_RING((BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_0_SHIFT) |
-	    (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_1_SHIFT) |
+   OUT_RING((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) |
+	    (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) |
 	    (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT) |
 	    (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT) |
 	    (0 << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT));
@@ -3320,21 +3357,23 @@ cc_viewport = (void *)(state_base + cc_v
       src_scale_y  = (float)src_h / (float)drw_h;
 
       i = 0;
-      vb[i++] = box_x2;
-      vb[i++] = box_y2;
+      vb[i++] = (float) box_x2;
+      vb[i++] = (float) box_y2;
       vb[i++] = (box_x2 - dxo) * src_scale_x;
       vb[i++] = (box_y2 - dyo) * src_scale_y;
 
-      vb[i++] = box_x1;
-      vb[i++] = box_y2;
+      vb[i++] = (float) box_x1;
+      vb[i++] = (float) box_y2;
       vb[i++] = (box_x1 - dxo) * src_scale_x;
       vb[i++] = (box_y2 - dyo) * src_scale_y;
 
-      vb[i++] = box_x1;
-      vb[i++] = box_y1;
+      vb[i++] = (float) box_x1;
+      vb[i++] = (float) box_y1;
       vb[i++] = (box_x1 - dxo) * src_scale_x;
       vb[i++] = (box_y1 - dyo) * src_scale_y;
 
+      memset (vs_scratch, 1, VS_SCRATCH_SIZE);
+      
       ErrorF ("before EU_ATT 0x%08x%08x EU_ATT_DATA 0x%08x%08x\n",
 	      INREG(BRW_EU_ATT_1), INREG(BRW_EU_ATT_0),
 	      INREG(BRW_EU_ATT_DATA_1), INREG(BRW_EU_ATT_DATA_0));
@@ -3345,7 +3384,7 @@ cc_viewport = (void *)(state_base + cc_v
 	     BRW_VF_CTL_SNAPSHOT_ENABLE);
       OUTREG(BRW_VF_STRG_VAL, 0);
       
-#if 0
+#if 1
       OUTREG(BRW_VS_CTL,
 	     BRW_VS_CTL_SNAPSHOT_ALL_THREADS |
 	     BRW_VS_CTL_SNAPSHOT_MUX_VALID_COUNT |
@@ -3367,19 +3406,13 @@ cc_viewport = (void *)(state_base + cc_v
       OUTREG(BRW_WIZ_STRG_VAL,
 	     (box_x1) | (box_y1 << 16));
       
+#if 0
       OUTREG(BRW_TS_CTL,
 	     BRW_TS_CTL_SNAPSHOT_MESSAGE_ERROR |
 	     BRW_TS_CTL_SNAPSHOT_ALL_CHILD_THREADS |
 	     BRW_TS_CTL_SNAPSHOT_ALL_ROOT_THREADS |
 	     BRW_TS_CTL_SNAPSHOT_ENABLE);
-
-      { static int first = 1;
-	 if (first)
-	    first = 0;
-	 else
-	    OUTREG(BRW_TD_CTL,
-		   BRW_TD_CTL_FORCE_EXTERNAL_HALT);
-      }
+#endif
 
       BEGIN_LP_RING(6);
       OUT_RING(BRW_3DPRIMITIVE | 
@@ -3394,7 +3427,7 @@ cc_viewport = (void *)(state_base + cc_v
       OUT_RING(0); /* index buffer offset, ignored */
       ADVANCE_LP_RING();
 
-      int   j;
+      int   j, k;
       CARD32	  ctl = 0, rdata;
       
       for (j = 0; j < 100000; j++) {
@@ -3407,7 +3440,7 @@ cc_viewport = (void *)(state_base + cc_v
       OUTREG(BRW_VF_CTL, 0);
       ErrorF ("VF_CTL: 0x%08x VF_RDATA: 0x%08x\n", ctl, rdata);
 
-#if 0
+#if 1
       for (j = 0; j < 1000000; j++) {
 	ctl = INREG(BRW_VS_CTL);
 	 if (ctl & BRW_VS_CTL_SNAPSHOT_COMPLETE)
@@ -3415,8 +3448,15 @@ cc_viewport = (void *)(state_base + cc_v
       }
 
       rdata = INREG(BRW_VS_RDATA);
+      for (k = 0; k <= 3; k++) {
+	 OUTREG(BRW_VS_CTL,
+		BRW_VS_CTL_SNAPSHOT_COMPLETE |
+		(k << 8));
+	 rdata = INREG(BRW_VS_RDATA);
+	 ErrorF ("VS_CTL: 0x%08x VS_RDATA(%d): 0x%08x\n", ctl, k, rdata);
+      }
+      
       OUTREG(BRW_VS_CTL, 0);
-      ErrorF ("VS_CTL: 0x%08x VS_RDATA: 0x%08x\n", ctl, rdata);
 #endif
 
       for (j = 0; j < 1000000; j++) {
@@ -3425,8 +3465,6 @@ cc_viewport = (void *)(state_base + cc_v
 	    break;
       }
 
-      int   k;
-
       for (k = 0; k <= 7; k++) {
 	 OUTREG(BRW_SF_CTL,
 		BRW_SF_CTL_SNAPSHOT_COMPLETE |
@@ -3461,11 +3499,20 @@ cc_viewport = (void *)(state_base + cc_v
 	      INREG(BRW_EU_ATT_1), INREG(BRW_EU_ATT_0),
 	      INREG(BRW_EU_ATT_DATA_1), INREG(BRW_EU_ATT_DATA_0));
 
+      for (j = 0; j < 32; j += 8)
+	 ErrorF (" vs_scratch(%2d): %02x %02x %02x %02x  %02x %02x %02x %02x\n",
+		 j,
+		 vs_scratch[j+0], vs_scratch[j+1],
+		 vs_scratch[j+2], vs_scratch[j+3], 
+		 vs_scratch[j+4], vs_scratch[j+5],
+		 vs_scratch[j+6], vs_scratch[j+7]);
+#if 0
       for (j = 0; j < 256; j++) {
 	 OUTREG(BRW_TD_CTL, j << BRW_TD_CTL_MUX_SHIFT);
 	 rdata = INREG(BRW_TD_RDATA);
 	 ErrorF ("TD_RDATA(%d): 0x%08x\n", j, rdata);
       }
+#endif
       first_output = FALSE;
       if (pI830->AccelInfoRec)
 	 pI830->AccelInfoRec->NeedToSync = TRUE;
diff-tree 79a514412bda7e38e018c105a603970c4a9d758a (from 9c111d89fe19f1773af2eefb000e1c2389b4b6e1)
Author: Keith his master's voice Packard <keithp at bw.jf.intel.com>
Date:   Sun May 28 16:09:59 2006 -0700

    dump out piles of debug. Create VS thread just to see how it works

diff --git a/src/brw_structs.h b/src/brw_structs.h
index 49383c1..c9c0751 100644
--- a/src/brw_structs.h
+++ b/src/brw_structs.h
@@ -658,7 +658,21 @@ struct brw_cc_unit_state
 struct brw_sf_unit_state
 {
    struct thread0 thread0;
-   struct thread1 thread1;
+   struct {
+      GLuint pad0:7;
+      GLuint sw_exception_enable:1; 
+      GLuint pad1:3;
+      GLuint mask_stack_exception_enable:1; 
+      GLuint pad2:1;
+      GLuint illegal_op_exception_enable:1; 
+      GLuint pad3:2;
+      GLuint floating_point_mode:1; 
+      GLuint thread_priority:1; 
+      GLuint binding_table_entry_count:8; 
+      GLuint pad4:5;
+      GLuint single_program_flow:1; 
+   } sf1;
+   
    struct thread2 thread2;
    struct thread3 thread3;
 
diff --git a/src/i810_reg.h b/src/i810_reg.h
index c096089..716275e 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -1746,8 +1746,109 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define BRW_VF_MAX_PRIM		       0x7514
 #define BRW_VF_RDATA		       0x7518
 
-/* End regs for broadwater */
+#define BRW_VS_CTL		       0x7600
+#define BRW_VS_CTL_SNAPSHOT_COMPLETE		   (1 << 31)
+#define BRW_VS_CTL_SNAPSHOT_MUX_VERTEX_0	   (0 << 8)
+#define BRW_VS_CTL_SNAPSHOT_MUX_VERTEX_1	   (1 << 8)
+#define BRW_VS_CTL_SNAPSHOT_MUX_VALID_COUNT	   (2 << 8)
+#define BRW_VS_CTL_SNAPSHOT_MUX_VS_KERNEL_POINTER  (3 << 8)
+#define BRW_VS_CTL_SNAPSHOT_ALL_THREADS		   (1 << 2)
+#define BRW_VS_CTL_THREAD_SNAPSHOT_ENABLE	   (1 << 1)
+#define BRW_VS_CTL_SNAPSHOT_ENABLE		   (1 << 0)
+
+#define BRW_VS_STRG_VAL		       0x7604
+#define BRW_VS_RDATA		       0x7608
+
+#define BRW_SF_CTL		       0x7b00
+#define BRW_SF_CTL_SNAPSHOT_COMPLETE		   (1 << 31)
+#define BRW_SF_CTL_SNAPSHOT_MUX_VERTEX_0_FF_ID	   (0 << 8)
+#define BRW_SF_CTL_SNAPSHOT_MUX_VERTEX_0_REL_COUNT (1 << 8)
+#define BRW_SF_CTL_SNAPSHOT_MUX_VERTEX_1_FF_ID	   (2 << 8)
+#define BRW_SF_CTL_SNAPSHOT_MUX_VERTEX_1_REL_COUNT (3 << 8)
+#define BRW_SF_CTL_SNAPSHOT_MUX_VERTEX_2_FF_ID	   (4 << 8)
+#define BRW_SF_CTL_SNAPSHOT_MUX_VERTEX_2_REL_COUNT (5 << 8)
+#define BRW_SF_CTL_SNAPSHOT_MUX_VERTEX_COUNT	   (6 << 8)
+#define BRW_SF_CTL_SNAPSHOT_MUX_SF_KERNEL_POINTER  (7 << 8)
+#define BRW_SF_CTL_MIN_MAX_PRIMITIVE_RANGE_ENABLE  (1 << 4)
+#define BRW_SF_CTL_DEBUG_CLIP_RECTANGLE_ENABLE	   (1 << 3)
+#define BRW_SF_CTL_SNAPSHOT_ALL_THREADS		   (1 << 2)
+#define BRW_SF_CTL_THREAD_SNAPSHOT_ENABLE	   (1 << 1)
+#define BRW_SF_CTL_SNAPSHOT_ENABLE		   (1 << 0)
+
+#define BRW_SF_STRG_VAL		       0x7b04
+#define BRW_SF_RDATA		       0x7b18
+
+#define BRW_WIZ_CTL		       0x7c00
+#define BRW_WIZ_CTL_SNAPSHOT_COMPLETE		   (1 << 31)
+#define BRW_WIZ_CTL_SUBSPAN_INSTANCE_SHIFT	   16
+#define BRW_WIZ_CTL_SNAPSHOT_MUX_WIZ_KERNEL_POINTER   (0 << 8)
+#define BRW_WIZ_CTL_SNAPSHOT_MUX_SUBSPAN_INSTANCE     (1 << 8)
+#define BRW_WIZ_CTL_SNAPSHOT_MUX_PRIMITIVE_SEQUENCE   (2 << 8)
+#define BRW_WIZ_CTL_SINGLE_SUBSPAN_DISPATCH	      (1 << 6)
+#define BRW_WIZ_CTL_IGNORE_COLOR_SCOREBOARD_STALLS    (1 << 5)
+#define BRW_WIZ_CTL_ENABLE_SUBSPAN_INSTANCE_COMPARE   (1 << 4)
+#define BRW_WIZ_CTL_USE_UPSTREAM_SNAPSHOT_FLAG	      (1 << 3)
+#define BRW_WIZ_CTL_SNAPSHOT_ALL_THREADS	      (1 << 2)
+#define BRW_WIZ_CTL_THREAD_SNAPSHOT_ENABLE	      (1 << 1)
+#define BRW_WIZ_CTL_SNAPSHOT_ENABLE		      (1 << 0)
+
+#define BRW_WIZ_STRG_VAL			      0x7c04
+#define BRW_WIZ_RDATA				      0x7c18
+
+#define BRW_TS_CTL		       0x7e00
+#define BRW_TS_CTL_SNAPSHOT_COMPLETE		   (1 << 31)
+#define BRW_TS_CTL_SNAPSHOT_MESSAGE_ERROR	   (0 << 8)
+#define BRW_TS_CTL_SNAPSHOT_INTERFACE_DESCRIPTOR   (3 << 8)
+#define BRW_TS_CTL_SNAPSHOT_ALL_CHILD_THREADS	   (1 << 2)
+#define BRW_TS_CTL_SNAPSHOT_ALL_ROOT_THREADS  	   (1 << 1)
+#define BRW_TS_CTL_SNAPSHOT_ENABLE		   (1 << 0)
+
+#define BRW_TS_STRG_VAL		       0x7e04
+#define BRW_TS_RDATA		       0x7e08
+
+#define BRW_TD_CTL		       0x8000
+#define BRW_TD_CTL_MUX_SHIFT	       8
+#define BRW_TD_CTL_EXTERNAL_HALT_R0_DEBUG_MATCH	   (1 << 7)
+#define BRW_TD_CTL_FORCE_EXTERNAL_HALT		   (1 << 6)
+#define BRW_TD_CTL_EXCEPTION_MASK_OVERRIDE	   (1 << 5)
+#define BRW_TD_CTL_FORCE_THREAD_BREAKPOINT_ENABLE  (1 << 4)
+#define BRW_TD_CTL_BREAKPOINT_ENABLE		   (1 << 2)
+#define BRW_TD_CTL2		       0x8004
+#define BRW_TD_CTL2_ILLEGAL_OPCODE_EXCEPTION_OVERRIDE (1 << 28)
+#define BRW_TD_CTL2_MASKSTACK_EXCEPTION_OVERRIDE      (1 << 26)
+#define BRW_TD_CTL2_SOFTWARE_EXCEPTION_OVERRIDE	      (1 << 25)
+#define BRW_TD_CTL2_ACTIVE_THREAD_LIMIT_SHIFT	      16
+#define BRW_TD_CTL2_ACTIVE_THREAD_LIMIT_ENABLE	      (1 << 8)
+#define BRW_TD_CTL2_THREAD_SPAWNER_EXECUTION_MASK_ENABLE (1 << 7)
+#define BRW_TD_CTL2_WIZ_EXECUTION_MASK_ENABLE	      (1 << 6)
+#define BRW_TD_CTL2_SF_EXECUTION_MASK_ENABLE	      (1 << 5)
+#define BRW_TD_CTL2_CLIPPER_EXECUTION_MASK_ENABLE     (1 << 4)
+#define BRW_TD_CTL2_GS_EXECUTION_MASK_ENABLE	      (1 << 3)
+#define BRW_TD_CTL2_VS_EXECUTION_MASK_ENABLE	      (1 << 0)
+#define BRW_TD_VF_VS_EMSK	       0x8008
+#define BRW_TD_GS_EMSK		       0x800c
+#define BRW_TD_CLIP_EMSK	       0x8010
+#define BRW_TD_SF_EMSK		       0x8014
+#define BRW_TD_WIZ_EMSK		       0x8018
+#define BRW_TD_0_6_EHTRG_VAL	       0x801c
+#define BRW_TD_0_7_EHTRG_VAL	       0x8020
+#define BRW_TD_0_6_EHTRG_MSK           0x8024
+#define BRW_TD_0_7_EHTRG_MSK	       0x8028
+#define BRW_TD_RDATA		       0x802c
+#define BRW_TD_TS_EMSK		       0x8030
+
+#define BRW_EU_CTL		       0x8800
+#define BRW_EU_CTL_SELECT_SHIFT	       16
+#define BRW_EU_CTL_DATA_MUX_SHIFT      8
+#define BRW_EU_ATT_0		       0x8810
+#define BRW_EU_ATT_1		       0x8814
+#define BRW_EU_ATT_DATA_0	       0x8820
+#define BRW_EU_ATT_DATA_1	       0x8824
+#define BRW_EU_ATT_CLR_0	       0x8830
+#define BRW_EU_ATT_CLR_1	       0x8834
+#define BRW_EU_RDATA		       0x8840
 
+/* End regs for broadwater */
 
 #define MAX_DISPLAY_PIPES	2
 
diff --git a/src/i830_video.c b/src/i830_video.c
index 5174338..bbbcd41 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2613,6 +2613,48 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
       pI830->AccelInfoRec->NeedToSync = TRUE;
 }
 
+static const CARD32 sip_kernel_static[][4] = {
+/*    wait (1) a0<1>UW a145<0,1,0>UW { align1 +  } */
+    { 0x00000030, 0x20000108, 0x00001220, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+};
+   
+static const CARD32 vs_kernel_static[][4] = {
+/*    wait (1) a0<1>UW a145<0,1,0>UW { align1 +  } */
+    { 0x00000030, 0x20000108, 0x00001220, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+};
+   
 /*
  * this program computes dA/dx and dA/dy for the texture coordinates along
  * with the base texture coordinate. It was extracted from the Mesa driver
@@ -2623,6 +2665,9 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
 #define SF_MAX_THREADS	   1
 
 static const CARD32 sf_kernel_static[][4] = {
+/*    wait (1) a0<1>UW a145<0,1,0>UW { align1 +  } */
+    { 0x00000030, 0x20000108, 0x00001220, 0x00000000 },
+#if 0
 /*    send   0 (1) g6<1>F g1.8<0,1,0>F math mlen 1 rlen 1 { align1 +  } */
     { 0x00000031, 0x20c01fbd, 0x00000028, 0x01110081 },
 /*    mov (2) g3.8<1>F g2<2,2,1>F { align1 +  } */
@@ -2657,6 +2702,7 @@ static const CARD32 sf_kernel_static[][4
     { 0x00600041, 0x204077be, 0x008d0120, 0x000000c0 },
 /*    mov (8) m3<1>F g3<8,8,1>F { align1 +  } */
     { 0x00600001, 0x206003be, 0x008d0060, 0x00000000 },
+#endif
 /*    send   0 (8) a0<1>F g0<8,8,1>F urb mlen 4 rlen 0 write +0 transpose used complete EOT{ align1 +  } */
     { 0x00600031, 0x20001fbc, 0x008d0000, 0x8640c800 },
 /*    nop (4) g0<1>UD { align1 +  } */
@@ -2682,6 +2728,7 @@ static const CARD32 sf_kernel_static[][4
 #define PS_MAX_THREADS	   1 /* MIN(12, PS_KERNEL_NUM_URB / 2) */
 
 static const CARD32 ps_kernel_static[][4] = {
+#if 0
 /*    mov (8) m2<1>F g2<16,16,1>UW { align1 +  } */
    { 0x00600001, 0x2040013e, 0x00b10040, 0x00000000 },
 /*    mov (8) m6<1>F g3<16,16,1>UW { align1 sechalf +  } */
@@ -2700,6 +2747,7 @@ static const CARD32 ps_kernel_static[][4
    { 0x00601001, 0x2120013e, 0x00b100c0, 0x00000000 },
 /*    mov (8) m1<1>F g1<8,8,1>F { align1 mask_disable +  } */
    { 0x00600201, 0x202003be, 0x008d0020, 0x00000000 },
+#endif
 /*    send   0 (16) a0<1>UW g0<8,8,1>UW write mlen 10 rlen 0 EOT{ align1 +  } */
    { 0x00800031, 0x20001d28, 0x008d0000, 0x85a04800 },
 /*    nop (4) g0<1>UD { align1 +  } */
@@ -2787,14 +2835,17 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    struct brw_wm_unit_state *wm_state;
    struct brw_cc_unit_state *cc_state;
    struct brw_cc_viewport *cc_viewport;
+   struct brw_instruction *vs_kernel;
    struct brw_instruction *sf_kernel;
    struct brw_instruction *ps_kernel;
+   struct brw_instruction *sip_kernel;
    CARD32 *vb, *binding_table;
    Bool first_output = TRUE;
    int dest_surf_offset, src_surf_offset, src_sampler_offset, vs_offset;
    int sf_offset, wm_offset, cc_offset, vb_offset, cc_viewport_offset;
    int wm_scratch_offset;
-   int sf_kernel_offset, ps_kernel_offset;
+   int vs_kernel_offset;
+   int sf_kernel_offset, ps_kernel_offset, sip_kernel_offset;
    int binding_table_offset;
    int next_offset, total_state_size;
    int vb_size = (4 * 4) * 4; /* 4 DWORDS per vertex */
@@ -2811,6 +2862,8 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    OUTREG (INST_PM,
 	   (1 << (16 + 4)) |
 	   (1 << 4));
+   ErrorF ("INST_PM 0x%08x\n", INREG(INST_PM));
+   
    assert((id == FOURCC_UYVY) || (id == FOURCC_YUY2));
 
    /* Tell the rotation code that we have stomped its invariant state by
@@ -2837,6 +2890,10 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    next_offset = sf_kernel_offset + sizeof (sf_kernel_static);
    ps_kernel_offset = ALIGN(next_offset, 64);
    next_offset = ps_kernel_offset + sizeof (ps_kernel_static);
+   sip_kernel_offset = ALIGN(next_offset, 64);
+   next_offset = sip_kernel_offset + sizeof (sip_kernel_static);
+   vs_kernel_offset = ALIGN(next_offset, 64);
+   next_offset = vs_kernel_offset + sizeof (vs_kernel_static);
    
    cc_viewport_offset = ALIGN(next_offset, 32);
    next_offset = cc_viewport_offset + sizeof(*cc_viewport);
@@ -2878,7 +2935,8 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    cc_state = (void *)(state_base + cc_offset);
    sf_kernel = (void *)(state_base + sf_kernel_offset);
    ps_kernel = (void *)(state_base + ps_kernel_offset);
-   cc_viewport = (void *)(state_base + cc_viewport_offset);
+   sip_kernel = (void *)(state_base + sip_kernel_offset);
+cc_viewport = (void *)(state_base + cc_viewport_offset);
    dest_surf_state = (void *)(state_base + dest_surf_offset);
    src_surf_state = (void *)(state_base + src_surf_offset);
    src_sampler_state = (void *)(state_base + src_sampler_offset);
@@ -2935,6 +2993,9 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    cc_state->cc5.logicop_func = 0xc;   /* COPYPEN */
    cc_state->cc5.statistics_enable = 1;
 
+   /* Upload system kernel */
+   memcpy (sip_kernel, sip_kernel_static, sizeof (sip_kernel_static));
+   
    /* Set up the state buffer for the destination surface */
    memset(dest_surf_state, 0, sizeof(*dest_surf_state));
    dest_surf_state->ss0.surface_type = BRW_SURFACE_2D;
@@ -3005,11 +3066,17 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    src_sampler_state->ss1.t_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
 
    /* Set up the vertex shader to be disabled (passthrough) */
+   memcpy(vs_kernel, vs_kernel_static, sizeof (vs_kernel_static));
+   
    memset(vs_state, 0, sizeof(*vs_state));
+   vs_state->thread0.kernel_start_pointer =
+	    (state_base_offset + vs_kernel_offset) >> 6;
+   vs_state->thread0.grf_reg_count = 1;
+   vs_state->thread1.single_program_flow = 1;
    vs_state->thread4.nr_urb_entries = URB_VS_ENTRIES;
    vs_state->thread4.urb_entry_allocation_size = URB_VS_ENTRY_SIZE - 1;
    vs_state->thread4.stats_enable = 1;
-   vs_state->vs6.vs_enable = 0;
+   vs_state->vs6.vs_enable = 1;
    vs_state->vs6.vert_cache_disable = 1;
 
    /* Set up the SF kernel to do coord interp: for each attribute,
@@ -3019,14 +3086,22 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
 
    memcpy (sf_kernel, sf_kernel_static, sizeof (sf_kernel_static));
    memset(sf_state, 0, sizeof(*sf_state));
-   sf_state->thread0.kernel_start_pointer = state_base_offset + sf_kernel_offset;
+   ErrorF ("sf kernel: 0x%08x\n", state_base_offset + sf_kernel_offset);
+   sf_state->thread0.kernel_start_pointer = 
+	       (state_base_offset + sf_kernel_offset) >> 6;
    sf_state->thread0.grf_reg_count = ((SF_KERNEL_NUM_GRF & ~15) / 16);
-   sf_state->thread1.single_program_flow = 1; /* XXX */
+   sf_state->sf1.single_program_flow = 1; /* XXX */
+   sf_state->sf1.binding_table_entry_count = 0;
+   sf_state->sf1.thread_priority = 0;
+   sf_state->sf1.floating_point_mode = 1; /* Mesa does this */
+   sf_state->sf1.illegal_op_exception_enable = 1;
+   sf_state->sf1.mask_stack_exception_enable = 1;
+   sf_state->sf1.sw_exception_enable = 1;
    sf_state->thread2.per_thread_scratch_space = 0;
    sf_state->thread2.scratch_space_base_pointer = 0; /* not used in our kernel */
-   sf_state->thread3.urb_entry_read_length = 4; /* XXX */
-   sf_state->thread3.dispatch_grf_start_reg = 3; /* XXX */
+   sf_state->thread3.urb_entry_read_length = 1; /* XXX */
    sf_state->thread3.urb_entry_read_offset = 1; /* XXX */
+   sf_state->thread3.dispatch_grf_start_reg = 3; /* XXX */
    sf_state->thread4.nr_urb_entries = URB_SF_ENTRIES;
    sf_state->thread4.urb_entry_allocation_size = URB_SF_ENTRY_SIZE - 1;
    sf_state->thread4.max_threads = MIN(12, URB_SF_ENTRIES / 2) - 1;
@@ -3052,8 +3127,10 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
     */
 
    memcpy (ps_kernel, ps_kernel_static, sizeof (ps_kernel_static));
+   ErrorF ("ps kernel: 0x%08x\n", state_base_offset + ps_kernel_offset);
    memset (wm_state, 0, sizeof (*wm_state));
-   wm_state->thread0.kernel_start_pointer = state_base_offset + ps_kernel_offset;
+   wm_state->thread0.kernel_start_pointer = 
+	    (state_base_offset + ps_kernel_offset) >> 6;
    wm_state->thread0.grf_reg_count = ((PS_KERNEL_NUM_GRF & ~15) / 16);
    wm_state->thread1.single_program_flow = 1; /* XXX */
    wm_state->thread1.binding_table_entry_count = 2;
@@ -3076,7 +3153,7 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
       BEGIN_LP_RING(2);
       OUT_RING(MI_FLUSH | 
 	       MI_STATE_INSTRUCTION_CACHE_FLUSH |
-	       /* BRW_MI_GLOBAL_SNAPSHOT_RESET */ 0);
+	       BRW_MI_GLOBAL_SNAPSHOT_RESET);
       OUT_RING(MI_NOOP);
       ADVANCE_LP_RING();
    }
@@ -3099,9 +3176,9 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    OUT_RING(0x10000000 | BASE_ADDRESS_MODIFY);  /* general state max addr, disabled */
    OUT_RING(1); /* media object state max addr, disabled */
 
-   /* Set system instruction pointer to zero */
+   /* Set system instruction pointer */
    OUT_RING(BRW_STATE_SIP | 0);
-   OUT_RING(0);			       /* system instruction pointer */
+   OUT_RING(state_base_offset + sip_kernel_offset); /* system instruction pointer */
       
    OUT_RING(MI_NOOP);
    ADVANCE_LP_RING(); }
@@ -3194,8 +3271,8 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
 	    VE0_VALID |
 	    (BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) |
 	    (0 << VE0_OFFSET_SHIFT));
-   OUT_RING((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) |
-	    (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) |
+   OUT_RING((BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_0_SHIFT) |
+	    (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_1_SHIFT) |
 	    (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT) |
 	    (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT) |
 	    (0 << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT));
@@ -3258,12 +3335,52 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
       vb[i++] = (box_x1 - dxo) * src_scale_x;
       vb[i++] = (box_y1 - dyo) * src_scale_y;
 
+      ErrorF ("before EU_ATT 0x%08x%08x EU_ATT_DATA 0x%08x%08x\n",
+	      INREG(BRW_EU_ATT_1), INREG(BRW_EU_ATT_0),
+	      INREG(BRW_EU_ATT_DATA_1), INREG(BRW_EU_ATT_DATA_0));
+
       OUTREG(BRW_VF_CTL,
 	     BRW_VF_CTL_SNAPSHOT_MUX_SELECT_THREADID |
 	     BRW_VF_CTL_SNAPSHOT_TYPE_VERTEX_INDEX |
 	     BRW_VF_CTL_SNAPSHOT_ENABLE);
       OUTREG(BRW_VF_STRG_VAL, 0);
       
+#if 0
+      OUTREG(BRW_VS_CTL,
+	     BRW_VS_CTL_SNAPSHOT_ALL_THREADS |
+	     BRW_VS_CTL_SNAPSHOT_MUX_VALID_COUNT |
+	     BRW_VS_CTL_THREAD_SNAPSHOT_ENABLE);
+      
+      OUTREG(BRW_VS_STRG_VAL, 0);
+#endif
+      
+      OUTREG(BRW_SF_CTL,
+	     BRW_SF_CTL_SNAPSHOT_MUX_VERTEX_COUNT |
+	     BRW_SF_CTL_SNAPSHOT_ALL_THREADS |
+	     BRW_SF_CTL_THREAD_SNAPSHOT_ENABLE);
+      OUTREG(BRW_SF_STRG_VAL, 0);
+      
+      OUTREG(BRW_WIZ_CTL,
+	     BRW_WIZ_CTL_SNAPSHOT_MUX_SUBSPAN_INSTANCE |
+	     BRW_WIZ_CTL_SNAPSHOT_ALL_THREADS |
+	     BRW_WIZ_CTL_SNAPSHOT_ENABLE);
+      OUTREG(BRW_WIZ_STRG_VAL,
+	     (box_x1) | (box_y1 << 16));
+      
+      OUTREG(BRW_TS_CTL,
+	     BRW_TS_CTL_SNAPSHOT_MESSAGE_ERROR |
+	     BRW_TS_CTL_SNAPSHOT_ALL_CHILD_THREADS |
+	     BRW_TS_CTL_SNAPSHOT_ALL_ROOT_THREADS |
+	     BRW_TS_CTL_SNAPSHOT_ENABLE);
+
+      { static int first = 1;
+	 if (first)
+	    first = 0;
+	 else
+	    OUTREG(BRW_TD_CTL,
+		   BRW_TD_CTL_FORCE_EXTERNAL_HALT);
+      }
+
       BEGIN_LP_RING(6);
       OUT_RING(BRW_3DPRIMITIVE | 
 	       BRW_3DPRIMITIVE_VERTEX_SEQUENTIAL |
@@ -3278,17 +3395,77 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
       ADVANCE_LP_RING();
 
       int   j;
-      CARD32	  ctl = 0;
+      CARD32	  ctl = 0, rdata;
       
       for (j = 0; j < 100000; j++) {
 	ctl = INREG(BRW_VF_CTL);
 	 if (ctl & BRW_VF_CTL_SNAPSHOT_COMPLETE)
 	    break;
       }
-      CARD32	  rdata = INREG(BRW_VF_RDATA);
-
+      
+      rdata = INREG(BRW_VF_RDATA);
+      OUTREG(BRW_VF_CTL, 0);
       ErrorF ("VF_CTL: 0x%08x VF_RDATA: 0x%08x\n", ctl, rdata);
 
+#if 0
+      for (j = 0; j < 1000000; j++) {
+	ctl = INREG(BRW_VS_CTL);
+	 if (ctl & BRW_VS_CTL_SNAPSHOT_COMPLETE)
+	    break;
+      }
+
+      rdata = INREG(BRW_VS_RDATA);
+      OUTREG(BRW_VS_CTL, 0);
+      ErrorF ("VS_CTL: 0x%08x VS_RDATA: 0x%08x\n", ctl, rdata);
+#endif
+
+      for (j = 0; j < 1000000; j++) {
+	ctl = INREG(BRW_SF_CTL);
+	 if (ctl & BRW_SF_CTL_SNAPSHOT_COMPLETE)
+	    break;
+      }
+
+      int   k;
+
+      for (k = 0; k <= 7; k++) {
+	 OUTREG(BRW_SF_CTL,
+		BRW_SF_CTL_SNAPSHOT_COMPLETE |
+		(k << 8));
+	 rdata = INREG(BRW_SF_RDATA);
+	 ErrorF ("SF_CTL: 0x%08x SF_RDATA(%d): 0x%08x\n", ctl, k, rdata);
+      }
+      
+      OUTREG(BRW_SF_CTL, 0);
+
+      for (j = 0; j < 100000; j++) {
+	ctl = INREG(BRW_WIZ_CTL);
+	 if (ctl & BRW_WIZ_CTL_SNAPSHOT_COMPLETE)
+	    break;
+      }
+      
+      rdata = INREG(BRW_WIZ_RDATA);
+      OUTREG(BRW_WIZ_CTL, 0);
+      ErrorF ("WIZ_CTL: 0x%08x WIZ_RDATA: 0x%08x\n", ctl, rdata);
+      
+      for (j = 0; j < 100000; j++) {
+	ctl = INREG(BRW_TS_CTL);
+	 if (ctl & BRW_TS_CTL_SNAPSHOT_COMPLETE)
+	    break;
+      }
+      
+      rdata = INREG(BRW_TS_RDATA);
+      OUTREG(BRW_TS_CTL, 0);
+      ErrorF ("TS_CTL: 0x%08x TS_RDATA: 0x%08x\n", ctl, rdata);
+      
+      ErrorF ("after EU_ATT 0x%08x%08x EU_ATT_DATA 0x%08x%08x\n",
+	      INREG(BRW_EU_ATT_1), INREG(BRW_EU_ATT_0),
+	      INREG(BRW_EU_ATT_DATA_1), INREG(BRW_EU_ATT_DATA_0));
+
+      for (j = 0; j < 256; j++) {
+	 OUTREG(BRW_TD_CTL, j << BRW_TD_CTL_MUX_SHIFT);
+	 rdata = INREG(BRW_TD_RDATA);
+	 ErrorF ("TD_RDATA(%d): 0x%08x\n", j, rdata);
+      }
       first_output = FALSE;
       if (pI830->AccelInfoRec)
 	 pI830->AccelInfoRec->NeedToSync = TRUE;
@@ -3296,7 +3473,7 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
 
    if (pI830->AccelInfoRec)
       (*pI830->AccelInfoRec->Sync)(pScrn);
-/*   I830PrintErrorState (pScrn); */
+   I830PrintErrorState (pScrn);
    xf86FreeOffscreenLinear(state_area);
 }
 
diff-tree 9c111d89fe19f1773af2eefb000e1c2389b4b6e1 (from 01101196b16010ac3dadab647bfe7000a53fa94d)
Author: Keith his master's voice Packard <keithp at bw.jf.intel.com>
Date:   Sat May 27 19:52:13 2006 -0700

    Push all of the obvious Mesa state setting into the video code

diff --git a/src/brw_structs.h b/src/brw_structs.h
index 1c59716..49383c1 100644
--- a/src/brw_structs.h
+++ b/src/brw_structs.h
@@ -923,7 +923,8 @@ struct brw_surface_state
       GLuint cube_neg_y:1; 
       GLuint cube_pos_x:1; 
       GLuint cube_neg_x:1; 
-      GLuint pad:4;
+      GLuint pad:3;
+      GLuint render_cache_read_mode:1;
       GLuint mipmap_layout_mode:1; 
       GLuint vert_line_stride_ofs:1; 
       GLuint vert_line_stride:1; 
@@ -943,7 +944,7 @@ struct brw_surface_state
    } ss1;
    
    struct {
-      GLuint pad:2;
+      GLuint render_target_rotation:2;
       GLuint mip_count:4; 
       GLuint width:13; 
       GLuint height:13; 
diff --git a/src/i810_reg.h b/src/i810_reg.h
index 19edad4..c096089 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -1596,6 +1596,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define MI_INHIBIT_RENDER_CACHE_FLUSH	(1<<2)
 #define MI_STATE_INSTRUCTION_CACHE_FLUSH (1<<1)
 #define MI_INVALIDATE_MAP_CACHE		(1<<0)
+/* broadwater flush bits */
+#define BRW_MI_GLOBAL_SNAPSHOT_RESET   (1 << 3)
 
 /* Noop */
 #define MI_NOOP				0x00
@@ -1678,6 +1680,18 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define BRW_CLIP_DISABLE	       0
 #define BRW_CLIP_ENABLE		       1
 
+/* for BRW_PIPE_CONTROL */
+#define BRW_PIPE_CONTROL_NOWRITE       (0 << 14)
+#define BRW_PIPE_CONTROL_WRITE_QWORD   (1 << 14)
+#define BRW_PIPE_CONTROL_WRITE_DEPTH   (2 << 14)
+#define BRW_PIPE_CONTROL_WRITE_TIME    (3 << 14)
+#define BRW_PIPE_CONTROL_DEPTH_STALL   (1 << 13)
+#define BRW_PIPE_CONTROL_WC_FLUSH      (1 << 12)
+#define BRW_PIPE_CONTROL_IS_FLUSH      (1 << 11)
+#define BRW_PIPE_CONTROL_NOTIFY_ENABLE (1 << 8)
+#define BRW_PIPE_CONTROL_GLOBAL_GTT    (1 << 2)
+#define BRW_PIPE_CONTROL_LOCAL_PGTT    (0 << 2)
+
 /* VERTEX_BUFFER_STATE Structure */
 #define VB0_BUFFER_INDEX_SHIFT		27
 #define VB0_VERTEXDATA			(0 << 26)
@@ -1701,6 +1715,37 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 /* Primitive types are in brw_defines.h */
 #define BRW_3DPRIMITIVE_TOPOLOGY_SHIFT	  10
 
+#define BRW_SVG_CTL		       0x7400
+
+#define BRW_SVG_CTL_GS_BA	       (0 << 8)
+#define BRW_SVG_CTL_SS_BA	       (1 << 8)
+#define BRW_SVG_CTL_IO_BA	       (2 << 8)
+#define BRW_SVG_CTL_GS_AUB	       (3 << 8)
+#define BRW_SVG_CTL_IO_AUB	       (4 << 8)
+#define BRW_SVG_CTL_SIP		       (5 << 8)
+
+#define BRW_SVG_RDATA		       0x7404
+#define BRW_SVG_WORK_CTL	       0x7408
+
+#define BRW_VF_CTL		       0x7500
+
+#define BRW_VF_CTL_SNAPSHOT_COMPLETE		   (1 << 31)
+#define BRW_VF_CTL_SNAPSHOT_MUX_SELECT_THREADID	   (0 << 8)
+#define BRW_VF_CTL_SNAPSHOT_MUX_SELECT_VF_DEBUG	   (1 << 8)
+#define BRW_VF_CTL_SNAPSHOT_TYPE_VERTEX_SEQUENCE   (0 << 4)
+#define BRW_VF_CTL_SNAPSHOT_TYPE_VERTEX_INDEX	   (1 << 4)
+#define BRW_VF_CTL_SKIP_INITIAL_PRIMITIVES	   (1 << 3)
+#define BRW_VF_CTL_MAX_PRIMITIVES_LIMIT_ENABLE	   (1 << 2)
+#define BRW_VF_CTL_VERTEX_RANGE_LIMIT_ENABLE	   (1 << 1)
+#define BRW_VF_CTL_SNAPSHOT_ENABLE	     	   (1 << 0)
+
+#define BRW_VF_STRG_VAL		       0x7504
+#define BRW_VF_STR_VL_OVR	       0x7508
+#define BRW_VF_VC_OVR		       0x750c
+#define BRW_VF_STR_PSKIP	       0x7510
+#define BRW_VF_MAX_PRIM		       0x7514
+#define BRW_VF_RDATA		       0x7518
+
 /* End regs for broadwater */
 
 
diff --git a/src/i830_video.c b/src/i830_video.c
index 4c1a145..5174338 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2620,7 +2620,7 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
 
 #define SF_KERNEL_NUM_GRF  10
 #define SF_KERNEL_NUM_URB  8
-#define SF_MAX_THREADS	   
+#define SF_MAX_THREADS	   1
 
 static const CARD32 sf_kernel_static[][4] = {
 /*    send   0 (1) g6<1>F g1.8<0,1,0>F math mlen 1 rlen 1 { align1 +  } */
@@ -2679,7 +2679,7 @@ static const CARD32 sf_kernel_static[][4
 
 #define PS_KERNEL_NUM_GRF   10
 #define PS_KERNEL_NUM_URB   8
-#define WM_MAX_THREADS	MIN(12, PS_KERNEL_NUM_URB / 2)
+#define PS_MAX_THREADS	   1 /* MIN(12, PS_KERNEL_NUM_URB / 2) */
 
 static const CARD32 ps_kernel_static[][4] = {
 /*    mov (8) m2<1>F g2<16,16,1>UW { align1 +  } */
@@ -2723,6 +2723,43 @@ static const CARD32 ps_kernel_static[][4
 #define ALIGN(i,m)    (((i) + (m) - 1) & ~((m) - 1))
 #define MIN(a,b) ((a) < (b) ? (a) : (b))
 
+#define WM_BINDING_TABLE_ENTRIES    2
+
+static CARD32 float_to_uint (float f) {
+   union {CARD32 i; float f;} x;
+   x.f = f;
+   return x.i;
+}
+
+static struct {
+   CARD32   svg_ctl;
+   char	    *name;
+} svg_ctl_bits[] = {
+   { BRW_SVG_CTL_GS_BA, "General State Base Address" },
+   { BRW_SVG_CTL_SS_BA, "Surface State Base Address" },
+   { BRW_SVG_CTL_IO_BA, "Indirect Object Base Address" },
+   { BRW_SVG_CTL_GS_AUB, "Generate State Access Upper Bound" },
+   { BRW_SVG_CTL_IO_AUB, "Indirect Object Access Upper Bound" },
+   { BRW_SVG_CTL_SIP, "System Instruction Pointer" },
+   { 0, 0 },
+};
+
+static void
+brw_debug (ScrnInfoPtr pScrn, char *when)
+{
+   I830Ptr pI830 = I830PTR(pScrn);
+   int	    i;
+   CARD32   v;
+   
+   I830Sync (pScrn);
+   ErrorF("brw_debug: %s\n", when);
+   for (i = 0; svg_ctl_bits[i].name; i++) {
+      OUTREG(BRW_SVG_CTL, svg_ctl_bits[i].svg_ctl);
+      v = INREG(BRW_SVG_RDATA);
+      ErrorF("\t%34.34s: 0x%08x\n", svg_ctl_bits[i].name, v);
+   }
+}
+
 static void
 BroadwaterDisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
 			       RegionPtr dstRegion,
@@ -2765,9 +2802,15 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    char *state_base;
    int state_base_offset;
 
+#if 0
    ErrorF("BroadwaterDisplayVideoTextured: %dx%d (pitch %d)\n", width, height,
 	  video_pitch);
+#endif
 
+   /* enable debug */
+   OUTREG (INST_PM,
+	   (1 << (16 + 4)) |
+	   (1 << 4));
    assert((id == FOURCC_UYVY) || (id == FOURCC_YUY2));
 
    /* Tell the rotation code that we have stomped its invariant state by
@@ -2786,7 +2829,7 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    wm_offset = ALIGN(next_offset, 32);
    next_offset = wm_offset + sizeof(*wm_state);
    wm_scratch_offset = ALIGN(next_offset, 1024);
-   next_offset = wm_scratch_offset + 1024 * WM_MAX_THREADS;
+   next_offset = wm_scratch_offset + 1024 * PS_MAX_THREADS;
    cc_offset = ALIGN(next_offset, 32);
    next_offset = cc_offset + sizeof(*cc_state);
 
@@ -2811,7 +2854,7 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    src_surf_offset = ALIGN(next_offset, 32);
    next_offset = src_surf_offset + sizeof(*src_surf_state);
    binding_table_offset = ALIGN(next_offset, 32);
-   next_offset = binding_table_offset + (2 * 4);
+   next_offset = binding_table_offset + (WM_BINDING_TABLE_ENTRIES * 4);
 
    /* Allocate an area in framebuffer for our state layout we just set up */
    total_state_size = next_offset;
@@ -2845,37 +2888,83 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    /* Set up a default static partitioning of the URB, which is supposed to
     * allow anything we would want to do, at potentially lower performance.
     */
+#define URB_VS_ENTRIES	      8
+#define URB_VS_ENTRY_SIZE     5
+   
+#define URB_GS_ENTRIES	      4
+#define URB_GS_ENTRY_SIZE     5
+   
+#define URB_CLIP_ENTRIES      6
+#define URB_CLIP_ENTRY_SIZE   5
+   
+#define URB_SF_ENTRIES	      8
+#define URB_SF_ENTRY_SIZE     11
+
+#define URB_CS_ENTRIES	      2
+#define URB_CS_ENTRY_SIZE     32
+   
    urb_vs_start = 0;
-   urb_vs_size = 8 * 5;
+   urb_vs_size = URB_VS_ENTRIES * URB_VS_ENTRY_SIZE;
    urb_gs_start = urb_vs_start + urb_vs_size;
-   urb_gs_size = 4 * 5;
+   urb_gs_size = URB_GS_ENTRIES * URB_GS_ENTRY_SIZE;
    urb_clip_start = urb_gs_start + urb_gs_size;
-   urb_clip_size = 6 * 5;
+   urb_clip_size = URB_CLIP_ENTRIES * URB_CLIP_ENTRY_SIZE;
    urb_sf_start = urb_clip_start + urb_clip_size;
-   urb_sf_size = 8 * 11;
+   urb_sf_size = URB_SF_ENTRIES * URB_SF_ENTRY_SIZE;
    urb_cs_start = urb_sf_start + urb_sf_size;
-   urb_cs_size = 2 * 32;
+   urb_cs_size = URB_CS_ENTRIES * URB_CS_ENTRY_SIZE;
 
    /* We'll be poking the state buffers that could be in use by the 3d hardware
     * here, but we should have synced the 3D engine already in I830PutImage.
     */
 
+   memset (cc_viewport, 0, sizeof (*cc_viewport));
+   cc_viewport->min_depth = -1.e35;
+   cc_viewport->max_depth = 1.e35;
+
+   /* Color calculator state */
+   memset(cc_state, 0, sizeof(*cc_state));
+   cc_state->cc0.stencil_enable = 0;   /* disable stencil */
+   cc_state->cc2.depth_test = 0;       /* disable depth test */
+   cc_state->cc2.logicop_enable = 1;   /* enable logic op */
+   cc_state->cc3.ia_blend_enable = 0;  /* blend alpha just like colors */
+   cc_state->cc3.blend_enable = 0;     /* disable color blend */
+   cc_state->cc3.alpha_test = 0;       /* disable alpha test */
+   cc_state->cc4.cc_viewport_state_offset = (state_base_offset + cc_viewport_offset) >> 5;
+   cc_state->cc5.dither_enable = 0;    /* disable dither */
+   cc_state->cc5.logicop_func = 0xc;   /* COPYPEN */
+   cc_state->cc5.statistics_enable = 1;
+
    /* Set up the state buffer for the destination surface */
    memset(dest_surf_state, 0, sizeof(*dest_surf_state));
    dest_surf_state->ss0.surface_type = BRW_SURFACE_2D;
+   dest_surf_state->ss0.data_return_format = BRW_SURFACERETURNFORMAT_FLOAT32;
    if (pI830->cpp == 2) {
       dest_surf_state->ss0.surface_format = BRW_SURFACEFORMAT_B5G6R5_UNORM;
    } else {
       dest_surf_state->ss0.surface_format = BRW_SURFACEFORMAT_B8G8R8X8_UNORM;
    }
+   dest_surf_state->ss0.writedisable_alpha = 0;
+   dest_surf_state->ss0.writedisable_red = 0;
+   dest_surf_state->ss0.writedisable_green = 0;
+   dest_surf_state->ss0.writedisable_blue = 0;
+   dest_surf_state->ss0.color_blend = 1;
+   dest_surf_state->ss0.vert_line_stride = 0;
+   dest_surf_state->ss0.vert_line_stride_ofs = 0;
+   dest_surf_state->ss0.mipmap_layout_mode = 0;
+   dest_surf_state->ss0.render_cache_read_mode = 0;
+   
    dest_surf_state->ss1.base_addr = pI830->FrontBuffer.Start;
-   dest_surf_state->ss2.width = pScrn->virtualX - 1;
    dest_surf_state->ss2.height = pScrn->virtualY - 1;
-   dest_surf_state->ss3.pitch = pI830->displayWidth * pI830->cpp;
+   dest_surf_state->ss2.width = pScrn->virtualX - 1;
+   dest_surf_state->ss2.mip_count = 0;
+   dest_surf_state->ss2.render_target_rotation = 0;
+   dest_surf_state->ss3.pitch = (pI830->displayWidth * pI830->cpp) - 1;
 
    /* Set up the source surface state buffer */
    memset(src_surf_state, 0, sizeof(*src_surf_state));
    src_surf_state->ss0.surface_type = BRW_SURFACE_2D;
+   src_surf_state->ss0.data_return_format = BRW_SURFACERETURNFORMAT_FLOAT32;
    switch (id) {
    case FOURCC_YUY2:
       src_surf_state->ss0.surface_format = BRW_SURFACEFORMAT_YCRCB_NORMAL;
@@ -2884,9 +2973,21 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
       src_surf_state->ss0.surface_format = BRW_SURFACEFORMAT_YCRCB_SWAPY;
       break;
    }
+   src_surf_state->ss0.writedisable_alpha = 0;
+   src_surf_state->ss0.writedisable_red = 0;
+   src_surf_state->ss0.writedisable_green = 0;
+   src_surf_state->ss0.writedisable_blue = 0;
+   src_surf_state->ss0.color_blend = 1;
+   src_surf_state->ss0.vert_line_stride = 0;
+   src_surf_state->ss0.vert_line_stride_ofs = 0;
+   src_surf_state->ss0.mipmap_layout_mode = 0;
+   src_surf_state->ss0.render_cache_read_mode = 0;
+   
    src_surf_state->ss1.base_addr = pPriv->YBuf0offset;
-   src_surf_state->ss2.width = width;
-   src_surf_state->ss2.height = height;
+   src_surf_state->ss2.width = width - 1;
+   src_surf_state->ss2.height = height - 1;
+   src_surf_state->ss2.mip_count = 0;
+   src_surf_state->ss2.render_target_rotation = 0;
    src_surf_state->ss3.pitch = video_pitch - 1;
 
    /* Set up a binding table for our two surfaces.  Only the PS will use it */
@@ -2899,33 +3000,43 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    memset(src_sampler_state, 0, sizeof(*src_sampler_state));
    src_sampler_state->ss0.min_filter = BRW_MAPFILTER_LINEAR;
    src_sampler_state->ss0.mag_filter = BRW_MAPFILTER_LINEAR;
+   src_sampler_state->ss1.r_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
    src_sampler_state->ss1.s_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
    src_sampler_state->ss1.t_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
 
    /* Set up the vertex shader to be disabled (passthrough) */
    memset(vs_state, 0, sizeof(*vs_state));
-   vs_state->vs6.vs_enable = FALSE;
+   vs_state->thread4.nr_urb_entries = URB_VS_ENTRIES;
+   vs_state->thread4.urb_entry_allocation_size = URB_VS_ENTRY_SIZE - 1;
+   vs_state->thread4.stats_enable = 1;
+   vs_state->vs6.vs_enable = 0;
+   vs_state->vs6.vert_cache_disable = 1;
 
    /* Set up the SF kernel to do coord interp: for each attribute,
     * calculate dA/dx and dA/dy.  Hand these interpolation coefficients
     * back to SF which then hands pixels off to WM.
     */
 
+   memcpy (sf_kernel, sf_kernel_static, sizeof (sf_kernel_static));
    memset(sf_state, 0, sizeof(*sf_state));
    sf_state->thread0.kernel_start_pointer = state_base_offset + sf_kernel_offset;
-   sf_state->thread0.grf_reg_count = ((SF_KERNEL_NUM_GRF + 15) / 16) - 1;
+   sf_state->thread0.grf_reg_count = ((SF_KERNEL_NUM_GRF & ~15) / 16);
    sf_state->thread1.single_program_flow = 1; /* XXX */
    sf_state->thread2.per_thread_scratch_space = 0;
    sf_state->thread2.scratch_space_base_pointer = 0; /* not used in our kernel */
-   sf_state->thread4.nr_urb_entries = SF_KERNEL_NUM_URB;
-   sf_state->thread4.urb_entry_allocation_size = 11;
-   sf_state->thread4.max_threads = WM_MAX_THREADS - 1;
+   sf_state->thread3.urb_entry_read_length = 4; /* XXX */
+   sf_state->thread3.dispatch_grf_start_reg = 3; /* XXX */
+   sf_state->thread3.urb_entry_read_offset = 1; /* XXX */
+   sf_state->thread4.nr_urb_entries = URB_SF_ENTRIES;
+   sf_state->thread4.urb_entry_allocation_size = URB_SF_ENTRY_SIZE - 1;
+   sf_state->thread4.max_threads = MIN(12, URB_SF_ENTRIES / 2) - 1;
+   sf_state->thread4.stats_enable = 1;
    sf_state->sf5.viewport_transform = FALSE; /* skip viewport */
    sf_state->sf6.cull_mode = BRW_CULLMODE_NONE;
-   sf_state->sf6.scissor = 0; /* XXX */
+   sf_state->sf6.scissor = 0;
+   sf_state->sf7.trifan_pv = 2;
    sf_state->sf6.dest_org_vbias = 0x8;
    sf_state->sf6.dest_org_hbias = 0x8;
-   sf_state->sf7.trifan_pv = 0;
 
    /* XXX: Set up the PS kernel (dispatched by WM) for converting YUV to RGB.
     * The 3D driver does this as:
@@ -2940,8 +3051,10 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
     *
     */
 
+   memcpy (ps_kernel, ps_kernel_static, sizeof (ps_kernel_static));
+   memset (wm_state, 0, sizeof (*wm_state));
    wm_state->thread0.kernel_start_pointer = state_base_offset + ps_kernel_offset;
-   wm_state->thread0.grf_reg_count = ((PS_KERNEL_NUM_GRF + 15) / 16) - 1;
+   wm_state->thread0.grf_reg_count = ((PS_KERNEL_NUM_GRF & ~15) / 16);
    wm_state->thread1.single_program_flow = 1; /* XXX */
    wm_state->thread1.binding_table_entry_count = 2;
    wm_state->thread2.scratch_space_base_pointer = 0; /* XXX */
@@ -2949,73 +3062,81 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    wm_state->thread3.dispatch_grf_start_reg = 0; /* XXX */
    wm_state->thread3.urb_entry_read_length = 4; /* XXX */
    wm_state->thread3.const_urb_entry_read_length = 0; /* XXX */
+   wm_state->thread3.urb_entry_read_offset = 0; /* XXX */
+   wm_state->wm4.stats_enable = 1;
    wm_state->wm4.sampler_state_pointer = (state_base_offset + src_sampler_offset) >> 5;
    wm_state->wm4.sampler_count = 1; /* 1-4 samplers used */
-   wm_state->wm5.max_threads = 0;
+   wm_state->wm5.max_threads = 0;   /* XXX should be PS_MAX_THREADS */
    wm_state->wm5.thread_dispatch_enable = 1;
    wm_state->wm5.enable_16_pix = 1;
    wm_state->wm5.enable_8_pix = 0;
+   wm_state->wm5.early_depth_test = 1;
 
-   cc_viewport->min_depth = 0.0;
-   cc_viewport->max_depth = 0.0;
-
-   memset(cc_state, 0, sizeof(*cc_state));
-   cc_state->cc0.stencil_enable = 0;   /* disable stencil */
-   cc_state->cc2.depth_test = 0;       /* disable depth test */
-   cc_state->cc2.logicop_enable = 1;   /* enable logic op */
-   cc_state->cc3.ia_blend_enable = 0;  /* blend alpha just like colors */
-   cc_state->cc3.blend_enable = 0;     /* disable color blend */
-   cc_state->cc3.alpha_test = 0;       /* disable alpha test */
-   cc_state->cc4.cc_viewport_state_offset = (state_base_offset + cc_viewport_offset) >> 5;
-   cc_state->cc5.dither_enable = 0;    /* disable dither */
-   cc_state->cc5.logicop_func = 0xf;   /* WHITE */
-
-   memcpy (sf_kernel, sf_kernel_static, sizeof (sf_kernel_static));
-   memcpy (ps_kernel, ps_kernel_static, sizeof (ps_kernel_static));
+   {
+      BEGIN_LP_RING(2);
+      OUT_RING(MI_FLUSH | 
+	       MI_STATE_INSTRUCTION_CACHE_FLUSH |
+	       /* BRW_MI_GLOBAL_SNAPSHOT_RESET */ 0);
+      OUT_RING(MI_NOOP);
+      ADVANCE_LP_RING();
+   }
    
-   BEGIN_LP_RING(38);
-   OUT_RING(MI_FLUSH | MI_STATE_INSTRUCTION_CACHE_FLUSH);
-
+/*    brw_debug (pScrn, "before base address modify"); */
+   { BEGIN_LP_RING(12);
+   /* Match Mesa driver setup */
    OUT_RING(BRW_PIPELINE_SELECT | PIPELINE_SELECT_3D);
 
-   OUT_RING(BRW_URB_FENCE |
-	    UF0_CS_REALLOC |
-	    UF0_SF_REALLOC |
-	    UF0_CLIP_REALLOC |
-	    UF0_GS_REALLOC |
-	    UF0_VS_REALLOC |
-	    1);
-   OUT_RING(((urb_clip_start + urb_clip_size) << UF1_CLIP_FENCE_SHIFT) |
-	    ((urb_gs_start + urb_gs_size) << UF1_GS_FENCE_SHIFT) |
-	    ((urb_vs_start + urb_vs_size) << UF1_VS_FENCE_SHIFT));
-   OUT_RING(((urb_cs_start + urb_cs_size) << UF2_CS_FENCE_SHIFT) |
-	    ((urb_sf_start + urb_sf_size) << UF2_SF_FENCE_SHIFT));
-
+   /* Mesa does this. Who knows... */
+   OUT_RING(BRW_CS_URB_STATE | 0);
+   OUT_RING((0 << 4) |	/* URB Entry Allocation Size */
+	    (0 << 0));	/* Number of URB Entries */
+   
    /* Zero out the two base address registers so all offsets are absolute */
    OUT_RING(BRW_STATE_BASE_ADDRESS | 4);
-   OUT_RING(0 | BASE_ADDRESS_MODIFY);	/* Generate state base address */
-   OUT_RING(0 | BASE_ADDRESS_MODIFY);	/* Surface state base address */
-   OUT_RING(0); /* media base addr, don't care */
-   OUT_RING(0); /* general state max addr, disabled */
-   OUT_RING(0); /* media object state max addr, disabled */
+   OUT_RING(0 | BASE_ADDRESS_MODIFY);  /* Generate state base address */
+   OUT_RING(0 | BASE_ADDRESS_MODIFY);  /* Surface state base address */
+   OUT_RING(0 | BASE_ADDRESS_MODIFY);  /* media base addr, don't care */
+   OUT_RING(0x10000000 | BASE_ADDRESS_MODIFY);  /* general state max addr, disabled */
+   OUT_RING(1); /* media object state max addr, disabled */
+
+   /* Set system instruction pointer to zero */
+   OUT_RING(BRW_STATE_SIP | 0);
+   OUT_RING(0);			       /* system instruction pointer */
+      
+   OUT_RING(MI_NOOP);
+   ADVANCE_LP_RING(); }
+   
+/*   brw_debug (pScrn, "after base address modify"); */
 
-   /* Set the pointers to the 3d pipeline state */
-   OUT_RING(BRW_3DSTATE_PIPELINED_POINTERS | 5);
-   OUT_RING(state_base_offset + vs_offset);  /* 32 byte aligned */
-   OUT_RING(BRW_GS_DISABLE);		     /* disable GS, resulting in passthrough */
-   OUT_RING(BRW_CLIP_DISABLE);		     /* disable CLIP, resulting in passthrough */
-   OUT_RING(state_base_offset + sf_offset);  /* 32 byte aligned */
-   OUT_RING(state_base_offset + wm_offset);  /* 32 byte aligned */
-   OUT_RING(state_base_offset + cc_offset);  /* 64 byte aligned */
+   { BEGIN_LP_RING(42);
+   /* Enable VF statistics */
+   OUT_RING(BRW_3DSTATE_VF_STATISTICS | 1);
+   
+   /* Pipe control */
+   OUT_RING(BRW_PIPE_CONTROL |
+	    BRW_PIPE_CONTROL_NOWRITE |
+	    BRW_PIPE_CONTROL_IS_FLUSH |
+	    2);
+   OUT_RING(0);			       /* Destination address */
+   OUT_RING(0);			       /* Immediate data low DW */
+   OUT_RING(0);			       /* Immediate data high DW */
 
-   /* Only the PS uses the binding table */
+   /* Binding table pointers */
    OUT_RING(BRW_3DSTATE_BINDING_TABLE_POINTERS | 4);
    OUT_RING(0); /* vs */
    OUT_RING(0); /* gs */
    OUT_RING(0); /* clip */
    OUT_RING(0); /* sf */
+   /* Only the PS uses the binding table */
    OUT_RING(state_base_offset + binding_table_offset); /* ps */
-
+   
+   /* Blend constant color (magenta is fun) */
+   OUT_RING(BRW_3DSTATE_CONSTANT_COLOR | 3);
+   OUT_RING(float_to_uint (1.0));
+   OUT_RING(float_to_uint (0.0));
+   OUT_RING(float_to_uint (1.0));
+   OUT_RING(float_to_uint (1.0));
+   
    /* The drawing rectangle clipping is always on.  Set it to values that
     * shouldn't do any clipping.
     */
@@ -3025,39 +3146,72 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
 	    (pScrn->virtualY - 1) << 16); /* ymax, xmax */
    OUT_RING(0x00000000);	/* yorigin, xorigin */
 
+   /* skip the depth buffer */
+   /* skip the polygon stipple */
+   /* skip the polygon stipple offset */
+   /* skip the line stipple */
+   
+   /* Set the pointers to the 3d pipeline state */
+   OUT_RING(BRW_3DSTATE_PIPELINED_POINTERS | 5);
+   OUT_RING(state_base_offset + vs_offset);  /* 32 byte aligned */
+   OUT_RING(BRW_GS_DISABLE);		     /* disable GS, resulting in passthrough */
+   OUT_RING(BRW_CLIP_DISABLE);		     /* disable CLIP, resulting in passthrough */
+   OUT_RING(state_base_offset + sf_offset);  /* 32 byte aligned */
+   OUT_RING(state_base_offset + wm_offset);  /* 32 byte aligned */
+   OUT_RING(state_base_offset + cc_offset);  /* 64 byte aligned */
+
+   /* URB fence */
+   OUT_RING(BRW_URB_FENCE |
+	    UF0_CS_REALLOC |
+	    UF0_SF_REALLOC |
+	    UF0_CLIP_REALLOC |
+	    UF0_GS_REALLOC |
+	    UF0_VS_REALLOC |
+	    1);
+   OUT_RING(((urb_clip_start + urb_clip_size) << UF1_CLIP_FENCE_SHIFT) |
+	    ((urb_gs_start + urb_gs_size) << UF1_GS_FENCE_SHIFT) |
+	    ((urb_vs_start + urb_vs_size) << UF1_VS_FENCE_SHIFT));
+   OUT_RING(((urb_cs_start + urb_cs_size) << UF2_CS_FENCE_SHIFT) |
+	    ((urb_sf_start + urb_sf_size) << UF2_SF_FENCE_SHIFT));
+
+   /* Constant buffer state */
+   OUT_RING(BRW_CS_URB_STATE | 0);
+   OUT_RING(((URB_CS_ENTRY_SIZE - 1) << 4) | /* URB Entry Allocation Size */
+	    (URB_CS_ENTRIES << 0));	     /* Number of URB Entries */
+   
    /* Set up the pointer to our vertex buffer */
    OUT_RING(BRW_3DSTATE_VERTEX_BUFFERS | 2);
    OUT_RING((0 << VB0_BUFFER_INDEX_SHIFT) |
 	    VB0_VERTEXDATA |
 	    ((4 * 4) << VB0_BUFFER_PITCH_SHIFT)); /* four 32-bit floats per vertex */
    OUT_RING(state_base_offset + vb_offset);
-   OUT_RING(4); /* four corners to our rectangle */
+   OUT_RING(3); /* four corners to our rectangle */
 
    /* Set up our vertex elements, sourced from the single vertex buffer. */
    OUT_RING(BRW_3DSTATE_VERTEX_ELEMENTS | 3);
-   /* offset 0: X,Y -> {X, Y, 0.0, 0.0} */
+   /* offset 0: X,Y -> {X, Y, 1.0, 1.0} */
    OUT_RING((0 << VE0_VERTEX_BUFFER_INDEX_SHIFT) |
 	    VE0_VALID |
 	    (BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) |
 	    (0 << VE0_OFFSET_SHIFT));
    OUT_RING((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) |
 	    (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) |
-	    (BRW_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_2_SHIFT) |
-	    (BRW_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_3_SHIFT) |
+	    (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT) |
+	    (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT) |
 	    (0 << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT));
-   /* offset 8: S0, T0 -> {S0, T0, 0.0, 0.0} */
+   /* offset 8: S0, T0 -> {S0, T0, 1.0, 1.0} */
    OUT_RING((0 << VE0_VERTEX_BUFFER_INDEX_SHIFT) |
 	    VE0_VALID |
 	    (BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) |
 	    (8 << VE0_OFFSET_SHIFT));
    OUT_RING((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) |
 	    (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) |
-	    (BRW_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_2_SHIFT) |
-	    (BRW_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_3_SHIFT) |
+	    (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT) |
+	    (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT) |
 	    (4 << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT));
 
-   OUT_RING(0);			/* pad to quadword */
-   ADVANCE_LP_RING();
+   OUT_RING(MI_NOOP);			/* pad to quadword */
+   ADVANCE_LP_RING(); }
 
    dxo = dstRegion->extents.x1;
    dyo = dstRegion->extents.y1;
@@ -3072,9 +3226,6 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
       int box_y2 = pbox->y2;
       int i;
       float src_scale_x, src_scale_y;
-      CARD32 vb[40];
-      float verts[4][2], tex[4][2], tex2[4][2];
-      int vert_data_count;
 
       if (!first_output) {
 	 /* Since we use the same little vertex buffer over and over, sync for
@@ -3091,30 +3242,7 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
       src_scale_x = (float)src_w / (float)drw_w;
       src_scale_y  = (float)src_h / (float)drw_h;
 
-      if (!planar)
-	 vert_data_count = 32;
-      else
-	 vert_data_count = 40;
-
-      OUT_RING(MI_NOOP);
-      OUT_RING(MI_NOOP);
-      OUT_RING(MI_NOOP);
-      OUT_RING(MI_NOOP);
-      OUT_RING(MI_NOOP);
-      OUT_RING(MI_NOOP);
-      OUT_RING(MI_NOOP);
-
       i = 0;
-      vb[i++] = box_x1;
-      vb[i++] = box_y1;
-      vb[i++] = (box_x1 - dxo) * src_scale_x;
-      vb[i++] = (box_y1 - dyo) * src_scale_y;
-
-      vb[i++] = box_x2;
-      vb[i++] = box_y1;
-      vb[i++] = (box_x2 - dxo) * src_scale_x;
-      vb[i++] = (box_y1 - dyo) * src_scale_y;
-
       vb[i++] = box_x2;
       vb[i++] = box_y2;
       vb[i++] = (box_x2 - dxo) * src_scale_x;
@@ -3125,27 +3253,51 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
       vb[i++] = (box_x1 - dxo) * src_scale_x;
       vb[i++] = (box_y2 - dyo) * src_scale_y;
 
+      vb[i++] = box_x1;
+      vb[i++] = box_y1;
+      vb[i++] = (box_x1 - dxo) * src_scale_x;
+      vb[i++] = (box_y1 - dyo) * src_scale_y;
+
+      OUTREG(BRW_VF_CTL,
+	     BRW_VF_CTL_SNAPSHOT_MUX_SELECT_THREADID |
+	     BRW_VF_CTL_SNAPSHOT_TYPE_VERTEX_INDEX |
+	     BRW_VF_CTL_SNAPSHOT_ENABLE);
+      OUTREG(BRW_VF_STRG_VAL, 0);
+      
       BEGIN_LP_RING(6);
       OUT_RING(BRW_3DPRIMITIVE | 
 	       BRW_3DPRIMITIVE_VERTEX_SEQUENTIAL |
-	       (_3DPRIM_TRIFAN << BRW_3DPRIMITIVE_TOPOLOGY_SHIFT) | 
-	       (0 << 9) |
+	       (_3DPRIM_TRILIST << BRW_3DPRIMITIVE_TOPOLOGY_SHIFT) | 
+	       (0 << 9) |  /* CTG - indirect vertex count */
 	       4);
-      OUT_RING(4); /* vertex count per instance XXX should this be 3 or 6? */
+      OUT_RING(3); /* vertex count per instance */
       OUT_RING(0); /* start vertex offset */
       OUT_RING(1); /* single instance */
       OUT_RING(0); /* start instance location */
       OUT_RING(0); /* index buffer offset, ignored */
-
       ADVANCE_LP_RING();
 
+      int   j;
+      CARD32	  ctl = 0;
+      
+      for (j = 0; j < 100000; j++) {
+	ctl = INREG(BRW_VF_CTL);
+	 if (ctl & BRW_VF_CTL_SNAPSHOT_COMPLETE)
+	    break;
+      }
+      CARD32	  rdata = INREG(BRW_VF_RDATA);
+
+      ErrorF ("VF_CTL: 0x%08x VF_RDATA: 0x%08x\n", ctl, rdata);
+
       first_output = FALSE;
+      if (pI830->AccelInfoRec)
+	 pI830->AccelInfoRec->NeedToSync = TRUE;
    }
 
-   xf86FreeOffscreenLinear(state_area);
-
    if (pI830->AccelInfoRec)
-      pI830->AccelInfoRec->NeedToSync = TRUE;
+      (*pI830->AccelInfoRec->Sync)(pScrn);
+/*   I830PrintErrorState (pScrn); */
+   xf86FreeOffscreenLinear(state_area);
 }
 
 static FBLinearPtr
@@ -3322,7 +3474,9 @@ I830PutImage(ScrnInfoPtr pScrn,
       }
       break;
    }
+#if 0
    ErrorF("srcPitch: %d, dstPitch: %d, size: %d\n", srcPitch, dstPitch, size);
+#endif
 
    /* size is multiplied by 2 because we have two buffers that are flipping */
    pPriv->linear = I830AllocateMemory(pScrn, pPriv->linear,
@@ -3454,7 +3608,9 @@ I830QueryImageAttributes(ScrnInfoPtr pSc
    I830Ptr pI830 = I830PTR(pScrn);
    int size, tmp;
 
+#if 0
    ErrorF("I830QueryImageAttributes: w is %d, h is %d\n", *w, *h);
+#endif
 
    if (!textured) {
       if (IS_845G(pI830) || IS_I830(pI830)) {
diff-tree 01101196b16010ac3dadab647bfe7000a53fa94d (from 462a860af89ed855fe2b718342fcaf9c169af3fb)
Author: Keith his master's voice Packard <keithp at bw.jf.intel.com>
Date:   Sat May 27 01:05:09 2006 -0700

    flesh out cc state. set cull mode to none. enable sf kernel

diff --git a/src/i830_video.c b/src/i830_video.c
index 225f9a9..4c1a145 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2623,7 +2623,6 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
 #define SF_MAX_THREADS	   
 
 static const CARD32 sf_kernel_static[][4] = {
-#if 0
 /*    send   0 (1) g6<1>F g1.8<0,1,0>F math mlen 1 rlen 1 { align1 +  } */
     { 0x00000031, 0x20c01fbd, 0x00000028, 0x01110081 },
 /*    mov (2) g3.8<1>F g2<2,2,1>F { align1 +  } */
@@ -2658,7 +2657,6 @@ static const CARD32 sf_kernel_static[][4
     { 0x00600041, 0x204077be, 0x008d0120, 0x000000c0 },
 /*    mov (8) m3<1>F g3<8,8,1>F { align1 +  } */
     { 0x00600001, 0x206003be, 0x008d0060, 0x00000000 },
-#endif
 /*    send   0 (8) a0<1>F g0<8,8,1>F urb mlen 4 rlen 0 write +0 transpose used complete EOT{ align1 +  } */
     { 0x00600031, 0x20001fbc, 0x008d0000, 0x8640c800 },
 /*    nop (4) g0<1>UD { align1 +  } */
@@ -2870,7 +2868,7 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    } else {
       dest_surf_state->ss0.surface_format = BRW_SURFACEFORMAT_B8G8R8X8_UNORM;
    }
-   dest_surf_state->ss1.base_addr = pI830->bufferOffset;
+   dest_surf_state->ss1.base_addr = pI830->FrontBuffer.Start;
    dest_surf_state->ss2.width = pScrn->virtualX - 1;
    dest_surf_state->ss2.height = pScrn->virtualY - 1;
    dest_surf_state->ss3.pitch = pI830->displayWidth * pI830->cpp;
@@ -2923,11 +2921,11 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    sf_state->thread4.urb_entry_allocation_size = 11;
    sf_state->thread4.max_threads = WM_MAX_THREADS - 1;
    sf_state->sf5.viewport_transform = FALSE; /* skip viewport */
-   sf_state->sf6.cull_mode = BRW_CULLMODE_BOTH;
+   sf_state->sf6.cull_mode = BRW_CULLMODE_NONE;
    sf_state->sf6.scissor = 0; /* XXX */
    sf_state->sf6.dest_org_vbias = 0x8;
    sf_state->sf6.dest_org_hbias = 0x8;
-   sf_state->sf7.trifan_pv = 2;
+   sf_state->sf7.trifan_pv = 0;
 
    /* XXX: Set up the PS kernel (dispatched by WM) for converting YUV to RGB.
     * The 3D driver does this as:
@@ -2944,6 +2942,7 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
 
    wm_state->thread0.kernel_start_pointer = state_base_offset + ps_kernel_offset;
    wm_state->thread0.grf_reg_count = ((PS_KERNEL_NUM_GRF + 15) / 16) - 1;
+   wm_state->thread1.single_program_flow = 1; /* XXX */
    wm_state->thread1.binding_table_entry_count = 2;
    wm_state->thread2.scratch_space_base_pointer = 0; /* XXX */
    wm_state->thread2.per_thread_scratch_space = 0; /* XXX */
@@ -2955,12 +2954,21 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    wm_state->wm5.max_threads = 0;
    wm_state->wm5.thread_dispatch_enable = 1;
    wm_state->wm5.enable_16_pix = 1;
+   wm_state->wm5.enable_8_pix = 0;
 
    cc_viewport->min_depth = 0.0;
    cc_viewport->max_depth = 0.0;
 
    memset(cc_state, 0, sizeof(*cc_state));
+   cc_state->cc0.stencil_enable = 0;   /* disable stencil */
+   cc_state->cc2.depth_test = 0;       /* disable depth test */
+   cc_state->cc2.logicop_enable = 1;   /* enable logic op */
+   cc_state->cc3.ia_blend_enable = 0;  /* blend alpha just like colors */
+   cc_state->cc3.blend_enable = 0;     /* disable color blend */
+   cc_state->cc3.alpha_test = 0;       /* disable alpha test */
    cc_state->cc4.cc_viewport_state_offset = (state_base_offset + cc_viewport_offset) >> 5;
+   cc_state->cc5.dither_enable = 0;    /* disable dither */
+   cc_state->cc5.logicop_func = 0xf;   /* WHITE */
 
    memcpy (sf_kernel, sf_kernel_static, sizeof (sf_kernel_static));
    memcpy (ps_kernel, ps_kernel_static, sizeof (ps_kernel_static));
@@ -3058,10 +3066,10 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    nbox = REGION_NUM_RECTS(dstRegion);
    while (nbox--)
    {
-      int box_x1 = pbox->x1 - pbox->x1;
-      int box_y1 = pbox->y1 - pbox->y1;
-      int box_x2 = pbox->x2 - pbox->x1;
-      int box_y2 = pbox->y2 - pbox->y1;
+      int box_x1 = pbox->x1;
+      int box_y1 = pbox->y1;
+      int box_x2 = pbox->x2;
+      int box_y2 = pbox->y2;
       int i;
       float src_scale_x, src_scale_y;
       CARD32 vb[40];
diff-tree 462a860af89ed855fe2b718342fcaf9c169af3fb (from 9ec7cf22e3f03c13524bb2d15711699dfcc02984)
Author: Keith his master's voice Packard <keithp at bw.jf.intel.com>
Date:   Sat May 27 00:17:25 2006 -0700

    Rename BRW instructions, check video instruction generation. Doesnt lock up, but doesnt display anything either

diff --git a/src/i810_reg.h b/src/i810_reg.h
index 0e13932..19edad4 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -1612,11 +1612,50 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 /*
  * New regs for broadwater -- we need to split this file up sensibly somehow.
  */
-#define STATE3D_PIPELINE_SELECT		(CMD_3D | (0x01<<24) | (0x04<<16))
+#define BRW_3D(Pipeline,Opcode,Subopcode) (CMD_3D | \
+					   ((Pipeline) << 27) | \
+					   ((Opcode) << 24) | \
+					   ((Subopcode) << 16))
+
+#define BRW_URB_FENCE				BRW_3D(0, 0, 0)
+#define BRW_CS_URB_STATE			BRW_3D(0, 0, 1)
+#define BRW_CONSTANT_BUFFER			BRW_3D(0, 0, 2)
+#define BRW_STATE_PREFETCH			BRW_3D(0, 0, 3)
+
+#define BRW_STATE_BASE_ADDRESS			BRW_3D(0, 1, 1)
+#define BRW_STATE_SIP				BRW_3D(0, 1, 2)
+#define BRW_PIPELINE_SELECT			BRW_3D(0, 1, 4)
+
+#define BRW_MEDIA_STATE_POINTERS		BRW_3D(2, 0, 0)
+#define BRW_MEDIA_OBJECT			BRW_3D(2, 1, 0)
+
+#define BRW_3DSTATE_PIPELINED_POINTERS		BRW_3D(3, 0, 0)
+#define BRW_3DSTATE_BINDING_TABLE_POINTERS	BRW_3D(3, 0, 1)
+#define BRW_3DSTATE_VERTEX_BUFFERS		BRW_3D(3, 0, 8)
+#define BRW_3DSTATE_VERTEX_ELEMENTS		BRW_3D(3, 0, 9)
+#define BRW_3DSTATE_INDEX_BUFFER		BRW_3D(3, 0, 0xa)
+#define BRW_3DSTATE_VF_STATISTICS		BRW_3D(3, 0, 0xb)
+
+#define BRW_3DSTATE_DRAWING_RECTANGLE		BRW_3D(3, 1, 0)
+#define BRW_3DSTATE_CONSTANT_COLOR		BRW_3D(3, 1, 1)
+#define BRW_3DSTATE_SAMPLER_PALETTE_LOAD	BRW_3D(3, 1, 2)
+#define BRW_3DSTATE_CHROMA_KEY			BRW_3D(3, 1, 4)
+#define BRW_3DSTATE_DEPTH_BUFFER		BRW_3D(3, 1, 5)
+#define BRW_3DSTATE_POLY_STIPPLE_OFFSET		BRW_3D(3, 1, 6)
+#define BRW_3DSTATE_POLY_STIPPLE_PATTERN	BRW_3D(3, 1, 7)
+#define BRW_3DSTATE_LINE_STIPPLE		BRW_3D(3, 1, 8)
+#define BRW_3DSTATE_GLOBAL_DEPTH_OFFSET_CLAMP	BRW_3D(3, 1, 9)
+/* These two are BLC and CTG only, not BW or CL */
+#define BRW_3DSTATE_AA_LINE_PARAMS		BRW_3D(3, 1, 0xa)
+#define BRW_3DSTATE_GS_SVB_INDEX		BRW_3D(3, 1, 0xb)
+
+#define BRW_PIPE_CONTROL			BRW_3D(3, 2, 0)
+
+#define BRW_3DPRIMITIVE				BRW_3D(3, 3, 0)
+
 #define PIPELINE_SELECT_3D		0
 #define PIPELINE_SELECT_MEDIA		1
 
-#define STATE3D_URB_FENCE		(CMD_3D | (0x00<<24) | (0x00<<16))
 #define UF0_CS_REALLOC			(1 << 13)
 #define UF0_VFE_REALLOC			(1 << 12)
 #define UF0_SF_REALLOC			(1 << 11)
@@ -1630,20 +1669,22 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define UF2_VFE_FENCE_SHIFT		10
 #define UF2_SF_FENCE_SHIFT		0
 
-#define STATE3D_DRAWING_RECTANGLE_BRW	(CMD_3D | (0x01<<24) | (0x00<<16))
-
-#define STATE3D_BASE_ADDRESS		(CMD_3D | (0x01<<24) | (0x01<<16))
+/* for BRW_STATE_BASE_ADDRESS */
 #define BASE_ADDRESS_MODIFY		(1 << 0)
 
-#define STATE3D_PIPELINED_POINTERS	(CMD_3D | (0x00<<24) | (0x00<<16))
+/* for BRW_3DSTATE_PIPELINED_POINTERS */
+#define BRW_GS_DISABLE		       0
+#define BRW_GS_ENABLE		       1
+#define BRW_CLIP_DISABLE	       0
+#define BRW_CLIP_ENABLE		       1
 
-#define STATE3D_VERTEX_BUFFERS	(CMD_3D | (0x03<<27) | (0x00<<24) | (0x08<<16))
+/* VERTEX_BUFFER_STATE Structure */
 #define VB0_BUFFER_INDEX_SHIFT		27
 #define VB0_VERTEXDATA			(0 << 26)
 #define VB0_INSTANCEDATA		(1 << 26)
 #define VB0_BUFFER_PITCH_SHIFT		0
 
-#define STATE3D_VERTEX_ELEMENTS		(CMD_3D | (0x00<<24) | (0x09<<16))
+/* VERTEX_ELEMENT_STATE Structure */
 #define VE0_VERTEX_BUFFER_INDEX_SHIFT	27
 #define VE0_VALID			(1 << 26)
 #define VE0_FORMAT_SHIFT		16
@@ -1654,11 +1695,12 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define VE1_VFCOMPONENT_3_SHIFT		16
 #define VE1_DESTINATION_ELEMENT_OFFSET_SHIFT	0
 
-#define STATE3D_BINDING_TABLE_POINTERS	(CMD_3D | (0x03<<27) | (0x00<<24) | (0x01<<16))
-
-#define PRIMITIVE3D_BRW		(CMD_3D | (0x03<<27) | (0x03<<24) | (0x08<<16))
+/* 3DPRIMITIVE bits */
+#define BRW_3DPRIMITIVE_VERTEX_SEQUENTIAL (0 << 15)
+#define BRW_3DPRIMITIVE_VERTEX_RANDOM	  (1 << 15)
 /* Primitive types are in brw_defines.h */
-#define P3D0_TOPO_SHIFT			10
+#define BRW_3DPRIMITIVE_TOPOLOGY_SHIFT	  10
+
 /* End regs for broadwater */
 
 
diff --git a/src/i830_video.c b/src/i830_video.c
index dca6a78..225f9a9 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2618,9 +2618,12 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
  * with the base texture coordinate. It was extracted from the Mesa driver
  */
 
-#define SF_KERNEL_NUM_GRF   10
+#define SF_KERNEL_NUM_GRF  10
+#define SF_KERNEL_NUM_URB  8
+#define SF_MAX_THREADS	   
 
 static const CARD32 sf_kernel_static[][4] = {
+#if 0
 /*    send   0 (1) g6<1>F g1.8<0,1,0>F math mlen 1 rlen 1 { align1 +  } */
     { 0x00000031, 0x20c01fbd, 0x00000028, 0x01110081 },
 /*    mov (2) g3.8<1>F g2<2,2,1>F { align1 +  } */
@@ -2655,6 +2658,7 @@ static const CARD32 sf_kernel_static[][4
     { 0x00600041, 0x204077be, 0x008d0120, 0x000000c0 },
 /*    mov (8) m3<1>F g3<8,8,1>F { align1 +  } */
     { 0x00600001, 0x206003be, 0x008d0060, 0x00000000 },
+#endif
 /*    send   0 (8) a0<1>F g0<8,8,1>F urb mlen 4 rlen 0 write +0 transpose used complete EOT{ align1 +  } */
     { 0x00600031, 0x20001fbc, 0x008d0000, 0x8640c800 },
 /*    nop (4) g0<1>UD { align1 +  } */
@@ -2676,6 +2680,8 @@ static const CARD32 sf_kernel_static[][4
 };
 
 #define PS_KERNEL_NUM_GRF   10
+#define PS_KERNEL_NUM_URB   8
+#define WM_MAX_THREADS	MIN(12, PS_KERNEL_NUM_URB / 2)
 
 static const CARD32 ps_kernel_static[][4] = {
 /*    mov (8) m2<1>F g2<16,16,1>UW { align1 +  } */
@@ -2696,7 +2702,8 @@ static const CARD32 ps_kernel_static[][4
    { 0x00601001, 0x2120013e, 0x00b100c0, 0x00000000 },
 /*    mov (8) m1<1>F g1<8,8,1>F { align1 mask_disable +  } */
    { 0x00600201, 0x202003be, 0x008d0020, 0x00000000 },
-/*    send   0 (16) a0<1>UW g0<8,8,1>UW write mlen 10 rlen 0 EOT{ align1 +  } */   { 0x00800031, 0x20001d28, 0x008d0000, 0x85a04800 },
+/*    send   0 (16) a0<1>UW g0<8,8,1>UW write mlen 10 rlen 0 EOT{ align1 +  } */
+   { 0x00800031, 0x20001d28, 0x008d0000, 0x85a04800 },
 /*    nop (4) g0<1>UD { align1 +  } */
    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
 /*    nop (4) g0<1>UD { align1 +  } */
@@ -2749,15 +2756,16 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    struct brw_instruction *ps_kernel;
    CARD32 *vb, *binding_table;
    Bool first_output = TRUE;
-   int surf_state_base_offset, general_state_base_offset;
    int dest_surf_offset, src_surf_offset, src_sampler_offset, vs_offset;
    int sf_offset, wm_offset, cc_offset, vb_offset, cc_viewport_offset;
+   int wm_scratch_offset;
    int sf_kernel_offset, ps_kernel_offset;
    int binding_table_offset;
    int next_offset, total_state_size;
    int vb_size = (4 * 4) * 4; /* 4 DWORDS per vertex */
    FBLinearPtr state_area;
    char *state_base;
+   int state_base_offset;
 
    ErrorF("BroadwaterDisplayVideoTextured: %dx%d (pitch %d)\n", width, height,
 	  video_pitch);
@@ -2774,12 +2782,13 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
 
    /* Set up our layout of state in framebuffer.  First the general state: */
    vs_offset = ALIGN(next_offset, 64);
-   general_state_base_offset = vs_offset;
    next_offset = vs_offset + sizeof(*vs_state);
    sf_offset = ALIGN(next_offset, 32);
    next_offset = sf_offset + sizeof(*sf_state);
    wm_offset = ALIGN(next_offset, 32);
    next_offset = wm_offset + sizeof(*wm_state);
+   wm_scratch_offset = ALIGN(next_offset, 1024);
+   next_offset = wm_scratch_offset + 1024 * WM_MAX_THREADS;
    cc_offset = ALIGN(next_offset, 32);
    next_offset = cc_offset + sizeof(*cc_state);
 
@@ -2800,7 +2809,6 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
 
    /* And then the general state: */
    dest_surf_offset = ALIGN(next_offset, 32);
-   surf_state_base_offset = dest_surf_offset;
    next_offset = dest_surf_offset + sizeof(*dest_surf_state);
    src_surf_offset = ALIGN(next_offset, 32);
    next_offset = src_surf_offset + sizeof(*src_surf_state);
@@ -2809,15 +2817,16 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
 
    /* Allocate an area in framebuffer for our state layout we just set up */
    total_state_size = next_offset;
-   state_area = I830AllocateMemory(pScrn, NULL, (total_state_size + 32) /
+   state_area = I830AllocateMemory(pScrn, NULL, (total_state_size + 64) /
 				   pI830->cpp);
    if (state_area == NULL) {
       ErrorF("Failed to allocate %d bytes for state\n", total_state_size);
       return;
    }
 
-   state_base = (char *)(pI830->FbBase + pPriv->linear->offset *
-			 pI830->cpp);
+   state_base_offset = pI830->FrontBuffer.Start + pPriv->linear->offset * pI830->cpp;
+   state_base_offset = ALIGN(state_base_offset, 64);
+   state_base = (char *)(pI830->FbBase + state_base_offset);
    /* Set up our pointers to state structures in framebuffer.  It would probably
     * be a good idea to fill these structures out in system memory and then dump
     * them there, instead.
@@ -2884,8 +2893,8 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
 
    /* Set up a binding table for our two surfaces.  Only the PS will use it */
    /* XXX: are these offset from the right place? */
-   binding_table[0] = dest_surf_offset - surf_state_base_offset;
-   binding_table[1] = src_surf_offset - surf_state_base_offset;
+   binding_table[0] = state_base_offset + dest_surf_offset;
+   binding_table[1] = state_base_offset + src_surf_offset;
 
    /* Set up the packed YUV source sampler.  Doesn't do colorspace conversion.
     */
@@ -2905,14 +2914,14 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
     */
 
    memset(sf_state, 0, sizeof(*sf_state));
-   sf_state->thread0.kernel_start_pointer = sf_kernel_offset - general_state_base_offset;
+   sf_state->thread0.kernel_start_pointer = state_base_offset + sf_kernel_offset;
    sf_state->thread0.grf_reg_count = ((SF_KERNEL_NUM_GRF + 15) / 16) - 1;
    sf_state->thread1.single_program_flow = 1; /* XXX */
-   sf_state->thread2.scratch_space_base_pointer = 0; /* XXX 1k aligned */
-   sf_state->thread4.nr_urb_entries = 8;
+   sf_state->thread2.per_thread_scratch_space = 0;
+   sf_state->thread2.scratch_space_base_pointer = 0; /* not used in our kernel */
+   sf_state->thread4.nr_urb_entries = SF_KERNEL_NUM_URB;
    sf_state->thread4.urb_entry_allocation_size = 11;
-   sf_state->thread4.max_threads = MIN(12, sf_state->thread4.nr_urb_entries /
-				       2) - 1;
+   sf_state->thread4.max_threads = WM_MAX_THREADS - 1;
    sf_state->sf5.viewport_transform = FALSE; /* skip viewport */
    sf_state->sf6.cull_mode = BRW_CULLMODE_BOTH;
    sf_state->sf6.scissor = 0; /* XXX */
@@ -2933,7 +2942,7 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
     *
     */
 
-   wm_state->thread0.kernel_start_pointer = ps_kernel_offset - general_state_base_offset;
+   wm_state->thread0.kernel_start_pointer = state_base_offset + ps_kernel_offset;
    wm_state->thread0.grf_reg_count = ((PS_KERNEL_NUM_GRF + 15) / 16) - 1;
    wm_state->thread1.binding_table_entry_count = 2;
    wm_state->thread2.scratch_space_base_pointer = 0; /* XXX */
@@ -2941,8 +2950,7 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    wm_state->thread3.dispatch_grf_start_reg = 0; /* XXX */
    wm_state->thread3.urb_entry_read_length = 4; /* XXX */
    wm_state->thread3.const_urb_entry_read_length = 0; /* XXX */
-   wm_state->wm4.sampler_state_pointer =
-	(src_sampler_offset - general_state_base_offset) >> 5;
+   wm_state->wm4.sampler_state_pointer = (state_base_offset + src_sampler_offset) >> 5;
    wm_state->wm4.sampler_count = 1; /* 1-4 samplers used */
    wm_state->wm5.max_threads = 0;
    wm_state->wm5.thread_dispatch_enable = 1;
@@ -2952,8 +2960,7 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    cc_viewport->max_depth = 0.0;
 
    memset(cc_state, 0, sizeof(*cc_state));
-   cc_state->cc4.cc_viewport_state_offset =
-	(cc_viewport_offset - general_state_base_offset) >> 5;
+   cc_state->cc4.cc_viewport_state_offset = (state_base_offset + cc_viewport_offset) >> 5;
 
    memcpy (sf_kernel, sf_kernel_static, sizeof (sf_kernel_static));
    memcpy (ps_kernel, ps_kernel_static, sizeof (ps_kernel_static));
@@ -2961,66 +2968,65 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    BEGIN_LP_RING(38);
    OUT_RING(MI_FLUSH | MI_STATE_INSTRUCTION_CACHE_FLUSH);
 
-   OUT_RING(STATE3D_PIPELINE_SELECT | PIPELINE_SELECT_3D);
+   OUT_RING(BRW_PIPELINE_SELECT | PIPELINE_SELECT_3D);
 
-   OUT_RING(STATE3D_URB_FENCE |
+   OUT_RING(BRW_URB_FENCE |
 	    UF0_CS_REALLOC |
 	    UF0_SF_REALLOC |
 	    UF0_CLIP_REALLOC |
 	    UF0_GS_REALLOC |
-	    UF0_VS_REALLOC);
+	    UF0_VS_REALLOC |
+	    1);
    OUT_RING(((urb_clip_start + urb_clip_size) << UF1_CLIP_FENCE_SHIFT) |
 	    ((urb_gs_start + urb_gs_size) << UF1_GS_FENCE_SHIFT) |
 	    ((urb_vs_start + urb_vs_size) << UF1_VS_FENCE_SHIFT));
    OUT_RING(((urb_cs_start + urb_cs_size) << UF2_CS_FENCE_SHIFT) |
 	    ((urb_sf_start + urb_sf_size) << UF2_SF_FENCE_SHIFT));
 
-   /* Set the general and surface state base addresses */
-   OUT_RING(STATE3D_BASE_ADDRESS | 4);
-   OUT_RING((pPriv->linear->offset * pI830->cpp + general_state_base_offset) |
-	    BASE_ADDRESS_MODIFY);
-   OUT_RING((pPriv->linear->offset * pI830->cpp + surf_state_base_offset) |
-	    BASE_ADDRESS_MODIFY);
+   /* Zero out the two base address registers so all offsets are absolute */
+   OUT_RING(BRW_STATE_BASE_ADDRESS | 4);
+   OUT_RING(0 | BASE_ADDRESS_MODIFY);	/* Generate state base address */
+   OUT_RING(0 | BASE_ADDRESS_MODIFY);	/* Surface state base address */
    OUT_RING(0); /* media base addr, don't care */
    OUT_RING(0); /* general state max addr, disabled */
    OUT_RING(0); /* media object state max addr, disabled */
 
    /* Set the pointers to the 3d pipeline state */
-   OUT_RING(STATE3D_PIPELINED_POINTERS | 5);
-   OUT_RING(vs_offset - general_state_base_offset); /* 32 byte aligned */
-   OUT_RING(0); /* disable GS, resulting in passthrough */
-   OUT_RING(0); /* disable CLIP, resulting in passthrough */
-   OUT_RING(sf_offset - general_state_base_offset); /* 32 byte aligned */
-   OUT_RING(wm_offset - general_state_base_offset); /* 32 byte aligned */
-   OUT_RING(cc_offset - general_state_base_offset); /* 64 byte aligned */
+   OUT_RING(BRW_3DSTATE_PIPELINED_POINTERS | 5);
+   OUT_RING(state_base_offset + vs_offset);  /* 32 byte aligned */
+   OUT_RING(BRW_GS_DISABLE);		     /* disable GS, resulting in passthrough */
+   OUT_RING(BRW_CLIP_DISABLE);		     /* disable CLIP, resulting in passthrough */
+   OUT_RING(state_base_offset + sf_offset);  /* 32 byte aligned */
+   OUT_RING(state_base_offset + wm_offset);  /* 32 byte aligned */
+   OUT_RING(state_base_offset + cc_offset);  /* 64 byte aligned */
 
    /* Only the PS uses the binding table */
-   OUT_RING(STATE3D_BINDING_TABLE_POINTERS | 4);
+   OUT_RING(BRW_3DSTATE_BINDING_TABLE_POINTERS | 4);
    OUT_RING(0); /* vs */
    OUT_RING(0); /* gs */
    OUT_RING(0); /* clip */
    OUT_RING(0); /* sf */
-   OUT_RING(binding_table_offset - surf_state_base_offset); /* ps */
+   OUT_RING(state_base_offset + binding_table_offset); /* ps */
 
    /* The drawing rectangle clipping is always on.  Set it to values that
     * shouldn't do any clipping.
     */
-   OUT_RING(STATE3D_DRAWING_RECTANGLE_BRW | 2);
+   OUT_RING(BRW_3DSTATE_DRAWING_RECTANGLE | 2);	/* XXX 3 for BLC or CTG */
    OUT_RING(0x00000000);	/* ymin, xmin */
    OUT_RING((pScrn->virtualX - 1) |
 	    (pScrn->virtualY - 1) << 16); /* ymax, xmax */
    OUT_RING(0x00000000);	/* yorigin, xorigin */
 
    /* Set up the pointer to our vertex buffer */
-   OUT_RING(STATE3D_VERTEX_BUFFERS | 2);
+   OUT_RING(BRW_3DSTATE_VERTEX_BUFFERS | 2);
    OUT_RING((0 << VB0_BUFFER_INDEX_SHIFT) |
 	    VB0_VERTEXDATA |
-	    (16 << VB0_BUFFER_PITCH_SHIFT));
-   OUT_RING(pPriv->linear->offset * pI830->cpp + vb_offset);
-   OUT_RING(0xffffffff); /* Max index -- don't care */
+	    ((4 * 4) << VB0_BUFFER_PITCH_SHIFT)); /* four 32-bit floats per vertex */
+   OUT_RING(state_base_offset + vb_offset);
+   OUT_RING(4); /* four corners to our rectangle */
 
    /* Set up our vertex elements, sourced from the single vertex buffer. */
-   OUT_RING(STATE3D_VERTEX_ELEMENTS | 3);
+   OUT_RING(BRW_3DSTATE_VERTEX_ELEMENTS | 3);
    /* offset 0: X,Y -> {X, Y, 0.0, 0.0} */
    OUT_RING((0 << VE0_VERTEX_BUFFER_INDEX_SHIFT) |
 	    VE0_VALID |
@@ -3052,10 +3058,10 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    nbox = REGION_NUM_RECTS(dstRegion);
    while (nbox--)
    {
-      int box_x1 = pbox->x1;
-      int box_y1 = pbox->y1;
-      int box_x2 = pbox->x2;
-      int box_y2 = pbox->y2;
+      int box_x1 = pbox->x1 - pbox->x1;
+      int box_y1 = pbox->y1 - pbox->y1;
+      int box_x2 = pbox->x2 - pbox->x1;
+      int box_y2 = pbox->y2 - pbox->y1;
       int i;
       float src_scale_x, src_scale_y;
       CARD32 vb[40];
@@ -3112,8 +3118,12 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
       vb[i++] = (box_y2 - dyo) * src_scale_y;
 
       BEGIN_LP_RING(6);
-      OUT_RING(PRIMITIVE3D_BRW | (_3DPRIM_TRIFAN << P3D0_TOPO_SHIFT) | 4);
-      OUT_RING(4); /* vertex count per instance */
+      OUT_RING(BRW_3DPRIMITIVE | 
+	       BRW_3DPRIMITIVE_VERTEX_SEQUENTIAL |
+	       (_3DPRIM_TRIFAN << BRW_3DPRIMITIVE_TOPOLOGY_SHIFT) | 
+	       (0 << 9) |
+	       4);
+      OUT_RING(4); /* vertex count per instance XXX should this be 3 or 6? */
       OUT_RING(0); /* start vertex offset */
       OUT_RING(1); /* single instance */
       OUT_RING(0); /* start instance location */
diff-tree 9ec7cf22e3f03c13524bb2d15711699dfcc02984 (from f5fe700b9a943c956bcfcc3a0d2de13c23b978bc)
Author: Keith his master's voice Packard <keithp at bw.jf.intel.com>
Date:   Fri May 26 21:30:55 2006 -0700

    Use broadwater video code on broadwater hardware. Pad ring to even length. compute state base as address rather than offset

diff --git a/src/i830_video.c b/src/i830_video.c
index bc97ee2..dca6a78 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -66,6 +66,7 @@ THE USE OR OTHER DEALINGS IN THE SOFTWAR
 
 #include <math.h>
 #include <string.h>
+#include <assert.h>
 
 #include "xf86.h"
 #include "xf86_OSproc.h"
@@ -2714,6 +2715,9 @@ static const CARD32 ps_kernel_static[][4
    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
 };
 
+#define ALIGN(i,m)    (((i) + (m) - 1) & ~((m) - 1))
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+
 static void
 BroadwaterDisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
 			       RegionPtr dstRegion,
@@ -2812,7 +2816,7 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
       return;
    }
 
-   state_base = (char *)(pI830->FrontBuffer.Start + pPriv->linear->offset *
+   state_base = (char *)(pI830->FbBase + pPriv->linear->offset *
 			 pI830->cpp);
    /* Set up our pointers to state structures in framebuffer.  It would probably
     * be a good idea to fill these structures out in system memory and then dump
@@ -2954,7 +2958,7 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    memcpy (sf_kernel, sf_kernel_static, sizeof (sf_kernel_static));
    memcpy (ps_kernel, ps_kernel_static, sizeof (ps_kernel_static));
    
-   BEGIN_LP_RING(17);
+   BEGIN_LP_RING(38);
    OUT_RING(MI_FLUSH | MI_STATE_INSTRUCTION_CACHE_FLUSH);
 
    OUT_RING(STATE3D_PIPELINE_SELECT | PIPELINE_SELECT_3D);
@@ -3038,6 +3042,7 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
 	    (BRW_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_3_SHIFT) |
 	    (4 << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT));
 
+   OUT_RING(0);			/* pad to quadword */
    ADVANCE_LP_RING();
 
    dxo = dstRegion->extents.x1;
@@ -3085,6 +3090,7 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
       OUT_RING(MI_NOOP);
       OUT_RING(MI_NOOP);
 
+      i = 0;
       vb[i++] = box_x1;
       vb[i++] = box_y1;
       vb[i++] = (box_x1 - dxo) * src_scale_x;
@@ -3407,6 +3413,10 @@ I830PutImage(ScrnInfoPtr pScrn,
 
       I830DisplayVideo(pScrn, destId, width, height, dstPitch,
 		       x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h);
+   } else if (IS_BROADWATER(pI830)) {
+      BroadwaterDisplayVideoTextured (pScrn, pPriv, destId, clipBoxes, width, height,
+				      dstPitch, x1, y1, x2, y2,
+				      src_w, src_h, drw_w, drw_h, pDraw);
    } else {
       I915DisplayVideoTextured(pScrn, pPriv, destId, clipBoxes, width, height,
 			       dstPitch, x1, y1, x2, y2,
diff-tree f5fe700b9a943c956bcfcc3a0d2de13c23b978bc (from 1549accb6f52498fef3dcbd87bb72d89fcd5bccd)
Author: Keith his master's voice Packard <keithp at bw.jf.intel.com>
Date:   Fri May 26 13:47:39 2006 -0700

    Prepare real SF kernel and fake WM kernel

diff --git a/src/i830_video.c b/src/i830_video.c
index 054a9f9..bc97ee2 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2612,52 +2612,106 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
       pI830->AccelInfoRec->NeedToSync = TRUE;
 }
 
-static const struct brw_instruction sf_kernel_static[] = {
-   {
-      header: {
-	 opcode: BRW_OPCODE_SEND
-      },
-      bits1: { da1: {
-	 dest_reg_file: BRW_MESSAGE_REGISTER_FILE,
-	 dest_reg_type: BRW_REGISTER_TYPE_D,
-	 src0_reg_file: BRW_IMMEDIATE_VALUE,
-	 src1_reg_file: BRW_ARCHITECTURE_REGISTER_FILE,
-	 src1_reg_type: BRW_REGISTER_TYPE_D,
-	 dest_subreg_nr: 0,
-	 dest_reg_nr: 0,
-	 dest_horiz_stride: 1,
-	 dest_address_mode: BRW_ADDRESS_DIRECT
-      } },
-      bits2: { da1: {
-      } },
-      bits3: { generic: {
-	 end_of_thread: 1
-      } }
-   }
+/*
+ * this program computes dA/dx and dA/dy for the texture coordinates along
+ * with the base texture coordinate. It was extracted from the Mesa driver
+ */
+
+#define SF_KERNEL_NUM_GRF   10
+
+static const CARD32 sf_kernel_static[][4] = {
+/*    send   0 (1) g6<1>F g1.8<0,1,0>F math mlen 1 rlen 1 { align1 +  } */
+    { 0x00000031, 0x20c01fbd, 0x00000028, 0x01110081 },
+/*    mov (2) g3.8<1>F g2<2,2,1>F { align1 +  } */
+    { 0x00200001, 0x206803bd, 0x00450040, 0x00000000 },
+/*    mov (2) g4.8<1>F g2.8<2,2,1>F { align1 +  } */
+    { 0x00200001, 0x208803bd, 0x00450048, 0x00000000 },
+/*    mov (2) g5.8<1>F g2.16<2,2,1>F { align1 +  } */
+    { 0x00200001, 0x20a803bd, 0x00450050, 0x00000000 },
+/*    mov (1) a48<1>UW 240 { align1 +  } */
+    { 0x00000001, 0x26002168, 0x00000000, 0x000000f0 },
+/*    mul (8) g3<1>F g3<8,8,1>F g2.4<0,1,0>F { align1 predreg+  } */
+    { 0x00610041, 0x206077bd, 0x008d0060, 0x00000044 },
+/*    mul (8) g4<1>F g4<8,8,1>F g2.12<0,1,0>F { align1 predreg+  } */
+    { 0x00610041, 0x208077bd, 0x008d0080, 0x0000004c },
+/*    mul (8) g5<1>F g5<8,8,1>F g2.20<0,1,0>F { align1 predreg+  } */
+    { 0x00610041, 0x20a077bd, 0x008d00a0, 0x00000054 },
+/*    add (8) g7<1>F g4<8,8,1>F g3<8,8,1>F { align1 +  } */
+    { 0x00600040, 0x20e077bd, 0x008d0080, 0x008d4060 },
+/*    add (8) g8<1>F g5<8,8,1>F g3<8,8,1>F { align1 +  } */
+    { 0x00600040, 0x210077bd, 0x008d00a0, 0x008d4060 },
+/*    mul (8) a0<1>F g7<8,8,1>F g1.24<0,1,0>F { align1 +  } */
+    { 0x00600041, 0x200077bc, 0x008d00e0, 0x00000038 },
+/*    mac (8) g9<1>F g8<8,8,1>F g1.20<0,1,0>F { align1 +  } */
+    { 0x00600048, 0x212077bd, 0x008d0100, 0x00004034 },
+/*    mul (8) m1<1>F g9<8,8,1>F g6<0,1,0>F { align1 +  } */
+    { 0x00600041, 0x202077be, 0x008d0120, 0x000000c0 },
+/*    mul (8) a0<1>F g8<8,8,1>F g1.12<0,1,0>F { align1 +  } */
+    { 0x00600041, 0x200077bc, 0x008d0100, 0x0000002c },
+/*    mac (8) g9<1>F g7<8,8,1>F g1.16<0,1,0>F { align1 +  } */
+    { 0x00600048, 0x212077bd, 0x008d00e0, 0x00004030 },
+/*    mul (8) m2<1>F g9<8,8,1>F g6<0,1,0>F { align1 +  } */
+    { 0x00600041, 0x204077be, 0x008d0120, 0x000000c0 },
+/*    mov (8) m3<1>F g3<8,8,1>F { align1 +  } */
+    { 0x00600001, 0x206003be, 0x008d0060, 0x00000000 },
+/*    send   0 (8) a0<1>F g0<8,8,1>F urb mlen 4 rlen 0 write +0 transpose used complete EOT{ align1 +  } */
+    { 0x00600031, 0x20001fbc, 0x008d0000, 0x8640c800 },
+/*    nop (4) g0<1>UD { align1 +  } */
+    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
 };
 
-static const struct brw_instruction ps_kernel_static[] = {
-    {
-	header: {
-	    opcode: BRW_OPCODE_SEND
-	},
-	bits1: { da1: {
-	    dest_reg_file: BRW_MESSAGE_REGISTER_FILE,
-	    dest_reg_type: BRW_REGISTER_TYPE_D,
-	    src0_reg_file: BRW_IMMEDIATE_VALUE,
-	    src1_reg_file: BRW_ARCHITECTURE_REGISTER_FILE,
-	    src1_reg_type: BRW_REGISTER_TYPE_D,
-	    dest_subreg_nr: 0,
-	    dest_reg_nr: 0,
-	    dest_horiz_stride: 1,
-	    dest_address_mode: BRW_ADDRESS_DIRECT
-	} },
-	bits2: { da1: {
-	} },
-	bits3: { generic: {
-	    end_of_thread: 1
-	} }
-    }
+#define PS_KERNEL_NUM_GRF   10
+
+static const CARD32 ps_kernel_static[][4] = {
+/*    mov (8) m2<1>F g2<16,16,1>UW { align1 +  } */
+   { 0x00600001, 0x2040013e, 0x00b10040, 0x00000000 },
+/*    mov (8) m6<1>F g3<16,16,1>UW { align1 sechalf +  } */
+   { 0x00601001, 0x20c0013e, 0x00b10060, 0x00000000 },
+/*    mov (8) m3<1>F g3<16,16,1>UW { align1 +  } */
+   { 0x00600001, 0x2060013e, 0x00b10060, 0x00000000 },
+/*    mov (8) m7<1>F g4<16,16,1>UW { align1 sechalf +  } */
+   { 0x00601001, 0x20e0013e, 0x00b10080, 0x00000000 },
+/*    mov (8) m4<1>F g4<16,16,1>UW { align1 +  } */
+   { 0x00600001, 0x2080013e, 0x00b10080, 0x00000000 },
+/*    mov (8) m8<1>F g5<16,16,1>UW { align1 sechalf +  } */
+   { 0x00601001, 0x2100013e, 0x00b100a0, 0x00000000 },
+/*    mov (8) m5<1>F g5<16,16,1>UW { align1 +  } */
+   { 0x00600001, 0x20a0013e, 0x00b100a0, 0x00000000 },
+/*    mov (8) m9<1>F g6<16,16,1>UW { align1 sechalf +  } */
+   { 0x00601001, 0x2120013e, 0x00b100c0, 0x00000000 },
+/*    mov (8) m1<1>F g1<8,8,1>F { align1 mask_disable +  } */
+   { 0x00600201, 0x202003be, 0x008d0020, 0x00000000 },
+/*    send   0 (16) a0<1>UW g0<8,8,1>UW write mlen 10 rlen 0 EOT{ align1 +  } */   { 0x00800031, 0x20001d28, 0x008d0000, 0x85a04800 },
+/*    nop (4) g0<1>UD { align1 +  } */
+   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
 };
 
 static void
@@ -2826,8 +2880,8 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
 
    /* Set up a binding table for our two surfaces.  Only the PS will use it */
    /* XXX: are these offset from the right place? */
-   binding_table[0] = dest_surf_state_offset - surf_state_base_offset;
-   binding_table[1] = src_surf_state_offset - surf_state_base_offset;
+   binding_table[0] = dest_surf_offset - surf_state_base_offset;
+   binding_table[1] = src_surf_offset - surf_state_base_offset;
 
    /* Set up the packed YUV source sampler.  Doesn't do colorspace conversion.
     */
@@ -2841,23 +2895,23 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    memset(vs_state, 0, sizeof(*vs_state));
    vs_state->vs6.vs_enable = FALSE;
 
-   /* XXX: Set up the SF kernel to do coord interp: for each attribute,
+   /* Set up the SF kernel to do coord interp: for each attribute,
     * calculate dA/dx and dA/dy.  Hand these interpolation coefficients
     * back to SF which then hands pixels off to WM.
     */
 
    memset(sf_state, 0, sizeof(*sf_state));
-   sf_state->thread0.kernel_start_pointer = XXX;
-   sf_state->thread0.grf_reg_count = XXX;
-   sf_state->thread1.single_program_flow = XXX;
-   sf_state->thread2.scratch_space_base_pointer = XXX; /* 1k aligned */
+   sf_state->thread0.kernel_start_pointer = sf_kernel_offset - general_state_base_offset;
+   sf_state->thread0.grf_reg_count = ((SF_KERNEL_NUM_GRF + 15) / 16) - 1;
+   sf_state->thread1.single_program_flow = 1; /* XXX */
+   sf_state->thread2.scratch_space_base_pointer = 0; /* XXX 1k aligned */
    sf_state->thread4.nr_urb_entries = 8;
    sf_state->thread4.urb_entry_allocation_size = 11;
    sf_state->thread4.max_threads = MIN(12, sf_state->thread4.nr_urb_entries /
 				       2) - 1;
    sf_state->sf5.viewport_transform = FALSE; /* skip viewport */
    sf_state->sf6.cull_mode = BRW_CULLMODE_BOTH;
-   sf_state->sf6.scissor = XXX;
+   sf_state->sf6.scissor = 0; /* XXX */
    sf_state->sf6.dest_org_vbias = 0x8;
    sf_state->sf6.dest_org_hbias = 0x8;
    sf_state->sf7.trifan_pv = 2;
@@ -2875,18 +2929,18 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
     *
     */
 
-   wm_state->thread0.kernel_start_pointer = XXX;
-   wm_state->thread0.grf_reg_count = XXX;
+   wm_state->thread0.kernel_start_pointer = ps_kernel_offset - general_state_base_offset;
+   wm_state->thread0.grf_reg_count = ((PS_KERNEL_NUM_GRF + 15) / 16) - 1;
    wm_state->thread1.binding_table_entry_count = 2;
-   wm_state->thread2.scratch_space_base_pointer = XXX;
-   wm_state->thread2.per_thread_scratch_space = XXX;
-   wm_state->thread3.dispatch_grf_start_reg = XXX;
-   wm_state->thread3.urb_entry_read_length = XXX;
-   wm_state->thread3.const_urb_entry_read_length = XXX;
+   wm_state->thread2.scratch_space_base_pointer = 0; /* XXX */
+   wm_state->thread2.per_thread_scratch_space = 0; /* XXX */
+   wm_state->thread3.dispatch_grf_start_reg = 0; /* XXX */
+   wm_state->thread3.urb_entry_read_length = 4; /* XXX */
+   wm_state->thread3.const_urb_entry_read_length = 0; /* XXX */
    wm_state->wm4.sampler_state_pointer =
 	(src_sampler_offset - general_state_base_offset) >> 5;
    wm_state->wm4.sampler_count = 1; /* 1-4 samplers used */
-   wm_state->wm5.max_threads = 31;
+   wm_state->wm5.max_threads = 0;
    wm_state->wm5.thread_dispatch_enable = 1;
    wm_state->wm5.enable_16_pix = 1;
 
@@ -2962,7 +3016,7 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    OUT_RING(0xffffffff); /* Max index -- don't care */
 
    /* Set up our vertex elements, sourced from the single vertex buffer. */
-   OUT_RING(STATE3D_VERTEX_ELEMENTS | XXX);
+   OUT_RING(STATE3D_VERTEX_ELEMENTS | 3);
    /* offset 0: X,Y -> {X, Y, 0.0, 0.0} */
    OUT_RING((0 << VE0_VERTEX_BUFFER_INDEX_SHIFT) |
 	    VE0_VALID |
@@ -3051,7 +3105,7 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
       vb[i++] = (box_x1 - dxo) * src_scale_x;
       vb[i++] = (box_y2 - dyo) * src_scale_y;
 
-      BEGIN_LP_RING(XXX);
+      BEGIN_LP_RING(6);
       OUT_RING(PRIMITIVE3D_BRW | (_3DPRIM_TRIFAN << P3D0_TOPO_SHIFT) | 4);
       OUT_RING(4); /* vertex count per instance */
       OUT_RING(0); /* start vertex offset */
diff-tree 1549accb6f52498fef3dcbd87bb72d89fcd5bccd (from bce209cd3f60cb5d51aadc5fc8ec1a4151435ec3)
Author: Keith his master's voice Packard <keithp at bw.jf.intel.com>
Date:   Thu May 25 16:10:31 2006 -0700

    Scale video source vertices. Allocate space for kernels

diff --git a/src/i830_video.c b/src/i830_video.c
index aa263b1..054a9f9 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2612,6 +2612,54 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
       pI830->AccelInfoRec->NeedToSync = TRUE;
 }
 
+static const struct brw_instruction sf_kernel_static[] = {
+   {
+      header: {
+	 opcode: BRW_OPCODE_SEND
+      },
+      bits1: { da1: {
+	 dest_reg_file: BRW_MESSAGE_REGISTER_FILE,
+	 dest_reg_type: BRW_REGISTER_TYPE_D,
+	 src0_reg_file: BRW_IMMEDIATE_VALUE,
+	 src1_reg_file: BRW_ARCHITECTURE_REGISTER_FILE,
+	 src1_reg_type: BRW_REGISTER_TYPE_D,
+	 dest_subreg_nr: 0,
+	 dest_reg_nr: 0,
+	 dest_horiz_stride: 1,
+	 dest_address_mode: BRW_ADDRESS_DIRECT
+      } },
+      bits2: { da1: {
+      } },
+      bits3: { generic: {
+	 end_of_thread: 1
+      } }
+   }
+};
+
+static const struct brw_instruction ps_kernel_static[] = {
+    {
+	header: {
+	    opcode: BRW_OPCODE_SEND
+	},
+	bits1: { da1: {
+	    dest_reg_file: BRW_MESSAGE_REGISTER_FILE,
+	    dest_reg_type: BRW_REGISTER_TYPE_D,
+	    src0_reg_file: BRW_IMMEDIATE_VALUE,
+	    src1_reg_file: BRW_ARCHITECTURE_REGISTER_FILE,
+	    src1_reg_type: BRW_REGISTER_TYPE_D,
+	    dest_subreg_nr: 0,
+	    dest_reg_nr: 0,
+	    dest_horiz_stride: 1,
+	    dest_address_mode: BRW_ADDRESS_DIRECT
+	} },
+	bits2: { da1: {
+	} },
+	bits3: { generic: {
+	    end_of_thread: 1
+	} }
+    }
+};
+
 static void
 BroadwaterDisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
 			       RegionPtr dstRegion,
@@ -2639,11 +2687,14 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    struct brw_wm_unit_state *wm_state;
    struct brw_cc_unit_state *cc_state;
    struct brw_cc_viewport *cc_viewport;
+   struct brw_instruction *sf_kernel;
+   struct brw_instruction *ps_kernel;
    CARD32 *vb, *binding_table;
    Bool first_output = TRUE;
    int surf_state_base_offset, general_state_base_offset;
    int dest_surf_offset, src_surf_offset, src_sampler_offset, vs_offset;
    int sf_offset, wm_offset, cc_offset, vb_offset, cc_viewport_offset;
+   int sf_kernel_offset, ps_kernel_offset;
    int binding_table_offset;
    int next_offset, total_state_size;
    int vb_size = (4 * 4) * 4; /* 4 DWORDS per vertex */
@@ -2674,8 +2725,11 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    cc_offset = ALIGN(next_offset, 32);
    next_offset = cc_offset + sizeof(*cc_state);
 
-   /* XXX: Add space for SF and PS kernels */
-
+   sf_kernel_offset = ALIGN(next_offset, 64);
+   next_offset = sf_kernel_offset + sizeof (sf_kernel_static);
+   ps_kernel_offset = ALIGN(next_offset, 64);
+   next_offset = ps_kernel_offset + sizeof (ps_kernel_static);
+   
    cc_viewport_offset = ALIGN(next_offset, 32);
    next_offset = cc_viewport_offset + sizeof(*cc_viewport);
 
@@ -2714,6 +2768,8 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    sf_state = (void *)(state_base + sf_offset);
    wm_state = (void *)(state_base + wm_offset);
    cc_state = (void *)(state_base + cc_offset);
+   sf_kernel = (void *)(state_base + sf_kernel_offset);
+   ps_kernel = (void *)(state_base + ps_kernel_offset);
    cc_viewport = (void *)(state_base + cc_viewport_offset);
    dest_surf_state = (void *)(state_base + dest_surf_offset);
    src_surf_state = (void *)(state_base + src_surf_offset);
@@ -2801,12 +2857,12 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
 				       2) - 1;
    sf_state->sf5.viewport_transform = FALSE; /* skip viewport */
    sf_state->sf6.cull_mode = BRW_CULLMODE_BOTH;
-   sf_state->sf6.scissor =
+   sf_state->sf6.scissor = XXX;
    sf_state->sf6.dest_org_vbias = 0x8;
    sf_state->sf6.dest_org_hbias = 0x8;
    sf_state->sf7.trifan_pv = 2;
 
-   /* XXX: Set up the PS kernel (dispatched by WM) for convertiny YUV to RGB.
+   /* XXX: Set up the PS kernel (dispatched by WM) for converting YUV to RGB.
     * The 3D driver does this as:
     *
 	 CONST C0 = { -.5, -.0625,  -.5, 1.164 }
@@ -2841,7 +2897,10 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    cc_state->cc4.cc_viewport_state_offset =
 	(cc_viewport_offset - general_state_base_offset) >> 5;
 
-   BEGIN_LP_RING(XXX);
+   memcpy (sf_kernel, sf_kernel_static, sizeof (sf_kernel_static));
+   memcpy (ps_kernel, ps_kernel_static, sizeof (ps_kernel_static));
+   
+   BEGIN_LP_RING(17);
    OUT_RING(MI_FLUSH | MI_STATE_INSTRUCTION_CACHE_FLUSH);
 
    OUT_RING(STATE3D_PIPELINE_SELECT | PIPELINE_SELECT_3D);
@@ -2974,23 +3033,23 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
 
       vb[i++] = box_x1;
       vb[i++] = box_y1;
-      vb[i++] = box_x1 - dxo;
-      vb[i++] = box_y1 - dyo;
+      vb[i++] = (box_x1 - dxo) * src_scale_x;
+      vb[i++] = (box_y1 - dyo) * src_scale_y;
 
       vb[i++] = box_x2;
       vb[i++] = box_y1;
-      vb[i++] = box_x2 - dxo;
-      vb[i++] = box_y1 - dyo;
+      vb[i++] = (box_x2 - dxo) * src_scale_x;
+      vb[i++] = (box_y1 - dyo) * src_scale_y;
 
       vb[i++] = box_x2;
       vb[i++] = box_y2;
-      vb[i++] = box_x2 - dxo;
-      vb[i++] = box_y2 - dyo;
+      vb[i++] = (box_x2 - dxo) * src_scale_x;
+      vb[i++] = (box_y2 - dyo) * src_scale_y;
 
       vb[i++] = box_x1;
       vb[i++] = box_y2;
-      vb[i++] = box_x1 - dxo;
-      vb[i++] = box_y2 - dyo;
+      vb[i++] = (box_x1 - dxo) * src_scale_x;
+      vb[i++] = (box_y2 - dyo) * src_scale_y;
 
       BEGIN_LP_RING(XXX);
       OUT_RING(PRIMITIVE3D_BRW | (_3DPRIM_TRIFAN << P3D0_TOPO_SHIFT) | 4);
diff --git a/src/intel_acpi.c b/src/intel_acpi.c
index 1cd6c97..51331fa 100644
--- a/src/intel_acpi.c
+++ b/src/intel_acpi.c
@@ -113,8 +113,10 @@ I830HandlePMEvents(int fd, pointer data)
     pmEvent events[MAX_NO_EVENTS];
     int i,j,n;
 
+#if 0
     if (!I830ACPIGetEventFromOs)
 	return;
+#endif
 
     if ((n = I830ACPIGetEventFromOs(fd,events,MAX_NO_EVENTS))) {
 	do {
diff-tree 2a1b3cfccb7de53f7ce8f9e4816e4278afb1fcab (from c2cd10e1fba0e75c0ed3db5d17211bddf7ab1e33)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Mon May 22 10:32:13 2006 -0700

    Use RECTLIST instead of TRIFAN for video so we get horizontal shearing instead
    of diagonal.  Also remove the unnecessary vertex elements that were being
    emitted.

diff --git a/src/i830_video.c b/src/i830_video.c
index a41db5c..37dcaa7 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2025,70 +2025,6 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int 
    OVERLAY_UPDATE;
 }
 
-/* Doesn't matter on the order for our purposes */
-typedef struct {
-   unsigned char red, green, blue, alpha;
-} intel_color_t;
-
-/* Vertex format */
-typedef union {
-   struct {
-      float x, y, z, w;
-      intel_color_t color;
-      intel_color_t specular;
-      float u0, v0;
-      float u1, v1;
-      float u2, v2;
-      float u3, v3;
-   } v;
-   float f[24];
-   unsigned int  ui[24];
-   unsigned char ub4[24][4];
-} intelVertex, *intelVertexPtr;
-
-static void draw_poly(CARD32 *vb,
-                      float verts[][2],
-                      float texcoords[][2],
-		      float texcoords2[][2])
-{
-   int vertex_size;
-   intelVertex tmp;
-   int i, k;
-
-   if (texcoords2 != NULL)
-      vertex_size = 10;
-   else
-      vertex_size = 8;
-   
-   /* initial constant vertex fields */
-   tmp.v.z = 1.0;
-   tmp.v.w = 1.0; 
-   tmp.v.color.red = 255;
-   tmp.v.color.green = 255;
-   tmp.v.color.blue = 255;
-   tmp.v.color.alpha = 255;
-   tmp.v.specular.red = 0;
-   tmp.v.specular.green = 0;
-   tmp.v.specular.blue = 0;
-   tmp.v.specular.alpha = 0;
-
-   for (k = 0; k < 4; k++) {
-      tmp.v.x = verts[k][0];
-      tmp.v.y = verts[k][1];
-      tmp.v.u0 = texcoords[k][0];
-      tmp.v.v0 = texcoords[k][1];
-      if (texcoords2 != NULL) {
-	 tmp.v.u1 = texcoords2[k][0];
-	 tmp.v.v1 = texcoords2[k][1];
-      }
-
-      for (i = 0 ; i < vertex_size ; i++)
-         vb[i] = tmp.ui[i];
-
-      vb += vertex_size;
-   }
-}
-
 union intfloat {
    CARD32 ui;
    float f;
@@ -2275,7 +2211,7 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
       S2_TEXCOORD_FMT(7, TEXCOORDFMT_NOT_PRESENT);
    OUT_RING(s2);
    OUT_RING((1 << S4_POINT_WIDTH_SHIFT) | S4_LINE_WIDTH_ONE |
-	    S4_CULLMODE_NONE | S4_VFMT_SPEC_FOG | S4_VFMT_COLOR | S4_VFMT_XYZW);
+	    S4_CULLMODE_NONE | S4_VFMT_XY);
    OUT_RING(0x00000000); /* S5 - enable bits */
    OUT_RING((2 << S6_DEPTH_TEST_FUNC_SHIFT) |
 	    (2 << S6_CBUF_SRC_BLEND_FACT_SHIFT) |
@@ -2512,10 +2448,7 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
       int box_y1 = pbox->y1;
       int box_x2 = pbox->x2;
       int box_y2 = pbox->y2;
-      int j;
       float src_scale_x, src_scale_y;
-      CARD32 vb[40];
-      float verts[4][2], tex[4][2], tex2[4][2];
       int vert_data_count;
 
       pbox++;
@@ -2524,9 +2457,9 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
       src_scale_y  = (float)src_h / (float)drw_h;
 
       if (!planar)
-	 vert_data_count = 32;
+	 vert_data_count = 12;
       else
-	 vert_data_count = 40;
+	 vert_data_count = 18;
 
       BEGIN_LP_RING(vert_data_count + 8);
       OUT_RING(MI_NOOP);
@@ -2537,48 +2470,49 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
       OUT_RING(MI_NOOP);
       OUT_RING(MI_NOOP);
 
-      /* vertex data */
-      OUT_RING(PRIMITIVE3D | PRIM3D_INLINE | PRIM3D_TRIFAN |
+      /* vertex data - rect list consists of bottom right, bottom left, and top
+       * left vertices.
+       */
+      OUT_RING(PRIMITIVE3D | PRIM3D_INLINE | PRIM3D_RECTLIST |
 	       (vert_data_count - 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;
-      verts[3][0] = box_x1; verts[3][1] = box_y2;
 
+      /* bottom right */
+      OUT_RING_F(box_x2);
+      OUT_RING_F(box_y2);
+      if (!planar) {
+	 OUT_RING_F((box_x2 - dxo) * src_scale_x);
+	 OUT_RING_F((box_y2 - dyo) * src_scale_y);
+      } else {
+	 OUT_RING_F((box_x2 - dxo) * src_scale_x / 2.0);
+	 OUT_RING_F((box_y2 - dyo) * src_scale_y / 2.0);
+	 OUT_RING_F((box_x2 - dxo) * src_scale_x);
+	 OUT_RING_F((box_y2 - dyo) * src_scale_y);
+      }
+
+      /* bottom left */
+      OUT_RING_F(box_x1);
+      OUT_RING_F(box_y2);
+      if (!planar) {
+	 OUT_RING_F((box_x1 - dxo) * src_scale_x);
+	 OUT_RING_F((box_y2 - dyo) * src_scale_y);
+      } else {
+	 OUT_RING_F((box_x1 - dxo) * src_scale_x / 2.0);
+	 OUT_RING_F((box_y2 - dyo) * src_scale_y / 2.0);
+	 OUT_RING_F((box_x1 - dxo) * src_scale_x);
+	 OUT_RING_F((box_y2 - dyo) * src_scale_y);
+      }
+
+      /* top left */
+      OUT_RING_F(box_x1);
+      OUT_RING_F(box_y1);
       if (!planar) {
-	 tex[0][0] = (box_x1 - dxo) * src_scale_x;
-	 tex[0][1] = (box_y1 - dyo) * src_scale_y;
-	 tex[1][0] = (box_x2 - dxo) * src_scale_x;
-	 tex[1][1] = (box_y1 - dyo) * src_scale_y;
-	 tex[2][0] = (box_x2 - dxo) * src_scale_x;
-	 tex[2][1] = (box_y2 - dyo) * src_scale_y;
-	 tex[3][0] = (box_x1 - dxo) * src_scale_x;
-	 tex[3][1] = (box_y2 - dyo) * src_scale_y;
-	 /* emit vertex buffer */
-	 draw_poly(vb, verts, tex, NULL);
-	 for (j = 0; j < vert_data_count; j++)
-	    OUT_RING(vb[j]);
+	 OUT_RING_F((box_x1 - dxo) * src_scale_x);
+	 OUT_RING_F((box_y1 - dyo) * src_scale_y);
       } else {
-	 tex[0][0] = (box_x1 - dxo) * src_scale_x / 2.0;
-	 tex[0][1] = (box_y1 - dyo) * src_scale_y / 2.0;
-	 tex[1][0] = (box_x2 - dxo) * src_scale_x / 2.0;
-	 tex[1][1] = (box_y1 - dyo) * src_scale_y / 2.0;
-	 tex[2][0] = (box_x2 - dxo) * src_scale_x / 2.0;
-	 tex[2][1] = (box_y2 - dyo) * src_scale_y / 2.0;
-	 tex[3][0] = (box_x1 - dxo) * src_scale_x / 2.0;
-	 tex[3][1] = (box_y2 - dyo) * src_scale_y / 2.0;
-	 tex2[0][0] = (box_x1 - dxo) * src_scale_x;
-	 tex2[0][1] = (box_y1 - dyo) * src_scale_y;
-	 tex2[1][0] = (box_x2 - dxo) * src_scale_x;
-	 tex2[1][1] = (box_y1 - dyo) * src_scale_y;
-	 tex2[2][0] = (box_x2 - dxo) * src_scale_x;
-	 tex2[2][1] = (box_y2 - dyo) * src_scale_y;
-	 tex2[3][0] = (box_x1 - dxo) * src_scale_x;
-	 tex2[3][1] = (box_y2 - dyo) * src_scale_y;
-	 /* emit vertex buffer */
-	 draw_poly(vb, verts, tex, tex2);
-	 for (j = 0; j < vert_data_count; j++)
-	    OUT_RING(vb[j]);
+	 OUT_RING_F((box_x1 - dxo) * src_scale_x / 2.0);
+	 OUT_RING_F((box_y1 - dyo) * src_scale_y / 2.0);
+	 OUT_RING_F((box_x1 - dxo) * src_scale_x);
+	 OUT_RING_F((box_y1 - dyo) * src_scale_y);
       }
 
       ADVANCE_LP_RING();
diff-tree bce209cd3f60cb5d51aadc5fc8ec1a4151435ec3 (from 3640117bd9f2073ff54dc474f0cdefff49742584)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Fri May 19 17:13:37 2006 -0700

    Put in code for idling accelerator on subsequent cliprects.

diff --git a/src/i830_video.c b/src/i830_video.c
index 27d6c79..aa263b1 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2945,7 +2945,13 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
       int vert_data_count;
 
       if (!first_output) {
-	 /* XXX: idle */
+	 /* Since we use the same little vertex buffer over and over, sync for
+	  * subsequent rectangles.
+	  */
+	 if (pI830->AccelInfoRec && pI830->AccelInfoRec->NeedToSync) {
+	    (*pI830->AccelInfoRec->Sync)(pScrn);
+	    pI830->AccelInfoRec->NeedToSync = FALSE;
+	 }
       }
 
       pbox++;
diff-tree 3640117bd9f2073ff54dc474f0cdefff49742584 (from de06cd70a9edb8b56d05d3f505137f7c7f083c2f)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Fri May 19 17:10:04 2006 -0700

    Set up the state buffer in framebuffer.

diff --git a/src/i830_video.c b/src/i830_video.c
index 9b60112..27d6c79 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -119,6 +119,9 @@ static int I830QueryImageAttributesTextu
 
 static void I830BlockHandler(int, pointer, pointer, pointer);
 
+static FBLinearPtr
+I830AllocateMemory(ScrnInfoPtr pScrn, FBLinearPtr linear, int size);
+
 #define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
 
 static Atom xvBrightness, xvContrast, xvColorKey, xvPipe, xvDoubleBuffer;
@@ -2115,14 +2118,6 @@ union intfloat {
    float f;
 };
 
-static inline CARD32 float_as_int(float f)
-{
-   union intfloat tmp;
-
-   tmp.f = f;
-   return tmp.ui;
-}
-
 #define OUT_RING_F(x) do {						\
    union intfloat _tmp;							\
    _tmp.f = x;								\
@@ -2643,8 +2638,17 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    struct brw_sf_unit_state *sf_state;
    struct brw_wm_unit_state *wm_state;
    struct brw_cc_unit_state *cc_state;
-   CARD32 *vb, *cc_viewport, *binding_table;
+   struct brw_cc_viewport *cc_viewport;
+   CARD32 *vb, *binding_table;
    Bool first_output = TRUE;
+   int surf_state_base_offset, general_state_base_offset;
+   int dest_surf_offset, src_surf_offset, src_sampler_offset, vs_offset;
+   int sf_offset, wm_offset, cc_offset, vb_offset, cc_viewport_offset;
+   int binding_table_offset;
+   int next_offset, total_state_size;
+   int vb_size = (4 * 4) * 4; /* 4 DWORDS per vertex */
+   FBLinearPtr state_area;
+   char *state_base;
 
    ErrorF("BroadwaterDisplayVideoTextured: %dx%d (pitch %d)\n", width, height,
 	  video_pitch);
@@ -2657,6 +2661,66 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
     */
    *pI830->used3D |= 1 << 30;
 
+   next_offset = 0;
+
+   /* Set up our layout of state in framebuffer.  First the general state: */
+   vs_offset = ALIGN(next_offset, 64);
+   general_state_base_offset = vs_offset;
+   next_offset = vs_offset + sizeof(*vs_state);
+   sf_offset = ALIGN(next_offset, 32);
+   next_offset = sf_offset + sizeof(*sf_state);
+   wm_offset = ALIGN(next_offset, 32);
+   next_offset = wm_offset + sizeof(*wm_state);
+   cc_offset = ALIGN(next_offset, 32);
+   next_offset = cc_offset + sizeof(*cc_state);
+
+   /* XXX: Add space for SF and PS kernels */
+
+   cc_viewport_offset = ALIGN(next_offset, 32);
+   next_offset = cc_viewport_offset + sizeof(*cc_viewport);
+
+   src_sampler_offset = ALIGN(next_offset, 32);
+   next_offset = src_sampler_offset + sizeof(*src_sampler_state);
+
+   /* Align VB to native size of elements, for safety */
+   vb_offset = ALIGN(next_offset, 8);
+   next_offset = vb_offset + vb_size;
+
+   /* And then the general state: */
+   dest_surf_offset = ALIGN(next_offset, 32);
+   surf_state_base_offset = dest_surf_offset;
+   next_offset = dest_surf_offset + sizeof(*dest_surf_state);
+   src_surf_offset = ALIGN(next_offset, 32);
+   next_offset = src_surf_offset + sizeof(*src_surf_state);
+   binding_table_offset = ALIGN(next_offset, 32);
+   next_offset = binding_table_offset + (2 * 4);
+
+   /* Allocate an area in framebuffer for our state layout we just set up */
+   total_state_size = next_offset;
+   state_area = I830AllocateMemory(pScrn, NULL, (total_state_size + 32) /
+				   pI830->cpp);
+   if (state_area == NULL) {
+      ErrorF("Failed to allocate %d bytes for state\n", total_state_size);
+      return;
+   }
+
+   state_base = (char *)(pI830->FrontBuffer.Start + pPriv->linear->offset *
+			 pI830->cpp);
+   /* Set up our pointers to state structures in framebuffer.  It would probably
+    * be a good idea to fill these structures out in system memory and then dump
+    * them there, instead.
+    */
+   vs_state = (void *)(state_base + vs_offset);
+   sf_state = (void *)(state_base + sf_offset);
+   wm_state = (void *)(state_base + wm_offset);
+   cc_state = (void *)(state_base + cc_offset);
+   cc_viewport = (void *)(state_base + cc_viewport_offset);
+   dest_surf_state = (void *)(state_base + dest_surf_offset);
+   src_surf_state = (void *)(state_base + src_surf_offset);
+   src_sampler_state = (void *)(state_base + src_sampler_offset);
+   binding_table = (void *)(state_base + binding_table_offset);
+   vb = (void *)(state_base + vb_offset);
+
    /* Set up a default static partitioning of the URB, which is supposed to
     * allow anything we would want to do, at potentially lower performance.
     */
@@ -2672,11 +2736,7 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    urb_cs_size = 2 * 32;
 
    /* We'll be poking the state buffers that could be in use by the 3d hardware
-    * here, but we should have synced the 3D engine if we've reached this point.
-    */
-
-   /* XXX: Allocate space for our state buffers and vb, and set up the state
-    * structure pointers.
+    * here, but we should have synced the 3D engine already in I830PutImage.
     */
 
    /* Set up the state buffer for the destination surface */
@@ -2710,8 +2770,8 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
 
    /* Set up a binding table for our two surfaces.  Only the PS will use it */
    /* XXX: are these offset from the right place? */
-   binding_table[0] = (CARD32)((char *)dest_surf_state - pScrn->fbOffset);
-   binding_table[1] = (CARD32)((char *)src_surf_state - pScrn->fbOffset);
+   binding_table[0] = dest_surf_state_offset - surf_state_base_offset;
+   binding_table[1] = src_surf_state_offset - surf_state_base_offset;
 
    /* Set up the packed YUV source sampler.  Doesn't do colorspace conversion.
     */
@@ -2768,18 +2828,18 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    wm_state->thread3.urb_entry_read_length = XXX;
    wm_state->thread3.const_urb_entry_read_length = XXX;
    wm_state->wm4.sampler_state_pointer =
-	((CARD8 *)src_sampler_state - general_state_base) >> 5;
+	(src_sampler_offset - general_state_base_offset) >> 5;
    wm_state->wm4.sampler_count = 1; /* 1-4 samplers used */
    wm_state->wm5.max_threads = 31;
    wm_state->wm5.thread_dispatch_enable = 1;
    wm_state->wm5.enable_16_pix = 1;
 
-   cc_viewport[0] = float_as_int(0.0);
-   cc_viewport[1] = float_as_int(0.0);
+   cc_viewport->min_depth = 0.0;
+   cc_viewport->max_depth = 0.0;
 
    memset(cc_state, 0, sizeof(*cc_state));
    cc_state->cc4.cc_viewport_state_offset =
-	((char *)cc_viewport - general_state_base) >> 5;
+	(cc_viewport_offset - general_state_base_offset) >> 5;
 
    BEGIN_LP_RING(XXX);
    OUT_RING(MI_FLUSH | MI_STATE_INSTRUCTION_CACHE_FLUSH);
@@ -2800,20 +2860,22 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
 
    /* Set the general and surface state base addresses */
    OUT_RING(STATE3D_BASE_ADDRESS | 4);
-   OUT_RING((general_state_base - pScrn->fbOffset) | BASE_ADDRESS_MODIFY);
-   OUT_RING((surf_state_base - pScrn->fbOffset) | BASE_ADDRESS_MODIFY);
+   OUT_RING((pPriv->linear->offset * pI830->cpp + general_state_base_offset) |
+	    BASE_ADDRESS_MODIFY);
+   OUT_RING((pPriv->linear->offset * pI830->cpp + surf_state_base_offset) |
+	    BASE_ADDRESS_MODIFY);
    OUT_RING(0); /* media base addr, don't care */
    OUT_RING(0); /* general state max addr, disabled */
    OUT_RING(0); /* media object state max addr, disabled */
 
    /* Set the pointers to the 3d pipeline state */
    OUT_RING(STATE3D_PIPELINED_POINTERS | 5);
-   OUT_RING((char *)vs_state - general_state_base); /* 32 byte aligned */
+   OUT_RING(vs_offset - general_state_base_offset); /* 32 byte aligned */
    OUT_RING(0); /* disable GS, resulting in passthrough */
    OUT_RING(0); /* disable CLIP, resulting in passthrough */
-   OUT_RING((char *)sf_state - general_state_base); /* 32 byte aligned */
-   OUT_RING((char *)wm_state - general_state_base); /* 32 byte aligned */
-   OUT_RING((char *)cc_state - general_state_base); /* 64 byte aligned */
+   OUT_RING(sf_offset - general_state_base_offset); /* 32 byte aligned */
+   OUT_RING(wm_offset - general_state_base_offset); /* 32 byte aligned */
+   OUT_RING(cc_offset - general_state_base_offset); /* 64 byte aligned */
 
    /* Only the PS uses the binding table */
    OUT_RING(STATE3D_BINDING_TABLE_POINTERS | 4);
@@ -2821,7 +2883,7 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    OUT_RING(0); /* gs */
    OUT_RING(0); /* clip */
    OUT_RING(0); /* sf */
-   OUT_RING((char *)binding_table - surf_state_base); /* ps */
+   OUT_RING(binding_table_offset - surf_state_base_offset); /* ps */
 
    /* The drawing rectangle clipping is always on.  Set it to values that
     * shouldn't do any clipping.
@@ -2837,7 +2899,7 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    OUT_RING((0 << VB0_BUFFER_INDEX_SHIFT) |
 	    VB0_VERTEXDATA |
 	    (16 << VB0_BUFFER_PITCH_SHIFT));
-   OUT_RING((CARD32)((char *)vb - pScrn->fbOffset));
+   OUT_RING(pPriv->linear->offset * pI830->cpp + vb_offset);
    OUT_RING(0xffffffff); /* Max index -- don't care */
 
    /* Set up our vertex elements, sourced from the single vertex buffer. */
@@ -2937,6 +2999,8 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
       first_output = FALSE;
    }
 
+   xf86FreeOffscreenLinear(state_area);
+
    if (pI830->AccelInfoRec)
       pI830->AccelInfoRec->NeedToSync = TRUE;
 }
diff-tree de06cd70a9edb8b56d05d3f505137f7c7f083c2f (from ad7ec6a24b436d5492d38e4fa56845b229cf5fb8)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Thu May 18 18:27:11 2006 -0700

    Checkpoint for filling out more 3D state.

diff --git a/src/i810_reg.h b/src/i810_reg.h
index f949d3c..0e13932 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -1648,6 +1648,13 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define VE0_VALID			(1 << 26)
 #define VE0_FORMAT_SHIFT		16
 #define VE0_OFFSET_SHIFT		0
+#define VE1_VFCOMPONENT_0_SHIFT		28
+#define VE1_VFCOMPONENT_1_SHIFT		24
+#define VE1_VFCOMPONENT_2_SHIFT		20
+#define VE1_VFCOMPONENT_3_SHIFT		16
+#define VE1_DESTINATION_ELEMENT_OFFSET_SHIFT	0
+
+#define STATE3D_BINDING_TABLE_POINTERS	(CMD_3D | (0x03<<27) | (0x00<<24) | (0x01<<16))
 
 #define PRIMITIVE3D_BRW		(CMD_3D | (0x03<<27) | (0x03<<24) | (0x08<<16))
 /* Primitive types are in brw_defines.h */
diff --git a/src/i830_video.c b/src/i830_video.c
index 3f11772..9b60112 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2639,9 +2639,11 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    struct brw_surface_state *dest_surf_state;
    struct brw_surface_state *src_surf_state;
    struct brw_sampler_state *src_sampler_state;
-   struct brw_cc_unit_state *cc_state;
    struct brw_vs_unit_state *vs_state;
-   CARD32 *vb;
+   struct brw_sf_unit_state *sf_state;
+   struct brw_wm_unit_state *wm_state;
+   struct brw_cc_unit_state *cc_state;
+   CARD32 *vb, *cc_viewport, *binding_table;
    Bool first_output = TRUE;
 
    ErrorF("BroadwaterDisplayVideoTextured: %dx%d (pitch %d)\n", width, height,
@@ -2706,6 +2708,11 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    src_surf_state->ss2.height = height;
    src_surf_state->ss3.pitch = video_pitch - 1;
 
+   /* Set up a binding table for our two surfaces.  Only the PS will use it */
+   /* XXX: are these offset from the right place? */
+   binding_table[0] = (CARD32)((char *)dest_surf_state - pScrn->fbOffset);
+   binding_table[1] = (CARD32)((char *)src_surf_state - pScrn->fbOffset);
+
    /* Set up the packed YUV source sampler.  Doesn't do colorspace conversion.
     */
    memset(src_sampler_state, 0, sizeof(*src_sampler_state));
@@ -2718,10 +2725,26 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    memset(vs_state, 0, sizeof(*vs_state));
    vs_state->vs6.vs_enable = FALSE;
 
-   /* XXX: Set up binding table state */
-   /* XXX: Set up the VF for however we send our prims */
-   /* XXX: Set up the SF kernel to do coord interp */
-   /* XXX: Set up the SF state */
+   /* XXX: Set up the SF kernel to do coord interp: for each attribute,
+    * calculate dA/dx and dA/dy.  Hand these interpolation coefficients
+    * back to SF which then hands pixels off to WM.
+    */
+
+   memset(sf_state, 0, sizeof(*sf_state));
+   sf_state->thread0.kernel_start_pointer = XXX;
+   sf_state->thread0.grf_reg_count = XXX;
+   sf_state->thread1.single_program_flow = XXX;
+   sf_state->thread2.scratch_space_base_pointer = XXX; /* 1k aligned */
+   sf_state->thread4.nr_urb_entries = 8;
+   sf_state->thread4.urb_entry_allocation_size = 11;
+   sf_state->thread4.max_threads = MIN(12, sf_state->thread4.nr_urb_entries /
+				       2) - 1;
+   sf_state->sf5.viewport_transform = FALSE; /* skip viewport */
+   sf_state->sf6.cull_mode = BRW_CULLMODE_BOTH;
+   sf_state->sf6.scissor =
+   sf_state->sf6.dest_org_vbias = 0x8;
+   sf_state->sf6.dest_org_hbias = 0x8;
+   sf_state->sf7.trifan_pv = 2;
 
    /* XXX: Set up the PS kernel (dispatched by WM) for convertiny YUV to RGB.
     * The 3D driver does this as:
@@ -2736,13 +2759,27 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
     *
     */
 
-   /* XXX: Set up the WM state. */
+   wm_state->thread0.kernel_start_pointer = XXX;
+   wm_state->thread0.grf_reg_count = XXX;
+   wm_state->thread1.binding_table_entry_count = 2;
+   wm_state->thread2.scratch_space_base_pointer = XXX;
+   wm_state->thread2.per_thread_scratch_space = XXX;
+   wm_state->thread3.dispatch_grf_start_reg = XXX;
+   wm_state->thread3.urb_entry_read_length = XXX;
+   wm_state->thread3.const_urb_entry_read_length = XXX;
+   wm_state->wm4.sampler_state_pointer =
+	((CARD8 *)src_sampler_state - general_state_base) >> 5;
+   wm_state->wm4.sampler_count = 1; /* 1-4 samplers used */
+   wm_state->wm5.max_threads = 31;
+   wm_state->wm5.thread_dispatch_enable = 1;
+   wm_state->wm5.enable_16_pix = 1;
 
-   /* XXX: Set up CC_VIEWPORT, though we really don't care about its behavior.
-    */
+   cc_viewport[0] = float_as_int(0.0);
+   cc_viewport[1] = float_as_int(0.0);
 
    memset(cc_state, 0, sizeof(*cc_state));
-   /* XXX: Set pointer to CC_VIEWPORT */
+   cc_state->cc4.cc_viewport_state_offset =
+	((char *)cc_viewport - general_state_base) >> 5;
 
    BEGIN_LP_RING(XXX);
    OUT_RING(MI_FLUSH | MI_STATE_INSTRUCTION_CACHE_FLUSH);
@@ -2761,55 +2798,73 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    OUT_RING(((urb_cs_start + urb_cs_size) << UF2_CS_FENCE_SHIFT) |
 	    ((urb_sf_start + urb_sf_size) << UF2_SF_FENCE_SHIFT));
 
+   /* Set the general and surface state base addresses */
    OUT_RING(STATE3D_BASE_ADDRESS | 4);
-   OUT_RING(XXX | BASE_ADDRESS_MODIFY); /* general state base addr, 4k align */
-   OUT_RING(XXX | BASE_ADDRESS_MODIFY); /* surf state base addr, 4k align */
+   OUT_RING((general_state_base - pScrn->fbOffset) | BASE_ADDRESS_MODIFY);
+   OUT_RING((surf_state_base - pScrn->fbOffset) | BASE_ADDRESS_MODIFY);
    OUT_RING(0); /* media base addr, don't care */
    OUT_RING(0); /* general state max addr, disabled */
    OUT_RING(0); /* media object state max addr, disabled */
 
+   /* Set the pointers to the 3d pipeline state */
    OUT_RING(STATE3D_PIPELINED_POINTERS | 5);
    OUT_RING((char *)vs_state - general_state_base); /* 32 byte aligned */
    OUT_RING(0); /* disable GS, resulting in passthrough */
    OUT_RING(0); /* disable CLIP, resulting in passthrough */
    OUT_RING((char *)sf_state - general_state_base); /* 32 byte aligned */
    OUT_RING((char *)wm_state - general_state_base); /* 32 byte aligned */
-   OUT_RING((char *)color_calc_state - general_state_base); /* 64 byte aligned */
+   OUT_RING((char *)cc_state - general_state_base); /* 64 byte aligned */
+
+   /* Only the PS uses the binding table */
+   OUT_RING(STATE3D_BINDING_TABLE_POINTERS | 4);
+   OUT_RING(0); /* vs */
+   OUT_RING(0); /* gs */
+   OUT_RING(0); /* clip */
+   OUT_RING(0); /* sf */
+   OUT_RING((char *)binding_table - surf_state_base); /* ps */
 
+   /* The drawing rectangle clipping is always on.  Set it to values that
+    * shouldn't do any clipping.
+    */
    OUT_RING(STATE3D_DRAWING_RECTANGLE_BRW | 2);
    OUT_RING(0x00000000);	/* ymin, xmin */
    OUT_RING((pScrn->virtualX - 1) |
 	    (pScrn->virtualY - 1) << 16); /* ymax, xmax */
    OUT_RING(0x00000000);	/* yorigin, xorigin */
 
+   /* Set up the pointer to our vertex buffer */
    OUT_RING(STATE3D_VERTEX_BUFFERS | 2);
    OUT_RING((0 << VB0_BUFFER_INDEX_SHIFT) |
 	    VB0_VERTEXDATA |
 	    (16 << VB0_BUFFER_PITCH_SHIFT));
-   OUT_RING(vb - pScrn->fbOffset);
+   OUT_RING((CARD32)((char *)vb - pScrn->fbOffset));
    OUT_RING(0xffffffff); /* Max index -- don't care */
 
    /* Set up our vertex elements, sourced from the single vertex buffer. */
    OUT_RING(STATE3D_VERTEX_ELEMENTS | XXX);
-   /* offset 0: X,Y */
+   /* offset 0: X,Y -> {X, Y, 0.0, 0.0} */
    OUT_RING((0 << VE0_VERTEX_BUFFER_INDEX_SHIFT) |
 	    VE0_VALID |
 	    (BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) |
 	    (0 << VE0_OFFSET_SHIFT));
-   /* offset 8: S0, S1 */
-   OUT_RING(0);
+   OUT_RING((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) |
+	    (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) |
+	    (BRW_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_2_SHIFT) |
+	    (BRW_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_3_SHIFT) |
+	    (0 << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT));
+   /* offset 8: S0, T0 -> {S0, T0, 0.0, 0.0} */
    OUT_RING((0 << VE0_VERTEX_BUFFER_INDEX_SHIFT) |
 	    VE0_VALID |
 	    (BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) |
 	    (8 << VE0_OFFSET_SHIFT));
-   OUT_RING(0);
-
-   /* XXX: Set the locations of the sampler/surface/etc. state */
+   OUT_RING((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) |
+	    (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) |
+	    (BRW_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_2_SHIFT) |
+	    (BRW_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_3_SHIFT) |
+	    (4 << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT));
 
    ADVANCE_LP_RING();
 
-   /* XXX: Finally, emit some prims */
-
    dxo = dstRegion->extents.x1;
    dyo = dstRegion->extents.y1;
 
@@ -2869,7 +2924,7 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
       vb[i++] = box_x1 - dxo;
       vb[i++] = box_y2 - dyo;
 
-      BEGIN_LP_RING(vert_data_count + 8);
+      BEGIN_LP_RING(XXX);
       OUT_RING(PRIMITIVE3D_BRW | (_3DPRIM_TRIFAN << P3D0_TOPO_SHIFT) | 4);
       OUT_RING(4); /* vertex count per instance */
       OUT_RING(0); /* start vertex offset */
diff-tree ad7ec6a24b436d5492d38e4fa56845b229cf5fb8 (from 291770efc691a02650e3c580ca40c2f9fce3896c)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Thu May 18 15:26:28 2006 -0700

    Checkpoint of BW textured video work, filling out vertex submission stuff and
    some more other state.

diff --git a/src/i810_reg.h b/src/i810_reg.h
index 5ccd8cc..f949d3c 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -1632,8 +1632,26 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 
 #define STATE3D_DRAWING_RECTANGLE_BRW	(CMD_3D | (0x01<<24) | (0x00<<16))
 
-#define PRIMITIVE3D_BRW			(CMD_3D | (0x03<<27) | (0x08<<16))
-#define PRIM3D_BRW_POINTLIST		0x0
+#define STATE3D_BASE_ADDRESS		(CMD_3D | (0x01<<24) | (0x01<<16))
+#define BASE_ADDRESS_MODIFY		(1 << 0)
+
+#define STATE3D_PIPELINED_POINTERS	(CMD_3D | (0x00<<24) | (0x00<<16))
+
+#define STATE3D_VERTEX_BUFFERS	(CMD_3D | (0x03<<27) | (0x00<<24) | (0x08<<16))
+#define VB0_BUFFER_INDEX_SHIFT		27
+#define VB0_VERTEXDATA			(0 << 26)
+#define VB0_INSTANCEDATA		(1 << 26)
+#define VB0_BUFFER_PITCH_SHIFT		0
+
+#define STATE3D_VERTEX_ELEMENTS		(CMD_3D | (0x00<<24) | (0x09<<16))
+#define VE0_VERTEX_BUFFER_INDEX_SHIFT	27
+#define VE0_VALID			(1 << 26)
+#define VE0_FORMAT_SHIFT		16
+#define VE0_OFFSET_SHIFT		0
+
+#define PRIMITIVE3D_BRW		(CMD_3D | (0x03<<27) | (0x03<<24) | (0x08<<16))
+/* Primitive types are in brw_defines.h */
+#define P3D0_TOPO_SHIFT			10
 /* End regs for broadwater */
 
 
diff --git a/src/i830_video.c b/src/i830_video.c
index d13b75f..3f11772 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2115,6 +2115,14 @@ union intfloat {
    float f;
 };
 
+static inline CARD32 float_as_int(float f)
+{
+   union intfloat tmp;
+
+   tmp.f = f;
+   return tmp.ui;
+}
+
 #define OUT_RING_F(x) do {						\
    union intfloat _tmp;							\
    _tmp.f = x;								\
@@ -2632,6 +2640,9 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    struct brw_surface_state *src_surf_state;
    struct brw_sampler_state *src_sampler_state;
    struct brw_cc_unit_state *cc_state;
+   struct brw_vs_unit_state *vs_state;
+   CARD32 *vb;
+   Bool first_output = TRUE;
 
    ErrorF("BroadwaterDisplayVideoTextured: %dx%d (pitch %d)\n", width, height,
 	  video_pitch);
@@ -2662,8 +2673,8 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
     * here, but we should have synced the 3D engine if we've reached this point.
     */
 
-   /* XXX: Allocate space for our state buffers, and set up the state structure
-    * pointers.
+   /* XXX: Allocate space for our state buffers and vb, and set up the state
+    * structure pointers.
     */
 
    /* Set up the state buffer for the destination surface */
@@ -2703,11 +2714,14 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    src_sampler_state->ss1.s_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
    src_sampler_state->ss1.t_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
 
+   /* Set up the vertex shader to be disabled (passthrough) */
+   memset(vs_state, 0, sizeof(*vs_state));
+   vs_state->vs6.vs_enable = FALSE;
+
    /* XXX: Set up binding table state */
    /* XXX: Set up the VF for however we send our prims */
    /* XXX: Set up the SF kernel to do coord interp */
    /* XXX: Set up the SF state */
-   /* XXX: Set up the clipper to do nothing for us, I think */
 
    /* XXX: Set up the PS kernel (dispatched by WM) for convertiny YUV to RGB.
     * The 3D driver does this as:
@@ -2737,7 +2751,6 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
 
    OUT_RING(STATE3D_URB_FENCE |
 	    UF0_CS_REALLOC |
-	    UF0_VFE_REALLOC |
 	    UF0_SF_REALLOC |
 	    UF0_CLIP_REALLOC |
 	    UF0_GS_REALLOC |
@@ -2746,15 +2759,51 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
 	    ((urb_gs_start + urb_gs_size) << UF1_GS_FENCE_SHIFT) |
 	    ((urb_vs_start + urb_vs_size) << UF1_VS_FENCE_SHIFT));
    OUT_RING(((urb_cs_start + urb_cs_size) << UF2_CS_FENCE_SHIFT) |
-	    ((urb_vfe_start + urb_vfe_size) << UF2_VFE_FENCE_SHIFT) |
 	    ((urb_sf_start + urb_sf_size) << UF2_SF_FENCE_SHIFT));
 
+   OUT_RING(STATE3D_BASE_ADDRESS | 4);
+   OUT_RING(XXX | BASE_ADDRESS_MODIFY); /* general state base addr, 4k align */
+   OUT_RING(XXX | BASE_ADDRESS_MODIFY); /* surf state base addr, 4k align */
+   OUT_RING(0); /* media base addr, don't care */
+   OUT_RING(0); /* general state max addr, disabled */
+   OUT_RING(0); /* media object state max addr, disabled */
+
+   OUT_RING(STATE3D_PIPELINED_POINTERS | 5);
+   OUT_RING((char *)vs_state - general_state_base); /* 32 byte aligned */
+   OUT_RING(0); /* disable GS, resulting in passthrough */
+   OUT_RING(0); /* disable CLIP, resulting in passthrough */
+   OUT_RING((char *)sf_state - general_state_base); /* 32 byte aligned */
+   OUT_RING((char *)wm_state - general_state_base); /* 32 byte aligned */
+   OUT_RING((char *)color_calc_state - general_state_base); /* 64 byte aligned */
+
    OUT_RING(STATE3D_DRAWING_RECTANGLE_BRW | 2);
    OUT_RING(0x00000000);	/* ymin, xmin */
    OUT_RING((pScrn->virtualX - 1) |
 	    (pScrn->virtualY - 1) << 16); /* ymax, xmax */
    OUT_RING(0x00000000);	/* yorigin, xorigin */
 
+   OUT_RING(STATE3D_VERTEX_BUFFERS | 2);
+   OUT_RING((0 << VB0_BUFFER_INDEX_SHIFT) |
+	    VB0_VERTEXDATA |
+	    (16 << VB0_BUFFER_PITCH_SHIFT));
+   OUT_RING(vb - pScrn->fbOffset);
+   OUT_RING(0xffffffff); /* Max index -- don't care */
+
+   /* Set up our vertex elements, sourced from the single vertex buffer. */
+   OUT_RING(STATE3D_VERTEX_ELEMENTS | XXX);
+   /* offset 0: X,Y */
+   OUT_RING((0 << VE0_VERTEX_BUFFER_INDEX_SHIFT) |
+	    VE0_VALID |
+	    (BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) |
+	    (0 << VE0_OFFSET_SHIFT));
+   /* offset 8: S0, S1 */
+   OUT_RING(0);
+   OUT_RING((0 << VE0_VERTEX_BUFFER_INDEX_SHIFT) |
+	    VE0_VALID |
+	    (BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) |
+	    (8 << VE0_OFFSET_SHIFT));
+   OUT_RING(0);
+
    /* XXX: Set the locations of the sampler/surface/etc. state */
 
    ADVANCE_LP_RING();
@@ -2764,7 +2813,6 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    dxo = dstRegion->extents.x1;
    dyo = dstRegion->extents.y1;
 
-#if 0
    pbox = REGION_RECTS(dstRegion);
    nbox = REGION_NUM_RECTS(dstRegion);
    while (nbox--)
@@ -2773,12 +2821,16 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
       int box_y1 = pbox->y1;
       int box_x2 = pbox->x2;
       int box_y2 = pbox->y2;
-      int j;
+      int i;
       float src_scale_x, src_scale_y;
       CARD32 vb[40];
       float verts[4][2], tex[4][2], tex2[4][2];
       int vert_data_count;
 
+      if (!first_output) {
+	 /* XXX: idle */
+      }
+
       pbox++;
 
       src_scale_x = (float)src_w / (float)drw_w;
@@ -2789,7 +2841,6 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
       else
 	 vert_data_count = 40;
 
-      BEGIN_LP_RING(vert_data_count + 8);
       OUT_RING(MI_NOOP);
       OUT_RING(MI_NOOP);
       OUT_RING(MI_NOOP);
@@ -2798,53 +2849,38 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
       OUT_RING(MI_NOOP);
       OUT_RING(MI_NOOP);
 
-      /* vertex data */
-      OUT_RING(PRIMITIVE3D | PRIM3D_INLINE | PRIM3D_TRIFAN |
-	       (vert_data_count - 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;
-      verts[3][0] = box_x1; verts[3][1] = box_y2;
+      vb[i++] = box_x1;
+      vb[i++] = box_y1;
+      vb[i++] = box_x1 - dxo;
+      vb[i++] = box_y1 - dyo;
+
+      vb[i++] = box_x2;
+      vb[i++] = box_y1;
+      vb[i++] = box_x2 - dxo;
+      vb[i++] = box_y1 - dyo;
+
+      vb[i++] = box_x2;
+      vb[i++] = box_y2;
+      vb[i++] = box_x2 - dxo;
+      vb[i++] = box_y2 - dyo;
+
+      vb[i++] = box_x1;
+      vb[i++] = box_y2;
+      vb[i++] = box_x1 - dxo;
+      vb[i++] = box_y2 - dyo;
 
-      if (!planar) {
-	 tex[0][0] = (box_x1 - dxo) * src_scale_x;
-	 tex[0][1] = (box_y1 - dyo) * src_scale_y;
-	 tex[1][0] = (box_x2 - dxo) * src_scale_x;
-	 tex[1][1] = (box_y1 - dyo) * src_scale_y;
-	 tex[2][0] = (box_x2 - dxo) * src_scale_x;
-	 tex[2][1] = (box_y2 - dyo) * src_scale_y;
-	 tex[3][0] = (box_x1 - dxo) * src_scale_x;
-	 tex[3][1] = (box_y2 - dyo) * src_scale_y;
-	 /* emit vertex buffer */
-	 draw_poly(vb, verts, tex, NULL);
-	 for (j = 0; j < vert_data_count; j++)
-	    OUT_RING(vb[j]);
-      } else {
-	 tex[0][0] = (box_x1 - dxo) * src_scale_x / 2.0;
-	 tex[0][1] = (box_y1 - dyo) * src_scale_y / 2.0;
-	 tex[1][0] = (box_x2 - dxo) * src_scale_x / 2.0;
-	 tex[1][1] = (box_y1 - dyo) * src_scale_y / 2.0;
-	 tex[2][0] = (box_x2 - dxo) * src_scale_x / 2.0;
-	 tex[2][1] = (box_y2 - dyo) * src_scale_y / 2.0;
-	 tex[3][0] = (box_x1 - dxo) * src_scale_x / 2.0;
-	 tex[3][1] = (box_y2 - dyo) * src_scale_y / 2.0;
-	 tex2[0][0] = (box_x1 - dxo) * src_scale_x;
-	 tex2[0][1] = (box_y1 - dyo) * src_scale_y;
-	 tex2[1][0] = (box_x2 - dxo) * src_scale_x;
-	 tex2[1][1] = (box_y1 - dyo) * src_scale_y;
-	 tex2[2][0] = (box_x2 - dxo) * src_scale_x;
-	 tex2[2][1] = (box_y2 - dyo) * src_scale_y;
-	 tex2[3][0] = (box_x1 - dxo) * src_scale_x;
-	 tex2[3][1] = (box_y2 - dyo) * src_scale_y;
-	 /* emit vertex buffer */
-	 draw_poly(vb, verts, tex, tex2);
-	 for (j = 0; j < vert_data_count; j++)
-	    OUT_RING(vb[j]);
-      }
+      BEGIN_LP_RING(vert_data_count + 8);
+      OUT_RING(PRIMITIVE3D_BRW | (_3DPRIM_TRIFAN << P3D0_TOPO_SHIFT) | 4);
+      OUT_RING(4); /* vertex count per instance */
+      OUT_RING(0); /* start vertex offset */
+      OUT_RING(1); /* single instance */
+      OUT_RING(0); /* start instance location */
+      OUT_RING(0); /* index buffer offset, ignored */
 
       ADVANCE_LP_RING();
+
+      first_output = FALSE;
    }
-#endif
 
    if (pI830->AccelInfoRec)
       pI830->AccelInfoRec->NeedToSync = TRUE;
diff-tree 291770efc691a02650e3c580ca40c2f9fce3896c (from bc51d6525a12c748d0a293b7e560f6dcea33eecb)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Thu May 18 10:43:07 2006 -0700

    Start laying out some of the bits that need to be done for BW textured video.
    Headers taken from TG code drop.

diff --git a/man/.gitignore b/man/.gitignore
deleted file mode 100644
index a438e80..0000000
--- a/man/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-i810.4
-i810.4x
diff --git a/src/brw_defines.h b/src/brw_defines.h
new file mode 100644
index 0000000..93aed54
--- /dev/null
+++ b/src/brw_defines.h
@@ -0,0 +1,847 @@
+ /**************************************************************************
+ * 
+ * Copyright 2005 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * 
+ * 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, sub license, 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 NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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.
+ * 
+ **************************************************************************/
+
+#ifndef BRW_DEFINES_H
+#define BRW_DEFINES_H
+
+/*
+ */
+#if 0
+#define MI_NOOP                              0x00
+#define MI_USER_INTERRUPT                    0x02
+#define MI_WAIT_FOR_EVENT                    0x03
+#define MI_FLUSH                             0x04
+#define MI_REPORT_HEAD                       0x07
+#define MI_ARB_ON_OFF                        0x08
+#define MI_BATCH_BUFFER_END                  0x0A
+#define MI_OVERLAY_FLIP                      0x11
+#define MI_LOAD_SCAN_LINES_INCL              0x12
+#define MI_LOAD_SCAN_LINES_EXCL              0x13
+#define MI_DISPLAY_BUFFER_INFO               0x14
+#define MI_SET_CONTEXT                       0x18
+#define MI_STORE_DATA_IMM                    0x20
+#define MI_STORE_DATA_INDEX                  0x21
+#define MI_LOAD_REGISTER_IMM                 0x22
+#define MI_STORE_REGISTER_MEM                0x24
+#define MI_BATCH_BUFFER_START                0x31
+
+#define MI_SYNCHRONOUS_FLIP                  0x0 
+#define MI_ASYNCHRONOUS_FLIP                 0x1
+
+#define MI_BUFFER_SECURE                     0x0 
+#define MI_BUFFER_NONSECURE                  0x1
+
+#define MI_ARBITRATE_AT_CHAIN_POINTS         0x0 
+#define MI_ARBITRATE_BETWEEN_INSTS           0x1
+#define MI_NO_ARBITRATION                    0x3 
+
+#define MI_CONDITION_CODE_WAIT_DISABLED      0x0
+#define MI_CONDITION_CODE_WAIT_0             0x1
+#define MI_CONDITION_CODE_WAIT_1             0x2
+#define MI_CONDITION_CODE_WAIT_2             0x3
+#define MI_CONDITION_CODE_WAIT_3             0x4
+#define MI_CONDITION_CODE_WAIT_4             0x5
+
+#define MI_DISPLAY_PIPE_A                    0x0
+#define MI_DISPLAY_PIPE_B                    0x1
+
+#define MI_DISPLAY_PLANE_A                   0x0 
+#define MI_DISPLAY_PLANE_B                   0x1
+#define MI_DISPLAY_PLANE_C                   0x2
+
+#define MI_STANDARD_FLIP                                 0x0
+#define MI_ENQUEUE_FLIP_PERFORM_BASE_FRAME_NUMBER_LOAD   0x1
+#define MI_ENQUEUE_FLIP_TARGET_FRAME_NUMBER_RELATIVE     0x2
+#define MI_ENQUEUE_FLIP_ABSOLUTE_TARGET_FRAME_NUMBER     0x3
+
+#define MI_PHYSICAL_ADDRESS                  0x0
+#define MI_VIRTUAL_ADDRESS                   0x1
+
+#define MI_BUFFER_MEMORY_MAIN                0x0 
+#define MI_BUFFER_MEMORY_GTT                 0x2
+#define MI_BUFFER_MEMORY_PER_PROCESS_GTT     0x3 
+
+#define MI_FLIP_CONTINUE                     0x0
+#define MI_FLIP_ON                           0x1
+#define MI_FLIP_OFF                          0x2
+
+#define MI_UNTRUSTED_REGISTER_SPACE          0x0
+#define MI_TRUSTED_REGISTER_SPACE            0x1
+#endif
+
+/* 3D state:
+ */
+#define _3DOP_3DSTATE_PIPELINED       0x0
+#define _3DOP_3DSTATE_NONPIPELINED    0x1
+#define _3DOP_3DCONTROL               0x2
+#define _3DOP_3DPRIMITIVE             0x3
+
+#define _3DSTATE_PIPELINED_POINTERS       0x00
+#define _3DSTATE_BINDING_TABLE_POINTERS   0x01
+#define _3DSTATE_VERTEX_BUFFERS           0x08
+#define _3DSTATE_VERTEX_ELEMENTS          0x09
+#define _3DSTATE_INDEX_BUFFER             0x0A
+#define _3DSTATE_VF_STATISTICS            0x0B
+#define _3DSTATE_DRAWING_RECTANGLE            0x00
+#define _3DSTATE_CONSTANT_COLOR               0x01
+#define _3DSTATE_SAMPLER_PALETTE_LOAD         0x02
+#define _3DSTATE_CHROMA_KEY                   0x04
+#define _3DSTATE_DEPTH_BUFFER                 0x05
+#define _3DSTATE_POLY_STIPPLE_OFFSET          0x06
+#define _3DSTATE_POLY_STIPPLE_PATTERN         0x07
+#define _3DSTATE_LINE_STIPPLE                 0x08
+#define _3DSTATE_GLOBAL_DEPTH_OFFSET_CLAMP    0x09
+#define _3DCONTROL    0x00
+#define _3DPRIMITIVE  0x00
+
+#define PIPE_CONTROL_NOWRITE          0x00
+#define PIPE_CONTROL_WRITEIMMEDIATE   0x01
+#define PIPE_CONTROL_WRITEDEPTH       0x02
+#define PIPE_CONTROL_WRITETIMESTAMP   0x03
+
+#define PIPE_CONTROL_GTTWRITE_PROCESS_LOCAL 0x00
+#define PIPE_CONTROL_GTTWRITE_GLOBAL        0x01
+
+#define _3DPRIM_POINTLIST         0x01
+#define _3DPRIM_LINELIST          0x02
+#define _3DPRIM_LINESTRIP         0x03
+#define _3DPRIM_TRILIST           0x04
+#define _3DPRIM_TRISTRIP          0x05
+#define _3DPRIM_TRIFAN            0x06
+#define _3DPRIM_QUADLIST          0x07
+#define _3DPRIM_QUADSTRIP         0x08
+#define _3DPRIM_LINELIST_ADJ      0x09
+#define _3DPRIM_LINESTRIP_ADJ     0x0A
+#define _3DPRIM_TRILIST_ADJ       0x0B
+#define _3DPRIM_TRISTRIP_ADJ      0x0C
+#define _3DPRIM_TRISTRIP_REVERSE  0x0D
+#define _3DPRIM_POLYGON           0x0E
+#define _3DPRIM_RECTLIST          0x0F
+#define _3DPRIM_LINELOOP          0x10
+#define _3DPRIM_POINTLIST_BF      0x11
+#define _3DPRIM_LINESTRIP_CONT    0x12
+#define _3DPRIM_LINESTRIP_BF      0x13
+#define _3DPRIM_LINESTRIP_CONT_BF 0x14
+#define _3DPRIM_TRIFAN_NOSTIPPLE  0x15
+
+#define _3DPRIM_VERTEXBUFFER_ACCESS_SEQUENTIAL 0
+#define _3DPRIM_VERTEXBUFFER_ACCESS_RANDOM     1
+
+#define BRW_ANISORATIO_2     0 
+#define BRW_ANISORATIO_4     1 
+#define BRW_ANISORATIO_6     2 
+#define BRW_ANISORATIO_8     3 
+#define BRW_ANISORATIO_10    4 
+#define BRW_ANISORATIO_12    5 
+#define BRW_ANISORATIO_14    6 
+#define BRW_ANISORATIO_16    7
+
+#define BRW_BLENDFACTOR_ONE                 0x1
+#define BRW_BLENDFACTOR_SRC_COLOR           0x2
+#define BRW_BLENDFACTOR_SRC_ALPHA           0x3
+#define BRW_BLENDFACTOR_DST_ALPHA           0x4
+#define BRW_BLENDFACTOR_DST_COLOR           0x5
+#define BRW_BLENDFACTOR_SRC_ALPHA_SATURATE  0x6
+#define BRW_BLENDFACTOR_CONST_COLOR         0x7
+#define BRW_BLENDFACTOR_CONST_ALPHA         0x8
+#define BRW_BLENDFACTOR_SRC1_COLOR          0x9
+#define BRW_BLENDFACTOR_SRC1_ALPHA          0x0A
+#define BRW_BLENDFACTOR_ZERO                0x11
+#define BRW_BLENDFACTOR_INV_SRC_COLOR       0x12
+#define BRW_BLENDFACTOR_INV_SRC_ALPHA       0x13
+#define BRW_BLENDFACTOR_INV_DST_ALPHA       0x14
+#define BRW_BLENDFACTOR_INV_DST_COLOR       0x15
+#define BRW_BLENDFACTOR_INV_CONST_COLOR     0x17
+#define BRW_BLENDFACTOR_INV_CONST_ALPHA     0x18
+#define BRW_BLENDFACTOR_INV_SRC1_COLOR      0x19
+#define BRW_BLENDFACTOR_INV_SRC1_ALPHA      0x1A
+
+#define BRW_BLENDFUNCTION_ADD               0
+#define BRW_BLENDFUNCTION_SUBTRACT          1
+#define BRW_BLENDFUNCTION_REVERSE_SUBTRACT  2
+#define BRW_BLENDFUNCTION_MIN               3
+#define BRW_BLENDFUNCTION_MAX               4
+
+#define BRW_ALPHATEST_FORMAT_UNORM8         0
+#define BRW_ALPHATEST_FORMAT_FLOAT32        1
+
+#define BRW_CHROMAKEY_KILL_ON_ANY_MATCH  0
+#define BRW_CHROMAKEY_REPLACE_BLACK      1
+
+#define BRW_CLIP_API_OGL     0
+#define BRW_CLIP_API_DX      1
+
+#define BRW_CLIPMODE_NORMAL              0
+#define BRW_CLIPMODE_CLIP_ALL            1
+#define BRW_CLIPMODE_CLIP_NON_REJECTED   2
+#define BRW_CLIPMODE_REJECT_ALL          3
+#define BRW_CLIPMODE_ACCEPT_ALL          4
+
+#define BRW_CLIP_NDCSPACE     0
+#define BRW_CLIP_SCREENSPACE  1
+
+#define BRW_COMPAREFUNCTION_ALWAYS       0
+#define BRW_COMPAREFUNCTION_NEVER        1
+#define BRW_COMPAREFUNCTION_LESS         2
+#define BRW_COMPAREFUNCTION_EQUAL        3
+#define BRW_COMPAREFUNCTION_LEQUAL       4
+#define BRW_COMPAREFUNCTION_GREATER      5
+#define BRW_COMPAREFUNCTION_NOTEQUAL     6
+#define BRW_COMPAREFUNCTION_GEQUAL       7
+
+#define BRW_COVERAGE_PIXELS_HALF     0
+#define BRW_COVERAGE_PIXELS_1        1
+#define BRW_COVERAGE_PIXELS_2        2
+#define BRW_COVERAGE_PIXELS_4        3
+
+#define BRW_CULLMODE_BOTH        0
+#define BRW_CULLMODE_NONE        1
+#define BRW_CULLMODE_FRONT       2
+#define BRW_CULLMODE_BACK        3
+
+#define BRW_DEFAULTCOLOR_R8G8B8A8_UNORM      0
+#define BRW_DEFAULTCOLOR_R32G32B32A32_FLOAT  1
+
+#define BRW_DEPTHFORMAT_D32_FLOAT_S8X24_UINT     0
+#define BRW_DEPTHFORMAT_D32_FLOAT                1
+#define BRW_DEPTHFORMAT_D24_UNORM_S8_UINT        2
+#define BRW_DEPTHFORMAT_D16_UNORM                5
+
+#define BRW_FLOATING_POINT_IEEE_754        0
+#define BRW_FLOATING_POINT_NON_IEEE_754    1
+
+#define BRW_FRONTWINDING_CW      0
+#define BRW_FRONTWINDING_CCW     1
+
+#define BRW_INDEX_BYTE     0
+#define BRW_INDEX_WORD     1
+#define BRW_INDEX_DWORD    2
+
+#define BRW_LOGICOPFUNCTION_CLEAR            0
+#define BRW_LOGICOPFUNCTION_NOR              1
+#define BRW_LOGICOPFUNCTION_AND_INVERTED     2
+#define BRW_LOGICOPFUNCTION_COPY_INVERTED    3
+#define BRW_LOGICOPFUNCTION_AND_REVERSE      4
+#define BRW_LOGICOPFUNCTION_INVERT           5
+#define BRW_LOGICOPFUNCTION_XOR              6
+#define BRW_LOGICOPFUNCTION_NAND             7
+#define BRW_LOGICOPFUNCTION_AND              8
+#define BRW_LOGICOPFUNCTION_EQUIV            9
+#define BRW_LOGICOPFUNCTION_NOOP             10
+#define BRW_LOGICOPFUNCTION_OR_INVERTED      11
+#define BRW_LOGICOPFUNCTION_COPY             12
+#define BRW_LOGICOPFUNCTION_OR_REVERSE       13
+#define BRW_LOGICOPFUNCTION_OR               14
+#define BRW_LOGICOPFUNCTION_SET              15  
+
+#define BRW_MAPFILTER_NEAREST        0x0 
+#define BRW_MAPFILTER_LINEAR         0x1 
+#define BRW_MAPFILTER_ANISOTROPIC    0x2
+
+#define BRW_MIPFILTER_NONE        0   
+#define BRW_MIPFILTER_NEAREST     1   
+#define BRW_MIPFILTER_LINEAR      3
+
+#define BRW_POLYGON_FRONT_FACING     0
+#define BRW_POLYGON_BACK_FACING      1
+
+#define BRW_PREFILTER_ALWAYS     0x0 
+#define BRW_PREFILTER_NEVER      0x1
+#define BRW_PREFILTER_LESS       0x2
+#define BRW_PREFILTER_EQUAL      0x3
+#define BRW_PREFILTER_LEQUAL     0x4
+#define BRW_PREFILTER_GREATER    0x5
+#define BRW_PREFILTER_NOTEQUAL   0x6
+#define BRW_PREFILTER_GEQUAL     0x7
+
+#define BRW_PROVOKING_VERTEX_0    0
+#define BRW_PROVOKING_VERTEX_1    1 
+#define BRW_PROVOKING_VERTEX_2    2
+
+#define BRW_RASTRULE_UPPER_LEFT  0    
+#define BRW_RASTRULE_UPPER_RIGHT 1
+
+#define BRW_RENDERTARGET_CLAMPRANGE_UNORM    0
+#define BRW_RENDERTARGET_CLAMPRANGE_SNORM    1
+#define BRW_RENDERTARGET_CLAMPRANGE_FORMAT   2
+
+#define BRW_STENCILOP_KEEP               0
+#define BRW_STENCILOP_ZERO               1
+#define BRW_STENCILOP_REPLACE            2
+#define BRW_STENCILOP_INCRSAT            3
+#define BRW_STENCILOP_DECRSAT            4
+#define BRW_STENCILOP_INCR               5
+#define BRW_STENCILOP_DECR               6
+#define BRW_STENCILOP_INVERT             7
+
+#define BRW_SURFACE_MIPMAPLAYOUT_BELOW   0
+#define BRW_SURFACE_MIPMAPLAYOUT_RIGHT   1
+
+#define BRW_SURFACEFORMAT_R32G32B32A32_FLOAT             0x000 
+#define BRW_SURFACEFORMAT_R32G32B32A32_SINT              0x001 
+#define BRW_SURFACEFORMAT_R32G32B32A32_UINT              0x002 
+#define BRW_SURFACEFORMAT_R32G32B32A32_UNORM             0x003 
+#define BRW_SURFACEFORMAT_R32G32B32A32_SNORM             0x004 
+#define BRW_SURFACEFORMAT_R64G64_FLOAT                   0x005 
+#define BRW_SURFACEFORMAT_R32G32B32X32_FLOAT             0x006 
+#define BRW_SURFACEFORMAT_R32G32B32A32_SSCALED           0x007
+#define BRW_SURFACEFORMAT_R32G32B32A32_USCALED           0x008
+#define BRW_SURFACEFORMAT_R32G32B32_FLOAT                0x040 
+#define BRW_SURFACEFORMAT_R32G32B32_SINT                 0x041 
+#define BRW_SURFACEFORMAT_R32G32B32_UINT                 0x042 
+#define BRW_SURFACEFORMAT_R32G32B32_UNORM                0x043 
+#define BRW_SURFACEFORMAT_R32G32B32_SNORM                0x044 
+#define BRW_SURFACEFORMAT_R32G32B32_SSCALED              0x045 
+#define BRW_SURFACEFORMAT_R32G32B32_USCALED              0x046 
+#define BRW_SURFACEFORMAT_R16G16B16A16_UNORM             0x080 
+#define BRW_SURFACEFORMAT_R16G16B16A16_SNORM             0x081 
+#define BRW_SURFACEFORMAT_R16G16B16A16_SINT              0x082 
+#define BRW_SURFACEFORMAT_R16G16B16A16_UINT              0x083 
+#define BRW_SURFACEFORMAT_R16G16B16A16_FLOAT             0x084 
+#define BRW_SURFACEFORMAT_R32G32_FLOAT                   0x085 
+#define BRW_SURFACEFORMAT_R32G32_SINT                    0x086 
+#define BRW_SURFACEFORMAT_R32G32_UINT                    0x087 
+#define BRW_SURFACEFORMAT_R32_FLOAT_X8X24_TYPELESS       0x088 
+#define BRW_SURFACEFORMAT_X32_TYPELESS_G8X24_UINT        0x089 
+#define BRW_SURFACEFORMAT_L32A32_FLOAT                   0x08A 
+#define BRW_SURFACEFORMAT_R32G32_UNORM                   0x08B 
+#define BRW_SURFACEFORMAT_R32G32_SNORM                   0x08C 
+#define BRW_SURFACEFORMAT_R64_FLOAT                      0x08D 
+#define BRW_SURFACEFORMAT_R16G16B16X16_UNORM             0x08E 
+#define BRW_SURFACEFORMAT_R16G16B16X16_FLOAT             0x08F 
+#define BRW_SURFACEFORMAT_A32X32_FLOAT                   0x090 
+#define BRW_SURFACEFORMAT_L32X32_FLOAT                   0x091 
+#define BRW_SURFACEFORMAT_I32X32_FLOAT                   0x092 
+#define BRW_SURFACEFORMAT_R16G16B16A16_SSCALED           0x093
+#define BRW_SURFACEFORMAT_R16G16B16A16_USCALED           0x094
+#define BRW_SURFACEFORMAT_R32G32_SSCALED                 0x095
+#define BRW_SURFACEFORMAT_R32G32_USCALED                 0x096
+#define BRW_SURFACEFORMAT_B8G8R8A8_UNORM                 0x0C0 
+#define BRW_SURFACEFORMAT_B8G8R8A8_UNORM_SRGB            0x0C1 
+#define BRW_SURFACEFORMAT_R10G10B10A2_UNORM              0x0C2 
+#define BRW_SURFACEFORMAT_R10G10B10A2_UNORM_SRGB         0x0C3 
+#define BRW_SURFACEFORMAT_R10G10B10A2_UINT               0x0C4 
+#define BRW_SURFACEFORMAT_R10G10B10_SNORM_A2_UNORM       0x0C5 
+#define BRW_SURFACEFORMAT_R8G8B8A8_UNORM                 0x0C7 
+#define BRW_SURFACEFORMAT_R8G8B8A8_UNORM_SRGB            0x0C8 
+#define BRW_SURFACEFORMAT_R8G8B8A8_SNORM                 0x0C9 
+#define BRW_SURFACEFORMAT_R8G8B8A8_SINT                  0x0CA 
+#define BRW_SURFACEFORMAT_R8G8B8A8_UINT                  0x0CB 
+#define BRW_SURFACEFORMAT_R16G16_UNORM                   0x0CC 
+#define BRW_SURFACEFORMAT_R16G16_SNORM                   0x0CD 
+#define BRW_SURFACEFORMAT_R16G16_SINT                    0x0CE 
+#define BRW_SURFACEFORMAT_R16G16_UINT                    0x0CF 
+#define BRW_SURFACEFORMAT_R16G16_FLOAT                   0x0D0 
+#define BRW_SURFACEFORMAT_B10G10R10A2_UNORM              0x0D1 
+#define BRW_SURFACEFORMAT_B10G10R10A2_UNORM_SRGB         0x0D2 
+#define BRW_SURFACEFORMAT_R11G11B10_FLOAT                0x0D3 
+#define BRW_SURFACEFORMAT_R32_SINT                       0x0D6 
+#define BRW_SURFACEFORMAT_R32_UINT                       0x0D7 
+#define BRW_SURFACEFORMAT_R32_FLOAT                      0x0D8 
+#define BRW_SURFACEFORMAT_R24_UNORM_X8_TYPELESS          0x0D9 
+#define BRW_SURFACEFORMAT_X24_TYPELESS_G8_UINT           0x0DA 
+#define BRW_SURFACEFORMAT_L16A16_UNORM                   0x0DF 
+#define BRW_SURFACEFORMAT_I24X8_UNORM                    0x0E0 
+#define BRW_SURFACEFORMAT_L24X8_UNORM                    0x0E1 
+#define BRW_SURFACEFORMAT_A24X8_UNORM                    0x0E2 
+#define BRW_SURFACEFORMAT_I32_FLOAT                      0x0E3 
+#define BRW_SURFACEFORMAT_L32_FLOAT                      0x0E4 
+#define BRW_SURFACEFORMAT_A32_FLOAT                      0x0E5 
+#define BRW_SURFACEFORMAT_B8G8R8X8_UNORM                 0x0E9 
+#define BRW_SURFACEFORMAT_B8G8R8X8_UNORM_SRGB            0x0EA 
+#define BRW_SURFACEFORMAT_R8G8B8X8_UNORM                 0x0EB 
+#define BRW_SURFACEFORMAT_R8G8B8X8_UNORM_SRGB            0x0EC 
+#define BRW_SURFACEFORMAT_R9G9B9E5_SHAREDEXP             0x0ED 
+#define BRW_SURFACEFORMAT_B10G10R10X2_UNORM              0x0EE 
+#define BRW_SURFACEFORMAT_L16A16_FLOAT                   0x0F0 
+#define BRW_SURFACEFORMAT_R32_UNORM                      0x0F1 
+#define BRW_SURFACEFORMAT_R32_SNORM                      0x0F2 
+#define BRW_SURFACEFORMAT_R10G10B10X2_USCALED            0x0F3
+#define BRW_SURFACEFORMAT_R8G8B8A8_SSCALED               0x0F4
+#define BRW_SURFACEFORMAT_R8G8B8A8_USCALED               0x0F5
+#define BRW_SURFACEFORMAT_R16G16_SSCALED                 0x0F6
+#define BRW_SURFACEFORMAT_R16G16_USCALED                 0x0F7
+#define BRW_SURFACEFORMAT_R32_SSCALED                    0x0F8
+#define BRW_SURFACEFORMAT_R32_USCALED                    0x0F9
+#define BRW_SURFACEFORMAT_B5G6R5_UNORM                   0x100 
+#define BRW_SURFACEFORMAT_B5G6R5_UNORM_SRGB              0x101 
+#define BRW_SURFACEFORMAT_B5G5R5A1_UNORM                 0x102 
+#define BRW_SURFACEFORMAT_B5G5R5A1_UNORM_SRGB            0x103 
+#define BRW_SURFACEFORMAT_B4G4R4A4_UNORM                 0x104 
+#define BRW_SURFACEFORMAT_B4G4R4A4_UNORM_SRGB            0x105 
+#define BRW_SURFACEFORMAT_R8G8_UNORM                     0x106 
+#define BRW_SURFACEFORMAT_R8G8_SNORM                     0x107 
+#define BRW_SURFACEFORMAT_R8G8_SINT                      0x108 
+#define BRW_SURFACEFORMAT_R8G8_UINT                      0x109 
+#define BRW_SURFACEFORMAT_R16_UNORM                      0x10A 
+#define BRW_SURFACEFORMAT_R16_SNORM                      0x10B 
+#define BRW_SURFACEFORMAT_R16_SINT                       0x10C 
+#define BRW_SURFACEFORMAT_R16_UINT                       0x10D 
+#define BRW_SURFACEFORMAT_R16_FLOAT                      0x10E 
+#define BRW_SURFACEFORMAT_I16_UNORM                      0x111 
+#define BRW_SURFACEFORMAT_L16_UNORM                      0x112 
+#define BRW_SURFACEFORMAT_A16_UNORM                      0x113 
+#define BRW_SURFACEFORMAT_L8A8_UNORM                     0x114 
+#define BRW_SURFACEFORMAT_I16_FLOAT                      0x115
+#define BRW_SURFACEFORMAT_L16_FLOAT                      0x116
+#define BRW_SURFACEFORMAT_A16_FLOAT                      0x117 
+#define BRW_SURFACEFORMAT_R5G5_SNORM_B6_UNORM            0x119 
+#define BRW_SURFACEFORMAT_B5G5R5X1_UNORM                 0x11A 
+#define BRW_SURFACEFORMAT_B5G5R5X1_UNORM_SRGB            0x11B
+#define BRW_SURFACEFORMAT_R8G8_SSCALED                   0x11C
+#define BRW_SURFACEFORMAT_R8G8_USCALED                   0x11D
+#define BRW_SURFACEFORMAT_R16_SSCALED                    0x11E
+#define BRW_SURFACEFORMAT_R16_USCALED                    0x11F
+#define BRW_SURFACEFORMAT_R8_UNORM                       0x140 
+#define BRW_SURFACEFORMAT_R8_SNORM                       0x141 
+#define BRW_SURFACEFORMAT_R8_SINT                        0x142 
+#define BRW_SURFACEFORMAT_R8_UINT                        0x143 
+#define BRW_SURFACEFORMAT_A8_UNORM                       0x144 
+#define BRW_SURFACEFORMAT_I8_UNORM                       0x145 
+#define BRW_SURFACEFORMAT_L8_UNORM                       0x146 
+#define BRW_SURFACEFORMAT_P4A4_UNORM                     0x147 
+#define BRW_SURFACEFORMAT_A4P4_UNORM                     0x148
+#define BRW_SURFACEFORMAT_R8_SSCALED                     0x149
+#define BRW_SURFACEFORMAT_R8_USCALED                     0x14A
+#define BRW_SURFACEFORMAT_R1_UINT                        0x181 
+#define BRW_SURFACEFORMAT_YCRCB_NORMAL                   0x182 
+#define BRW_SURFACEFORMAT_YCRCB_SWAPUVY                  0x183 
+#define BRW_SURFACEFORMAT_BC1_UNORM                      0x186 
+#define BRW_SURFACEFORMAT_BC2_UNORM                      0x187 
+#define BRW_SURFACEFORMAT_BC3_UNORM                      0x188 
+#define BRW_SURFACEFORMAT_BC4_UNORM                      0x189 
+#define BRW_SURFACEFORMAT_BC5_UNORM                      0x18A 
+#define BRW_SURFACEFORMAT_BC1_UNORM_SRGB                 0x18B 
+#define BRW_SURFACEFORMAT_BC2_UNORM_SRGB                 0x18C 
+#define BRW_SURFACEFORMAT_BC3_UNORM_SRGB                 0x18D 
+#define BRW_SURFACEFORMAT_MONO8                          0x18E 
+#define BRW_SURFACEFORMAT_YCRCB_SWAPUV                   0x18F 
+#define BRW_SURFACEFORMAT_YCRCB_SWAPY                    0x190 
+#define BRW_SURFACEFORMAT_DXT1_RGB                       0x191 
+#define BRW_SURFACEFORMAT_FXT1                           0x192 
+#define BRW_SURFACEFORMAT_R8G8B8_UNORM                   0x193 
+#define BRW_SURFACEFORMAT_R8G8B8_SNORM                   0x194 
+#define BRW_SURFACEFORMAT_R8G8B8_SSCALED                 0x195 
+#define BRW_SURFACEFORMAT_R8G8B8_USCALED                 0x196 
+#define BRW_SURFACEFORMAT_R64G64B64A64_FLOAT             0x197 
+#define BRW_SURFACEFORMAT_R64G64B64_FLOAT                0x198 
+#define BRW_SURFACEFORMAT_BC4_SNORM                      0x199 
+#define BRW_SURFACEFORMAT_BC5_SNORM                      0x19A 
+#define BRW_SURFACEFORMAT_R16G16B16_UNORM                0x19C 
+#define BRW_SURFACEFORMAT_R16G16B16_SNORM                0x19D 
+#define BRW_SURFACEFORMAT_R16G16B16_SSCALED              0x19E 
+#define BRW_SURFACEFORMAT_R16G16B16_USCALED              0x19F
+
+#define BRW_SURFACERETURNFORMAT_FLOAT32  0
+#define BRW_SURFACERETURNFORMAT_S1       1
+
+#define BRW_SURFACE_1D      0
+#define BRW_SURFACE_2D      1
+#define BRW_SURFACE_3D      2
+#define BRW_SURFACE_CUBE    3
+#define BRW_SURFACE_BUFFER  4
+#define BRW_SURFACE_NULL    7
+
+#define BRW_TEXCOORDMODE_WRAP            0
+#define BRW_TEXCOORDMODE_MIRROR          1
+#define BRW_TEXCOORDMODE_CLAMP           2
+#define BRW_TEXCOORDMODE_CUBE            3
+#define BRW_TEXCOORDMODE_CLAMP_BORDER    4
+#define BRW_TEXCOORDMODE_MIRROR_ONCE     5
+
+#define BRW_THREAD_PRIORITY_NORMAL   0
+#define BRW_THREAD_PRIORITY_HIGH     1
+
+#define BRW_TILEWALK_XMAJOR                 0
+#define BRW_TILEWALK_YMAJOR                 1
+
+#define BRW_VERTEX_SUBPIXEL_PRECISION_8BITS  0
+#define BRW_VERTEX_SUBPIXEL_PRECISION_4BITS  1
+
+#define BRW_VERTEXBUFFER_ACCESS_VERTEXDATA     0
+#define BRW_VERTEXBUFFER_ACCESS_INSTANCEDATA   1
+
+#define BRW_VFCOMPONENT_NOSTORE      0
+#define BRW_VFCOMPONENT_STORE_SRC    1
+#define BRW_VFCOMPONENT_STORE_0      2
+#define BRW_VFCOMPONENT_STORE_1_FLT  3
+#define BRW_VFCOMPONENT_STORE_1_INT  4
+#define BRW_VFCOMPONENT_STORE_VID    5
+#define BRW_VFCOMPONENT_STORE_IID    6
+#define BRW_VFCOMPONENT_STORE_PID    7
+
+
+
+/* Execution Unit (EU) defines
+ */
+
+#define BRW_ALIGN_1   0
+#define BRW_ALIGN_16  1
+
+#define BRW_ADDRESS_DIRECT                        0
+#define BRW_ADDRESS_REGISTER_INDIRECT_REGISTER    1
+
+#define BRW_CHANNEL_X     0
+#define BRW_CHANNEL_Y     1
+#define BRW_CHANNEL_Z     2
+#define BRW_CHANNEL_W     3
+
+#define BRW_COMPRESSION_NONE          0
+#define BRW_COMPRESSION_2NDHALF       1
+#define BRW_COMPRESSION_COMPRESSED    2
+
+#define BRW_CONDITIONAL_NONE  0
+#define BRW_CONDITIONAL_Z     1
+#define BRW_CONDITIONAL_NZ    2
+#define BRW_CONDITIONAL_EQ    1	/* Z */
+#define BRW_CONDITIONAL_NEQ   2	/* NZ */
+#define BRW_CONDITIONAL_G     3
+#define BRW_CONDITIONAL_GE    4
+#define BRW_CONDITIONAL_L     5
+#define BRW_CONDITIONAL_LE    6
+#define BRW_CONDITIONAL_C     7
+#define BRW_CONDITIONAL_O     8
+
+#define BRW_DEBUG_NONE        0
+#define BRW_DEBUG_BREAKPOINT  1
+
+#define BRW_DEPENDENCY_NORMAL         0
+#define BRW_DEPENDENCY_NOTCLEARED     1
+#define BRW_DEPENDENCY_NOTCHECKED     2
+#define BRW_DEPENDENCY_DISABLE        3
+
+#define BRW_EXECUTE_1     0
+#define BRW_EXECUTE_2     1
+#define BRW_EXECUTE_4     2
+#define BRW_EXECUTE_8     3
+#define BRW_EXECUTE_16    4
+#define BRW_EXECUTE_32    5
+
+#define BRW_HORIZONTAL_STRIDE_0   0
+#define BRW_HORIZONTAL_STRIDE_1   1
+#define BRW_HORIZONTAL_STRIDE_2   2
+#define BRW_HORIZONTAL_STRIDE_4   3
+
+#define BRW_INSTRUCTION_NORMAL    0
+#define BRW_INSTRUCTION_SATURATE  1
+
+#define BRW_MASK_ENABLE   0
+#define BRW_MASK_DISABLE  1
+
+#define BRW_OPCODE_MOV        1
+#define BRW_OPCODE_SEL        2
+#define BRW_OPCODE_NOT        4
+#define BRW_OPCODE_AND        5
+#define BRW_OPCODE_OR         6
+#define BRW_OPCODE_XOR        7
+#define BRW_OPCODE_SHR        8
+#define BRW_OPCODE_SHL        9
+#define BRW_OPCODE_RSR        10
+#define BRW_OPCODE_RSL        11
+#define BRW_OPCODE_ASR        12
+#define BRW_OPCODE_CMP        16
+#define BRW_OPCODE_JMPI       32
+#define BRW_OPCODE_IF         34
+#define BRW_OPCODE_IFF        35
+#define BRW_OPCODE_ELSE       36
+#define BRW_OPCODE_ENDIF      37
+#define BRW_OPCODE_DO         38
+#define BRW_OPCODE_WHILE      39
+#define BRW_OPCODE_BREAK      40
+#define BRW_OPCODE_CONTINUE   41
+#define BRW_OPCODE_HALT       42
+#define BRW_OPCODE_MSAVE      44
+#define BRW_OPCODE_MRESTORE   45
+#define BRW_OPCODE_PUSH       46
+#define BRW_OPCODE_POP        47
+#define BRW_OPCODE_WAIT       48
+#define BRW_OPCODE_SEND       49
+#define BRW_OPCODE_ADD        64
+#define BRW_OPCODE_MUL        65
+#define BRW_OPCODE_AVG        66
+#define BRW_OPCODE_FRC        67
+#define BRW_OPCODE_RNDU       68
+#define BRW_OPCODE_RNDD       69
+#define BRW_OPCODE_RNDE       70
+#define BRW_OPCODE_RNDZ       71
+#define BRW_OPCODE_MAC        72
+#define BRW_OPCODE_MACH       73
+#define BRW_OPCODE_LZD        74
+#define BRW_OPCODE_SAD2       80
+#define BRW_OPCODE_SADA2      81
+#define BRW_OPCODE_DP4        84
+#define BRW_OPCODE_DPH        85
+#define BRW_OPCODE_DP3        86
+#define BRW_OPCODE_DP2        87
+#define BRW_OPCODE_DPA2       88
+#define BRW_OPCODE_LINE       89
+#define BRW_OPCODE_NOP        126
+
+#define BRW_PREDICATE_NONE             0
+#define BRW_PREDICATE_NORMAL           1
+#define BRW_PREDICATE_ALIGN1_ANYV             2
+#define BRW_PREDICATE_ALIGN1_ALLV             3
+#define BRW_PREDICATE_ALIGN1_ANY2H            4
+#define BRW_PREDICATE_ALIGN1_ALL2H            5
+#define BRW_PREDICATE_ALIGN1_ANY4H            6
+#define BRW_PREDICATE_ALIGN1_ALL4H            7
+#define BRW_PREDICATE_ALIGN1_ANY8H            8
+#define BRW_PREDICATE_ALIGN1_ALL8H            9
+#define BRW_PREDICATE_ALIGN1_ANY16H           10
+#define BRW_PREDICATE_ALIGN1_ALL16H           11
+#define BRW_PREDICATE_ALIGN16_REPLICATE_X     2
+#define BRW_PREDICATE_ALIGN16_REPLICATE_Y     3
+#define BRW_PREDICATE_ALIGN16_REPLICATE_Z     4
+#define BRW_PREDICATE_ALIGN16_REPLICATE_W     5
+#define BRW_PREDICATE_ALIGN16_ANY4H           6
+#define BRW_PREDICATE_ALIGN16_ALL4H           7
+
+#define BRW_ARCHITECTURE_REGISTER_FILE    0
+#define BRW_GENERAL_REGISTER_FILE         1
+#define BRW_MESSAGE_REGISTER_FILE         2
+#define BRW_IMMEDIATE_VALUE               3
+
+#define BRW_REGISTER_TYPE_UD  0
+#define BRW_REGISTER_TYPE_D   1
+#define BRW_REGISTER_TYPE_UW  2
+#define BRW_REGISTER_TYPE_W   3
+#define BRW_REGISTER_TYPE_UB  4
+#define BRW_REGISTER_TYPE_B   5
+#define BRW_REGISTER_TYPE_VF  5	/* packed float vector, immediates only? */
+#define BRW_REGISTER_TYPE_HF  6
+#define BRW_REGISTER_TYPE_V   6	/* packed int vector, immediates only, uword dest only */
+#define BRW_REGISTER_TYPE_F   7
+
+#define BRW_ARF_NULL                  0x00
+#define BRW_ARF_ADDRESS               0x10
+#define BRW_ARF_ACCUMULATOR           0x20   
+#define BRW_ARF_FLAG                  0x30
+#define BRW_ARF_MASK                  0x40
+#define BRW_ARF_MASK_STACK            0x50
+#define BRW_ARF_MASK_STACK_DEPTH      0x60
+#define BRW_ARF_STATE                 0x70
+#define BRW_ARF_CONTROL               0x80
+#define BRW_ARF_NOTIFICATION_COUNT    0x90
+#define BRW_ARF_IP                    0xA0
+
+#define BRW_AMASK   0
+#define BRW_IMASK   1
+#define BRW_LMASK   2
+#define BRW_CMASK   3
+
+
+
+#define BRW_THREAD_NORMAL     0
+#define BRW_THREAD_ATOMIC     1
+#define BRW_THREAD_SWITCH     2
+
+#define BRW_VERTICAL_STRIDE_0                 0
+#define BRW_VERTICAL_STRIDE_1                 1
+#define BRW_VERTICAL_STRIDE_2                 2
+#define BRW_VERTICAL_STRIDE_4                 3
+#define BRW_VERTICAL_STRIDE_8                 4
+#define BRW_VERTICAL_STRIDE_16                5
+#define BRW_VERTICAL_STRIDE_32                6
+#define BRW_VERTICAL_STRIDE_64                7
+#define BRW_VERTICAL_STRIDE_128               8
+#define BRW_VERTICAL_STRIDE_256               9
+#define BRW_VERTICAL_STRIDE_ONE_DIMENSIONAL   0xF
+
+#define BRW_WIDTH_1       0
+#define BRW_WIDTH_2       1
+#define BRW_WIDTH_4       2
+#define BRW_WIDTH_8       3
+#define BRW_WIDTH_16      4
+
+#define BRW_STATELESS_BUFFER_BOUNDARY_1K      0
+#define BRW_STATELESS_BUFFER_BOUNDARY_2K      1
+#define BRW_STATELESS_BUFFER_BOUNDARY_4K      2
+#define BRW_STATELESS_BUFFER_BOUNDARY_8K      3
+#define BRW_STATELESS_BUFFER_BOUNDARY_16K     4
+#define BRW_STATELESS_BUFFER_BOUNDARY_32K     5
+#define BRW_STATELESS_BUFFER_BOUNDARY_64K     6
+#define BRW_STATELESS_BUFFER_BOUNDARY_128K    7
+#define BRW_STATELESS_BUFFER_BOUNDARY_256K    8
+#define BRW_STATELESS_BUFFER_BOUNDARY_512K    9
+#define BRW_STATELESS_BUFFER_BOUNDARY_1M      10
+#define BRW_STATELESS_BUFFER_BOUNDARY_2M      11
+
+#define BRW_POLYGON_FACING_FRONT      0
+#define BRW_POLYGON_FACING_BACK       1
+
+#define BRW_MESSAGE_TARGET_NULL               0
+#define BRW_MESSAGE_TARGET_MATH               1
+#define BRW_MESSAGE_TARGET_SAMPLER            2
+#define BRW_MESSAGE_TARGET_GATEWAY            3
+#define BRW_MESSAGE_TARGET_DATAPORT_READ      4
+#define BRW_MESSAGE_TARGET_DATAPORT_WRITE     5
+#define BRW_MESSAGE_TARGET_URB                6
+#define BRW_MESSAGE_TARGET_THREAD_SPAWNER     7
+
+#define BRW_SAMPLER_RETURN_FORMAT_FLOAT32     0
+#define BRW_SAMPLER_RETURN_FORMAT_UINT32      2
+#define BRW_SAMPLER_RETURN_FORMAT_SINT32      3
+
+#define BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE              0
+#define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE             0
+#define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS        0
+#define BRW_SAMPLER_MESSAGE_SIMD8_KILLPIX             1
+#define BRW_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_LOD        1
+#define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_LOD         1
+#define BRW_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_GRADIENTS  2
+#define BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_GRADIENTS    2
+#define BRW_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_COMPARE    0
+#define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_COMPARE     2
+#define BRW_SAMPLER_MESSAGE_SIMD4X2_RESINFO           2
+#define BRW_SAMPLER_MESSAGE_SIMD8_RESINFO             2
+#define BRW_SAMPLER_MESSAGE_SIMD16_RESINFO            2
+#define BRW_SAMPLER_MESSAGE_SIMD4X2_LD                3
+#define BRW_SAMPLER_MESSAGE_SIMD8_LD                  3
+#define BRW_SAMPLER_MESSAGE_SIMD16_LD                 3
+
+#define BRW_DATAPORT_OWORD_BLOCK_1_OWORDLOW   0
+#define BRW_DATAPORT_OWORD_BLOCK_1_OWORDHIGH  1
+#define BRW_DATAPORT_OWORD_BLOCK_2_OWORDS     2
+#define BRW_DATAPORT_OWORD_BLOCK_4_OWORDS     3
+#define BRW_DATAPORT_OWORD_BLOCK_8_OWORDS     4
+
+#define BRW_DATAPORT_OWORD_DUAL_BLOCK_1OWORD     0
+#define BRW_DATAPORT_OWORD_DUAL_BLOCK_4OWORDS    2
+
+#define BRW_DATAPORT_DWORD_SCATTERED_BLOCK_8DWORDS   2
+#define BRW_DATAPORT_DWORD_SCATTERED_BLOCK_16DWORDS  3
+
+#define BRW_DATAPORT_READ_MESSAGE_OWORD_BLOCK_READ          0
+#define BRW_DATAPORT_READ_MESSAGE_OWORD_DUAL_BLOCK_READ     1
+#define BRW_DATAPORT_READ_MESSAGE_DWORD_BLOCK_READ          2
+#define BRW_DATAPORT_READ_MESSAGE_DWORD_SCATTERED_READ      3
+
+#define BRW_DATAPORT_READ_TARGET_DATA_CACHE      0
+#define BRW_DATAPORT_READ_TARGET_RENDER_CACHE    1
+#define BRW_DATAPORT_READ_TARGET_SAMPLER_CACHE   2
+
+#define BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD16_SINGLE_SOURCE                0
+#define BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD16_SINGLE_SOURCE_REPLICATED     1
+#define BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD8_DUAL_SOURCE_SUBSPAN01         2
+#define BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD8_DUAL_SOURCE_SUBSPAN23         3
+#define BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD8_SINGLE_SOURCE_SUBSPAN01       4
+
+#define BRW_DATAPORT_WRITE_MESSAGE_OWORD_BLOCK_WRITE                0
+#define BRW_DATAPORT_WRITE_MESSAGE_OWORD_DUAL_BLOCK_WRITE           1
+#define BRW_DATAPORT_WRITE_MESSAGE_DWORD_BLOCK_WRITE                2
+#define BRW_DATAPORT_WRITE_MESSAGE_DWORD_SCATTERED_WRITE            3
+#define BRW_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE              4
+#define BRW_DATAPORT_WRITE_MESSAGE_STREAMED_VERTEX_BUFFER_WRITE     5
+#define BRW_DATAPORT_WRITE_MESSAGE_FLUSH_RENDER_CACHE               7
+
+#define BRW_MATH_FUNCTION_INV                              1
+#define BRW_MATH_FUNCTION_LOG                              2
+#define BRW_MATH_FUNCTION_EXP                              3
+#define BRW_MATH_FUNCTION_SQRT                             4
+#define BRW_MATH_FUNCTION_RSQ                              5
+#define BRW_MATH_FUNCTION_SIN                              6 /* was 7 */
+#define BRW_MATH_FUNCTION_COS                              7 /* was 8 */
+#define BRW_MATH_FUNCTION_SINCOS                           8 /* was 6 */
+#define BRW_MATH_FUNCTION_TAN                              9
+#define BRW_MATH_FUNCTION_POW                              10
+#define BRW_MATH_FUNCTION_INT_DIV_QUOTIENT_AND_REMAINDER   11
+#define BRW_MATH_FUNCTION_INT_DIV_QUOTIENT                 12
+#define BRW_MATH_FUNCTION_INT_DIV_REMAINDER                13
+
+#define BRW_MATH_INTEGER_UNSIGNED     0
+#define BRW_MATH_INTEGER_SIGNED       1
+
+#define BRW_MATH_PRECISION_FULL        0
+#define BRW_MATH_PRECISION_PARTIAL     1
+
+#define BRW_MATH_SATURATE_NONE         0
+#define BRW_MATH_SATURATE_SATURATE     1
+
+#define BRW_MATH_DATA_VECTOR  0
+#define BRW_MATH_DATA_SCALAR  1
+
+#define BRW_URB_OPCODE_WRITE  0
+
+#define BRW_URB_SWIZZLE_NONE          0
+#define BRW_URB_SWIZZLE_INTERLEAVE    1
+#define BRW_URB_SWIZZLE_TRANSPOSE     2
+
+#define BRW_SCRATCH_SPACE_SIZE_1K     0
+#define BRW_SCRATCH_SPACE_SIZE_2K     1
+#define BRW_SCRATCH_SPACE_SIZE_4K     2
+#define BRW_SCRATCH_SPACE_SIZE_8K     3
+#define BRW_SCRATCH_SPACE_SIZE_16K    4
+#define BRW_SCRATCH_SPACE_SIZE_32K    5
+#define BRW_SCRATCH_SPACE_SIZE_64K    6
+#define BRW_SCRATCH_SPACE_SIZE_128K   7
+#define BRW_SCRATCH_SPACE_SIZE_256K   8
+#define BRW_SCRATCH_SPACE_SIZE_512K   9
+#define BRW_SCRATCH_SPACE_SIZE_1M     10
+#define BRW_SCRATCH_SPACE_SIZE_2M     11
+
+
+
+
+#define CMD_URB_FENCE                 0x6000
+#define CMD_CONST_BUFFER_STATE        0x6001
+#define CMD_CONST_BUFFER              0x6002
+
+#define CMD_STATE_BASE_ADDRESS        0x6101
+#define CMD_STATE_INSN_POINTER        0x6102
+#define CMD_PIPELINE_SELECT           0x6104
+
+#define CMD_PIPELINED_STATE_POINTERS  0x7800
+#define CMD_BINDING_TABLE_PTRS        0x7801
+#define CMD_VERTEX_BUFFER             0x7808
+#define CMD_VERTEX_ELEMENT            0x7809
+#define CMD_INDEX_BUFFER              0x780a
+#define CMD_VF_STATISTICS             0x780b
+
+#define CMD_DRAW_RECT                 0x7900
+#define CMD_BLEND_CONSTANT_COLOR      0x7901
+#define CMD_CHROMA_KEY                0x7904
+#define CMD_DEPTH_BUFFER              0x7905
+#define CMD_POLY_STIPPLE_OFFSET       0x7906
+#define CMD_POLY_STIPPLE_PATTERN      0x7907
+#define CMD_LINE_STIPPLE_PATTERN      0x7908
+#define CMD_GLOBAL_DEPTH_OFFSET_CLAMP 0x7908
+
+#define CMD_PIPE_CONTROL              0x7a00
+
+#define CMD_3D_PRIM                   0x7b00
+
+#define CMD_MI_FLUSH                  0x0200
+
+
+/* Various values from the R0 vertex header:
+ */
+#define R02_PRIM_END    0x1
+#define R02_PRIM_START  0x2
+
+
+
+#endif
diff --git a/src/brw_structs.h b/src/brw_structs.h
new file mode 100644
index 0000000..1c59716
--- /dev/null
+++ b/src/brw_structs.h
@@ -0,0 +1,1325 @@
+ /**************************************************************************
+ * 
+ * Copyright 2005 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * 
+ * 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, sub license, 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 NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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.
+ * 
+ **************************************************************************/
+
+#ifndef BRW_STRUCTS_H
+#define BRW_STRUCTS_H
+
+/* Command packets:
+ */
+struct header 
+{
+   GLuint length:16; 
+   GLuint opcode:16; 
+} bits;
+
+
+union header_union
+{
+   struct header bits;
+   GLuint dword;
+};
+
+struct brw_3d_control
+{   
+   struct 
+   {
+      GLuint length:8;
+      GLuint notify_enable:1;
+      GLuint pad:3;
+      GLuint wc_flush_enable:1; 
+      GLuint depth_stall_enable:1; 
+      GLuint operation:2; 
+      GLuint opcode:16; 
+   } header;
+   
+   struct
+   {
+      GLuint pad:2;
+      GLuint dest_addr_type:1; 
+      GLuint dest_addr:29; 
+   } dest;
+   
+   GLuint dword2;   
+   GLuint dword3;   
+};
+
+
+struct brw_3d_primitive
+{
+   struct
+   {
+      GLuint length:8; 
+      GLuint pad:2;
+      GLuint topology:5; 
+      GLuint indexed:1; 
+      GLuint opcode:16; 
+   } header;
+
+   GLuint verts_per_instance;  
+   GLuint start_vert_location;  
+   GLuint instance_count;  
+   GLuint start_instance_location;  
+   GLuint base_vert_location;  
+};
+
+/* These seem to be passed around as function args, so it works out
+ * better to keep them as #defines:
+ */
+#define BRW_FLUSH_READ_CACHE           0x1
+#define BRW_FLUSH_STATE_CACHE          0x2
+#define BRW_INHIBIT_FLUSH_RENDER_CACHE 0x4
+#define BRW_FLUSH_SNAPSHOT_COUNTERS    0x8
+
+struct brw_mi_flush
+{
+   GLuint flags:4;
+   GLuint pad:12;
+   GLuint opcode:16;
+};
+
+struct brw_vf_statistics
+{
+   GLuint statistics_enable:1;
+   GLuint pad:15;
+   GLuint opcode:16;
+};
+
+
+
+struct brw_binding_table_pointers
+{
+   struct header header;
+   GLuint vs; 
+   GLuint gs; 
+   GLuint clp; 
+   GLuint sf; 
+   GLuint wm; 
+};
+
+
+struct brw_blend_constant_color
+{
+   struct header header;
+   GLfloat blend_constant_color[4];  
+};
+
+
+struct brw_depthbuffer
+{
+   union header_union header;
+   
+   union {
+      struct {
+	 GLuint pitch:18; 
+	 GLuint format:3; 
+	 GLuint pad:4;
+	 GLuint depth_offset_disable:1; 
+	 GLuint tile_walk:1; 
+	 GLuint tiled_surface:1; 
+	 GLuint pad2:1;
+	 GLuint surface_type:3; 
+      } bits;
+      GLuint dword;
+   } dword1;
+   
+   GLuint dword2_base_addr; 
+ 
+   union {
+      struct {
+	 GLuint pad:1;
+	 GLuint mipmap_layout:1; 
+	 GLuint lod:4; 
+	 GLuint width:13; 
+	 GLuint height:13; 
+      } bits;
+      GLuint dword;
+   } dword3;
+
+   union {
+      struct {
+	 GLuint pad:12;
+	 GLuint min_array_element:9; 
+	 GLuint depth:11; 
+      } bits;
+      GLuint dword;
+   } dword4;
+};
+
+struct brw_drawrect
+{
+   struct header header;
+   GLuint xmin:16; 
+   GLuint ymin:16; 
+   GLuint xmax:16; 
+   GLuint ymax:16; 
+   GLuint xorg:16;  
+   GLuint yorg:16;  
+};
+
+
+
+
+struct brw_global_depth_offset_clamp
+{
+   struct header header;
+   GLfloat depth_offset_clamp;  
+};
+
+struct brw_indexbuffer
+{   
+   union {
+      struct
+      {
+	 GLuint length:8; 
+	 GLuint index_format:2; 
+	 GLuint cut_index_enable:1; 
+	 GLuint pad:5; 
+	 GLuint opcode:16; 
+      } bits;
+      GLuint dword;
+
+   } header;
+
+   GLuint buffer_start; 
+   GLuint buffer_end; 
+};
+
+
+struct brw_line_stipple
+{   
+   struct header header;
+  
+   struct
+   {
+      GLuint pattern:16; 
+      GLuint pad:16;
+   } bits0;
+   
+   struct
+   {
+      GLuint repeat_count:9; 
+      GLuint pad:7;
+      GLuint inverse_repeat_count:16; 
+   } bits1;
+};
+
+
+struct brw_pipelined_state_pointers
+{
+   struct header header;
+   
+   struct {
+      GLuint pad:5;
+      GLuint offset:27; 
+   } vs;
+   
+   struct
+   {
+      GLuint enable:1;
+      GLuint pad:4;
+      GLuint offset:27; 
+   } gs;
+   
+   struct
+   {
+      GLuint enable:1;
+      GLuint pad:4;
+      GLuint offset:27; 
+   } clp;
+   
+   struct
+   {
+      GLuint pad:5;
+      GLuint offset:27; 
+   } sf;
+
+   struct
+   {
+      GLuint pad:5;
+      GLuint offset:27; 
+   } wm;
+   
+   struct
+   {
+      GLuint pad:5;
+      GLuint offset:27; /* KW: check me! */
+   } cc;
+};
+
+
+struct brw_polygon_stipple_offset
+{
+   struct header header;
+
+   struct {
+      GLuint y_offset:5; 
+      GLuint pad:3;
+      GLuint x_offset:5; 
+      GLuint pad0:19;
+   } bits0;
+};
+
+
+
+struct brw_polygon_stipple
+{
+   struct header header;
+   GLuint stipple[32];
+};
+
+
+
+struct brw_pipeline_select
+{
+   struct
+   {
+      GLuint pipeline_select:1;   
+      GLuint pad:15;
+      GLuint opcode:16;   
+   } header;
+};
+
+
+struct brw_pipe_control
+{
+   struct
+   {
+      GLuint length:8;
+      GLuint notify_enable:1;
+      GLuint pad:2;
+      GLuint instruction_state_cache_flush_enable:1;
+      GLuint write_cache_flush_enable:1;
+      GLuint depth_stall_enable:1;
+      GLuint post_sync_operation:2;
+
+      GLuint opcode:16;
+   } header;
+
+   struct
+   {
+      GLuint pad:2;
+      GLuint dest_addr_type:1;
+      GLuint dest_addr:29;
+   } bits1;
+
+   GLuint data0;
+   GLuint data1;
+};
+
+
+struct brw_urb_fence
+{
+   struct
+   {
+      GLuint length:8;   
+      GLuint vs_realloc:1;   
+      GLuint gs_realloc:1;   
+      GLuint clp_realloc:1;   
+      GLuint sf_realloc:1;   
+      GLuint vfe_realloc:1;   
+      GLuint cs_realloc:1;   
+      GLuint pad:2;
+      GLuint opcode:16;   
+   } header;
+
+   struct
+   {
+      GLuint vs_fence:10;  
+      GLuint gs_fence:10;  
+      GLuint clp_fence:10;  
+      GLuint pad:2;
+   } bits0;
+
+   struct
+   {
+      GLuint sf_fence:10;  
+      GLuint vf_fence:10;  
+      GLuint cs_fence:10;  
+      GLuint pad:2;
+   } bits1;
+};
+
+struct brw_constant_buffer_state /* previously brw_command_streamer */
+{
+   struct header header;
+
+   struct
+   {
+      GLuint nr_urb_entries:3;   
+      GLuint pad:1;
+      GLuint urb_entry_size:5;   
+      GLuint pad0:23;
+   } bits0;
+};
+
+struct brw_constant_buffer
+{
+   struct
+   {
+      GLuint length:8;   
+      GLuint valid:1;   
+      GLuint pad:7;
+      GLuint opcode:16;   
+   } header;
+
+   struct
+   {
+      GLuint buffer_length:6;   
+      GLuint buffer_address:26;  
+   } bits0;
+};
+
+struct brw_state_base_address
+{
+   struct header header;
+
+   struct
+   {
+      GLuint modify_enable:1;
+      GLuint pad:4;
+      GLuint general_state_address:27;  
+   } bits0;
+
+   struct
+   {
+      GLuint modify_enable:1;
+      GLuint pad:4;
+      GLuint surface_state_address:27;  
+   } bits1;
+
+   struct
+   {
+      GLuint modify_enable:1;
+      GLuint pad:4;
+      GLuint indirect_object_state_address:27;  
+   } bits2;
+
+   struct
+   {
+      GLuint modify_enable:1;
+      GLuint pad:11;
+      GLuint general_state_upper_bound:20;  
+   } bits3;
+
+   struct
+   {
+      GLuint modify_enable:1;
+      GLuint pad:11;
+      GLuint indirect_object_state_upper_bound:20;  
+   } bits4;
+};
+
+struct brw_state_prefetch
+{
+   struct header header;
+
+   struct
+   {
+      GLuint prefetch_count:3;   
+      GLuint pad:3;
+      GLuint prefetch_pointer:26;  
+   } bits0;
+};
+
+struct brw_system_instruction_pointer
+{
+   struct header header;
+
+   struct
+   {
+      GLuint pad:4;
+      GLuint system_instruction_pointer:28;  
+   } bits0;
+};
+
+
+
+
+/* State structs for the various fixed function units:
+ */
+
+
+struct thread0
+{
+   GLuint pad0:1;
+   GLuint grf_reg_count:3; 
+   GLuint pad1:2;
+   GLuint kernel_start_pointer:26; 
+};
+
+struct thread1
+{
+   GLuint ext_halt_exception_enable:1; 
+   GLuint sw_exception_enable:1; 
+   GLuint mask_stack_exception_enable:1; 
+   GLuint timeout_exception_enable:1; 
+   GLuint illegal_op_exception_enable:1; 
+   GLuint pad0:3;
+   GLuint depth_coef_urb_read_offset:6;	/* WM only */
+   GLuint pad1:2;
+   GLuint floating_point_mode:1; 
+   GLuint thread_priority:1; 
+   GLuint binding_table_entry_count:8; 
+   GLuint pad3:5;
+   GLuint single_program_flow:1; 
+};
+
+struct thread2
+{
+   GLuint per_thread_scratch_space:4; 
+   GLuint pad0:6;
+   GLuint scratch_space_base_pointer:22; 
+};
+
+   
+struct thread3
+{
+   GLuint dispatch_grf_start_reg:4; 
+   GLuint urb_entry_read_offset:6; 
+   GLuint pad0:1;
+   GLuint urb_entry_read_length:6; 
+   GLuint pad1:1;
+   GLuint const_urb_entry_read_offset:6; 
+   GLuint pad2:1;
+   GLuint const_urb_entry_read_length:6; 
+   GLuint pad3:1;
+};
+
+
+
+struct brw_clip_unit_state
+{
+   struct thread0 thread0;
+   struct thread1 thread1;
+   struct thread2 thread2;
+   struct thread3 thread3;
+
+   struct
+   {
+      GLuint pad0:9;
+      GLuint gs_output_stats:1; /* not always */
+      GLuint stats_enable:1; 
+      GLuint nr_urb_entries:7; 
+      GLuint pad1:1;
+      GLuint urb_entry_allocation_size:5; 
+      GLuint pad2:1;
+      GLuint max_threads:6; 	/* may be less */
+      GLuint pad3:1;
+   } thread4;   
+      
+   struct
+   {
+      GLuint pad0:13;
+      GLuint clip_mode:3; 
+      GLuint userclip_enable_flags:8; 
+      GLuint userclip_must_clip:1; 
+      GLuint pad1:1;
+      GLuint guard_band_enable:1; 
+      GLuint viewport_z_clip_enable:1; 
+      GLuint viewport_xy_clip_enable:1; 
+      GLuint vertex_position_space:1; 
+      GLuint api_mode:1; 
+      GLuint pad2:1;
+   } clip5;
+   
+   struct
+   {
+      GLuint pad0:5;
+      GLuint clipper_viewport_state_ptr:27; 
+   } clip6;
+
+   
+   GLfloat viewport_xmin;  
+   GLfloat viewport_xmax;  
+   GLfloat viewport_ymin;  
+   GLfloat viewport_ymax;  
+};
+
+
+
+struct brw_cc_unit_state
+{
+   struct
+   {
+      GLuint pad0:3;
+      GLuint bf_stencil_pass_depth_pass_op:3; 
+      GLuint bf_stencil_pass_depth_fail_op:3; 
+      GLuint bf_stencil_fail_op:3; 
+      GLuint bf_stencil_func:3; 
+      GLuint bf_stencil_enable:1; 
+      GLuint pad1:2;
+      GLuint stencil_write_enable:1; 
+      GLuint stencil_pass_depth_pass_op:3; 
+      GLuint stencil_pass_depth_fail_op:3; 
+      GLuint stencil_fail_op:3; 
+      GLuint stencil_func:3; 
+      GLuint stencil_enable:1; 
+   } cc0;
+
+   
+   struct
+   {
+      GLuint bf_stencil_ref:8; 
+      GLuint stencil_write_mask:8; 
+      GLuint stencil_test_mask:8; 
+      GLuint stencil_ref:8; 
+   } cc1;
+
+   
+   struct
+   {
+      GLuint logicop_enable:1; 
+      GLuint pad0:10;
+      GLuint depth_write_enable:1; 
+      GLuint depth_test_function:3; 
+      GLuint depth_test:1; 
+      GLuint bf_stencil_write_mask:8; 
+      GLuint bf_stencil_test_mask:8; 
+   } cc2;
+
+   
+   struct
+   {
+      GLuint pad0:8;
+      GLuint alpha_test_func:3; 
+      GLuint alpha_test:1; 
+      GLuint blend_enable:1; 
+      GLuint ia_blend_enable:1; 
+      GLuint pad1:1;
+      GLuint alpha_test_format:1;
+      GLuint pad2:16;
+   } cc3;
+   
+   struct
+   {
+      GLuint pad0:5; 
+      GLuint cc_viewport_state_offset:27; 
+   } cc4;
+   
+   struct
+   {
+      GLuint pad0:2;
+      GLuint ia_dest_blend_factor:5; 
+      GLuint ia_src_blend_factor:5; 
+      GLuint ia_blend_function:3; 
+      GLuint statistics_enable:1; 
+      GLuint logicop_func:4; 
+      GLuint pad1:11;
+      GLuint dither_enable:1; 
+   } cc5;
+
+   struct
+   {
+      GLuint clamp_post_alpha_blend:1; 
+      GLuint clamp_pre_alpha_blend:1; 
+      GLuint clamp_range:2; 
+      GLuint pad0:11;
+      GLuint y_dither_offset:2; 
+      GLuint x_dither_offset:2; 
+      GLuint dest_blend_factor:5; 
+      GLuint src_blend_factor:5; 
+      GLuint blend_function:3; 
+   } cc6;
+
+   struct {
+      union {
+	 GLfloat f;  
+	 GLubyte ub[4];
+      } alpha_ref;
+   } cc7;
+};
+
+
+
+struct brw_sf_unit_state
+{
+   struct thread0 thread0;
+   struct thread1 thread1;
+   struct thread2 thread2;
+   struct thread3 thread3;
+
+   struct
+   {
+      GLuint pad0:10;
+      GLuint stats_enable:1; 
+      GLuint nr_urb_entries:7; 
+      GLuint pad1:1;
+      GLuint urb_entry_allocation_size:5; 
+      GLuint pad2:1;
+      GLuint max_threads:6; 
+      GLuint pad3:1;
+   } thread4;   
+
+   struct
+   {
+      GLuint front_winding:1; 
+      GLuint viewport_transform:1; 
+      GLuint pad0:3;
+      GLuint sf_viewport_state_offset:27; 
+   } sf5;
+   
+   struct
+   {
+      GLuint pad0:9;
+      GLuint dest_org_vbias:4; 
+      GLuint dest_org_hbias:4; 
+      GLuint scissor:1; 
+      GLuint disable_2x2_trifilter:1; 
+      GLuint disable_zero_pix_trifilter:1; 
+      GLuint point_rast_rule:2; 
+      GLuint line_endcap_aa_region_width:2; 
+      GLuint line_width:4; 
+      GLuint fast_scissor_disable:1; 
+      GLuint cull_mode:2; 
+      GLuint aa_enable:1; 
+   } sf6;
+
+   struct
+   {
+      GLuint point_size:11; 
+      GLuint use_point_size_state:1; 
+      GLuint subpixel_precision:1; 
+      GLuint sprite_point:1; 
+      GLuint pad0:11;
+      GLuint trifan_pv:2; 
+      GLuint linestrip_pv:2; 
+      GLuint tristrip_pv:2; 
+      GLuint line_last_pixel_enable:1; 
+   } sf7;
+
+};
+
+
+struct brw_gs_unit_state
+{
+   struct thread0 thread0;
+   struct thread1 thread1;
+   struct thread2 thread2;
+   struct thread3 thread3;
+
+   struct
+   {
+      GLuint pad0:10;
+      GLuint stats_enable:1; 
+      GLuint nr_urb_entries:7; 
+      GLuint pad1:1;
+      GLuint urb_entry_allocation_size:5; 
+      GLuint pad2:1;
+      GLuint max_threads:1; 
+      GLuint pad3:6;
+   } thread4;   
+      
+   struct
+   {
+      GLuint sampler_count:3; 
+      GLuint pad0:2;
+      GLuint sampler_state_pointer:27; 
+   } gs5;
+
+   
+   struct
+   {
+      GLuint max_vp_index:4; 
+      GLuint pad0:26;
+      GLuint reorder_enable:1; 
+      GLuint pad1:1;
+   } gs6;
+};
+
+
+struct brw_vs_unit_state
+{
+   struct thread0 thread0;
+   struct thread1 thread1;
+   struct thread2 thread2;
+   struct thread3 thread3;
+   
+   struct
+   {
+      GLuint pad0:10;
+      GLuint stats_enable:1; 
+      GLuint nr_urb_entries:7; 
+      GLuint pad1:1;
+      GLuint urb_entry_allocation_size:5; 
+      GLuint pad2:1;
+      GLuint max_threads:4; 
+      GLuint pad3:3;
+   } thread4;   
+
+   struct
+   {
+      GLuint sampler_count:3; 
+      GLuint pad0:2;
+      GLuint sampler_state_pointer:27; 
+   } vs5;
+
+   struct
+   {
+      GLuint vs_enable:1; 
+      GLuint vert_cache_disable:1; 
+      GLuint pad0:30;
+   } vs6;
+};
+
+
+struct brw_wm_unit_state
+{
+   struct thread0 thread0;
+   struct thread1 thread1;
+   struct thread2 thread2;
+   struct thread3 thread3;
+   
+   struct {
+      GLuint stats_enable:1; 
+      GLuint pad0:1;
+      GLuint sampler_count:3; 
+      GLuint sampler_state_pointer:27; 
+   } wm4;
+   
+   struct
+   {
+      GLuint enable_8_pix:1; 
+      GLuint enable_16_pix:1; 
+      GLuint enable_32_pix:1; 
+      GLuint pad0:7;
+      GLuint legacy_global_depth_bias:1; 
+      GLuint line_stipple:1; 
+      GLuint depth_offset:1; 
+      GLuint polygon_stipple:1; 
+      GLuint line_aa_region_width:2; 
+      GLuint line_endcap_aa_region_width:2; 
+      GLuint early_depth_test:1; 
+      GLuint thread_dispatch_enable:1; 
+      GLuint program_uses_depth:1; 
+      GLuint program_computes_depth:1; 
+      GLuint program_uses_killpixel:1; 
+      GLuint legacy_line_rast: 1; 
+      GLuint pad1:1; 
+      GLuint max_threads:6; 
+      GLuint pad2:1;
+   } wm5;
+   
+   GLfloat global_depth_offset_constant;  
+   GLfloat global_depth_offset_scale;   
+};
+
+struct brw_sampler_default_color {
+   GLfloat color[4];
+};
+
+struct brw_sampler_state
+{
+   
+   struct
+   {
+      GLuint shadow_function:3; 
+      GLuint lod_bias:11; 
+      GLuint min_filter:3; 
+      GLuint mag_filter:3; 
+      GLuint mip_filter:2; 
+      GLuint base_level:5; 
+      GLuint pad:1;
+      GLuint lod_preclamp:1; 
+      GLuint default_color_mode:1; 
+      GLuint pad0:1;
+      GLuint disable:1; 
+   } ss0;
+
+   struct
+   {
+      GLuint r_wrap_mode:3; 
+      GLuint t_wrap_mode:3; 
+      GLuint s_wrap_mode:3; 
+      GLuint pad:3;
+      GLuint max_lod:10; 
+      GLuint min_lod:10; 
+   } ss1;
+
+   
+   struct
+   {
+      GLuint pad:5;
+      GLuint default_color_pointer:27; 
+   } ss2;
+   
+   struct
+   {
+      GLuint pad:19;
+      GLuint max_aniso:3; 
+      GLuint chroma_key_mode:1; 
+      GLuint chroma_key_index:2; 
+      GLuint chroma_key_enable:1; 
+      GLuint monochrome_filter_width:3; 
+      GLuint monochrome_filter_height:3; 
+   } ss3;
+};
+
+
+struct brw_clipper_viewport
+{
+   GLfloat xmin;  
+   GLfloat xmax;  
+   GLfloat ymin;  
+   GLfloat ymax;  
+};
+
+struct brw_cc_viewport
+{
+   GLfloat min_depth;  
+   GLfloat max_depth;  
+};
+
+struct brw_sf_viewport
+{
+   struct {
+      GLfloat m00;  
+      GLfloat m11;  
+      GLfloat m22;  
+      GLfloat m30;  
+      GLfloat m31;  
+      GLfloat m32;  
+   } viewport;
+
+   struct {
+      GLshort xmin;
+      GLshort ymin;
+      GLshort xmax;
+      GLshort ymax;
+   } scissor;
+};
+
+/* Documented in the subsystem/shared-functions/sampler chapter...
+ */
+struct brw_surface_state
+{
+   struct {
+      GLuint cube_pos_z:1; 
+      GLuint cube_neg_z:1; 
+      GLuint cube_pos_y:1; 
+      GLuint cube_neg_y:1; 
+      GLuint cube_pos_x:1; 
+      GLuint cube_neg_x:1; 
+      GLuint pad:4;
+      GLuint mipmap_layout_mode:1; 
+      GLuint vert_line_stride_ofs:1; 
+      GLuint vert_line_stride:1; 
+      GLuint color_blend:1; 
+      GLuint writedisable_blue:1; 
+      GLuint writedisable_green:1; 
+      GLuint writedisable_red:1; 
+      GLuint writedisable_alpha:1; 
+      GLuint surface_format:9; 
+      GLuint data_return_format:1; 
+      GLuint pad0:1;
+      GLuint surface_type:3; 
+   } ss0;
+   
+   struct {
+      GLuint base_addr;  
+   } ss1;
+   
+   struct {
+      GLuint pad:2;
+      GLuint mip_count:4; 
+      GLuint width:13; 
+      GLuint height:13; 
+   } ss2;
+
+   struct {
+      GLuint tile_walk:1; 
+      GLuint tiled_surface:1; 
+      GLuint pad:1; 
+      GLuint pitch:18; 
+      GLuint depth:11; 
+   } ss3;
+   
+   struct {
+      GLuint pad:19;
+      GLuint min_array_elt:9; 
+      GLuint min_lod:4; 
+   } ss4;
+};
+
+
+
+struct brw_vertex_buffer_state
+{
+   struct {
+      GLuint pitch:11; 
+      GLuint pad:15;
+      GLuint access_type:1; 
+      GLuint vb_index:5; 
+   } vb0;
+   
+   GLuint start_addr; 
+   GLuint max_index;   
+#if 1
+   GLuint instance_data_step_rate; /* not included for sequential/random vertices? */
+#endif
+};
+
+#define BRW_VBP_MAX 17
+
+struct brw_vb_array_state {
+   struct header header;
+   struct brw_vertex_buffer_state vb[BRW_VBP_MAX];
+};
+
+
+struct brw_vertex_element_state
+{
+   struct
+   {
+      GLuint src_offset:11; 
+      GLuint pad:5;
+      GLuint src_format:9; 
+      GLuint pad0:1;
+      GLuint valid:1; 
+      GLuint vertex_buffer_index:5; 
+   } ve0;
+   
+   struct
+   {
+      GLuint dst_offset:8; 
+      GLuint pad:8;
+      GLuint vfcomponent3:4; 
+      GLuint vfcomponent2:4; 
+      GLuint vfcomponent1:4; 
+      GLuint vfcomponent0:4; 
+   } ve1;
+};
+
+#define BRW_VEP_MAX 18
+
+struct brw_vertex_element_packet {
+   struct header header;
+   struct brw_vertex_element_state ve[BRW_VEP_MAX]; /* note: less than _TNL_ATTRIB_MAX */
+};
+
+
+struct brw_urb_immediate {
+   GLuint opcode:4;
+   GLuint offset:6;
+   GLuint swizzle_control:2; 
+   GLuint pad:1;
+   GLuint allocate:1;
+   GLuint used:1;
+   GLuint complete:1;
+   GLuint response_length:4;
+   GLuint msg_length:4;
+   GLuint msg_target:4;
+   GLuint pad1:3;
+   GLuint end_of_thread:1;
+};
+
+/* Instruction format for the execution units:
+ */
+ 
+struct brw_instruction
+{
+   struct 
+   {
+      GLuint opcode:7;
+      GLuint pad:1;
+      GLuint access_mode:1;
+      GLuint mask_control:1;
+      GLuint dependency_control:2;
+      GLuint compression_control:2;
+      GLuint thread_control:2;
+      GLuint predicate_control:4;
+      GLuint predicate_inverse:1;
+      GLuint execution_size:3;
+      GLuint destreg__conditonalmod:4; /* destreg - send, conditionalmod - others */
+      GLuint pad0:2;
+      GLuint debug_control:1;
+      GLuint saturate:1;
+   } header;
+
+   union {
+      struct
+      {
+	 GLuint dest_reg_file:2;
+	 GLuint dest_reg_type:3;
+	 GLuint src0_reg_file:2;
+	 GLuint src0_reg_type:3;
+	 GLuint src1_reg_file:2;
+	 GLuint src1_reg_type:3;
+	 GLuint pad:1;
+	 GLuint dest_subreg_nr:5;
+	 GLuint dest_reg_nr:8;
+	 GLuint dest_horiz_stride:2;
+	 GLuint dest_address_mode:1;
+      } da1;
+
+      struct
+      {
+	 GLuint dest_reg_file:2;
+	 GLuint dest_reg_type:3;
+	 GLuint src0_reg_file:2;
+	 GLuint src0_reg_type:3;
+	 GLuint pad:6;
+	 GLint dest_indirect_offset:10;	/* offset against the deref'd address reg */
+	 GLuint dest_subreg_nr:3; /* subnr for the address reg a0.x */
+	 GLuint dest_horiz_stride:2;
+	 GLuint dest_address_mode:1;
+      } ia1;
+
+      struct
+      {
+	 GLuint dest_reg_file:2;
+	 GLuint dest_reg_type:3;
+	 GLuint src0_reg_file:2;
+	 GLuint src0_reg_type:3;
+	 GLuint src1_reg_file:2;
+	 GLuint src1_reg_type:3;
+	 GLuint pad0:1;
+	 GLuint dest_writemask:4;
+	 GLuint dest_subreg_nr:1;
+	 GLuint dest_reg_nr:8;
+	 GLuint pad1:2;
+	 GLuint dest_address_mode:1;
+      } da16;
+
+      struct
+      {
+	 GLuint dest_reg_file:2;
+	 GLuint dest_reg_type:3;
+	 GLuint src0_reg_file:2;
+	 GLuint src0_reg_type:3;
+	 GLuint pad0:6;
+	 GLuint dest_writemask:4;
+	 GLint dest_indirect_offset:6;
+	 GLuint dest_subreg_nr:3;
+	 GLuint pad1:2;
+	 GLuint dest_address_mode:1;
+      } ia16;
+   } bits1;
+
+
+   union {
+      struct
+      {
+	 GLuint src0_subreg_nr:5;
+	 GLuint src0_reg_nr:8;
+	 GLuint src0_abs:1;
+	 GLuint src0_negate:1;
+	 GLuint src0_address_mode:1;
+	 GLuint src0_horiz_stride:2;
+	 GLuint src0_width:3;
+	 GLuint src0_vert_stride:4;
+	 GLuint flag_reg_nr:1;
+	 GLuint pad:6;
+      } da1;
+
+      struct
+      {
+	 GLint src0_indirect_offset:10;
+	 GLuint src0_subreg_nr:3;
+	 GLuint src0_abs:1;
+	 GLuint src0_negate:1;
+	 GLuint src0_address_mode:1;
+	 GLuint src0_horiz_stride:2;
+	 GLuint src0_width:3;
+	 GLuint src0_vert_stride:4;
+	 GLuint flag_reg_nr:1;
+	 GLuint pad:6;	
+      } ia1;
+
+      struct
+      {
+	 GLuint src0_swz_x:2;
+	 GLuint src0_swz_y:2;
+	 GLuint src0_subreg_nr:1;
+	 GLuint src0_reg_nr:8;
+	 GLuint src0_abs:1;
+	 GLuint src0_negate:1;
+	 GLuint src0_address_mode:1;
+	 GLuint src0_swz_z:2;
+	 GLuint src0_swz_w:2;
+	 GLuint pad0:1;
+	 GLuint src0_vert_stride:4;
+	 GLuint flag_reg_nr:1;
+	 GLuint pad1:6;
+      } da16;
+
+      struct
+      {
+	 GLuint src0_swz_x:2;
+	 GLuint src0_swz_y:2;
+	 GLint src0_indirect_offset:6;
+	 GLuint src0_subreg_nr:3;
+	 GLuint src0_abs:1;
+	 GLuint src0_negate:1;
+	 GLuint src0_address_mode:1;
+	 GLuint src0_swz_z:2;
+	 GLuint src0_swz_w:2;
+	 GLuint pad0:1;
+	 GLuint src0_vert_stride:4;
+	 GLuint flag_reg_nr:1;
+	 GLuint pad1:6;
+      } ia16;
+
+   } bits2;
+
+   union
+   {
+      struct
+      {
+	 GLuint src1_subreg_nr:5;
+	 GLuint src1_reg_nr:8;
+	 GLuint src1_abs:1;
+	 GLuint src1_negate:1;
+	 GLuint pad:1;
+	 GLuint src1_horiz_stride:2;
+	 GLuint src1_width:3;
+	 GLuint src1_vert_stride:4;
+	 GLuint pad0:7;
+      } da1;
+
+      struct
+      {
+	 GLuint src1_swz_x:2;
+	 GLuint src1_swz_y:2;
+	 GLuint src1_subreg_nr:1;
+	 GLuint src1_reg_nr:8;
+	 GLuint src1_abs:1;
+	 GLuint src1_negate:1;
+	 GLuint pad0:1;
+	 GLuint src1_swz_z:2;
+	 GLuint src1_swz_w:2;
+	 GLuint pad1:1;
+	 GLuint src1_vert_stride:4;
+	 GLuint pad2:7;
+      } da16;
+
+      struct
+      {
+	 GLint  src1_indirect_offset:10;
+	 GLuint src1_subreg_nr:3;
+	 GLuint src1_abs:1;
+	 GLuint src1_negate:1;
+	 GLuint pad0:1;
+	 GLuint src1_horiz_stride:2;
+	 GLuint src1_width:3;
+	 GLuint src1_vert_stride:4;
+	 GLuint flag_reg_nr:1;
+	 GLuint pad1:6;	
+      } ia1;
+
+      struct
+      {
+	 GLuint src1_swz_x:2;
+	 GLuint src1_swz_y:2;
+	 GLint  src1_indirect_offset:6;
+	 GLuint src1_subreg_nr:3;
+	 GLuint src1_abs:1;
+	 GLuint src1_negate:1;
+	 GLuint pad0:1;
+	 GLuint src1_swz_z:2;
+	 GLuint src1_swz_w:2;
+	 GLuint pad1:1;
+	 GLuint src1_vert_stride:4;
+	 GLuint flag_reg_nr:1;
+	 GLuint pad2:6;
+      } ia16;
+
+
+      struct
+      {
+	 GLint  jump_count:16;	/* note: signed */
+	 GLuint  pop_count:4;
+	 GLuint  pad0:12;
+      } if_else;
+
+      struct {
+	 GLuint function:4;
+	 GLuint int_type:1;
+	 GLuint precision:1;
+	 GLuint saturate:1;
+	 GLuint data_type:1;
+	 GLuint pad0:8;
+	 GLuint response_length:4;
+	 GLuint msg_length:4;
+	 GLuint msg_target:4;
+	 GLuint pad1:3;
+	 GLuint end_of_thread:1;
+      } math;
+
+      struct {
+	 GLuint binding_table_index:8;
+	 GLuint sampler:4;
+	 GLuint return_format:2; 
+	 GLuint msg_type:2;   
+	 GLuint response_length:4;
+	 GLuint msg_length:4;
+	 GLuint msg_target:4;
+	 GLuint pad1:3;
+	 GLuint end_of_thread:1;
+      } sampler;
+
+      struct brw_urb_immediate urb;
+
+      struct {
+	 GLuint binding_table_index:8;
+	 GLuint msg_control:4;  
+	 GLuint msg_type:2;  
+	 GLuint target_cache:2;    
+	 GLuint response_length:4;
+	 GLuint msg_length:4;
+	 GLuint msg_target:4;
+	 GLuint pad1:3;
+	 GLuint end_of_thread:1;
+      } dp_read;
+
+      struct {
+	 GLuint binding_table_index:8;
+	 GLuint msg_control:3;
+	 GLuint pixel_scoreboard_clear:1;
+	 GLuint msg_type:3;    
+	 GLuint send_commit_msg:1;
+	 GLuint response_length:4;
+	 GLuint msg_length:4;
+	 GLuint msg_target:4;
+	 GLuint pad1:3;
+	 GLuint end_of_thread:1;
+      } dp_write;
+
+      struct {
+	 GLuint pad:16;
+	 GLuint response_length:4;
+	 GLuint msg_length:4;
+	 GLuint msg_target:4;
+	 GLuint pad1:3;
+	 GLuint end_of_thread:1;
+      } generic;
+
+      GLuint ud;
+   } bits3;
+};
+
+
+#endif
diff --git a/src/i810_reg.h b/src/i810_reg.h
index 5b9654b..5ccd8cc 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -1594,6 +1594,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define MI_WRITE_DIRTY_STATE		(1<<4)
 #define MI_END_SCENE			(1<<3)
 #define MI_INHIBIT_RENDER_CACHE_FLUSH	(1<<2)
+#define MI_STATE_INSTRUCTION_CACHE_FLUSH (1<<1)
 #define MI_INVALIDATE_MAP_CACHE		(1<<0)
 
 /* Noop */
@@ -1608,6 +1609,33 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define ENABLE_FOG_CONST	(1<<24)
 #define ENABLE_FOG_DENSITY	(1<<23)
 
+/*
+ * New regs for broadwater -- we need to split this file up sensibly somehow.
+ */
+#define STATE3D_PIPELINE_SELECT		(CMD_3D | (0x01<<24) | (0x04<<16))
+#define PIPELINE_SELECT_3D		0
+#define PIPELINE_SELECT_MEDIA		1
+
+#define STATE3D_URB_FENCE		(CMD_3D | (0x00<<24) | (0x00<<16))
+#define UF0_CS_REALLOC			(1 << 13)
+#define UF0_VFE_REALLOC			(1 << 12)
+#define UF0_SF_REALLOC			(1 << 11)
+#define UF0_CLIP_REALLOC		(1 << 10)
+#define UF0_GS_REALLOC			(1 << 9)
+#define UF0_VS_REALLOC			(1 << 8)
+#define UF1_CLIP_FENCE_SHIFT		20
+#define UF1_GS_FENCE_SHIFT		10
+#define UF1_VS_FENCE_SHIFT		0
+#define UF2_CS_FENCE_SHIFT		20
+#define UF2_VFE_FENCE_SHIFT		10
+#define UF2_SF_FENCE_SHIFT		0
+
+#define STATE3D_DRAWING_RECTANGLE_BRW	(CMD_3D | (0x01<<24) | (0x00<<16))
+
+#define PRIMITIVE3D_BRW			(CMD_3D | (0x03<<27) | (0x08<<16))
+#define PRIM3D_BRW_POINTLIST		0x0
+/* End regs for broadwater */
+
 
 #define MAX_DISPLAY_PIPES	2
 
diff --git a/src/i830_video.c b/src/i830_video.c
index 1a133b9..d13b75f 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -83,6 +83,8 @@ THE USE OR OTHER DEALINGS IN THE SOFTWAR
 #include "xaalocal.h"
 #include "dixstruct.h"
 #include "fourcc.h"
+#include "brw_defines.h"
+#include "brw_structs.h"
 
 #ifndef USE_USLEEP_FOR_VIDEO
 #define USE_USLEEP_FOR_VIDEO 0
@@ -488,7 +490,7 @@ I830InitVideo(ScreenPtr pScreen)
    /* Set up textured video if we can do it at this depth and we are on
     * supported hardware.
     */
-   if (pScrn->bitsPerPixel >= 16 && IS_I9XX(pI830)) {
+   if (pScrn->bitsPerPixel >= 16 && IS_I9XX(pI830) || IS_BROADWATER(pI830)) {
       texturedAdaptor = I830SetupImageVideoTextured(pScreen);
       if (texturedAdaptor != NULL) {
 	 adaptors[num_adaptors++] = texturedAdaptor;
@@ -2607,6 +2609,247 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
       pI830->AccelInfoRec->NeedToSync = TRUE;
 }
 
+static void
+BroadwaterDisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
+			       RegionPtr dstRegion,
+			       short width, short height, int video_pitch,
+			       int x1, int y1, int x2, int y2,
+			       short src_w, short src_h,
+			       short drw_w, short drw_h,
+			       DrawablePtr pDraw)
+{
+   I830Ptr pI830 = I830PTR(pScrn);
+   CARD32 format, ms3, s2;
+   BoxPtr pbox;
+   int nbox, dxo, dyo;
+   Bool planar;
+   int urb_vs_start, urb_vs_size;
+   int urb_gs_start, urb_gs_size;
+   int urb_clip_start, urb_clip_size;
+   int urb_sf_start, urb_sf_size;
+   int urb_cs_start, urb_cs_size;
+   struct brw_surface_state *dest_surf_state;
+   struct brw_surface_state *src_surf_state;
+   struct brw_sampler_state *src_sampler_state;
+   struct brw_cc_unit_state *cc_state;
+
+   ErrorF("BroadwaterDisplayVideoTextured: %dx%d (pitch %d)\n", width, height,
+	  video_pitch);
+
+   assert((id == FOURCC_UYVY) || (id == FOURCC_YUY2));
+
+   /* Tell the rotation code that we have stomped its invariant state by
+    * setting a high bit.  We don't use any invariant 3D state for video, so we
+    * don't have to worry about it ourselves.
+    */
+   *pI830->used3D |= 1 << 30;
+
+   /* Set up a default static partitioning of the URB, which is supposed to
+    * allow anything we would want to do, at potentially lower performance.
+    */
+   urb_vs_start = 0;
+   urb_vs_size = 8 * 5;
+   urb_gs_start = urb_vs_start + urb_vs_size;
+   urb_gs_size = 4 * 5;
+   urb_clip_start = urb_gs_start + urb_gs_size;
+   urb_clip_size = 6 * 5;
+   urb_sf_start = urb_clip_start + urb_clip_size;
+   urb_sf_size = 8 * 11;
+   urb_cs_start = urb_sf_start + urb_sf_size;
+   urb_cs_size = 2 * 32;
+
+   /* We'll be poking the state buffers that could be in use by the 3d hardware
+    * here, but we should have synced the 3D engine if we've reached this point.
+    */
+
+   /* XXX: Allocate space for our state buffers, and set up the state structure
+    * pointers.
+    */
+
+   /* Set up the state buffer for the destination surface */
+   memset(dest_surf_state, 0, sizeof(*dest_surf_state));
+   dest_surf_state->ss0.surface_type = BRW_SURFACE_2D;
+   if (pI830->cpp == 2) {
+      dest_surf_state->ss0.surface_format = BRW_SURFACEFORMAT_B5G6R5_UNORM;
+   } else {
+      dest_surf_state->ss0.surface_format = BRW_SURFACEFORMAT_B8G8R8X8_UNORM;
+   }
+   dest_surf_state->ss1.base_addr = pI830->bufferOffset;
+   dest_surf_state->ss2.width = pScrn->virtualX - 1;
+   dest_surf_state->ss2.height = pScrn->virtualY - 1;
+   dest_surf_state->ss3.pitch = pI830->displayWidth * pI830->cpp;
+
+   /* Set up the source surface state buffer */
+   memset(src_surf_state, 0, sizeof(*src_surf_state));
+   src_surf_state->ss0.surface_type = BRW_SURFACE_2D;
+   switch (id) {
+   case FOURCC_YUY2:
+      src_surf_state->ss0.surface_format = BRW_SURFACEFORMAT_YCRCB_NORMAL;
+      break;
+   case FOURCC_UYVY:
+      src_surf_state->ss0.surface_format = BRW_SURFACEFORMAT_YCRCB_SWAPY;
+      break;
+   }
+   src_surf_state->ss1.base_addr = pPriv->YBuf0offset;
+   src_surf_state->ss2.width = width;
+   src_surf_state->ss2.height = height;
+   src_surf_state->ss3.pitch = video_pitch - 1;
+
+   /* Set up the packed YUV source sampler.  Doesn't do colorspace conversion.
+    */
+   memset(src_sampler_state, 0, sizeof(*src_sampler_state));
+   src_sampler_state->ss0.min_filter = BRW_MAPFILTER_LINEAR;
+   src_sampler_state->ss0.mag_filter = BRW_MAPFILTER_LINEAR;
+   src_sampler_state->ss1.s_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
+   src_sampler_state->ss1.t_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
+
+   /* XXX: Set up binding table state */
+   /* XXX: Set up the VF for however we send our prims */
+   /* XXX: Set up the SF kernel to do coord interp */
+   /* XXX: Set up the SF state */
+   /* XXX: Set up the clipper to do nothing for us, I think */
+
+   /* XXX: Set up the PS kernel (dispatched by WM) for convertiny YUV to RGB.
+    * The 3D driver does this as:
+    *
+	 CONST C0 = { -.5, -.0625,  -.5, 1.164 }
+	 CONST C1 = { 1.596, -0.813, 2.018, -.391 }
+	 UYV     = TEX ...
+	 UYV.xyz = ADD UYV,     C0
+	 UYV.y   = MUL UYV.y,   C0.w
+	 RGB.xyz = MAD UYV.xxz, C1,   UYV.y
+	 RGB.y   = MAD UYV.z,   C1.w, RGB.y
+    *
+    */
+
+   /* XXX: Set up the WM state. */
+
+   /* XXX: Set up CC_VIEWPORT, though we really don't care about its behavior.
+    */
+
+   memset(cc_state, 0, sizeof(*cc_state));
+   /* XXX: Set pointer to CC_VIEWPORT */
+
+   BEGIN_LP_RING(XXX);
+   OUT_RING(MI_FLUSH | MI_STATE_INSTRUCTION_CACHE_FLUSH);
+
+   OUT_RING(STATE3D_PIPELINE_SELECT | PIPELINE_SELECT_3D);
+
+   OUT_RING(STATE3D_URB_FENCE |
+	    UF0_CS_REALLOC |
+	    UF0_VFE_REALLOC |
+	    UF0_SF_REALLOC |
+	    UF0_CLIP_REALLOC |
+	    UF0_GS_REALLOC |
+	    UF0_VS_REALLOC);
+   OUT_RING(((urb_clip_start + urb_clip_size) << UF1_CLIP_FENCE_SHIFT) |
+	    ((urb_gs_start + urb_gs_size) << UF1_GS_FENCE_SHIFT) |
+	    ((urb_vs_start + urb_vs_size) << UF1_VS_FENCE_SHIFT));
+   OUT_RING(((urb_cs_start + urb_cs_size) << UF2_CS_FENCE_SHIFT) |
+	    ((urb_vfe_start + urb_vfe_size) << UF2_VFE_FENCE_SHIFT) |
+	    ((urb_sf_start + urb_sf_size) << UF2_SF_FENCE_SHIFT));
+
+   OUT_RING(STATE3D_DRAWING_RECTANGLE_BRW | 2);
+   OUT_RING(0x00000000);	/* ymin, xmin */
+   OUT_RING((pScrn->virtualX - 1) |
+	    (pScrn->virtualY - 1) << 16); /* ymax, xmax */
+   OUT_RING(0x00000000);	/* yorigin, xorigin */
+
+   /* XXX: Set the locations of the sampler/surface/etc. state */
+
+   ADVANCE_LP_RING();
+
+   /* XXX: Finally, emit some prims */
+
+   dxo = dstRegion->extents.x1;
+   dyo = dstRegion->extents.y1;
+
+#if 0
+   pbox = REGION_RECTS(dstRegion);
+   nbox = REGION_NUM_RECTS(dstRegion);
+   while (nbox--)
+   {
+      int box_x1 = pbox->x1;
+      int box_y1 = pbox->y1;
+      int box_x2 = pbox->x2;
+      int box_y2 = pbox->y2;
+      int j;
+      float src_scale_x, src_scale_y;
+      CARD32 vb[40];
+      float verts[4][2], tex[4][2], tex2[4][2];
+      int vert_data_count;
+
+      pbox++;
+
+      src_scale_x = (float)src_w / (float)drw_w;
+      src_scale_y  = (float)src_h / (float)drw_h;
+
+      if (!planar)
+	 vert_data_count = 32;
+      else
+	 vert_data_count = 40;
+
+      BEGIN_LP_RING(vert_data_count + 8);
+      OUT_RING(MI_NOOP);
+      OUT_RING(MI_NOOP);
+      OUT_RING(MI_NOOP);
+      OUT_RING(MI_NOOP);
+      OUT_RING(MI_NOOP);
+      OUT_RING(MI_NOOP);
+      OUT_RING(MI_NOOP);
+
+      /* vertex data */
+      OUT_RING(PRIMITIVE3D | PRIM3D_INLINE | PRIM3D_TRIFAN |
+	       (vert_data_count - 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;
+      verts[3][0] = box_x1; verts[3][1] = box_y2;
+
+      if (!planar) {
+	 tex[0][0] = (box_x1 - dxo) * src_scale_x;
+	 tex[0][1] = (box_y1 - dyo) * src_scale_y;
+	 tex[1][0] = (box_x2 - dxo) * src_scale_x;
+	 tex[1][1] = (box_y1 - dyo) * src_scale_y;
+	 tex[2][0] = (box_x2 - dxo) * src_scale_x;
+	 tex[2][1] = (box_y2 - dyo) * src_scale_y;
+	 tex[3][0] = (box_x1 - dxo) * src_scale_x;
+	 tex[3][1] = (box_y2 - dyo) * src_scale_y;
+	 /* emit vertex buffer */
+	 draw_poly(vb, verts, tex, NULL);
+	 for (j = 0; j < vert_data_count; j++)
+	    OUT_RING(vb[j]);
+      } else {
+	 tex[0][0] = (box_x1 - dxo) * src_scale_x / 2.0;
+	 tex[0][1] = (box_y1 - dyo) * src_scale_y / 2.0;
+	 tex[1][0] = (box_x2 - dxo) * src_scale_x / 2.0;
+	 tex[1][1] = (box_y1 - dyo) * src_scale_y / 2.0;
+	 tex[2][0] = (box_x2 - dxo) * src_scale_x / 2.0;
+	 tex[2][1] = (box_y2 - dyo) * src_scale_y / 2.0;
+	 tex[3][0] = (box_x1 - dxo) * src_scale_x / 2.0;
+	 tex[3][1] = (box_y2 - dyo) * src_scale_y / 2.0;
+	 tex2[0][0] = (box_x1 - dxo) * src_scale_x;
+	 tex2[0][1] = (box_y1 - dyo) * src_scale_y;
+	 tex2[1][0] = (box_x2 - dxo) * src_scale_x;
+	 tex2[1][1] = (box_y1 - dyo) * src_scale_y;
+	 tex2[2][0] = (box_x2 - dxo) * src_scale_x;
+	 tex2[2][1] = (box_y2 - dyo) * src_scale_y;
+	 tex2[3][0] = (box_x1 - dxo) * src_scale_x;
+	 tex2[3][1] = (box_y2 - dyo) * src_scale_y;
+	 /* emit vertex buffer */
+	 draw_poly(vb, verts, tex, tex2);
+	 for (j = 0; j < vert_data_count; j++)
+	    OUT_RING(vb[j]);
+      }
+
+      ADVANCE_LP_RING();
+   }
+#endif
+
+   if (pI830->AccelInfoRec)
+      pI830->AccelInfoRec->NeedToSync = TRUE;
+}
+
 static FBLinearPtr
 I830AllocateMemory(ScrnInfoPtr pScrn, FBLinearPtr linear, int size)
 {
@@ -2749,7 +2992,7 @@ I830PutImage(ScrnInfoPtr pScrn,
    if (pPriv->textured) {
       pitchAlignMask = 3;
    } else {
-      if (IS_BROADWATER(pI830)) {
+      if (IS_BROADWATER(pI830))
 	 pitchAlignMask = 255;
       else
 	 pitchAlignMask = 63;
diff-tree bc51d6525a12c748d0a293b7e560f6dcea33eecb (from b0ac5303f33f75dc607cf0c705c23db1da836983)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Wed May 17 13:42:51 2006 -0700

    Turn off overlay video on BW until we have stable PCI IDs so we can know whether
    the hardware supports overlay.

diff --git a/src/i830_video.c b/src/i830_video.c
index dc0f8e1..1a133b9 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -473,7 +473,7 @@ I830InitVideo(ScreenPtr pScreen)
    xvContrast = MAKE_ATOM("XV_CONTRAST");
 
    /* Set up overlay video if we can do it at this depth. */
-   if (pScrn->bitsPerPixel != 8) {
+   if (!IS_BROADWATER(pI830) && pScrn->bitsPerPixel != 8) {
       overlayAdaptor = I830SetupImageVideoOverlay(pScreen);
       if (overlayAdaptor != NULL) {
 	 adaptors[num_adaptors++] = overlayAdaptor;
diff-tree f97895efd5532cca145b6f224f9615739b1e8f26 (from f2967a2f5f47b636b2445fa69dbc3ec79e065c90)
Author: Dave Airlie <airlied at linux.ie>
Date:   Wed May 17 14:46:37 2006 +1000

    fixup chipid override
    
    This makes the ChipID override work so that we actually override the pci id
    that gets used everywhere in the driver.

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 053ccd1..5462d6c 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -2293,6 +2293,7 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int f
       from = X_CONFIG;
       xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n",
 		 pI830->pEnt->device->chipID);
+      pI830->PciInfo->chipType = pI830->pEnt->device->chipID;
    } else {
       from = X_PROBED;
       pScrn->chipset = (char *)xf86TokenToString(I830BIOSChipsets,
diff-tree b0ac5303f33f75dc607cf0c705c23db1da836983 (from parents)
Merge: 4c727254da354cfd6f35148a334d046d67a50e99 c2cd10e1fba0e75c0ed3db5d17211bddf7ab1e33
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Tue May 16 15:21:17 2006 -0700

    Merge branch 'textured-video' into broadwater-video
    
    Conflicts:
    
    	src/i830_video.c

diff --cc src/i830_video.c
index 8ae1906,a41db5c..dc0f8e1
@@@ -1976,23 -2713,39 +2732,42 @@@
     case FOURCC_I420:
        srcPitch = (width + 3) & ~3;
        srcPitch2 = ((width >> 1) + 3) & ~3;
- #if 1
-       if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
-          dstPitch = ((height / 2) + 63) & ~63;
-          size = dstPitch * width * 3;
-       } else {
-          dstPitch = ((width / 2) + 63) & ~63;	/* of chroma */
-          size = dstPitch * height * 3;
+       if (pPriv->textured) {
+ 	 destId = FOURCC_YUY2;
        }
- #else
+       break;
+    case FOURCC_UYVY:
+    case FOURCC_YUY2:
+    default:
+       srcPitch = width << 1;
+       break;
+    }
+ 
+    /* Only needs to be DWORD-aligned for textured on i915, but overlay has
+     * stricter requirements.
+     */
+    if (pPriv->textured) {
+       pitchAlignMask = 3;
+    } else {
 -      pitchAlignMask = 63;
++      if (IS_BROADWATER(pI830)) {
++	 pitchAlignMask = 255;
++      else
++	 pitchAlignMask = 63;
+    }
+ 
+    /* Determine the desired destination pitch (representing the chroma's pitch,
+     * in the planar case.
+     */
+    switch (destId) {
+    case FOURCC_YV12:
+    case FOURCC_I420:
        if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
-          dstPitch = ((height / 2) + 255) & ~255;
+          dstPitch = ((height / 2) + pitchAlignMask) & ~pitchAlignMask;
           size = dstPitch * width * 3;
        } else {
-          dstPitch = ((width / 2) + 255) & ~255;	/* of chroma */
+          dstPitch = ((width / 2) + pitchAlignMask) & ~pitchAlignMask;
           size = dstPitch * height * 3;
        }
- #endif
        break;
     case FOURCC_UYVY:
     case FOURCC_YUY2:
diff-tree c2cd10e1fba0e75c0ed3db5d17211bddf7ab1e33 (from 63a72e46fa20a4a4ba74efed386f6c3c167be5b5)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Tue May 16 10:08:58 2006 -0700

    Flag the 3D state as dirty when we draw textured video, which should help
    
    rotation (I have other issues with rotation anyway).

diff --git a/src/i830_video.c b/src/i830_video.c
index e07a118..a41db5c 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2195,7 +2195,11 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
       break;
    }
 
-   /* XXX: Dirty dri/rotate state  */
+   /* Tell the rotation code that we have stomped its invariant state by
+    * setting a high bit.  We don't use any invariant 3D state for video, so we
+    * don't have to worry about it ourselves.
+    */
+   *pI830->used3D |= 1 << 30;
 
    BEGIN_LP_RING(44);
 
diff-tree 63a72e46fa20a4a4ba74efed386f6c3c167be5b5 (from 01c043de0393170e98515169f8239fef4d3e2053)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Tue May 16 08:54:43 2006 -0700

    Turn debugging back off.

diff --git a/src/i830_video.c b/src/i830_video.c
index 99bb533..e07a118 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -1,4 +1,4 @@
-#define VIDEO_DEBUG 1
+#define VIDEO_DEBUG 0
 /***************************************************************************
  
 Copyright 2000 Intel Corporation.  All Rights Reserved. 
diff-tree 01c043de0393170e98515169f8239fef4d3e2053 (from db3683907d15959e79adfb8f0cd94e861fae5c36)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Tue May 16 08:53:40 2006 -0700

    Use linear min/mag blending.

diff --git a/src/i830_video.c b/src/i830_video.c
index 11c022a..99bb533 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2317,8 +2317,11 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
 
       OUT_RING(STATE3D_SAMPLER_STATE | 3);
       OUT_RING(0x00000001);
-      OUT_RING(SS2_COLORSPACE_CONVERSION);
-      OUT_RING(0x00000000);
+      OUT_RING(SS2_COLORSPACE_CONVERSION |
+	       (FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) |
+	       (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT));
+      OUT_RING((TEXCOORDMODE_CLAMP_EDGE << SS3_TCX_ADDR_MODE_SHIFT) |
+	       (TEXCOORDMODE_CLAMP_EDGE << SS3_TCY_ADDR_MODE_SHIFT));
       OUT_RING(0x00000000);
 
       OUT_RING(STATE3D_MAP_STATE | 3);
@@ -2444,16 +2447,22 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
       OUT_RING(0x00000007);
       /* sampler 0 */
       OUT_RING(0x00000000);
-      OUT_RING(0x00000000);
-      OUT_RING(0x00000000);
+      OUT_RING((FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) |
+	       (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT));
+      OUT_RING((TEXCOORDMODE_CLAMP_EDGE << SS3_TCX_ADDR_MODE_SHIFT) |
+	       (TEXCOORDMODE_CLAMP_EDGE << SS3_TCY_ADDR_MODE_SHIFT));
       /* sampler 1 */
       OUT_RING(0x00000000);
-      OUT_RING(0x00000000);
-      OUT_RING(0x00000000);
+      OUT_RING((FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) |
+	       (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT));
+      OUT_RING((TEXCOORDMODE_CLAMP_EDGE << SS3_TCX_ADDR_MODE_SHIFT) |
+	       (TEXCOORDMODE_CLAMP_EDGE << SS3_TCY_ADDR_MODE_SHIFT));
       /* sampler 2 */
       OUT_RING(0x00000000);
-      OUT_RING(0x00000000);
-      OUT_RING(0x00000000);
+      OUT_RING((FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) |
+	       (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT));
+      OUT_RING((TEXCOORDMODE_CLAMP_EDGE << SS3_TCX_ADDR_MODE_SHIFT) |
+	       (TEXCOORDMODE_CLAMP_EDGE << SS3_TCY_ADDR_MODE_SHIFT));
 
       OUT_RING(STATE3D_MAP_STATE | 9);
       OUT_RING(0x00000007);
diff-tree db3683907d15959e79adfb8f0cd94e861fae5c36 (from 29a8e88ed01c9e15a2ceba5eb62b19773e14c1f8)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Tue May 16 08:40:53 2006 -0700

    For textured video, disable double buffering and sync before uploading new video
    
    data.  Allows more videos to play simultaneously.

diff --git a/src/i830_video.c b/src/i830_video.c
index bb257c7..11c022a 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -864,7 +864,7 @@ I830SetupImageVideoTextured(ScreenPtr pS
       pPriv->videoStatus = 0;
       pPriv->linear = NULL;
       pPriv->currentBuf = 0;
-      pPriv->doubleBuffer = 1;
+      pPriv->doubleBuffer = 0;
 
       /* gotta uninit this someplace, XXX: shouldn't be necessary for textured */
       REGION_NULL(pScreen, &pPriv->clip);
@@ -2570,6 +2570,9 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
 
       ADVANCE_LP_RING();
    }
+
+   if (pI830->AccelInfoRec)
+      pI830->AccelInfoRec->NeedToSync = TRUE;
 }
 
 static FBLinearPtr
@@ -2805,6 +2808,17 @@ I830PutImage(ScrnInfoPtr pScrn,
    left = (x1 >> 16) & ~1;
    npixels = ((((x2 + 0xffff) >> 16) + 1) & ~1) - left;
 
+   if (pPriv->textured) {
+      /* For textured video, we don't double buffer, and instead just wait for
+       * acceleration to finish before writing the new video data into
+       * framebuffer.
+       */
+      if (pI830->AccelInfoRec && pI830->AccelInfoRec->NeedToSync) {
+	 (*pI830->AccelInfoRec->Sync)(pScrn);
+	 pI830->AccelInfoRec->NeedToSync = FALSE;
+      }
+   }
+
    switch (id) {
    case FOURCC_YV12:
    case FOURCC_I420:
diff-tree 29a8e88ed01c9e15a2ceba5eb62b19773e14c1f8 (from c9be11459bc2198b435c97c5a3432425246c4d2d)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Mon May 15 17:19:33 2006 -0700

    Relax the alignment requirements for textured video.

diff --git a/src/i830_video.c b/src/i830_video.c
index a3cbfaf..bb257c7 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2647,6 +2647,7 @@ I830PutImage(ScrnInfoPtr pScrn,
    int srcPitch, srcPitch2 = 0, dstPitch, destId;
    int top, left, npixels, nlines, size, loops;
    BoxRec dstBox;
+   int pitchAlignMask;
 
    DPRINTF(PFX, "I830PutImage: src: (%d,%d)(%d,%d), dst: (%d,%d)(%d,%d)\n"
 	   "width %d, height %d\n", src_x, src_y, src_w, src_h, drw_x, drw_y,
@@ -2707,47 +2708,39 @@ I830PutImage(ScrnInfoPtr pScrn,
       break;
    }
 
+   /* Only needs to be DWORD-aligned for textured on i915, but overlay has
+    * stricter requirements.
+    */
+   if (pPriv->textured) {
+      pitchAlignMask = 3;
+   } else {
+      pitchAlignMask = 63;
+   }
+
+   /* Determine the desired destination pitch (representing the chroma's pitch,
+    * in the planar case.
+    */
    switch (destId) {
    case FOURCC_YV12:
    case FOURCC_I420:
-#if 1
       if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
-         dstPitch = ((height / 2) + 63) & ~63;
+         dstPitch = ((height / 2) + pitchAlignMask) & ~pitchAlignMask;
          size = dstPitch * width * 3;
       } else {
-         dstPitch = ((width / 2) + 63) & ~63;	/* of chroma */
+         dstPitch = ((width / 2) + pitchAlignMask) & ~pitchAlignMask;
          size = dstPitch * height * 3;
       }
-#else
-      if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
-         dstPitch = ((height / 2) + 511) & ~511;
-         size = dstPitch * width * 3;
-      } else {
-         dstPitch = ((width / 2) + 511) & ~511;	/* of chroma */
-         size = dstPitch * height * 3;
-      }
-#endif
       break;
    case FOURCC_UYVY:
    case FOURCC_YUY2:
    default:
-#if 1
       if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
-         dstPitch = ((height << 1) + 63) & ~63;
+         dstPitch = ((height << 1) + pitchAlignMask) & ~pitchAlignMask;
          size = dstPitch * width;
       } else {
-         dstPitch = ((width << 1) + 63) & ~63;	/* of chroma */
+         dstPitch = ((width << 1) + pitchAlignMask) & ~pitchAlignMask;
          size = dstPitch * height;
       }
-#else
-      if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
-         dstPitch = ((height << 1) + 511) & ~511;
-         size = dstPitch * width;
-      } else {
-         dstPitch = ((width << 1) + 511) & ~511;	/* of chroma */
-         size = dstPitch * height;
-      }
-#endif
       break;
    }
    ErrorF("srcPitch: %d, dstPitch: %d, size: %d\n", srcPitch, dstPitch, size);
diff-tree c9be11459bc2198b435c97c5a3432425246c4d2d (from f268979a0c779641c84e8d5b763acbda131474cf)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Mon May 15 17:04:27 2006 -0700

    Enable overlay and/or textured video at runtime according to hardware
    
    capabilities.  Sets up 16 textured-video ports.  Left in one hack (disconnected
    but advertised BRIGHTNESS and CONTRAST atoms) which may actually not be
    necessary.

diff --git a/src/i830_video.c b/src/i830_video.c
index d23e83c..a3cbfaf 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -84,8 +84,6 @@ THE USE OR OTHER DEALINGS IN THE SOFTWAR
 #include "dixstruct.h"
 #include "fourcc.h"
 
-#define USE_TEXTURED_VIDEO
-
 #ifndef USE_USLEEP_FOR_VIDEO
 #define USE_USLEEP_FOR_VIDEO 0
 #endif
@@ -101,7 +99,8 @@ THE USE OR OTHER DEALINGS IN THE SOFTWAR
 
 static void I830InitOffscreenImages(ScreenPtr);
 
-static XF86VideoAdaptorPtr I830SetupImageVideo(ScreenPtr);
+static XF86VideoAdaptorPtr I830SetupImageVideoOverlay(ScreenPtr);
+static XF86VideoAdaptorPtr I830SetupImageVideoTextured(ScreenPtr);
 static void I830StopVideo(ScrnInfoPtr, pointer, Bool);
 static int I830SetPortAttribute(ScrnInfoPtr, Atom, INT32, pointer);
 static int I830GetPortAttribute(ScrnInfoPtr, Atom, INT32 *, pointer);
@@ -111,8 +110,10 @@ static void I830QueryBestSize(ScrnInfoPt
 static int I830PutImage(ScrnInfoPtr, short, short, short, short, short, short,
 			short, short, int, unsigned char *, short, short,
 			Bool, RegionPtr, pointer, DrawablePtr);
-static int I830QueryImageAttributes(ScrnInfoPtr, int, unsigned short *,
-				    unsigned short *, int *, int *);
+static int I830QueryImageAttributesOverlay(ScrnInfoPtr, int, unsigned short *,
+					   unsigned short *, int *, int *);
+static int I830QueryImageAttributesTextured(ScrnInfoPtr, int, unsigned short *,
+					    unsigned short *, int *, int *);
 
 static void I830BlockHandler(int, pointer, pointer, pointer);
 
@@ -288,6 +289,12 @@ static XF86AttributeRec Attributes[NUM_A
    {XvSettable | XvGettable, 0, 1, "XV_DOUBLE_BUFFER"}
 };
 
+#define NUM_TEXTURED_ATTRIBUTES 2
+static XF86AttributeRec TexturedAttributes[NUM_ATTRIBUTES] = {
+   {XvSettable | XvGettable, -128, 127, "XV_BRIGHTNESS"},
+   {XvSettable | XvGettable, 0, 255, "XV_CONTRAST"},
+};
+
 #define GAMMA_ATTRIBUTES 6
 static XF86AttributeRec GammaAttributes[GAMMA_ATTRIBUTES] = {
    {XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA0"},
@@ -396,6 +403,7 @@ typedef struct {
    Bool overlayOK;
    int oneLineMode;
    int scaleRatio;
+   Bool textured;
 } I830PortPrivRec, *I830PortPrivPtr;
 
 #define GET_PORT_PRIVATE(pScrn) \
@@ -426,8 +434,9 @@ void
 I830InitVideo(ScreenPtr pScreen)
 {
    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+   I830Ptr pI830 = I830PTR(pScrn);
    XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL;
-   XF86VideoAdaptorPtr newAdaptor = NULL;
+   XF86VideoAdaptorPtr overlayAdaptor = NULL, texturedAdaptor = NULL;
    int num_adaptors;
 
    DPRINTF(PFX, "I830InitVideo\n");
@@ -446,35 +455,54 @@ I830InitVideo(ScreenPtr pScreen)
    }
 #endif
 
+   num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors);
+   /* Give our adaptor list enough space for the overlay and/or texture video
+    * adaptors.
+    */
+   newAdaptors = xalloc((num_adaptors + 2) * sizeof(XF86VideoAdaptorPtr *));
+   if (newAdaptors == NULL)
+      return;
+
+   memcpy(newAdaptors, adaptors, num_adaptors * sizeof(XF86VideoAdaptorPtr));
+   adaptors = newAdaptors;
+
+   /* Add the adaptors supported by our hardware.  First, set up the atoms
+    * that will be used by both output adaptors.
+    */
+   xvBrightness = MAKE_ATOM("XV_BRIGHTNESS");
+   xvContrast = MAKE_ATOM("XV_CONTRAST");
+
+   /* Set up overlay video if we can do it at this depth. */
    if (pScrn->bitsPerPixel != 8) {
-      newAdaptor = I830SetupImageVideo(pScreen);
+      overlayAdaptor = I830SetupImageVideoOverlay(pScreen);
+      if (overlayAdaptor != NULL) {
+	 adaptors[num_adaptors++] = overlayAdaptor;
+	 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Set up overlay video\n");
+      } else {
+	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		    "Failed to set up overlay video\n");
+      }
       I830InitOffscreenImages(pScreen);
    }
 
-   num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors);
-
-   if (newAdaptor) {
-      if (!num_adaptors) {
-	 num_adaptors = 1;
-	 adaptors = &newAdaptor;
+   /* Set up textured video if we can do it at this depth and we are on
+    * supported hardware.
+    */
+   if (pScrn->bitsPerPixel >= 16 && IS_I9XX(pI830)) {
+      texturedAdaptor = I830SetupImageVideoTextured(pScreen);
+      if (texturedAdaptor != NULL) {
+	 adaptors[num_adaptors++] = texturedAdaptor;
+	 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Set up textured video\n");
       } else {
-	 newAdaptors =			/* need to free this someplace */
-	       xalloc((num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr *));
-	 if (newAdaptors) {
-	    memcpy(newAdaptors, adaptors, num_adaptors *
-		   sizeof(XF86VideoAdaptorPtr));
-	    newAdaptors[num_adaptors] = newAdaptor;
-	    adaptors = newAdaptors;
-	    num_adaptors++;
-	 }
+	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		    "Failed to set up textured video\n");
       }
    }
 
    if (num_adaptors)
       xf86XVScreenInit(pScreen, adaptors, num_adaptors);
 
-   if (newAdaptors)
-      xfree(newAdaptors);
+   xfree(adaptors);
 }
 
 static void
@@ -644,7 +672,7 @@ I830UpdateGamma(ScrnInfoPtr pScrn)
 }
 
 static XF86VideoAdaptorPtr
-I830SetupImageVideo(ScreenPtr pScreen)
+I830SetupImageVideoOverlay(ScreenPtr pScreen)
 {
    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
    I830Ptr pI830 = I830PTR(pScrn);
@@ -652,7 +680,7 @@ I830SetupImageVideo(ScreenPtr pScreen)
    I830PortPrivPtr pPriv;
    XF86AttributePtr att;
 
-   DPRINTF(PFX, "I830SetupImageVideo\n");
+   DPRINTF(PFX, "I830SetupImageVideoOverlay\n");
 
    if (!(adapt = xcalloc(1, sizeof(XF86VideoAdaptorRec) +
 			 sizeof(I830PortPrivRec) + sizeof(DevUnion))))
@@ -705,8 +733,9 @@ I830SetupImageVideo(ScreenPtr pScreen)
    adapt->GetPortAttribute = I830GetPortAttribute;
    adapt->QueryBestSize = I830QueryBestSize;
    adapt->PutImage = I830PutImage;
-   adapt->QueryImageAttributes = I830QueryImageAttributes;
+   adapt->QueryImageAttributes = I830QueryImageAttributesOverlay;
 
+   pPriv->textured = FALSE;
    pPriv->colorKey = pI830->colorKey & ((1 << pScrn->depth) - 1);
    pPriv->videoStatus = 0;
    pPriv->brightness = 0;
@@ -744,8 +773,6 @@ I830SetupImageVideo(ScreenPtr pScreen)
    pScreen->BlockHandler = I830BlockHandler;
 
    xvColorKey = MAKE_ATOM("XV_COLORKEY");
-   xvBrightness = MAKE_ATOM("XV_BRIGHTNESS");
-   xvContrast = MAKE_ATOM("XV_CONTRAST");
    xvDoubleBuffer = MAKE_ATOM("XV_DOUBLE_BUFFER");
 
    /* Allow the pipe to be switched from pipe A to B when in clone mode */
@@ -768,6 +795,86 @@ I830SetupImageVideo(ScreenPtr pScreen)
    return adapt;
 }
 
+static XF86VideoAdaptorPtr
+I830SetupImageVideoTextured(ScreenPtr pScreen)
+{
+   XF86VideoAdaptorPtr adapt;
+   XF86VideoEncodingPtr encoding;
+   XF86AttributePtr attrs;
+   I830PortPrivPtr portPrivs;
+   DevUnion *devUnions;
+   int nports = 16, i;
+   int nAttributes;
+
+   DPRINTF(PFX, "I830SetupImageVideoOverlay\n");
+
+   nAttributes = NUM_TEXTURED_ATTRIBUTES;
+
+   adapt = xcalloc(1, sizeof(XF86VideoAdaptorRec));
+   portPrivs = xcalloc(nports, sizeof(I830PortPrivRec));
+   devUnions = xcalloc(nports, sizeof(DevUnion));
+   encoding = xcalloc(1, sizeof(XF86VideoEncodingRec));
+   attrs = xcalloc(nAttributes, sizeof(XF86AttributeRec));
+   if (adapt == NULL || portPrivs == NULL || devUnions == NULL ||
+       encoding == NULL || attrs == NULL)
+   {
+      xfree(adapt);
+      xfree(portPrivs);
+      xfree(devUnions);
+      xfree(encoding);
+      xfree(attrs);
+      return NULL;
+   }
+
+   adapt->type = XvWindowMask | XvInputMask | XvImageMask;
+   adapt->flags = 0;
+   adapt->name = "Intel(R) Textured Video";
+   adapt->nEncodings = 1;
+   adapt->pEncodings = encoding;
+   adapt->pEncodings[0].id = 0;
+   adapt->pEncodings[0].name = "XV_IMAGE";
+   adapt->pEncodings[0].width = 2048;
+   adapt->pEncodings[0].height = 2048;
+   adapt->pEncodings[0].rate.numerator = 1;
+   adapt->pEncodings[0].rate.denominator = 1;
+   adapt->nFormats = NUM_FORMATS;
+   adapt->pFormats = Formats;
+   adapt->nPorts = nports;
+   adapt->pPortPrivates = devUnions;
+   adapt->nAttributes = nAttributes;
+   adapt->pAttributes = attrs;
+   memcpy(attrs, TexturedAttributes, nAttributes * sizeof(XF86AttributeRec));
+   adapt->nImages = NUM_IMAGES;
+   adapt->pImages = Images;
+   adapt->PutVideo = NULL;
+   adapt->PutStill = NULL;
+   adapt->GetVideo = NULL;
+   adapt->GetStill = NULL;
+   adapt->StopVideo = I830StopVideo;
+   adapt->SetPortAttribute = I830SetPortAttribute;
+   adapt->GetPortAttribute = I830GetPortAttribute;
+   adapt->QueryBestSize = I830QueryBestSize;
+   adapt->PutImage = I830PutImage;
+   adapt->QueryImageAttributes = I830QueryImageAttributesTextured;
+
+   for (i = 0; i < nports; i++) {
+      I830PortPrivPtr pPriv = &portPrivs[i];
+
+      pPriv->textured = TRUE;
+      pPriv->videoStatus = 0;
+      pPriv->linear = NULL;
+      pPriv->currentBuf = 0;
+      pPriv->doubleBuffer = 1;
+
+      /* gotta uninit this someplace, XXX: shouldn't be necessary for textured */
+      REGION_NULL(pScreen, &pPriv->clip);
+
+      adapt->pPortPrivates[i].ptr = (pointer) (pPriv);
+   }
+
+   return adapt;
+}
+
 static Bool
 RegionsEqual(RegionPtr A, RegionPtr B)
 {
@@ -805,6 +912,9 @@ I830StopVideo(ScrnInfoPtr pScrn, pointer
    I830OverlayRegPtr overlay =
 	 (I830OverlayRegPtr) (pI830->FbBase + pI830->OverlayMem->Start);
 
+   if (pPriv->textured)
+      return;
+
    DPRINTF(PFX, "I830StopVideo\n");
 
    REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
@@ -844,6 +954,14 @@ I830SetPortAttribute(ScrnInfoPtr pScrn,
    I830OverlayRegPtr overlay =
 	 (I830OverlayRegPtr) (pI830->FbBase + pI830->OverlayMem->Start);
 
+   if (pPriv->textured) {
+      /* XXX: Currently the brightness/saturation attributes aren't hooked up.
+       * However, apps expect them to be there, and the spec seems to let us
+       * sneak out of actually implementing them for now.
+       */
+      return Success;
+   }
+
    if (attribute == xvBrightness) {
       if ((value < -128) || (value > 127))
 	 return BadValue;
@@ -996,13 +1114,12 @@ I830QueryBestSize(ScrnInfoPtr pScrn,
 }
 
 static void
-I830CopyPackedData(ScrnInfoPtr pScrn,
+I830CopyPackedData(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv,
 		   unsigned char *buf,
 		   int srcPitch,
 		   int dstPitch, int top, int left, int h, int w)
 {
    I830Ptr pI830 = I830PTR(pScrn);
-   I830PortPrivPtr pPriv = pI830->adaptor->pPortPrivates[0].ptr;
    unsigned char *src, *dst;
    int i,j;
    unsigned char *s;
@@ -1093,12 +1210,12 @@ I830CopyPackedData(ScrnInfoPtr pScrn,
 /* Copies planar data in *buf to UYVY-packed data in the screen atYBufXOffset.
  */
 static void
-I830CopyPlanarToPackedData(ScrnInfoPtr pScrn, unsigned char *buf, int srcPitch,
+I830CopyPlanarToPackedData(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv,
+			   unsigned char *buf, int srcPitch,
 			   int srcPitch2, int dstPitch, int srcH,
 			   int top, int left, int h, int w, int id)
 {
    I830Ptr pI830 = I830PTR(pScrn);
-   I830PortPrivPtr pPriv = pI830->adaptor->pPortPrivates[0].ptr;
    CARD8 *dst1, *srcy, *srcu, *srcv;
    int y;
 
@@ -1150,12 +1267,12 @@ I830CopyPlanarToPackedData(ScrnInfoPtr p
 }
 
 static void
-I830CopyPlanarData(ScrnInfoPtr pScrn, unsigned char *buf, int srcPitch,
+I830CopyPlanarData(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv,
+		   unsigned char *buf, int srcPitch,
 		   int srcPitch2, int dstPitch, int srcH, int top, int left,
 		   int h, int w, int id)
 {
    I830Ptr pI830 = I830PTR(pScrn);
-   I830PortPrivPtr pPriv = pI830->adaptor->pPortPrivates[0].ptr;
    int i, j = 0;
    unsigned char *src1, *src2, *src3, *dst1, *dst2, *dst3;
    unsigned char *s;
@@ -2046,7 +2163,6 @@ do {									\
 	    (SRC_W << A2_SRC1_CHANNEL_W_SHIFT));			\
 } while (0)
 
-#ifdef USE_TEXTURED_VIDEO
 static void
 I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
 			 RegionPtr dstRegion,
@@ -2455,7 +2571,6 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
       ADVANCE_LP_RING();
    }
 }
-#endif /* USE_TEXTURED_VIDEO */
 
 static FBLinearPtr
 I830AllocateMemory(ScrnInfoPtr pScrn, FBLinearPtr linear, int size)
@@ -2529,7 +2644,7 @@ I830PutImage(ScrnInfoPtr pScrn,
    I830OverlayRegPtr overlay =
 	 (I830OverlayRegPtr) (pI830->FbBase + pI830->OverlayMem->Start);
    INT32 x1, x2, y1, y2;
-   int srcPitch, srcPitch2 = 0, dstPitch;
+   int srcPitch, srcPitch2 = 0, dstPitch, destId;
    int top, left, npixels, nlines, size, loops;
    BoxRec dstBox;
 
@@ -2575,11 +2690,15 @@ I830PutImage(ScrnInfoPtr pScrn,
 			      width, height))
       return Success;
 
+   destId = id;
    switch (id) {
    case FOURCC_YV12:
    case FOURCC_I420:
       srcPitch = (width + 3) & ~3;
       srcPitch2 = ((width >> 1) + 3) & ~3;
+      if (pPriv->textured) {
+	 destId = FOURCC_YUY2;
+      }
       break;
    case FOURCC_UYVY:
    case FOURCC_YUY2:
@@ -2588,8 +2707,7 @@ I830PutImage(ScrnInfoPtr pScrn,
       break;
    }
 
-   switch (id) {
-#ifndef USE_TEXTURED_VIDEO
+   switch (destId) {
    case FOURCC_YV12:
    case FOURCC_I420:
 #if 1
@@ -2610,13 +2728,6 @@ I830PutImage(ScrnInfoPtr pScrn,
       }
 #endif
       break;
-#else /* USE_TEXTURED_VIDEO */
-   case FOURCC_YV12:
-   case FOURCC_I420:
-      /* If we're doing textured video, then we're going to pack the data as
-       * UYVY in framebuffer, so allocate and align the memory that way.
-       */
-#endif
    case FOURCC_UYVY:
    case FOURCC_YUY2:
    default:
@@ -2670,7 +2781,9 @@ I830PutImage(ScrnInfoPtr pScrn,
 
    /* Make sure this buffer isn't in use */
    loops = 0;
-   if (*pI830->overlayOn && pPriv->doubleBuffer && (overlay->OCMD & OVERLAY_ENABLE)) {
+   if (!pPriv->textured && *pI830->overlayOn && pPriv->doubleBuffer &&
+       (overlay->OCMD & OVERLAY_ENABLE))
+   {
       while (loops < 1000000) {
 #if USE_USLEEP_FOR_VIDEO
          usleep(10);
@@ -2704,39 +2817,38 @@ I830PutImage(ScrnInfoPtr pScrn,
    case FOURCC_I420:
       top &= ~1;
       nlines = ((((y2 + 0xffff) >> 16) + 1) & ~1) - top;
-#ifdef USE_TEXTURED_VIDEO
-      I830CopyPlanarToPackedData(pScrn, buf, srcPitch, srcPitch2, dstPitch,
-				 height, top, left, nlines, npixels, id);
-      /* Our data is now in this forat, either way. */
-      id = FOURCC_YUY2;
-#else
-      I830CopyPlanarData(pScrn, buf, srcPitch, srcPitch2, dstPitch, height, top, left,
-			 nlines, npixels, id);
-#endif
+      if (pPriv->textured) {
+	 I830CopyPlanarToPackedData(pScrn, pPriv, buf, srcPitch, srcPitch2,
+				    dstPitch, height, top, left, nlines,
+				    npixels, id);
+      } else {
+	 I830CopyPlanarData(pScrn, pPriv, buf, srcPitch, srcPitch2, dstPitch,
+			    height, top, left, nlines, npixels, id);
+      }
       break;
    case FOURCC_UYVY:
    case FOURCC_YUY2:
    default:
       nlines = ((y2 + 0xffff) >> 16) - top;
-      I830CopyPackedData(pScrn, buf, srcPitch, dstPitch, top, left, nlines,
-			 npixels);
+      I830CopyPackedData(pScrn, pPriv, buf, srcPitch, dstPitch, top, left,
+			 nlines, npixels);
       break;
    }
 
-#ifndef USE_TEXTURED_VIDEO
-   /* update cliplist */
-   if (!RegionsEqual(&pPriv->clip, clipBoxes)) {
-      REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes);
-      xf86XVFillKeyHelper(pScreen, pPriv->colorKey, clipBoxes);
-   }
+   if (!pPriv->textured) {
+      /* update cliplist */
+      if (!RegionsEqual(&pPriv->clip, clipBoxes)) {
+ 	REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes);
+	 xf86XVFillKeyHelper(pScreen, pPriv->colorKey, clipBoxes);
+      }
 
-   I830DisplayVideo(pScrn, id, width, height, dstPitch,
-		    x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h);
-#else
-   I915DisplayVideoTextured(pScrn, pPriv, id, clipBoxes, width, height,
-			    dstPitch,
-			    x1, y1, x2, y2, src_w, src_h, drw_w, drw_h, pDraw);
-#endif
+      I830DisplayVideo(pScrn, destId, width, height, dstPitch,
+		       x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h);
+   } else {
+      I915DisplayVideoTextured(pScrn, pPriv, destId, clipBoxes, width, height,
+			       dstPitch, x1, y1, x2, y2,
+			       src_w, src_h, drw_w, drw_h, pDraw);
+   }
    pPriv->videoStatus = CLIENT_VIDEO_ON;
 
    return Success;
@@ -2746,23 +2858,25 @@ static int
 I830QueryImageAttributes(ScrnInfoPtr pScrn,
 			 int id,
 			 unsigned short *w, unsigned short *h,
-			 int *pitches, int *offsets)
+			 int *pitches, int *offsets, Bool textured)
 {
    I830Ptr pI830 = I830PTR(pScrn);
    int size, tmp;
 
    ErrorF("I830QueryImageAttributes: w is %d, h is %d\n", *w, *h);
 
-   if (IS_845G(pI830) || IS_I830(pI830)) {
-   if (*w > IMAGE_MAX_WIDTH_LEGACY)
-      *w = IMAGE_MAX_WIDTH_LEGACY;
-   if (*h > IMAGE_MAX_HEIGHT_LEGACY)
-      *h = IMAGE_MAX_HEIGHT_LEGACY;
-   } else {
-   if (*w > IMAGE_MAX_WIDTH)
-      *w = IMAGE_MAX_WIDTH;
-   if (*h > IMAGE_MAX_HEIGHT)
-      *h = IMAGE_MAX_HEIGHT;
+   if (!textured) {
+      if (IS_845G(pI830) || IS_I830(pI830)) {
+	 if (*w > IMAGE_MAX_WIDTH_LEGACY)
+	    *w = IMAGE_MAX_WIDTH_LEGACY;
+	 if (*h > IMAGE_MAX_HEIGHT_LEGACY)
+	    *h = IMAGE_MAX_HEIGHT_LEGACY;
+      } else {
+	 if (*w > IMAGE_MAX_WIDTH)
+	    *w = IMAGE_MAX_WIDTH;
+	 if (*h > IMAGE_MAX_HEIGHT)
+	    *h = IMAGE_MAX_HEIGHT;
+      }
    }
 
    *w = (*w + 1) & ~1;
@@ -2815,6 +2929,24 @@ I830QueryImageAttributes(ScrnInfoPtr pSc
    return size;
 }
 
+static int
+I830QueryImageAttributesOverlay(ScrnInfoPtr pScrn,
+				int id,
+				unsigned short *w, unsigned short *h,
+				int *pitches, int *offsets)
+{
+   return I830QueryImageAttributes(pScrn, id, w, h, pitches, offsets, FALSE);
+}
+
+static int
+I830QueryImageAttributesTextured(ScrnInfoPtr pScrn,
+				 int id,
+				 unsigned short *w, unsigned short *h,
+				 int *pitches, int *offsets)
+{
+   return I830QueryImageAttributes(pScrn, id, w, h, pitches, offsets, TRUE);
+}
+
 static void
 I830BlockHandler(int i,
 		 pointer blockData, pointer pTimeout, pointer pReadmask)
diff-tree f268979a0c779641c84e8d5b763acbda131474cf (from b09fd42d7088ead6c23e040ac4b71114f62de82b)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Mon May 15 10:05:19 2006 -0700

    Correct drawing issues with planar formats when top or left != 0, and Y didn't
    
    get its offset.

diff --git a/src/i830_video.c b/src/i830_video.c
index ac0833e..d23e83c 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -1107,15 +1107,15 @@ I830CopyPlanarToPackedData(ScrnInfoPtr p
    else
       dst1 = pI830->FbBase + pPriv->YBuf1offset;
 
-   srcy = buf;
+   srcy = buf + (top * srcPitch) + left;
    if (id == FOURCC_YV12) {
-      srcu = buf + (srcH * srcPitch) + ((top * srcPitch) >> 2) + (left >> 1);
-      srcv = buf + (srcH * srcPitch) + ((srcH >> 1) * srcPitch2) +
-	    ((top * srcPitch) >> 2) + (left >> 1);
+      srcu = buf + (srcH * srcPitch) + ((top / 2) * srcPitch2) + (left / 2);
+      srcv = buf + (srcH * srcPitch) + ((srcH / 2) * srcPitch2) +
+	    ((top / 2) * srcPitch2) + (left / 2);
    } else {
-      srcv = buf + (srcH * srcPitch) + ((top * srcPitch) >> 2) + (left >> 1);
-      srcu = buf + (srcH * srcPitch) + ((srcH >> 1) * srcPitch2) +
-	    ((top * srcPitch) >> 2) + (left >> 1);
+      srcv = buf + (srcH * srcPitch) + ((top / 2) * srcPitch2) + (left / 2);
+      srcu = buf + (srcH * srcPitch) + ((srcH / 2) * srcPitch2) +
+	    ((top / 2) * srcPitch2) + (left / 2);
    }
 
    for (y = 0; y < h; y++) {
diff-tree b09fd42d7088ead6c23e040ac4b71114f62de82b (from dd48790f4600a880fc4907c6e3b1cd51e9c0f0b7)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Mon May 15 09:29:43 2006 -0700

    Fix the planar formats to display correctly in textured mode. Still has issues
    
    with clipping, and some sampling differences between ximagesink and xvimagesink.

diff --git a/src/i830_video.c b/src/i830_video.c
index 39ab507..ac0833e 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -1099,7 +1099,7 @@ I830CopyPlanarToPackedData(ScrnInfoPtr p
 {
    I830Ptr pI830 = I830PTR(pScrn);
    I830PortPrivPtr pPriv = pI830->adaptor->pPortPrivates[0].ptr;
-   unsigned char *dst1, *srcy, *srcu, *srcv;
+   CARD8 *dst1, *srcy, *srcu, *srcv;
    int y;
 
    if (pPriv->currentBuf == 0)
@@ -1109,20 +1109,20 @@ I830CopyPlanarToPackedData(ScrnInfoPtr p
 
    srcy = buf;
    if (id == FOURCC_YV12) {
-      srcv = buf + (srcH * srcPitch) + ((top * srcPitch) >> 2) + (left >> 1);
-      srcu = buf + (srcH * srcPitch) + ((srcH >> 1) * srcPitch2) +
-	    ((top * srcPitch) >> 2) + (left >> 1);
-   } else {
       srcu = buf + (srcH * srcPitch) + ((top * srcPitch) >> 2) + (left >> 1);
       srcv = buf + (srcH * srcPitch) + ((srcH >> 1) * srcPitch2) +
 	    ((top * srcPitch) >> 2) + (left >> 1);
+   } else {
+      srcv = buf + (srcH * srcPitch) + ((top * srcPitch) >> 2) + (left >> 1);
+      srcu = buf + (srcH * srcPitch) + ((srcH >> 1) * srcPitch2) +
+	    ((top * srcPitch) >> 2) + (left >> 1);
    }
 
    for (y = 0; y < h; y++) {
-      unsigned char *dst = dst1;
-      unsigned char *sy = srcy;
-      unsigned char *su = srcu;
-      unsigned char *sv = srcv;
+      CARD32 *dst = (CARD32 *)dst1;
+      CARD8 *sy = srcy;
+      CARD8 *su = srcu;
+      CARD8 *sv = srcv;
       int i;
 
       i = w / 2;
@@ -2708,7 +2708,7 @@ I830PutImage(ScrnInfoPtr pScrn,
       I830CopyPlanarToPackedData(pScrn, buf, srcPitch, srcPitch2, dstPitch,
 				 height, top, left, nlines, npixels, id);
       /* Our data is now in this forat, either way. */
-      id = FOURCC_UYVY;
+      id = FOURCC_YUY2;
 #else
       I830CopyPlanarData(pScrn, buf, srcPitch, srcPitch2, dstPitch, height, top, left,
 			 nlines, npixels, id);
diff-tree dd48790f4600a880fc4907c6e3b1cd51e9c0f0b7 (from eec5e996ec9361099bf81d8d3b66933d5981c5a8)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Fri May 12 13:27:33 2006 -0700

    Divide width by 2 in planar-to-packed conversion loop, since each pass through
    
    the loop writes two source pixels.

diff --git a/src/i830_video.c b/src/i830_video.c
index 89f49e0..39ab507 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -1125,7 +1125,7 @@ I830CopyPlanarToPackedData(ScrnInfoPtr p
       unsigned char *sv = srcv;
       int i;
 
-      i = w;
+      i = w / 2;
       while(i > 4) {
 	 dst[0] = sy[0] | (sy[1] << 16) | (sv[0] << 8) | (su[0] << 24);
 	 dst[1] = sy[2] | (sy[3] << 16) | (sv[1] << 8) | (su[1] << 24);
diff-tree eec5e996ec9361099bf81d8d3b66933d5981c5a8 (from 4154a2f74811b91c0ef5bef32a919d6f8baf1a70)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Thu May 11 20:26:26 2006 -0700

    Merge textured-video-wip to textured-video-planar-full.

diff --git a/src/common.h b/src/common.h
index a6e4ca3..76509d4 100644
--- a/src/common.h
+++ b/src/common.h
@@ -125,13 +125,17 @@ extern void I830DPRINTF_stub(const char 
 
 #define ADVANCE_LP_RING() do {						\
    if (ringused > needed)          \
-      ErrorF("%s: ADVANCE_LP_RING: exceeded allocation %d/%d\n ",      \
-	     __FUNCTION__, ringused, needed);     \
+      FatalError("%s: ADVANCE_LP_RING: exceeded allocation %d/%d\n ",	\
+	     __FUNCTION__, ringused, needed);   			\
+   else if (ringused < needed)						\
+      FatalError("%s: ADVANCE_LP_RING: under-used allocation %d/%d\n ",	\
+	     __FUNCTION__, ringused, needed);   			\
    RecPtr->LpRing->tail = outring;					\
    RecPtr->LpRing->space -= ringused;					\
    if (outring & 0x07)							\
-      ErrorF("ADVANCE_LP_RING: "					\
-	     "outring (0x%x) isn't on a QWord boundary\n", outring);	\
+      FatalError("%s: ADVANCE_LP_RING: "					\
+	     "outring (0x%x) isn't on a QWord boundary\n",		\
+	     __FUNCTION__, outring);					\
    OUTREG(LP_RING + RING_TAIL, outring);				\
 } while (0)
 
diff --git a/src/i830_video.c b/src/i830_video.c
index a30b909..89f49e0 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -1090,6 +1090,65 @@ I830CopyPackedData(ScrnInfoPtr pScrn,
    }
 }
 
+/* Copies planar data in *buf to UYVY-packed data in the screen atYBufXOffset.
+ */
+static void
+I830CopyPlanarToPackedData(ScrnInfoPtr pScrn, unsigned char *buf, int srcPitch,
+			   int srcPitch2, int dstPitch, int srcH,
+			   int top, int left, int h, int w, int id)
+{
+   I830Ptr pI830 = I830PTR(pScrn);
+   I830PortPrivPtr pPriv = pI830->adaptor->pPortPrivates[0].ptr;
+   unsigned char *dst1, *srcy, *srcu, *srcv;
+   int y;
+
+   if (pPriv->currentBuf == 0)
+      dst1 = pI830->FbBase + pPriv->YBuf0offset;
+   else
+      dst1 = pI830->FbBase + pPriv->YBuf1offset;
+
+   srcy = buf;
+   if (id == FOURCC_YV12) {
+      srcv = buf + (srcH * srcPitch) + ((top * srcPitch) >> 2) + (left >> 1);
+      srcu = buf + (srcH * srcPitch) + ((srcH >> 1) * srcPitch2) +
+	    ((top * srcPitch) >> 2) + (left >> 1);
+   } else {
+      srcu = buf + (srcH * srcPitch) + ((top * srcPitch) >> 2) + (left >> 1);
+      srcv = buf + (srcH * srcPitch) + ((srcH >> 1) * srcPitch2) +
+	    ((top * srcPitch) >> 2) + (left >> 1);
+   }
+
+   for (y = 0; y < h; y++) {
+      unsigned char *dst = dst1;
+      unsigned char *sy = srcy;
+      unsigned char *su = srcu;
+      unsigned char *sv = srcv;
+      int i;
+
+      i = w;
+      while(i > 4) {
+	 dst[0] = sy[0] | (sy[1] << 16) | (sv[0] << 8) | (su[0] << 24);
+	 dst[1] = sy[2] | (sy[3] << 16) | (sv[1] << 8) | (su[1] << 24);
+	 dst[2] = sy[4] | (sy[5] << 16) | (sv[2] << 8) | (su[2] << 24);
+	 dst[3] = sy[6] | (sy[7] << 16) | (sv[3] << 8) | (su[3] << 24);
+	 dst += 4; su += 4; sv += 4; sy += 8;
+	 i -= 4;
+      }
+      while(i--) {
+	 dst[0] = sy[0] | (sy[1] << 16) | (sv[0] << 8) | (su[0] << 24);
+	 dst++; su++; sv++;
+	 sy += 2;
+      }
+
+      dst1 += dstPitch;
+      srcy += srcPitch;
+      if (y & 1) {
+	 srcu += srcPitch2;
+	 srcv += srcPitch2;
+      }	
+   }
+}
+
 static void
 I830CopyPlanarData(ScrnInfoPtr pScrn, unsigned char *buf, int srcPitch,
 		   int srcPitch2, int dstPitch, int srcH, int top, int left,
@@ -2521,6 +2580,18 @@ I830PutImage(ScrnInfoPtr pScrn,
    case FOURCC_I420:
       srcPitch = (width + 3) & ~3;
       srcPitch2 = ((width >> 1) + 3) & ~3;
+      break;
+   case FOURCC_UYVY:
+   case FOURCC_YUY2:
+   default:
+      srcPitch = width << 1;
+      break;
+   }
+
+   switch (id) {
+#ifndef USE_TEXTURED_VIDEO
+   case FOURCC_YV12:
+   case FOURCC_I420:
 #if 1
       if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
          dstPitch = ((height / 2) + 63) & ~63;
@@ -2539,10 +2610,16 @@ I830PutImage(ScrnInfoPtr pScrn,
       }
 #endif
       break;
+#else /* USE_TEXTURED_VIDEO */
+   case FOURCC_YV12:
+   case FOURCC_I420:
+      /* If we're doing textured video, then we're going to pack the data as
+       * UYVY in framebuffer, so allocate and align the memory that way.
+       */
+#endif
    case FOURCC_UYVY:
    case FOURCC_YUY2:
    default:
-      srcPitch = width << 1;
 #if 1
       if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
          dstPitch = ((height << 1) + 63) & ~63;
@@ -2627,8 +2704,15 @@ I830PutImage(ScrnInfoPtr pScrn,
    case FOURCC_I420:
       top &= ~1;
       nlines = ((((y2 + 0xffff) >> 16) + 1) & ~1) - top;
+#ifdef USE_TEXTURED_VIDEO
+      I830CopyPlanarToPackedData(pScrn, buf, srcPitch, srcPitch2, dstPitch,
+				 height, top, left, nlines, npixels, id);
+      /* Our data is now in this forat, either way. */
+      id = FOURCC_UYVY;
+#else
       I830CopyPlanarData(pScrn, buf, srcPitch, srcPitch2, dstPitch, height, top, left,
 			 nlines, npixels, id);
+#endif
       break;
    case FOURCC_UYVY:
    case FOURCC_YUY2:
diff-tree 4154a2f74811b91c0ef5bef32a919d6f8baf1a70 (from 3e0a9c9082942eb6f52612235d84b8408e1e03e9)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Wed May 10 12:09:00 2006 -0700

    Experimental work to use a full pixel shader for planar to YUV conversion, which
    
    also doesn't quite work.

diff --git a/src/i830_video.c b/src/i830_video.c
index 027351a..a30b909 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -1913,10 +1913,23 @@ static void draw_poly(CARD32 *vb,
    }
 }
 
+union intfloat {
+   CARD32 ui;
+   float f;
+};
+
+#define OUT_RING_F(x) do {						\
+   union intfloat _tmp;							\
+   _tmp.f = x;								\
+   OUT_RING(_tmp.ui);							\
+} while (0)
+
 #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);							\
@@ -1935,6 +1948,45 @@ do {									\
       OUT_RING(0x00000000);						\
 } while (0)
 
+/* Move the dest_chan from src0 to dest, leaving the other channels alone */
+#define OUT_MOV_TO_CHANNEL(dest_type, dest_nr, src0_type, src0_nr,	\
+			   dest_chan)					\
+do {									\
+   OUT_RING(A0_MOV | A0_DEST_CHANNEL_##dest_chan |			\
+	    (REG_TYPE_##dest_type << A0_DEST_TYPE_SHIFT) |		\
+	    (dest_nr << A0_DEST_NR_SHIFT) |				\
+	    (REG_TYPE_##src0_type << A0_SRC0_TYPE_SHIFT) |		\
+	    (src0_nr << 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));			\
+   OUT_RING(0);								\
+} while (0)
+
+/* Dot3-product src0 and src1, storing the result in dest_chan of the dest.
+ * Saturates, in case we have out-of-range YUV values.
+ */
+#define OUT_DP3_TO_CHANNEL(dest_type, dest_nr, src0_type, src0_nr,	\
+			   src1_type, src1_nr, dest_chan)		\
+do {									\
+   OUT_RING(A0_DP3 | A0_DEST_CHANNEL_##dest_chan | A0_DEST_SATURATE |	\
+	    (REG_TYPE_##dest_type << A0_DEST_TYPE_SHIFT) |		\
+	    (dest_nr << A0_DEST_NR_SHIFT) |				\
+	    (REG_TYPE_##src0_type << A0_SRC0_TYPE_SHIFT) |		\
+	    (src0_nr << 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_##src1_type << A1_SRC1_TYPE_SHIFT) |		\
+	    (src1_nr << A1_SRC1_TYPE_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));			\
+} while (0)
+
 #ifdef USE_TEXTURED_VIDEO
 static void
 I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
@@ -2114,15 +2166,51 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
       OUT_RING(((video_pitch / 4) - 1) << 21);
       ADVANCE_LP_RING();
    } else {
-      BEGIN_LP_RING(50);
-      /* For the planar formats, we set up three samplers -- one for each plane.
-       * Each plane is in a Y8 format, but the sampler converts this into a
-       * packed format.  We have to use a magic pixel shader, where we load
-       * each sampler into a temporary in turn, and then move that temporary
-       * into the real destination.
+      BEGIN_LP_RING(1 + 18 + (1 + 3*16) + 11 + 11);
+      OUT_RING(MI_NOOP);
+      /* For the planar formats, we set up three samplers -- one for each plane,
+       * in a Y8 format.  Because I couldn't get the special PLANAR_TO_PACKED
+       * shader setup to work, I did the manual pixel shader:
+       *
+       * y' = y - .0625
+       * u' = u - .5
+       * v' = v - .5;
+       *
+       * r = 1.1643 * y' + 0.0     * u' + 1.5958  * v'
+       * g = 1.1643 * y' - 0.39173 * u' - 0.81290 * v'
+       * b = 1.1643 * y' + 2.017   * u' + 0.0     * v'
+       *
+       * register assignment:
+       * r0 = (y',u',v',0)
+       * r1 = (y,y,y,y)
+       * r2 = (u,u,u,u)
+       * r3 = (v,v,v,v)
+       * OC = (r,g,b,1)
        */
-      /* fragment program - texture blend replace. */
-      OUT_RING(STATE3D_PIXEL_SHADER_PROGRAM | 26);
+      OUT_RING(STATE3D_PIXEL_SHADER_CONSTANTS | 16);
+      OUT_RING(0x000000f);	/* constants 0-3 */
+      /* constant 0: normalization offsets */
+      OUT_RING_F(-0.0625);
+      OUT_RING_F(-0.5);
+      OUT_RING_F(-0.5);
+      OUT_RING_F(0.0);
+      /* constant 1: r coefficients*/
+      OUT_RING_F(1.1643);
+      OUT_RING_F(0.0);
+      OUT_RING_F(1.5958);
+      OUT_RING_F(0.0);
+      /* constant 2: g coefficients */
+      OUT_RING_F(1.1643);
+      OUT_RING_F(-0.39173);
+      OUT_RING_F(-0.81290);
+      OUT_RING_F(0.0);
+      /* constant 3: b coefficients */
+      OUT_RING_F(1.1643);
+      OUT_RING_F(2.017);
+      OUT_RING_F(0.0);
+      OUT_RING_F(0.0);
+
+      OUT_RING(STATE3D_PIXEL_SHADER_PROGRAM | (3 * 16 - 1));
       /* Declare samplers */
       OUT_DCL(S, 0);
       OUT_DCL(S, 1);
@@ -2130,36 +2218,65 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
       OUT_DCL(T, 0);
       OUT_DCL(T, 1);
 
-      /* Load each sampler in turn.  Y (sampler 0) gets the un-halved coords
+      /* Load samplers to temporaries.  Y (sampler 0) gets the un-halved coords
        * from t1.
        */
-      OUT_TEXLD(R, 0, 0, T, 1);
-      OUT_TEXLD(R, 0, 1, T, 0);
-      OUT_TEXLD(R, 0, 2, T, 0);
+      OUT_TEXLD(R, 1, 0, T, 1);
+      OUT_TEXLD(R, 2, 1, T, 0);
+      OUT_TEXLD(R, 3, 2, T, 0);
+
+      /* Move the sampled YUV data in R[123] to the first 3 channels of R0. */
+      OUT_MOV_TO_CHANNEL(R, 0, R, 1, X);
+      OUT_MOV_TO_CHANNEL(R, 0, R, 2, Y);
+      OUT_MOV_TO_CHANNEL(R, 0, R, 3, Z);
+
+      /* Normalize the YUV data */
+      OUT_RING(A0_ADD | A0_DEST_CHANNEL_ALL |
+	       (REG_TYPE_R << A0_DEST_TYPE_SHIFT) | (0 << A0_DEST_NR_SHIFT) |				\
+	       (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_CONST << A1_SRC1_TYPE_SHIFT) | (0 << 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));
+
+      /* dot-product the YUV data in R0 by the vectors of coefficients for
+       * calculating R, G, and B, storing the results in the R, G, or B channels
+       * of the output color.
+       */
+      OUT_DP3_TO_CHANNEL(OC, 0, R, 0, CONST, 1, X);
+      OUT_DP3_TO_CHANNEL(OC, 0, R, 0, CONST, 2, Y);
+      OUT_DP3_TO_CHANNEL(OC, 0, R, 0, CONST, 3, Z);
 
-      /* Move the temporary to the destination */
-      OUT_RING(A0_MOV | A0_DEST_CHANNEL_ALL |
+      /* Set alpha of the output to 1.0, by wiring W to 1 and not actually using
+       * the source.
+       */
+      OUT_RING(A0_MOV | A0_DEST_CHANNEL_W |
 	       (REG_TYPE_OC << A0_DEST_TYPE_SHIFT) | (0 << A0_DEST_NR_SHIFT) |
-	       (REG_TYPE_R << A0_SRC0_TYPE_SHIFT) | (0 << A0_SRC0_NR_SHIFT));
+	       (REG_TYPE_OC << 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));
+	       (SRC_ONE << A1_SRC0_CHANNEL_W_SHIFT));
       OUT_RING(0);
       /* End fragment program */
 
       OUT_RING(STATE3D_SAMPLER_STATE | 9);
       OUT_RING(0x00000007);
       /* sampler 0 */
-      OUT_RING(SS2_COLORSPACE_CONVERSION | SS2_PLANAR_TO_PACKED_ENABLE);
+      OUT_RING(0x00000000);
       OUT_RING(0x00000000);
       OUT_RING(0x00000000);
       /* sampler 1 */
-      OUT_RING(SS2_COLORSPACE_CONVERSION | SS2_PLANAR_TO_PACKED_ENABLE);
+      OUT_RING(0x00000000);
       OUT_RING(0x00000000);
       OUT_RING(0x00000000);
       /* sampler 2 */
-      OUT_RING(SS2_COLORSPACE_CONVERSION | SS2_PLANAR_TO_PACKED_ENABLE);
+      OUT_RING(0x00000000);
       OUT_RING(0x00000000);
       OUT_RING(0x00000000);
 
diff-tree 3e0a9c9082942eb6f52612235d84b8408e1e03e9 (from 3af4a967e73b367bb531f2760b4803db1388bcf9)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Tue May 9 16:57:19 2006 -0700

    Do a separate BEGIN/ADVANCE_LP_RING set in the planar vs packed blocks, so I
    
    can adjust the planar code more easily.

diff --git a/src/i830_video.c b/src/i830_video.c
index 985148e..027351a 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -1947,7 +1947,7 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
    I830Ptr pI830 = I830PTR(pScrn);
    CARD32 format, ms3, s2;
    BoxPtr pbox;
-   int nbox, dwords, dxo, dyo;
+   int nbox, dxo, dyo;
    Bool planar;
 
    ErrorF("I915DisplayVideo: %dx%d (pitch %d)\n", width, height,
@@ -1970,12 +1970,7 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
 
    /* XXX: Dirty dri/rotate state  */
 
-   if (planar)
-      dwords = 94;
-   else
-      dwords = 64;
-
-   BEGIN_LP_RING(dwords);
+   BEGIN_LP_RING(44);
 
    /* invarient state */
    OUT_RING(MI_NOOP);
@@ -2082,8 +2077,10 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
    OUT_RING(BUFFERID_COLOR_BACK | BUFFER_USE_FENCES |
 	    (((pI830->displayWidth * pI830->cpp) / 4) << 2));
    OUT_RING(pI830->bufferOffset);
+   ADVANCE_LP_RING();
 
    if (!planar) {
+      BEGIN_LP_RING(20);
       /* fragment program - texture blend replace. */
       OUT_RING(STATE3D_PIXEL_SHADER_PROGRAM | 8);
       OUT_DCL(S, 0);
@@ -2115,7 +2112,9 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
 	 ms3 |= MS3_USE_FENCE_REGS;
       OUT_RING(ms3);
       OUT_RING(((video_pitch / 4) - 1) << 21);
+      ADVANCE_LP_RING();
    } else {
+      BEGIN_LP_RING(50);
       /* For the planar formats, we set up three samplers -- one for each plane.
        * Each plane is in a Y8 format, but the sampler converts this into a
        * packed format.  We have to use a magic pixel shader, where we load
@@ -2187,9 +2186,8 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
       ms3 |= (width / 2 - 1) << MS3_WIDTH_SHIFT;
       OUT_RING(ms3);
       OUT_RING(((video_pitch / 4) - 1) << 21);
+      ADVANCE_LP_RING();
    }
-
-   ADVANCE_LP_RING();
    
    {
       BEGIN_LP_RING(2);
diff-tree 3af4a967e73b367bb531f2760b4803db1388bcf9 (from 06e62ec521ed3f7ed232ace8e188891bedb53097)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Tue May 9 16:50:48 2006 -0700

    Add a couple of macros to simplify writing of video pixel shaders.

diff --git a/src/i810_reg.h b/src/i810_reg.h
index 08b576f..0ed7ff6 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -1407,6 +1407,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define D0_CHANNEL_XYZ              (D0_CHANNEL_XY|D0_CHANNEL_Z)
 /* End description of STATE3D_PIXEL_SHADER_PROGRAM */
 
+#define STATE3D_PIXEL_SHADER_CONSTANTS	(CMD_3D | (0x1d<<24)|(0x06<<16))
+
 #define STATE3D_DRAWING_RECTANGLE	(CMD_3D | (0x1d<<24)|(0x80<<16)|3)
 
 #define STATE3D_SCISSOR_RECTANGLE	(CMD_3D | (0x1d<<24)|(0x81<<16)|1)
diff --git a/src/i830_video.c b/src/i830_video.c
index 77f65d0..985148e 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -1913,6 +1913,28 @@ static void draw_poly(CARD32 *vb,
    }
 }
 
+#define OUT_DCL(type, nr) do {						\
+   CARD32 chans = 0;							\
+   if (REG_TYPE_##type == REG_TYPE_T)					\
+      chans = D0_CHANNEL_ALL;						\
+   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)
+
 #ifdef USE_TEXTURED_VIDEO
 static void
 I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
@@ -2064,20 +2086,9 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
    if (!planar) {
       /* fragment program - texture blend replace. */
       OUT_RING(STATE3D_PIXEL_SHADER_PROGRAM | 8);
-      OUT_RING(D0_DCL | (REG_TYPE_S << D0_TYPE_SHIFT) | (0 << D0_NR_SHIFT));
-      OUT_RING(0x00000000);
-      OUT_RING(0x00000000);
-
-      OUT_RING(D0_DCL | (REG_TYPE_T << D0_TYPE_SHIFT) | (0 << D0_NR_SHIFT) |
-	       D0_CHANNEL_ALL);
-      OUT_RING(0x00000000);
-      OUT_RING(0x00000000);
-
-      OUT_RING(T0_TEXLD | (REG_TYPE_OC << T0_DEST_TYPE_SHIFT) |
-	       (0 << T0_SAMPLER_NR_SHIFT));
-      OUT_RING((REG_TYPE_T << T1_ADDRESS_REG_TYPE_SHIFT) |
-	       (0 << T1_ADDRESS_REG_NR_SHIFT));
-      OUT_RING(0x00000000);
+      OUT_DCL(S, 0);
+      OUT_DCL(T, 0);
+      OUT_TEXLD(OC, 0, 0, T, 0);
       /* End fragment program */
 
       OUT_RING(STATE3D_SAMPLER_STATE | 3);
@@ -2114,47 +2125,18 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
       /* fragment program - texture blend replace. */
       OUT_RING(STATE3D_PIXEL_SHADER_PROGRAM | 26);
       /* Declare samplers */
-      OUT_RING(D0_DCL | (REG_TYPE_S << D0_TYPE_SHIFT) | (0 << D0_NR_SHIFT));
-      OUT_RING(0x00000000);
-      OUT_RING(0x00000000);
-      OUT_RING(D0_DCL | (REG_TYPE_S << D0_TYPE_SHIFT) | (1 << D0_NR_SHIFT));
-      OUT_RING(0x00000000);
-      OUT_RING(0x00000000);
-      OUT_RING(D0_DCL | (REG_TYPE_S << D0_TYPE_SHIFT) | (2 << D0_NR_SHIFT));
-      OUT_RING(0x00000000);
-      OUT_RING(0x00000000);
+      OUT_DCL(S, 0);
+      OUT_DCL(S, 1);
+      OUT_DCL(S, 2);
+      OUT_DCL(T, 0);
+      OUT_DCL(T, 1);
 
-      /* Declare coordinate sources */
-      OUT_RING(D0_DCL | (REG_TYPE_T << D0_TYPE_SHIFT) | (0 << D0_NR_SHIFT) |
-	       D0_CHANNEL_ALL);
-      OUT_RING(0x00000000);
-      OUT_RING(0x00000000);
-      OUT_RING(D0_DCL | (REG_TYPE_T << D0_TYPE_SHIFT) | (1 << D0_NR_SHIFT) |
-	       D0_CHANNEL_ALL);
-      OUT_RING(0x00000000);
-      OUT_RING(0x00000000);
-
-      /* Load each sampler in turn.  Y (sampler 0) gets the coords with
-       * doubled width.
+      /* Load each sampler in turn.  Y (sampler 0) gets the un-halved coords
+       * from t1.
        */
-      OUT_RING(T0_TEXLD |
-	       (REG_TYPE_R << T0_DEST_TYPE_SHIFT) | (0 << T0_DEST_NR_SHIFT) |
-	       (0 << T0_SAMPLER_NR_SHIFT));
-      OUT_RING((REG_TYPE_T << T1_ADDRESS_REG_TYPE_SHIFT) |
-	       (1 << T1_ADDRESS_REG_NR_SHIFT));
-      OUT_RING(0x00000000);
-      OUT_RING(T0_TEXLD |
-	       (REG_TYPE_R << T0_DEST_TYPE_SHIFT) | (0 << T0_DEST_NR_SHIFT) |
-	       (1 << T0_SAMPLER_NR_SHIFT));
-      OUT_RING((REG_TYPE_T << T1_ADDRESS_REG_TYPE_SHIFT) |
-	       (0 << T1_ADDRESS_REG_NR_SHIFT));
-      OUT_RING(0x00000000);
-      OUT_RING(T0_TEXLD |
-	       (REG_TYPE_R << T0_DEST_TYPE_SHIFT) | (0 << T0_DEST_NR_SHIFT) |
-	       (2 << T0_SAMPLER_NR_SHIFT));
-      OUT_RING((REG_TYPE_T << T1_ADDRESS_REG_TYPE_SHIFT) |
-	       (0 << T1_ADDRESS_REG_NR_SHIFT));
-      OUT_RING(0x00000000);
+      OUT_TEXLD(R, 0, 0, T, 1);
+      OUT_TEXLD(R, 0, 1, T, 0);
+      OUT_TEXLD(R, 0, 2, T, 0);
 
       /* Move the temporary to the destination */
       OUT_RING(A0_MOV | A0_DEST_CHANNEL_ALL |
diff-tree 06e62ec521ed3f7ed232ace8e188891bedb53097 (from b1090a42b200710628dd8b0c7ced15db7bbe71a1)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Tue May 9 12:04:58 2006 -0700

    Commit a WIP implementation of the planar video shader that does the
    
    planar-to-packed conversion for us.  Unfortunately the documentation is unclear,
    and I haven't managed to get any implementation of it working correctly.

diff --git a/src/i810_reg.h b/src/i810_reg.h
index f57d5d8..08b576f 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -1046,7 +1046,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define SS1_MAPMASK_MASK                (0x8fff<<0)
 
 #define SS2_REVERSE_GAMMA_ENABLE        (1<<31)
-#define SS2_PACKED_TO_PLANAR_ENABLE     (1<<30)
+#define SS2_PLANAR_TO_PACKED_ENABLE     (1<<30)
 #define SS2_COLORSPACE_CONVERSION       (1<<29)
 #define SS2_CHROMAKEY_SHIFT             27
 #define SS2_BASE_MIP_LEVEL_SHIFT        22
diff --git a/src/i830_video.c b/src/i830_video.c
index ab6b777..77f65d0 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -1872,12 +1872,18 @@ typedef union {
 
 static void draw_poly(CARD32 *vb,
                       float verts[][2],
-                      float texcoords[][2])
+                      float texcoords[][2],
+		      float texcoords2[][2])
 {
-   int vertex_size = 8;
+   int vertex_size;
    intelVertex tmp;
    int i, k;
 
+   if (texcoords2 != NULL)
+      vertex_size = 10;
+   else
+      vertex_size = 8;
+   
    /* initial constant vertex fields */
    tmp.v.z = 1.0;
    tmp.v.w = 1.0; 
@@ -1895,6 +1901,10 @@ static void draw_poly(CARD32 *vb,
       tmp.v.y = verts[k][1];
       tmp.v.u0 = texcoords[k][0];
       tmp.v.v0 = texcoords[k][1];
+      if (texcoords2 != NULL) {
+	 tmp.v.u1 = texcoords2[k][0];
+	 tmp.v.v1 = texcoords2[k][1];
+      }
 
       for (i = 0 ; i < vertex_size ; i++)
          vb[i] = tmp.ui[i];
@@ -1905,22 +1915,46 @@ static void draw_poly(CARD32 *vb,
 
 #ifdef USE_TEXTURED_VIDEO
 static void
-I915DisplayVideoTextured(ScrnInfoPtr pScrn, int id, RegionPtr dstRegion,
-		 short width, short height, int video_offset,
-		 int video_pitch, int x1, int y1, int x2, int y2,
-		 short src_w, short src_h, short drw_w, short drw_h,
-		 DrawablePtr pDraw)
+I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
+			 RegionPtr dstRegion,
+			 short width, short height, int video_pitch,
+			 int x1, int y1, int x2, int y2,
+			 short src_w, short src_h, short drw_w, short drw_h,
+			 DrawablePtr pDraw)
 {
    I830Ptr pI830 = I830PTR(pScrn);
-   CARD32 format, ms3;
+   CARD32 format, ms3, s2;
    BoxPtr pbox;
-   int nbox, dxo, dyo;
+   int nbox, dwords, dxo, dyo;
+   Bool planar;
 
    ErrorF("I915DisplayVideo: %dx%d (pitch %d)\n", width, height,
 	  video_pitch);
 
+   switch (id) {
+   case FOURCC_UYVY:
+   case FOURCC_YUY2:
+      planar = FALSE;
+      break;
+   case FOURCC_YV12:
+   case FOURCC_I420:
+      planar = TRUE;
+      break;
+   default:
+      ErrorF("Unknown format 0x%x\n", id);
+      planar = FALSE;
+      break;
+   }
+
    /* XXX: Dirty dri/rotate state  */
-   BEGIN_LP_RING(64);
+
+   if (planar)
+      dwords = 94;
+   else
+      dwords = 64;
+
+   BEGIN_LP_RING(dwords);
+
    /* invarient state */
    OUT_RING(MI_NOOP);
    OUT_RING(STATE3D_ANTI_ALIASING |
@@ -1947,7 +1981,7 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
 	    ENABLE_POINT_RASTER_RULE | OGL_POINT_RASTER_RULE);
 
    OUT_RING(STATE3D_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(3) | 1);
-   OUT_RING(0x00000000);
+   OUT_RING(0x00000000); /* texture coordinate wrap */
 
    /* flush map & render cache */
    OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE);
@@ -1980,10 +2014,25 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
 
    OUT_RING(STATE3D_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) |
 	    I1_LOAD_S(4) | I1_LOAD_S(5) | I1_LOAD_S(6) | 4);
-   OUT_RING(0xfffffff0);
-   OUT_RING(0x00902c80);
-   OUT_RING(0x00000000);
-   OUT_RING(0x00020216);
+   s2 = S2_TEXCOORD_FMT(0, TEXCOORDFMT_2D);
+   if (planar)
+      s2 |= S2_TEXCOORD_FMT(1, TEXCOORDFMT_2D);
+   else
+      s2 |= S2_TEXCOORD_FMT(1, TEXCOORDFMT_NOT_PRESENT);
+   s2 |= 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(s2);
+   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(STATE3D_INDEPENDENT_ALPHA_BLEND |
 	    IAB_MODIFY_ENABLE |
@@ -2006,57 +2055,158 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
    OUT_RING(STATE3D_STIPPLE);
    OUT_RING(0x00000000);
 
-   /* fragment program - texture blend replace*/
-   OUT_RING(STATE3D_PIXEL_SHADER_PROGRAM | 8);
-   OUT_RING(D0_DCL | (REG_TYPE_S << D0_TYPE_SHIFT) | (0 << D0_NR_SHIFT));
-   OUT_RING(0x00000000);
-   OUT_RING(0x00000000);
-
-   OUT_RING(D0_DCL | (REG_TYPE_T << D0_TYPE_SHIFT) | (0 << D0_NR_SHIFT) |
-	    D0_CHANNEL_ALL);
-   OUT_RING(0x00000000);
-   OUT_RING(0x00000000);
-
-   OUT_RING(T0_TEXLD | (REG_TYPE_OC << T0_DEST_TYPE_SHIFT) |
-	    (0 << T0_SAMPLER_NR_SHIFT));
-   OUT_RING((REG_TYPE_T << T1_ADDRESS_REG_TYPE_SHIFT) |
-	    (0 << T1_ADDRESS_REG_NR_SHIFT));
-   OUT_RING(0x00000000);
-   /* End fragment program */
-
-   OUT_RING(STATE3D_SAMPLER_STATE | 3);
-   OUT_RING(0x00000001);
-   OUT_RING(SS2_COLORSPACE_CONVERSION);
-   OUT_RING(0x00000000);
-   OUT_RING(0x00000000);
-
    /* front buffer, pitch, offset */
    OUT_RING(STATE3D_BUFFER_INFO);
    OUT_RING(BUFFERID_COLOR_BACK | BUFFER_USE_FENCES |
 	    (((pI830->displayWidth * pI830->cpp) / 4) << 2));
    OUT_RING(pI830->bufferOffset);
 
-   /* Set the entire frontbuffer up as a texture */
-   OUT_RING(STATE3D_MAP_STATE);
-   OUT_RING(0x00000001);	/* texture map #1 */
-   OUT_RING(video_offset);
+   if (!planar) {
+      /* fragment program - texture blend replace. */
+      OUT_RING(STATE3D_PIXEL_SHADER_PROGRAM | 8);
+      OUT_RING(D0_DCL | (REG_TYPE_S << D0_TYPE_SHIFT) | (0 << D0_NR_SHIFT));
+      OUT_RING(0x00000000);
+      OUT_RING(0x00000000);
 
-   ms3 = MAPSURF_422;
-   switch (id) {
-   case FOURCC_YUY2:
-      ms3 |= MT_422_YCRCB_NORMAL;
-      break;
-   case FOURCC_UYVY:
-      ms3 |= MT_422_YCRCB_SWAPY;
-      break;
+      OUT_RING(D0_DCL | (REG_TYPE_T << D0_TYPE_SHIFT) | (0 << D0_NR_SHIFT) |
+	       D0_CHANNEL_ALL);
+      OUT_RING(0x00000000);
+      OUT_RING(0x00000000);
+
+      OUT_RING(T0_TEXLD | (REG_TYPE_OC << T0_DEST_TYPE_SHIFT) |
+	       (0 << T0_SAMPLER_NR_SHIFT));
+      OUT_RING((REG_TYPE_T << T1_ADDRESS_REG_TYPE_SHIFT) |
+	       (0 << T1_ADDRESS_REG_NR_SHIFT));
+      OUT_RING(0x00000000);
+      /* End fragment program */
+
+      OUT_RING(STATE3D_SAMPLER_STATE | 3);
+      OUT_RING(0x00000001);
+      OUT_RING(SS2_COLORSPACE_CONVERSION);
+      OUT_RING(0x00000000);
+      OUT_RING(0x00000000);
+
+      OUT_RING(STATE3D_MAP_STATE | 3);
+      OUT_RING(0x00000001);	/* texture map #1 */
+      OUT_RING(pPriv->YBuf0offset);
+      ms3 = MAPSURF_422;
+      switch (id) {
+      case FOURCC_YUY2:
+	 ms3 |= MT_422_YCRCB_NORMAL;
+	 break;
+      case FOURCC_UYVY:
+	 ms3 |= MT_422_YCRCB_SWAPY;
+	 break;
+      }
+      ms3 |= (height - 1) << MS3_HEIGHT_SHIFT;
+      ms3 |= (width - 1) << MS3_WIDTH_SHIFT;
+      if (!pI830->disableTiling)
+	 ms3 |= MS3_USE_FENCE_REGS;
+      OUT_RING(ms3);
+      OUT_RING(((video_pitch / 4) - 1) << 21);
+   } else {
+      /* For the planar formats, we set up three samplers -- one for each plane.
+       * Each plane is in a Y8 format, but the sampler converts this into a
+       * packed format.  We have to use a magic pixel shader, where we load
+       * each sampler into a temporary in turn, and then move that temporary
+       * into the real destination.
+       */
+      /* fragment program - texture blend replace. */
+      OUT_RING(STATE3D_PIXEL_SHADER_PROGRAM | 26);
+      /* Declare samplers */
+      OUT_RING(D0_DCL | (REG_TYPE_S << D0_TYPE_SHIFT) | (0 << D0_NR_SHIFT));
+      OUT_RING(0x00000000);
+      OUT_RING(0x00000000);
+      OUT_RING(D0_DCL | (REG_TYPE_S << D0_TYPE_SHIFT) | (1 << D0_NR_SHIFT));
+      OUT_RING(0x00000000);
+      OUT_RING(0x00000000);
+      OUT_RING(D0_DCL | (REG_TYPE_S << D0_TYPE_SHIFT) | (2 << D0_NR_SHIFT));
+      OUT_RING(0x00000000);
+      OUT_RING(0x00000000);
+
+      /* Declare coordinate sources */
+      OUT_RING(D0_DCL | (REG_TYPE_T << D0_TYPE_SHIFT) | (0 << D0_NR_SHIFT) |
+	       D0_CHANNEL_ALL);
+      OUT_RING(0x00000000);
+      OUT_RING(0x00000000);
+      OUT_RING(D0_DCL | (REG_TYPE_T << D0_TYPE_SHIFT) | (1 << D0_NR_SHIFT) |
+	       D0_CHANNEL_ALL);
+      OUT_RING(0x00000000);
+      OUT_RING(0x00000000);
+
+      /* Load each sampler in turn.  Y (sampler 0) gets the coords with
+       * doubled width.
+       */
+      OUT_RING(T0_TEXLD |
+	       (REG_TYPE_R << T0_DEST_TYPE_SHIFT) | (0 << T0_DEST_NR_SHIFT) |
+	       (0 << T0_SAMPLER_NR_SHIFT));
+      OUT_RING((REG_TYPE_T << T1_ADDRESS_REG_TYPE_SHIFT) |
+	       (1 << T1_ADDRESS_REG_NR_SHIFT));
+      OUT_RING(0x00000000);
+      OUT_RING(T0_TEXLD |
+	       (REG_TYPE_R << T0_DEST_TYPE_SHIFT) | (0 << T0_DEST_NR_SHIFT) |
+	       (1 << T0_SAMPLER_NR_SHIFT));
+      OUT_RING((REG_TYPE_T << T1_ADDRESS_REG_TYPE_SHIFT) |
+	       (0 << T1_ADDRESS_REG_NR_SHIFT));
+      OUT_RING(0x00000000);
+      OUT_RING(T0_TEXLD |
+	       (REG_TYPE_R << T0_DEST_TYPE_SHIFT) | (0 << T0_DEST_NR_SHIFT) |
+	       (2 << T0_SAMPLER_NR_SHIFT));
+      OUT_RING((REG_TYPE_T << T1_ADDRESS_REG_TYPE_SHIFT) |
+	       (0 << T1_ADDRESS_REG_NR_SHIFT));
+      OUT_RING(0x00000000);
+
+      /* Move the temporary to the destination */
+      OUT_RING(A0_MOV | A0_DEST_CHANNEL_ALL |
+	       (REG_TYPE_OC << A0_DEST_TYPE_SHIFT) | (0 << A0_DEST_NR_SHIFT) |
+	       (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));
+      OUT_RING(0);
+      /* End fragment program */
+
+      OUT_RING(STATE3D_SAMPLER_STATE | 9);
+      OUT_RING(0x00000007);
+      /* sampler 0 */
+      OUT_RING(SS2_COLORSPACE_CONVERSION | SS2_PLANAR_TO_PACKED_ENABLE);
+      OUT_RING(0x00000000);
+      OUT_RING(0x00000000);
+      /* sampler 1 */
+      OUT_RING(SS2_COLORSPACE_CONVERSION | SS2_PLANAR_TO_PACKED_ENABLE);
+      OUT_RING(0x00000000);
+      OUT_RING(0x00000000);
+      /* sampler 2 */
+      OUT_RING(SS2_COLORSPACE_CONVERSION | SS2_PLANAR_TO_PACKED_ENABLE);
+      OUT_RING(0x00000000);
+      OUT_RING(0x00000000);
+
+      OUT_RING(STATE3D_MAP_STATE | 9);
+      OUT_RING(0x00000007);
+
+      OUT_RING(pPriv->YBuf0offset);
+      ms3 = MAPSURF_8BIT | MT_8BIT_I8;
+      ms3 |= (height - 1) << MS3_HEIGHT_SHIFT;
+      ms3 |= (width - 1) << MS3_WIDTH_SHIFT;
+      OUT_RING(ms3);
+      OUT_RING(((video_pitch * 2 / 4) - 1) << 21);
+
+      OUT_RING(pPriv->UBuf0offset);
+      ms3 = MAPSURF_8BIT | MT_8BIT_I8;
+      ms3 |= (height / 2 - 1) << MS3_HEIGHT_SHIFT;
+      ms3 |= (width / 2 - 1) << MS3_WIDTH_SHIFT;
+      OUT_RING(ms3);
+      OUT_RING(((video_pitch / 4) - 1) << 21);
+
+      OUT_RING(pPriv->VBuf0offset);
+      ms3 = MAPSURF_8BIT | MT_8BIT_I8;
+      ms3 |= (height / 2 - 1) << MS3_HEIGHT_SHIFT;
+      ms3 |= (width / 2 - 1) << MS3_WIDTH_SHIFT;
+      OUT_RING(ms3);
+      OUT_RING(((video_pitch / 4) - 1) << 21);
    }
-   ms3 |= (height - 1) << MS3_HEIGHT_SHIFT;
-   ms3 |= (width - 1) << MS3_WIDTH_SHIFT;
-   if (!pI830->disableTiling)
-      ms3 |= MS3_USE_FENCE_REGS;
 
-   OUT_RING(ms3);
-   OUT_RING(((video_pitch / 4) - 1) << 21);
    ADVANCE_LP_RING();
    
    {
@@ -2079,15 +2229,21 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
       int box_y2 = pbox->y2;
       int j;
       float src_scale_x, src_scale_y;
-      CARD32 vb[32];
-      float verts[4][2], tex[4][2];
+      CARD32 vb[40];
+      float verts[4][2], tex[4][2], tex2[4][2];
+      int vert_data_count;
 
       pbox++;
 
       src_scale_x = (float)src_w / (float)drw_w;
       src_scale_y  = (float)src_h / (float)drw_h;
 
-      BEGIN_LP_RING(40);
+      if (!planar)
+	 vert_data_count = 32;
+      else
+	 vert_data_count = 40;
+
+      BEGIN_LP_RING(vert_data_count + 8);
       OUT_RING(MI_NOOP);
       OUT_RING(MI_NOOP);
       OUT_RING(MI_NOOP);
@@ -2097,24 +2253,48 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
       OUT_RING(MI_NOOP);
 
       /* vertex data */
-      OUT_RING(PRIMITIVE3D | PRIM3D_INLINE | PRIM3D_TRIFAN | (32 - 1));
+      OUT_RING(PRIMITIVE3D | PRIM3D_INLINE | PRIM3D_TRIFAN |
+	       (vert_data_count - 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;
       verts[3][0] = box_x1; verts[3][1] = box_y2;
-      tex[0][0] = (box_x1 - dxo) * src_scale_x;
-      tex[0][1] = (box_y1 - dyo) * src_scale_y;
-      tex[1][0] = (box_x2 - dxo) * src_scale_x;
-      tex[1][1] = (box_y1 - dyo) * src_scale_y;
-      tex[2][0] = (box_x2 - dxo) * src_scale_x;
-      tex[2][1] = (box_y2 - dyo) * src_scale_y;
-      tex[3][0] = (box_x1 - dxo) * src_scale_x;
-      tex[3][1] = (box_y2 - dyo) * src_scale_y;
-
-      /* emit vertex buffer */
-      draw_poly(vb, verts, tex);
-      for (j = 0; j < 32; j++)
-         OUT_RING(vb[j]);
+
+      if (!planar) {
+	 tex[0][0] = (box_x1 - dxo) * src_scale_x;
+	 tex[0][1] = (box_y1 - dyo) * src_scale_y;
+	 tex[1][0] = (box_x2 - dxo) * src_scale_x;
+	 tex[1][1] = (box_y1 - dyo) * src_scale_y;
+	 tex[2][0] = (box_x2 - dxo) * src_scale_x;
+	 tex[2][1] = (box_y2 - dyo) * src_scale_y;
+	 tex[3][0] = (box_x1 - dxo) * src_scale_x;
+	 tex[3][1] = (box_y2 - dyo) * src_scale_y;
+	 /* emit vertex buffer */
+	 draw_poly(vb, verts, tex, NULL);
+	 for (j = 0; j < vert_data_count; j++)
+	    OUT_RING(vb[j]);
+      } else {
+	 tex[0][0] = (box_x1 - dxo) * src_scale_x / 2.0;
+	 tex[0][1] = (box_y1 - dyo) * src_scale_y / 2.0;
+	 tex[1][0] = (box_x2 - dxo) * src_scale_x / 2.0;
+	 tex[1][1] = (box_y1 - dyo) * src_scale_y / 2.0;
+	 tex[2][0] = (box_x2 - dxo) * src_scale_x / 2.0;
+	 tex[2][1] = (box_y2 - dyo) * src_scale_y / 2.0;
+	 tex[3][0] = (box_x1 - dxo) * src_scale_x / 2.0;
+	 tex[3][1] = (box_y2 - dyo) * src_scale_y / 2.0;
+	 tex2[0][0] = (box_x1 - dxo) * src_scale_x;
+	 tex2[0][1] = (box_y1 - dyo) * src_scale_y;
+	 tex2[1][0] = (box_x2 - dxo) * src_scale_x;
+	 tex2[1][1] = (box_y1 - dyo) * src_scale_y;
+	 tex2[2][0] = (box_x2 - dxo) * src_scale_x;
+	 tex2[2][1] = (box_y2 - dyo) * src_scale_y;
+	 tex2[3][0] = (box_x1 - dxo) * src_scale_x;
+	 tex2[3][1] = (box_y2 - dyo) * src_scale_y;
+	 /* emit vertex buffer */
+	 draw_poly(vb, verts, tex, tex2);
+	 for (j = 0; j < vert_data_count; j++)
+	    OUT_RING(vb[j]);
+      }
 
       ADVANCE_LP_RING();
    }
@@ -2372,8 +2552,8 @@ I830PutImage(ScrnInfoPtr pScrn,
    I830DisplayVideo(pScrn, id, width, height, dstPitch,
 		    x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h);
 #else
-   I915DisplayVideoTextured(pScrn, id, clipBoxes, width, height,
-			    pPriv->YBuf0offset, dstPitch,
+   I915DisplayVideoTextured(pScrn, pPriv, id, clipBoxes, width, height,
+			    dstPitch,
 			    x1, y1, x2, y2, src_w, src_h, drw_w, drw_h, pDraw);
 #endif
    pPriv->videoStatus = CLIENT_VIDEO_ON;
diff-tree b1090a42b200710628dd8b0c7ced15db7bbe71a1 (from 3a2d8af214a79591322ce6e5546f856a1ee41736)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Mon May 8 14:22:00 2006 -0700

    More magic number reduction in rotation code.

diff --git a/src/i810_reg.h b/src/i810_reg.h
index 54536c6..f57d5d8 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -958,7 +958,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define ENABLE_SCISSOR_RECT		((1<<1) | 1)
 #define DISABLE_SCISSOR_RECT		((1<<1) | 0)
 
-#define STATE3D_MAP_STATE		(CMD_3D | (0x1d<<24)|(0x00<<16)|3)
+#define STATE3D_MAP_STATE		(CMD_3D | (0x1d<<24)|(0x00<<16))
 
 #define MS1_MAPMASK_SHIFT               0
 #define MS1_MAPMASK_MASK                (0x8fff<<0)
@@ -1108,6 +1108,113 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define STATE3D_LOAD_STATE_IMMEDIATE_1	(CMD_3D | (0x1d<<24)|(0x04<<16))
 #define I1_LOAD_S(n)				(1 << (4 + n))
 
+#define S0_VB_OFFSET_MASK              0xffffffc
+#define S0_AUTO_CACHE_INV_DISABLE      (1<<0)
+
+#define S1_VERTEX_WIDTH_SHIFT          24
+#define S1_VERTEX_WIDTH_MASK           (0x3f<<24)
+#define S1_VERTEX_PITCH_SHIFT          16
+#define S1_VERTEX_PITCH_MASK           (0x3f<<16)
+
+#define TEXCOORDFMT_2D                 0x0
+#define TEXCOORDFMT_3D                 0x1
+#define TEXCOORDFMT_4D                 0x2
+#define TEXCOORDFMT_1D                 0x3
+#define TEXCOORDFMT_2D_16              0x4
+#define TEXCOORDFMT_4D_16              0x5
+#define TEXCOORDFMT_NOT_PRESENT        0xf
+#define S2_TEXCOORD_FMT0_MASK            0xf
+#define S2_TEXCOORD_FMT1_SHIFT           4
+#define S2_TEXCOORD_FMT(unit, type)    ((type)<<(unit*4))
+#define S2_TEXCOORD_NONE               (~0)
+
+/* S3 not interesting */
+
+#define S4_POINT_WIDTH_SHIFT           23
+#define S4_POINT_WIDTH_MASK            (0x1ff<<23)
+#define S4_LINE_WIDTH_SHIFT            19
+#define S4_LINE_WIDTH_ONE              (0x2<<19)
+#define S4_LINE_WIDTH_MASK             (0xf<<19)
+#define S4_FLATSHADE_ALPHA             (1<<18)
+#define S4_FLATSHADE_FOG               (1<<17)
+#define S4_FLATSHADE_SPECULAR          (1<<16)
+#define S4_FLATSHADE_COLOR             (1<<15)
+#define S4_CULLMODE_BOTH	       (0<<13)
+#define S4_CULLMODE_NONE	       (1<<13)
+#define S4_CULLMODE_CW		       (2<<13)
+#define S4_CULLMODE_CCW		       (3<<13)
+#define S4_CULLMODE_MASK	       (3<<13)
+#define S4_VFMT_POINT_WIDTH            (1<<12)
+#define S4_VFMT_SPEC_FOG               (1<<11)
+#define S4_VFMT_COLOR                  (1<<10)
+#define S4_VFMT_DEPTH_OFFSET           (1<<9)
+#define S4_VFMT_XYZ     	       (1<<6)
+#define S4_VFMT_XYZW     	       (2<<6)
+#define S4_VFMT_XY     		       (3<<6)
+#define S4_VFMT_XYW     	       (4<<6)
+#define S4_VFMT_XYZW_MASK              (7<<6)
+#define S4_FORCE_DEFAULT_DIFFUSE       (1<<5)
+#define S4_FORCE_DEFAULT_SPECULAR      (1<<4)
+#define S4_LOCAL_DEPTH_OFFSET_ENABLE   (1<<3)
+#define S4_VFMT_FOG_PARAM              (1<<2)
+#define S4_SPRITE_POINT_ENABLE         (1<<1)
+#define S4_LINE_ANTIALIAS_ENABLE       (1<<0)
+
+#define S4_VFMT_MASK (S4_VFMT_POINT_WIDTH   | 	\
+		      S4_VFMT_SPEC_FOG      |	\
+		      S4_VFMT_COLOR         |	\
+		      S4_VFMT_DEPTH_OFFSET  |	\
+		      S4_VFMT_XYZW_MASK     |	\
+		      S4_VFMT_FOG_PARAM)
+
+
+#define S5_WRITEDISABLE_ALPHA          (1<<31)
+#define S5_WRITEDISABLE_RED            (1<<30)
+#define S5_WRITEDISABLE_GREEN          (1<<29)
+#define S5_WRITEDISABLE_BLUE           (1<<28)
+#define S5_WRITEDISABLE_MASK           (0xf<<28)
+#define S5_FORCE_DEFAULT_POINT_SIZE    (1<<27)
+#define S5_LAST_PIXEL_ENABLE           (1<<26)
+#define S5_GLOBAL_DEPTH_OFFSET_ENABLE  (1<<25)
+#define S5_FOG_ENABLE                  (1<<24)
+#define S5_STENCIL_REF_SHIFT           16
+#define S5_STENCIL_REF_MASK            (0xff<<16)
+#define S5_STENCIL_TEST_FUNC_SHIFT     13
+#define S5_STENCIL_TEST_FUNC_MASK      (0x7<<13)
+#define S5_STENCIL_FAIL_SHIFT          10
+#define S5_STENCIL_FAIL_MASK           (0x7<<10)
+#define S5_STENCIL_PASS_Z_FAIL_SHIFT   7
+#define S5_STENCIL_PASS_Z_FAIL_MASK    (0x7<<7)
+#define S5_STENCIL_PASS_Z_PASS_SHIFT   4
+#define S5_STENCIL_PASS_Z_PASS_MASK    (0x7<<4)
+#define S5_STENCIL_WRITE_ENABLE        (1<<3)
+#define S5_STENCIL_TEST_ENABLE         (1<<2)
+#define S5_COLOR_DITHER_ENABLE         (1<<1)
+#define S5_LOGICOP_ENABLE              (1<<0)
+
+
+#define S6_ALPHA_TEST_ENABLE           (1<<31)
+#define S6_ALPHA_TEST_FUNC_SHIFT       28
+#define S6_ALPHA_TEST_FUNC_MASK        (0x7<<28)
+#define S6_ALPHA_REF_SHIFT             20
+#define S6_ALPHA_REF_MASK              (0xff<<20)
+#define S6_DEPTH_TEST_ENABLE           (1<<19)
+#define S6_DEPTH_TEST_FUNC_SHIFT       16
+#define S6_DEPTH_TEST_FUNC_MASK        (0x7<<16)
+#define S6_CBUF_BLEND_ENABLE           (1<<15)
+#define S6_CBUF_BLEND_FUNC_SHIFT       12
+#define S6_CBUF_BLEND_FUNC_MASK        (0x7<<12)
+#define S6_CBUF_SRC_BLEND_FACT_SHIFT   8
+#define S6_CBUF_SRC_BLEND_FACT_MASK    (0xf<<8)
+#define S6_CBUF_DST_BLEND_FACT_SHIFT   4
+#define S6_CBUF_DST_BLEND_FACT_MASK    (0xf<<4)
+#define S6_DEPTH_WRITE_ENABLE          (1<<3)
+#define S6_COLOR_WRITE_ENABLE          (1<<2)
+#define S6_TRISTRIP_PV_SHIFT           0
+#define S6_TRISTRIP_PV_MASK            (0x3<<0)
+
+#define S7_DEPTH_OFFSET_CONST_MASK     ~0
+
 #define STATE3D_PIXEL_SHADER_PROGRAM	(CMD_3D | (0x1d<<24)|(0x05<<16))
 
 #define REG_TYPE_R                 0 /* temporary regs, no need to
diff --git a/src/i830_rotate.c b/src/i830_rotate.c
index 3b5ed25..cd02fbc 100644
--- a/src/i830_rotate.c
+++ b/src/i830_rotate.c
@@ -292,7 +292,7 @@ I915UpdateRotate (ScreenPtr      pScreen
 	       ENABLE_POINT_RASTER_RULE | OGL_POINT_RASTER_RULE);
 
       OUT_RING(STATE3D_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(3) | 1);
-      OUT_RING(0x00000000);
+      OUT_RING(0x00000000); /* texture coordinate wrap */
 
       /* flush map & render cache */
       OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE);
@@ -325,10 +325,22 @@ I915UpdateRotate (ScreenPtr      pScreen
 
       OUT_RING(STATE3D_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) |
 	       I1_LOAD_S(4) | I1_LOAD_S(5) | I1_LOAD_S(6) | 4);
-      OUT_RING(0xfffffff0);
-      OUT_RING(0x00902c80);
-      OUT_RING(0x00000000);
-      OUT_RING(0x00020216);
+      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(STATE3D_INDEPENDENT_ALPHA_BLEND |
 	       IAB_MODIFY_ENABLE |
@@ -387,7 +399,7 @@ I915UpdateRotate (ScreenPtr      pScreen
          OUT_RING(pI8301->FrontBuffer2.Start);
 
       /* Set the entire frontbuffer up as a texture */
-      OUT_RING(STATE3D_MAP_STATE);
+      OUT_RING(STATE3D_MAP_STATE | 3);
       OUT_RING(0x00000001);	/* texture map #1 */
 
       if (I830IsPrimary(pScrn)) 
diff-tree 3a2d8af214a79591322ce6e5546f856a1ee41736 (from 66875c1559bc20b531ab72e5d6b921d9f50b29f3)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Mon May 8 09:42:40 2006 -0700

    Add initial textured XV support for i915, which can do YUY2 and UYVY, but fails
    
    on I420 and YV12 currently, doesn't support the composite extension, and should
    break XV support on non-i915.

diff --git a/src/i810_reg.h b/src/i810_reg.h
index 6c9b5bc..54536c6 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -1040,7 +1040,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define MS4_VOLUME_DEPTH_SHIFT          0    
 #define MS4_VOLUME_DEPTH_MASK           (0xff<<0)
 
-#define STATE3D_SAMPLER_STATE		(CMD_3D | (0x1d<<24)|(0x01<<16)
+#define STATE3D_SAMPLER_STATE		(CMD_3D | (0x1d<<24)|(0x01<<16))
 
 #define SS1_MAPMASK_SHIFT               0
 #define SS1_MAPMASK_MASK                (0x8fff<<0)
diff --git a/src/i830_video.c b/src/i830_video.c
index a608a7e..ab6b777 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -1,4 +1,4 @@
-#define VIDEO_DEBUG 0
+#define VIDEO_DEBUG 1
 /***************************************************************************
  
 Copyright 2000 Intel Corporation.  All Rights Reserved. 
@@ -84,6 +84,8 @@ THE USE OR OTHER DEALINGS IN THE SOFTWAR
 #include "dixstruct.h"
 #include "fourcc.h"
 
+#define USE_TEXTURED_VIDEO
+
 #ifndef USE_USLEEP_FOR_VIDEO
 #define USE_USLEEP_FOR_VIDEO 0
 #endif
@@ -1847,6 +1849,278 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int 
    OVERLAY_UPDATE;
 }
 
+/* Doesn't matter on the order for our purposes */
+typedef struct {
+   unsigned char red, green, blue, alpha;
+} intel_color_t;
+
+/* Vertex format */
+typedef union {
+   struct {
+      float x, y, z, w;
+      intel_color_t color;
+      intel_color_t specular;
+      float u0, v0;
+      float u1, v1;
+      float u2, v2;
+      float u3, v3;
+   } v;
+   float f[24];
+   unsigned int  ui[24];
+   unsigned char ub4[24][4];
+} intelVertex, *intelVertexPtr;
+
+static void draw_poly(CARD32 *vb,
+                      float verts[][2],
+                      float texcoords[][2])
+{
+   int vertex_size = 8;
+   intelVertex tmp;
+   int i, k;
+
+   /* initial constant vertex fields */
+   tmp.v.z = 1.0;
+   tmp.v.w = 1.0; 
+   tmp.v.color.red = 255;
+   tmp.v.color.green = 255;
+   tmp.v.color.blue = 255;
+   tmp.v.color.alpha = 255;
+   tmp.v.specular.red = 0;
+   tmp.v.specular.green = 0;
+   tmp.v.specular.blue = 0;
+   tmp.v.specular.alpha = 0;
+
+   for (k = 0; k < 4; k++) {
+      tmp.v.x = verts[k][0];
+      tmp.v.y = verts[k][1];
+      tmp.v.u0 = texcoords[k][0];
+      tmp.v.v0 = texcoords[k][1];
+
+      for (i = 0 ; i < vertex_size ; i++)
+         vb[i] = tmp.ui[i];
+
+      vb += vertex_size;
+   }
+}
+
+#ifdef USE_TEXTURED_VIDEO
+static void
+I915DisplayVideoTextured(ScrnInfoPtr pScrn, int id, RegionPtr dstRegion,
+		 short width, short height, int video_offset,
+		 int video_pitch, int x1, int y1, int x2, int y2,
+		 short src_w, short src_h, short drw_w, short drw_h,
+		 DrawablePtr pDraw)
+{
+   I830Ptr pI830 = I830PTR(pScrn);
+   CARD32 format, ms3;
+   BoxPtr pbox;
+   int nbox, dxo, dyo;
+
+   ErrorF("I915DisplayVideo: %dx%d (pitch %d)\n", width, height,
+	  video_pitch);
+
+   /* XXX: Dirty dri/rotate state  */
+   BEGIN_LP_RING(64);
+   /* invarient state */
+   OUT_RING(MI_NOOP);
+   OUT_RING(STATE3D_ANTI_ALIASING |
+	    LINE_CAP_WIDTH_MODIFY | LINE_CAP_WIDTH_1_0 |
+	    LINE_WIDTH_MODIFY | LINE_WIDTH_1_0);
+
+   OUT_RING(STATE3D_DFLT_DIFFUSE_CMD);
+   OUT_RING(0x00000000);
+
+   OUT_RING(STATE3D_DFLT_SPEC_CMD);
+   OUT_RING(0x00000000);
+
+   OUT_RING(STATE3D_DFLT_Z_CMD);
+   OUT_RING(0x00000000);
+
+   OUT_RING(STATE3D_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(STATE3D_RASTERIZATION_RULES |
+	    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(STATE3D_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 -- just clipping */
+   OUT_RING(STATE3D_DRAWING_RECTANGLE);
+   OUT_RING(0x00000000);	/* flags */
+   OUT_RING(0x00000000);	/* ymin, xmin */
+   OUT_RING((pScrn->virtualX - 1) | (pScrn->virtualY - 1) << 16); /* ymax, xmax */
+   OUT_RING(0x00000000);	/* yorigin, xorigin */
+   OUT_RING(MI_NOOP);
+
+   /* scissor */
+   OUT_RING(STATE3D_SCISSOR_ENABLE | DISABLE_SCISSOR_RECT);
+   OUT_RING(STATE3D_SCISSOR_RECTANGLE);
+   OUT_RING(0x00000000);	/* ymin, xmin */
+   OUT_RING(0x00000000);	/* ymax, xmax */
+
+   OUT_RING(0x7c000003);	/* unknown command */
+   OUT_RING(0x7d070000);
+   OUT_RING(0x00000000);
+   OUT_RING(0x68000002);
+
+   /* context setup */
+   OUT_RING(STATE3D_MODES_4 |
+	    ENABLE_LOGIC_OP_FUNC | LOGIC_OP_FUNC(LOGICOP_COPY) |
+	    ENABLE_STENCIL_WRITE_MASK | STENCIL_WRITE_MASK(0xff) |
+	    ENABLE_STENCIL_TEST_MASK | STENCIL_TEST_MASK(0xff));
+
+   OUT_RING(STATE3D_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) |
+	    I1_LOAD_S(4) | I1_LOAD_S(5) | I1_LOAD_S(6) | 4);
+   OUT_RING(0xfffffff0);
+   OUT_RING(0x00902c80);
+   OUT_RING(0x00000000);
+   OUT_RING(0x00020216);
+
+   OUT_RING(STATE3D_INDEPENDENT_ALPHA_BLEND |
+	    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(STATE3D_CONST_BLEND_COLOR);
+   OUT_RING(0x00000000);
+
+   OUT_RING(STATE3D_DEST_BUFFER_VARIABLES);
+   if (pI830->cpp == 2)
+      format = COLR_BUF_RGB565;
+   else
+      format = COLR_BUF_ARGB8888 | DEPTH_FRMT_24_FIXED_8_OTHER;
+
+   OUT_RING(LOD_PRECLAMP_OGL |
+     DSTORG_HORIZ_BIAS(0x80) | DSTORG_VERT_BIAS(0x80) | format);
+
+   OUT_RING(STATE3D_STIPPLE);
+   OUT_RING(0x00000000);
+
+   /* fragment program - texture blend replace*/
+   OUT_RING(STATE3D_PIXEL_SHADER_PROGRAM | 8);
+   OUT_RING(D0_DCL | (REG_TYPE_S << D0_TYPE_SHIFT) | (0 << D0_NR_SHIFT));
+   OUT_RING(0x00000000);
+   OUT_RING(0x00000000);
+
+   OUT_RING(D0_DCL | (REG_TYPE_T << D0_TYPE_SHIFT) | (0 << D0_NR_SHIFT) |
+	    D0_CHANNEL_ALL);
+   OUT_RING(0x00000000);
+   OUT_RING(0x00000000);
+
+   OUT_RING(T0_TEXLD | (REG_TYPE_OC << T0_DEST_TYPE_SHIFT) |
+	    (0 << T0_SAMPLER_NR_SHIFT));
+   OUT_RING((REG_TYPE_T << T1_ADDRESS_REG_TYPE_SHIFT) |
+	    (0 << T1_ADDRESS_REG_NR_SHIFT));
+   OUT_RING(0x00000000);
+   /* End fragment program */
+
+   OUT_RING(STATE3D_SAMPLER_STATE | 3);
+   OUT_RING(0x00000001);
+   OUT_RING(SS2_COLORSPACE_CONVERSION);
+   OUT_RING(0x00000000);
+   OUT_RING(0x00000000);
+
+   /* front buffer, pitch, offset */
+   OUT_RING(STATE3D_BUFFER_INFO);
+   OUT_RING(BUFFERID_COLOR_BACK | BUFFER_USE_FENCES |
+	    (((pI830->displayWidth * pI830->cpp) / 4) << 2));
+   OUT_RING(pI830->bufferOffset);
+
+   /* Set the entire frontbuffer up as a texture */
+   OUT_RING(STATE3D_MAP_STATE);
+   OUT_RING(0x00000001);	/* texture map #1 */
+   OUT_RING(video_offset);
+
+   ms3 = MAPSURF_422;
+   switch (id) {
+   case FOURCC_YUY2:
+      ms3 |= MT_422_YCRCB_NORMAL;
+      break;
+   case FOURCC_UYVY:
+      ms3 |= MT_422_YCRCB_SWAPY;
+      break;
+   }
+   ms3 |= (height - 1) << MS3_HEIGHT_SHIFT;
+   ms3 |= (width - 1) << MS3_WIDTH_SHIFT;
+   if (!pI830->disableTiling)
+      ms3 |= MS3_USE_FENCE_REGS;
+
+   OUT_RING(ms3);
+   OUT_RING(((video_pitch / 4) - 1) << 21);
+   ADVANCE_LP_RING();
+   
+   {
+      BEGIN_LP_RING(2);
+      OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE);
+      OUT_RING(0x00000000);
+      ADVANCE_LP_RING();
+   }
+
+   dxo = dstRegion->extents.x1;
+   dyo = dstRegion->extents.y1;
+
+   pbox = REGION_RECTS(dstRegion);
+   nbox = REGION_NUM_RECTS(dstRegion);
+   while (nbox--)
+   {
+      int box_x1 = pbox->x1;
+      int box_y1 = pbox->y1;
+      int box_x2 = pbox->x2;
+      int box_y2 = pbox->y2;
+      int j;
+      float src_scale_x, src_scale_y;
+      CARD32 vb[32];
+      float verts[4][2], tex[4][2];
+
+      pbox++;
+
+      src_scale_x = (float)src_w / (float)drw_w;
+      src_scale_y  = (float)src_h / (float)drw_h;
+
+      BEGIN_LP_RING(40);
+      OUT_RING(MI_NOOP);
+      OUT_RING(MI_NOOP);
+      OUT_RING(MI_NOOP);
+      OUT_RING(MI_NOOP);
+      OUT_RING(MI_NOOP);
+      OUT_RING(MI_NOOP);
+      OUT_RING(MI_NOOP);
+
+      /* vertex data */
+      OUT_RING(PRIMITIVE3D | 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;
+      verts[3][0] = box_x1; verts[3][1] = box_y2;
+      tex[0][0] = (box_x1 - dxo) * src_scale_x;
+      tex[0][1] = (box_y1 - dyo) * src_scale_y;
+      tex[1][0] = (box_x2 - dxo) * src_scale_x;
+      tex[1][1] = (box_y1 - dyo) * src_scale_y;
+      tex[2][0] = (box_x2 - dxo) * src_scale_x;
+      tex[2][1] = (box_y2 - dyo) * src_scale_y;
+      tex[3][0] = (box_x1 - dxo) * src_scale_x;
+      tex[3][1] = (box_y2 - dyo) * src_scale_y;
+
+      /* emit vertex buffer */
+      draw_poly(vb, verts, tex);
+      for (j = 0; j < 32; j++)
+         OUT_RING(vb[j]);
+
+      ADVANCE_LP_RING();
+   }
+}
+#endif /* USE_TEXTURED_VIDEO */
+
 static FBLinearPtr
 I830AllocateMemory(ScrnInfoPtr pScrn, FBLinearPtr linear, int size)
 {
@@ -1889,6 +2163,19 @@ I830AllocateMemory(ScrnInfoPtr pScrn, FB
    return new_linear;
 }
 
+/*
+ * The source rectangle of the video is defined by (src_x, src_y, src_w, src_h).
+ * The dest rectangle of the video is defined by (drw_x, drw_y, drw_w, drw_h).
+ * id is a fourcc code for the format of the video.
+ * buf is the pointer to the source data in system memory.
+ * width and height are the w/h of the source data.
+ * If "sync" is TRUE, then we must be finished with *buf at the point of return
+ * (which we always are).
+ * clipBoxes is the clipping region in screen space.
+ * data is a pointer to our port private.
+ * pDraw is a Drawable, which might not be the screen in the case of
+ * compositing.  It's a new argument to the function in the 1.1 server.
+ */
 static int
 I830PutImage(ScrnInfoPtr pScrn,
 	     short src_x, short src_y,
@@ -2075,6 +2362,7 @@ I830PutImage(ScrnInfoPtr pScrn,
       break;
    }
 
+#ifndef USE_TEXTURED_VIDEO
    /* update cliplist */
    if (!RegionsEqual(&pPriv->clip, clipBoxes)) {
       REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes);
@@ -2083,7 +2371,11 @@ I830PutImage(ScrnInfoPtr pScrn,
 
    I830DisplayVideo(pScrn, id, width, height, dstPitch,
 		    x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h);
-
+#else
+   I915DisplayVideoTextured(pScrn, id, clipBoxes, width, height,
+			    pPriv->YBuf0offset, dstPitch,
+			    x1, y1, x2, y2, src_w, src_h, drw_w, drw_h, pDraw);
+#endif
    pPriv->videoStatus = CLIENT_VIDEO_ON;
 
    return Success;
diff-tree 66875c1559bc20b531ab72e5d6b921d9f50b29f3 (from f2967a2f5f47b636b2445fa69dbc3ec79e065c90)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Fri May 5 10:15:23 2006 -0700

    Convert magic numbers in i915 rotation 3D state to symbolic names.

diff --git a/src/i810_reg.h b/src/i810_reg.h
index e52375f..6c9b5bc 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -837,6 +837,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define I852_GME				0x2
 #define I852_GM					0x5
 
+#define CMD_MI				(0 << 29)
+#define CMD_2D				(2 << 29)
+#define CMD_3D				(3 << 29)
 /* BLT commands */
 #define COLOR_BLT_CMD		((2<<29)|(0x40<<22)|(0x3))
 #define COLOR_BLT_WRITE_ALPHA	(1<<21)
@@ -867,14 +870,514 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define XY_MONO_SRC_BLT_WRITE_RGB	(1<<20)
 
 /* 3d state */
+#define STATE3D_ANTI_ALIASING		(CMD_3D | (0x06<<24))
+#define LINE_CAP_WIDTH_MODIFY		(1 << 16)
+#define LINE_CAP_WIDTH_1_0		(0x1 << 14)
+#define LINE_WIDTH_MODIFY		(1 << 8)
+#define LINE_WIDTH_1_0			(0x1 << 6)
+
+#define STATE3D_RASTERIZATION_RULES	(CMD_3D | (0x07<<24))
+#define ENABLE_POINT_RASTER_RULE	(1<<15)
+#define OGL_POINT_RASTER_RULE		(1<<13)
+#define ENABLE_TEXKILL_3D_4D            (1<<10)
+#define TEXKILL_3D                      (0<<9)
+#define TEXKILL_4D                      (1<<9)
+#define ENABLE_LINE_STRIP_PROVOKE_VRTX	(1<<8)
+#define ENABLE_TRI_FAN_PROVOKE_VRTX	(1<<5)
+#define LINE_STRIP_PROVOKE_VRTX(x)	((x)<<6)
+#define TRI_FAN_PROVOKE_VRTX(x) 	((x)<<3)
+
+#define STATE3D_INDEPENDENT_ALPHA_BLEND	(CMD_3D | (0x0b<<24))
+#define IAB_MODIFY_ENABLE	        (1<<23)
+#define IAB_ENABLE       	        (1<<22)
+#define IAB_MODIFY_FUNC         	(1<<21)
+#define IAB_FUNC_SHIFT          	16
+#define IAB_MODIFY_SRC_FACTOR   	(1<<11)
+#define IAB_SRC_FACTOR_SHIFT		6
+#define IAB_SRC_FACTOR_MASK		(BLENDFACT_MASK<<6)
+#define IAB_MODIFY_DST_FACTOR	        (1<<5)
+#define IAB_DST_FACTOR_SHIFT		0
+#define IAB_DST_FACTOR_MASK		(BLENDFACT_MASK<<0)
+
+#define BLENDFUNC_ADD			0x0
+#define BLENDFUNC_SUBTRACT		0x1
+#define BLENDFUNC_REVERSE_SUBTRACT	0x2
+#define BLENDFUNC_MIN			0x3
+#define BLENDFUNC_MAX			0x4
+#define BLENDFUNC_MASK			0x7
+
+#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 STATE3D_MODES_4			(CMD_3D | (0x0d<<24))
+#define ENABLE_LOGIC_OP_FUNC		(1<<23)
+#define LOGIC_OP_FUNC(x)		((x)<<18)
+#define LOGICOP_MASK			(0xf<<18)
+#define MODE4_ENABLE_STENCIL_TEST_MASK	((1<<17)|(0xff00))
+#define ENABLE_STENCIL_TEST_MASK	(1<<17)
+#define STENCIL_TEST_MASK(x)		((x)<<8)
+#define MODE4_ENABLE_STENCIL_WRITE_MASK	((1<<16)|(0x00ff))
+#define ENABLE_STENCIL_WRITE_MASK	(1<<16)
+#define STENCIL_WRITE_MASK(x)		((x)&0xff)
+
+#define LOGICOP_CLEAR			0
+#define LOGICOP_NOR			0x1
+#define LOGICOP_AND_INV 		0x2
+#define LOGICOP_COPY_INV		0x3
+#define LOGICOP_AND_RVRSE		0x4
+#define LOGICOP_INV			0x5
+#define LOGICOP_XOR			0x6
+#define LOGICOP_NAND			0x7
+#define LOGICOP_AND			0x8
+#define LOGICOP_EQUIV			0x9
+#define LOGICOP_NOOP			0xa
+#define LOGICOP_OR_INV			0xb
+#define LOGICOP_COPY			0xc
+#define LOGICOP_OR_RVRSE		0xd
+#define LOGICOP_OR			0xe
+#define LOGICOP_SET			0xf
+
+#define STATE3D_COORD_SET_BINDINGS	(CMD_3D | (0x16<<24))
+#define CSB_TCB(iunit,eunit)		((eunit) << ((iunit) * 3))
+
+#define STATE3D_SCISSOR_ENABLE		(CMD_3D | (0x1c<<24)|(0x10<<19))
+#define ENABLE_SCISSOR_RECT		((1<<1) | 1)
+#define DISABLE_SCISSOR_RECT		((1<<1) | 0)
+
+#define STATE3D_MAP_STATE		(CMD_3D | (0x1d<<24)|(0x00<<16)|3)
+
+#define MS1_MAPMASK_SHIFT               0
+#define MS1_MAPMASK_MASK                (0x8fff<<0)
+
+#define MS2_UNTRUSTED_SURFACE           (1<<31)
+#define MS2_ADDRESS_MASK                0xfffffffc
+#define MS2_VERTICAL_LINE_STRIDE        (1<<1)
+#define MS2_VERTICAL_OFFSET             (1<<1)
+
+#define MS3_HEIGHT_SHIFT              21
+#define MS3_WIDTH_SHIFT               10
+#define MS3_PALETTE_SELECT            (1<<9)
+#define MS3_MAPSURF_FORMAT_SHIFT      7
+#define MS3_MAPSURF_FORMAT_MASK       (0x7<<7)
+#define    MAPSURF_8BIT		 	   (1<<7)
+#define    MAPSURF_16BIT		   (2<<7)
+#define    MAPSURF_32BIT		   (3<<7)
+#define    MAPSURF_422			   (5<<7)
+#define    MAPSURF_COMPRESSED		   (6<<7)
+#define    MAPSURF_4BIT_INDEXED		   (7<<7)
+#define MS3_MT_FORMAT_MASK         (0x7 << 3)
+#define MS3_MT_FORMAT_SHIFT        3
+#define    MT_4BIT_IDX_ARGB8888	           (7<<3) /* SURFACE_4BIT_INDEXED */
+#define    MT_8BIT_I8		           (0<<3) /* SURFACE_8BIT */
+#define    MT_8BIT_L8		           (1<<3)
+#define    MT_8BIT_A8		           (4<<3)
+#define    MT_8BIT_MONO8	           (5<<3)
+#define    MT_16BIT_RGB565 		   (0<<3) /* SURFACE_16BIT */
+#define    MT_16BIT_ARGB1555		   (1<<3)
+#define    MT_16BIT_ARGB4444		   (2<<3)
+#define    MT_16BIT_AY88		   (3<<3)
+#define    MT_16BIT_88DVDU	           (5<<3)
+#define    MT_16BIT_BUMP_655LDVDU	   (6<<3)
+#define    MT_16BIT_I16	                   (7<<3)
+#define    MT_16BIT_L16	                   (8<<3)
+#define    MT_16BIT_A16	                   (9<<3)
+#define    MT_32BIT_ARGB8888		   (0<<3) /* SURFACE_32BIT */
+#define    MT_32BIT_ABGR8888		   (1<<3)
+#define    MT_32BIT_XRGB8888		   (2<<3)
+#define    MT_32BIT_XBGR8888		   (3<<3)
+#define    MT_32BIT_QWVU8888		   (4<<3)
+#define    MT_32BIT_AXVU8888		   (5<<3)
+#define    MT_32BIT_LXVU8888	           (6<<3)
+#define    MT_32BIT_XLVU8888	           (7<<3)
+#define    MT_32BIT_ARGB2101010	           (8<<3)
+#define    MT_32BIT_ABGR2101010	           (9<<3)
+#define    MT_32BIT_AWVU2101010	           (0xA<<3)
+#define    MT_32BIT_GR1616	           (0xB<<3)
+#define    MT_32BIT_VU1616	           (0xC<<3)
+#define    MT_32BIT_xI824	           (0xD<<3)
+#define    MT_32BIT_xA824	           (0xE<<3)
+#define    MT_32BIT_xL824	           (0xF<<3)
+#define    MT_422_YCRCB_SWAPY	           (0<<3) /* SURFACE_422 */
+#define    MT_422_YCRCB_NORMAL	           (1<<3)
+#define    MT_422_YCRCB_SWAPUV	           (2<<3)
+#define    MT_422_YCRCB_SWAPUVY	           (3<<3)
+#define    MT_COMPRESS_DXT1		   (0<<3) /* SURFACE_COMPRESSED */
+#define    MT_COMPRESS_DXT2_3	           (1<<3)
+#define    MT_COMPRESS_DXT4_5	           (2<<3)
+#define    MT_COMPRESS_FXT1		   (3<<3)
+#define    MT_COMPRESS_DXT1_RGB		   (4<<3)
+#define MS3_USE_FENCE_REGS              (1<<2)
+#define MS3_TILED_SURFACE             (1<<1)
+#define MS3_TILE_WALK                 (1<<0)
+
+#define MS4_PITCH_SHIFT                 21
+#define MS4_CUBE_FACE_ENA_NEGX          (1<<20)
+#define MS4_CUBE_FACE_ENA_POSX          (1<<19)
+#define MS4_CUBE_FACE_ENA_NEGY          (1<<18)
+#define MS4_CUBE_FACE_ENA_POSY          (1<<17)
+#define MS4_CUBE_FACE_ENA_NEGZ          (1<<16)
+#define MS4_CUBE_FACE_ENA_POSZ          (1<<15)
+#define MS4_CUBE_FACE_ENA_MASK          (0x3f<<15)
+#define MS4_MAX_LOD_SHIFT		9
+#define MS4_MAX_LOD_MASK		(0x3f<<9)
+#define MS4_MIP_LAYOUT_LEGACY           (0<<8)
+#define MS4_MIP_LAYOUT_BELOW_LPT        (0<<8)
+#define MS4_MIP_LAYOUT_RIGHT_LPT        (1<<8)
+#define MS4_VOLUME_DEPTH_SHIFT          0    
+#define MS4_VOLUME_DEPTH_MASK           (0xff<<0)
+
+#define STATE3D_SAMPLER_STATE		(CMD_3D | (0x1d<<24)|(0x01<<16)
+
+#define SS1_MAPMASK_SHIFT               0
+#define SS1_MAPMASK_MASK                (0x8fff<<0)
+
+#define SS2_REVERSE_GAMMA_ENABLE        (1<<31)
+#define SS2_PACKED_TO_PLANAR_ENABLE     (1<<30)
+#define SS2_COLORSPACE_CONVERSION       (1<<29)
+#define SS2_CHROMAKEY_SHIFT             27
+#define SS2_BASE_MIP_LEVEL_SHIFT        22
+#define SS2_BASE_MIP_LEVEL_MASK         (0x1f<<22)
+#define SS2_MIP_FILTER_SHIFT            20
+#define SS2_MIP_FILTER_MASK             (0x3<<20)
+#define   MIPFILTER_NONE       	0
+#define   MIPFILTER_NEAREST	1
+#define   MIPFILTER_LINEAR	3
+#define SS2_MAG_FILTER_SHIFT          17
+#define SS2_MAG_FILTER_MASK           (0x7<<17)
+#define   FILTER_NEAREST	0
+#define   FILTER_LINEAR		1
+#define   FILTER_ANISOTROPIC	2
+#define   FILTER_4X4_1    	3
+#define   FILTER_4X4_2    	4
+#define   FILTER_4X4_FLAT 	5
+#define   FILTER_6X5_MONO   	6 /* XXX - check */
+#define SS2_MIN_FILTER_SHIFT          14
+#define SS2_MIN_FILTER_MASK           (0x7<<14)
+#define SS2_LOD_BIAS_SHIFT            5
+#define SS2_LOD_BIAS_ONE              (0x10<<5)
+#define SS2_LOD_BIAS_MASK             (0x1ff<<5)
+/* Shadow requires:
+ *  MT_X8{I,L,A}24 or MT_{I,L,A}16 texture format
+ *  FILTER_4X4_x  MIN and MAG filters
+ */
+#define SS2_SHADOW_ENABLE             (1<<4)
+#define SS2_MAX_ANISO_MASK            (1<<3)
+#define SS2_MAX_ANISO_2               (0<<3)
+#define SS2_MAX_ANISO_4               (1<<3)
+#define SS2_SHADOW_FUNC_SHIFT         0
+#define SS2_SHADOW_FUNC_MASK          (0x7<<0)
+/* SS2_SHADOW_FUNC values: see COMPAREFUNC_* */
+
+#define SS3_MIN_LOD_SHIFT            24
+#define SS3_MIN_LOD_ONE              (0x10<<24)
+#define SS3_MIN_LOD_MASK             (0xff<<24)
+#define SS3_KILL_PIXEL_ENABLE        (1<<17)
+#define SS3_TCX_ADDR_MODE_SHIFT      12
+#define SS3_TCX_ADDR_MODE_MASK       (0x7<<12)
+#define   TEXCOORDMODE_WRAP		0
+#define   TEXCOORDMODE_MIRROR		1
+#define   TEXCOORDMODE_CLAMP_EDGE	2
+#define   TEXCOORDMODE_CUBE       	3
+#define   TEXCOORDMODE_CLAMP_BORDER	4
+#define   TEXCOORDMODE_MIRROR_ONCE      5
+#define SS3_TCY_ADDR_MODE_SHIFT      9
+#define SS3_TCY_ADDR_MODE_MASK       (0x7<<9)
+#define SS3_TCZ_ADDR_MODE_SHIFT      6
+#define SS3_TCZ_ADDR_MODE_MASK       (0x7<<6)
+#define SS3_NORMALIZED_COORDS        (1<<5)
+#define SS3_TEXTUREMAP_INDEX_SHIFT   1
+#define SS3_TEXTUREMAP_INDEX_MASK    (0xf<<1)
+#define SS3_DEINTERLACER_ENABLE      (1<<0)
+
+#define SS4_BORDER_COLOR_MASK        (~0)
+
+#define STATE3D_LOAD_STATE_IMMEDIATE_1	(CMD_3D | (0x1d<<24)|(0x04<<16))
+#define I1_LOAD_S(n)				(1 << (4 + n))
+
+#define STATE3D_PIXEL_SHADER_PROGRAM	(CMD_3D | (0x1d<<24)|(0x05<<16))
+
+#define REG_TYPE_R                 0 /* temporary regs, no need to
+				      * dcl, must be written before
+				      * read -- Preserved between
+				      * phases. 
+				      */
+#define REG_TYPE_T                 1 /* Interpolated values, must be
+				      * dcl'ed before use.
+				      *
+				      * 0..7: texture coord,
+				      * 8: diffuse spec,
+				      * 9: specular color,
+				      * 10: fog parameter in w.
+				      */
+#define REG_TYPE_CONST             2 /* Restriction: only one const
+				      * can be referenced per
+				      * instruction, though it may be
+				      * selected for multiple inputs.
+				      * Constants not initialized
+				      * default to zero.
+				      */
+#define REG_TYPE_S                 3 /* sampler */
+#define REG_TYPE_OC                4 /* output color (rgba) */
+#define REG_TYPE_OD                5 /* output depth (w), xyz are
+				      * temporaries.  If not written,
+				      * interpolated depth is used?
+				      */
+#define REG_TYPE_U                 6 /* unpreserved temporaries */
+#define REG_TYPE_MASK              0x7
+#define REG_NR_MASK                0xf
+
+
+/* REG_TYPE_T:
+ */
+#define T_TEX0     0
+#define T_TEX1     1
+#define T_TEX2     2
+#define T_TEX3     3
+#define T_TEX4     4
+#define T_TEX5     5
+#define T_TEX6     6
+#define T_TEX7     7
+#define T_DIFFUSE  8
+#define T_SPECULAR 9
+#define T_FOG_W    10		/* interpolated fog is in W coord */
+
+/* Arithmetic instructions */
+
+/* .replicate_swizzle == selection and replication of a particular
+ * scalar channel, ie., .xxxx, .yyyy, .zzzz or .wwww 
+ */
+#define A0_NOP    (0x0<<24)		/* no operation */
+#define A0_ADD    (0x1<<24)		/* dst = src0 + src1 */
+#define A0_MOV    (0x2<<24)		/* dst = src0 */
+#define A0_MUL    (0x3<<24)		/* dst = src0 * src1 */
+#define A0_MAD    (0x4<<24)		/* dst = src0 * src1 + src2 */
+#define A0_DP2ADD (0x5<<24)		/* dst.xyzw = src0.xy dot src1.xy + src2.replicate_swizzle */
+#define A0_DP3    (0x6<<24)		/* dst.xyzw = src0.xyz dot src1.xyz */
+#define A0_DP4    (0x7<<24)		/* dst.xyzw = src0.xyzw dot src1.xyzw */
+#define A0_FRC    (0x8<<24)		/* dst = src0 - floor(src0) */
+#define A0_RCP    (0x9<<24)		/* dst.xyzw = 1/(src0.replicate_swizzle) */
+#define A0_RSQ    (0xa<<24)		/* dst.xyzw = 1/(sqrt(abs(src0.replicate_swizzle))) */
+#define A0_EXP    (0xb<<24)		/* dst.xyzw = exp2(src0.replicate_swizzle) */
+#define A0_LOG    (0xc<<24)		/* dst.xyzw = log2(abs(src0.replicate_swizzle)) */
+#define A0_CMP    (0xd<<24)		/* dst = (src0 >= 0.0) ? src1 : src2 */
+#define A0_MIN    (0xe<<24)		/* dst = (src0 < src1) ? src0 : src1 */
+#define A0_MAX    (0xf<<24)		/* dst = (src0 >= src1) ? src0 : src1 */
+#define A0_FLR    (0x10<<24)		/* dst = floor(src0) */
+#define A0_MOD    (0x11<<24)		/* dst = src0 fmod 1.0 */
+#define A0_TRC    (0x12<<24)		/* dst = int(src0) */
+#define A0_SGE    (0x13<<24)		/* dst = src0 >= src1 ? 1.0 : 0.0 */
+#define A0_SLT    (0x14<<24)		/* dst = src0 < src1 ? 1.0 : 0.0 */
+#define A0_DEST_SATURATE                 (1<<22)
+#define A0_DEST_TYPE_SHIFT                19
+/* Allow: R, OC, OD, U */
+#define A0_DEST_NR_SHIFT                 14
+/* Allow R: 0..15, OC,OD: 0..0, U: 0..2 */
+#define A0_DEST_CHANNEL_X                (1<<10)
+#define A0_DEST_CHANNEL_Y                (2<<10)
+#define A0_DEST_CHANNEL_Z                (4<<10)
+#define A0_DEST_CHANNEL_W                (8<<10)
+#define A0_DEST_CHANNEL_ALL              (0xf<<10)
+#define A0_DEST_CHANNEL_SHIFT            10
+#define A0_SRC0_TYPE_SHIFT               7
+#define A0_SRC0_NR_SHIFT                 2
+
+#define A0_DEST_CHANNEL_XY              (A0_DEST_CHANNEL_X|A0_DEST_CHANNEL_Y)
+#define A0_DEST_CHANNEL_XYZ             (A0_DEST_CHANNEL_XY|A0_DEST_CHANNEL_Z)
+
+
+#define SRC_X        0
+#define SRC_Y        1
+#define SRC_Z        2
+#define SRC_W        3
+#define SRC_ZERO     4
+#define SRC_ONE      5
+
+#define A1_SRC0_CHANNEL_X_NEGATE         (1<<31)
+#define A1_SRC0_CHANNEL_X_SHIFT          28
+#define A1_SRC0_CHANNEL_Y_NEGATE         (1<<27)
+#define A1_SRC0_CHANNEL_Y_SHIFT          24
+#define A1_SRC0_CHANNEL_Z_NEGATE         (1<<23)
+#define A1_SRC0_CHANNEL_Z_SHIFT          20
+#define A1_SRC0_CHANNEL_W_NEGATE         (1<<19)
+#define A1_SRC0_CHANNEL_W_SHIFT          16
+#define A1_SRC1_TYPE_SHIFT               13
+#define A1_SRC1_NR_SHIFT                 8
+#define A1_SRC1_CHANNEL_X_NEGATE         (1<<7)
+#define A1_SRC1_CHANNEL_X_SHIFT          4
+#define A1_SRC1_CHANNEL_Y_NEGATE         (1<<3)
+#define A1_SRC1_CHANNEL_Y_SHIFT          0
+
+#define A2_SRC1_CHANNEL_Z_NEGATE         (1<<31)
+#define A2_SRC1_CHANNEL_Z_SHIFT          28
+#define A2_SRC1_CHANNEL_W_NEGATE         (1<<27)
+#define A2_SRC1_CHANNEL_W_SHIFT          24
+#define A2_SRC2_TYPE_SHIFT               21
+#define A2_SRC2_NR_SHIFT                 16
+#define A2_SRC2_CHANNEL_X_NEGATE         (1<<15)
+#define A2_SRC2_CHANNEL_X_SHIFT          12
+#define A2_SRC2_CHANNEL_Y_NEGATE         (1<<11)
+#define A2_SRC2_CHANNEL_Y_SHIFT          8
+#define A2_SRC2_CHANNEL_Z_NEGATE         (1<<7)
+#define A2_SRC2_CHANNEL_Z_SHIFT          4
+#define A2_SRC2_CHANNEL_W_NEGATE         (1<<3)
+#define A2_SRC2_CHANNEL_W_SHIFT          0
+
+
+
+/* Texture instructions */
+#define T0_TEXLD     (0x15<<24)	/* Sample texture using predeclared
+				 * sampler and address, and output
+				 * filtered texel data to destination
+				 * register */
+#define T0_TEXLDP    (0x16<<24)	/* Same as texld but performs a
+				 * perspective divide of the texture
+				 * coordinate .xyz values by .w before
+				 * sampling. */
+#define T0_TEXLDB    (0x17<<24)	/* Same as texld but biases the
+				 * computed LOD by w.  Only S4.6 two's
+				 * comp is used.  This implies that a
+				 * float to fixed conversion is
+				 * done. */
+#define T0_TEXKILL   (0x18<<24)	/* Does not perform a sampling
+				 * operation.  Simply kills the pixel
+				 * if any channel of the address
+				 * register is < 0.0. */
+#define T0_DEST_TYPE_SHIFT                19
+/* Allow: R, OC, OD, U */
+/* Note: U (unpreserved) regs do not retain their values between
+ * phases (cannot be used for feedback) 
+ *
+ * Note: oC and OD registers can only be used as the destination of a
+ * texture instruction once per phase (this is an implementation
+ * restriction). 
+ */
+#define T0_DEST_NR_SHIFT                 14
+/* Allow R: 0..15, OC,OD: 0..0, U: 0..2 */
+#define T0_SAMPLER_NR_SHIFT              0 /* This field ignored for TEXKILL */
+#define T0_SAMPLER_NR_MASK               (0xf<<0)
+
+#define T1_ADDRESS_REG_TYPE_SHIFT        24 /* Reg to use as texture coord */
+/* Allow R, T, OC, OD -- R, OC, OD are 'dependent' reads, new program phase */
+#define T1_ADDRESS_REG_NR_SHIFT          17
+#define T2_MBZ                           0
+
+/* Declaration instructions */
+#define D0_DCL       (0x19<<24)	/* Declare a t (interpolated attrib)
+				 * register or an s (sampler)
+				 * register. */
+#define D0_SAMPLE_TYPE_SHIFT              22
+#define D0_SAMPLE_TYPE_2D                 (0x0<<22)
+#define D0_SAMPLE_TYPE_CUBE               (0x1<<22)
+#define D0_SAMPLE_TYPE_VOLUME             (0x2<<22)
+#define D0_SAMPLE_TYPE_MASK               (0x3<<22)
+
+#define D0_TYPE_SHIFT                19
+/* Allow: T, S */
+#define D0_NR_SHIFT                  14
+/* Allow T: 0..10, S: 0..15 */
+#define D0_CHANNEL_X                (1<<10)
+#define D0_CHANNEL_Y                (2<<10)
+#define D0_CHANNEL_Z                (4<<10)
+#define D0_CHANNEL_W                (8<<10)
+#define D0_CHANNEL_ALL              (0xf<<10)
+#define D0_CHANNEL_NONE             (0<<10)
+
+#define D0_CHANNEL_XY               (D0_CHANNEL_X|D0_CHANNEL_Y)
+#define D0_CHANNEL_XYZ              (D0_CHANNEL_XY|D0_CHANNEL_Z)
+/* End description of STATE3D_PIXEL_SHADER_PROGRAM */
+
+#define STATE3D_DRAWING_RECTANGLE	(CMD_3D | (0x1d<<24)|(0x80<<16)|3)
+
+#define STATE3D_SCISSOR_RECTANGLE	(CMD_3D | (0x1d<<24)|(0x81<<16)|1)
+
+#define STATE3D_STIPPLE			(CMD_3D | (0x1d<<24)|(0x83<<16))
+#define ST1_ENABLE               (1<<16)
+#define ST1_MASK                 (0xffff)
+
+#define STATE3D_DEST_BUFFER_VARIABLES	(CMD_3D | (0x1d<<24)|(0x85<<16))
+#define TEX_DEFAULT_COLOR_OGL           (0<<30)
+#define TEX_DEFAULT_COLOR_D3D           (1<<30)
+#define ZR_EARLY_DEPTH                  (1<<29)
+#define LOD_PRECLAMP_OGL                (1<<28)
+#define LOD_PRECLAMP_D3D                (0<<28)
+#define DITHER_FULL_ALWAYS              (0<<26)
+#define DITHER_FULL_ON_FB_BLEND         (1<<26)
+#define DITHER_CLAMPED_ALWAYS           (2<<26)
+#define LINEAR_GAMMA_BLEND_32BPP        (1<<25)
+#define DEBUG_DISABLE_ENH_DITHER        (1<<24)
+#define DSTORG_HORIZ_BIAS(x)		((x)<<20)
+#define DSTORG_VERT_BIAS(x)		((x)<<16)
+#define COLOR_4_2_2_CHNL_WRT_ALL	0
+#define COLOR_4_2_2_CHNL_WRT_Y		(1<<12)
+#define COLOR_4_2_2_CHNL_WRT_CR		(2<<12)
+#define COLOR_4_2_2_CHNL_WRT_CB		(3<<12)
+#define COLOR_4_2_2_CHNL_WRT_CRCB	(4<<12)
+#define COLR_BUF_8BIT			0
+#define COLR_BUF_RGB555 		(1<<8)
+#define COLR_BUF_RGB565 		(2<<8)
+#define COLR_BUF_ARGB8888		(3<<8)
+#define DEPTH_FRMT_16_FIXED		0
+#define DEPTH_FRMT_16_FLOAT		(1<<2)
+#define DEPTH_FRMT_24_FIXED_8_OTHER	(2<<2)
+#define VERT_LINE_STRIDE_1		(1<<1)
+#define VERT_LINE_STRIDE_0		(0<<1)
+#define VERT_LINE_STRIDE_OFS_1		1
+#define VERT_LINE_STRIDE_OFS_0		0
+
+#define STATE3D_CONST_BLEND_COLOR	(CMD_3D | (0x1d<<24)|(0x88<<16))
+
 #define STATE3D_FOG_MODE		((3<<29)|(0x1d<<24)|(0x89<<16)|2)
 #define FOG_MODE_VERTEX 		(1<<31)
 #define STATE3D_MAP_COORD_TRANSFORM	((3<<29)|(0x1d<<24)|(0x8c<<16))
+
+#define STATE3D_BUFFER_INFO		(CMD_3D | (0x1d<<24)|(0x8e<<16)|1)
+#define BUFFERID_COLOR_BACK		(3 << 24)
+#define BUFFERID_COLOR_AUX		(4 << 24)
+#define BUFFERID_MC_INTRA_CORR		(5 << 24)
+#define BUFFERID_DEPTH			(7 << 24)
+#define BUFFER_USE_FENCES		(1 << 23)
+
+#define STATE3D_DFLT_Z_CMD		(CMD_3D | (0x1d<<24)|(0x98<<16))
+
+#define STATE3D_DFLT_DIFFUSE_CMD	(CMD_3D | (0x1d<<24)|(0x99<<16))
+
+#define STATE3D_DFLT_SPEC_CMD		(CMD_3D | (0x1d<<24)|(0x9a<<16))
+
+#define PRIMITIVE3D			(CMD_3D | (0x1f<<24))
+#define PRIM3D_INLINE		(0<<23)
+#define PRIM3D_INDIRECT		(1<<23)
+#define PRIM3D_TRILIST		(0x0<<18)
+#define PRIM3D_TRISTRIP 	(0x1<<18)
+#define PRIM3D_TRISTRIP_RVRSE	(0x2<<18)
+#define PRIM3D_TRIFAN		(0x3<<18)
+#define PRIM3D_POLY		(0x4<<18)
+#define PRIM3D_LINELIST 	(0x5<<18)
+#define PRIM3D_LINESTRIP	(0x6<<18)
+#define PRIM3D_RECTLIST 	(0x7<<18)
+#define PRIM3D_POINTLIST	(0x8<<18)
+#define PRIM3D_DIB		(0x9<<18)
+#define PRIM3D_CLEAR_RECT	(0xa<<18)
+#define PRIM3D_ZONE_INIT	(0xd<<18)
+#define PRIM3D_MASK		(0x1f<<18)
+
+
 #define DISABLE_TEX_TRANSFORM		(1<<28)
 #define TEXTURE_SET(x)			(x<<29)
-#define STATE3D_RASTERIZATION_RULES	((3<<29)|(0x07<<24))
-#define POINT_RASTER_ENABLE		(1<<15)
-#define POINT_RASTER_OGL		(1<<13)
+
 #define STATE3D_VERTEX_TRANSFORM	((3<<29)|(0x1d<<24)|(0x8b<<16))
 #define DISABLE_VIEWPORT_TRANSFORM	(1<<31)
 #define DISABLE_PERSPECTIVE_DIVIDE	(1<<29)
diff --git a/src/i830_rotate.c b/src/i830_rotate.c
index e4a8064..3b5ed25 100644
--- a/src/i830_rotate.c
+++ b/src/i830_rotate.c
@@ -214,6 +214,7 @@ I915UpdateRotate (ScreenPtr      pScreen
    drm_context_t myContext = 0;
 #endif
    Bool didLock = FALSE;
+   CARD32 format;
 
    if (I830IsPrimary(pScrn)) {
       pI8301 = pI830;
@@ -267,86 +268,127 @@ I915UpdateRotate (ScreenPtr      pScreen
       BEGIN_LP_RING(64);
       /* invarient state */
       OUT_RING(MI_NOOP);
-      OUT_RING(0x66014140);
-      OUT_RING(0x7d990000);
+      OUT_RING(STATE3D_ANTI_ALIASING |
+	       LINE_CAP_WIDTH_MODIFY | LINE_CAP_WIDTH_1_0 |
+	       LINE_WIDTH_MODIFY | LINE_WIDTH_1_0);
+
+      OUT_RING(STATE3D_DFLT_DIFFUSE_CMD);
       OUT_RING(0x00000000);
-      OUT_RING(0x7d9a0000);
+
+      OUT_RING(STATE3D_DFLT_SPEC_CMD);
       OUT_RING(0x00000000);
-      OUT_RING(0x7d980000);
+
+      OUT_RING(STATE3D_DFLT_Z_CMD);
       OUT_RING(0x00000000);
-      OUT_RING(0x76fac688);
-      OUT_RING(0x6700a770);
-      OUT_RING(0x7d040081);
+
+      OUT_RING(STATE3D_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(STATE3D_RASTERIZATION_RULES |
+	       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(STATE3D_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);
+      OUT_RING(STATE3D_DRAWING_RECTANGLE);
+      OUT_RING(0x00000000);	/* flags */
+      OUT_RING(0x00000000);	/* ymin, xmin */
+      OUT_RING((pScrn->virtualX - 1) | (pScrn->virtualY - 1) << 16); /* ymax, xmax */
+      OUT_RING(0x00000000);	/* yorigin, xorigin */
+      OUT_RING(MI_NOOP);
+
       /* scissor */
-      OUT_RING(0x7c800002);
-      OUT_RING(0x7d810001);
-      OUT_RING(0x00000000);
-      OUT_RING(0x00000000);
-      OUT_RING(0x7c000003);
+      OUT_RING(STATE3D_SCISSOR_ENABLE | DISABLE_SCISSOR_RECT);
+      OUT_RING(STATE3D_SCISSOR_RECTANGLE);
+      OUT_RING(0x00000000);	/* ymin, xmin */
+      OUT_RING(0x00000000);	/* ymax, xmax */
+
+      OUT_RING(0x7c000003);	/* unknown command */
       OUT_RING(0x7d070000);
       OUT_RING(0x00000000);
       OUT_RING(0x68000002);
+
       /* context setup */
-      OUT_RING(0x6db3ffff);
-      OUT_RING(0x7d040744);
+      OUT_RING(STATE3D_MODES_4 |
+	       ENABLE_LOGIC_OP_FUNC | LOGIC_OP_FUNC(LOGICOP_COPY) |
+	       ENABLE_STENCIL_WRITE_MASK | STENCIL_WRITE_MASK(0xff) |
+	       ENABLE_STENCIL_TEST_MASK | STENCIL_TEST_MASK(0xff));
+
+      OUT_RING(STATE3D_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) |
+	       I1_LOAD_S(4) | I1_LOAD_S(5) | I1_LOAD_S(6) | 4);
       OUT_RING(0xfffffff0);
       OUT_RING(0x00902c80);
       OUT_RING(0x00000000);
       OUT_RING(0x00020216);
-      OUT_RING(0x6ba008a1);
-      OUT_RING(0x7d880000);
+
+      OUT_RING(STATE3D_INDEPENDENT_ALPHA_BLEND |
+	       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(STATE3D_CONST_BLEND_COLOR);
       OUT_RING(0x00000000);
-      /* dv0 */
-      OUT_RING(0x7d850000);
-      /* dv1 */
+
+      OUT_RING(STATE3D_DEST_BUFFER_VARIABLES);
       if (pI830->cpp == 1)
-         OUT_RING(0x10880000);
+	 format = COLR_BUF_8BIT;
       else if (pI830->cpp == 2)
-            OUT_RING(0x10880200);
-         else
-            OUT_RING(0x10880308);
-      /* stipple */
-      OUT_RING(0x7d830000);
+	 format = COLR_BUF_RGB565;
+      else
+	 format = COLR_BUF_ARGB8888 | DEPTH_FRMT_24_FIXED_8_OTHER;
+
+      OUT_RING(LOD_PRECLAMP_OGL |
+	       DSTORG_HORIZ_BIAS(0x80) | DSTORG_VERT_BIAS(0x80) | format);
+
+      OUT_RING(STATE3D_STIPPLE);
       OUT_RING(0x00000000);
+
       /* fragment program - texture blend replace*/
-      OUT_RING(0x7d050008);
-      OUT_RING(0x19180000);
+      OUT_RING(STATE3D_PIXEL_SHADER_PROGRAM | 8);
+      OUT_RING(D0_DCL | (REG_TYPE_S << D0_TYPE_SHIFT) | (0 << D0_NR_SHIFT));
       OUT_RING(0x00000000);
       OUT_RING(0x00000000);
-      OUT_RING(0x19083c00);
+
+      OUT_RING(D0_DCL | (REG_TYPE_T << D0_TYPE_SHIFT) | (0 << D0_NR_SHIFT) |
+	       D0_CHANNEL_ALL);
       OUT_RING(0x00000000);
       OUT_RING(0x00000000);
-      OUT_RING(0x15200000);
-      OUT_RING(0x01000000);
+
+      OUT_RING(T0_TEXLD | (REG_TYPE_OC << T0_DEST_TYPE_SHIFT) |
+	       (0 << T0_SAMPLER_NR_SHIFT));
+      OUT_RING((REG_TYPE_T << T1_ADDRESS_REG_TYPE_SHIFT) |
+	       (0 << T1_ADDRESS_REG_NR_SHIFT));
       OUT_RING(0x00000000);
-      /* texture sampler state */
-      OUT_RING(0x7d010003);
+      /* End fragment program */
+
+      OUT_RING(STATE3D_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(STATE3D_BUFFER_INFO);
+      OUT_RING(BUFFERID_COLOR_BACK | BUFFER_USE_FENCES |
+          (((pI830->displayWidth * pI830->cpp) / 4) << 2));
       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(0x00000001);
+      OUT_RING(STATE3D_MAP_STATE);
+      OUT_RING(0x00000001);	/* texture map #1 */
 
       if (I830IsPrimary(pScrn)) 
          OUT_RING(pI830->RotatedMem.Start);
@@ -356,15 +398,15 @@ I915UpdateRotate (ScreenPtr      pScreen
       if (pI830->disableTiling)
          use_fence = 0;
       else
-         use_fence = 4;
+         use_fence = MS3_USE_FENCE_REGS;
       
       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 +437,7 @@ I915UpdateRotate (ScreenPtr      pScreen
       OUT_RING(MI_NOOP);
 
       /* vertex data */
-      OUT_RING(0x7f0c001f);
+      OUT_RING(PRIMITIVE3D | 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;
@@ -520,15 +562,15 @@ I830UpdateRotate (ScreenPtr      pScreen
       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);
+      OUT_RING(STATE3D_DRAWING_RECTANGLE);
+      OUT_RING(0x00000000);	/* flags */
+      OUT_RING(0x00000000);	/* ymin, xmin */
+      OUT_RING((pScrn->virtualX - 1) | (pScrn->virtualY - 1) << 16); /* ymax, xmax */
+      OUT_RING(0x00000000);	/* yorigin, xorigin */
+      OUT_RING(MI_NOOP);
 
       /* front buffer */
-      OUT_RING(0x7d8e0001);
+      OUT_RING(STATE3D_BUFFER_INFO);
       OUT_RING(0x03800000 | (((pI830->displayWidth * pI830->cpp) / 4) << 2));
       if (I830IsPrimary(pScrn))
 	 OUT_RING(pI830->FrontBuffer.Start);
diff-tree 4c727254da354cfd6f35148a334d046d67a50e99 (from a115c4b872a385530dcf94b7e7f2fa9b3b7e3155)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Fri May 12 16:26:58 2006 -0700

    Remove the local, renamed copy of lnx_agp.c.  The diff between lnx_agp.c and it
    appeared to be removal of bugfixes.

diff --git a/src/Makefile.am b/src/Makefile.am
index ad861e7..f1726f1 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -44,7 +44,6 @@ i810_drv_la_SOURCES = \
          i810_video.c \
          i810_wmark.c \
          i830_accel.c \
-         i830_agp.c \
          i830_common.h \
          i830_cursor.c \
          i830_dga.c \
diff --git a/src/i830.h b/src/i830.h
index 29506ea..cc26149 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -460,8 +460,6 @@ extern Bool I830DoPoolAllocation(ScrnInf
 extern Bool I830FixupOffsets(ScrnInfoPtr pScrn);
 extern Bool I830BindAGPMemory(ScrnInfoPtr pScrn);
 extern Bool I830UnbindAGPMemory(ScrnInfoPtr pScrn);
-extern Bool I830BindGARTMemory(int screenNum, int key, unsigned long offset);
-extern Bool I830UnbindGARTMemory(int screenNum, int key);
 extern unsigned long I830AllocVidMem(ScrnInfoPtr pScrn, I830MemRange *result,
 				     I830MemPool *pool, long size,
 				     unsigned long alignment, int flags);
@@ -482,20 +480,6 @@ extern int I830GetBestRefresh(ScrnInfoPt
 extern Bool I830CheckModeSupport(ScrnInfoPtr pScrn, int x, int y, int mode);
 extern Bool I830Rotate(ScrnInfoPtr pScrn, DisplayModePtr mode);
 extern Bool I830FixOffset(ScrnInfoPtr pScrn, I830MemRange *mem);
-
-/* AGP */
-extern Bool I830AgpGARTSupported(void);
-extern AgpInfoPtr I830GetAGPInfo(int screenNum);
-extern Bool I830AcquireGART(int screenNum);
-extern Bool I830ReleaseGART(int screenNum);
-extern int I830AllocateGARTMemory(int screenNum, unsigned long size, int type,
-				  unsigned long *physical);
-extern Bool I830DeallocateGARTMemory(int screenNum, int key);
-extern Bool I830BindGARTMemory(int screenNum, int key, unsigned long offset);
-extern Bool I830UnbindGARTMemory(int screenNum, int key);
-extern Bool I830EnableAGP(int screenNum, CARD32 mode);
-extern Bool I830GARTCloseScreen(int screenNum);
-
 /*
  * 12288 is set as the maximum, chosen because it is enough for
  * 1920x1440 at 32bpp with a 2048 pixel line pitch with some to spare.
diff --git a/src/i830_agp.c b/src/i830_agp.c
deleted file mode 100644
index aba5bcf..0000000
--- a/src/i830_agp.c
+++ /dev/null
@@ -1,366 +0,0 @@
-/*
- * Abstraction of the AGP GART interface.
- *
- * This version is for both Linux and FreeBSD.
- *
- * Copyright © 2000 VA Linux Systems, Inc.
- * Copyright © 2001 The XFree86 Project, Inc.
- */
-
-/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_agp.c,v 3.11 2003/04/03 22:47:42 dawes Exp $ */
-
-#if defined(linux)
-#include <sys/types.h>
-#include <linux/agpgart.h>
-#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <sys/agpio.h>
-#include <sys/errno.h>
-#include <sys/fcntl.h>
-#endif
-
-#include "xf86.h"
-#include "xf86_OSproc.h"
-#include "i830.h"
-
-
-#ifndef AGP_DEVICE
-#define AGP_DEVICE		"/dev/agpgart"
-#endif
-/* AGP page size is independent of the host page size. */
-#ifndef AGP_PAGE_SIZE
-#define AGP_PAGE_SIZE		4096
-#endif
-#define AGPGART_MAJOR_VERSION	0
-#define AGPGART_MINOR_VERSION	99
-
-static int gartFd = -1;
-static int acquiredScreen = -1;
-static Bool initDone = FALSE;
-/*
- * Close /dev/agpgart.  This frees all associated memory allocated during
- * this server generation.
- */
-Bool
-I830GARTCloseScreen(int screenNum)
-{
-	if(gartFd != -1) {
-		close(gartFd);
-		acquiredScreen = -1;
-		gartFd = -1;
-		initDone = FALSE;
-	}
-	return TRUE;
-}
-
-/*
- * Open /dev/agpgart.  Keep it open until I830GARTCloseScreen is called.
- */
-static Bool
-GARTInit(int screenNum)
-{
-	struct _agp_info agpinf;
-
-	if (initDone)
-		return (gartFd != -1);
-
-	initDone = TRUE;
-
-	if (gartFd == -1)
-		gartFd = open(AGP_DEVICE, O_RDWR, 0);
-	else
-		return FALSE;
-
-	if (gartFd == -1) {
-	    xf86DrvMsg(screenNum, X_ERROR,
-		"I830GARTInit: Unable to open " AGP_DEVICE " (%s)\n",
-		strerror(errno));
-	    return FALSE;
-	}
-
-	I830AcquireGART(-1);
-	/* Check the kernel driver version. */
-	if (ioctl(gartFd, AGPIOC_INFO, &agpinf) != 0) {
-		xf86DrvMsg(screenNum, X_ERROR,
-			"I830GARTInit: AGPIOC_INFO failed (%s)\n", strerror(errno));
-		close(gartFd);
-		gartFd = -1;
-		return FALSE;
-	}
-	I830ReleaseGART(-1);
-
-#if defined(linux)
-	/* Per Dave Jones, every effort will be made to keep the 
-	 * agpgart interface backwards compatible, so allow all 
-	 * future versions.
-	 */
-	if (
-#if (AGPGART_MAJOR_VERSION > 0) /* quiet compiler */
-	    agpinf.version.major < AGPGART_MAJOR_VERSION ||
-#endif
-	    (agpinf.version.major == AGPGART_MAJOR_VERSION &&
-	     agpinf.version.minor < AGPGART_MINOR_VERSION)) {
-		xf86DrvMsg(screenNum, X_ERROR,
-			"GARTInit: Kernel agpgart driver version is not current"
-			" (%d.%d vs %d.%d)\n",
-			agpinf.version.major, agpinf.version.minor,
-			AGPGART_MAJOR_VERSION, AGPGART_MINOR_VERSION);
-		close(gartFd);
-		gartFd = -1;
-		return FALSE;
-	}
-#endif
-	
-	return TRUE;
-}
-
-Bool
-I830AgpGARTSupported()
-{
-	return GARTInit(-1);
-}
-
-AgpInfoPtr
-I830GetAGPInfo(int screenNum)
-{
-	struct _agp_info agpinf;
-	AgpInfoPtr info;
-
-	if (!GARTInit(screenNum))
-		return NULL;
-
-
-	if ((info = xcalloc(sizeof(AgpInfo), 1)) == NULL) {
-		xf86DrvMsg(screenNum, X_ERROR,
-			   "I830GetAGPInfo: Failed to allocate AgpInfo\n");
-		return NULL;
-	}
-
-	if (ioctl(gartFd, AGPIOC_INFO, &agpinf) != 0) {
-		xf86DrvMsg(screenNum, X_ERROR,
-			   "I830GetAGPInfo: AGPIOC_INFO failed (%s)\n",
-			   strerror(errno));
-		return NULL;
-	}
-
-	info->bridgeId = agpinf.bridge_id;
-	info->agpMode = agpinf.agp_mode;
-	info->base = agpinf.aper_base;
-	info->size = agpinf.aper_size;
-	info->totalPages = agpinf.pg_total;
-	info->systemPages = agpinf.pg_system;
-	info->usedPages = agpinf.pg_used;
-
-	return info;
-}
-
-/*
- * XXX If multiple screens can acquire the GART, should we have a reference
- * count instead of using acquiredScreen?
- */
-
-Bool
-I830AcquireGART(int screenNum)
-{
-	if (screenNum != -1 && !GARTInit(screenNum))
-		return FALSE;
-
-	if (screenNum == -1 || acquiredScreen != screenNum) {
-		if (ioctl(gartFd, AGPIOC_ACQUIRE, 0) != 0) {
-			xf86DrvMsg(screenNum, X_WARNING,
-				"I830AcquireGART: AGPIOC_ACQUIRE failed (%s)\n",
-				strerror(errno));
-			return FALSE;
-		}
-		acquiredScreen = screenNum;
-	}
-	return TRUE;
-}
-
-Bool
-I830ReleaseGART(int screenNum)
-{
-	if (screenNum != -1 && !GARTInit(screenNum))
-		return FALSE;
-
-	if (acquiredScreen == screenNum) {
-		/*
-		 * The FreeBSD agp driver removes allocations on release.
-		 * The Linux driver doesn't.  I830ReleaseGART() is expected
-		 * to give up access to the GART, but not to remove any
-		 * allocations.
-		 */
-#if !defined(linux)
-	    if (screenNum == -1)
-#endif
-	    {
-		if (ioctl(gartFd, AGPIOC_RELEASE, 0) != 0) {
-			xf86DrvMsg(screenNum, X_WARNING,
-				"I830ReleaseGART: AGPIOC_RELEASE failed (%s)\n",
-				strerror(errno));
-			return FALSE;
-		}
-		acquiredScreen = -1;
-	    }
-	    return TRUE;
-	}
-	return FALSE;
-}
-
-int
-I830AllocateGARTMemory(int screenNum, unsigned long size, int type,
-			unsigned long *physical)
-{
-	struct _agp_allocate alloc;
-	int pages;
-
-	/*
-	 * Allocates "size" bytes of GART memory (rounds up to the next
-	 * page multiple) or type "type".  A handle (key) for the allocated
-	 * memory is returned.  On error, the return value is -1.
-	 */
-
-	if (!GARTInit(screenNum) || acquiredScreen != screenNum)
-		return -1;
-
-	pages = (size / AGP_PAGE_SIZE);
-	if (size % AGP_PAGE_SIZE != 0)
-		pages++;
-
-	/* XXX check for pages == 0? */
-
-	alloc.pg_count = pages;
-	alloc.type = type;
-
-	if (ioctl(gartFd, AGPIOC_ALLOCATE, &alloc) != 0) {
-		if (type != 3)
-		   xf86DrvMsg(screenNum, X_WARNING, "I830AllocateGARTMemory: "
-			   "allocation of %d pages failed\n\t(%s)\n", pages,
-			   strerror(errno));
-		return -1;
-	}
-
-	if (physical)
-		*physical = alloc.physical;
-
-	return alloc.key;
-}
-
-Bool
-I830DeallocateGARTMemory(int screenNum, int key)
-{
-	if (!GARTInit(screenNum) || acquiredScreen != screenNum)
-		return FALSE;
-
-	if (acquiredScreen != screenNum) {
-		xf86DrvMsg(screenNum, X_ERROR,
-                   "xf86UnbindGARTMemory: AGP not acquired by this screen\n");
-		return FALSE;
-	}
-
-	if (ioctl(gartFd, AGPIOC_DEALLOCATE, (int *)key) != 0) {
-		xf86DrvMsg(screenNum, X_WARNING,"I830DeAllocateGARTMemory: "
-                   "deallocation gart memory with key %d failed\n\t(%s)\n",
-                   key, strerror(errno));
-		return FALSE;
-	}
-
-	return TRUE;
-}
-
-/* Bind GART memory with "key" at "offset" */
-Bool
-I830BindGARTMemory(int screenNum, int key, unsigned long offset)
-{
-	struct _agp_bind bind;
-	int pageOffset;
-
-	if (!GARTInit(screenNum) || acquiredScreen != screenNum)
-		return FALSE;
-
-	if (acquiredScreen != screenNum) {
-		xf86DrvMsg(screenNum, X_ERROR,
-		      "I830BindGARTMemory: AGP not acquired by this screen\n");
-		return FALSE;
-	}
-
-	if (offset % AGP_PAGE_SIZE != 0) {
-		xf86DrvMsg(screenNum, X_WARNING, "I830BindGARTMemory: "
-			   "offset (0x%lx) is not page-aligned (%d)\n",
-			   offset, AGP_PAGE_SIZE);
-		return FALSE;
-	}
-	pageOffset = offset / AGP_PAGE_SIZE;
-
-	xf86DrvMsgVerb(screenNum, X_INFO, 3,
-		       "I830BindGARTMemory: bind key %d at 0x%08lx "
-		       "(pgoffset %d)\n", key, offset, pageOffset);
-
-	bind.pg_start = pageOffset;
-	bind.key = key;
-
-	if (ioctl(gartFd, AGPIOC_BIND, &bind) != 0) {
-		xf86DrvMsg(screenNum, X_WARNING, "I830BindGARTMemory: "
-			   "binding of gart memory with key %d\n"
-			   "\tat offset 0x%lx failed (%s)\n",
-			   key, offset, strerror(errno));
-		return FALSE;
-	}
-
-	return TRUE;
-}
-
-
-/* Unbind GART memory with "key" */
-Bool
-I830UnbindGARTMemory(int screenNum, int key)
-{
-	struct _agp_unbind unbind;
-
-	if (!GARTInit(screenNum) || acquiredScreen != screenNum)
-		return FALSE;
-
-	if (acquiredScreen != screenNum) {
-		xf86DrvMsg(screenNum, X_ERROR,
-		    "I830UnbindGARTMemory: AGP not acquired by this screen\n");
-		return FALSE;
-	}
-
-	unbind.priority = 0;
-	unbind.key = key;
-
-	if (ioctl(gartFd, AGPIOC_UNBIND, &unbind) != 0) {
-		xf86DrvMsg(screenNum, X_WARNING, "I830UnbindGARTMemory: "
-			   "unbinding of gart memory with key %d "
-			   "failed (%s)\n", key, strerror(errno));
-		return FALSE;
-	}
-
-	xf86DrvMsgVerb(screenNum, X_INFO, 3,
-		       "I830UnbindGARTMemory: unbind key %d\n", key);
-
-	return TRUE;
-}
-
-
-/* XXX Interface may change. */
-Bool
-I830EnableAGP(int screenNum, CARD32 mode)
-{
-	agp_setup setup;
-
-	if (!GARTInit(screenNum) || acquiredScreen != screenNum)
-		return FALSE;
-
-	setup.agp_mode = mode;
-	if (ioctl(gartFd, AGPIOC_SETUP, &setup) != 0) {
-		xf86DrvMsg(screenNum, X_WARNING, "I830EnableAGP: "
-			   "AGPIOC_SETUP with mode %ld failed (%s)\n",
-			   (unsigned long)mode, strerror(errno));
-		return FALSE;
-	}
-
-	return TRUE;
-}
-
diff --git a/src/i830_driver.c b/src/i830_driver.c
index d36ff3e..1e1e02d 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -6090,7 +6090,7 @@ I830BIOSCloseScreen(int scrnIndex, Scree
    }
 
    if (I830IsPrimary(pScrn)) {
-      I830GARTCloseScreen(scrnIndex);
+      xf86GARTCloseScreen(scrnIndex);
 
       xfree(pI830->LpRing);
       pI830->LpRing = NULL;
diff --git a/src/i830_memory.c b/src/i830_memory.c
index e5c9215..accc0a7 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -210,15 +210,15 @@ AllocFromAGP(ScrnInfoPtr pScrn, I830MemR
 	 return 0;
 
       if (flags & NEED_PHYSICAL_ADDR) {
-	 result->Key = I830AllocateGARTMemory(pScrn->scrnIndex, size, 2,
+	 result->Key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 2,
 					      &(result->Physical));
       } else {
          /* Due to a bug in agpgart in 2.6 kernels resulting in very poor
 	  * allocation performance we need to workaround it here...
 	  */
-	 result->Key = I830AllocateGARTMemory(pScrn->scrnIndex, size, 3, NULL);
+	 result->Key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 3, NULL);
          if (result->Key == -1)
-	    result->Key = I830AllocateGARTMemory(pScrn->scrnIndex, size, 0, NULL);
+	    result->Key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 0, NULL);
       }
       if (result->Key == -1)
 	 return 0;
@@ -248,7 +248,7 @@ I830FreeVidMem(ScrnInfoPtr pScrn, I830Me
       return;
 
    if (range->Key != -1)
-      I830DeallocateGARTMemory(pScrn->scrnIndex, range->Key);
+      xf86DeallocateGARTMemory(pScrn->scrnIndex, range->Key);
 
    if (range->Pool) {
       /* 
@@ -635,7 +635,7 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, 
 	   BOOLTOSTRING(flags & ALLOC_INITIAL));
 
    if (!pI830->StolenOnly &&
-       (!I830AgpGARTSupported() || !I830AcquireGART(pScrn->scrnIndex))) {
+       (!xf86AgpGARTSupported() || !xf86AcquireGART(pScrn->scrnIndex))) {
       if (!dryrun) {
 	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 		    "AGP GART support is either not available or cannot "
@@ -977,9 +977,9 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, 
        * allocation performance we need to workaround it here...
        */
       pI830->Dummy.Key = 
-           I830AllocateGARTMemory(pScrn->scrnIndex, size, 3, NULL);
+           xf86AllocateGARTMemory(pScrn->scrnIndex, size, 3, NULL);
       if (pI830->Dummy.Key == -1)
-         pI830->Dummy.Key = I830AllocateGARTMemory(pScrn->scrnIndex, size, 0, NULL);
+         pI830->Dummy.Key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 0, NULL);
       pI830->Dummy.Offset = 0;
    }
 #endif
@@ -1403,10 +1403,10 @@ I830DoPoolAllocation(ScrnInfoPtr pScrn, 
        * allocation performance we need to workaround it here...
        */
       pool->Allocated.Key = 
-           I830AllocateGARTMemory(pScrn->scrnIndex, pool->Allocated.Size,
+           xf86AllocateGARTMemory(pScrn->scrnIndex, pool->Allocated.Size,
 				   3, NULL);
       if (pool->Allocated.Key == -1)
-         pool->Allocated.Key = I830AllocateGARTMemory(pScrn->scrnIndex, 
+         pool->Allocated.Key = xf86AllocateGARTMemory(pScrn->scrnIndex, 
 				   pool->Allocated.Size, 0, NULL);
       if (pool->Allocated.Key == -1) {
 	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Pool allocation failed\n");
@@ -1865,7 +1865,7 @@ BindMemRange(ScrnInfoPtr pScrn, I830MemR
    if (mem->Key == -1)
       return TRUE;
 
-   return I830BindGARTMemory(pScrn->scrnIndex, mem->Key, mem->Offset);
+   return xf86BindGARTMemory(pScrn->scrnIndex, mem->Key, mem->Offset);
 }
 
 Bool
@@ -1880,8 +1880,8 @@ I830BindAGPMemory(ScrnInfoPtr pScrn)
    if (pI830->StolenOnly == TRUE)
       return TRUE;
 
-   if (I830AgpGARTSupported() && !pI830->GttBound) {
-      if (!I830AcquireGART(pScrn->scrnIndex))
+   if (xf86AgpGARTSupported() && !pI830->GttBound) {
+      if (!xf86AcquireGART(pScrn->scrnIndex))
 	 return FALSE;
 
 #if REMAP_RESERVED
@@ -1950,7 +1950,7 @@ UnbindMemRange(ScrnInfoPtr pScrn, I830Me
    if (mem->Key == -1)
       return TRUE;
 
-   return I830UnbindGARTMemory(pScrn->scrnIndex, mem->Key);
+   return xf86UnbindGARTMemory(pScrn->scrnIndex, mem->Key);
 }
 
 
@@ -1966,7 +1966,7 @@ I830UnbindAGPMemory(ScrnInfoPtr pScrn)
    if (pI830->StolenOnly == TRUE)
       return TRUE;
 
-   if (I830AgpGARTSupported() && pI830->GttBound) {
+   if (xf86AgpGARTSupported() && pI830->GttBound) {
 
 #if REMAP_RESERVED
       /* "unbind" the pre-allocated region. */
@@ -2019,7 +2019,7 @@ I830UnbindAGPMemory(ScrnInfoPtr pScrn)
 	    return FALSE;
       }
 #endif
-      if (!I830ReleaseGART(pScrn->scrnIndex))
+      if (!xf86ReleaseGART(pScrn->scrnIndex))
 	 return FALSE;
 
       pI830->GttBound = 0;
@@ -2034,10 +2034,10 @@ I830CheckAvailableMemory(ScrnInfoPtr pSc
    AgpInfoPtr agpinf;
    int maxPages;
 
-   if (!I830AgpGARTSupported() ||
-       !I830AcquireGART(pScrn->scrnIndex) ||
-       (agpinf = I830GetAGPInfo(pScrn->scrnIndex)) == NULL ||
-       !I830ReleaseGART(pScrn->scrnIndex))
+   if (!xf86AgpGARTSupported() ||
+       !xf86AcquireGART(pScrn->scrnIndex) ||
+       (agpinf = xf86GetAGPInfo(pScrn->scrnIndex)) == NULL ||
+       !xf86ReleaseGART(pScrn->scrnIndex))
       return -1;
 
    maxPages = agpinf->totalPages - agpinf->usedPages;
diff --git a/src/i830_rotate.c b/src/i830_rotate.c
index d0d9cf2..82b2c5d 100644
--- a/src/i830_rotate.c
+++ b/src/i830_rotate.c
@@ -737,17 +737,17 @@ I830Rotate(ScrnInfoPtr pScrn, DisplayMod
       
       
       if (pI8301->TexMem.Key != -1)
-         I830UnbindGARTMemory(pScrn1->scrnIndex, pI8301->TexMem.Key);
+         xf86UnbindGARTMemory(pScrn1->scrnIndex, pI8301->TexMem.Key);
       I830FreeVidMem(pScrn1, &(pI8301->TexMem));
       if (pI8301->StolenPool.Allocated.Key != -1) {
-         I830UnbindGARTMemory(pScrn1->scrnIndex, pI8301->StolenPool.Allocated.Key);
-         I830DeallocateGARTMemory(pScrn1->scrnIndex, pI8301->StolenPool.Allocated.Key);
+         xf86UnbindGARTMemory(pScrn1->scrnIndex, pI8301->StolenPool.Allocated.Key);
+         xf86DeallocateGARTMemory(pScrn1->scrnIndex, pI8301->StolenPool.Allocated.Key);
       }
       if (pI8301->DepthBuffer.Key != -1)
-         I830UnbindGARTMemory(pScrn1->scrnIndex, pI8301->DepthBuffer.Key);
+         xf86UnbindGARTMemory(pScrn1->scrnIndex, pI8301->DepthBuffer.Key);
       I830FreeVidMem(pScrn1, &(pI8301->DepthBuffer));
       if (pI8301->BackBuffer.Key != -1)
-         I830UnbindGARTMemory(pScrn1->scrnIndex, pI8301->BackBuffer.Key);
+         xf86UnbindGARTMemory(pScrn1->scrnIndex, pI8301->BackBuffer.Key);
       I830FreeVidMem(pScrn1, &(pI8301->BackBuffer));
    }
 #endif
@@ -756,7 +756,7 @@ I830Rotate(ScrnInfoPtr pScrn, DisplayMod
       *pI830->used3D |= 1<<31; /* use high bit to denote new rotation occured */
 
       if (pI8301->RotatedMem.Key != -1)
-         I830UnbindGARTMemory(pScrn1->scrnIndex, pI8301->RotatedMem.Key);
+         xf86UnbindGARTMemory(pScrn1->scrnIndex, pI8301->RotatedMem.Key);
  
       I830FreeVidMem(pScrn1, &(pI8301->RotatedMem));
       memset(&(pI8301->RotatedMem), 0, sizeof(pI8301->RotatedMem));
@@ -764,7 +764,7 @@ I830Rotate(ScrnInfoPtr pScrn, DisplayMod
 
       if (pI830->entityPrivate) {
          if (pI8301->RotatedMem2.Key != -1)
-            I830UnbindGARTMemory(pScrn1->scrnIndex, pI8301->RotatedMem2.Key);
+            xf86UnbindGARTMemory(pScrn1->scrnIndex, pI8301->RotatedMem2.Key);
  
          I830FreeVidMem(pScrn1, &(pI8301->RotatedMem2));
          memset(&(pI8301->RotatedMem2), 0, sizeof(pI8301->RotatedMem2));
@@ -832,7 +832,7 @@ I830Rotate(ScrnInfoPtr pScrn, DisplayMod
 
             I830FixOffset(pScrn1, &(pI8301->RotatedMem2));
             if (pI8301->RotatedMem2.Key != -1)
-               I830BindGARTMemory(pScrn1->scrnIndex, pI8301->RotatedMem2.Key, pI8301->RotatedMem2.Offset);
+               xf86BindGARTMemory(pScrn1->scrnIndex, pI8301->RotatedMem2.Key, pI8301->RotatedMem2.Offset);
          }
       }
 
@@ -843,7 +843,7 @@ I830Rotate(ScrnInfoPtr pScrn, DisplayMod
 
          I830FixOffset(pScrn1, &(pI8301->RotatedMem));
          if (pI8301->RotatedMem.Key != -1)
-            I830BindGARTMemory(pScrn1->scrnIndex, pI8301->RotatedMem.Key, pI8301->RotatedMem.Offset);
+            xf86BindGARTMemory(pScrn1->scrnIndex, pI8301->RotatedMem.Key, pI8301->RotatedMem.Offset);
       }
    }
    
@@ -898,13 +898,13 @@ I830Rotate(ScrnInfoPtr pScrn, DisplayMod
       I830FixOffset(pScrn1, &(pI8301->DepthBuffer));
 
       if (pI8301->BackBuffer.Key != -1)
-         I830BindGARTMemory(pScrn1->scrnIndex, pI8301->BackBuffer.Key, pI8301->BackBuffer.Offset);
+         xf86BindGARTMemory(pScrn1->scrnIndex, pI8301->BackBuffer.Key, pI8301->BackBuffer.Offset);
       if (pI8301->DepthBuffer.Key != -1)
-         I830BindGARTMemory(pScrn1->scrnIndex, pI8301->DepthBuffer.Key, pI8301->DepthBuffer.Offset);
+         xf86BindGARTMemory(pScrn1->scrnIndex, pI8301->DepthBuffer.Key, pI8301->DepthBuffer.Offset);
       if (pI8301->StolenPool.Allocated.Key != -1)
-         I830BindGARTMemory(pScrn1->scrnIndex, pI8301->StolenPool.Allocated.Key, pI8301->StolenPool.Allocated.Offset);
+         xf86BindGARTMemory(pScrn1->scrnIndex, pI8301->StolenPool.Allocated.Key, pI8301->StolenPool.Allocated.Offset);
       if (pI8301->TexMem.Key != -1)
-         I830BindGARTMemory(pScrn1->scrnIndex, pI8301->TexMem.Key, pI8301->TexMem.Offset);
+         xf86BindGARTMemory(pScrn1->scrnIndex, pI8301->TexMem.Key, pI8301->TexMem.Offset);
       I830SetupMemoryTiling(pScrn1);
       /* update fence registers */
       for (i = 0; i < 8; i++) 
@@ -992,7 +992,7 @@ BAIL3:
 BAIL2:
    if (pI8301->rotation != RR_Rotate_0) {
       if (pI8301->RotatedMem.Key != -1)
-         I830UnbindGARTMemory(pScrn1->scrnIndex, pI8301->RotatedMem.Key);
+         xf86UnbindGARTMemory(pScrn1->scrnIndex, pI8301->RotatedMem.Key);
   
       I830FreeVidMem(pScrn1, &(pI8301->RotatedMem));
       memset(&(pI8301->RotatedMem), 0, sizeof(pI8301->RotatedMem));
@@ -1002,7 +1002,7 @@ BAIL1:
    if (pI830->entityPrivate) {
       if (pI8302->rotation != RR_Rotate_0) {
          if (pI8301->RotatedMem.Key != -1)
-            I830UnbindGARTMemory(pScrn1->scrnIndex, pI8301->RotatedMem.Key);
+            xf86UnbindGARTMemory(pScrn1->scrnIndex, pI8301->RotatedMem.Key);
 
          I830FreeVidMem(pScrn1, &(pI8301->RotatedMem));
          memset(&(pI8301->RotatedMem), 0, sizeof(pI8301->RotatedMem));
@@ -1041,7 +1041,7 @@ BAIL0:
 
          I830FixOffset(pScrn1, &(pI8301->RotatedMem2));
          if (pI8301->RotatedMem2.Key != -1)
-            I830BindGARTMemory(pScrn1->scrnIndex, pI8301->RotatedMem2.Key, pI8301->RotatedMem2.Offset);
+            xf86BindGARTMemory(pScrn1->scrnIndex, pI8301->RotatedMem2.Key, pI8301->RotatedMem2.Offset);
       }
    }
 
@@ -1053,7 +1053,7 @@ BAIL0:
 
       I830FixOffset(pScrn1, &(pI8301->RotatedMem));
       if (pI8301->RotatedMem.Key != -1)
-         I830BindGARTMemory(pScrn1->scrnIndex, pI8301->RotatedMem.Key, pI8301->RotatedMem.Offset);
+         xf86BindGARTMemory(pScrn1->scrnIndex, pI8301->RotatedMem.Key, pI8301->RotatedMem.Offset);
    }
 
    shadowRemove (pScrn->pScreen, NULL);
@@ -1132,13 +1132,13 @@ BAIL0:
       I830FixOffset(pScrn1, &(pI8301->DepthBuffer));
 
       if (pI8301->BackBuffer.Key != -1)
-         I830BindGARTMemory(pScrn1->scrnIndex, pI8301->BackBuffer.Key, pI8301->BackBuffer.Offset);
+         xf86BindGARTMemory(pScrn1->scrnIndex, pI8301->BackBuffer.Key, pI8301->BackBuffer.Offset);
       if (pI8301->DepthBuffer.Key != -1)
-         I830BindGARTMemory(pScrn1->scrnIndex, pI8301->DepthBuffer.Key, pI8301->DepthBuffer.Offset);
+         xf86BindGARTMemory(pScrn1->scrnIndex, pI8301->DepthBuffer.Key, pI8301->DepthBuffer.Offset);
       if (pI8301->StolenPool.Allocated.Key != -1)
-         I830BindGARTMemory(pScrn1->scrnIndex, pI8301->StolenPool.Allocated.Key, pI8301->StolenPool.Allocated.Offset);
+         xf86BindGARTMemory(pScrn1->scrnIndex, pI8301->StolenPool.Allocated.Key, pI8301->StolenPool.Allocated.Offset);
       if (pI8301->TexMem.Key != -1)
-         I830BindGARTMemory(pScrn1->scrnIndex, pI8301->TexMem.Key, pI8301->TexMem.Offset);
+         xf86BindGARTMemory(pScrn1->scrnIndex, pI8301->TexMem.Key, pI8301->TexMem.Offset);
       I830SetupMemoryTiling(pScrn1);
       /* update fence registers */
       for (i = 0; i < 8; i++) 
diff-tree a115c4b872a385530dcf94b7e7f2fa9b3b7e3155 (from 0cb251fadca1cbb3d4c5b97982cd0d8c2fc3e840)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Fri May 12 16:11:29 2006 -0700

    Remove the code that changes our behavior based on whether a magic file exists
    with magic contents in /tmp (created by some install script).

diff --git a/src/i830_driver.c b/src/i830_driver.c
index ca76a68..d36ff3e 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -3112,47 +3112,6 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int f
 
    SetPipeAccess(pScrn);
 
-   /* 
-    * Using the installation script we need to find out if we've just been
-    * installed, and if so, default to the native panel resolutions, otherwise
-    * we'll default to whatever existed or the default monitor settings
-    * that's inbuilt into the Xserver.
-    */
-   {
-	FILE *f;
-   	if ((f = fopen("/tmp/.newinstallation", "r"))) {
-		char data[2];
-		fgets(data, 2, f);
-		if (data[0] == 48) { /* First time */
-			/* Ignore our monitors horizsync and vertrefresh 
-	 		 * settings when we've detected a new installation 
-			 * and we're on a flat panel, therefore we should
-	 		 * start with the native panels resolution 
-	 		 */
-#if 0
-   			if ((pI830->pipe == 1) && 
-			    (pI830->operatingDevices & (PIPE_LFP << 8))) {
-#else
-			/* Changed this to only work on LFP only systems
-			 * as the other devices may not support the LFP's
-			 * resolution.
-			 */
-   			if ((pI830->pipe == 1) && 
-			    (pI830->operatingDevices == (PIPE_LFP << 8))) {
-#endif
-   	    			pScrn->monitor->nHsync = 0;
-   	    			pScrn->monitor->nVrefresh = 0;
-   				xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-	      				"Detected new installation of driver, defaulting to LFP panel size.\n");
-			}
-		}
-		fclose(f);
-		f = fopen("/tmp/.newinstallation", "w");
-		fputc(49, f);
-		fclose(f);
-   	}
-   }
-
    /* Check we have an LFP connected, before trying to
     * read PanelID information. */
    if ( (pI830->pipe == 1 && pI830->operatingDevices & (PIPE_LFP << 8)) ||
diff-tree 0cb251fadca1cbb3d4c5b97982cd0d8c2fc3e840 (from 78b95386b630039864b31954ebcd02ec8829b0c8)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Fri May 12 16:10:02 2006 -0700

    Do a couple of reverts to get the DRI code building.  At this point, the whole
    driver builds.

diff --git a/src/i830_dri.c b/src/i830_dri.c
index b82eae6..2eacc5b 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -444,12 +444,13 @@ I830CheckDRIAvailable(ScrnInfoPtr pScrn)
       int major, minor, patch;
 
       DRIQueryVersion(&major, &minor, &patch);
-      if (major != 4 || minor < 0) {
+      if (major != DRIINFO_MAJOR_VERSION || minor < DRIINFO_MINOR_VERSION) {
 	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 		    "[dri] %s failed because of a version mismatch.\n"
-		    "[dri] libDRI version is %d.%d.%d but version 4.0.x is needed.\n"
+		    "[dri] libDRI version is %d.%d.%d but version %d.%d.x is needed.\n"
 		    "[dri] Disabling DRI.\n",
-		    "I830CheckDRIAvailable", major, minor, patch);
+		    "I830CheckDRIAvailable", major, minor, patch,
+		     DRIINFO_MAJOR_VERSION, DRIINFO_MINOR_VERSION);
 	 return FALSE;
       }
    }
@@ -495,10 +496,10 @@ I830DRIScreenInit(ScreenPtr pScreen)
 	      ((pciConfigPtr) pI830->PciInfo->thisCard)->devnum,
 	      ((pciConfigPtr) pI830->PciInfo->thisCard)->funcnum);
    }
-   pDRIInfo->ddxDriverMajorVersion = INTEL_MAJOR_VERSION;
-   pDRIInfo->ddxDriverMinorVersion = INTEL_MINOR_VERSION;
-   pDRIInfo->ddxDriverPatchVersion = INTEL_PATCHLEVEL;
-   pDRIInfo->frameBufferPhysicalAddress = pI830->LinearAddr +
+   pDRIInfo->ddxDriverMajorVersion = I830_MAJOR_VERSION;
+   pDRIInfo->ddxDriverMinorVersion = I830_MINOR_VERSION;
+   pDRIInfo->ddxDriverPatchVersion = I830_PATCHLEVEL;
+   pDRIInfo->frameBufferPhysicalAddress = (pointer) pI830->LinearAddr +
 					  pI830->FrontBuffer.Start;
 #if 0
    pDRIInfo->frameBufferSize = ROUND_TO_PAGE(pScrn->displayWidth *
@@ -542,8 +543,6 @@ I830DRIScreenInit(ScreenPtr pScreen)
    pDRIInfo->InitBuffers = I830DRIInitBuffers;
    pDRIInfo->MoveBuffers = I830DRIMoveBuffers;
    pDRIInfo->bufferRequests = DRI_ALL_WINDOWS;
-   pDRIInfo->OpenFullScreen = I830DRIOpenFullScreen;
-   pDRIInfo->CloseFullScreen = I830DRICloseFullScreen;
    pDRIInfo->TransitionTo2d = I830DRITransitionTo2d;
    pDRIInfo->TransitionTo3d = I830DRITransitionTo3d;
    pDRIInfo->TransitionSingleToMulti3D = I830DRITransitionSingleToMulti3d;
diff --git a/src/i830_dri.h b/src/i830_dri.h
index 281013b..66e9525 100644
--- a/src/i830_dri.h
+++ b/src/i830_dri.h
@@ -9,6 +9,10 @@
 
 #define I830_MAX_DRAWABLES 256
 
+#define I830_MAJOR_VERSION 1
+#define I830_MINOR_VERSION 5
+#define I830_PATCHLEVEL 1
+
 #define I830_REG_SIZE 0x80000
 
 typedef struct _I830DRIRec {
diff-tree 78b95386b630039864b31954ebcd02ec8829b0c8 (from 2e58aa401dfbab438752038a9034df571c8f8bde)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Fri May 12 16:09:40 2006 -0700

    Remove intel_randr.c and stick with the previous code.  Broadwater shouldn't be
    changing our randr, and the new version didn't compile.

diff --git a/src/Makefile.am b/src/Makefile.am
index 1680123..ad861e7 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -56,7 +56,6 @@ i810_drv_la_SOURCES = \
          i830_video.c \
          i830_rotate.c \
 	 i830_randr.c \
-	 intel_randr.c \
 	 intel_acpi.c
 
 if DRI
diff --git a/src/intel_randr.c b/src/intel_randr.c
deleted file mode 100644
index 950a122..0000000
--- a/src/intel_randr.c
+++ /dev/null
@@ -1,424 +0,0 @@
-/* $XdotOrg: xc/programs/Xserver/hw/xfree86/common/xf86RandR.c,v 1.3 2004/07/30 21:53:09 eich Exp $ */
-/*
- * $XFree86: xc/programs/Xserver/hw/xfree86/common/xf86RandR.c,v 1.7tsi Exp $
- *
- * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission.  Keith Packard makes no
- * representations about the suitability of this software for any purpose.  It
- * is provided "as is" without express or implied warranty.
- *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include "X.h"
-#include "os.h"
-#include "mibank.h"
-#include "globals.h"
-#include "xf86.h"
-#include "xf86Priv.h"
-#include "xf86DDC.h"
-#include "mipointer.h"
-#include "windowstr.h"
-#include "mivalidate.h"
-#include <randrstr.h>
-
-#include "i830.h"
-
-typedef struct _i830RandRInfo {
-    int				    virtualX;
-    int				    virtualY;
-    int				    mmWidth;
-    int				    mmHeight;
-    int				    maxX;
-    int				    maxY;
-    Rotation			    rotation; /* current mode */
-    Rotation                        supported_rotations; /* driver supported */
-} XF86RandRInfoRec, *XF86RandRInfoPtr;
-    
-static int	    i830RandRIndex;
-static int	    i830RandRGeneration;
-
-#define XF86RANDRINFO(p)    ((XF86RandRInfoPtr) (p)->devPrivates[i830RandRIndex].ptr)
-
-static int
-I830RandRModeRefresh (DisplayModePtr mode)
-{
-    if (mode->VRefresh)
-	return (int) (mode->VRefresh + 0.5);
-    else
-	return (int) (mode->Clock * 1000.0 / mode->HTotal / mode->VTotal + 0.5);
-}
-
-static Bool
-I830RandRGetInfo (ScreenPtr pScreen, Rotation *rotations)
-{
-    RRScreenSizePtr	    pSize;
-    ScrnInfoPtr		    scrp = XF86SCRNINFO(pScreen);
-    XF86RandRInfoPtr	    randrp = XF86RANDRINFO(pScreen);
-    DisplayModePtr	    mode;
-    int			    refresh0 = 60;
-    int			    maxX = 0, maxY = 0;
-    
-    *rotations = randrp->supported_rotations;
-
-    if (randrp->virtualX == -1 || randrp->virtualY == -1) 
-    {
-	randrp->virtualX = scrp->virtualX;
-	randrp->virtualY = scrp->virtualY;
-    }
-
-    for (mode = scrp->modes; ; mode = mode->next)
-    {
-	int refresh = I830RandRModeRefresh (mode);
-	if (randrp->maxX == 0 || randrp->maxY == 0)
-	{
-		if (maxX < mode->HDisplay)
-			maxX = mode->HDisplay;
-		if (maxY < mode->VDisplay)
-			maxY = mode->VDisplay;
-	}
-	if (mode == scrp->modes)
-	    refresh0 = refresh;
-	pSize = RRRegisterSize (pScreen,
-				mode->HDisplay, mode->VDisplay,
-				randrp->mmWidth, randrp->mmHeight);
-	if (!pSize)
-	    return FALSE;
-	RRRegisterRate (pScreen, pSize, refresh);
-	if (mode == scrp->currentMode &&
-	    mode->HDisplay == scrp->virtualX && mode->VDisplay == scrp->virtualY)
-	    RRSetCurrentConfig (pScreen, randrp->rotation, refresh, pSize);
-	if (mode->next == scrp->modes)
-	    break;
-    }
-
-    if (randrp->maxX == 0 || randrp->maxY == 0)
-    {
-	randrp->maxX = maxX;
-	randrp->maxY = maxY;
-    }
-   
-    if (scrp->currentMode->HDisplay != randrp->virtualX ||
-	scrp->currentMode->VDisplay != randrp->virtualY)
-    {
-	mode = scrp->modes;
-	pSize = RRRegisterSize (pScreen,
-				randrp->virtualX, randrp->virtualY,
-				randrp->mmWidth,
-				randrp->mmHeight);
-	if (!pSize)
-	    return FALSE;
-	RRRegisterRate (pScreen, pSize, refresh0);
-	if (scrp->virtualX == randrp->virtualX && 
-	    scrp->virtualY == randrp->virtualY)
-	{
-	    RRSetCurrentConfig (pScreen, randrp->rotation, refresh0, pSize);
-	}
-    }
-
-    /* If there is driver support for randr, let it set our supported rotations */
-    if(scrp->RRFunc) {
-	xorgRRRotation RRRotation;
-	
-	RRRotation.RRRotations = *rotations;
-	if (!(*scrp->RRFunc)(scrp, RR_GET_INFO, &RRRotation))
-	    return FALSE;
-	*rotations = RRRotation.RRRotations;
-    }
-    
-    return TRUE;
-}
-
-static Bool
-I830RandRSetMode (ScreenPtr	    pScreen,
-		  DisplayModePtr    mode,
-		  Bool		    useVirtual,
-		  int		    mmWidth,
-		  int		    mmHeight)
-{
-    ScrnInfoPtr		scrp = XF86SCRNINFO(pScreen);
-    XF86RandRInfoPtr	randrp = XF86RANDRINFO(pScreen);
-    int			oldWidth = pScreen->width;
-    int			oldHeight = pScreen->height;
-    int			oldmmWidth = pScreen->mmWidth;
-    int			oldmmHeight = pScreen->mmHeight;
-    WindowPtr		pRoot = WindowTable[pScreen->myNum];
-    DisplayModePtr      currentMode = NULL;
-    Bool 		ret = TRUE;
-    PixmapPtr 		pspix = NULL;
-    
-    if (pRoot)
-	(*scrp->EnableDisableFBAccess) (pScreen->myNum, FALSE);
-    if (useVirtual)
-    {
-	scrp->virtualX = randrp->virtualX;
-	scrp->virtualY = randrp->virtualY;
-    }
-    else
-    {
-	scrp->virtualX = mode->HDisplay;
-	scrp->virtualY = mode->VDisplay;
-    }
-    if(randrp->rotation & (RR_Rotate_90 | RR_Rotate_270))
-    {
-	/* If the screen is rotated 90 or 270 degrees, swap the sizes. */
-	pScreen->width = scrp->virtualY;
-	pScreen->height = scrp->virtualX;
-	pScreen->mmWidth = mmHeight;
-	pScreen->mmHeight = mmWidth;
-    }
-    else
-    {
-	pScreen->width = scrp->virtualX;
-	pScreen->height = scrp->virtualY;
-	pScreen->mmWidth = mmWidth;
-	pScreen->mmHeight = mmHeight;
-    }
-    if (scrp->currentMode == mode) {
-        /* Save current mode */
-        currentMode = scrp->currentMode;
-        /* Reset, just so we ensure the drivers SwitchMode is called */
-        scrp->currentMode = NULL;
-    }
-    /*
-     * We assume that if the driver failed to SwitchMode to the rotated
-     * version, then it should revert back to it's prior mode... Mmm...
-     */
-    if (!xf86SwitchMode (pScreen, mode))
-    {
-        ret = FALSE;
-	scrp->virtualX = pScreen->width = oldWidth;
-	scrp->virtualY = pScreen->height = oldHeight;
-	pScreen->mmWidth = oldmmWidth;
-	pScreen->mmHeight = oldmmHeight;
-        scrp->currentMode = currentMode;
-    }
-    /*
-     * Get the new Screen pixmap ptr as SwitchMode might have called
-     * ModifyPixmapHeader and xf86EnableDisableFBAccess will put it back...
-     * Unfortunately.
-     */
-    pspix = (*pScreen->GetScreenPixmap) (pScreen);
-    if (pspix->devPrivate.ptr)
-       scrp->pixmapPrivate = pspix->devPrivate;
-    
-    /*
-     * Make sure the layout is correct
-     */
-    xf86ReconfigureLayout();
-
-    /*
-     * Make sure the whole screen is visible
-     */
-    xf86SetViewport (pScreen, pScreen->width, pScreen->height);
-    xf86SetViewport (pScreen, 0, 0);
-    if (pRoot)
-	(*scrp->EnableDisableFBAccess) (pScreen->myNum, TRUE);
-    return ret;
-}
-
-Bool
-I830RandRSetConfig (ScreenPtr		pScreen,
-		    Rotation		rotation,
-		    int			rate,
-		    RRScreenSizePtr	pSize)
-{
-    ScrnInfoPtr		    scrp = XF86SCRNINFO(pScreen);
-    XF86RandRInfoPtr	    randrp = XF86RANDRINFO(pScreen);
-    DisplayModePtr	    mode;
-    int			    px, py;
-    Bool		    useVirtual = FALSE;
-    int			    maxX = 0, maxY = 0;
-    Rotation		    oldRotation = randrp->rotation;
-
-    randrp->rotation = rotation;
-
-    if (randrp->virtualX == -1 || randrp->virtualY == -1) 
-    {
-	randrp->virtualX = scrp->virtualX;
-	randrp->virtualY = scrp->virtualY;
-    }
-
-    miPointerPosition (&px, &py);
-    for (mode = scrp->modes; ; mode = mode->next)
-    {
-	if (randrp->maxX == 0 || randrp->maxY == 0)
-	{
-		if (maxX < mode->HDisplay)
-			maxX = mode->HDisplay;
-		if (maxY < mode->VDisplay)
-			maxY = mode->VDisplay;
-	}
-	if (mode->HDisplay == pSize->width && 
-	    mode->VDisplay == pSize->height &&
-	    (rate == 0 || I830RandRModeRefresh (mode) == rate))
-	    break;
-	if (mode->next == scrp->modes)
-	{
-	    if (pSize->width == randrp->virtualX &&
-		pSize->height == randrp->virtualY)
-	    {
-		mode = scrp->modes;
-		useVirtual = TRUE;
-		break;
-	    }
-    	    if (randrp->maxX == 0 || randrp->maxY == 0)
-    	    {
-		randrp->maxX = maxX;
-		randrp->maxY = maxY;
-    	    }
-	    return FALSE;
-	}
-    }
-
-    if (randrp->maxX == 0 || randrp->maxY == 0)
-    {
-	randrp->maxX = maxX;
-	randrp->maxY = maxY;
-    }
-
-    /* Have the driver do its thing. */
-    if (scrp->RRFunc) {
-	xorgRRRotation RRRotation;
-	RRRotation.RRConfig.rotation = rotation;
-	RRRotation.RRConfig.rate = rate;
-	RRRotation.RRConfig.width = pSize->width;
-	RRRotation.RRConfig.height = pSize->height;
-	
-        if (!(*scrp->RRFunc)(scrp, RR_SET_CONFIG, &RRRotation))
-			  return FALSE;
-    }
-
-    if (!I830RandRSetMode (pScreen, mode, useVirtual, pSize->mmWidth, pSize->mmHeight)) {
-        randrp->rotation = oldRotation;
-	return FALSE;
-    }
-
-    /*
-     * Move the cursor back where it belongs; SwitchMode repositions it
-     */
-    if (pScreen == miPointerCurrentScreen ())
-    {
-        px = (px >= pScreen->width ? (pScreen->width - 1) : px);
-        py = (py >= pScreen->height ? (pScreen->height - 1) : py);
-
-	xf86SetViewport(pScreen, px, py);
-
-	(*pScreen->SetCursorPosition) (pScreen, px, py, FALSE);
-    }
-
-    return TRUE;
-}
-
-Rotation
-I830GetRotation(ScreenPtr pScreen)
-{
-    XF86RandRInfoPtr	    randrp = XF86RANDRINFO(pScreen);
-
-    return randrp->rotation;
-}
-
-Bool
-I830RandRInit (ScreenPtr    pScreen, int rotation)
-{
-    rrScrPrivPtr	rp;
-    XF86RandRInfoPtr	randrp;
-    ScrnInfoPtr		scrp = XF86SCRNINFO(pScreen);
-    
-#ifdef PANORAMIX
-    /* XXX disable RandR when using Xinerama */
-    if (!noPanoramiXExtension)
-	return TRUE;
-#endif
-    if (i830RandRGeneration != serverGeneration)
-    {
-	i830RandRIndex = AllocateScreenPrivateIndex();
-	i830RandRGeneration = serverGeneration;
-    }
-    
-    randrp = xalloc (sizeof (XF86RandRInfoRec));
-    if (!randrp)
-	return FALSE;
-			
-    if (!RRScreenInit(pScreen))
-    {
-	xfree (randrp);
-	return FALSE;
-    }
-    rp = rrGetScrPriv(pScreen);
-    rp->rrGetInfo = I830RandRGetInfo;
-    rp->rrSetConfig = I830RandRSetConfig;
-
-    randrp->virtualX = -1;
-    randrp->virtualY = -1;
-    randrp->mmWidth = pScreen->mmWidth;
-    randrp->mmHeight = pScreen->mmHeight;
-    
-    randrp->rotation = RR_Rotate_0; /* initial rotated mode */
-
-    randrp->supported_rotations = rotation;
-
-    randrp->maxX = randrp->maxY = 0;
-
-    pScreen->devPrivates[i830RandRIndex].ptr = randrp;
-
-    return TRUE;
-}
-
-#ifdef XFree86LOADER
-static MODULESETUPPROTO(intelrandrSetup);
-
-static XF86ModuleVersionInfo intelrandrVersRec =
-{
-	"intel_randr",
-	"Tungsten Graphics, Inc",
-	MODINFOSTRING1,
-	MODINFOSTRING2,
-	XF86_VERSION_CURRENT,
-	INTEL_MAJOR_VERSION, INTEL_MINOR_VERSION, INTEL_PATCHLEVEL,
-	ABI_CLASS_EXTENSION,
-	ABI_EXTENSION_VERSION,
-	MOD_CLASS_EXTENSION,
-	{0,0,0,0}
-};
-
-XF86ModuleData intel_randrModuleData = { &intelrandrVersRec, intelrandrSetup, NULL };
-
-ModuleInfoRec INTELRANDR = {
-    1,
-    "INTELRANDR",
-    NULL,
-    0,
-    NULL,
-};
-
-/*ARGSUSED*/
-static pointer
-intelrandrSetup(pointer Module, pointer Options, int *ErrorMajor, int *ErrorMinor)
-{
-    static Bool Initialised = FALSE;
-
-    if (!Initialised) {
-	Initialised = TRUE;
-#ifndef REMOVE_LOADER_CHECK_MODULE_INFO
-	if (xf86LoaderCheckSymbol("xf86AddModuleInfo"))
-#endif
-	xf86AddModuleInfo(&INTELRANDR, Module);
-    }
-
-    return (pointer)TRUE;
-}
-#endif
diff-tree 2e58aa401dfbab438752038a9034df571c8f8bde (from 2cd6c8fa2321ca217ef89db1027dbe9e716ad7aa)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Fri May 12 15:54:37 2006 -0700

    Make the intel_acpi.c code non-modular and make it compile.  I think we'll end
    up nuking this code anyway, as keithp (and I, as well) disagree about how ACPI
    should be handled, but the goal is to compile at the moment.

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 8671e5a..ca76a68 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -2110,22 +2110,10 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int f
    if (pScrn->numEntities != 1)
       return FALSE;
 
-   if (!xf86LoadSubModule(pScrn, "intel_acpi"))
-      return FALSE;
-
    /* try to load the video kernel module now */
    xf86LoadKernelModule("video");
 
-   if (xf86LoaderCheckSymbol("I830ACPIOpen")) {
-      void (*acpiOpen)(void) = NULL;
-
-      acpiOpen = LoaderSymbol("I830ACPIOpen");
-
-      if (acpiOpen) {
-         ErrorF("Opening ACPI\n");
-         (*acpiOpen)();
-      }
-   }
+   I830ACPIOpen();
 
    /* Load int10 module */
    if (!xf86LoadSubModule(pScrn, "int10"))
diff --git a/src/intel_acpi.c b/src/intel_acpi.c
index e7014b2..1cd6c97 100644
--- a/src/intel_acpi.c
+++ b/src/intel_acpi.c
@@ -1,3 +1,7 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #ifndef XFree86LOADER
 #include <fcntl.h>
 #include <errno.h>
@@ -5,7 +9,8 @@
 #endif
 #include <sys/un.h>
 #include <sys/socket.h>
-#include "X.h"
+#include <sys/fcntl.h>
+#include <sys/errno.h>
 #include "os.h"
 #include "xf86.h"
 #include "xf86Priv.h"
@@ -184,48 +189,3 @@ I830CloseACPI(void)
 	I830ACPIihPtr = NULL;
     }
 }
-
-#ifdef XFree86LOADER
-static MODULESETUPPROTO(intel_acpiSetup);
-
-static XF86ModuleVersionInfo intel_acpiVersRec =
-{
-	"intel_acpi",
-	"Tungsten Graphics, Inc",
-	MODINFOSTRING1,
-	MODINFOSTRING2,
-	XF86_VERSION_CURRENT,
-	INTEL_MAJOR_VERSION, INTEL_MINOR_VERSION, INTEL_PATCHLEVEL,
-	ABI_CLASS_EXTENSION,
-	ABI_EXTENSION_VERSION,
-	MOD_CLASS_EXTENSION,
-	{0,0,0,0}
-};
-
-XF86ModuleData intel_acpiModuleData = { &intel_acpiVersRec, intel_acpiSetup, NULL };
-
-ModuleInfoRec INTELACPI = {
-    1,
-    "INTELACPI",
-    NULL,
-    0,
-    NULL,
-};
-
-/*ARGSUSED*/
-static pointer
-intel_acpiSetup(pointer Module, pointer Options, int *ErrorMajor, int *ErrorMinor)
-{
-    static Bool Initialised = FALSE;
-
-    if (!Initialised) {
-	Initialised = TRUE;
-#ifndef REMOVE_LOADER_CHECK_MODULE_INFO
-	if (xf86LoaderCheckSymbol("xf86AddModuleInfo"))
-#endif
-	xf86AddModuleInfo(&INTELACPI, Module);
-    }
-
-    return (pointer)TRUE;
-}
-#endif
diff-tree 2cd6c8fa2321ca217ef89db1027dbe9e716ad7aa (from 88558ebeed12d6cefd73bba0ddac3c043861ac89)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Fri May 12 15:37:44 2006 -0700

    Revert internal shadow module changes back like master, along with RandR
    initialization.  RandR initialization retains the no-rotation setting for BW.

diff --git a/src/i830_dri.c b/src/i830_dri.c
index e3fcc97..b82eae6 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -974,8 +974,7 @@ I830DRIFinishScreenInit(ScreenPtr pScree
     */
 #if 0
    if (pI830->allowPageFlip && pI830->drmMinor >= 1) {
-      I830shadowSetup(pScreen);
-      I830shadowAdd(pScreen, 0, I830DRIShadowUpdate, 0, 0, 0);
+      shadowAdd(pScreen, 0, I830DRIShadowUpdate, 0, 0, 0);
    }
    else
 #endif
diff --git a/src/i830_driver.c b/src/i830_driver.c
index f4cdfdc..8671e5a 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -5372,44 +5372,25 @@ I830BIOSScreenInit(int scrnIndex, Screen
    pI830->CloseScreen = pScreen->CloseScreen;
    pScreen->CloseScreen = I830BIOSCloseScreen;
 
-#if 1 /* ROTATION */
-   {
-      Bool init = TRUE;
-
-      if (!xf86LoadSubModule(pScrn, "intel_randr"))
-         init = FALSE;
-
-#if 0
-      if (!xf86LoadSubModule(pScrn, "i830_damage"))
-         init = FALSE;
-
-      if (!xf86LoadSubModule(pScrn, "i830_shadow"))
-         init = FALSE;
-#endif
-
-      if (init && xf86LoaderCheckSymbol("I830RandRInit")) {
-         Bool (*I830RandRInit)(ScreenPtr pScreen, int rotation) = NULL;
-
-         I830RandRInit = LoaderSymbol("I830RandRInit");
-
-         if (I830RandRInit) {
-            xf86DisableRandR(); /* Disable built-in RandR extension */
-	    I830shadowSetup(pScreen);
-            if (IS_BROADWATER(pI830))
-               /* only 0 degrees for Broadwater */
-               (*I830RandRInit)(pScreen, RR_Rotate_0);
-            else
-            	/* support all rotations */
-               (*I830RandRInit)(pScreen, RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_180 | RR_Rotate_270);
-      	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Intel: RandR enabled, ignore the following RandR disabled message.\n");
-	    pI830->PointerMoved = pScrn->PointerMoved;
-	    pScrn->PointerMoved = I830PointerMoved;
-	    pI830->CreateScreenResources = pScreen->CreateScreenResources;
-            pScreen->CreateScreenResources = I830CreateScreenResources;
-         }
+   if (pI830->shadowReq.minorversion >= 1) {
+      /* Rotation */
+      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "RandR enabled, ignore the following RandR disabled message.\n");
+      xf86DisableRandR(); /* Disable built-in RandR extension */
+      shadowSetup(pScreen);
+      /* support all rotations */
+      if (IS_BROADWATER(pI830)) {
+	 I830RandRInit(pScreen, RR_Rotate_0); /* only 0 degrees for Broadwater */
+      } else {
+	 I830RandRInit(pScreen, RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_180 | RR_Rotate_270);
       }
+      pI830->PointerMoved = pScrn->PointerMoved;
+      pScrn->PointerMoved = I830PointerMoved;
+      pI830->CreateScreenResources = pScreen->CreateScreenResources;
+      pScreen->CreateScreenResources = I830CreateScreenResources;
+   } else {
+      /* Rotation */
+      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "libshadow is version %d.%d.%d, required 1.1.0 or greater for rotation.\n",pI830->shadowReq.majorversion,pI830->shadowReq.minorversion,pI830->shadowReq.patchlevel);
    }
-#endif
 
    if (serverGeneration == 1)
       xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
diff --git a/src/i830_rotate.c b/src/i830_rotate.c
index 1f1d729..d0d9cf2 100644
--- a/src/i830_rotate.c
+++ b/src/i830_rotate.c
@@ -702,13 +702,7 @@ I830Rotate(ScrnInfoPtr pScrn, DisplayMod
       pScrn2 = pScrn;
    }
 
-   if (xf86LoaderCheckSymbol("I830GetRotation")) {
-      Rotation (*I830GetRotation)(ScreenPtr pScreen) = NULL;
-      I830GetRotation = LoaderSymbol("I830GetRotation");
-      if (I830GetRotation) {
-         pI830->rotation = (*I830GetRotation)(pScrn->pScreen);
-      }
-   }   
+   pI830->rotation = I830GetRotation(pScrn->pScreen);
 
    /* Check if we've still got the same orientation, or same mode */
    if (pI830->rotation == oldRotation && pI830->currentMode == mode)
@@ -853,12 +847,11 @@ I830Rotate(ScrnInfoPtr pScrn, DisplayMod
       }
    }
    
-   I830shadowUnset (pScrn->pScreen);
+   shadowRemove (pScrn->pScreen, NULL);
    if (pI830->rotation != RR_Rotate_0)
-      I830shadowSet (pScrn->pScreen, 
-                    (*pScrn->pScreen->GetScreenPixmap) (pScrn->pScreen), 
-		    pI830->noAccel ? I830shadowUpdateRotatePacked : func, 
-                    I830WindowLinear, pI830->rotation, 0);
+      shadowAdd (pScrn->pScreen, 
+		 (*pScrn->pScreen->GetScreenPixmap) (pScrn->pScreen),
+		 func, I830WindowLinear, pI830->rotation, 0);
 
    if (I830IsPrimary(pScrn)) {
       if (pI830->rotation != RR_Rotate_0)
@@ -1063,12 +1056,11 @@ BAIL0:
          I830BindGARTMemory(pScrn1->scrnIndex, pI8301->RotatedMem.Key, pI8301->RotatedMem.Offset);
    }
 
-   I830shadowUnset (pScrn->pScreen);
+   shadowRemove (pScrn->pScreen, NULL);
    if (pI830->rotation != RR_Rotate_0)
-      I830shadowSet (pScrn->pScreen, 
-                    (*pScrn->pScreen->GetScreenPixmap) (pScrn->pScreen), 
-		    pI830->noAccel ? I830shadowUpdateRotatePacked : func, 
-                    I830WindowLinear, pI830->rotation, 0);
+      shadowAdd (pScrn->pScreen, 
+		 (*pScrn->pScreen->GetScreenPixmap) (pScrn->pScreen),
+		 func, I830WindowLinear, pI830->rotation, 0);
 
    if (I830IsPrimary(pScrn)) {
       if (pI830->rotation != RR_Rotate_0)
diff-tree 88558ebeed12d6cefd73bba0ddac3c043861ac89 (from 9e387ef92be9b38c68bda8a6a28b0d9eb98d53a4)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Fri May 12 15:00:17 2006 -0700

    Start fixing up the build and remove a regression from master (I think) in
    rotation.

diff --git a/src/Makefile.am b/src/Makefile.am
index c64c203..1680123 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -44,6 +44,7 @@ i810_drv_la_SOURCES = \
          i810_video.c \
          i810_wmark.c \
          i830_accel.c \
+         i830_agp.c \
          i830_common.h \
          i830_cursor.c \
          i830_dga.c \
@@ -54,7 +55,9 @@ i810_drv_la_SOURCES = \
          i830_modes.c \
          i830_video.c \
          i830_rotate.c \
-	 i830_randr.c
+	 i830_randr.c \
+	 intel_randr.c \
+	 intel_acpi.c
 
 if DRI
 i810_drv_la_SOURCES += \
diff --git a/src/i810_driver.c b/src/i810_driver.c
index cf3725a..37c20d8 100644
--- a/src/i810_driver.c
+++ b/src/i810_driver.c
@@ -327,13 +327,6 @@ const char *I810driSymbols[] = {
    NULL
 };
 
-#ifdef XF86DRI
-
-const char *I810shadowFBSymbols[] = {
-    "ShadowFBInit",
-    NULL
-};
-
 const char *I810shadowSymbols[] = {
     "shadowInit",
     "shadowSetup",
@@ -341,8 +334,6 @@ const char *I810shadowSymbols[] = {
     NULL
 };
 
-#endif
-
 #endif /* I830_ONLY */
 
 #ifndef I810_DEBUG
diff --git a/src/i830.h b/src/i830.h
index 2ff20a7..29506ea 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -47,6 +47,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #ifndef _I830_H_
 #define _I830_H_
 
+#include "xf86_OSproc.h"
 #include "compiler.h"
 #include "xf86PciInfo.h"
 #include "xf86Pci.h"
@@ -220,6 +221,7 @@ typedef struct _I830Rec {
 #endif
    unsigned int LinearAlloc;
   
+   XF86ModReqInfo shadowReq; /* to test for later libshadow */
    I830MemRange RotatedMem;
    I830MemRange RotatedMem2;
    Rotation rotation;
diff --git a/src/i830_agp.c b/src/i830_agp.c
index b10af0e..aba5bcf 100644
--- a/src/i830_agp.c
+++ b/src/i830_agp.c
@@ -13,11 +13,13 @@
 #include <sys/types.h>
 #include <linux/agpgart.h>
 #elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
+#include <sys/types.h>
 #include <sys/ioctl.h>
 #include <sys/agpio.h>
+#include <sys/errno.h>
+#include <sys/fcntl.h>
 #endif
 
-#include "X.h"
 #include "xf86.h"
 #include "xf86_OSproc.h"
 #include "i830.h"
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 1886c52..f4cdfdc 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -169,6 +169,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include <string.h>
 #include <unistd.h>
 #include <stdlib.h>
+#include <stdio.h>
 
 #include "xf86.h"
 #include "xf86_OSproc.h"
diff --git a/src/i830_rotate.c b/src/i830_rotate.c
index 9c91cc4..1f1d729 100644
--- a/src/i830_rotate.c
+++ b/src/i830_rotate.c
@@ -680,10 +680,13 @@ I830Rotate(ScrnInfoPtr pScrn, DisplayMod
 	 0
    };
 
-   if (IS_I9XX(pI830))
-      func = I915UpdateRotate;
+   if (pI830->noAccel)
+      func = LoaderSymbol("shadowUpdateRotatePacked");
    else
-      func = I830UpdateRotate;
+      if (IS_I9XX(pI830))
+	 func = I915UpdateRotate;
+      else
+	 func = I830UpdateRotate;
 
    if (I830IsPrimary(pScrn)) {
       pI8301 = pI830;
diff-tree 9e387ef92be9b38c68bda8a6a28b0d9eb98d53a4 (from af2432322ba1d561057c34ab185561a8e799e8cd)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Fri May 12 13:41:38 2006 -0700

    Re-add authorship note in i830_driver.c accidentally left out of last commit.

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 43b33fc..1886c52 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -150,6 +150,12 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
  *    09/2005 Alan Hourihane
  *        - Add Intel(R) 945GM support.
  *
+ *    10/2005 Alan Hourihane, Keith Whitwell, Brian Paul
+ *        - Added Rotation support
+ *
+ *    12/2005 Alan Hourihane
+ *        - Add Intel(R) Broadwater support.
+ *
  */
 
 #ifdef HAVE_CONFIG_H
diff-tree af2432322ba1d561057c34ab185561a8e799e8cd (from f2967a2f5f47b636b2445fa69dbc3ec79e065c90)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Fri May 12 13:32:38 2006 -0700

    First pass of integrating the Tungsten Graphics driver for Broadwater.  This
    patch is based off of diffing from the branchpoint to the supplied code, but
    with many chunks containing reversions of commits removed.  Won't work yet.

diff --git a/src/common.h b/src/common.h
index a6e4ca3..70f58a9 100644
--- a/src/common.h
+++ b/src/common.h
@@ -272,6 +272,11 @@ extern int I810_DEBUG;
 #define PCI_CHIP_I945_GM_BRIDGE 0x27A0
 #endif
 
+#ifndef PCI_CHIP_BROADWATER
+#define PCI_CHIP_BROADWATER	0x2982
+#define PCI_CHIP_BROADWATER_BRIDGE 0x2980
+#endif
+
 #define IS_I810(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I810 ||	\
 			pI810->PciInfo->chipType == PCI_CHIP_I810_DC100 || \
 			pI810->PciInfo->chipType == PCI_CHIP_I810_E)
@@ -287,7 +292,8 @@ extern int I810_DEBUG;
 #define IS_I915GM(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I915_GM)
 #define IS_I945G(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I945_G)
 #define IS_I945GM(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I945_GM)
-#define IS_I9XX(pI810) (IS_I915G(pI810) || IS_I915GM(pI810) || IS_I945G(pI810) || IS_I945GM(pI810))
+#define IS_BROADWATER(pI810) (pI810->PciInfo->chipType == PCI_CHIP_BROADWATER)
+#define IS_I9XX(pI810) (IS_I915G(pI810) || IS_I915GM(pI810) || IS_I945G(pI810) || IS_I945GM(pI810) || IS_BROADWATER(pI810))
 
 #define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810) || IS_I915GM(pI810) || IS_I945GM(pI810))
 
diff --git a/src/i810_driver.c b/src/i810_driver.c
index 7d854df..cf3725a 100644
--- a/src/i810_driver.c
+++ b/src/i810_driver.c
@@ -140,6 +140,7 @@ static SymTabRec I810Chipsets[] = {
    {PCI_CHIP_I915_GM,		"915GM"},
    {PCI_CHIP_I945_G,		"945G"},
    {PCI_CHIP_I945_GM,		"945GM"},
+   {PCI_CHIP_BROADWATER,	"Broadwater"},
    {-1,				NULL}
 };
 
@@ -159,6 +160,7 @@ static PciChipsets I810PciChipsets[] = {
    {PCI_CHIP_I915_GM,		PCI_CHIP_I915_GM,	RES_SHARED_VGA},
    {PCI_CHIP_I945_G,		PCI_CHIP_I945_G,	RES_SHARED_VGA},
    {PCI_CHIP_I945_GM,		PCI_CHIP_I945_GM,	RES_SHARED_VGA},
+   {PCI_CHIP_BROADWATER,	PCI_CHIP_BROADWATER,	RES_SHARED_VGA},
    {-1,				-1, RES_UNDEFINED }
 };
 
@@ -324,17 +326,25 @@ const char *I810driSymbols[] = {
    "DRICreatePCIBusID",
    NULL
 };
-#endif 
+
+#ifdef XF86DRI
+
+const char *I810shadowFBSymbols[] = {
+    "ShadowFBInit",
+    NULL
+};
 
 const char *I810shadowSymbols[] = {
     "shadowInit",
     "shadowSetup",
     "shadowAdd",
-    "shadowRemove",
-    "shadowUpdateRotatePacked",
     NULL
 };
 
+#endif
+
+#endif /* I830_ONLY */
+
 #ifndef I810_DEBUG
 int I810_DEBUG = (0
 /*     		  | DEBUG_ALWAYS_SYNC  */
@@ -578,6 +588,7 @@ I810Probe(DriverPtr drv, int flags)
 	    case PCI_CHIP_I915_GM:
 	    case PCI_CHIP_I945_G:
 	    case PCI_CHIP_I945_GM:
+	    case PCI_CHIP_BROADWATER:
     	       xf86SetEntitySharable(usedChips[i]);
 
     	       /* Allocate an entity private if necessary */		
diff --git a/src/i810_reg.h b/src/i810_reg.h
index e52375f..6acdda9 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -293,16 +293,78 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define STATE_VAR_UPDATE_DISABLE     0x02
 #define PAL_STIP_DISABLE             0x01
 
-#define INST_DONE                0x2090
-#define INST_PS                  0x20c4
 
 #define MEMMODE                  0x20dc
 
 
 /* Instruction parser error register.  p279
  */
+#if 0
 #define IPEIR                  0x2088
 #define IPEHR                  0x208C
+#define INST_DONE                0x2090
+#define INST_PS                  0x20c4
+#else
+#define IPEIR                  0x2064 /* brw */
+#define IPEHR                  0x2068 /* brw */
+#define INST_DONE              0x206c
+#define INST_PS                0x2070
+#define ACTHD                 0x2074
+#define DMA_FADD_P             0x2078
+#define INST_DONE_1              0x207c
+
+#define CACHE_MODE_0           0x2120
+#define CACHE_MODE_1           0x2124
+#define MI_ARB_STATE           0x20e4
+
+#define WIZ_CTL                0x7c00
+#define WIZ_CTL_SINGLE_SUBSPAN  (1<<6)
+#define WIZ_CTL_IGNORE_STALLS  (1<<5)
+
+#define SVG_WORK_CTL           0x7408
+
+#define TS_CTL                 0x7e00
+#define TS_MUX_ERR_CODE        (0<<8)
+#define TS_MUX_URB_0           (1<<8)
+#define TS_MUX_DISPATCH_ID_0   (10<<8)
+#define TS_MUX_ERR_CODE_VALID  (15<<8)
+#define TS_MUX_TID_0           (16<<8)
+#define TS_MUX_EUID_0          (18<<8)
+#define TS_MUX_FFID_0          (22<<8)
+#define TS_MUX_EOT             (26<<8)
+#define TS_MUX_SIDEBAND_0      (27<<8)
+#define TS_SNAP_ALL_CHILD      (1<<2)
+#define TS_SNAP_ALL_ROOT       (1<<1)
+#define TS_SNAP_ENABLE         (1<<0)
+
+#define TS_DEBUG_DATA          0x7e0c
+
+#define TD_CTL                 0x8000
+#define TD_CTL2                0x8004
+
+
+#define ECOSKPD 0x21d0
+#define EXCC    0x2028
+
+#endif
+
+/* Broadwater debug regs:
+ */
+#define IA_VERTICES_COUNT_QW   0x2310
+#define IA_PRIMITIVES_COUNT_QW 0x2318
+#define VS_INVOCATION_COUNT_QW 0x2320
+#define GS_INVOCATION_COUNT_QW 0x2328
+#define GS_PRIMITIVES_COUNT_QW 0x2330
+#define CL_INVOCATION_COUNT_QW 0x2338
+#define CL_PRIMITIVES_COUNT_QW 0x2340
+#define PS_INVOCATION_COUNT_QW 0x2348
+#define PS_DEPTH_COUNT_QW      0x2350
+#define TIMESTAMP_QW           0x2358
+#define CLKCMP_QW              0x2360
+
+
+
+
 
 
 /* General error reporting regs, p296
@@ -366,6 +428,13 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define FENCE            0x2000
 #define FENCE_NR         8
 
+#define FENCE_NEW        0x3000
+#define FENCE_NEW_NR     16
+
+#define FENCE_LINEAR     0
+#define FENCE_XMAJOR	 1
+#define FENCE_YMAJOR  	 2
+
 #define I915G_FENCE_START_MASK	0x0ff00000
 
 #define I830_FENCE_START_MASK	0x07f80000
@@ -772,6 +841,12 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define DSPBPOS			0x7118C
 #define DSPBSIZE		0x71190
 
+#define DSPASURF		0x7019C
+#define DSPATILEOFF		0x701A4
+
+#define DSPBSURF		0x7119C
+#define DSPBTILEOFF		0x711A4
+
 /* Various masks for reserved bits, etc. */
 #define I830_FWATER1_MASK        (~((1<<11)|(1<<10)|(1<<9)|      \
         (1<<8)|(1<<26)|(1<<25)|(1<<24)|(1<<5)|(1<<4)|(1<<3)|    \
diff --git a/src/i830.h b/src/i830.h
index d227662..2ff20a7 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]; /* Broadwater has more fence regs */
 } I830RegRec, *I830RegPtr;
 
 typedef struct {
@@ -220,7 +220,6 @@ typedef struct _I830Rec {
 #endif
    unsigned int LinearAlloc;
   
-   XF86ModReqInfo shadowReq; /* to test for later libshadow */
    I830MemRange RotatedMem;
    I830MemRange RotatedMem2;
    Rotation rotation;
@@ -238,6 +237,12 @@ typedef struct _I830Rec {
    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 +382,9 @@ typedef struct _I830Rec {
    Bool devicePresence;
 
    OsTimerPtr devicesTimer;
+
+   CARD32 savedAsurf;
+   CARD32 savedBsurf;
 } I830Rec;
 
 #define I830PTR(p) ((I830Ptr)((p)->driverPrivate))
@@ -448,8 +456,10 @@ extern long I830GetExcessMemoryAllocatio
 extern Bool I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags);
 extern Bool I830DoPoolAllocation(ScrnInfoPtr pScrn, I830MemPool *pool);
 extern Bool I830FixupOffsets(ScrnInfoPtr pScrn);
-extern Bool I830BindGARTMemory(ScrnInfoPtr pScrn);
-extern Bool I830UnbindGARTMemory(ScrnInfoPtr pScrn);
+extern Bool I830BindAGPMemory(ScrnInfoPtr pScrn);
+extern Bool I830UnbindAGPMemory(ScrnInfoPtr pScrn);
+extern Bool I830BindGARTMemory(int screenNum, int key, unsigned long offset);
+extern Bool I830UnbindGARTMemory(int screenNum, int key);
 extern unsigned long I830AllocVidMem(ScrnInfoPtr pScrn, I830MemRange *result,
 				     I830MemPool *pool, long size,
 				     unsigned long alignment, int flags);
@@ -471,6 +481,19 @@ extern Bool I830CheckModeSupport(ScrnInf
 extern Bool I830Rotate(ScrnInfoPtr pScrn, DisplayModePtr mode);
 extern Bool I830FixOffset(ScrnInfoPtr pScrn, I830MemRange *mem);
 
+/* AGP */
+extern Bool I830AgpGARTSupported(void);
+extern AgpInfoPtr I830GetAGPInfo(int screenNum);
+extern Bool I830AcquireGART(int screenNum);
+extern Bool I830ReleaseGART(int screenNum);
+extern int I830AllocateGARTMemory(int screenNum, unsigned long size, int type,
+				  unsigned long *physical);
+extern Bool I830DeallocateGARTMemory(int screenNum, int key);
+extern Bool I830BindGARTMemory(int screenNum, int key, unsigned long offset);
+extern Bool I830UnbindGARTMemory(int screenNum, int key);
+extern Bool I830EnableAGP(int screenNum, CARD32 mode);
+extern Bool I830GARTCloseScreen(int screenNum);
+
 /*
  * 12288 is set as the maximum, chosen because it is enough for
  * 1920x1440 at 32bpp with a 2048 pixel line pitch with some to spare.
diff --git a/src/i830_accel.c b/src/i830_accel.c
index a11f64b..112d32d 100644
--- a/src/i830_accel.c
+++ b/src/i830_accel.c
@@ -133,6 +133,7 @@ void
 I830Sync(ScrnInfoPtr pScrn)
 {
    I830Ptr pI830 = I830PTR(pScrn);
+   int flags = MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE;
 
    if (I810_DEBUG & (DEBUG_VERBOSE_ACCEL | DEBUG_VERBOSE_SYNC))
       ErrorF("I830Sync\n");
@@ -147,13 +148,17 @@ I830Sync(ScrnInfoPtr pScrn)
 
    if (pI830->entityPrivate && !pI830->entityPrivate->RingRunning) return;
 
+   if (IS_BROADWATER(pI830))
+      flags = 0;
+
    /* Send a flush instruction and then wait till the ring is empty.
     * This is stronger than waiting for the blitter to finish as it also
     * flushes the internal graphics caches.
     */
+   
    {
       BEGIN_LP_RING(2);
-      OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE);
+      OUT_RING(MI_FLUSH | flags);
       OUT_RING(MI_NOOP);		/* pad to quadword */
       ADVANCE_LP_RING();
    }
@@ -168,9 +173,13 @@ void
 I830EmitFlush(ScrnInfoPtr pScrn)
 {
    I830Ptr pI830 = I830PTR(pScrn);
+   int flags = MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE;
+
+   if (IS_BROADWATER(pI830))
+      flags = 0;
 
    BEGIN_LP_RING(2);
-   OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE);
+   OUT_RING(MI_FLUSH | flags);
    OUT_RING(MI_NOOP);		/* pad to quadword */
    ADVANCE_LP_RING();
 }
@@ -439,6 +448,9 @@ I830SubsequentSolidFillRect(ScrnInfoPtr 
 
       ADVANCE_LP_RING();
    }
+
+   if (IS_BROADWATER(pI830))
+      I830EmitFlush(pScrn);
 }
 
 void
@@ -500,6 +512,9 @@ I830SubsequentScreenToScreenCopy(ScrnInf
 
       ADVANCE_LP_RING();
    }
+
+   if (IS_BROADWATER(pI830))
+      I830EmitFlush(pScrn);
 }
 
 static void
@@ -574,6 +589,9 @@ I830SubsequentMono8x8PatternFillRect(Scr
       OUT_RING(0);
       ADVANCE_LP_RING();
    }
+
+   if (IS_BROADWATER(pI830))
+      I830EmitFlush(pScrn);
 }
 
 static void
@@ -690,6 +708,9 @@ I830SubsequentColorExpandScanline(ScrnIn
     */
    pI830->BR[9] += pScrn->displayWidth * pI830->cpp;
    I830GetNextScanlineColorExpandBuffer(pScrn);
+
+   if (IS_BROADWATER(pI830))
+      I830EmitFlush(pScrn);
 }
 
 #if DO_SCANLINE_IMAGE_WRITE
diff --git a/src/i830_agp.c b/src/i830_agp.c
new file mode 100644
index 0000000..b10af0e
--- /dev/null
+++ b/src/i830_agp.c
@@ -0,0 +1,364 @@
+/*
+ * Abstraction of the AGP GART interface.
+ *
+ * This version is for both Linux and FreeBSD.
+ *
+ * Copyright © 2000 VA Linux Systems, Inc.
+ * Copyright © 2001 The XFree86 Project, Inc.
+ */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_agp.c,v 3.11 2003/04/03 22:47:42 dawes Exp $ */
+
+#if defined(linux)
+#include <sys/types.h>
+#include <linux/agpgart.h>
+#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
+#include <sys/ioctl.h>
+#include <sys/agpio.h>
+#endif
+
+#include "X.h"
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "i830.h"
+
+
+#ifndef AGP_DEVICE
+#define AGP_DEVICE		"/dev/agpgart"
+#endif
+/* AGP page size is independent of the host page size. */
+#ifndef AGP_PAGE_SIZE
+#define AGP_PAGE_SIZE		4096
+#endif
+#define AGPGART_MAJOR_VERSION	0
+#define AGPGART_MINOR_VERSION	99
+
+static int gartFd = -1;
+static int acquiredScreen = -1;
+static Bool initDone = FALSE;
+/*
+ * Close /dev/agpgart.  This frees all associated memory allocated during
+ * this server generation.
+ */
+Bool
+I830GARTCloseScreen(int screenNum)
+{
+	if(gartFd != -1) {
+		close(gartFd);
+		acquiredScreen = -1;
+		gartFd = -1;
+		initDone = FALSE;
+	}
+	return TRUE;
+}
+
+/*
+ * Open /dev/agpgart.  Keep it open until I830GARTCloseScreen is called.
+ */
+static Bool
+GARTInit(int screenNum)
+{
+	struct _agp_info agpinf;
+
+	if (initDone)
+		return (gartFd != -1);
+
+	initDone = TRUE;
+
+	if (gartFd == -1)
+		gartFd = open(AGP_DEVICE, O_RDWR, 0);
+	else
+		return FALSE;
+
+	if (gartFd == -1) {
+	    xf86DrvMsg(screenNum, X_ERROR,
+		"I830GARTInit: Unable to open " AGP_DEVICE " (%s)\n",
+		strerror(errno));
+	    return FALSE;
+	}
+
+	I830AcquireGART(-1);
+	/* Check the kernel driver version. */
+	if (ioctl(gartFd, AGPIOC_INFO, &agpinf) != 0) {
+		xf86DrvMsg(screenNum, X_ERROR,
+			"I830GARTInit: AGPIOC_INFO failed (%s)\n", strerror(errno));
+		close(gartFd);
+		gartFd = -1;
+		return FALSE;
+	}
+	I830ReleaseGART(-1);
+
+#if defined(linux)
+	/* Per Dave Jones, every effort will be made to keep the 
+	 * agpgart interface backwards compatible, so allow all 
+	 * future versions.
+	 */
+	if (
+#if (AGPGART_MAJOR_VERSION > 0) /* quiet compiler */
+	    agpinf.version.major < AGPGART_MAJOR_VERSION ||
+#endif
+	    (agpinf.version.major == AGPGART_MAJOR_VERSION &&
+	     agpinf.version.minor < AGPGART_MINOR_VERSION)) {
+		xf86DrvMsg(screenNum, X_ERROR,
+			"GARTInit: Kernel agpgart driver version is not current"
+			" (%d.%d vs %d.%d)\n",
+			agpinf.version.major, agpinf.version.minor,
+			AGPGART_MAJOR_VERSION, AGPGART_MINOR_VERSION);
+		close(gartFd);
+		gartFd = -1;
+		return FALSE;
+	}
+#endif
+	
+	return TRUE;
+}
+
+Bool
+I830AgpGARTSupported()
+{
+	return GARTInit(-1);
+}
+
+AgpInfoPtr
+I830GetAGPInfo(int screenNum)
+{
+	struct _agp_info agpinf;
+	AgpInfoPtr info;
+
+	if (!GARTInit(screenNum))
+		return NULL;
+
+
+	if ((info = xcalloc(sizeof(AgpInfo), 1)) == NULL) {
+		xf86DrvMsg(screenNum, X_ERROR,
+			   "I830GetAGPInfo: Failed to allocate AgpInfo\n");
+		return NULL;
+	}
+
+	if (ioctl(gartFd, AGPIOC_INFO, &agpinf) != 0) {
+		xf86DrvMsg(screenNum, X_ERROR,
+			   "I830GetAGPInfo: AGPIOC_INFO failed (%s)\n",
+			   strerror(errno));
+		return NULL;
+	}
+
+	info->bridgeId = agpinf.bridge_id;
+	info->agpMode = agpinf.agp_mode;
+	info->base = agpinf.aper_base;
+	info->size = agpinf.aper_size;
+	info->totalPages = agpinf.pg_total;
+	info->systemPages = agpinf.pg_system;
+	info->usedPages = agpinf.pg_used;
+
+	return info;
+}
+
+/*
+ * XXX If multiple screens can acquire the GART, should we have a reference
+ * count instead of using acquiredScreen?
+ */
+
+Bool
+I830AcquireGART(int screenNum)
+{
+	if (screenNum != -1 && !GARTInit(screenNum))
+		return FALSE;
+
+	if (screenNum == -1 || acquiredScreen != screenNum) {
+		if (ioctl(gartFd, AGPIOC_ACQUIRE, 0) != 0) {
+			xf86DrvMsg(screenNum, X_WARNING,
+				"I830AcquireGART: AGPIOC_ACQUIRE failed (%s)\n",
+				strerror(errno));
+			return FALSE;
+		}
+		acquiredScreen = screenNum;
+	}
+	return TRUE;
+}
+
+Bool
+I830ReleaseGART(int screenNum)
+{
+	if (screenNum != -1 && !GARTInit(screenNum))
+		return FALSE;
+
+	if (acquiredScreen == screenNum) {
+		/*
+		 * The FreeBSD agp driver removes allocations on release.
+		 * The Linux driver doesn't.  I830ReleaseGART() is expected
+		 * to give up access to the GART, but not to remove any
+		 * allocations.
+		 */
+#if !defined(linux)
+	    if (screenNum == -1)
+#endif
+	    {
+		if (ioctl(gartFd, AGPIOC_RELEASE, 0) != 0) {
+			xf86DrvMsg(screenNum, X_WARNING,
+				"I830ReleaseGART: AGPIOC_RELEASE failed (%s)\n",
+				strerror(errno));
+			return FALSE;
+		}
+		acquiredScreen = -1;
+	    }
+	    return TRUE;
+	}
+	return FALSE;
+}
+
+int
+I830AllocateGARTMemory(int screenNum, unsigned long size, int type,
+			unsigned long *physical)
+{
+	struct _agp_allocate alloc;
+	int pages;
+
+	/*
+	 * Allocates "size" bytes of GART memory (rounds up to the next
+	 * page multiple) or type "type".  A handle (key) for the allocated
+	 * memory is returned.  On error, the return value is -1.
+	 */
+
+	if (!GARTInit(screenNum) || acquiredScreen != screenNum)
+		return -1;
+
+	pages = (size / AGP_PAGE_SIZE);
+	if (size % AGP_PAGE_SIZE != 0)
+		pages++;
+
+	/* XXX check for pages == 0? */
+
+	alloc.pg_count = pages;
+	alloc.type = type;
+
+	if (ioctl(gartFd, AGPIOC_ALLOCATE, &alloc) != 0) {
+		if (type != 3)
+		   xf86DrvMsg(screenNum, X_WARNING, "I830AllocateGARTMemory: "
+			   "allocation of %d pages failed\n\t(%s)\n", pages,
+			   strerror(errno));
+		return -1;
+	}
+
+	if (physical)
+		*physical = alloc.physical;
+
+	return alloc.key;
+}
+
+Bool
+I830DeallocateGARTMemory(int screenNum, int key)
+{
+	if (!GARTInit(screenNum) || acquiredScreen != screenNum)
+		return FALSE;
+
+	if (acquiredScreen != screenNum) {
+		xf86DrvMsg(screenNum, X_ERROR,
+                   "xf86UnbindGARTMemory: AGP not acquired by this screen\n");
+		return FALSE;
+	}
+
+	if (ioctl(gartFd, AGPIOC_DEALLOCATE, (int *)key) != 0) {
+		xf86DrvMsg(screenNum, X_WARNING,"I830DeAllocateGARTMemory: "
+                   "deallocation gart memory with key %d failed\n\t(%s)\n",
+                   key, strerror(errno));
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+/* Bind GART memory with "key" at "offset" */
+Bool
+I830BindGARTMemory(int screenNum, int key, unsigned long offset)
+{
+	struct _agp_bind bind;
+	int pageOffset;
+
+	if (!GARTInit(screenNum) || acquiredScreen != screenNum)
+		return FALSE;
+
+	if (acquiredScreen != screenNum) {
+		xf86DrvMsg(screenNum, X_ERROR,
+		      "I830BindGARTMemory: AGP not acquired by this screen\n");
+		return FALSE;
+	}
+
+	if (offset % AGP_PAGE_SIZE != 0) {
+		xf86DrvMsg(screenNum, X_WARNING, "I830BindGARTMemory: "
+			   "offset (0x%lx) is not page-aligned (%d)\n",
+			   offset, AGP_PAGE_SIZE);
+		return FALSE;
+	}
+	pageOffset = offset / AGP_PAGE_SIZE;
+
+	xf86DrvMsgVerb(screenNum, X_INFO, 3,
+		       "I830BindGARTMemory: bind key %d at 0x%08lx "
+		       "(pgoffset %d)\n", key, offset, pageOffset);
+
+	bind.pg_start = pageOffset;
+	bind.key = key;
+
+	if (ioctl(gartFd, AGPIOC_BIND, &bind) != 0) {
+		xf86DrvMsg(screenNum, X_WARNING, "I830BindGARTMemory: "
+			   "binding of gart memory with key %d\n"
+			   "\tat offset 0x%lx failed (%s)\n",
+			   key, offset, strerror(errno));
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+
+/* Unbind GART memory with "key" */
+Bool
+I830UnbindGARTMemory(int screenNum, int key)
+{
+	struct _agp_unbind unbind;
+
+	if (!GARTInit(screenNum) || acquiredScreen != screenNum)
+		return FALSE;
+
+	if (acquiredScreen != screenNum) {
+		xf86DrvMsg(screenNum, X_ERROR,
+		    "I830UnbindGARTMemory: AGP not acquired by this screen\n");
+		return FALSE;
+	}
+
+	unbind.priority = 0;
+	unbind.key = key;
+
+	if (ioctl(gartFd, AGPIOC_UNBIND, &unbind) != 0) {
+		xf86DrvMsg(screenNum, X_WARNING, "I830UnbindGARTMemory: "
+			   "unbinding of gart memory with key %d "
+			   "failed (%s)\n", key, strerror(errno));
+		return FALSE;
+	}
+
+	xf86DrvMsgVerb(screenNum, X_INFO, 3,
+		       "I830UnbindGARTMemory: unbind key %d\n", key);
+
+	return TRUE;
+}
+
+
+/* XXX Interface may change. */
+Bool
+I830EnableAGP(int screenNum, CARD32 mode)
+{
+	agp_setup setup;
+
+	if (!GARTInit(screenNum) || acquiredScreen != screenNum)
+		return FALSE;
+
+	setup.agp_mode = mode;
+	if (ioctl(gartFd, AGPIOC_SETUP, &setup) != 0) {
+		xf86DrvMsg(screenNum, X_WARNING, "I830EnableAGP: "
+			   "AGPIOC_SETUP with mode %ld failed (%s)\n",
+			   (unsigned long)mode, strerror(errno));
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
diff --git a/src/i830_common.h b/src/i830_common.h
index 41b5cc3..15056a1 100644
--- a/src/i830_common.h
+++ b/src/i830_common.h
@@ -112,6 +112,12 @@ typedef struct {
 	int rotated_size;
 	int rotated_pitch;
 	int virtualX, virtualY;
+
+        unsigned int front_tiled;
+        unsigned int back_tiled;
+        unsigned int depth_tiled;
+        unsigned int rotated_tiled;
+        unsigned int rotated2_tiled;
 } drmI830Sarea;
 
 /* Flags for perf_boxes
diff --git a/src/i830_cursor.c b/src/i830_cursor.c
index e465b98..0475093 100644
--- a/src/i830_cursor.c
+++ b/src/i830_cursor.c
@@ -91,32 +91,44 @@ I830InitHWCursor(ScrnInfoPtr pScrn)
       temp = INREG(CURSOR_A_CONTROL);
       temp &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE | MCURSOR_MEM_TYPE_LOCAL |
 		MCURSOR_PIPE_SELECT);
+      if(pI830->CursorIsARGB)
+	 temp |= MCURSOR_GAMMA_ENABLE;
       temp |= CURSOR_MODE_DISABLE;
       temp |= (pI830->pipe << 28);
-      if(pI830->CursorIsARGB)
-         temp |= MCURSOR_GAMMA_ENABLE;
       /* Need to set control, then address. */
       OUTREG(CURSOR_A_CONTROL, temp);
-      if (pI830->CursorIsARGB)
-         OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Physical);
-      else
-         OUTREG(CURSOR_A_BASE, pI830->CursorMem->Physical);
+      if (pI830->CursorNeedsPhysical) {
+         if (pI830->CursorIsARGB)
+            OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Physical);
+         else
+            OUTREG(CURSOR_A_BASE, pI830->CursorMem->Physical);
+      } else {
+         if (pI830->CursorIsARGB)
+            OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Start);
+         else
+            OUTREG(CURSOR_A_BASE, pI830->CursorMem->Start);
+      }
       if (pI830->Clone) {
          temp &= ~MCURSOR_PIPE_SELECT;
          temp |= (!pI830->pipe << 28);
          OUTREG(CURSOR_B_CONTROL, temp);
-         if (pI830->CursorIsARGB)
-            OUTREG(CURSOR_B_BASE, pI830->CursorMemARGB->Physical);
-         else
-            OUTREG(CURSOR_B_BASE, pI830->CursorMem->Physical);
+         if (pI830->CursorNeedsPhysical) {
+            if (pI830->CursorIsARGB)
+               OUTREG(CURSOR_B_BASE, pI830->CursorMemARGB->Physical);
+            else
+               OUTREG(CURSOR_B_BASE, pI830->CursorMem->Physical);
+	 } else {
+            if (pI830->CursorIsARGB)
+               OUTREG(CURSOR_B_BASE, pI830->CursorMemARGB->Start);
+            else
+               OUTREG(CURSOR_B_BASE, pI830->CursorMem->Start);
+	 }
       }
    } else {
       temp = INREG(CURSOR_CONTROL);
       temp &= ~(CURSOR_FORMAT_MASK | CURSOR_GAMMA_ENABLE |
 		CURSOR_ENABLE  | CURSOR_STRIDE_MASK);
       temp |= (CURSOR_FORMAT_3C);
-      if (pI830->CursorIsARGB)
-         temp |= CURSOR_GAMMA_ENABLE;
       /* This initialises the format and leave the cursor disabled. */
       OUTREG(CURSOR_CONTROL, temp);
       /* Need to set address and size after disabling. */
@@ -362,12 +374,10 @@ I830SetCursorPosition(ScrnInfoPtr pScrn,
 {
    I830Ptr pI830 = I830PTR(pScrn);
    CARD32 temp = 0;
+   static Bool outsideViewport = FALSE;
    Bool hide = FALSE, show = FALSE;
    int oldx = x, oldy = y;
    int hotspotx = 0, hotspoty = 0;
-#if 0
-   static Bool outsideViewport = FALSE;
-#endif
 
    oldx += pScrn->frameX0; /* undo what xf86HWCurs did */
    oldy += pScrn->frameY0;
@@ -451,15 +461,29 @@ I830SetCursorPosition(ScrnInfoPtr pScrn,
 
    /* have to upload the base for the new position */
    if (IS_I9XX(pI830)) {
-      if (pI830->CursorIsARGB)
-         OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Physical);
-      else
-         OUTREG(CURSOR_A_BASE, pI830->CursorMem->Physical);
-      if (pI830->Clone) {
+      if (pI830->CursorNeedsPhysical) {
          if (pI830->CursorIsARGB)
-            OUTREG(CURSOR_B_BASE, pI830->CursorMemARGB->Physical);
+            OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Physical);
          else
-            OUTREG(CURSOR_B_BASE, pI830->CursorMem->Physical);
+            OUTREG(CURSOR_A_BASE, pI830->CursorMem->Physical);
+      } else {
+         if (pI830->CursorIsARGB)
+            OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Start);
+         else
+            OUTREG(CURSOR_A_BASE, pI830->CursorMem->Start);
+      }
+      if (pI830->Clone) {
+         if (pI830->CursorNeedsPhysical) {
+            if (pI830->CursorIsARGB)
+               OUTREG(CURSOR_B_BASE, pI830->CursorMemARGB->Physical);
+            else
+               OUTREG(CURSOR_B_BASE, pI830->CursorMem->Physical);
+	 } else {
+            if (pI830->CursorIsARGB)
+               OUTREG(CURSOR_B_BASE, pI830->CursorMemARGB->Start);
+            else
+               OUTREG(CURSOR_B_BASE, pI830->CursorMem->Start);
+	 }
       }
    }
 }
@@ -483,7 +507,7 @@ I830ShowCursor(ScrnInfoPtr pScrn)
    pI830->cursorOn = TRUE;
    if (IS_MOBILE(pI830) || IS_I9XX(pI830)) {
       temp = INREG(CURSOR_A_CONTROL);
-      temp &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT);
+      temp &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE | MCURSOR_PIPE_SELECT);
       if (pI830->CursorIsARGB)
          temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
       else
@@ -491,25 +515,39 @@ I830ShowCursor(ScrnInfoPtr pScrn)
       temp |= (pI830->pipe << 28); /* Connect to correct pipe */
       /* Need to set mode, then address. */
       OUTREG(CURSOR_A_CONTROL, temp);
-      if (pI830->CursorIsARGB)
-         OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Physical);
-      else
-         OUTREG(CURSOR_A_BASE, pI830->CursorMem->Physical);
+      if (pI830->CursorNeedsPhysical) {
+         if (pI830->CursorIsARGB)
+            OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Physical);
+         else
+            OUTREG(CURSOR_A_BASE, pI830->CursorMem->Physical);
+      } else {
+         if (pI830->CursorIsARGB)
+            OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Start);
+         else
+            OUTREG(CURSOR_A_BASE, pI830->CursorMem->Start);
+      }
       if (pI830->Clone) {
          temp &= ~MCURSOR_PIPE_SELECT;
          temp |= (!pI830->pipe << 28);
          OUTREG(CURSOR_B_CONTROL, temp);
-         if (pI830->CursorIsARGB)
-            OUTREG(CURSOR_B_BASE, pI830->CursorMemARGB->Physical);
-         else
-            OUTREG(CURSOR_B_BASE, pI830->CursorMem->Physical);
+         if (pI830->CursorNeedsPhysical) {
+            if (pI830->CursorIsARGB)
+               OUTREG(CURSOR_B_BASE, pI830->CursorMemARGB->Physical);
+            else
+               OUTREG(CURSOR_B_BASE, pI830->CursorMem->Physical);
+	 } else {
+            if (pI830->CursorIsARGB)
+               OUTREG(CURSOR_B_BASE, pI830->CursorMemARGB->Start);
+            else
+               OUTREG(CURSOR_B_BASE, pI830->CursorMem->Start);
+	 }
       }
    } else {
       temp = INREG(CURSOR_CONTROL);
       temp &= ~(CURSOR_FORMAT_MASK);
       temp |= CURSOR_ENABLE;
       if (pI830->CursorIsARGB)
-         temp |= CURSOR_FORMAT_ARGB | CURSOR_GAMMA_ENABLE;
+         temp |= CURSOR_FORMAT_ARGB;
       else 
          temp |= CURSOR_FORMAT_3C;
       OUTREG(CURSOR_CONTROL, temp);
@@ -531,7 +569,7 @@ I830HideCursor(ScrnInfoPtr pScrn)
    pI830->cursorOn = FALSE;
    if (IS_MOBILE(pI830) || IS_I9XX(pI830)) {
       temp = INREG(CURSOR_A_CONTROL);
-      temp &= ~(CURSOR_MODE|MCURSOR_GAMMA_ENABLE);
+      temp &= ~CURSOR_MODE;
       temp |= CURSOR_MODE_DISABLE;
       OUTREG(CURSOR_A_CONTROL, temp);
       /* This is needed to flush the above change. */
@@ -548,7 +586,7 @@ I830HideCursor(ScrnInfoPtr pScrn)
       }
    } else {
       temp = INREG(CURSOR_CONTROL);
-      temp &= ~(CURSOR_ENABLE|CURSOR_GAMMA_ENABLE);
+      temp &= ~CURSOR_ENABLE;
       OUTREG(CURSOR_CONTROL, temp);
    }
 }
diff --git a/src/i830_dri.c b/src/i830_dri.c
index 13d2cfd..e3fcc97 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -81,8 +81,11 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "i830.h"
 #include "i830_dri.h"
 
+#include "dristruct.h"
+
 static char I830KernelDriverName[] = "i915";
 static char I830ClientDriverName[] = "i915";
+static char BRWClientDriverName[] = "brw";
 
 static Bool I830InitVisualConfigs(ScreenPtr pScreen);
 static Bool I830CreateContext(ScreenPtr pScreen, VisualPtr visual,
@@ -99,12 +102,16 @@ static void I830DRIInitBuffers(WindowPtr
 static void I830DRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg,
 			       RegionPtr prgnSrc, CARD32 index);
 
+static Bool I830DRICloseFullScreen(ScreenPtr pScreen);
+static Bool I830DRIOpenFullScreen(ScreenPtr pScreen);
 static void I830DRITransitionTo2d(ScreenPtr pScreen);
 static void I830DRITransitionTo3d(ScreenPtr pScreen);
 static void I830DRITransitionMultiToSingle3d(ScreenPtr pScreen);
 static void I830DRITransitionSingleToMulti3d(ScreenPtr pScreen);
 
+#if 0
 static void I830DRIShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf);
+#endif
 
 extern void GlxSetVisualConfigs(int nconfigs,
 				__GLXvisualConfig * configs,
@@ -422,11 +429,13 @@ I830CheckDRIAvailable(ScrnInfoPtr pScrn)
     * for known symbols in each module. */
    if (!xf86LoaderCheckSymbol("GlxSetVisualConfigs"))
       return FALSE;
+   if (!xf86LoaderCheckSymbol("DRIScreenInit"))
+      return FALSE;
    if (!xf86LoaderCheckSymbol("drmAvailable"))
       return FALSE;
    if (!xf86LoaderCheckSymbol("DRIQueryVersion")) {
       xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-		 "[dri] %s failed (libdri.a too old)\n", "I830DRIScreenInit");
+		 "[dri] %s failed (libdri.a too old)\n", "I830CheckDRIAvailable");
       return FALSE;
    }
 
@@ -435,13 +444,12 @@ I830CheckDRIAvailable(ScrnInfoPtr pScrn)
       int major, minor, patch;
 
       DRIQueryVersion(&major, &minor, &patch);
-      if (major != DRIINFO_MAJOR_VERSION || minor < DRIINFO_MINOR_VERSION) {
+      if (major != 4 || minor < 0) {
 	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 		    "[dri] %s failed because of a version mismatch.\n"
-		    "[dri] libdri version is %d.%d.%d bug version %d.%d.x is needed.\n"
+		    "[dri] libDRI version is %d.%d.%d but version 4.0.x is needed.\n"
 		    "[dri] Disabling DRI.\n",
-		    "I830DRIScreenInit", major, minor, patch,
-                    DRIINFO_MAJOR_VERSION, DRIINFO_MINOR_VERSION);
+		    "I830CheckDRIAvailable", major, minor, patch);
 	 return FALSE;
       }
    }
@@ -473,7 +481,11 @@ I830DRIScreenInit(ScreenPtr pScreen)
    pI830->LockHeld = 0;
 
    pDRIInfo->drmDriverName = I830KernelDriverName;
-   pDRIInfo->clientDriverName = I830ClientDriverName;
+   if (IS_BROADWATER(pI830))
+      pDRIInfo->clientDriverName = BRWClientDriverName;
+   else 
+      pDRIInfo->clientDriverName = I830ClientDriverName;
+
    if (xf86LoaderCheckSymbol("DRICreatePCIBusID")) {
       pDRIInfo->busIdString = DRICreatePCIBusID(pI830->PciInfo);
    } else {
@@ -483,16 +495,19 @@ I830DRIScreenInit(ScreenPtr pScreen)
 	      ((pciConfigPtr) pI830->PciInfo->thisCard)->devnum,
 	      ((pciConfigPtr) pI830->PciInfo->thisCard)->funcnum);
    }
-   pDRIInfo->ddxDriverMajorVersion = I830_MAJOR_VERSION;
-   pDRIInfo->ddxDriverMinorVersion = I830_MINOR_VERSION;
-   pDRIInfo->ddxDriverPatchVersion = I830_PATCHLEVEL;
-#if 1 /* temporary until this gets removed from the libdri layer */
-   pDRIInfo->frameBufferPhysicalAddress = (pointer) pI830->LinearAddr +
+   pDRIInfo->ddxDriverMajorVersion = INTEL_MAJOR_VERSION;
+   pDRIInfo->ddxDriverMinorVersion = INTEL_MINOR_VERSION;
+   pDRIInfo->ddxDriverPatchVersion = INTEL_PATCHLEVEL;
+   pDRIInfo->frameBufferPhysicalAddress = pI830->LinearAddr +
 					  pI830->FrontBuffer.Start;
+#if 0
    pDRIInfo->frameBufferSize = ROUND_TO_PAGE(pScrn->displayWidth *
 					     pScrn->virtualY * pI830->cpp);
-   pDRIInfo->frameBufferStride = pScrn->displayWidth * pI830->cpp;
+#else
+   /* For rotation we map a 0 length framebuffer as we remap ourselves later */
+   pDRIInfo->frameBufferSize = 0;
 #endif
+   pDRIInfo->frameBufferStride = pScrn->displayWidth * pI830->cpp;
    pDRIInfo->ddxDrawableTableEntry = I830_MAX_DRAWABLES;
 
    if (SAREA_MAX_DRAWABLES < I830_MAX_DRAWABLES)
@@ -527,11 +542,14 @@ I830DRIScreenInit(ScreenPtr pScreen)
    pDRIInfo->InitBuffers = I830DRIInitBuffers;
    pDRIInfo->MoveBuffers = I830DRIMoveBuffers;
    pDRIInfo->bufferRequests = DRI_ALL_WINDOWS;
+   pDRIInfo->OpenFullScreen = I830DRIOpenFullScreen;
+   pDRIInfo->CloseFullScreen = I830DRICloseFullScreen;
    pDRIInfo->TransitionTo2d = I830DRITransitionTo2d;
    pDRIInfo->TransitionTo3d = I830DRITransitionTo3d;
    pDRIInfo->TransitionSingleToMulti3D = I830DRITransitionSingleToMulti3d;
    pDRIInfo->TransitionMultiToSingle3D = I830DRITransitionMultiToSingle3d;
 
+   /* do driver-independent DRI screen initialization here */
    if (!DRIScreenInit(pScreen, pDRIInfo, &pI830->drmSubFD)) {
       xf86DrvMsg(pScreen->myNum, X_ERROR,
 		 "[dri] DRIScreenInit failed. Disabling DRI.\n");
@@ -542,6 +560,27 @@ I830DRIScreenInit(ScreenPtr pScreen)
       return FALSE;
    }
 
+#if 0 /* disabled now, see frameBufferSize above being set to 0 */
+   /* for this driver, get rid of the front buffer mapping now */
+   if (xf86LoaderCheckSymbol("DRIGetScreenPrivate")) {
+      DRIScreenPrivPtr pDRIPriv 
+         = (DRIScreenPrivPtr) DRIGetScreenPrivate(pScreen);
+
+      if (pDRIPriv && pDRIPriv->drmFD && pDRIPriv->hFrameBuffer) {
+         xf86DrvMsg(pScreen->myNum, X_ERROR,
+                    "[intel] removing original screen mapping\n");
+         drmRmMap(pDRIPriv->drmFD, pDRIPriv->hFrameBuffer);
+         pDRIPriv->hFrameBuffer = 0;
+         xf86DrvMsg(pScreen->myNum, X_ERROR,
+                    "[intel] done removing original screen mapping\n");
+      }
+   }
+   else {
+      xf86DrvMsg(pScreen->myNum, X_ERROR,
+                 "[intel] DRIGetScreenPrivate not found!!!!\n");
+   }      
+#endif
+
    /* Check the i915 DRM versioning */
    {
       drmVersionPtr version;
@@ -587,11 +626,11 @@ I830DRIScreenInit(ScreenPtr pScreen)
       /* Check the i915 DRM version */
       version = drmGetVersion(pI830->drmSubFD);
       if (version) {
-	 if (version->version_major != 1 || version->version_minor < 4) {
+	 if (version->version_major != 1 || version->version_minor < 3) {
 	    /* incompatible drm version */
 	    xf86DrvMsg(pScreen->myNum, X_ERROR,
 		       "[dri] %s failed because of a version mismatch.\n"
-		       "[dri] i915 kernel module version is %d.%d.%d but version 1.4 or greater is needed.\n"
+		       "[dri] i915 kernel module version is %d.%d.%d but version 1.3 or greater is needed.\n"
 		       "[dri] Disabling DRI.\n",
 		       "I830DRIScreenInit",
 		       version->version_major,
@@ -935,7 +974,8 @@ I830DRIFinishScreenInit(ScreenPtr pScree
     */
 #if 0
    if (pI830->allowPageFlip && pI830->drmMinor >= 1) {
-      shadowAdd(pScreen, 0, I830DRIShadowUpdate, 0, 0, 0);
+      I830shadowSetup(pScreen);
+      I830shadowAdd(pScreen, 0, I830DRIShadowUpdate, 0, 0, 0);
    }
    else
 #endif
@@ -1227,6 +1267,7 @@ I830EmitInvarientState(ScrnInfoPtr pScrn
  * might be faster, but seems like a lot more work...
  */
 
+
 #if 0
 /* This should be done *before* XAA syncs,
  * Otherwise will have to sync again???
@@ -1236,7 +1277,7 @@ I830DRIShadowUpdate (ScreenPtr pScreen, 
 {
    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
    I830Ptr pI830 = I830PTR(pScrn);
-   RegionPtr damage = (RegionPtr) shadowDamage(pBuf);
+   RegionPtr damage = &pBuf->damage;
    int i, num =  REGION_NUM_RECTS(damage);
    BoxPtr pbox = REGION_RECTS(damage);
    drmI830Sarea *pSAREAPriv = DRIGetSAREAPrivate(pScreen);
@@ -1366,6 +1407,10 @@ I830DRITransitionTo2d(ScreenPtr pScreen)
    }
 
    pI830->have3DWindows = 0;
+
+   
+   I830PrintErrorState(pScrn);
+      
 }
 
 
@@ -1382,6 +1427,14 @@ I830UpdateDRIBuffers(ScrnInfoPtr pScrn, 
 
    I830DRIUnmapScreenRegions(pScrn, sarea);
 
+   sarea->front_tiled = pI830->front_tiled;
+   sarea->back_tiled = pI830->back_tiled;
+   sarea->depth_tiled = pI830->depth_tiled;
+   sarea->rotated_tiled = pI830->rotated_tiled;
+#if 0
+   sarea->rotated2_tiled = pI830->rotated2_tiled;
+#endif
+
    if (pI830->rotation == RR_Rotate_0) {
       sarea->front_offset = pI830->FrontBuffer.Start;
       /* Don't use FrontBuffer.Size here as it includes the pixmap cache area
diff --git a/src/i830_dri.h b/src/i830_dri.h
index e511ac7..281013b 100644
--- a/src/i830_dri.h
+++ b/src/i830_dri.h
@@ -3,36 +3,18 @@
 #ifndef _I830_DRI_H
 #define _I830_DRI_H
 
+#include "xf86dri.h"
 #include "xf86drm.h"
 #include "i830_common.h"
 
 #define I830_MAX_DRAWABLES 256
 
-#define I830_MAJOR_VERSION 1
-#define I830_MINOR_VERSION 5
-#define I830_PATCHLEVEL 1
-
 #define I830_REG_SIZE 0x80000
 
 typedef struct _I830DRIRec {
    drm_handle_t regs;
    drmSize regsSize;
 
-   drmSize backbufferSize;
-   drm_handle_t backbuffer;
-
-   drmSize depthbufferSize;
-   drm_handle_t depthbuffer;
-
-   drmSize rotatedSize;
-   drm_handle_t rotatedbuffer;
-
-   drm_handle_t textures;
-   int textureSize;
-
-   drm_handle_t agp_buffers;
-   drmSize agp_buf_size;
-
    int deviceID;
    int width;
    int height;
@@ -43,18 +25,6 @@ typedef struct _I830DRIRec {
    int fbOffset;
    int fbStride;
 
-   int backOffset;
-   int backPitch;
-
-   int depthOffset;
-   int depthPitch;
-
-   int rotatedOffset;
-   int rotatedPitch;
-
-   int logTextureGranularity;
-   int textureOffset;
-
    int irq;
    int sarea_priv_offset;
 } I830DRIRec, *I830DRIPtr;
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 053ccd1..43b33fc 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -185,6 +185,10 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "shadow.h"
 #include "i830.h"
 
+#ifdef HAS_MTRR_SUPPORT
+#include <asm/mtrr.h>
+#endif
+
 #ifdef XF86DRI
 #include "dri.h"
 #endif
@@ -204,6 +208,7 @@ static SymTabRec I830BIOSChipsets[] = {
    {PCI_CHIP_I915_GM,		"915GM"},
    {PCI_CHIP_I945_G,		"945G"},
    {PCI_CHIP_I945_GM,		"945GM"},
+   {PCI_CHIP_BROADWATER,	"Broadwater"},
    {-1,				NULL}
 };
 
@@ -217,6 +222,7 @@ static PciChipsets I830BIOSPciChipsets[]
    {PCI_CHIP_I915_GM,		PCI_CHIP_I915_GM,	RES_SHARED_VGA},
    {PCI_CHIP_I945_G,		PCI_CHIP_I945_G,	RES_SHARED_VGA},
    {PCI_CHIP_I945_GM,		PCI_CHIP_I945_GM,	RES_SHARED_VGA},
+   {PCI_CHIP_BROADWATER,	PCI_CHIP_BROADWATER,	RES_SHARED_VGA},
    {-1,				-1,			RES_UNDEFINED}
 };
 
@@ -272,7 +278,7 @@ static OptionInfoRec I830BIOSOptions[] =
 
 static void I830DisplayPowerManagementSet(ScrnInfoPtr pScrn,
 					  int PowerManagementMode, int flags);
-static void I830BIOSAdjustFrame(int scrnIndex, int x, int y, int flags);
+static void I830AdjustFrame(int scrnIndex, int x, int y, int flags);
 static Bool I830BIOSCloseScreen(int scrnIndex, ScreenPtr pScreen);
 static Bool I830BIOSSaveScreen(ScreenPtr pScreen, int unblack);
 static Bool I830BIOSEnterVT(int scrnIndex, int flags);
@@ -471,7 +477,7 @@ GetNextDisplayDeviceList(ScrnInfoPtr pSc
       CARD32 VODA = (CARD32)((CARD32*)pVbe->memory)[i];
 
       xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Next ACPI _DGS [%d] 0x%lx\n",
-		 i, (unsigned long) VODA);
+		i, VODA);
 
       /* Check if it's a custom Video Output Device Attribute */
       if (!(VODA & 0x80000000)) 
@@ -528,8 +534,7 @@ GetAttachableDisplayDeviceList(ScrnInfoP
 
    for (i=0; i<(pVbe->pInt10->cx & 0xff); i++)
         xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
-		"Attachable device 0x%lx.\n", 
-		   (unsigned long) ((CARD32*)pVbe->memory)[i]);
+		"Attachable device 0x%lx.\n", ((CARD32*)pVbe->memory)[i]);
 
    return pVbe->pInt10->cx & 0xffff;
 }
@@ -1423,8 +1428,11 @@ I830DetectMemory(ScrnInfoPtr pScrn)
    gmch_ctrl = pciReadWord(bridge, I830_GMCH_CTRL);
 
    /* We need to reduce the stolen size, by the GTT and the popup.
-    * The GTT varying according the the FbMapSize and the popup is 4KB */
-   range = (pI830->FbMapSize / (1024*1024)) + 4;
+    * The GTT varying according the the FbMapSize and the popup is 4KB. */
+   if (IS_BROADWATER(pI830))
+      range = 512 + 4; /* Fixed 512KB size for Broadwater */
+   else
+      range = (pI830->FbMapSize / MB(1)) + 4;
 
    if (IS_I85X(pI830) || IS_I865G(pI830) || IS_I9XX(pI830)) {
       switch (gmch_ctrl & I830_GMCH_GMS_MASK) {
@@ -1470,6 +1478,12 @@ I830DetectMemory(ScrnInfoPtr pScrn)
 	 break;
       }
    }
+
+#if 0
+   /* And 64KB page aligned */
+   memsize &= ~0xFFFF;
+#endif
+
    if (memsize > 0) {
       xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 		 "detected %d kB stolen memory.\n", memsize / 1024);
@@ -1841,7 +1855,7 @@ I830LoadPalette(ScrnInfoPtr pScrn, int n
    unsigned char r, g, b;
    CARD32 val, temp;
    int palreg;
-   int dspreg, dspbase;
+   int dspreg, dspbase, dspsurf;
 
    DPRINTF(PFX, "I830LoadPalette: numColors: %d\n", numColors);
    pI830 = I830PTR(pScrn);
@@ -1850,10 +1864,12 @@ I830LoadPalette(ScrnInfoPtr pScrn, int n
       palreg = PALETTE_A;
       dspreg = DSPACNTR;
       dspbase = DSPABASE;
+      dspsurf = DSPASURF;
    } else {
       palreg = PALETTE_B;
       dspreg = DSPBCNTR;
       dspbase = DSPBBASE;
+      dspsurf = DSPBSURF;
    }
 
    /* To ensure gamma is enabled we need to turn off and on the plane */
@@ -1862,6 +1878,8 @@ I830LoadPalette(ScrnInfoPtr pScrn, int n
    OUTREG(dspbase, INREG(dspbase));
    OUTREG(dspreg, temp | DISPPLANE_GAMMA_ENABLE);
    OUTREG(dspbase, INREG(dspbase));
+   if (IS_BROADWATER(pI830)) 
+      OUTREG(dspsurf, INREG(dspsurf));
 
    /* It seems that an initial read is needed. */
    temp = INREG(palreg);
@@ -2085,6 +2103,23 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int f
    if (pScrn->numEntities != 1)
       return FALSE;
 
+   if (!xf86LoadSubModule(pScrn, "intel_acpi"))
+      return FALSE;
+
+   /* try to load the video kernel module now */
+   xf86LoadKernelModule("video");
+
+   if (xf86LoaderCheckSymbol("I830ACPIOpen")) {
+      void (*acpiOpen)(void) = NULL;
+
+      acpiOpen = LoaderSymbol("I830ACPIOpen");
+
+      if (acpiOpen) {
+         ErrorF("Opening ACPI\n");
+         (*acpiOpen)();
+      }
+   }
+
    /* Load int10 module */
    if (!xf86LoadSubModule(pScrn, "int10"))
       return FALSE;
@@ -2269,6 +2304,9 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int f
    case PCI_CHIP_I945_GM:
       chipname = "945GM";
       break;
+   case PCI_CHIP_BROADWATER:
+      chipname = "Broadwater";
+      break;
    default:
       chipname = "unknown chipset";
       break;
@@ -2889,7 +2927,7 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int f
     * or, at least it's meant to..... alas it doesn't seem to always work.
     */
    if (pI830->devicePresence) {
-      int req=0, att=0, enc=0;
+      int req, att, enc;
       GetDevicePresence(pScrn, &req, &att, &enc);
       for (i = 0; i < NumDisplayTypes; i++) {
          xf86DrvMsg(pScrn->scrnIndex, X_INFO,
@@ -3035,6 +3073,9 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int f
    else
       pI830->CursorNeedsPhysical = FALSE;
 
+   if (IS_BROADWATER(pI830))
+      pI830->CursorNeedsPhysical = FALSE;
+
    /* Force ring buffer to be in low memory for all chipsets */
    pI830->NeedRingBufferLow = TRUE;
 
@@ -3076,6 +3117,47 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int f
 
    SetPipeAccess(pScrn);
 
+   /* 
+    * Using the installation script we need to find out if we've just been
+    * installed, and if so, default to the native panel resolutions, otherwise
+    * we'll default to whatever existed or the default monitor settings
+    * that's inbuilt into the Xserver.
+    */
+   {
+	FILE *f;
+   	if ((f = fopen("/tmp/.newinstallation", "r"))) {
+		char data[2];
+		fgets(data, 2, f);
+		if (data[0] == 48) { /* First time */
+			/* Ignore our monitors horizsync and vertrefresh 
+	 		 * settings when we've detected a new installation 
+			 * and we're on a flat panel, therefore we should
+	 		 * start with the native panels resolution 
+	 		 */
+#if 0
+   			if ((pI830->pipe == 1) && 
+			    (pI830->operatingDevices & (PIPE_LFP << 8))) {
+#else
+			/* Changed this to only work on LFP only systems
+			 * as the other devices may not support the LFP's
+			 * resolution.
+			 */
+   			if ((pI830->pipe == 1) && 
+			    (pI830->operatingDevices == (PIPE_LFP << 8))) {
+#endif
+   	    			pScrn->monitor->nHsync = 0;
+   	    			pScrn->monitor->nVrefresh = 0;
+   				xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+	      				"Detected new installation of driver, defaulting to LFP panel size.\n");
+			}
+		}
+		fclose(f);
+		f = fopen("/tmp/.newinstallation", "w");
+		fputc(49, f);
+		fclose(f);
+   	}
+   }
+
    /* Check we have an LFP connected, before trying to
     * read PanelID information. */
    if ( (pI830->pipe == 1 && pI830->operatingDevices & (PIPE_LFP << 8)) ||
@@ -3620,8 +3702,15 @@ ResetState(ScrnInfoPtr pScrn, Bool flush
       pI830->entityPrivate->RingRunning = 0;
 
    /* Reset the fence registers to 0 */
-   for (i = 0; i < 8; i++)
-      OUTREG(FENCE + i * 4, 0);
+   if (IS_BROADWATER(pI830)) {
+      for (i = 0; i < FENCE_NEW_NR; i++) {
+	 OUTREG(FENCE_NEW + i * 8, 0);
+	 OUTREG(FENCE_NEW + 4 + i * 8, 0);
+      }
+   } else {
+      for (i = 0; i < FENCE_NR; i++)
+         OUTREG(FENCE + i * 4, 0);
+   }
 
    /* Flush the ring buffer (if enabled), then disable it. */
    if (pI830->AccelInfoRec != NULL && flush) {
@@ -3651,10 +3740,21 @@ SetFenceRegs(ScrnInfoPtr pScrn)
 
    if (!I830IsPrimary(pScrn)) return;
 
-   for (i = 0; i < 8; i++) {
-      OUTREG(FENCE + i * 4, pI830->ModeReg.Fence[i]);
-      if (I810_DEBUG & DEBUG_VERBOSE_VGA)
-	 ErrorF("Fence Register : %x\n", pI830->ModeReg.Fence[i]);
+   if (IS_BROADWATER(pI830)) {
+      for (i = 0; i < FENCE_NEW_NR; i++) {
+         OUTREG(FENCE_NEW + i * 8, pI830->ModeReg.Fence[i]);
+         OUTREG(FENCE_NEW + 4 + i * 8, pI830->ModeReg.Fence[i+FENCE_NEW_NR]);
+         if (I810_DEBUG & DEBUG_VERBOSE_VGA) {
+	    ErrorF("Fence Start Register : %x\n", pI830->ModeReg.Fence[i]);
+	    ErrorF("Fence End Register : %x\n", pI830->ModeReg.Fence[i+FENCE_NEW_NR]);
+         }
+      }
+   } else {
+      for (i = 0; i < FENCE_NR; i++) {
+         OUTREG(FENCE + i * 4, pI830->ModeReg.Fence[i]);
+         if (I810_DEBUG & DEBUG_VERBOSE_VGA)
+	    ErrorF("Fence Register : %x\n", pI830->ModeReg.Fence[i]);
+      }
    }
 }
 
@@ -3755,6 +3855,12 @@ SaveHWState(ScrnInfoPtr pScrn)
    vgaHWSave(pScrn, vgaReg, VGA_SR_FONTS);
 
    pVesa = pI830->vesa;
+
+   if (IS_BROADWATER(pI830)) {
+      pI830->savedAsurf = INREG(DSPASURF);
+      pI830->savedBsurf = INREG(DSPBSURF);
+   }
+
    /*
     * This save/restore method doesn't work for 845G BIOS, or for some
     * other platforms.  Enable it in all cases.
@@ -3865,6 +3971,11 @@ RestoreHWState(ScrnInfoPtr pScrn)
 
    VBESetDisplayStart(pVbe, pVesa->x, pVesa->y, TRUE);
 
+   if (IS_BROADWATER(pI830)) {
+      OUTREG(DSPASURF, pI830->savedAsurf);
+      OUTREG(DSPBSURF, pI830->savedBsurf);
+   }
+
    vgaHWRestore(pScrn, vgaReg, VGA_SR_FONTS);
    vgaHWLock(hwp);
 
@@ -4096,6 +4207,25 @@ I830VESASetMode(ScrnInfoPtr pScrn, Displ
 
    SetPipeAccess(pScrn);
 
+#if 0
+   { /* BROADWATER ENABLE TILING */
+      planeA = INREG(DSPACNTR) | 1<<10;
+      OUTREG(DSPACNTR, planeA);
+      /* flush the change. */
+      temp = INREG(DSPABASE);
+      OUTREG(DSPABASE, temp);
+   }
+#else
+   { /* BROADWATER DISABLE TILING */
+      planeA = INREG(DSPACNTR) & ~1<<10;
+      OUTREG(DSPACNTR, planeA);
+      /* flush the change. */
+      temp = INREG(DSPABASE);
+      OUTREG(DSPABASE, temp);
+      OUTREG(DSPASURF, INREG(DSPASURF));
+   }
+#endif
+
    if (I830VESASetVBEMode(pScrn, mode, data->block) == FALSE) {
       xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Set VBE Mode failed!\n");
       return FALSE;
@@ -4160,6 +4290,10 @@ I830VESASetMode(ScrnInfoPtr pScrn, Displ
       /* flush the change. */
       temp = INREG(DSPABASE);
       OUTREG(DSPABASE, temp);
+      if (IS_BROADWATER(pI830)) {
+         temp = INREG(DSPASURF);
+         OUTREG(DSPASURF, temp);
+      }
    }
    if (pI830->planeEnabled[1]) {
       xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Enabling plane B.\n");
@@ -4170,6 +4304,10 @@ I830VESASetMode(ScrnInfoPtr pScrn, Displ
       /* flush the change. */
       temp = INREG(DSPBADDR);
       OUTREG(DSPBADDR, temp);
+      if (IS_BROADWATER(pI830)) {
+         temp = INREG(DSPBSURF);
+         OUTREG(DSPBSURF, temp);
+      }
    }
 
    planeA = INREG(DSPACNTR);
@@ -4202,6 +4340,7 @@ I830VESASetMode(ScrnInfoPtr pScrn, Displ
          CARD32 stridereg = !pI830->pipe ? DSPASTRIDE : DSPBSTRIDE;
          CARD32 basereg = !pI830->pipe ? DSPABASE : DSPBBASE;
          CARD32 sizereg = !pI830->pipe ? DSPASIZE : DSPBSIZE;
+         CARD32 surfreg = !pI830->pipe ? DSPASURF : DSPBSURF;
          I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
 
          temp = INREG(stridereg);
@@ -4215,12 +4354,17 @@ I830VESASetMode(ScrnInfoPtr pScrn, Displ
          /* Trigger update */
          temp = INREG(basereg);
          OUTREG(basereg, temp);
+         if (IS_BROADWATER(pI830)) {
+            temp = INREG(surfreg);
+            OUTREG(surfreg, temp);
+         }
 
          if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) {
             I830Ptr pI8302 = I830PTR(pI830->entityPrivate->pScrn_2);
             stridereg = pI830->pipe ? DSPASTRIDE : DSPBSTRIDE;
             basereg = pI830->pipe ? DSPABASE : DSPBBASE;
             sizereg = pI830->pipe ? DSPASIZE : DSPBSIZE;
+            surfreg = pI830->pipe ? DSPASURF : DSPBSURF;
 
             temp = INREG(stridereg);
             if (temp / pI8302->cpp != (CARD32)(pI8302->displayWidth)) {
@@ -4233,11 +4377,16 @@ I830VESASetMode(ScrnInfoPtr pScrn, Displ
             /* Trigger update */
             temp = INREG(basereg);
             OUTREG(basereg, temp);
+            if (IS_BROADWATER(pI830)) {
+               temp = INREG(surfreg);
+               OUTREG(surfreg, temp);
+            }
          }
       } else {
          CARD32 stridereg = pI830->pipe ? DSPASTRIDE : DSPBSTRIDE;
          CARD32 basereg = pI830->pipe ? DSPABASE : DSPBBASE;
          CARD32 sizereg = pI830->pipe ? DSPASIZE : DSPBSIZE;
+         CARD32 surfreg = pI830->pipe ? DSPASURF : DSPBSURF;
          I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
          I830Ptr pI8302 = I830PTR(pI830->entityPrivate->pScrn_2);
 
@@ -4252,10 +4401,15 @@ I830VESASetMode(ScrnInfoPtr pScrn, Displ
          /* Trigger update */
          temp = INREG(basereg);
          OUTREG(basereg, temp);
+         if (IS_BROADWATER(pI830)) {
+            temp = INREG(surfreg);
+            OUTREG(surfreg, temp);
+         }
 
          stridereg = !pI830->pipe ? DSPASTRIDE : DSPBSTRIDE;
          basereg = !pI830->pipe ? DSPABASE : DSPBBASE;
          sizereg = !pI830->pipe ? DSPASIZE : DSPBSIZE;
+         surfreg = !pI830->pipe ? DSPASURF : DSPBSURF;
 
          temp = INREG(stridereg);
          if (temp / pI8302->cpp != ((CARD32)pI8302->displayWidth)) {
@@ -4268,12 +4422,17 @@ I830VESASetMode(ScrnInfoPtr pScrn, Displ
          /* Trigger update */
          temp = INREG(basereg);
          OUTREG(basereg, temp);
+         if (IS_BROADWATER(pI830)) {
+            temp = INREG(surfreg);
+            OUTREG(surfreg, temp);
+         }
       }
    } else {
       for (i = 0; i < pI830->availablePipes; i++) {
          CARD32 stridereg = i ? DSPBSTRIDE : DSPASTRIDE;
          CARD32 basereg = i ? DSPBBASE : DSPABASE;
          CARD32 sizereg = i ? DSPBSIZE : DSPASIZE;
+         CARD32 surfreg = i ? DSPBSURF : DSPASURF;
 
          if (!pI830->planeEnabled[i])
 	    continue;
@@ -4286,9 +4445,12 @@ I830VESASetMode(ScrnInfoPtr pScrn, Displ
 	    OUTREG(stridereg, pI830->displayWidth * pI830->cpp);
          }
          OUTREG(sizereg, (pMode->HDisplay - 1) | ((pMode->VDisplay - 1) << 16));
-	 /* Trigger update */
 	 temp = INREG(basereg);
 	 OUTREG(basereg, temp);
+         if (IS_BROADWATER(pI830)) {
+            temp = INREG(surfreg);
+            OUTREG(surfreg, temp);
+         }
       }
    }
 
@@ -4391,6 +4553,10 @@ I830VESASetMode(ScrnInfoPtr pScrn, Displ
    SetHWOperatingState(pScrn);
 #endif
 
+#if 0
+   I830PrintErrorState(pScrn);
+#endif
+
 #ifdef XF86DRI
    if (didLock)
       I830DRIUnlock(pScrn);
@@ -4421,27 +4587,51 @@ I830PrintErrorState(ScrnInfoPtr pScrn)
    I830Ptr pI830 = I830PTR(pScrn);
 
    ErrorF("pgetbl_ctl: 0x%lx pgetbl_err: 0x%lx\n",
-	  (unsigned long)INREG(PGETBL_CTL), (unsigned long)INREG(PGE_ERR));
+	  INREG(PGETBL_CTL), INREG(PGE_ERR));
 
-   ErrorF("ipeir: %lx iphdr: %lx\n", (unsigned long)INREG(IPEIR), 
-	  (unsigned long)INREG(IPEHR));
+   ErrorF("ipeir: %lx iphdr: %lx\n", INREG(IPEIR), INREG(IPEHR));
 
    ErrorF("LP ring tail: %lx head: %lx len: %lx start %lx\n",
-	  (unsigned long)INREG(LP_RING + RING_TAIL),
-	  (unsigned long)INREG(LP_RING + RING_HEAD) & HEAD_ADDR,
-	  (unsigned long)INREG(LP_RING + RING_LEN), 
-	  (unsigned long)INREG(LP_RING + RING_START));
+	  INREG(LP_RING + RING_TAIL),
+	  INREG(LP_RING + RING_HEAD) & HEAD_ADDR,
+	  INREG(LP_RING + RING_LEN), INREG(LP_RING + RING_START));
+
+   ErrorF("Err ID (eir): %x Err Status (esr): %x Err Mask (emr): %x\n",
+	  INREG(EIR), INREG(ESR), INREG(EMR));
+
+   ErrorF("instdone: %x instdone_1: %x\n", INREG(INST_DONE), INREG(INST_DONE_1));
+   ErrorF("instpm: %x\n", INREG(INST_PM));
+
+   ErrorF("memmode: %lx instps: %lx\n", INREG(MEMMODE), INREG(INST_PS));
 
-   ErrorF("eir: %x esr: %x emr: %x\n",
-	  INREG16(EIR), INREG16(ESR), INREG16(EMR));
+   ErrorF("HW Status mask (hwstam): %x\nIRQ enable (ier): %x imr: %x iir: %x\n",
+	  INREG(HWSTAM), INREG(IER), INREG(IMR), INREG(IIR));
 
-   ErrorF("instdone: %x instpm: %x\n", INREG16(INST_DONE), INREG8(INST_PM));
+   ErrorF("acthd: %lx dma_fadd_p: %lx\n", INREG(ACTHD), INREG(DMA_FADD_P));
+   ErrorF("ecoskpd: %lx excc: %lx\n", INREG(ECOSKPD), INREG(EXCC));
 
-   ErrorF("memmode: %lx instps: %lx\n", (unsigned long)INREG(MEMMODE), 
-	  (unsigned long)INREG(INST_PS));
+   ErrorF("cache_mode: %x/%x\n", INREG(CACHE_MODE_0), INREG(CACHE_MODE_1));
+   ErrorF("mi_arb_state: %x\n", INREG(MI_ARB_STATE));
 
-   ErrorF("hwstam: %x ier: %x imr: %x iir: %x\n",
-	  INREG16(HWSTAM), INREG16(IER), INREG16(IMR), INREG16(IIR));
+   ErrorF("IA_VERTICES_COUNT_QW %x/%x\n", INREG(IA_VERTICES_COUNT_QW), INREG(IA_VERTICES_COUNT_QW+4));
+   ErrorF("IA_PRIMITIVES_COUNT_QW %x/%x\n", INREG(IA_PRIMITIVES_COUNT_QW), INREG(IA_PRIMITIVES_COUNT_QW+4));
+
+   ErrorF("VS_INVOCATION_COUNT_QW %x/%x\n", INREG(VS_INVOCATION_COUNT_QW), INREG(VS_INVOCATION_COUNT_QW+4));
+
+   ErrorF("GS_INVOCATION_COUNT_QW %x/%x\n", INREG(GS_INVOCATION_COUNT_QW), INREG(GS_INVOCATION_COUNT_QW+4));
+   ErrorF("GS_PRIMITIVES_COUNT_QW %x/%x\n", INREG(GS_PRIMITIVES_COUNT_QW), INREG(GS_PRIMITIVES_COUNT_QW+4));
+
+   ErrorF("CL_INVOCATION_COUNT_QW %x/%x\n", INREG(CL_INVOCATION_COUNT_QW), INREG(CL_INVOCATION_COUNT_QW+4));
+   ErrorF("CL_PRIMITIVES_COUNT_QW %x/%x\n", INREG(CL_PRIMITIVES_COUNT_QW), INREG(CL_PRIMITIVES_COUNT_QW+4));
+
+   ErrorF("PS_INVOCATION_COUNT_QW %x/%x\n", INREG(PS_INVOCATION_COUNT_QW), INREG(PS_INVOCATION_COUNT_QW+4));
+   ErrorF("PS_DEPTH_COUNT_QW %x/%x\n", INREG(PS_DEPTH_COUNT_QW), INREG(PS_DEPTH_COUNT_QW+4));
+
+   ErrorF("WIZ_CTL %x\n", INREG(WIZ_CTL));
+   ErrorF("TS_CTL %x  TS_DEBUG_DATA %x\n", INREG(TS_CTL), INREG(TS_DEBUG_DATA));
+   ErrorF("TD_CTL %x / %x\n", INREG(TD_CTL), INREG(TD_CTL2));
+
+   
 }
 
 #ifdef I830DEBUG
@@ -4670,7 +4860,8 @@ I830CreateScreenResources (ScreenPtr pSc
    if (!(*pScreen->CreateScreenResources)(pScreen))
       return FALSE;
 
-   if (pI830->rotation != RR_Rotate_0) {
+   if (xf86LoaderCheckSymbol("I830RandRSetConfig") && pI830->rotation != RR_Rotate_0) {
+      Rotation (*I830RandRSetConfig)(ScreenPtr pScreen, Rotation rr, int rate, RRScreenSizePtr pSize) = NULL;
       RRScreenSize p;
       Rotation requestedRotation = pI830->rotation;
 
@@ -4682,9 +4873,12 @@ I830CreateScreenResources (ScreenPtr pSc
       p.mmWidth = pScreen->mmWidth;
       p.mmHeight = pScreen->mmHeight;
 
-      pI830->starting = TRUE; /* abuse this for dual head & rotation */
-      I830RandRSetConfig (pScreen, requestedRotation, 0, &p);
-      pI830->starting = FALSE;
+      I830RandRSetConfig = LoaderSymbol("I830RandRSetConfig");
+      if (I830RandRSetConfig) {
+         pI830->starting = TRUE; /* abuse this for dual head & rotation */
+   	 (*I830RandRSetConfig) (pScreen, requestedRotation, 0, &p);
+         pI830->starting = FALSE;
+      }
    } 
 
    return TRUE;
@@ -4779,6 +4973,47 @@ I830BIOSScreenInit(int scrnIndex, Screen
       pI830->RotatedMem2.Key = -1;
    }
 
+#ifdef HAS_MTRR_SUPPORT
+   {
+      int fd;
+      struct mtrr_gentry gentry;
+      struct mtrr_sentry sentry;
+
+      if ( ( fd = open ("/proc/mtrr", O_RDONLY, 0) ) != -1 ) {
+         for (gentry.regnum = 0; ioctl (fd, MTRRIOC_GET_ENTRY, &gentry) == 0;
+	      ++gentry.regnum) {
+
+	    if (gentry.size < 1) {
+	       /* DISABLED */
+	       continue;
+	    }
+
+            /* Check the MTRR range is one we like and if not - remove it.
+             * The Xserver common layer will then setup the right range
+             * for us.
+             */
+	    if (gentry.base == pI830->LinearAddr && 
+	        gentry.size < pI830->FbMapSize) {
+
+               xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+		  "Removing bad MTRR range (base 0x%lx, size 0x%x)\n",
+		  gentry.base, gentry.size);
+
+    	       sentry.base = gentry.base;
+               sentry.size = gentry.size;
+               sentry.type = gentry.type;
+
+               if (ioctl (fd, MTRRIOC_DEL_ENTRY, &sentry) == -1) {
+                  xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		     "Failed to remove bad MTRR range\n");
+               }
+	    }
+         }
+         close(fd);
+      }
+   }
+#endif
+
    if (xf86IsEntityShared(pScrn->entityList[0])) {
       /* PreInit failed on the second head, so make sure we turn it off */
       if (I830IsPrimary(pScrn) && !pI830->entityPrivate->pScrn_2) {
@@ -5130,21 +5365,44 @@ I830BIOSScreenInit(int scrnIndex, Screen
    pI830->CloseScreen = pScreen->CloseScreen;
    pScreen->CloseScreen = I830BIOSCloseScreen;
 
-   if (pI830->shadowReq.minorversion >= 1) {
-      /* Rotation */
-      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "RandR enabled, ignore the following RandR disabled message.\n");
-      xf86DisableRandR(); /* Disable built-in RandR extension */
-      shadowSetup(pScreen);
-      /* support all rotations */
-      I830RandRInit(pScreen, RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_180 | RR_Rotate_270);
-      pI830->PointerMoved = pScrn->PointerMoved;
-      pScrn->PointerMoved = I830PointerMoved;
-      pI830->CreateScreenResources = pScreen->CreateScreenResources;
-      pScreen->CreateScreenResources = I830CreateScreenResources;
-   } else {
-      /* Rotation */
-      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "libshadow is version %d.%d.%d, required 1.1.0 or greater for rotation.\n",pI830->shadowReq.majorversion,pI830->shadowReq.minorversion,pI830->shadowReq.patchlevel);
+#if 1 /* ROTATION */
+   {
+      Bool init = TRUE;
+
+      if (!xf86LoadSubModule(pScrn, "intel_randr"))
+         init = FALSE;
+
+#if 0
+      if (!xf86LoadSubModule(pScrn, "i830_damage"))
+         init = FALSE;
+
+      if (!xf86LoadSubModule(pScrn, "i830_shadow"))
+         init = FALSE;
+#endif
+
+      if (init && xf86LoaderCheckSymbol("I830RandRInit")) {
+         Bool (*I830RandRInit)(ScreenPtr pScreen, int rotation) = NULL;
+
+         I830RandRInit = LoaderSymbol("I830RandRInit");
+
+         if (I830RandRInit) {
+            xf86DisableRandR(); /* Disable built-in RandR extension */
+	    I830shadowSetup(pScreen);
+            if (IS_BROADWATER(pI830))
+               /* only 0 degrees for Broadwater */
+               (*I830RandRInit)(pScreen, RR_Rotate_0);
+            else
+            	/* support all rotations */
+               (*I830RandRInit)(pScreen, RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_180 | RR_Rotate_270);
+      	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Intel: RandR enabled, ignore the following RandR disabled message.\n");
+	    pI830->PointerMoved = pScrn->PointerMoved;
+	    pScrn->PointerMoved = I830PointerMoved;
+	    pI830->CreateScreenResources = pScreen->CreateScreenResources;
+            pScreen->CreateScreenResources = I830CreateScreenResources;
+         }
+      }
    }
+#endif
 
    if (serverGeneration == 1)
       xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
@@ -5153,6 +5411,36 @@ I830BIOSScreenInit(int scrnIndex, Screen
    I830_dump_registers(pScrn);
 #endif
 
+   /* turn off clock gating */
+   /* XXX: How much of this is needed for BRW?  I am currently turning
+    * off everything.
+    */
+#if 1
+   /* A0
+    */
+   if (IS_BROADWATER(pI830)) {
+      OUTREG(0x6204, 0x70804000);
+      OUTREG(0x6208, 0x00000001);
+   }
+#else
+   /* C0 ?
+    */
+   if (IS_BROADWATER(pI830)) {
+      OUTREG(0x6204, (1<<23));
+      OUTREG(0x6208, 0x0);
+   }
+#endif
+
+   /* Enable DAP stateless accesses.  
+    * Required for all broadwater steppings.
+    */
+   if (IS_BROADWATER(pI830)) {
+      ErrorF("SVG_WORK_CTL before %x\n", INREG(SVG_WORK_CTL));
+      OUTREG(SVG_WORK_CTL, 0x00000010);
+      ErrorF("SVG_WORK_CTL after %x\n", INREG(SVG_WORK_CTL));
+   }
+
+
    pI830->starting = FALSE;
    pI830->closing = FALSE;
    pI830->suspended = FALSE;
@@ -5161,7 +5449,7 @@ I830BIOSScreenInit(int scrnIndex, Screen
 }
 
 static void
-I830BIOSAdjustFrame(int scrnIndex, int x, int y, int flags)
+I830AdjustFrame(int scrnIndex, int x, int y, int flags)
 {
    ScrnInfoPtr pScrn;
    I830Ptr pI830;
@@ -5172,7 +5460,7 @@ I830BIOSAdjustFrame(int scrnIndex, int x
    pI830 = I830PTR(pScrn);
    pVbe = pI830->pVbe;
 
-   DPRINTF(PFX, "I830BIOSAdjustFrame: y = %d (+ %d), x = %d (+ %d)\n",
+   DPRINTF(PFX, "I830AdjustFrame: y = %d (+ %d), x = %d (+ %d)\n",
 	   x, pI830->xoffset, y, pI830->yoffset);
 
    /* Sync the engine before adjust frame */
@@ -5195,16 +5483,36 @@ I830BIOSAdjustFrame(int scrnIndex, int x
 
    if (pI830->Clone) {
       if (!pI830->pipe == 0) {
-         OUTREG(DSPABASE, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
+         if (!IS_BROADWATER(pI830)) {
+            OUTREG(DSPABASE, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
+         } else {
+            OUTREG(DSPABASE, 0);
+            OUTREG(DSPASURF, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
+         }
       } else {
-         OUTREG(DSPBBASE, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
+         if (!IS_BROADWATER(pI830)) {
+            OUTREG(DSPBBASE, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
+         } else {
+            OUTREG(DSPBBASE, 0);
+            OUTREG(DSPBSURF, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
+         }
       }
    }
 
    if (pI830->pipe == 0) {
-      OUTREG(DSPABASE, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
+      if (!IS_BROADWATER(pI830)) {
+         OUTREG(DSPABASE, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
+      } else {
+         OUTREG(DSPABASE, 0);
+         OUTREG(DSPASURF, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
+      }
    } else {
-      OUTREG(DSPBBASE, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
+      if (!IS_BROADWATER(pI830)) {
+         OUTREG(DSPBBASE, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
+      } else {
+         OUTREG(DSPBBASE, 0);
+         OUTREG(DSPBSURF, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
+      }
    }
 }
 
@@ -5665,7 +5973,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 == pI830->PointerMoved) ) {
       if (!I830Rotate(pScrn, mode))
          ret = FALSE;
    }
@@ -5701,7 +6009,7 @@ I830BIOSSaveScreen(ScreenPtr pScreen, in
    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
    I830Ptr pI830 = I830PTR(pScrn);
    Bool on = xf86IsUnblank(mode);
-   CARD32 temp, ctrl, base;
+   CARD32 temp, ctrl, base, surf;
 
    DPRINTF(PFX, "I830BIOSSaveScreen: %d, on is %s\n", mode, BOOLTOSTRING(on));
 
@@ -5709,9 +6017,11 @@ I830BIOSSaveScreen(ScreenPtr pScreen, in
       if (pI830->pipe == 0) {
 	 ctrl = DSPACNTR;
 	 base = DSPABASE;
+	 surf = DSPASURF;
       } else {
 	 ctrl = DSPBCNTR;
 	 base = DSPBADDR;
+	 surf = DSPBSURF;
       }
       if (pI830->planeEnabled[pI830->pipe]) {
 	 temp = INREG(ctrl);
@@ -5723,6 +6033,10 @@ I830BIOSSaveScreen(ScreenPtr pScreen, in
 	 /* Flush changes */
 	 temp = INREG(base);
 	 OUTREG(base, temp);
+	 if (IS_BROADWATER(pI830)) {
+            temp = INREG(surf);
+            OUTREG(surf, temp);
+         }
       }
 
       if (pI830->CursorInfoRec && !pI830->SWCursor && pI830->cursorOn) {
@@ -5841,7 +6155,7 @@ I830BIOSCloseScreen(int scrnIndex, Scree
    }
 
    if (I830IsPrimary(pScrn)) {
-      xf86GARTCloseScreen(scrnIndex);
+      I830GARTCloseScreen(scrnIndex);
 
       xfree(pI830->LpRing);
       pI830->LpRing = NULL;
@@ -5857,9 +6171,7 @@ I830BIOSCloseScreen(int scrnIndex, Scree
       pI830->used3D = NULL;
    }
 
-   if (pI830->shadowReq.minorversion >= 1)
-      pScrn->PointerMoved = pI830->PointerMoved;
-
+   pScrn->PointerMoved = pI830->PointerMoved;
    pScrn->vtSema = FALSE;
    pI830->closing = FALSE;
    pScreen->CloseScreen = pI830->CloseScreen;
@@ -6187,16 +6499,23 @@ I830CheckDevicesTimer(OsTimerPtr timer, 
             offset = pI8301->FrontBuffer2.Start + ((pScrn->frameY0 * pI830->displayWidth + pScrn->frameX0) * pI830->cpp);
 	 }
 
-         if (pI830->pipe == 0)
-            adjust = INREG(DSPABASE);
-         else 
-            adjust = INREG(DSPBBASE);
+         if (IS_BROADWATER(pI830)) {
+            if (pI830->pipe == 0)
+               adjust = INREG(DSPASURF);
+            else 
+               adjust = INREG(DSPBSURF);
+         } else {
+            if (pI830->pipe == 0)
+               adjust = INREG(DSPABASE);
+            else 
+               adjust = INREG(DSPBBASE);
+         }
 
          if (adjust != offset) {
             xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 			                       "Fixing display offsets.\n");
 
-            I830BIOSAdjustFrame(pScrn->pScreen->myNum, pScrn->frameX0, pScrn->frameY0, 0);
+            I830AdjustFrame(pScrn->pScreen->myNum, pScrn->frameX0, pScrn->frameY0, 0);
          }
       }
 
@@ -6221,7 +6540,7 @@ I830CheckDevicesTimer(OsTimerPtr timer, 
 
          pI830->currentMode = NULL;
          I830BIOSSwitchMode(pScrn->pScreen->myNum, pScrn->currentMode, 0);
-         I830BIOSAdjustFrame(pScrn->pScreen->myNum, pScrn->frameX0, pScrn->frameY0, 0);
+         I830AdjustFrame(pScrn->pScreen->myNum, pScrn->frameX0, pScrn->frameY0, 0);
 
          if (xf86IsEntityShared(pScrn->entityList[0])) {
 	    ScrnInfoPtr pScrn2;
@@ -6240,7 +6559,7 @@ I830CheckDevicesTimer(OsTimerPtr timer, 
 
             pI8302->currentMode = NULL;
             I830BIOSSwitchMode(pScrn2->pScreen->myNum, pScrn2->currentMode, 0);
-            I830BIOSAdjustFrame(pScrn2->pScreen->myNum, pScrn2->frameX0, pScrn2->frameY0, 0);
+            I830AdjustFrame(pScrn2->pScreen->myNum, pScrn2->frameX0, pScrn2->frameY0, 0);
 
  	    (*pScrn2->EnableDisableFBAccess) (pScrn2->pScreen->myNum, FALSE);
  	    (*pScrn2->EnableDisableFBAccess) (pScrn2->pScreen->myNum, TRUE);
@@ -6289,7 +6608,7 @@ I830InitpScrn(ScrnInfoPtr pScrn)
    pScrn->PreInit = I830BIOSPreInit;
    pScrn->ScreenInit = I830BIOSScreenInit;
    pScrn->SwitchMode = I830BIOSSwitchMode;
-   pScrn->AdjustFrame = I830BIOSAdjustFrame;
+   pScrn->AdjustFrame = I830AdjustFrame;
    pScrn->EnterVT = I830BIOSEnterVT;
    pScrn->LeaveVT = I830BIOSLeaveVT;
    pScrn->FreeScreen = I830BIOSFreeScreen;
diff --git a/src/i830_memory.c b/src/i830_memory.c
index 433aa47..e5c9215 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -210,10 +210,15 @@ AllocFromAGP(ScrnInfoPtr pScrn, I830MemR
 	 return 0;
 
       if (flags & NEED_PHYSICAL_ADDR) {
-	 result->Key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 2,
+	 result->Key = I830AllocateGARTMemory(pScrn->scrnIndex, size, 2,
 					      &(result->Physical));
       } else {
-	 result->Key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 0, NULL);
+         /* Due to a bug in agpgart in 2.6 kernels resulting in very poor
+	  * allocation performance we need to workaround it here...
+	  */
+	 result->Key = I830AllocateGARTMemory(pScrn->scrnIndex, size, 3, NULL);
+         if (result->Key == -1)
+	    result->Key = I830AllocateGARTMemory(pScrn->scrnIndex, size, 0, NULL);
       }
       if (result->Key == -1)
 	 return 0;
@@ -243,7 +248,7 @@ I830FreeVidMem(ScrnInfoPtr pScrn, I830Me
       return;
 
    if (range->Key != -1)
-      xf86DeallocateGARTMemory(pScrn->scrnIndex, range->Key);
+      I830DeallocateGARTMemory(pScrn->scrnIndex, range->Key);
 
    if (range->Pool) {
       /* 
@@ -498,7 +503,7 @@ I830AllocateRotatedBuffer(ScrnInfoPtr pS
    alloced = 0;
    if (tileable) {
       align = GetBestTileAlignment(size);
-      for (align = GetBestTileAlignment(size); align >= KB(512); align >>= 1) {
+      for (align = GetBestTileAlignment(size); align >= (IS_I9XX(pI830) ? MB(1) : KB(512)); align >>= 1) {
 	 alloced = I830AllocVidMem(pScrn, &(pI830->RotatedMem),
 				   &(pI830->StolenPool), size, align,
 				   flags | FROM_ANYWHERE | ALLOCATE_AT_TOP |
@@ -563,7 +568,7 @@ I830AllocateRotated2Buffer(ScrnInfoPtr p
    alloced = 0;
    if (tileable) {
       align = GetBestTileAlignment(size);
-      for (align = GetBestTileAlignment(size); align >= KB(512); align >>= 1) {
+      for (align = GetBestTileAlignment(size); align >= (IS_I9XX(pI830) ? MB(1) : KB(512)); align >>= 1) {
 	 alloced = I830AllocVidMem(pScrn, &(pI830->RotatedMem2),
 				   &(pI830->StolenPool), size, align,
 				   flags | FROM_ANYWHERE | ALLOCATE_AT_TOP |
@@ -630,7 +635,7 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, 
 	   BOOLTOSTRING(flags & ALLOC_INITIAL));
 
    if (!pI830->StolenOnly &&
-       (!xf86AgpGARTSupported() || !xf86AcquireGART(pScrn->scrnIndex))) {
+       (!I830AgpGARTSupported() || !I830AcquireGART(pScrn->scrnIndex))) {
       if (!dryrun) {
 	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 		    "AGP GART support is either not available or cannot "
@@ -673,6 +678,7 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, 
          memset(&(pI830->FrontBuffer2), 0, sizeof(pI830->FrontBuffer2));
          pI830->FrontBuffer2.Key = -1;
 
+#if 1 /* ROTATION */
          pI830->FbMemBox2.x1 = 0;
          pI830->FbMemBox2.x2 = pI830Ent->pScrn_2->displayWidth;
          pI830->FbMemBox2.y1 = 0;
@@ -680,6 +686,12 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, 
             pI830->FbMemBox2.y2 = pI830Ent->pScrn_2->virtualX;
          else
             pI830->FbMemBox2.y2 = pI830Ent->pScrn_2->virtualY;
+#else
+         pI830->FbMemBox2.x1 = 0;
+         pI830->FbMemBox2.x2 = pI830Ent->pScrn_2->displayWidth;
+         pI830->FbMemBox2.y1 = 0;
+         pI830->FbMemBox2.y2 = pI830Ent->pScrn_2->virtualY;
+#endif
 
          /*
           * Calculate how much framebuffer memory to allocate.  For the
@@ -731,19 +743,26 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, 
          tileable = !(flags & ALLOC_NO_TILING) && pI8302->allowPageFlip &&
 		 IsTileable(pI830Ent->pScrn_2->displayWidth * pI8302->cpp);
          if (tileable) {
-	    align = KB(512);
+            if (IS_I9XX(pI830))
+               align = MB(1);
+            else
+	       align = KB(512);
 	    alignflags = ALIGN_BOTH_ENDS;
          } else {
 	    align = KB(64);
 	    alignflags = 0;
          }
 
+#if 1 /* ROTATION */
          if (pI830Ent->pScrn_2->virtualX > pI830Ent->pScrn_2->virtualY)
             size = lineSize * (pI830Ent->pScrn_2->virtualX + cacheLines);
          else 
             size = lineSize * (pI830Ent->pScrn_2->virtualY + cacheLines);
          size = ROUND_TO_PAGE(size);
-
+#else
+         size = lineSize * (pI830Ent->pScrn_2->virtualY + cacheLines);
+         size = ROUND_TO_PAGE(size);
+#endif
          xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
 		     "%sSecondary framebuffer allocation size: %ld kByte\n", s,
 		     size / 1024);
@@ -765,6 +784,7 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, 
       memset(&(pI830->FrontBuffer), 0, sizeof(pI830->FrontBuffer));
       pI830->FrontBuffer.Key = -1;
 
+#if 1 /* ROTATION */
       pI830->FbMemBox.x1 = 0;
       pI830->FbMemBox.x2 = pScrn->displayWidth;
       pI830->FbMemBox.y1 = 0;
@@ -772,6 +792,12 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, 
          pI830->FbMemBox.y2 = pScrn->virtualX;
       else
          pI830->FbMemBox.y2 = pScrn->virtualY;
+#else
+      pI830->FbMemBox.x1 = 0;
+      pI830->FbMemBox.x2 = pScrn->displayWidth;
+      pI830->FbMemBox.y1 = 0;
+      pI830->FbMemBox.y2 = pScrn->virtualY;
+#endif
 
       /*
        * Calculate how much framebuffer memory to allocate.  For the
@@ -823,19 +849,26 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, 
       tileable = !(flags & ALLOC_NO_TILING) && pI830->allowPageFlip &&
 		 IsTileable(pScrn->displayWidth * pI830->cpp);
       if (tileable) {
-	 align = KB(512);
+         if (IS_I9XX(pI830))
+            align = MB(1);
+         else
+	    align = KB(512);
 	 alignflags = ALIGN_BOTH_ENDS;
       } else {
 	 align = KB(64);
 	 alignflags = 0;
       }
 
+#if 1 /* ROTATION */
       if (pScrn->virtualX > pScrn->virtualY)
          size = lineSize * (pScrn->virtualX + cacheLines);
       else 
          size = lineSize * (pScrn->virtualY + cacheLines);
       size = ROUND_TO_PAGE(size);
-
+#else
+      size = lineSize * (pScrn->virtualY + cacheLines);
+      size = ROUND_TO_PAGE(size);
+#endif
       xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
 		     "%sInitial framebuffer allocation size: %ld kByte\n", s,
 		     size / 1024);
@@ -909,7 +942,10 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, 
 	 tileable = !(flags & ALLOC_NO_TILING) && pI830->allowPageFlip &&
 		 IsTileable(pScrn->displayWidth * pI830->cpp);
 	 if (tileable) {
-	    align = KB(512);
+            if (IS_I9XX(pI830))
+               align = MB(1);
+            else
+	       align = KB(512);
 	    alignflags = ALIGN_BOTH_ENDS;
 	 } else {
 	    align = KB(64);
@@ -937,7 +973,13 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, 
     */
    if (!dryrun) {
       memset(&(pI830->Dummy), 0, sizeof(pI830->Dummy));
-      pI830->Dummy.Key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 0, NULL);
+      /* Due to a bug in agpgart in 2.6 kernels resulting in very poor
+       * allocation performance we need to workaround it here...
+       */
+      pI830->Dummy.Key = 
+           I830AllocateGARTMemory(pScrn->scrnIndex, size, 3, NULL);
+      if (pI830->Dummy.Key == -1)
+         pI830->Dummy.Key = I830AllocateGARTMemory(pScrn->scrnIndex, size, 0, NULL);
       pI830->Dummy.Offset = 0;
    }
 #endif
@@ -1147,7 +1189,7 @@ I830AllocateBackBuffer(ScrnInfoPtr pScrn
    alloced = 0;
    if (tileable) {
       align = GetBestTileAlignment(size);
-      for (align = GetBestTileAlignment(size); align >= KB(512); align >>= 1) {
+      for (align = GetBestTileAlignment(size); align >= (IS_I9XX(pI830) ? MB(1) : KB(512)); align >>= 1) {
 	 alloced = I830AllocVidMem(pScrn, &(pI830->BackBuffer),
 				   &(pI830->StolenPool), size, align,
 				   flags | FROM_ANYWHERE | ALLOCATE_AT_TOP |
@@ -1210,7 +1252,7 @@ I830AllocateDepthBuffer(ScrnInfoPtr pScr
    alloced = 0;
    if (tileable) {
       align = GetBestTileAlignment(size);
-      for (align = GetBestTileAlignment(size); align >= KB(512); align >>= 1) {
+      for (align = GetBestTileAlignment(size); align >= (IS_I9XX(pI830) ? MB(1) : KB(512)); align >>= 1) {
 	 alloced = I830AllocVidMem(pScrn, &(pI830->DepthBuffer),
 				   &(pI830->StolenPool), size, align,
 				   flags | FROM_ANYWHERE | ALLOCATE_AT_TOP |
@@ -1357,7 +1399,14 @@ I830DoPoolAllocation(ScrnInfoPtr pScrn, 
 
    if (pool->Total.Size > pool->Fixed.Size) {
       pool->Allocated.Size = pool->Total.Size - pool->Fixed.Size;
-      pool->Allocated.Key = xf86AllocateGARTMemory(pScrn->scrnIndex, 
+      /* Due to a bug in agpgart in 2.6 kernels resulting in very poor
+       * allocation performance we need to workaround it here...
+       */
+      pool->Allocated.Key = 
+           I830AllocateGARTMemory(pScrn->scrnIndex, pool->Allocated.Size,
+				   3, NULL);
+      if (pool->Allocated.Key == -1)
+         pool->Allocated.Key = I830AllocateGARTMemory(pScrn->scrnIndex, 
 				   pool->Allocated.Size, 0, NULL);
       if (pool->Allocated.Key == -1) {
 	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Pool allocation failed\n");
@@ -1644,7 +1693,7 @@ SetFence(ScrnInfoPtr pScrn, int nr, unsi
 }
 
 static Bool
-MakeTiles(ScrnInfoPtr pScrn, I830MemRange *pMem)
+MakeTiles(ScrnInfoPtr pScrn, I830MemRange *pMem, unsigned int fence)
 {
    I830Ptr pI830 = I830PTR(pScrn);
    int pitch, ntiles, i;
@@ -1662,6 +1711,31 @@ MakeTiles(ScrnInfoPtr pScrn, I830MemRang
    }
 
    pitch = pScrn->displayWidth * pI830->cpp;
+
+   if (IS_BROADWATER(pI830)) {
+      I830RegPtr i830Reg = &pI830->ModeReg;
+
+      switch (fence) {
+         case FENCE_XMAJOR:
+            i830Reg->Fence[nextTile] = (((pitch / 128) - 1) << 2) | pMem->Start | 1;
+            break;
+         case FENCE_YMAJOR:
+            /* YMajor can be 128B aligned but the current code dictates
+             * otherwise. This isn't a problem apart from memory waste.
+             * FIXME */
+            i830Reg->Fence[nextTile] = (((pitch / 128) - 1) << 2) | pMem->Start | 1;
+	    i830Reg->Fence[nextTile] |= (1<<1);
+            break;
+         default:
+         case FENCE_LINEAR:
+            break;
+      }
+
+      i830Reg->Fence[nextTile+FENCE_NEW_NR] = pMem->End;
+      nextTile++;
+      return TRUE;
+   }
+
    /*
     * Simply try to break the region up into at most four pieces of size
     * equal to the alignment.
@@ -1703,20 +1777,27 @@ I830SetupMemoryTiling(ScrnInfoPtr pScrn)
       return;
    }
 
+   pI830->front_tiled = FENCE_LINEAR;
+   pI830->back_tiled = FENCE_LINEAR;
+   pI830->depth_tiled = FENCE_LINEAR;
+   pI830->rotated_tiled = FENCE_LINEAR;
+   pI830->rotated2_tiled = FENCE_LINEAR;
+
    if (pI830->allowPageFlip) {
       if (pI830->allowPageFlip && pI830->FrontBuffer.Alignment >= KB(512)) {
-	 if (MakeTiles(pScrn, &(pI830->FrontBuffer))) {
+	 if (MakeTiles(pScrn, &(pI830->FrontBuffer), FENCE_XMAJOR)) {
 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-		       "Activating tiled memory for the FRONT buffer\n");
+		       "Activating tiled memory for the front buffer\n");
+            pI830->front_tiled = FENCE_XMAJOR;
 	 } else {
 	    pI830->allowPageFlip = FALSE;
 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-		       "MakeTiles failed for the FRONT buffer\n");
+		       "MakeTiles failed for the front buffer\n");
 	 }
       } else {
 	 pI830->allowPageFlip = FALSE;
 	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-		 "Alignment bad for the FRONT buffer\n");
+		 "Alignment bad for the front buffer\n");
       }
    }
 
@@ -1727,9 +1808,10 @@ I830SetupMemoryTiling(ScrnInfoPtr pScrn)
     * value.
     */
    if (pI830->BackBuffer.Alignment >= KB(512)) {
-      if (MakeTiles(pScrn, &(pI830->BackBuffer))) {
+      if (MakeTiles(pScrn, &(pI830->BackBuffer), FENCE_XMAJOR)) {
 	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 		    "Activating tiled memory for the back buffer.\n");
+         pI830->back_tiled = FENCE_XMAJOR;
       } else {
 	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 		    "MakeTiles failed for the back buffer.\n");
@@ -1738,9 +1820,10 @@ I830SetupMemoryTiling(ScrnInfoPtr pScrn)
    }
 
    if (pI830->DepthBuffer.Alignment >= KB(512)) {
-      if (MakeTiles(pScrn, &(pI830->DepthBuffer))) {
+      if (MakeTiles(pScrn, &(pI830->DepthBuffer), FENCE_YMAJOR)) {
 	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-		    "Activating tiled memory for the depth buffer.\n");
+	 	    "Activating tiled memory for the depth buffer.\n");
+         pI830->depth_tiled = FENCE_YMAJOR;
       } else {
 	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 		    "MakeTiles failed for the depth buffer.\n");
@@ -1748,9 +1831,10 @@ I830SetupMemoryTiling(ScrnInfoPtr pScrn)
    }
 	
    if (pI830->RotatedMem.Alignment >= KB(512)) {
-      if (MakeTiles(pScrn, &(pI830->RotatedMem))) {
+      if (MakeTiles(pScrn, &(pI830->RotatedMem), FENCE_XMAJOR)) {
 	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 		    "Activating tiled memory for the rotated buffer.\n");
+         pI830->rotated_tiled = FENCE_XMAJOR;
       } else {
 	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 		    "MakeTiles failed for the rotated buffer.\n");
@@ -1759,9 +1843,10 @@ I830SetupMemoryTiling(ScrnInfoPtr pScrn)
 
 #if 0
    if (pI830->RotatedMem2.Alignment >= KB(512)) {
-      if (MakeTiles(pScrn, &(pI830->RotatedMem2))) {
+      if (MakeTiles(pScrn, &(pI830->RotatedMem2), FENCE_XMAJOR)) {
 	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 		    "Activating tiled memory for the rotated2 buffer.\n");
+         pI830->rotated2_tiled = FENCE_XMAJOR;
       } else {
 	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 		    "MakeTiles failed for the rotated buffer.\n");
@@ -1780,7 +1865,7 @@ BindMemRange(ScrnInfoPtr pScrn, I830MemR
    if (mem->Key == -1)
       return TRUE;
 
-   return xf86BindGARTMemory(pScrn->scrnIndex, mem->Key, mem->Offset);
+   return I830BindGARTMemory(pScrn->scrnIndex, mem->Key, mem->Offset);
 }
 
 Bool
@@ -1795,8 +1880,8 @@ I830BindAGPMemory(ScrnInfoPtr pScrn)
    if (pI830->StolenOnly == TRUE)
       return TRUE;
 
-   if (xf86AgpGARTSupported() && !pI830->GttBound) {
-      if (!xf86AcquireGART(pScrn->scrnIndex))
+   if (I830AgpGARTSupported() && !pI830->GttBound) {
+      if (!I830AcquireGART(pScrn->scrnIndex))
 	 return FALSE;
 
 #if REMAP_RESERVED
@@ -1865,7 +1950,7 @@ UnbindMemRange(ScrnInfoPtr pScrn, I830Me
    if (mem->Key == -1)
       return TRUE;
 
-   return xf86UnbindGARTMemory(pScrn->scrnIndex, mem->Key);
+   return I830UnbindGARTMemory(pScrn->scrnIndex, mem->Key);
 }
 
 
@@ -1881,7 +1966,7 @@ I830UnbindAGPMemory(ScrnInfoPtr pScrn)
    if (pI830->StolenOnly == TRUE)
       return TRUE;
 
-   if (xf86AgpGARTSupported() && pI830->GttBound) {
+   if (I830AgpGARTSupported() && pI830->GttBound) {
 
 #if REMAP_RESERVED
       /* "unbind" the pre-allocated region. */
@@ -1934,7 +2019,7 @@ I830UnbindAGPMemory(ScrnInfoPtr pScrn)
 	    return FALSE;
       }
 #endif
-      if (!xf86ReleaseGART(pScrn->scrnIndex))
+      if (!I830ReleaseGART(pScrn->scrnIndex))
 	 return FALSE;
 
       pI830->GttBound = 0;
@@ -1949,10 +2034,10 @@ I830CheckAvailableMemory(ScrnInfoPtr pSc
    AgpInfoPtr agpinf;
    int maxPages;
 
-   if (!xf86AgpGARTSupported() ||
-       !xf86AcquireGART(pScrn->scrnIndex) ||
-       (agpinf = xf86GetAGPInfo(pScrn->scrnIndex)) == NULL ||
-       !xf86ReleaseGART(pScrn->scrnIndex))
+   if (!I830AgpGARTSupported() ||
+       !I830AcquireGART(pScrn->scrnIndex) ||
+       (agpinf = I830GetAGPInfo(pScrn->scrnIndex)) == NULL ||
+       !I830ReleaseGART(pScrn->scrnIndex))
       return -1;
 
    maxPages = agpinf->totalPages - agpinf->usedPages;
diff --git a/src/i830_rotate.c b/src/i830_rotate.c
index e4a8064..9c91cc4 100644
--- a/src/i830_rotate.c
+++ b/src/i830_rotate.c
@@ -680,13 +680,10 @@ I830Rotate(ScrnInfoPtr pScrn, DisplayMod
 	 0
    };
 
-   if (pI830->noAccel)
-	   func = LoaderSymbol("shadowUpdateRotatePacked");
+   if (IS_I9XX(pI830))
+      func = I915UpdateRotate;
    else
-	   if (IS_I9XX(pI830))
-		   func = I915UpdateRotate;
-	   else
-		   func = I830UpdateRotate;
+      func = I830UpdateRotate;
 
    if (I830IsPrimary(pScrn)) {
       pI8301 = pI830;
@@ -702,7 +699,13 @@ I830Rotate(ScrnInfoPtr pScrn, DisplayMod
       pScrn2 = pScrn;
    }
 
-   pI830->rotation = I830GetRotation(pScrn->pScreen);
+   if (xf86LoaderCheckSymbol("I830GetRotation")) {
+      Rotation (*I830GetRotation)(ScreenPtr pScreen) = NULL;
+      I830GetRotation = LoaderSymbol("I830GetRotation");
+      if (I830GetRotation) {
+         pI830->rotation = (*I830GetRotation)(pScrn->pScreen);
+      }
+   }   
 
    /* Check if we've still got the same orientation, or same mode */
    if (pI830->rotation == oldRotation && pI830->currentMode == mode)
@@ -716,6 +719,7 @@ I830Rotate(ScrnInfoPtr pScrn, DisplayMod
     * We grab the DRI lock when reallocating buffers to avoid DRI clients
     * getting bogus information.
     */
+
 #ifdef XF86DRI
    if (pI8301->directRenderingEnabled && reAllocate) {
       didLock = I830DRILock(pScrn1);
@@ -734,18 +738,19 @@ I830Rotate(ScrnInfoPtr pScrn, DisplayMod
 	 }
       }
       
+      
       if (pI8301->TexMem.Key != -1)
-         xf86UnbindGARTMemory(pScrn1->scrnIndex, pI8301->TexMem.Key);
+         I830UnbindGARTMemory(pScrn1->scrnIndex, pI8301->TexMem.Key);
       I830FreeVidMem(pScrn1, &(pI8301->TexMem));
       if (pI8301->StolenPool.Allocated.Key != -1) {
-         xf86UnbindGARTMemory(pScrn1->scrnIndex, pI8301->StolenPool.Allocated.Key);
-         xf86DeallocateGARTMemory(pScrn1->scrnIndex, pI8301->StolenPool.Allocated.Key);
+         I830UnbindGARTMemory(pScrn1->scrnIndex, pI8301->StolenPool.Allocated.Key);
+         I830DeallocateGARTMemory(pScrn1->scrnIndex, pI8301->StolenPool.Allocated.Key);
       }
       if (pI8301->DepthBuffer.Key != -1)
-         xf86UnbindGARTMemory(pScrn1->scrnIndex, pI8301->DepthBuffer.Key);
+         I830UnbindGARTMemory(pScrn1->scrnIndex, pI8301->DepthBuffer.Key);
       I830FreeVidMem(pScrn1, &(pI8301->DepthBuffer));
       if (pI8301->BackBuffer.Key != -1)
-         xf86UnbindGARTMemory(pScrn1->scrnIndex, pI8301->BackBuffer.Key);
+         I830UnbindGARTMemory(pScrn1->scrnIndex, pI8301->BackBuffer.Key);
       I830FreeVidMem(pScrn1, &(pI8301->BackBuffer));
    }
 #endif
@@ -754,7 +759,7 @@ I830Rotate(ScrnInfoPtr pScrn, DisplayMod
       *pI830->used3D |= 1<<31; /* use high bit to denote new rotation occured */
 
       if (pI8301->RotatedMem.Key != -1)
-         xf86UnbindGARTMemory(pScrn1->scrnIndex, pI8301->RotatedMem.Key);
+         I830UnbindGARTMemory(pScrn1->scrnIndex, pI8301->RotatedMem.Key);
  
       I830FreeVidMem(pScrn1, &(pI8301->RotatedMem));
       memset(&(pI8301->RotatedMem), 0, sizeof(pI8301->RotatedMem));
@@ -762,7 +767,7 @@ I830Rotate(ScrnInfoPtr pScrn, DisplayMod
 
       if (pI830->entityPrivate) {
          if (pI8301->RotatedMem2.Key != -1)
-            xf86UnbindGARTMemory(pScrn1->scrnIndex, pI8301->RotatedMem2.Key);
+            I830UnbindGARTMemory(pScrn1->scrnIndex, pI8301->RotatedMem2.Key);
  
          I830FreeVidMem(pScrn1, &(pI8301->RotatedMem2));
          memset(&(pI8301->RotatedMem2), 0, sizeof(pI8301->RotatedMem2));
@@ -830,26 +835,27 @@ I830Rotate(ScrnInfoPtr pScrn, DisplayMod
 
             I830FixOffset(pScrn1, &(pI8301->RotatedMem2));
             if (pI8301->RotatedMem2.Key != -1)
-               xf86BindGARTMemory(pScrn1->scrnIndex, pI8301->RotatedMem2.Key, pI8301->RotatedMem2.Offset);
+               I830BindGARTMemory(pScrn1->scrnIndex, pI8301->RotatedMem2.Key, pI8301->RotatedMem2.Offset);
          }
       }
 
       if (pI8301->rotation != RR_Rotate_0) {
          if (!I830AllocateRotatedBuffer(pScrn1, 
-			      (pI8301->disableTiling ? ALLOC_NO_TILING : 0)))
+			      pI8301->disableTiling ? ALLOC_NO_TILING : 0))
             goto BAIL1;
 
          I830FixOffset(pScrn1, &(pI8301->RotatedMem));
          if (pI8301->RotatedMem.Key != -1)
-            xf86BindGARTMemory(pScrn1->scrnIndex, pI8301->RotatedMem.Key, pI8301->RotatedMem.Offset);
+            I830BindGARTMemory(pScrn1->scrnIndex, pI8301->RotatedMem.Key, pI8301->RotatedMem.Offset);
       }
    }
    
-   shadowRemove (pScrn->pScreen, NULL);
+   I830shadowUnset (pScrn->pScreen);
    if (pI830->rotation != RR_Rotate_0)
-      shadowAdd (pScrn->pScreen, 
+      I830shadowSet (pScrn->pScreen, 
                     (*pScrn->pScreen->GetScreenPixmap) (pScrn->pScreen), 
-                    func, I830WindowLinear, pI830->rotation, 0);
+		    pI830->noAccel ? I830shadowUpdateRotatePacked : func, 
+                    I830WindowLinear, pI830->rotation, 0);
 
    if (I830IsPrimary(pScrn)) {
       if (pI830->rotation != RR_Rotate_0)
@@ -896,13 +902,13 @@ I830Rotate(ScrnInfoPtr pScrn, DisplayMod
       I830FixOffset(pScrn1, &(pI8301->DepthBuffer));
 
       if (pI8301->BackBuffer.Key != -1)
-         xf86BindGARTMemory(pScrn1->scrnIndex, pI8301->BackBuffer.Key, pI8301->BackBuffer.Offset);
+         I830BindGARTMemory(pScrn1->scrnIndex, pI8301->BackBuffer.Key, pI8301->BackBuffer.Offset);
       if (pI8301->DepthBuffer.Key != -1)
-         xf86BindGARTMemory(pScrn1->scrnIndex, pI8301->DepthBuffer.Key, pI8301->DepthBuffer.Offset);
+         I830BindGARTMemory(pScrn1->scrnIndex, pI8301->DepthBuffer.Key, pI8301->DepthBuffer.Offset);
       if (pI8301->StolenPool.Allocated.Key != -1)
-         xf86BindGARTMemory(pScrn1->scrnIndex, pI8301->StolenPool.Allocated.Key, pI8301->StolenPool.Allocated.Offset);
+         I830BindGARTMemory(pScrn1->scrnIndex, pI8301->StolenPool.Allocated.Key, pI8301->StolenPool.Allocated.Offset);
       if (pI8301->TexMem.Key != -1)
-         xf86BindGARTMemory(pScrn1->scrnIndex, pI8301->TexMem.Key, pI8301->TexMem.Offset);
+         I830BindGARTMemory(pScrn1->scrnIndex, pI8301->TexMem.Key, pI8301->TexMem.Offset);
       I830SetupMemoryTiling(pScrn1);
       /* update fence registers */
       for (i = 0; i < 8; i++) 
@@ -990,7 +996,7 @@ BAIL3:
 BAIL2:
    if (pI8301->rotation != RR_Rotate_0) {
       if (pI8301->RotatedMem.Key != -1)
-         xf86UnbindGARTMemory(pScrn1->scrnIndex, pI8301->RotatedMem.Key);
+         I830UnbindGARTMemory(pScrn1->scrnIndex, pI8301->RotatedMem.Key);
   
       I830FreeVidMem(pScrn1, &(pI8301->RotatedMem));
       memset(&(pI8301->RotatedMem), 0, sizeof(pI8301->RotatedMem));
@@ -1000,7 +1006,7 @@ BAIL1:
    if (pI830->entityPrivate) {
       if (pI8302->rotation != RR_Rotate_0) {
          if (pI8301->RotatedMem.Key != -1)
-            xf86UnbindGARTMemory(pScrn1->scrnIndex, pI8301->RotatedMem.Key);
+            I830UnbindGARTMemory(pScrn1->scrnIndex, pI8301->RotatedMem.Key);
 
          I830FreeVidMem(pScrn1, &(pI8301->RotatedMem));
          memset(&(pI8301->RotatedMem), 0, sizeof(pI8301->RotatedMem));
@@ -1039,26 +1045,27 @@ BAIL0:
 
          I830FixOffset(pScrn1, &(pI8301->RotatedMem2));
          if (pI8301->RotatedMem2.Key != -1)
-            xf86BindGARTMemory(pScrn1->scrnIndex, pI8301->RotatedMem2.Key, pI8301->RotatedMem2.Offset);
+            I830BindGARTMemory(pScrn1->scrnIndex, pI8301->RotatedMem2.Key, pI8301->RotatedMem2.Offset);
       }
    }
 
    if (pI8301->rotation != RR_Rotate_0) {
       if (!I830AllocateRotatedBuffer(pScrn1, 
-			      (pI8301->disableTiling ? ALLOC_NO_TILING : 0)))
+			      pI8301->disableTiling ? ALLOC_NO_TILING : 0))
          xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
 		    "Oh dear, the rotated buffer failed - badness\n");
 
       I830FixOffset(pScrn1, &(pI8301->RotatedMem));
       if (pI8301->RotatedMem.Key != -1)
-         xf86BindGARTMemory(pScrn1->scrnIndex, pI8301->RotatedMem.Key, pI8301->RotatedMem.Offset);
+         I830BindGARTMemory(pScrn1->scrnIndex, pI8301->RotatedMem.Key, pI8301->RotatedMem.Offset);
    }
 
-   shadowRemove (pScrn->pScreen, NULL);
+   I830shadowUnset (pScrn->pScreen);
    if (pI830->rotation != RR_Rotate_0)
-      shadowAdd (pScrn->pScreen, 
+      I830shadowSet (pScrn->pScreen, 
                     (*pScrn->pScreen->GetScreenPixmap) (pScrn->pScreen), 
-                    func, I830WindowLinear, pI830->rotation, 0);
+		    pI830->noAccel ? I830shadowUpdateRotatePacked : func, 
+                    I830WindowLinear, pI830->rotation, 0);
 
    if (I830IsPrimary(pScrn)) {
       if (pI830->rotation != RR_Rotate_0)
@@ -1130,13 +1137,13 @@ BAIL0:
       I830FixOffset(pScrn1, &(pI8301->DepthBuffer));
 
       if (pI8301->BackBuffer.Key != -1)
-         xf86BindGARTMemory(pScrn1->scrnIndex, pI8301->BackBuffer.Key, pI8301->BackBuffer.Offset);
+         I830BindGARTMemory(pScrn1->scrnIndex, pI8301->BackBuffer.Key, pI8301->BackBuffer.Offset);
       if (pI8301->DepthBuffer.Key != -1)
-         xf86BindGARTMemory(pScrn1->scrnIndex, pI8301->DepthBuffer.Key, pI8301->DepthBuffer.Offset);
+         I830BindGARTMemory(pScrn1->scrnIndex, pI8301->DepthBuffer.Key, pI8301->DepthBuffer.Offset);
       if (pI8301->StolenPool.Allocated.Key != -1)
-         xf86BindGARTMemory(pScrn1->scrnIndex, pI8301->StolenPool.Allocated.Key, pI8301->StolenPool.Allocated.Offset);
+         I830BindGARTMemory(pScrn1->scrnIndex, pI8301->StolenPool.Allocated.Key, pI8301->StolenPool.Allocated.Offset);
       if (pI8301->TexMem.Key != -1)
-         xf86BindGARTMemory(pScrn1->scrnIndex, pI8301->TexMem.Key, pI8301->TexMem.Offset);
+         I830BindGARTMemory(pScrn1->scrnIndex, pI8301->TexMem.Key, pI8301->TexMem.Offset);
       I830SetupMemoryTiling(pScrn1);
       /* update fence registers */
       for (i = 0; i < 8; i++) 
diff --git a/src/i830_video.c b/src/i830_video.c
index a608a7e..8ae1906 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -1,4 +1,4 @@
-#define VIDEO_DEBUG 0
+#define VIDEO_DEBUG 1
 /***************************************************************************
  
 Copyright 2000 Intel Corporation.  All Rights Reserved. 
@@ -120,9 +120,9 @@ static Atom xvBrightness, xvContrast, xv
 static Atom xvGamma0, xvGamma1, xvGamma2, xvGamma3, xvGamma4, xvGamma5;
 
 #define IMAGE_MAX_WIDTH		1920
-#define IMAGE_MAX_HEIGHT	1088
+#define IMAGE_MAX_HEIGHT	1080
 #define IMAGE_MAX_WIDTH_LEGACY	1024
-#define IMAGE_MAX_HEIGHT_LEGACY	1088
+#define IMAGE_MAX_HEIGHT_LEGACY	1080
 
 #if !VIDEO_DEBUG
 #define ErrorF Edummy
@@ -157,7 +157,7 @@ Edummy(const char *dummy, ...)
 	 OUT_RING(MI_NOOP);						\
 	 OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_CONTINUE);		\
       }									\
-      OUT_RING(pI830->OverlayMem->Physical | OFC_UPDATE); 		\
+      OUT_RING(pI830->OverlayMem->Start | OFC_UPDATE); 		\
       ADVANCE_LP_RING();						\
       ErrorF("OVERLAY_UPDATE\n");					\
    } while(0)
@@ -172,11 +172,11 @@ Edummy(const char *dummy, ...)
 	 OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);	\
 	 OUT_RING(MI_NOOP);						\
 	 OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_CONTINUE);		\
-         OUT_RING(pI830->OverlayMem->Physical | OFC_UPDATE); 		\
+         OUT_RING(pI830->OverlayMem->Start | OFC_UPDATE); 		\
 	 OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);	\
 	 OUT_RING(MI_NOOP);						\
 	 OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_OFF);		\
-         OUT_RING(pI830->OverlayMem->Physical | OFC_UPDATE); 		\
+         OUT_RING(pI830->OverlayMem->Start | OFC_UPDATE); 		\
 	 OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);	\
 	 OUT_RING(MI_NOOP);						\
 	 ADVANCE_LP_RING();						\
@@ -334,18 +334,18 @@ typedef struct {
    CARD32 OCONFIG;
    CARD32 OCMD;
    CARD32 RESERVED1;			/* 0x6C */
-   CARD32 AWINPOS;
-   CARD32 AWINSZ;
-   CARD32 RESERVED2;			/* 0x78 */
-   CARD32 RESERVED3;			/* 0x7C */
-   CARD32 RESERVED4;			/* 0x80 */
-   CARD32 RESERVED5;			/* 0x84 */
-   CARD32 RESERVED6;			/* 0x88 */
-   CARD32 RESERVED7;			/* 0x8C */
-   CARD32 RESERVED8;			/* 0x90 */
-   CARD32 RESERVED9;			/* 0x94 */
-   CARD32 RESERVEDA;			/* 0x98 */
-   CARD32 RESERVEDB;			/* 0x9C */
+   CARD32 OSTART_0Y; 		/* for broadwater */
+   CARD32 OSTART_1Y;		/* for broadwater */
+   CARD32 OSTART_0U;
+   CARD32 OSTART_0V;
+   CARD32 OSTART_1U;
+   CARD32 OSTART_1V;
+   CARD32 OTILEOFF_0Y;
+   CARD32 OTILEOFF_1Y;
+   CARD32 OTILEOFF_0U;
+   CARD32 OTILEOFF_0V;
+   CARD32 OTILEOFF_1U;
+   CARD32 OTILEOFF_1V;
    CARD32 FASTHSCALE;			/* 0xA0 */
    CARD32 UVSCALEV;			/* 0xA4 */
 
@@ -501,8 +501,10 @@ I830ResetVideo(ScrnInfoPtr pScrn)
    overlay->SHEIGHT = 0;
    overlay->OCLRC0 = (pPriv->contrast << 18) | (pPriv->brightness & 0xff);
    overlay->OCLRC1 = 0x00000080;	/* saturation: bypass */
+#if 0
    overlay->AWINPOS = 0;
    overlay->AWINSZ = 0;
+#endif
    overlay->FASTHSCALE = 0;
 
    /*
@@ -1647,14 +1649,31 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int 
 			dstBox->x2, dstBox->y2);
 
    /* buffer locations */
-   overlay->OBUF_0Y = pPriv->YBuf0offset;
-   overlay->OBUF_0U = pPriv->UBuf0offset;
-   overlay->OBUF_0V = pPriv->VBuf0offset;
-
-   if(pPriv->doubleBuffer) {
-      overlay->OBUF_1Y = pPriv->YBuf1offset;
-      overlay->OBUF_1U = pPriv->UBuf1offset;
-      overlay->OBUF_1V = pPriv->VBuf1offset;
+   if (IS_BROADWATER(pI830))
+   {
+      overlay->OBUF_0Y = 0;
+      overlay->OBUF_0U = 0;
+      overlay->OBUF_0V = 0;
+      overlay->OSTART_0Y = pPriv->YBuf0offset;
+      overlay->OSTART_0U = pPriv->UBuf0offset;
+      overlay->OSTART_0V = pPriv->VBuf0offset;
+      if(pPriv->doubleBuffer) {
+         overlay->OBUF_1Y = 0;
+         overlay->OBUF_1U = 0;
+         overlay->OBUF_1V = 0;
+         overlay->OSTART_1Y = pPriv->YBuf1offset;
+         overlay->OSTART_1U = pPriv->UBuf1offset;
+         overlay->OSTART_1V = pPriv->VBuf1offset;
+      }
+   } else {
+      overlay->OBUF_0Y = pPriv->YBuf0offset;
+      overlay->OBUF_0U = pPriv->UBuf0offset;
+      overlay->OBUF_0V = pPriv->VBuf0offset;
+      if(pPriv->doubleBuffer) {
+         overlay->OBUF_1Y = pPriv->YBuf1offset;
+         overlay->OBUF_1U = pPriv->UBuf1offset;
+         overlay->OBUF_1V = pPriv->VBuf1offset;
+      }
    }
 
    ErrorF("Buffers: Y0: 0x%lx, U0: 0x%lx, V0: 0x%lx\n", overlay->OBUF_0Y,
@@ -1967,10 +1986,10 @@ I830PutImage(ScrnInfoPtr pScrn,
       }
 #else
       if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
-         dstPitch = ((height / 2) + 511) & ~511;
+         dstPitch = ((height / 2) + 255) & ~255;
          size = dstPitch * width * 3;
       } else {
-         dstPitch = ((width / 2) + 511) & ~511;	/* of chroma */
+         dstPitch = ((width / 2) + 255) & ~255;	/* of chroma */
          size = dstPitch * height * 3;
       }
 #endif
@@ -1989,10 +2008,10 @@ I830PutImage(ScrnInfoPtr pScrn,
       }
 #else
       if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
-         dstPitch = ((height << 1) + 511) & ~511;
+         dstPitch = ((height << 1) + 255) & ~255;
          size = dstPitch * width;
       } else {
-         dstPitch = ((width << 1) + 511) & ~511;	/* of chroma */
+         dstPitch = ((width << 1) + 255) & ~255;	/* of chroma */
          size = dstPitch * height;
       }
 #endif
@@ -2008,7 +2027,11 @@ I830PutImage(ScrnInfoPtr pScrn,
       return BadAlloc;
 
    /* fixup pointers */
+#if 0
+   pPriv->YBuf0offset = pScrn->fbOffset + pPriv->linear->offset * pI830->cpp;
+#else
    pPriv->YBuf0offset = pI830->FrontBuffer.Start + pPriv->linear->offset * pI830->cpp;
+#endif
    if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
       pPriv->UBuf0offset = pPriv->YBuf0offset + (dstPitch * 2 * width);
       pPriv->VBuf0offset = pPriv->UBuf0offset + (dstPitch * width / 2);
@@ -2180,7 +2203,11 @@ I830BlockHandler(int i,
    pScreen->BlockHandler = I830BlockHandler;
 
    if (pPriv->videoStatus & TIMER_MASK) {
+#if 1
       Time now = currentTime.milliseconds;
+#else
+      UpdateCurrentTime();
+#endif
       if (pPriv->videoStatus & OFF_TIMER) {
 	 if (pPriv->offTime < now) {
 	    /* Turn off the overlay */
@@ -2280,7 +2307,11 @@ I830AllocateSurface(ScrnInfoPtr pScrn,
    surface->offsets[0] = linear->offset * bpp;
    surface->devPrivate.ptr = (pointer) pPriv;
 
+#if 0
+   memset(pI830->FbBase + pScrn->fbOffset + surface->offsets[0], 0, size);
+#else
    memset(pI830->FbBase + pI830->FrontBuffer.Start + surface->offsets[0], 0, size);
+#endif
 
    return Success;
 }
@@ -2526,27 +2557,29 @@ I830VideoSwitchModeAfter(ScrnInfoPtr pSc
       }
    }
 
-   if (pPriv->pipe == 0) {
-      if (INREG(PIPEACONF) & PIPEACONF_DOUBLE_WIDE) {
-         xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-	   "Disabling XVideo output because Pipe A is in double-wide mode.\n");
-         pPriv->overlayOK = FALSE;
-      } else if (!pPriv->overlayOK) {
-         xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-	   "Re-enabling XVideo output because Pipe A is now in single-wide mode.\n");
-         pPriv->overlayOK = TRUE;
+   if (!IS_BROADWATER(pI830)) {
+      if (pPriv->pipe == 0) {
+         if (INREG(PIPEACONF) & PIPEACONF_DOUBLE_WIDE) {
+            xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+	    "Disabling XVideo output because Pipe A is in double-wide mode.\n");
+            pPriv->overlayOK = FALSE;
+         } else if (!pPriv->overlayOK) {
+            xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+	    "Re-enabling XVideo output because Pipe A is now in single-wide mode.\n");
+            pPriv->overlayOK = TRUE;
+         }
       }
-   }
 
-   if (pPriv->pipe == 1) {
-      if (INREG(PIPEBCONF) & PIPEBCONF_DOUBLE_WIDE) {
-         xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-	   "Disabling XVideo output because Pipe B is in double-wide mode.\n");
-         pPriv->overlayOK = FALSE;
-      } else if (!pPriv->overlayOK) {
-         xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-	   "Re-enabling XVideo output because Pipe B is now in single-wide mode.\n");
-         pPriv->overlayOK = TRUE;
+      if (pPriv->pipe == 1) {
+         if (INREG(PIPEBCONF) & PIPEBCONF_DOUBLE_WIDE) {
+            xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+   	    "Disabling XVideo output because Pipe B is in double-wide mode.\n");
+            pPriv->overlayOK = FALSE;
+         } else if (!pPriv->overlayOK) {
+            xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+	    "Re-enabling XVideo output because Pipe B is now in single-wide mode.\n");
+            pPriv->overlayOK = TRUE;
+         }
       }
    }
 
diff --git a/src/intel_acpi.c b/src/intel_acpi.c
new file mode 100644
index 0000000..e7014b2
--- /dev/null
+++ b/src/intel_acpi.c
@@ -0,0 +1,231 @@
+#ifndef XFree86LOADER
+#include <fcntl.h>
+#include <errno.h>
+#include <stdio.h>
+#endif
+#include <sys/un.h>
+#include <sys/socket.h>
+#include "X.h"
+#include "os.h"
+#include "xf86.h"
+#include "xf86Priv.h"
+#define XF86_OS_PRIVS
+#include "xf86_OSproc.h"
+
+#include "i830.h"
+ 
+#define ACPI_SOCKET  "/var/run/acpid.socket"
+#define ACPI_EVENTS  "/proc/acpi/event"
+
+#define ACPI_VIDEO_NOTIFY_SWITCH	0x80
+#define ACPI_VIDEO_NOTIFY_PROBE		0x81
+#define ACPI_VIDEO_NOTIFY_CYCLE		0x82
+#define ACPI_VIDEO_NOTIFY_NEXT_OUTPUT	0x83
+#define ACPI_VIDEO_NOTIFY_PREV_OUTPUT	0x84
+
+#define ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS	0x82
+#define	ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS	0x83
+#define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS	0x84
+#define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS	0x85
+#define ACPI_VIDEO_NOTIFY_DISPLAY_OFF		0x86
+
+#define ACPI_VIDEO_HEAD_INVALID		(~0u - 1)
+#define ACPI_VIDEO_HEAD_END		(~0u)
+
+static void I830CloseACPI(void);
+pointer I830ACPIihPtr = NULL;
+PMClose I830ACPIOpen(void);
+
+#define LINE_LENGTH 80
+
+#define MAX_NO_EVENTS 10
+
+static int
+I830ACPIGetEventFromOs(int fd, pmEvent *events, int num)
+{
+    char ev[LINE_LENGTH];
+    int n;
+
+    memset(ev, 0, LINE_LENGTH);
+
+    n = read( fd, ev, LINE_LENGTH );
+
+    /* Check that we have a video event */
+    if (strstr(ev, "video") == ev) {
+	char *video = NULL;
+	char *GFX = NULL;
+	char *notify = NULL;
+	char *data = NULL; /* doesn't appear to be used in the kernel */
+	unsigned long int notify_l, data_l;
+
+	video = strtok(ev, "video");
+
+	GFX = strtok(NULL, " ");
+#if 0
+	ErrorF("GFX: %s\n",GFX);
+#endif
+
+	notify = strtok(NULL, " ");
+	notify_l = strtoul(notify, NULL, 16);
+#if 0
+	ErrorF("notify: 0x%lx\n",notify_l);
+#endif
+
+	data = strtok(NULL, " ");
+	data_l = strtoul(data, NULL, 16);
+#if 0
+	ErrorF("data: 0x%lx\n",data_l);
+#endif
+
+	/* Currently we don't differentiate events */
+	switch (notify_l) {
+		case ACPI_VIDEO_NOTIFY_SWITCH:
+			break;
+		case ACPI_VIDEO_NOTIFY_PROBE:
+			break;
+		case ACPI_VIDEO_NOTIFY_CYCLE:
+			break;
+		case ACPI_VIDEO_NOTIFY_NEXT_OUTPUT:
+			break;
+		case ACPI_VIDEO_NOTIFY_PREV_OUTPUT:
+			break;
+		default:
+			break;
+	}
+
+	/* We should probably add the ACPI events to the common layer */
+        events[0] = XF86_APM_CAPABILITY_CHANGED;
+
+	return 1;
+    }
+    
+    return 0;
+}
+
+static void
+I830HandlePMEvents(int fd, pointer data)
+{
+    pmEvent events[MAX_NO_EVENTS];
+    int i,j,n;
+
+    if (!I830ACPIGetEventFromOs)
+	return;
+
+    if ((n = I830ACPIGetEventFromOs(fd,events,MAX_NO_EVENTS))) {
+	do {
+	    for (j = 0; j < n; j++) {
+		xf86EnterServerState(SETUP);
+		for (i = 0; i < xf86NumScreens; i++) {
+	    	    xf86EnableAccess(xf86Screens[i]);
+	    	    if (xf86Screens[i]->PMEvent)
+			xf86Screens[i]->PMEvent(i,events[j],FALSE);
+		}
+		xf86EnterServerState(OPERATING);
+	    }
+	    break;
+	} while (1);
+    }
+}
+
+PMClose
+I830ACPIOpen(void)
+{
+    int fd;    
+    struct sockaddr_un addr;
+    int r = -1;
+
+#ifdef DEBUG
+    ErrorF("ACPI: OSPMOpen called\n");
+#endif
+    if (I830ACPIihPtr)
+	return NULL;
+   
+#ifdef DEBUG
+    ErrorF("ACPI: Opening device\n");
+#endif
+    if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) > -1) {
+	memset(&addr, 0, sizeof(addr));
+	addr.sun_family = AF_UNIX;
+	strcpy(addr.sun_path, ACPI_SOCKET);
+	if ((r = connect(fd, (struct sockaddr*)&addr, sizeof(addr))) == -1) {
+	    shutdown(fd, 2);
+            close(fd);
+	    fd = -1;
+	}
+    }
+
+    /* acpid's socket isn't available, so try going direct */
+    if (fd == -1) {
+        if ((fd = open(ACPI_EVENTS, O_RDONLY)) < 0) {
+	    xf86MsgVerb(X_WARNING,3,"Open ACPI failed (%s) (%s)\n", ACPI_EVENTS,
+	    	strerror(errno));
+	    return NULL;
+    	}
+    }
+
+    I830ACPIihPtr = xf86AddInputHandler(fd,I830HandlePMEvents,NULL);
+    xf86MsgVerb(X_INFO,3,"Open ACPI successful (%s)\n", (r != -1) ? ACPI_SOCKET : ACPI_EVENTS);
+
+    return I830CloseACPI;
+}
+
+static void
+I830CloseACPI(void)
+{
+    int fd;
+    
+#ifdef DEBUG
+   ErrorF("ACPI: Closing device\n");
+#endif
+    if (I830ACPIihPtr) {
+	fd = xf86RemoveInputHandler(I830ACPIihPtr);
+	shutdown(fd, 2);
+        close(fd);
+	I830ACPIihPtr = NULL;
+    }
+}
+
+#ifdef XFree86LOADER
+static MODULESETUPPROTO(intel_acpiSetup);
+
+static XF86ModuleVersionInfo intel_acpiVersRec =
+{
+	"intel_acpi",
+	"Tungsten Graphics, Inc",
+	MODINFOSTRING1,
+	MODINFOSTRING2,
+	XF86_VERSION_CURRENT,
+	INTEL_MAJOR_VERSION, INTEL_MINOR_VERSION, INTEL_PATCHLEVEL,
+	ABI_CLASS_EXTENSION,
+	ABI_EXTENSION_VERSION,
+	MOD_CLASS_EXTENSION,
+	{0,0,0,0}
+};
+
+XF86ModuleData intel_acpiModuleData = { &intel_acpiVersRec, intel_acpiSetup, NULL };
+
+ModuleInfoRec INTELACPI = {
+    1,
+    "INTELACPI",
+    NULL,
+    0,
+    NULL,
+};
+
+/*ARGSUSED*/
+static pointer
+intel_acpiSetup(pointer Module, pointer Options, int *ErrorMajor, int *ErrorMinor)
+{
+    static Bool Initialised = FALSE;
+
+    if (!Initialised) {
+	Initialised = TRUE;
+#ifndef REMOVE_LOADER_CHECK_MODULE_INFO
+	if (xf86LoaderCheckSymbol("xf86AddModuleInfo"))
+#endif
+	xf86AddModuleInfo(&INTELACPI, Module);
+    }
+
+    return (pointer)TRUE;
+}
+#endif
diff --git a/src/intel_randr.c b/src/intel_randr.c
new file mode 100644
index 0000000..950a122
--- /dev/null
+++ b/src/intel_randr.c
@@ -0,0 +1,424 @@
+/* $XdotOrg: xc/programs/Xserver/hw/xfree86/common/xf86RandR.c,v 1.3 2004/07/30 21:53:09 eich Exp $ */
+/*
+ * $XFree86: xc/programs/Xserver/hw/xfree86/common/xf86RandR.c,v 1.7tsi Exp $
+ *
+ * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  Keith Packard makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "X.h"
+#include "os.h"
+#include "mibank.h"
+#include "globals.h"
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86DDC.h"
+#include "mipointer.h"
+#include "windowstr.h"
+#include "mivalidate.h"
+#include <randrstr.h>
+
+#include "i830.h"
+
+typedef struct _i830RandRInfo {
+    int				    virtualX;
+    int				    virtualY;
+    int				    mmWidth;
+    int				    mmHeight;
+    int				    maxX;
+    int				    maxY;
+    Rotation			    rotation; /* current mode */
+    Rotation                        supported_rotations; /* driver supported */
+} XF86RandRInfoRec, *XF86RandRInfoPtr;
+    
+static int	    i830RandRIndex;
+static int	    i830RandRGeneration;
+
+#define XF86RANDRINFO(p)    ((XF86RandRInfoPtr) (p)->devPrivates[i830RandRIndex].ptr)
+
+static int
+I830RandRModeRefresh (DisplayModePtr mode)
+{
+    if (mode->VRefresh)
+	return (int) (mode->VRefresh + 0.5);
+    else
+	return (int) (mode->Clock * 1000.0 / mode->HTotal / mode->VTotal + 0.5);
+}
+
+static Bool
+I830RandRGetInfo (ScreenPtr pScreen, Rotation *rotations)
+{
+    RRScreenSizePtr	    pSize;
+    ScrnInfoPtr		    scrp = XF86SCRNINFO(pScreen);
+    XF86RandRInfoPtr	    randrp = XF86RANDRINFO(pScreen);
+    DisplayModePtr	    mode;
+    int			    refresh0 = 60;
+    int			    maxX = 0, maxY = 0;
+    
+    *rotations = randrp->supported_rotations;
+
+    if (randrp->virtualX == -1 || randrp->virtualY == -1) 
+    {
+	randrp->virtualX = scrp->virtualX;
+	randrp->virtualY = scrp->virtualY;
+    }
+
+    for (mode = scrp->modes; ; mode = mode->next)
+    {
+	int refresh = I830RandRModeRefresh (mode);
+	if (randrp->maxX == 0 || randrp->maxY == 0)
+	{
+		if (maxX < mode->HDisplay)
+			maxX = mode->HDisplay;
+		if (maxY < mode->VDisplay)
+			maxY = mode->VDisplay;
+	}
+	if (mode == scrp->modes)
+	    refresh0 = refresh;
+	pSize = RRRegisterSize (pScreen,
+				mode->HDisplay, mode->VDisplay,
+				randrp->mmWidth, randrp->mmHeight);
+	if (!pSize)
+	    return FALSE;
+	RRRegisterRate (pScreen, pSize, refresh);
+	if (mode == scrp->currentMode &&
+	    mode->HDisplay == scrp->virtualX && mode->VDisplay == scrp->virtualY)
+	    RRSetCurrentConfig (pScreen, randrp->rotation, refresh, pSize);
+	if (mode->next == scrp->modes)
+	    break;
+    }
+
+    if (randrp->maxX == 0 || randrp->maxY == 0)
+    {
+	randrp->maxX = maxX;
+	randrp->maxY = maxY;
+    }
+   
+    if (scrp->currentMode->HDisplay != randrp->virtualX ||
+	scrp->currentMode->VDisplay != randrp->virtualY)
+    {
+	mode = scrp->modes;
+	pSize = RRRegisterSize (pScreen,
+				randrp->virtualX, randrp->virtualY,
+				randrp->mmWidth,
+				randrp->mmHeight);
+	if (!pSize)
+	    return FALSE;
+	RRRegisterRate (pScreen, pSize, refresh0);
+	if (scrp->virtualX == randrp->virtualX && 
+	    scrp->virtualY == randrp->virtualY)
+	{
+	    RRSetCurrentConfig (pScreen, randrp->rotation, refresh0, pSize);
+	}
+    }
+
+    /* If there is driver support for randr, let it set our supported rotations */
+    if(scrp->RRFunc) {
+	xorgRRRotation RRRotation;
+	
+	RRRotation.RRRotations = *rotations;
+	if (!(*scrp->RRFunc)(scrp, RR_GET_INFO, &RRRotation))
+	    return FALSE;
+	*rotations = RRRotation.RRRotations;
+    }
+    
+    return TRUE;
+}
+
+static Bool
+I830RandRSetMode (ScreenPtr	    pScreen,
+		  DisplayModePtr    mode,
+		  Bool		    useVirtual,
+		  int		    mmWidth,
+		  int		    mmHeight)
+{
+    ScrnInfoPtr		scrp = XF86SCRNINFO(pScreen);
+    XF86RandRInfoPtr	randrp = XF86RANDRINFO(pScreen);
+    int			oldWidth = pScreen->width;
+    int			oldHeight = pScreen->height;
+    int			oldmmWidth = pScreen->mmWidth;
+    int			oldmmHeight = pScreen->mmHeight;
+    WindowPtr		pRoot = WindowTable[pScreen->myNum];
+    DisplayModePtr      currentMode = NULL;
+    Bool 		ret = TRUE;
+    PixmapPtr 		pspix = NULL;
+    
+    if (pRoot)
+	(*scrp->EnableDisableFBAccess) (pScreen->myNum, FALSE);
+    if (useVirtual)
+    {
+	scrp->virtualX = randrp->virtualX;
+	scrp->virtualY = randrp->virtualY;
+    }
+    else
+    {
+	scrp->virtualX = mode->HDisplay;
+	scrp->virtualY = mode->VDisplay;
+    }
+    if(randrp->rotation & (RR_Rotate_90 | RR_Rotate_270))
+    {
+	/* If the screen is rotated 90 or 270 degrees, swap the sizes. */
+	pScreen->width = scrp->virtualY;
+	pScreen->height = scrp->virtualX;
+	pScreen->mmWidth = mmHeight;
+	pScreen->mmHeight = mmWidth;
+    }
+    else
+    {
+	pScreen->width = scrp->virtualX;
+	pScreen->height = scrp->virtualY;
+	pScreen->mmWidth = mmWidth;
+	pScreen->mmHeight = mmHeight;
+    }
+    if (scrp->currentMode == mode) {
+        /* Save current mode */
+        currentMode = scrp->currentMode;
+        /* Reset, just so we ensure the drivers SwitchMode is called */
+        scrp->currentMode = NULL;
+    }
+    /*
+     * We assume that if the driver failed to SwitchMode to the rotated
+     * version, then it should revert back to it's prior mode... Mmm...
+     */
+    if (!xf86SwitchMode (pScreen, mode))
+    {
+        ret = FALSE;
+	scrp->virtualX = pScreen->width = oldWidth;
+	scrp->virtualY = pScreen->height = oldHeight;
+	pScreen->mmWidth = oldmmWidth;
+	pScreen->mmHeight = oldmmHeight;
+        scrp->currentMode = currentMode;
+    }
+    /*
+     * Get the new Screen pixmap ptr as SwitchMode might have called
+     * ModifyPixmapHeader and xf86EnableDisableFBAccess will put it back...
+     * Unfortunately.
+     */
+    pspix = (*pScreen->GetScreenPixmap) (pScreen);
+    if (pspix->devPrivate.ptr)
+       scrp->pixmapPrivate = pspix->devPrivate;
+    
+    /*
+     * Make sure the layout is correct
+     */
+    xf86ReconfigureLayout();
+
+    /*
+     * Make sure the whole screen is visible
+     */
+    xf86SetViewport (pScreen, pScreen->width, pScreen->height);
+    xf86SetViewport (pScreen, 0, 0);
+    if (pRoot)
+	(*scrp->EnableDisableFBAccess) (pScreen->myNum, TRUE);
+    return ret;
+}
+
+Bool
+I830RandRSetConfig (ScreenPtr		pScreen,
+		    Rotation		rotation,
+		    int			rate,
+		    RRScreenSizePtr	pSize)
+{
+    ScrnInfoPtr		    scrp = XF86SCRNINFO(pScreen);
+    XF86RandRInfoPtr	    randrp = XF86RANDRINFO(pScreen);
+    DisplayModePtr	    mode;
+    int			    px, py;
+    Bool		    useVirtual = FALSE;
+    int			    maxX = 0, maxY = 0;
+    Rotation		    oldRotation = randrp->rotation;
+
+    randrp->rotation = rotation;
+
+    if (randrp->virtualX == -1 || randrp->virtualY == -1) 
+    {
+	randrp->virtualX = scrp->virtualX;
+	randrp->virtualY = scrp->virtualY;
+    }
+
+    miPointerPosition (&px, &py);
+    for (mode = scrp->modes; ; mode = mode->next)
+    {
+	if (randrp->maxX == 0 || randrp->maxY == 0)
+	{
+		if (maxX < mode->HDisplay)
+			maxX = mode->HDisplay;
+		if (maxY < mode->VDisplay)
+			maxY = mode->VDisplay;
+	}
+	if (mode->HDisplay == pSize->width && 
+	    mode->VDisplay == pSize->height &&
+	    (rate == 0 || I830RandRModeRefresh (mode) == rate))
+	    break;
+	if (mode->next == scrp->modes)
+	{
+	    if (pSize->width == randrp->virtualX &&
+		pSize->height == randrp->virtualY)
+	    {
+		mode = scrp->modes;
+		useVirtual = TRUE;
+		break;
+	    }
+    	    if (randrp->maxX == 0 || randrp->maxY == 0)
+    	    {
+		randrp->maxX = maxX;
+		randrp->maxY = maxY;
+    	    }
+	    return FALSE;
+	}
+    }
+
+    if (randrp->maxX == 0 || randrp->maxY == 0)
+    {
+	randrp->maxX = maxX;
+	randrp->maxY = maxY;
+    }
+
+    /* Have the driver do its thing. */
+    if (scrp->RRFunc) {
+	xorgRRRotation RRRotation;
+	RRRotation.RRConfig.rotation = rotation;
+	RRRotation.RRConfig.rate = rate;
+	RRRotation.RRConfig.width = pSize->width;
+	RRRotation.RRConfig.height = pSize->height;
+	
+        if (!(*scrp->RRFunc)(scrp, RR_SET_CONFIG, &RRRotation))
+			  return FALSE;
+    }
+
+    if (!I830RandRSetMode (pScreen, mode, useVirtual, pSize->mmWidth, pSize->mmHeight)) {
+        randrp->rotation = oldRotation;
+	return FALSE;
+    }
+
+    /*
+     * Move the cursor back where it belongs; SwitchMode repositions it
+     */
+    if (pScreen == miPointerCurrentScreen ())
+    {
+        px = (px >= pScreen->width ? (pScreen->width - 1) : px);
+        py = (py >= pScreen->height ? (pScreen->height - 1) : py);
+
+	xf86SetViewport(pScreen, px, py);
+
+	(*pScreen->SetCursorPosition) (pScreen, px, py, FALSE);
+    }
+
+    return TRUE;
+}
+
+Rotation
+I830GetRotation(ScreenPtr pScreen)
+{
+    XF86RandRInfoPtr	    randrp = XF86RANDRINFO(pScreen);
+
+    return randrp->rotation;
+}
+
+Bool
+I830RandRInit (ScreenPtr    pScreen, int rotation)
+{
+    rrScrPrivPtr	rp;
+    XF86RandRInfoPtr	randrp;
+    ScrnInfoPtr		scrp = XF86SCRNINFO(pScreen);
+    
+#ifdef PANORAMIX
+    /* XXX disable RandR when using Xinerama */
+    if (!noPanoramiXExtension)
+	return TRUE;
+#endif
+    if (i830RandRGeneration != serverGeneration)
+    {
+	i830RandRIndex = AllocateScreenPrivateIndex();
+	i830RandRGeneration = serverGeneration;
+    }
+    
+    randrp = xalloc (sizeof (XF86RandRInfoRec));
+    if (!randrp)
+	return FALSE;
+			
+    if (!RRScreenInit(pScreen))
+    {
+	xfree (randrp);
+	return FALSE;
+    }
+    rp = rrGetScrPriv(pScreen);
+    rp->rrGetInfo = I830RandRGetInfo;
+    rp->rrSetConfig = I830RandRSetConfig;
+
+    randrp->virtualX = -1;
+    randrp->virtualY = -1;
+    randrp->mmWidth = pScreen->mmWidth;
+    randrp->mmHeight = pScreen->mmHeight;
+    
+    randrp->rotation = RR_Rotate_0; /* initial rotated mode */
+
+    randrp->supported_rotations = rotation;
+
+    randrp->maxX = randrp->maxY = 0;
+
+    pScreen->devPrivates[i830RandRIndex].ptr = randrp;
+
+    return TRUE;
+}
+
+#ifdef XFree86LOADER
+static MODULESETUPPROTO(intelrandrSetup);
+
+static XF86ModuleVersionInfo intelrandrVersRec =
+{
+	"intel_randr",
+	"Tungsten Graphics, Inc",
+	MODINFOSTRING1,
+	MODINFOSTRING2,
+	XF86_VERSION_CURRENT,
+	INTEL_MAJOR_VERSION, INTEL_MINOR_VERSION, INTEL_PATCHLEVEL,
+	ABI_CLASS_EXTENSION,
+	ABI_EXTENSION_VERSION,
+	MOD_CLASS_EXTENSION,
+	{0,0,0,0}
+};
+
+XF86ModuleData intel_randrModuleData = { &intelrandrVersRec, intelrandrSetup, NULL };
+
+ModuleInfoRec INTELRANDR = {
+    1,
+    "INTELRANDR",
+    NULL,
+    0,
+    NULL,
+};
+
+/*ARGSUSED*/
+static pointer
+intelrandrSetup(pointer Module, pointer Options, int *ErrorMajor, int *ErrorMinor)
+{
+    static Bool Initialised = FALSE;
+
+    if (!Initialised) {
+	Initialised = TRUE;
+#ifndef REMOVE_LOADER_CHECK_MODULE_INFO
+	if (xf86LoaderCheckSymbol("xf86AddModuleInfo"))
+#endif
+	xf86AddModuleInfo(&INTELRANDR, Module);
+    }
+
+    return (pointer)TRUE;
+}
+#endif



More information about the xorg-commit mailing list