xf86-video-intel: Branch 'modesetting' - 75 commits - man/i810.man src/i830_3d.c src/i830_accel.c src/i830_dga.c src/i830_dri.c src/i830_driver.c src/i830_exa.c src/i830_exa_render.c src/i830.h src/i830_memory.c src/i830_reg.h src/i830_rotate.c src/i830_video.c src/i830_xaa.c src/i915_3d.c src/i915_3d.h src/i915_exa_render.c src/i915_reg.h src/i915_video.c src/Makefile.am

Eric Anholt anholt at kemper.freedesktop.org
Thu Nov 30 21:28:19 EET 2006


 man/i810.man          |    7 
 src/Makefile.am       |    9 
 src/i830.h            |   35 ++
 src/i830_3d.c         |   10 
 src/i830_accel.c      |  647 ---------------------------------------------
 src/i830_dga.c        |    4 
 src/i830_dri.c        |    8 
 src/i830_driver.c     |  171 ++++++++++--
 src/i830_exa.c        |  505 +++++++++++++++++++++++++++++++++++
 src/i830_exa_render.c |  514 ++++++++++++++++++++++++++++++++++++
 src/i830_memory.c     |   28 +
 src/i830_reg.h        |  117 +++++++-
 src/i830_rotate.c     |  140 ++-------
 src/i830_video.c      |    2 
 src/i830_xaa.c        |  711 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/i915_3d.c         |   38 +-
 src/i915_3d.h         |   27 +
 src/i915_exa_render.c |  489 ++++++++++++++++++++++++++++++++++
 src/i915_reg.h        |   12 
 src/i915_video.c      |   53 ---
 20 files changed, 2678 insertions(+), 849 deletions(-)

New commits:
diff-tree b94b7c4bcfdb7ba59ed818f72309b5060a2ab7ee (from parents)
Merge: b6fc8df9a52f5fe1b4d26ae06bc4d48235b44a67 25e6e497824a23eb231fc6fd6e483f601d612cee
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Nov 30 09:15:30 2006 -0800

    Merge branch 'exa' of ../xf86-video-intel into modesetting
    
    Conflicts:
    
    	man/i810.man
    	src/Makefile.am
    	src/i830.h
    	src/i830_driver.c
    	src/i830_rotate.c
    	src/i830_video.c

diff --cc man/i810.man
index fa588fb,509ffbc..ff45809
@@@ -181,32 -201,14 +181,37 @@@
  .BI "Option \*qLinearAlloc\*q \*q" integer \*q
  Allows more memory for the offscreen allocator. This usually helps in
  situations where HDTV movies are required to play but not enough offscreen
 -memory is usually available. Set this to 6144 for upto 1920x1080 HDTV support.
 +memory is usually available. Set this to 8160 for upto 1920x1080 HDTV support.
  Default 0KB (off).
  .TP
 +.BI "Option \*qLegacy3D\*q \*q" boolean \*q
 +Enable support for the legacy i915_dri.so 3D driver.
 +This will, among other things, make the 2D driver tell libGL to
 +load the 3D driver i915_dri.so instead of the newer i915tex_dri.so.
 +This option is only used for chipsets in the range i830-i945. 
 +Default for i830-i945 series: Enabled for i915 drm versions < 1.7.0. Otherwise
 +disabled. 
 +Default for i810: The option is not used.
 +Default for i965: The option is always true.
 +.TP
 +.BI "Option \*qAperTexSize\*q \*q" integer \*q
 +Give the size in kiB of the AGP aperture area that is reserved for the
 +DRM memory manager present in i915 drm from version 1.7.0 and upwards,
 +and that is used with the 3D driver in Mesa from version 6.5.2 and
 +upwards. If the size is set too high to make room for pre-allocated
 +VideoRam, the driver will try to reduce it automatically. If you use only
 +older Mesa or DRM versions, you may set this value to zero, and
 +atctivate the legacy texture pool (see 
 +.B "Option \*qLegacy3D\*q"
 +). If you run 3D programs with large texture memory requirements, you might
 +gain some performance by increasing this value.
 +Default: 32768.
-  
++.TP
+ .BI "Option \*qAccelMethod\*q \*q" string \*q
+ Choose acceleration architecture, either "XAA" or "EXA".  XAA is the old
+ (but stable) XFree86 based acceleration architecture.  EXA is a newer and
+ simpler acceleration architecture designed to better accelerate the X Render
+ extension.  Default: "XAA".
  
  .SH "SEE ALSO"
  __xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), xorgconfig(__appmansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__)
diff --cc src/Makefile.am
index 583925f,163cc3f..5246270
@@@ -24,7 -24,7 +24,8 @@@
  # -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 = @WARN_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@ -DI830_XV
 -AM_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@ -DI830_XV -DI830_USE_XAA -DI830_USE_EXA
++AM_CFLAGS = @WARN_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@ \
++	-DI830_XV -DI830_USE_XAA -DI830_USE_EXA
  
  i810_drv_la_LTLIBRARIES = i810_drv.la
  i810_drv_la_LDFLAGS = -module -avoid-version
diff --cc src/i830.h
index 1534f61,9c37068..422fdb7
@@@ -69,13 -70,17 +69,22 @@@
  #include "i830_dri.h"
  #endif
  
+ #ifdef I830_USE_EXA
+ #include "exa.h"
+ Bool I830EXAInit(ScreenPtr pScreen);
+ #endif
+ 
+ #ifdef I830_USE_XAA
+ Bool I830XAAInit(ScreenPtr pScreen);
+ #endif
+ 
 +typedef struct _I830OutputRec I830OutputRec, *I830OutputPtr;
 +
  #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 */
@@@ -147,155 -170,36 +156,163 @@@
  #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;
 +/* store information about an Ixxx DVO */
 +/* The i830->i865 use multiple DVOs with multiple i2cs */
 +/* the i915, i945 have a single sDVO i2c bus - which is different */
 +#define MAX_OUTPUTS 6
 +
 +#define I830_I2C_BUS_DVO 1
 +#define I830_I2C_BUS_SDVO 2
 +
 +/* these are outputs from the chip - integrated only 
 +   external chips are via DVO or SDVO output */
 +#define I830_OUTPUT_UNUSED 0
 +#define I830_OUTPUT_ANALOG 1
 +#define I830_OUTPUT_DVO 2
 +#define I830_OUTPUT_SDVO 3
 +#define I830_OUTPUT_LVDS 4
 +#define I830_OUTPUT_TVOUT 5
 +
 +#define I830_DVO_CHIP_NONE 0
 +#define I830_DVO_CHIP_LVDS 1
 +#define I830_DVO_CHIP_TMDS 2
 +#define I830_DVO_CHIP_TVOUT 4
 +
 +struct _I830DVODriver {
 +   int type;
 +   char *modulename;
 +   char *fntablename;
 +   int address;
 +   const char **symbols;
 +   I830I2CVidOutputRec *vid_rec;
 +   void *dev_priv;
 +   pointer modhandle;
 +};
 +
 +extern const char *i830_output_type_names[];
 +
 +enum detect_status {
 +   OUTPUT_STATUS_CONNECTED,
 +   OUTPUT_STATUS_DISCONNECTED,
 +   OUTPUT_STATUS_UNKNOWN
 +};
 +
 +struct _I830OutputRec {
 +   int type;
 +   int pipe;
 +   Bool enabled;
 +   /**
 +    * Marks that the output and associated pipe is temporarily enabled for
 +    * load detection.
 +    */
 +   Bool load_detect_temp;
 +
 +   /**
 +    * Turns the output on/off, or sets intermediate power levels if available.
 +    *
 +    * Unsupported intermediate modes drop to the lower power setting.  If the
 +    * mode is DPMSModeOff, the output must be disabled, as the DPLL may be
 +    * disabled afterwards.
 +    */
 +   void (*dpms)(ScrnInfoPtr pScrn, I830OutputPtr output, int mode);
 +
 +   /**
 +    * Saves the output's state for restoration on VT switch.
 +    */
 +   void (*save)(ScrnInfoPtr pScrn, I830OutputPtr output);
 +
 +   /**
 +    * Restore's the output's state at VT switch.
 +    */
 +   void (*restore)(ScrnInfoPtr pScrn, I830OutputPtr output);
 +
 +   /**
 +    * Callback for testing a video mode for a given output.
 +    *
 +    * This function should only check for cases where a mode can't be supported
 +    * on the pipe specifically, and not represent generic CRTC limitations.
 +    *
 +    * \return MODE_OK if the mode is valid, or another MODE_* otherwise.
 +    */
 +   int (*mode_valid)(ScrnInfoPtr pScrn, I830OutputPtr output,
 +		     DisplayModePtr pMode);
 +
 +   /**
 +    * Callback for setting up a video mode before any pipe/dpll changes.
 +    *
 +    * \param pMode the mode that will be set, or NULL if the mode to be set is
 +    * unknown (such as the restore path of VT switching).
 +    */
 +   void (*pre_set_mode)(ScrnInfoPtr pScrn, I830OutputPtr output,
 +			DisplayModePtr pMode);
 +
 +   /**
 +    * Callback for setting up a video mode after the DPLL update but before
 +    * the plane is enabled.
 +    */
 +   void (*post_set_mode)(ScrnInfoPtr pScrn, I830OutputPtr output,
 +			 DisplayModePtr pMode);
 +
 +   /**
 +    * Probe for a connected output, and return detect_status.
 +    */
 +   enum detect_status (*detect)(ScrnInfoPtr pScrn, I830OutputPtr output);
 +
 +   /**
 +    * Query the device for the modes it provides.
 +    *
 +    * This function may also update MonInfo, mm_width, and mm_height.
 +    *
 +    * \return singly-linked list of modes or NULL if no modes found.
 +    */
 +   DisplayModePtr (*get_modes)(ScrnInfoPtr pScrn, I830OutputPtr output);
 +
 +   /**
 +    * List of available modes on this output.
 +    *
 +    * This should be the list from get_modes(), plus perhaps additional
 +    * compatible modes added later.
 +    */
 +   DisplayModePtr probed_modes;
 +
 +   /** EDID monitor information */
 +   xf86MonPtr MonInfo;
 +
 +   /** Physical size of the output currently attached. */
 +   int mm_width, mm_height;
 +
 +   I2CBusPtr pI2CBus;
 +   I2CBusPtr pDDCBus;
 +   struct _I830DVODriver *i2c_drv;
 +   /** Output-private structure.  Should replace i2c_drv */
 +   void *dev_priv;
 +#ifdef RANDR_12_INTERFACE
 +   RROutputPtr randr_output;
 +#endif
 +};
  
+ /** enumeration of 3d consumers so some can maintain invariant state. */
+ enum last_3d {
+     LAST_3D_OTHER,
+     LAST_3D_VIDEO,
+     LAST_3D_RENDER,
+     LAST_3D_ROTATION
+ };
+ 
 +typedef struct _I830PipeRec {
 +   Bool		  enabled;
 +   Bool		  gammaEnabled;
 +   int		  x;
 +   int		  y;
 +   Bool		  cursorInRange;
 +   Bool		  cursorShown;
 +   DisplayModeRec curMode;
 +   DisplayModeRec desiredMode;
 +#ifdef RANDR_12_INTERFACE
 +   RRCrtcPtr	  randr_crtc;
 +#endif
 +} I830PipeRec, *I830PipePtr;
 +
  typedef struct _I830Rec {
     unsigned char *MMIOBase;
     unsigned char *FbBase;
@@@ -416,8 -347,10 +435,9 @@@
     int NumScanlineColorExpandBuffers;
     int nextColorExpandBuf;
  
 -   I830RegRec SavedReg;
     I830RegRec ModeReg;
  
+    Bool useEXA;
     Bool noAccel;
     Bool SWCursor;
     Bool cursorOn;
@@@ -487,82 -455,13 +515,84 @@@
 -   Bool vbeRestoreWorkaround;
 -   Bool displayInfo;
 -   Bool devicePresence;
  
     OsTimerPtr devicesTimer;
  
 -   CARD32 savedAsurf;
 -   CARD32 savedBsurf;
 +   int ddc2;
 +   int num_outputs;
 +   struct _I830OutputRec output[MAX_OUTPUTS];
 +
 +   /* 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;
  
 -    enum last_3d last_3d;
 +   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 saveDPLL_A_MD;
 +   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 saveDPLL_B_MD;
 +   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;
++
++   enum last_3d last_3d;
  } I830Rec;
  
  #define I830PTR(p) ((I830Ptr)((p)->driverPrivate))
@@@ -652,24 -550,19 +682,27 @@@
  extern void I830ChangeFrontbuffer(ScrnInfoPtr pScrn,int buffer);
  extern Bool I830IsPrimary(ScrnInfoPtr pScrn);
  
 -extern DisplayModePtr I830GetModePool(ScrnInfoPtr pScrn, vbeInfoPtr pVbe,
 -					VbeInfoBlock *vbe);
 -extern void I830SetModeParameters(ScrnInfoPtr pScrn, vbeInfoPtr pVbe);
 -extern void I830UnsetModeParameters(ScrnInfoPtr pScrn, vbeInfoPtr pVbe);
 -extern void I830PrintModes(ScrnInfoPtr pScrn);
 -extern int I830GetBestRefresh(ScrnInfoPtr pScrn, int refresh);
 -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);
 +extern Bool I830I2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, int i2c_reg,
 +			char *name);
 +
 +/* i830_display.c */
 +Bool
 +i830PipeHasType (ScrnInfoPtr pScrn, int pipe, int type);
 +
 +/* i830_crt.c */
 +void i830_crt_init(ScrnInfoPtr pScrn);
 +
 +/* i830_dvo.c */
 +void i830_dvo_init(ScrnInfoPtr pScrn);
 +
 +/* i830_lvds.c */
 +void i830_lvds_init(ScrnInfoPtr pScrn);
  
+ extern void i830MarkSync(ScrnInfoPtr pScrn);
+ extern void i830WaitSync(ScrnInfoPtr pScrn);
+ 
  /* i830_memory.c */
  Bool I830BindAGPMemory(ScrnInfoPtr pScrn);
  Bool I830UnbindAGPMemory(ScrnInfoPtr pScrn);
diff --cc src/i830_driver.c
index 55610f5,12fc524..61dbeea
@@@ -197,10 -197,20 +197,22 @@@
  
  #ifdef XF86DRI
  #include "dri.h"
 +#include <sys/ioctl.h>
 +#include <errno.h>
  #endif
  
+ #ifdef I830_USE_EXA
+ const char *I830exaSymbols[] = {
+     "exaGetVersion",
+     "exaDriverInit",
+     "exaDriverFini",
+     "exaOffscreenAlloc",
+     "exaOffscreenFree",
+     "exaWaitSync",
+     NULL
+ };
+ #endif
+ 
  #define BIT(x) (1 << (x))
  #define MAX(a,b) ((a) > (b) ? (a) : (b))
  #define NB_OF(x) (sizeof (x) / sizeof (*x))
@@@ -265,11 -278,18 +280,14 @@@
     OPTION_FIXEDPIPE,
     OPTION_ROTATE,
     OPTION_LINEARALLOC,
 -   OPTION_MERGEDFB,
 -   OPTION_METAMODES,
 -   OPTION_SECONDHSYNC,
 -   OPTION_SECONDVREFRESH,
 -   OPTION_SECONDPOSITION,
 -   OPTION_INTELXINERAMA
 +   OPTION_INTELTEXPOOL,
 +   OPTION_INTELMMSIZE
  } I830Opts;
  
 -static OptionInfoRec I830BIOSOptions[] = {
 +static OptionInfoRec I830Options[] = {
+ #if defined(I830_USE_XAA) && defined(I830_USE_EXA)
+    {OPTION_ACCELMETHOD,	"AccelMethod",	OPTV_ANYSTR,	{0},	FALSE},
+ #endif
     {OPTION_NOACCEL,	"NoAccel",	OPTV_BOOLEAN,	{0},	FALSE},
     {OPTION_SW_CURSOR,	"SWcursor",	OPTV_BOOLEAN,	{0},	FALSE},
     {OPTION_CACHE_LINES,	"CacheLines",	OPTV_INTEGER,	{0},	FALSE},
@@@ -3189,70 -7584,110 +3284,69 @@@
           break;
     }
  
- 
 -   return TRUE;
 -}
 -
 -static void
 -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;
 -
 -   DPRINTF(PFX, "I830AdjustFrame: y = %d (+ %d), x = %d (+ %d)\n",
 -	   x, pI830->xoffset, y, pI830->yoffset);
 -
 -   /* Sync the engine before adjust frame */
 -   i830WaitSync(pScrn);
 -
 -   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;
 -   }
 -
 -   if (I830IsPrimary(pScrn))
 -      Start = pI830->FrontBuffer.Start;
 -   else {
 -      I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
 -      Start = pI8301->FrontBuffer2.Start;
 -   }
 -
 -   /* Sigh...
 -    * It seems that there are quite a few Video BIOS' that get this wrong.
 -    * So, we'll bypass the VBE call and hit the hardware directly.
 -    */
 -
 -   if (pI830->Clone) {
 -      if (!pI830->pipe == 0) {
 -         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 {
 -         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) {
 -      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 {
 -      if (!IS_I965G(pI830)) {
 -         OUTREG(DSPBBASE, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
 +#ifdef XF86DRI
 +   if (pI830->directRenderingEnabled && (pI830->mmModeFlags & I830_KERNEL_MM)) {
 +      unsigned long aperEnd = ROUND_DOWN_TO(pI830->FbMapSize, GTT_PAGE_SIZE) 
 +	 / GTT_PAGE_SIZE;
 +      unsigned long aperStart = ROUND_TO(pI830->FbMapSize - KB(pI830->mmSize), GTT_PAGE_SIZE) 
 +	 / GTT_PAGE_SIZE;
 +
 +      if (aperEnd < aperStart || aperEnd - aperStart < I830_MM_MINPAGES) {
 +	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 
 +		    "Too little AGP aperture space for DRM memory manager.\n"
 +		    "\tPlease increase AGP aperture size from BIOS configuration screen\n"
 +		    "\tor decrease the amount of video RAM using option \"VideoRam\".\n"
 +		    "\tDisabling DRI.\n");
 +	 pI830->directRenderingOpen = FALSE;
 +	 I830DRICloseScreen(pScreen);
 +	 pI830->directRenderingEnabled = FALSE;
        } else {
 -         OUTREG(DSPBBASE, 0);
 -         OUTREG(DSPBSURF, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
 +#ifndef XSERVER_LIBDRM_MM
 +	 if (I830DrmMMInit(pI830->drmSubFD, aperStart, aperEnd - aperStart,
 +			   DRM_BO_MEM_TT)) {
 +#else
 +	 if (drmMMInit(pI830->drmSubFD, aperStart, aperEnd - aperStart,
 +		       DRM_BO_MEM_TT)) {
 +#endif	   
 +	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 
 +		       "Could not initialize the DRM memory manager.\n");
 +	    
 +	    pI830->directRenderingOpen = FALSE;
 +	    I830DRICloseScreen(pScreen);
 +	    pI830->directRenderingEnabled = FALSE;
 +	 } else {
 +	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
 +		       "Initialized DRM memory manager, %ld AGP pages\n"
 +		       "\tat AGP offset 0x%lx\n", 
 +		       aperEnd - aperStart,
 +		       aperStart);
 +	 }
        }
     }
 -}
 -
 -static void
 -I830BIOSFreeScreen(int scrnIndex, int flags)
 -{
 -   I830BIOSFreeRec(xf86Screens[scrnIndex]);
 -   if (xf86LoaderCheckSymbol("vgaHWFreeHWRec"))
 -      vgaHWFreeHWRec(xf86Screens[scrnIndex]);
 -}
 -
 -#ifndef SAVERESTORE_HWSTATE
 -#define SAVERESTORE_HWSTATE 0
  #endif
  
 -#if SAVERESTORE_HWSTATE
 +   return TRUE;
 +}
 +
  static void
 -SaveHWOperatingState(ScrnInfoPtr pScrn)
 +i830AdjustFrame(int scrnIndex, int x, int y, int flags)
  {
 +   ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
     I830Ptr pI830 = I830PTR(pScrn);
 -   I830RegPtr save = &pI830->SavedReg;
 +   int i;
 +
 +   DPRINTF(PFX, "i830AdjustFrame: y = %d (+ %d), x = %d (+ %d)\n",
 +	   x, pI830->xoffset, y, pI830->yoffset);
  
 -   DPRINTF(PFX, "SaveHWOperatingState\n");
 +   /* Sync the engine before adjust frame */
 +   if (pI830->AccelInfoRec && pI830->AccelInfoRec->NeedToSync) {
 +      (*pI830->AccelInfoRec->Sync)(pScrn);
 +      pI830->AccelInfoRec->NeedToSync = FALSE;
 +   }
  
 -   return;
 +   for (i = 0; i < pI830->num_pipes; i++)
 +      if (pI830->pipes[i].enabled)
 +	 i830PipeSetBase(pScrn, i, x, y);
  }
  
  static void
@@@ -3853,15 -8888,52 +3953,52 @@@
  }
  
  void
+ i830WaitSync(ScrnInfoPtr pScrn)
+ {
+    I830Ptr pI830 = I830PTR(pScrn);
+ 
+ #ifdef I830_USE_XAA
+    if (!pI830->noAccel && !pI830->useEXA && pI830->AccelInfoRec 
+ 	&& pI830->AccelInfoRec->NeedToSync) {
+       (*pI830->AccelInfoRec->Sync)(pScrn);
+       pI830->AccelInfoRec->NeedToSync = FALSE;
+    }
+ #endif
+ #ifdef I830_USE_EXA
+    if (!pI830->noAccel && pI830->useEXA && pI830->EXADriverPtr) {
+ 	ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
+ 	exaWaitSync(pScreen);
+    }
+ #endif
+ }
+ 
+ void
+ i830MarkSync(ScrnInfoPtr pScrn)
+ {
+    I830Ptr pI830 = I830PTR(pScrn);
+ 
+ #ifdef I830_USE_XAA
+    if (!pI830->useEXA && pI830->AccelInfoRec)
+       pI830->AccelInfoRec->NeedToSync = TRUE;
+ #endif
+ #ifdef I830_USE_EXA
+    if (pI830->useEXA && pI830->EXADriverPtr) {
+       ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
+       exaMarkSync(pScreen);
+    }
+ #endif
+ }
+ 
+ void
  I830InitpScrn(ScrnInfoPtr pScrn)
  {
 -   pScrn->PreInit = I830BIOSPreInit;
 -   pScrn->ScreenInit = I830BIOSScreenInit;
 -   pScrn->SwitchMode = I830BIOSSwitchMode;
 -   pScrn->AdjustFrame = I830AdjustFrame;
 -   pScrn->EnterVT = I830BIOSEnterVT;
 -   pScrn->LeaveVT = I830BIOSLeaveVT;
 -   pScrn->FreeScreen = I830BIOSFreeScreen;
 +   pScrn->PreInit = I830PreInit;
 +   pScrn->ScreenInit = I830ScreenInit;
 +   pScrn->SwitchMode = I830SwitchMode;
 +   pScrn->AdjustFrame = i830AdjustFrame;
 +   pScrn->EnterVT = I830EnterVT;
 +   pScrn->LeaveVT = I830LeaveVT;
 +   pScrn->FreeScreen = I830FreeScreen;
     pScrn->ValidMode = I830ValidMode;
     pScrn->PMEvent = I830PMEvent;
  }
diff-tree 25e6e497824a23eb231fc6fd6e483f601d612cee (from 0bdcce2e4541c6e441c44aad49254ad3093cedb2)
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Oct 26 15:47:49 2006 -0700

    Major cleanup of 3D invariant state, fixing hangs with rotation and render.
    
    Now, the generic invariant state is always set while the X Server is active,
    and happens automatically when the X Server grabs the DRI lock.  More 3D state
    is moved to the generic code.
    
    Then, the 3D consumers (video, rotation, render) set last_3d to their enum
    entry, and can update their own invariant state when another consumer was
    active.

diff --git a/src/i830.h b/src/i830.h
index df1c171..9c37068 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -192,6 +192,13 @@ typedef struct _region {
     int x0,x1,y0,y1;
 } region;
 
+/** enumeration of 3d consumers so some can maintain invariant state. */
+enum last_3d {
+    LAST_3D_OTHER,
+    LAST_3D_VIDEO,
+    LAST_3D_RENDER,
+    LAST_3D_ROTATION
+};
 
 typedef struct _I830Rec {
    unsigned char *MMIOBase;
@@ -453,6 +460,8 @@ typedef struct _I830Rec {
 
    CARD32 savedAsurf;
    CARD32 savedBsurf;
+
+    enum last_3d last_3d;
 } I830Rec;
 
 #define I830PTR(p) ((I830Ptr)((p)->driverPrivate))
diff --git a/src/i830_dri.c b/src/i830_dri.c
index 8a52750..b844d33 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -1000,6 +1000,8 @@ I830DRISwapContext(ScreenPtr pScreen, DR
       if (I810_DEBUG & DEBUG_VERBOSE_DRI)
 	 ErrorF("i830DRISwapContext (in)\n");
 
+      pI830->last_3d = LAST_3D_OTHER;
+
       if (!pScrn->vtSema)
      	 return;
       pI830->LockHeld = 1;
diff --git a/src/i830_driver.c b/src/i830_driver.c
index f9ca77c..12fc524 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -7041,10 +7041,23 @@ IntelEmitInvarientState(ScrnInfoPtr pScr
 {
    I830Ptr pI830 = I830PTR(pScrn);
    CARD32 ctx_addr;
+#ifdef XF86DRI
+   drmI830Sarea *sarea;
+#endif
 
    if (pI830->noAccel)
       return;
 
+#ifdef XF86DRI
+   if (pI830->directRenderingEnabled) {
+      sarea = DRIGetSAREAPrivate(pScrn->pScreen);
+
+      /* Mark that the X Server was the last holder of the context */
+      if (sarea)
+	 sarea->ctxOwner = DRIGetContext(pScrn->pScreen);
+   }
+#endif
+
    ctx_addr = pI830->ContextMem.Start;
    /* Align to a 2k boundry */
    ctx_addr = ((ctx_addr + 2048 - 1) / 2048) * 2048;
diff --git a/src/i830_exa_render.c b/src/i830_exa_render.c
index 86e11d2..f63313f 100644
--- a/src/i830_exa_render.c
+++ b/src/i830_exa_render.c
@@ -404,6 +404,8 @@ I830EXAPrepareComposite(int op, PictureP
     dst_offset = exaGetPixmapOffset(pDst);
     dst_pitch = exaGetPixmapPitch(pDst);
 
+    pI830->last_3d = LAST_3D_RENDER;
+
     if (!I830TextureSetup(pSrcPicture, pSrc, 0))
 	I830FALLBACK("fail to setup src texture\n");
     if (pMask != NULL) {
diff --git a/src/i830_rotate.c b/src/i830_rotate.c
index 76effa2..3cdb3ae 100644
--- a/src/i830_rotate.c
+++ b/src/i830_rotate.c
@@ -211,11 +211,6 @@ I915UpdateRotate (ScreenPtr      pScreen
    struct matrix23 rotMatrix;
    int j;
    int use_fence;
-   Bool updateInvarient = FALSE;
-#ifdef XF86DRI
-   drmI830Sarea *sarea = NULL;
-   drm_context_t myContext = 0;
-#endif
    Bool didLock = FALSE;
 
    if (I830IsPrimary(pScrn)) {
@@ -246,58 +241,20 @@ I915UpdateRotate (ScreenPtr      pScreen
    }
 
 #ifdef XF86DRI
-   if (pI8301->directRenderingEnabled) {
-      sarea = DRIGetSAREAPrivate(pScrn1->pScreen);
-      myContext = DRIGetContext(pScrn1->pScreen);
+   if (pI8301->directRenderingEnabled)
       didLock = I830DRILock(pScrn1);
-   }
 #endif
 
+   /* If another screen was active, we don't know the current state. */
    if (pScrn->scrnIndex != *pI830->used3D)
-      updateInvarient = TRUE;
- 
-#ifdef XF86DRI
-   if (sarea && sarea->ctxOwner != myContext)
-      updateInvarient = TRUE;
-#endif
+      pI830->last_3d = LAST_3D_OTHER;
 
-   if (updateInvarient) {
+   if (pI830->last_3d != LAST_3D_ROTATION) {
       FS_LOCALS(3);
       *pI830->used3D = pScrn->scrnIndex;
-#ifdef XF86DRI
-      if (sarea)
-         sarea->ctxOwner = myContext;
-#endif
-      BEGIN_LP_RING(54);
-      /* 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);
+      BEGIN_LP_RING(34);
+      /* invarient state */
 
       /* flush map & render cache */
       OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE);
@@ -313,24 +270,13 @@ I915UpdateRotate (ScreenPtr      pScreen
 
       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(_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);
+	       I1_LOAD_S(2) | I1_LOAD_S(4) | I1_LOAD_S(5) | I1_LOAD_S(6) | 3);
 
       OUT_RING(S2_TEXCOORD_FMT(0, TEXCOORDFMT_2D) |
 	       S2_TEXCOORD_FMT(1, TEXCOORDFMT_NOT_PRESENT) |
@@ -349,14 +295,6 @@ I915UpdateRotate (ScreenPtr      pScreen
 	       (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);
 
@@ -373,9 +311,6 @@ I915UpdateRotate (ScreenPtr      pScreen
 		  DEPTH_FRMT_24_FIXED_8_OTHER);
       }
 
-      OUT_RING(_3DSTATE_STIPPLE);
-      OUT_RING(0x00000000);
-
       /* texture sampler state */
       OUT_RING(_3DSTATE_SAMPLER_STATE | 3);
       OUT_RING(0x00000001);
@@ -493,13 +428,8 @@ I830UpdateRotate (ScreenPtr      pScreen
    CARD32	vb[32];	/* 32 dword vertex buffer */
    float verts[4][2], tex[4][2];
    struct matrix23 rotMatrix;
-   Bool updateInvarient = FALSE;
    int use_fence;
    int j;
-#ifdef XF86DRI
-   drmI830Sarea *sarea = NULL;
-   drm_context_t myContext = 0;
-#endif
    Bool didLock = FALSE;
 
    if (I830IsPrimary(pScrn)) {
@@ -530,28 +460,18 @@ I830UpdateRotate (ScreenPtr      pScreen
    }
 
 #ifdef XF86DRI
-   if (pI8301->directRenderingEnabled) {
-      sarea = DRIGetSAREAPrivate(pScrn1->pScreen);
-      myContext = DRIGetContext(pScrn1->pScreen);
+   if (pI8301->directRenderingEnabled)
       didLock = I830DRILock(pScrn1);
-   }
 #endif
 
    if (pScrn->scrnIndex != *pI830->used3D)
-      updateInvarient = TRUE;
+      pI830->last_3d = LAST_3D_OTHER;
 
-#ifdef XF86DRI
-   if (sarea && sarea->ctxOwner != myContext)
-      updateInvarient = TRUE;
-#endif
-
-   if (updateInvarient) {
+   if (pI830->last_3d != LAST_3D_ROTATION) {
       *pI830->used3D = pScrn->scrnIndex;
-#ifdef XF86DRI
-      if (sarea)
-         sarea->ctxOwner = myContext;
-#endif
-      
+
+      pI830->last_3d = LAST_3D_ROTATION;
+
       BEGIN_LP_RING(48);
       OUT_RING(0x682008a1);
       OUT_RING(0x6f402100);
diff --git a/src/i915_3d.c b/src/i915_3d.c
index e70bb24..ff59171 100644
--- a/src/i915_3d.c
+++ b/src/i915_3d.c
@@ -38,7 +38,7 @@ void I915EmitInvarientState( ScrnInfoPtr
 {
    I830Ptr pI830 = I830PTR(pScrn);
 
-   BEGIN_LP_RING(20);
+   BEGIN_LP_RING(24);
 
    OUT_RING(_3DSTATE_AA_CMD |
 	     AA_LINE_ECAAR_WIDTH_ENABLE |
@@ -46,6 +46,13 @@ void I915EmitInvarientState( ScrnInfoPtr
 	     AA_LINE_REGION_WIDTH_ENABLE |
 	     AA_LINE_REGION_WIDTH_1_0);
 
+   /* Disable independent alpha blend */
+   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_DFLT_DIFFUSE_CMD);
    OUT_RING(0);
 
@@ -76,15 +83,15 @@ void I915EmitInvarientState( ScrnInfoPtr
 	     ENABLE_TEXKILL_3D_4D |
 	     TEXKILL_4D);
 
-   /* Need to initialize this to zero.
-    */
+   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(3) | 0);
-   OUT_RING(0);
- 
-   /* XXX: Use this */
-   OUT_RING(_3DSTATE_SCISSOR_ENABLE_CMD | 
-	     DISABLE_SCISSOR_RECT);
+   OUT_RING(0x00000000);	/* Disable texture coordinate wrap-shortest */
 
+   OUT_RING(_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT);
    OUT_RING(_3DSTATE_SCISSOR_RECT_0_CMD);
    OUT_RING(0);
    OUT_RING(0);
@@ -94,12 +101,11 @@ void I915EmitInvarientState( ScrnInfoPtr
    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(_3DSTATE_STIPPLE);
+   OUT_RING(0x00000000);
+
+   OUT_RING(_3DSTATE_BACKFACE_STENCIL_OPS | BFO_ENABLE_STENCIL_TWO_SIDE | 0 );
+   OUT_RING(MI_NOOP);
 
-   OUT_RING(0);
-   
    ADVANCE_LP_RING();
 }
diff --git a/src/i915_exa_render.c b/src/i915_exa_render.c
index 13fe3ee..eae8171 100644
--- a/src/i915_exa_render.c
+++ b/src/i915_exa_render.c
@@ -329,6 +329,8 @@ I915EXAPrepareComposite(int op, PictureP
     ErrorF("Enter i915 prepareComposite\n");
 #endif
 
+    pI830->last_3d = LAST_3D_RENDER;
+
     I915GetDestFormat(pDstPicture, &dst_format);
     dst_offset = exaGetPixmapOffset(pDst);
     dst_pitch = exaGetPixmapPitch(pDst);
@@ -383,7 +385,7 @@ I915EXAPrepareComposite(int op, PictureP
     {
 	CARD32 ss2;
 
-	BEGIN_LP_RING(26);
+	BEGIN_LP_RING(18);
 	/* color buffer
 	 * XXX: Need to add USE_FENCE if we ever tile the X Server's pixmaps or
 	 * visible screen.
@@ -391,23 +393,12 @@ I915EXAPrepareComposite(int op, PictureP
 	OUT_RING(_3DSTATE_BUF_INFO_CMD);
 	OUT_RING(BUF_3D_ID_COLOR_BACK| BUF_3D_PITCH(dst_pitch));
 	OUT_RING(BUF_3D_ADDR(dst_offset));
-	OUT_RING(MI_NOOP);
 
 	OUT_RING(_3DSTATE_DST_BUF_VARS_CMD);
 	OUT_RING(dst_format);
 
-	/* XXX: defaults */
-	OUT_RING(_3DSTATE_DFLT_Z_CMD);
-	OUT_RING(0x00000000);
-
-	OUT_RING(_3DSTATE_DFLT_DIFFUSE_CMD);
-	OUT_RING(0x00000000);
-
-	OUT_RING(_3DSTATE_DFLT_SPEC_CMD);
-	OUT_RING(0x00000000);
-
 	OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) |
-		 I1_LOAD_S(3) | I1_LOAD_S(4) | I1_LOAD_S(5) | I1_LOAD_S(6) | 4);
+		 I1_LOAD_S(4) | I1_LOAD_S(5) | I1_LOAD_S(6) | 3);
 	ss2 = S2_TEXCOORD_FMT(0, TEXCOORDFMT_2D);
 	if (pMask)
 		ss2 |= S2_TEXCOORD_FMT(1, TEXCOORDFMT_2D);
@@ -420,7 +411,6 @@ I915EXAPrepareComposite(int op, PictureP
 	ss2 |= S2_TEXCOORD_FMT(6, TEXCOORDFMT_NOT_PRESENT);
 	ss2 |= S2_TEXCOORD_FMT(7, TEXCOORDFMT_NOT_PRESENT);
 	OUT_RING(ss2);
-	OUT_RING(0x00000000); /* Disable texture coordinate wrap-shortest */
 	OUT_RING((1 << S4_POINT_WIDTH_SHIFT) | S4_LINE_WIDTH_ONE |
 		 S4_CULLMODE_NONE| S4_VFMT_XY);
 	blendctl = I915GetBlendCntl(op, pMaskPicture, pDstPicture->format);
diff --git a/src/i915_video.c b/src/i915_video.c
index 0833d50..aa192af 100644
--- a/src/i915_video.c
+++ b/src/i915_video.c
@@ -89,35 +89,9 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
     */
    *pI830->used3D |= 1 << 30;
 
-   BEGIN_LP_RING(44);
+   pI830->last_3d = LAST_3D_VIDEO;
 
-   /* 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 */
+   BEGIN_LP_RING(24);
 
    /* flush map & render cache */
    OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE);
@@ -132,25 +106,13 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
    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);
+	    I1_LOAD_S(4) | I1_LOAD_S(5) | I1_LOAD_S(6) | 3);
    s2 = S2_TEXCOORD_FMT(0, TEXCOORDFMT_2D);
    if (planar)
       s2 |= S2_TEXCOORD_FMT(1, TEXCOORDFMT_2D);
@@ -171,12 +133,6 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
 	    (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);
 
@@ -189,9 +145,6 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
    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 |
diff-tree 0bdcce2e4541c6e441c44aad49254ad3093cedb2 (from c3666a968b1cfac61b7867874d5fbe2acd894720)
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Oct 26 14:30:46 2006 -0700

    Note alignment requirement for i915 3D (texturing).

diff --git a/src/i830_exa.c b/src/i830_exa.c
index a1c7546..7de5617 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -457,6 +457,7 @@ I830EXAInit(ScreenPtr pScreen)
 	/* disable Xv here... */
     }
 
+    /* i915 3D requires 16 byte alignment (4k if tiled) */
     pI830->EXADriverPtr->pixmapOffsetAlign = 256;
     pI830->EXADriverPtr->pixmapPitchAlign = 64;
 
diff-tree c3666a968b1cfac61b7867874d5fbe2acd894720 (from f272f0d811f9ee059e8f8617a516e6c8bff917a1)
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Oct 26 14:30:25 2006 -0700

    Don't write unused values beyond the end of scale_units array.

diff --git a/src/i915_exa_render.c b/src/i915_exa_render.c
index 3bc2c0b..13fe3ee 100644
--- a/src/i915_exa_render.c
+++ b/src/i915_exa_render.c
@@ -332,8 +332,6 @@ I915EXAPrepareComposite(int op, PictureP
     I915GetDestFormat(pDstPicture, &dst_format);
     dst_offset = exaGetPixmapOffset(pDst);
     dst_pitch = exaGetPixmapPitch(pDst);
-    scale_units[2][0] = pDst->drawable.width;
-    scale_units[2][1] = pDst->drawable.height;
     FS_LOCALS(20);
 
     if (!I915TextureSetup(pSrcPicture, pSrc, 0))
diff-tree f272f0d811f9ee059e8f8617a516e6c8bff917a1 (from parents)
Merge: ff202f8e2ae4117b464c94047001023d5d0531cc b3ddcf3348365873aed4a2b8b2750b330fb4cf26
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Mon Sep 25 14:15:21 2006 +0800

    Merge branch 'master' into exa

diff --cc src/Makefile.am
index e58350c,ce7b40e..163cc3f
@@@ -64,12 -65,15 +65,19 @@@
  	 i915_3d.c \
  	 i915_3d.h \
  	 i915_reg.h \
 -	 i915_video.c
 +	 i915_video.c \
 +	 i830_exa.c \
 +	 i830_xaa.c \
 +	 i830_exa_render.c \
 +	 i915_exa_render.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-tree ff202f8e2ae4117b464c94047001023d5d0531cc (from 1681fe6bb041385e5aefb11baa9afd1f614abc5b)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Fri Sep 22 15:02:19 2006 +0800

    Fix a typo to mark sync for XAA.
    
    This should fix the scrolling screen corrupt in
    XAA method.

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 10a329c..4d9de0c 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -8900,7 +8900,7 @@ i830MarkSync(ScrnInfoPtr pScrn)
 
 #ifdef I830_USE_XAA
    if (!pI830->useEXA && pI830->AccelInfoRec)
-      pI830->AccelInfoRec->NeedToSync = FALSE;
+      pI830->AccelInfoRec->NeedToSync = TRUE;
 #endif
 #ifdef I830_USE_EXA
    if (pI830->useEXA && pI830->EXADriverPtr) {
diff-tree 1681fe6bb041385e5aefb11baa9afd1f614abc5b (from 5adb05f0b82ee3a168142d803ab3434f75cf15a3)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Wed Sep 20 09:36:02 2006 +0800

    Revert "fix default tex wrap mode with clamp"
    
    oops, we've set border color to all zero, which should
    give us transparent in RepeatNone case.

diff --git a/src/i915_exa_render.c b/src/i915_exa_render.c
index 55d5c94..3bc2c0b 100644
--- a/src/i915_exa_render.c
+++ b/src/i915_exa_render.c
@@ -255,7 +255,7 @@ I915TextureSetup(PicturePtr pPict, Pixma
     I830Ptr pI830 = I830PTR(pScrn);
     CARD32 format, offset, pitch, filter;
     int w, h, i;
-    CARD32 wrap_mode = TEXCOORDMODE_CLAMP_EDGE;
+    CARD32 wrap_mode = TEXCOORDMODE_CLAMP_BORDER;
 
     offset = exaGetPixmapOffset(pPix);
     pitch = exaGetPixmapPitch(pPix);
diff-tree 5adb05f0b82ee3a168142d803ab3434f75cf15a3 (from e3ab89b0327ef6ff790ab53bba29c721aef032cd)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Tue Sep 19 17:14:05 2006 +0800

    fix default tex wrap mode with clamp
    
    we don't set any 'default' border color,
    default tex wrap mode should be clamp to edge.

diff --git a/src/i915_exa_render.c b/src/i915_exa_render.c
index 3bc2c0b..55d5c94 100644
--- a/src/i915_exa_render.c
+++ b/src/i915_exa_render.c
@@ -255,7 +255,7 @@ I915TextureSetup(PicturePtr pPict, Pixma
     I830Ptr pI830 = I830PTR(pScrn);
     CARD32 format, offset, pitch, filter;
     int w, h, i;
-    CARD32 wrap_mode = TEXCOORDMODE_CLAMP_BORDER;
+    CARD32 wrap_mode = TEXCOORDMODE_CLAMP_EDGE;
 
     offset = exaGetPixmapOffset(pPix);
     pitch = exaGetPixmapPitch(pPix);
diff-tree e3ab89b0327ef6ff790ab53bba29c721aef032cd (from 37429c3ecb97df8faf0f3f56128d7a2b22eb8a5e)
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Sep 19 10:27:36 2006 +0800

    shader program fix for component alpha set
    
    If CA is set and blend op needs src alpha, the src
    value is not needed and should be (src.A * mask.X).
    This is found in handling exa magic two pass composite.

diff --git a/src/i915_exa_render.c b/src/i915_exa_render.c
index 62b2507..3bc2c0b 100644
--- a/src/i915_exa_render.c
+++ b/src/i915_exa_render.c
@@ -473,15 +473,23 @@ I915EXAPrepareComposite(int op, PictureP
 	if (PICT_FORMAT_A(pMaskPicture->format) == 0)
 	    i915_fs_mov_masked(FS_R1, MASK_W, i915_fs_operand_one());
 
-	/* If component alpha is set in the mask, then we need to provide
-	 * the source alpha component (channelwise multiplication) as the
-	 * output color.  If it isn't set, then we need to provide the
-	 * source value component, which is the multipliction of the source
-	 * by the mask alpha.
+	/* If component alpha is set in the mask and the blend operation
+	 * uses the source alpha, then we know we don't need the source
+	 * value (otherwise we would have hit a fallback earlier), so we
+	 * provide the source alpha (src.A * mask.X) as output color.
+	 * Conversely, if CA is set and we don't need the source alpha, then
+	 * we produce the source value (src.X * mask.X) and the source alpha
+	 * is unused..  Otherwise, we provide the non-CA source value
+	 * (src.X * mask.A).
 	 */
-	if (pMaskPicture->componentAlpha && pDstPicture->format != PICT_a8) {
-	    i915_fs_mul(FS_OC, i915_fs_operand_reg(FS_R0),
-			i915_fs_operand_reg(FS_R1));
+	if (pMaskPicture->componentAlpha) {
+	    if (I915BlendOp[op].src_alpha) {
+		i915_fs_mul(FS_OC, i915_fs_operand(FS_R0, W, W, W, W),
+			    i915_fs_operand_reg(FS_R1));
+	    } else {
+		i915_fs_mul(FS_OC, i915_fs_operand_reg(FS_R0),
+			    i915_fs_operand_reg(FS_R1));
+	    }
 	} else {
 	    i915_fs_mul(FS_OC, i915_fs_operand_reg(FS_R0),
 			i915_fs_operand(FS_R1, W, W, W, W));
diff-tree 37429c3ecb97df8faf0f3f56128d7a2b22eb8a5e (from bd758030a6a59af32f9d73655cb691e018e94a7d)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Tue Sep 19 10:08:31 2006 +0800

    misc cleanup

diff --git a/src/i830_exa.c b/src/i830_exa.c
index c633747..a1c7546 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -197,8 +197,8 @@ I830EXASolid(PixmapPtr pPixmap, int x1, 
 	    OUT_RING(XY_COLOR_BLT_CMD);
 
 	OUT_RING(pI830->BR[13]);
-	OUT_RING((y1 << 16) | x1);
-	OUT_RING((y2 << 16) | x2);
+	OUT_RING((y1 << 16) | (x1 & 0xffff));
+	OUT_RING((y2 << 16) | (x2 & 0xffff));
 	OUT_RING(offset);
 	OUT_RING(pI830->BR[16]);
 	ADVANCE_LP_RING();
@@ -255,12 +255,11 @@ I830EXACopy(PixmapPtr pDstPixmap, int sr
     ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
     I830Ptr pI830 = I830PTR(pScrn);
     int dst_x2, dst_y2;
-    unsigned int src_off, dst_off;
+    unsigned int dst_off;
 
     dst_x2 = dst_x1 + w;
     dst_y2 = dst_y1 + h;
 
-    src_off = pI830->copy_src_off;
     dst_off = exaGetPixmapOffset(pDstPixmap);
 
     {
@@ -278,7 +277,7 @@ I830EXACopy(PixmapPtr pDstPixmap, int sr
 	OUT_RING(dst_off);
 	OUT_RING((src_y1 << 16) | (src_x1 & 0xffff));
 	OUT_RING(pI830->copy_src_pitch);
-	OUT_RING(src_off);
+	OUT_RING(pI830->copy_src_off);
 
 	ADVANCE_LP_RING();
     }
@@ -298,7 +297,6 @@ static void
 IntelEXAComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
 		 int dstX, int dstY, int w, int h)
 {
-	/* should be same like I830Composite */
     ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
     I830Ptr pI830 = I830PTR(pScrn);
     int srcXend, srcYend, maskXend, maskYend;
diff-tree bd758030a6a59af32f9d73655cb691e018e94a7d (from f46c70e877a3432ba23696e1a16d5906183876af)
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Sep 14 11:12:03 2006 -0700

    Add a compile flag to enable syncing after each operation in EXA.
    
    This replaces other debug sync options sprinkled around the EXA code.  It
    doesn't change the mis-rendering of text on the 915.

diff --git a/src/i830_exa.c b/src/i830_exa.c
index 6a7028f..c633747 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -41,6 +41,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define DEBUG_I830FALLBACK 1
 #endif
 
+#define ALWAYS_SYNC		1
+
 #ifdef DEBUG_I830FALLBACK
 #define I830FALLBACK(s, arg...)				\
 do {							\
@@ -206,7 +208,11 @@ I830EXASolid(PixmapPtr pPixmap, int x1, 
 static void
 I830EXADoneSolid(PixmapPtr pPixmap)
 {
-    return;
+#if ALWAYS_SYNC
+    ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
+
+    I830Sync(pScrn);
+#endif
 }
 
 /**
@@ -281,7 +287,11 @@ I830EXACopy(PixmapPtr pDstPixmap, int sr
 static void
 I830EXADoneCopy(PixmapPtr pDstPixmap)
 {
-    	return;
+#if ALWAYS_SYNC
+    ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
+
+    I830Sync(pScrn);
+#endif
 }
 
 static void
@@ -399,17 +409,16 @@ IntelEXAComposite(PixmapPtr pDst, int sr
 	}
 	ADVANCE_LP_RING();
     }
-#ifdef I830DEBUG
-    ErrorF("sync after 3dprimitive");
-    I830Sync(pScrn);
-#endif
-
 }
 
 static void
 IntelEXADoneComposite(PixmapPtr pDst)
 {
-    return; 
+#if ALWAYS_SYNC
+    ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
+
+    I830Sync(pScrn);
+#endif
 }
 /*
  * TODO:
diff --git a/src/i915_exa_render.c b/src/i915_exa_render.c
index cb96898..62b2507 100644
--- a/src/i915_exa_render.c
+++ b/src/i915_exa_render.c
@@ -312,11 +312,6 @@ I915TextureSetup(PicturePtr pPict, Pixma
         is_transform[unit] = FALSE;
     }
 
-#ifdef I830DEBUG
-    ErrorF("try to sync to show any errors...");
-    I830Sync(pScrn);
-#endif
-
     return TRUE;
 }
 
@@ -494,10 +489,5 @@ I915EXAPrepareComposite(int op, PictureP
     }
     FS_END();
 
-#ifdef I830DEBUG
-    ErrorF("try to sync to show any errors...");
-    I830Sync(pScrn);
-#endif
-
     return TRUE;
 }
diff-tree f46c70e877a3432ba23696e1a16d5906183876af (from ce00db054bf0b7f62ff0be312d7e3470141922dc)
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Sep 14 10:05:51 2006 -0700

    Add a note on maxX/maxY for the 2D rendering.

diff --git a/src/i830_exa.c b/src/i830_exa.c
index a2382ba..6a7028f 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -452,6 +452,8 @@ I830EXAInit(ScreenPtr pScreen)
 
     pI830->EXADriverPtr->pixmapOffsetAlign = 256;
     pI830->EXADriverPtr->pixmapPitchAlign = 64;
+
+    /* i845 and i945 2D limits rendering to 65536 lines and pitch of 32768. */
     pI830->EXADriverPtr->maxX = 4095;
     pI830->EXADriverPtr->maxY = 4095;
 
diff-tree ce00db054bf0b7f62ff0be312d7e3470141922dc (from 71c2dd63361be9616c77db80a93445307d63dd41)
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Sep 14 10:00:06 2006 -0700

    Replace a couple of mis-uses of the screen's bpp when the pixmap's was needed.

diff --git a/src/i830_exa.c b/src/i830_exa.c
index 4009327..a2382ba 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -229,7 +229,7 @@ I830EXAPrepareCopy(PixmapPtr pSrcPixmap,
     pI830->BR[13] = exaGetPixmapPitch(pDstPixmap);
     pI830->BR[13] |= I830CopyROP[alu] << 16;
 
-    switch (pScrn->bitsPerPixel) {
+    switch (pSrcPixmap->drawable.bitsPerPixel) {
     case 8:
 	break;
     case 16:
@@ -260,7 +260,7 @@ I830EXACopy(PixmapPtr pDstPixmap, int sr
     {
 	BEGIN_LP_RING(8);
 
-	if (pScrn->bitsPerPixel == 32)
+	if (pDstPixmap->drawable.bitsPerPixel == 32)
 	    OUT_RING(XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
 		     XY_SRC_COPY_BLT_WRITE_RGB);
 	else
diff-tree 71c2dd63361be9616c77db80a93445307d63dd41 (from 59ce4180b95270432540624a1fdf7ae8dd18a7f3)
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Sep 14 09:54:19 2006 -0700

    Replace duplicated sync code in exa with a call to I830Sync.
    
    The I830Sync version has additional code for the 965.

diff --git a/src/i830_exa.c b/src/i830_exa.c
index 2bab0c7..4009327 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -123,38 +123,16 @@ extern Bool I915EXAPrepareComposite(int,
  * @pScreen: current screen
  * @marker: marker command to wait for
  *
- * Wait for the command specified by @marker to finish, then return.
+ * Wait for the command specified by @marker to finish, then return.  We don't
+ * actually do marker waits, though we might in the future.  For now, just
+ * wait for a full idle.
  */
 static void
 I830EXASync(ScreenPtr pScreen, int marker)
 {
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-    I830Ptr pI830 = I830PTR(pScrn);
-
-#ifdef XF86DRI
-    /* VT switching tries to do this. */
-    if (!pI830->LockHeld && pI830->directRenderingEnabled)
-	return;
-#endif
-
-    if (pI830->entityPrivate && !pI830->entityPrivate->RingRunning)
-	return;
-
-    /* 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_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;
+    I830Sync(pScrn);
 }
 
 /**
diff-tree 59ce4180b95270432540624a1fdf7ae8dd18a7f3 (from 2b7602847aa7ae9b4e88fbea070710695d2cb8a4)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Mon Sep 11 22:57:23 2006 +0800

    reimplement Solid function
    
    Replace COLOR_BLT_CMD with XY_COLOR_BLT_CMD, by which
    device would care for direction and provide a (x,y) coord
    interface. This fixes pixmap artifacts even in no composite
    case.

diff --git a/src/i830_exa.c b/src/i830_exa.c
index 2544760..2bab0c7 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -159,9 +159,6 @@ I830EXASync(ScreenPtr pScreen, int marke
 
 /**
  * I830EXAPrepareSolid - prepare for a Solid operation, if possible
- *
- * TODO:
- *   - support planemask using FILL_MONO_SRC_BLT_CMD?
  */
 static Bool
 I830EXAPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg)
@@ -173,6 +170,9 @@ I830EXAPrepareSolid(PixmapPtr pPixmap, i
     if (!EXA_PM_IS_SOLID(&pPixmap->drawable, planemask))
 	I830FALLBACK("planemask is not solid");
 
+    if (pPixmap->drawable.bitsPerPixel == 24)
+	I830FALLBACK("solid 24bpp unsupported!\n");
+
     offset = exaGetPixmapOffset(pPixmap);
     pitch = exaGetPixmapPitch(pPixmap);
 
@@ -181,25 +181,21 @@ I830EXAPrepareSolid(PixmapPtr pPixmap, i
     if ( pitch % pI830->EXADriverPtr->pixmapPitchAlign != 0)
 	I830FALLBACK("pixmap pitch not aligned");
 
-    pI830->BR[13] = pitch;
-    pI830->BR[13] |= I830PatternROP[alu] << 16;
-
-    pI830->BR[16] = fg;
-
-    /*
-     * Depth: 00 - 8 bit, 01 - 16 bit, 10 - 24 bit, 11 - 32 bit
-     */
-    switch (pScrn->bitsPerPixel) {
-    case 8:
-	pI830->BR[13] |= ((0 << 25) | (0 << 24));
-	break;
-    case 16:
-	pI830->BR[13] |= ((0 << 25) | (1 << 24));
-	break;
-    case 32:
-	pI830->BR[13] |= ((1 << 25) | (1 << 24));
-	break;
+    pI830->BR[13] = (pitch & 0xffff);
+    switch (pPixmap->drawable.bitsPerPixel) {
+	case 8:
+	    break;
+	case 16:
+	    /* RGB565 */
+	    pI830->BR[13] |= (1 << 24);
+	    break;
+	case 32:
+	    /* RGB8888 */
+	    pI830->BR[13] |= ((1 << 24) | (1 << 25));
+	    break;
     }
+    pI830->BR[13] |= (I830PatternROP[alu] & 0xff) << 16 ;
+    pI830->BR[16] = fg;
     return TRUE;
 }
 
@@ -208,32 +204,23 @@ I830EXASolid(PixmapPtr pPixmap, int x1, 
 {
     ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
     I830Ptr pI830 = I830PTR(pScrn);
-    int h, w;
     unsigned long offset;
 
-    /* pixmap's offset and pitch is aligned, 
-       otherwise it falls back in PrepareSolid */
-    offset = exaGetPixmapOffset(pPixmap) + y1 * exaGetPixmapPitch(pPixmap) +
-	x1 * (pPixmap->drawable.bitsPerPixel / 8);
+    offset = exaGetPixmapOffset(pPixmap);  
     
-    h = y2 - y1;
-    w = x2 - x1;
-
     {
 	BEGIN_LP_RING(6);
-
-	if (pScrn->bitsPerPixel == 32)
-	    OUT_RING(COLOR_BLT_CMD | COLOR_BLT_WRITE_ALPHA |
-		     COLOR_BLT_WRITE_RGB);
+	if (pPixmap->drawable.bitsPerPixel == 32)
+	    OUT_RING(XY_COLOR_BLT_CMD | XY_COLOR_BLT_WRITE_ALPHA
+			| XY_COLOR_BLT_WRITE_RGB);
 	else
-	    OUT_RING(COLOR_BLT_CMD);
+	    OUT_RING(XY_COLOR_BLT_CMD);
 
 	OUT_RING(pI830->BR[13]);
-	OUT_RING((h << 16) | (w * (pPixmap->drawable.bitsPerPixel/8)));
+	OUT_RING((y1 << 16) | x1);
+	OUT_RING((y2 << 16) | x2);
 	OUT_RING(offset);
 	OUT_RING(pI830->BR[16]);
-	OUT_RING(0);
-
 	ADVANCE_LP_RING();
     }
 }
diff-tree 2b7602847aa7ae9b4e88fbea070710695d2cb8a4 (from parents)
Merge: e4cdc42a98dd1be74e5c2bf5d9566f7449523b14 b45f4b54b189a496255ddae12af38fc4c4408a51
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Sep 8 11:02:41 2006 -0700

    Merge branch 'exa-origin' into exa
    
    Conflicts:
    
    	src/i915_exa_render.c

diff-tree e4cdc42a98dd1be74e5c2bf5d9566f7449523b14 (from 099be52a3bb52516fb5e8d56c154a4d6b6707e09)
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Sep 7 10:32:02 2006 -0700

    Remove another debug printf.

diff --git a/src/i830_exa.c b/src/i830_exa.c
index 1074649..230c8a7 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -339,7 +339,6 @@ IntelEXAComposite(PixmapPtr pDst, int sr
 	    scale_units[1][0], scale_units[1][1]);
 
     if (scale_units[1][0] == -1 || scale_units[1][1] == -1) {
-	ErrorF("mask is null\n");
 	pMask = 0;
     }
 
diff-tree 099be52a3bb52516fb5e8d56c154a4d6b6707e09 (from 4ad577f83f7190df4d64e66fbf7c515ee6f411ce)
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Sep 7 10:28:09 2006 -0700

    Re-remove xf86_ansic.h, and move copyright to the top of the file.

diff --git a/src/i830_exa.c b/src/i830_exa.c
index 0829c34..1074649 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -31,7 +31,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #include "config.h"
 #endif
 
-#include "xf86_ansic.h"
 #include "xf86.h"
 #include "xaarop.h"
 #include "i830.h"
diff --git a/src/i830_xaa.c b/src/i830_xaa.c
index 9f3a391..d4cc743 100644
--- a/src/i830_xaa.c
+++ b/src/i830_xaa.c
@@ -1,17 +1,3 @@
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "xf86_ansic.h"
-#include "xf86.h"
-#include "xaarop.h"
-#include "i830.h"
-#include "i810_reg.h"
-
-#ifndef DO_SCANLINE_IMAGE_WRITE
-#define DO_SCANLINE_IMAGE_WRITE 0
-#endif
-
 /**************************************************************************
 
 Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
@@ -58,6 +44,19 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
  *
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "xf86.h"
+#include "xaarop.h"
+#include "i830.h"
+#include "i810_reg.h"
+
+#ifndef DO_SCANLINE_IMAGE_WRITE
+#define DO_SCANLINE_IMAGE_WRITE 0
+#endif
+
 /* I830 Accel Functions */
 static void I830SetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
 					   int pattx, int patty,
diff-tree 4ad577f83f7190df4d64e66fbf7c515ee6f411ce (from c378328ece701756ddca966eb108e2b1f5c3ed6c)
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Sep 7 10:24:23 2006 -0700

    Remove the UTS/DFS implementations that just match the fallback versions.

diff --git a/src/i830_exa.c b/src/i830_exa.c
index bb75b24..0829c34 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -112,11 +112,6 @@ union intfloat {
 Bool is_transform[2];
 PictTransform *transform[2];
 
-Bool i830UploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, 
-			    char *src, int src_pitch);
-Bool i830DownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h,
-			    char *dst, int dst_pitch);
-
 extern Bool I830EXACheckComposite(int, PicturePtr, PicturePtr, PicturePtr);
 extern Bool I830EXAPrepareComposite(int, PicturePtr, PicturePtr, PicturePtr, 
 				PixmapPtr, PixmapPtr, PixmapPtr);
@@ -325,61 +320,6 @@ I830EXADoneCopy(PixmapPtr pDstPixmap)
     	return;
 }
 
-static Bool
-I830EXAUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, 
-		char *src, int src_pitch)
-{
-    ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
-    I830Ptr pI830 = I830PTR(pScrn);
-    int dst_pitch = exaGetPixmapPitch(pDst);
-    int dst_offset = exaGetPixmapOffset(pDst);
-    unsigned char *dst;
-
-    I830Sync(pScrn);
-
-#ifdef I830DEBUG
-    ErrorF("Up->Screen: dst offset 0x%x, dst pitch %d, x %d, y %d, src %p, src pitch %d\n",
-		dst_offset, dst_pitch, x, y, src, src_pitch);
-#endif
-    dst = pI830->FbBase + dst_offset + y*dst_pitch + 
-		x* (pDst->drawable.bitsPerPixel/8);
-    w *= pDst->drawable.bitsPerPixel/8;
-    while(h--) {
-	memcpy(dst, src, w);
-	src += src_pitch;
-	dst += dst_pitch;
-    }
-
-    return TRUE;
-}
-
-static Bool
-I830EXADownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h,
-			  char *dst, int dst_pitch)
-{
-    ScrnInfoPtr pScrn = xf86Screens[pSrc->drawable.pScreen->myNum];
-    I830Ptr pI830 = I830PTR(pScrn);
-    int src_pitch = exaGetPixmapPitch(pSrc);
-    int src_offset = exaGetPixmapOffset(pSrc);
-    unsigned char *src = pI830->FbBase + src_offset + y*src_pitch +
-		x*(pSrc->drawable.bitsPerPixel/8);
-
-    I830Sync(pScrn);
-
-#ifdef I830DEBUG
-    ErrorF("Screen->Mem: src offset 0x%x, src %p, src pitch %d, x %d, y %d, dst %p, dst_pitch %d\n",
-	src_offset, src, src_pitch, x, y, dst, dst_pitch);
-#endif
-    w *= pSrc->drawable.bitsPerPixel/8;
-    while(h--) {
-	memcpy(dst, src, w);
-	src += src_pitch;
-	dst += dst_pitch;
-    }
-
-    return TRUE;
-}
-
 static void
 IntelEXAComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
 		 int dstX, int dstY, int w, int h)
@@ -578,10 +518,6 @@ I830EXAInit(ScreenPtr pScreen)
     	pI830->EXADriverPtr->DoneComposite = IntelEXADoneComposite;
     }
 
-    /* Upload, download to/from Screen, experimental!! */
-    pI830->EXADriverPtr->UploadToScreen = I830EXAUploadToScreen;
-    pI830->EXADriverPtr->DownloadFromScreen = I830EXADownloadFromScreen;
-
     if(!exaDriverInit(pScreen, pI830->EXADriverPtr)) {
 	xfree(pI830->EXADriverPtr);
 	pI830->noAccel = TRUE;
diff-tree c378328ece701756ddca966eb108e2b1f5c3ed6c (from 7458a6adb5ea62f56bb3d4ab19ad7d1aa6ad2d19)
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Sep 6 11:15:17 2006 -0700

    Remove a debug printf.

diff --git a/src/i915_exa_render.c b/src/i915_exa_render.c
index 90240b8..ef3cf2a 100644
--- a/src/i915_exa_render.c
+++ b/src/i915_exa_render.c
@@ -330,8 +330,6 @@ I915EXAPrepareComposite(int op, PictureP
     CARD32 dst_format, dst_offset, dst_pitch;
     CARD32 blendctl;
 
-    ErrorF("i915 prepareComposite\n");
-
     I915GetDestFormat(pDstPicture, &dst_format);
     dst_offset = exaGetPixmapOffset(pDst);
     dst_pitch = exaGetPixmapPitch(pDst);
diff-tree b45f4b54b189a496255ddae12af38fc4c4408a51 (from cc79b3ec19a7e858972228a270ef774041eb8946)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Fri Aug 25 16:23:18 2006 +0800

    Making render log a little quiet in normal

diff --git a/src/i915_exa_render.c b/src/i915_exa_render.c
index 90240b8..cb96898 100644
--- a/src/i915_exa_render.c
+++ b/src/i915_exa_render.c
@@ -330,7 +330,9 @@ I915EXAPrepareComposite(int op, PictureP
     CARD32 dst_format, dst_offset, dst_pitch;
     CARD32 blendctl;
 
-    ErrorF("i915 prepareComposite\n");
+#ifdef I830DEBUG
+    ErrorF("Enter i915 prepareComposite\n");
+#endif
 
     I915GetDestFormat(pDstPicture, &dst_format);
     dst_offset = exaGetPixmapOffset(pDst);
diff-tree cc79b3ec19a7e858972228a270ef774041eb8946 (from 078af29fa65653c5322b006404f7ad29aec24cce)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Thu Aug 24 10:28:59 2006 +0800

    Current 915 render operations for 915G/945G only

diff --git a/src/i830_exa.c b/src/i830_exa.c
index bb75b24..c2d3303 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -566,12 +566,14 @@ I830EXAInit(ScreenPtr pScreen)
     pI830->EXADriverPtr->DoneCopy = I830EXADoneCopy;
 
     /* Composite */
-    if (IS_I9XX(pI830)) {   		
+    if (IS_I915G(pI830) || IS_I915GM(pI830) || 
+	IS_I945G(pI830) || IS_I945GM(pI830)) {   		
 	pI830->EXADriverPtr->CheckComposite = I915EXACheckComposite;
    	pI830->EXADriverPtr->PrepareComposite = I915EXAPrepareComposite;
     	pI830->EXADriverPtr->Composite = IntelEXAComposite;
     	pI830->EXADriverPtr->DoneComposite = IntelEXADoneComposite;
-    } else if (IS_I865G(pI830) || IS_I855(pI830) || IS_845G(pI830) || IS_I830(pI830)) { 
+    } else if (IS_I865G(pI830) || IS_I855(pI830) || 
+	IS_845G(pI830) || IS_I830(pI830)) { 
     	pI830->EXADriverPtr->CheckComposite = I830EXACheckComposite;
     	pI830->EXADriverPtr->PrepareComposite = I830EXAPrepareComposite;
     	pI830->EXADriverPtr->Composite = IntelEXAComposite;
diff-tree 078af29fa65653c5322b006404f7ad29aec24cce (from parents)
Merge: 7458a6adb5ea62f56bb3d4ab19ad7d1aa6ad2d19 ea63e82ef417a9918e7d7105910a8ddeba2994f6
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Thu Aug 24 10:23:22 2006 +0800

    Merge branch 'master' into exa
    
    Conflicts:
    
    	man/i810.man
    	src/Makefile.am
    	src/i830_accel.c
    	src/i830_dga.c
    	src/i830_driver.c

diff --cc src/Makefile.am
index c2e49ac,63370ab..e58350c
@@@ -60,10 -64,7 +64,11 @@@
  	 i915_3d.c \
  	 i915_3d.h \
  	 i915_reg.h \
 -	 i915_video.c
++	 i915_video.c \
 +	 i830_exa.c \
 +	 i830_xaa.c \
 +	 i830_exa_render.c \
 +	 i915_exa_render.c
  
  if DRI
  i810_drv_la_SOURCES += \
diff --cc src/i830.h
index 777ffd3,38a880f..df1c171
@@@ -68,17 -70,13 +70,22 @@@
  #include "i830_dri.h"
  #endif
  
 +#ifdef I830_USE_EXA
 +#include "exa.h"
 +Bool I830EXAInit(ScreenPtr pScreen);
 +#endif
 +
 +#ifdef I830_USE_XAA
 +Bool I830XAAInit(ScreenPtr pScreen);
 +#endif
 +
  #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 */
  
  /*
diff --cc src/i830_driver.c
index ed85585,c0d9672..10a329c
@@@ -3712,27 -5638,25 +5711,34 @@@
        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) {
 -      temp = INREG(LP_RING + RING_LEN);
 -      if (temp & 1) {
 -	 I830RefreshRing(pScrn);
 -	 I830Sync(pScrn);
 -	 DO_RING_IDLE();
 -      }
 -   }
 +   /* God this is ugly */
 +#define flush_ring() do { \
 +      temp = INREG(LP_RING + RING_LEN); \
 +      if (temp & 1) { \
 +	 I830RefreshRing(pScrn); \
 +	 I830Sync(pScrn); \
 +	 DO_RING_IDLE(); \
 +      } \
 +   } while(0)
 +#ifdef I830_USE_XAA
 +   if (!pI830->useEXA && flush && pI830->AccelInfoRec)
 +       flush_ring();
 +#endif
 +#ifdef I830_USE_XAA
 +   if (pI830->useEXA && flush && pI830->EXADriverPtr)
 +       flush_ring();
 +#endif
 +
     OUTREG(LP_RING + RING_LEN, 0);
     OUTREG(LP_RING + RING_HEAD, 0);
     OUTREG(LP_RING + RING_TAIL, 0);
@@@ -5311,8 -7509,25 +7591,22 @@@
  	   x, pI830->xoffset, y, pI830->yoffset);
  
     /* Sync the engine before adjust frame */
 -   if (pI830->AccelInfoRec && pI830->AccelInfoRec->NeedToSync) {
 -      (*pI830->AccelInfoRec->Sync)(pScrn);
 -      pI830->AccelInfoRec->NeedToSync = FALSE;
 -   }
 +   i830WaitSync(pScrn);
  
+    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;
+    }
+ 
     if (I830IsPrimary(pScrn))
        Start = pI830->FrontBuffer.Start;
     else {
diff --cc src/i830_xaa.c
index 9f3a391,0000000..6948be0
mode 100644,000000..100644
@@@ -1,658 -1,0 +1,712 @@@
 +#ifdef HAVE_CONFIG_H
 +#include "config.h"
 +#endif
 +
 +#include "xf86_ansic.h"
 +#include "xf86.h"
 +#include "xaarop.h"
 +#include "i830.h"
 +#include "i810_reg.h"
 +
 +#ifndef DO_SCANLINE_IMAGE_WRITE
 +#define DO_SCANLINE_IMAGE_WRITE 0
 +#endif
 +
 +/**************************************************************************
 +
 +Copyright 1998-1999 Precision Insight, 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 PRECISION INSIGHT 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.
 +
 +**************************************************************************/
 +
 +/*
 + * Reformatted with GNU indent (2.2.8), using the following options:
 + *
 + *    -bad -bap -c41 -cd0 -ncdb -ci6 -cli0 -cp0 -ncs -d0 -di3 -i3 -ip3 -l78
 + *    -lp -npcs -psl -sob -ss -br -ce -sc -hnl
 + *
 + * This provides a good match with the original i810 code and preferred
 + * XFree86 formatting conventions.
 + *
 + * When editing this driver, please follow the existing formatting, and edit
 + * with <TAB> characters expanded at 8-column intervals.
 + */
 +
 +/*
 + * Authors:
 + *   Keith Whitwell <keith at tungstengraphics.com>
 + *
 + */
 +
 +/* I830 Accel Functions */
 +static void I830SetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
 +					   int pattx, int patty,
 +					   int fg, int bg, int rop,
 +					   unsigned int planemask);
 +static void I830SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,
 +						 int pattx, int patty,
 +						 int x, int y, int w, int h);
 +
 +static void I830SetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
 +							   int fg, int bg,
 +							   int rop,
 +							   unsigned int mask);
 +
 +static void I830SubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr
 +							     pScrn, int x,
 +							     int y, int w,
 +							     int h,
 +							     int skipleft);
 +
 +static void I830SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno);
 +
 +#if DO_SCANLINE_IMAGE_WRITE
 +static void I830SetupForScanlineImageWrite(ScrnInfoPtr pScrn, int rop,
 +					   unsigned int planemask,
 +					   int trans_color, int bpp,
 +					   int depth);
 +static void I830SubsequentScanlineImageWriteRect(ScrnInfoPtr pScrn,
 +						 int x, int y, int w, int h,
 +						 int skipleft);
 +static void I830SubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno);
 +#endif
 +static void I830RestoreAccelState(ScrnInfoPtr pScrn);
 +
 +#ifdef I830_USE_EXA
 +extern const int I830PatternROP[16];
 +extern const int I830CopyROP[16];
 +#endif
 +
 +Bool
 +I830XAAInit(ScreenPtr pScreen)
 +{
 +    XAAInfoRecPtr infoPtr;
 +    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
 +    I830Ptr pI830 = I830PTR(pScrn);
 +    int i;
 +    int width = 0;
 +    int nr_buffers = 0;
 +    unsigned char *ptr = NULL;
 +
 +    if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
 +	ErrorF("I830XAAInit\n");
 +
 +    pI830->AccelInfoRec = infoPtr = XAACreateInfoRec();
 +    if (!infoPtr)
 +	return FALSE;
 +
 +    pI830->bufferOffset = 0;
 +    infoPtr->Flags = LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS | PIXMAP_CACHE;
 +
 +    /* Use the same sync function as the I830.
 +     */
 +    infoPtr->Sync = I830Sync;
 +
 +    /* Everything else is different enough to justify different functions */
 +    {
 +	infoPtr->SolidFillFlags = NO_PLANEMASK;
 +	infoPtr->SetupForSolidFill = I830SetupForSolidFill;
 +	infoPtr->SubsequentSolidFillRect = I830SubsequentSolidFillRect;
 +    }
 +
 +    {
 +	infoPtr->ScreenToScreenCopyFlags = (NO_PLANEMASK | NO_TRANSPARENCY);
 +
 +	infoPtr->SetupForScreenToScreenCopy = I830SetupForScreenToScreenCopy;
 +	infoPtr->SubsequentScreenToScreenCopy =
 +	    I830SubsequentScreenToScreenCopy;
 +    }
 +
 +    {
 +	infoPtr->SetupForMono8x8PatternFill = I830SetupForMono8x8PatternFill;
 +	infoPtr->SubsequentMono8x8PatternFillRect =
 +	    I830SubsequentMono8x8PatternFillRect;
 +
 +	infoPtr->Mono8x8PatternFillFlags = (HARDWARE_PATTERN_PROGRAMMED_BITS |
 +					    HARDWARE_PATTERN_SCREEN_ORIGIN |
 +					    HARDWARE_PATTERN_PROGRAMMED_ORIGIN|
 +					    BIT_ORDER_IN_BYTE_MSBFIRST |
 +					    NO_PLANEMASK);
 +
 +    }
 +
 +    /* On the primary screen */
 +    if (pI830->init == 0) {
 +	if (pI830->Scratch.Size != 0) {
 +	    width = ((pScrn->displayWidth + 31) & ~31) / 8;
 +	    nr_buffers = pI830->Scratch.Size / width;
 +	    ptr = pI830->FbBase + pI830->Scratch.Start;
 +	}
 +    } else {
 +	/* On the secondary screen */
 +	I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
 +	if (pI8301->Scratch2.Size != 0) {
 +	    width = ((pScrn->displayWidth + 31) & ~31) / 8;
 +	    nr_buffers = pI8301->Scratch2.Size / width;
 +	    /* We have to use the primary screen's FbBase, as that's where
 +	     * we allocated Scratch2, so we get the correct pointer */
 +	    ptr = pI8301->FbBase + pI8301->Scratch2.Start;
 +	}
 +    }
 +
 +    if (nr_buffers) {
 +	pI830->NumScanlineColorExpandBuffers = nr_buffers;
 +	pI830->ScanlineColorExpandBuffers = (unsigned char **)
 +	    xnfcalloc(nr_buffers, sizeof(unsigned char *));
 +
 +	for (i = 0; i < nr_buffers; i++, ptr += width)
 +	    pI830->ScanlineColorExpandBuffers[i] = ptr;
 +
 +	infoPtr->ScanlineCPUToScreenColorExpandFillFlags =
 +	    (NO_PLANEMASK | ROP_NEEDS_SOURCE | BIT_ORDER_IN_BYTE_MSBFIRST);
 +
 +	infoPtr->ScanlineColorExpandBuffers = (unsigned char **)
 +	    xnfcalloc(1, sizeof(unsigned char *));
 +	infoPtr->NumScanlineColorExpandBuffers = 1;
 +
 +	infoPtr->ScanlineColorExpandBuffers[0] =
 +	    pI830->ScanlineColorExpandBuffers[0];
 +	pI830->nextColorExpandBuf = 0;
 +
 +	infoPtr->SetupForScanlineCPUToScreenColorExpandFill =
 +	    I830SetupForScanlineCPUToScreenColorExpandFill;
 +
 +	infoPtr->SubsequentScanlineCPUToScreenColorExpandFill =
 +	    I830SubsequentScanlineCPUToScreenColorExpandFill;
 +
 +	infoPtr->SubsequentColorExpandScanline =
 +	    I830SubsequentColorExpandScanline;
 +
 +#if DO_SCANLINE_IMAGE_WRITE
 +	infoPtr->NumScanlineImageWriteBuffers = 1;
 +	infoPtr->ScanlineImageWriteBuffers =
 +	    infoPtr->ScanlineColorExpandBuffers;
 +	infoPtr->SetupForScanlineImageWrite = I830SetupForScanlineImageWrite;
 +	infoPtr->SubsequentScanlineImageWriteRect =
 +	    I830SubsequentScanlineImageWriteRect;
 +	infoPtr->SubsequentImageWriteScanline =
 +	    I830SubsequentImageWriteScanline;
 +	infoPtr->ScanlineImageWriteFlags = NO_GXCOPY |
 +	    NO_PLANEMASK |
 +	    ROP_NEEDS_SOURCE |
 +	    SCANLINE_PAD_DWORD;
 +#endif
 +    }
 +
 +    {
 +	Bool shared_accel = FALSE;
 +	int i;
 +
 +	for(i = 0; i < pScrn->numEntities; i++) {
 +	    if(xf86IsEntityShared(pScrn->entityList[i]))
 +		shared_accel = TRUE;
 +	}
 +	if(shared_accel == TRUE)
 +	    infoPtr->RestoreAccelState = I830RestoreAccelState;
 +    }
 +
 +    I830SelectBuffer(pScrn, I830_SELECT_FRONT);
 +
 +    return XAAInit(pScreen, infoPtr);
 +}
 +
++#ifdef XF86DRI
++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;
++}
++#else
++#define CheckTiling(pScrn) 0
++#endif
++
 +void
 +I830SetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
 +		      unsigned int planemask)
 +{
 +    I830Ptr pI830 = I830PTR(pScrn);
 +
 +    if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
 +	ErrorF("I830SetupForFillRectSolid color: %x rop: %x mask: %x\n",
 +	       color, rop, planemask);
 +
 +#ifdef I830_USE_EXA
 +    /* This function gets used by I830DRIInitBuffers(), and we might not have
 +     * XAAGetPatternROP() available.  So just use the ROPs from our EXA code
 +     * if available.
 +     */
 +    pI830->BR[13] = ((I830PatternROP[rop] << 16) |
 +		     (pScrn->displayWidth * pI830->cpp));
 +#else
 +    pI830->BR[13] = ((XAAGetPatternROP(rop) << 16) |
 +		     (pScrn->displayWidth * pI830->cpp));
 +#endif
 +
 +    pI830->BR[16] = color;
 +
 +    switch (pScrn->bitsPerPixel) {
 +    case 8:
 +	break;
 +    case 16:
 +	pI830->BR[13] |= (1 << 24);
 +	break;
 +    case 32:
 +	pI830->BR[13] |= ((1 << 25) | (1 << 24));
 +	break;
 +    }
 +}
 +
 +void
 +I830SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h)
 +{
 +    I830Ptr pI830 = I830PTR(pScrn);
 +
 +    if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
 +	ErrorF("I830SubsequentFillRectSolid %d,%d %dx%d\n", x, y, w, h);
 +
 +    {
 +	BEGIN_LP_RING(6);
 +
 +	if (pScrn->bitsPerPixel == 32) {
 +	    OUT_RING(COLOR_BLT_CMD | COLOR_BLT_WRITE_ALPHA |
 +		     COLOR_BLT_WRITE_RGB);
 +	} else {
 +	    OUT_RING(COLOR_BLT_CMD);
 +	}
 +	OUT_RING(pI830->BR[13]);
 +	OUT_RING((h << 16) | (w * pI830->cpp));
 +	OUT_RING(pI830->bufferOffset + (y * pScrn->displayWidth + x) *
 +		 pI830->cpp);
 +	OUT_RING(pI830->BR[16]);
 +	OUT_RING(0);
 +
 +	ADVANCE_LP_RING();
 +    }
++
++    if (IS_I965G(pI830))
++      I830EmitFlush(pScrn);
 +}
 +
 +void
 +I830SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, int rop,
 +			       unsigned int planemask, int transparency_color)
 +{
 +    I830Ptr pI830 = I830PTR(pScrn);
 +
 +    if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
 +	ErrorF("I830SetupForScreenToScreenCopy %d %d %x %x %d\n",
 +	       xdir, ydir, rop, planemask, transparency_color);
 +
 +    pI830->BR[13] = (pScrn->displayWidth * pI830->cpp);
 +#ifdef I830_USE_EXA
 +    /* This function gets used by I830DRIInitBuffers(), and we might not have
 +     * XAAGetCopyROP() available.  So just use the ROPs from our EXA code
 +     * if available.
 +     */
 +    pI830->BR[13] |= I830CopyROP[rop] << 16;
 +#else
 +    pI830->BR[13] |= XAAGetCopyROP(rop) << 16;
 +#endif
 +
 +    switch (pScrn->bitsPerPixel) {
 +    case 8:
 +	break;
 +    case 16:
 +	pI830->BR[13] |= (1 << 24);
 +	break;
 +    case 32:
 +	pI830->BR[13] |= ((1 << 25) | (1 << 24));
 +	break;
 +    }
 +
 +}
 +
 +void
 +I830SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int src_x1, int src_y1,
 +				 int dst_x1, int dst_y1, int w, int h)
 +{
 +    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",
 +	       src_x1, src_y1, dst_x1, dst_y1, w, h);
 +
 +    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));
 +	OUT_RING((dst_y2 << 16) | (dst_x2 & 0xffff));
 +	OUT_RING(pI830->bufferOffset);
 +	OUT_RING((src_y1 << 16) | (src_x1 & 0xffff));
 +	OUT_RING(pI830->BR[13] & 0xFFFF);
 +	OUT_RING(pI830->bufferOffset);
 +
 +	ADVANCE_LP_RING();
 +    }
++
++    if (IS_I965G(pI830))
++      I830EmitFlush(pScrn);
 +}
 +
 +static void
 +I830SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int pattx, int patty,
 +			       int fg, int bg, int rop,
 +			       unsigned int planemask)
 +{
 +    I830Ptr pI830 = I830PTR(pScrn);
 +
 +    if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
 +	ErrorF("I830SetupForMono8x8PatternFill\n");
 +
 +    pI830->BR[16] = pattx;
 +    pI830->BR[17] = patty;
 +    pI830->BR[18] = bg;
 +    pI830->BR[19] = fg;
 +
 +    pI830->BR[13] = (pScrn->displayWidth * pI830->cpp);	/* In bytes */
 +    pI830->BR[13] |= XAAGetPatternROP(rop) << 16;
 +    if (bg == -1)
 +	pI830->BR[13] |= (1 << 28);
 +
 +    switch (pScrn->bitsPerPixel) {
 +    case 8:
 +	break;
 +    case 16:
 +	pI830->BR[13] |= (1 << 24);
 +	break;
 +    case 32:
 +	pI830->BR[13] |= ((1 << 25) | (1 << 24));
 +	break;
 +    }
 +
 +}
 +
 +static void
 +I830SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int pattx, int patty,
 +				     int x, int y, int w, int h)
 +{
 +    I830Ptr pI830 = I830PTR(pScrn);
 +    int x1, x2, y1, y2;
++    unsigned int tiled = CheckTiling(pScrn);
 +
 +    x1 = x;
 +    x2 = x + w;
 +    y1 = y;
 +    y2 = y + h;
 +
 +    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 |
++		     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 |
++	    OUT_RING(XY_MONO_PAT_BLT_CMD | tiled << 11 |
 +		     ((patty << 8) & XY_MONO_PAT_VERT_SEED) |
 +		     ((pattx << 12) & XY_MONO_PAT_HORT_SEED));
 +	}
 +	OUT_RING(pI830->BR[13]);
 +	OUT_RING((y1 << 16) | x1);
 +	OUT_RING((y2 << 16) | x2);
 +	OUT_RING(pI830->bufferOffset);
 +	OUT_RING(pI830->BR[18]);		/* bg */
 +	OUT_RING(pI830->BR[19]);		/* fg */
 +	OUT_RING(pI830->BR[16]);		/* pattern data */
 +	OUT_RING(pI830->BR[17]);
 +	OUT_RING(0);
 +	ADVANCE_LP_RING();
 +    }
++
++    if (IS_I965G(pI830))
++      I830EmitFlush(pScrn);
 +}
 +
 +static void
 +I830GetNextScanlineColorExpandBuffer(ScrnInfoPtr pScrn)
 +{
 +    I830Ptr pI830 = I830PTR(pScrn);
 +    XAAInfoRecPtr infoPtr = pI830->AccelInfoRec;
 +
 +    if (pI830->nextColorExpandBuf == pI830->NumScanlineColorExpandBuffers)
 +	I830Sync(pScrn);
 +
 +    infoPtr->ScanlineColorExpandBuffers[0] =
 +	pI830->ScanlineColorExpandBuffers[pI830->nextColorExpandBuf];
 +
 +    if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
 +	ErrorF("using color expand buffer %d\n", pI830->nextColorExpandBuf);
 +
 +    pI830->nextColorExpandBuf++;
 +}
 +
 +static void
 +I830SetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
 +					       int fg, int bg, int rop,
 +					       unsigned int planemask)
 +{
 +    I830Ptr pI830 = I830PTR(pScrn);
 +
 +    if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
 +	ErrorF("I830SetupForScanlineScreenToScreenColorExpand %d %d %x %x\n",
 +	       fg, bg, rop, planemask);
 +
 +    /* Fill out register values */
 +    pI830->BR[13] = (pScrn->displayWidth * pI830->cpp);
 +    pI830->BR[13] |= XAAGetCopyROP(rop) << 16;
 +    if (bg == -1)
 +	pI830->BR[13] |= (1 << 29);
 +
 +    switch (pScrn->bitsPerPixel) {
 +    case 8:
 +	break;
 +    case 16:
 +	pI830->BR[13] |= (1 << 24);
 +	break;
 +    case 32:
 +	pI830->BR[13] |= ((1 << 25) | (1 << 24));
 +	break;
 +    }
 +
 +    pI830->BR[18] = bg;
 +    pI830->BR[19] = fg;
 +
 +    I830GetNextScanlineColorExpandBuffer(pScrn);
 +}
 +
 +static void
 +I830SubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
 +						 int x, int y,
 +						 int w, int h, int skipleft)
 +{
 +    I830Ptr pI830 = I830PTR(pScrn);
 +
 +    if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
 +	ErrorF("I830SubsequentScanlineCPUToScreenColorExpandFill "
 +	       "%d,%d %dx%x %d\n", x, y, w, h, skipleft);
 +
 +    /* Fill out register values */
 +    pI830->BR[9] = (pI830->bufferOffset +
 +		    (y * pScrn->displayWidth + x) * pI830->cpp);
 +    pI830->BR[11] = ((1 << 16) | w);
 +}
 +
 +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] -
 +			 pI830->FbBase);
 +    } else {
 +	I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
 +
 +	/* We have to use the primary screen's FbBase, as that's where
 +	 * we allocated Scratch2, so we get the correct pointer */
 +	pI830->BR[12] = (pI830->AccelInfoRec->ScanlineColorExpandBuffers[0] -
 +			 pI8301->FbBase);
 +    }
 +
 +    if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
 +	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 |
- 		     XY_MONO_SRC_BLT_WRITE_RGB);
++		     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 */
 +	OUT_RING(pI830->BR[11]);		/* x2 = w, y2 = 1 */
 +	OUT_RING(pI830->BR[9]);		/* dst addr */
 +	OUT_RING(pI830->BR[12]);		/* src addr */
 +	OUT_RING(pI830->BR[18]);		/* bg */
 +	OUT_RING(pI830->BR[19]);		/* fg */
 +
 +	ADVANCE_LP_RING();
 +    }
 +
 +    /* Advance to next scanline.
 +     */
 +    pI830->BR[9] += pScrn->displayWidth * pI830->cpp;
 +    I830GetNextScanlineColorExpandBuffer(pScrn);
++
++    if (IS_I965G(pI830))
++      I830EmitFlush(pScrn);
 +}
 +
 +#if DO_SCANLINE_IMAGE_WRITE
 +static void
 +I830SetupForScanlineImageWrite(ScrnInfoPtr pScrn, int rop,
 +			       unsigned int planemask, int trans_color,
 +			       int bpp, int depth)
 +{
 +    I830Ptr pI830 = I830PTR(pScrn);
 +
 +    if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
 +	ErrorF("I830SetupForScanlineImageWrite %x %x\n", rop, planemask);
 +
 +    /* Fill out register values */
 +    pI830->BR[13] = (pScrn->displayWidth * pI830->cpp);
 +    pI830->BR[13] |= XAAGetCopyROP(rop) << 16;
 +
 +    switch (pScrn->bitsPerPixel) {
 +    case 8:
 +	break;
 +    case 16:
 +	pI830->BR[13] |= (1 << 24);
 +	break;
 +    case 32:
 +	pI830->BR[13] |= ((1 << 25) | (1 << 24));
 +	break;
 +    }
 +
 +    I830GetNextScanlineColorExpandBuffer(pScrn);
 +}
 +
 +static void
 +I830SubsequentScanlineImageWriteRect(ScrnInfoPtr pScrn, int x, int y,
 +				     int w, int h, int skipleft)
 +{
 +    I830Ptr pI830 = I830PTR(pScrn);
 +
 +    if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
 +	ErrorF("I830SubsequentScanlineImageWriteRect "
 +	       "%d,%d %dx%x %d\n", x, y, w, h, skipleft);
 +
 +    /* Fill out register values */
 +    pI830->BR[9] = (pI830->bufferOffset +
 +		    (y * pScrn->displayWidth + x) * pI830->cpp);
 +    pI830->BR[11] = ((1 << 16) | w);
 +}
 +
 +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] -
 +			 pI830->FbBase);
 +    } else {
 +	I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
 +
 +	/* We have to use the primary screen's FbBase, as that's where
 +	 * we allocated Scratch2, so we get the correct pointer */
 +	pI830->BR[12] = (pI830->AccelInfoRec->ScanlineColorExpandBuffers[0] -
 +			 pI8301->FbBase);
 +    }
 +
 +    if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
 +	ErrorF("I830SubsequentImageWriteScanline %d (addr %x)\n",
 +	       bufno, pI830->BR[12]);
 +
 +    {
 +	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);
++		     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 */
++	OUT_RING(0);				/* x1 = 0, y1 = 0 */
 +	OUT_RING(pI830->BR[11]);		/* x2 = w, y2 = 1 */
- 	OUT_RING(pI830->BR[9]);		/* dst addr */
- 	OUT_RING(0);			/* source origin (0,0) */
++	OUT_RING(pI830->BR[9]);			/* dst addr */
++	OUT_RING(0);				/* source origin (0,0) */
 +	OUT_RING(pI830->BR[11] & 0xffff);	/* source pitch */
 +	OUT_RING(pI830->BR[12]);		/* src addr */
 +
 +	ADVANCE_LP_RING();
 +    }
 +
 +    /* Advance to next scanline.
 +     */
 +    pI830->BR[9] += pScrn->displayWidth * pI830->cpp;
 +    I830GetNextScanlineColorExpandBuffer(pScrn);
 +}
 +#endif /* DO_SCANLINE_IMAGE_WRITE */
 +/* Support for multiscreen */
 +
 +static void
 +I830RestoreAccelState(ScrnInfoPtr pScrn)
 +{
 +#if 0
 +   /* might be needed, but everything is on a ring, so I don't think so */
 +   I830Sync(pScrn);
 +#endif
 +}
 +
diff-tree 7458a6adb5ea62f56bb3d4ab19ad7d1aa6ad2d19 (from 7ea74843bbdbf54b6804727be9b41d26832c8f76)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Mon Jul 31 10:09:17 2006 -0700

    Move MAPSURF_XBIT settings into the texture formats structure.

diff --git a/src/i915_exa_render.c b/src/i915_exa_render.c
index 24b5752..90240b8 100644
--- a/src/i915_exa_render.c
+++ b/src/i915_exa_render.c
@@ -109,14 +109,14 @@ static struct blendinfo I915BlendOp[] = 
 };
 
 static struct formatinfo I915TexFormats[] = {
-        {PICT_a8r8g8b8, MT_32BIT_ARGB8888 },
-        {PICT_x8r8g8b8, MT_32BIT_XRGB8888 },
-        {PICT_a8b8g8r8, MT_32BIT_ABGR8888 },
-        {PICT_x8b8g8r8, MT_32BIT_XBGR8888 },
-        {PICT_r5g6b5,   MT_16BIT_RGB565   },
-        {PICT_a1r5g5b5, MT_16BIT_ARGB1555 },
-        {PICT_x1r5g5b5, MT_16BIT_ARGB1555 },
-        {PICT_a8,       MT_8BIT_A8 	  },
+        {PICT_a8r8g8b8, MAPSURF_32BIT | MT_32BIT_ARGB8888 },
+        {PICT_x8r8g8b8, MAPSURF_32BIT | MT_32BIT_XRGB8888 },
+        {PICT_a8b8g8r8, MAPSURF_32BIT | MT_32BIT_ABGR8888 },
+        {PICT_x8b8g8r8, MAPSURF_32BIT | MT_32BIT_XBGR8888 },
+        {PICT_r5g6b5,   MAPSURF_16BIT | MT_16BIT_RGB565   },
+        {PICT_a1r5g5b5, MAPSURF_16BIT | MT_16BIT_ARGB1555 },
+        {PICT_x1r5g5b5, MAPSURF_16BIT | MT_16BIT_ARGB1555 },
+        {PICT_a8,       MAPSURF_8BIT | MT_8BIT_A8 	  },
 };
 
 static CARD32 I915GetBlendCntl(int op, PicturePtr pMask, CARD32 dst_format)
@@ -289,13 +289,6 @@ I915TextureSetup(PicturePtr pPict, Pixma
         I830FALLBACK("Bad filter 0x%x\n", pPict->filter);
     }
 
-    if (pPix->drawable.bitsPerPixel == 8)
-	format |= MAPSURF_8BIT;
-    else if (pPix->drawable.bitsPerPixel == 16)
-	format |= MAPSURF_16BIT;
-    else
-	format |= MAPSURF_32BIT;
-
     mapstate[unit * 3 + 0] = offset;
     mapstate[unit * 3 + 1] = format |
 	((pPix->drawable.height - 1) << MS3_HEIGHT_SHIFT) |
diff-tree 7ea74843bbdbf54b6804727be9b41d26832c8f76 (from 30952e58ed83e2e18d1007f662d2cc9a773c876c)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Mon Jul 31 10:06:34 2006 -0700

    Whitespace cleanup.

diff --git a/src/i915_exa_render.c b/src/i915_exa_render.c
index 9769765..24b5752 100644
--- a/src/i915_exa_render.c
+++ b/src/i915_exa_render.c
@@ -49,7 +49,7 @@ do {							\
 #define I830FALLBACK(s, arg...) 			\
 do { 							\
 	return FALSE;					\
-} while(0) 
+} while(0)
 #endif
 
 extern float scale_units[2][2];
@@ -79,7 +79,7 @@ I915EXAPrepareComposite(int op, PictureP
 			PicturePtr pMaskPicture, PicturePtr pDstPicture,
 			PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst);
 
-static struct blendinfo I915BlendOp[] = { 
+static struct blendinfo I915BlendOp[] = {
     /* Clear */
     {0, 0, BLENDFACT_ZERO,          BLENDFACT_ZERO},
     /* Src */
@@ -148,8 +148,8 @@ static CARD32 I915GetBlendCntl(int op, P
         }
     }
 
-    return (sblend <<S6_CBUF_SRC_BLEND_FACT_SHIFT) |
-	(dblend <<S6_CBUF_DST_BLEND_FACT_SHIFT);
+    return (sblend << S6_CBUF_SRC_BLEND_FACT_SHIFT) |
+	(dblend << S6_CBUF_DST_BLEND_FACT_SHIFT);
 }
 
 static Bool I915GetDestFormat(PicturePtr pDstPicture, CARD32 *dst_format)
@@ -193,7 +193,7 @@ static Bool I915CheckCompositeTexture(Pi
     int w = pPict->pDrawable->width;
     int h = pPict->pDrawable->height;
     int i;
-                                                                                                                                                            
+
     if ((w > 0x7ff) || (h > 0x7ff))
         I830FALLBACK("Picture w/h too large (%dx%d)\n", w, h);
 
@@ -222,11 +222,10 @@ I915EXACheckComposite(int op, PicturePtr
 		      PicturePtr pDstPicture)
 {
     CARD32 tmp1;
-    
+
     /* Check for unsupported compositing operations. */
     if (op >= sizeof(I915BlendOp) / sizeof(I915BlendOp[0]))
         I830FALLBACK("Unsupported Composite op 0x%x\n", op);
-                                                                                                                                                            
     if (pMaskPicture != NULL && pMaskPicture->componentAlpha) {
         /* Check if it's component alpha that relies on a source alpha and on
          * the source value.  We can only get one of those into the single
@@ -243,7 +242,7 @@ I915EXACheckComposite(int op, PicturePtr
     if (pMaskPicture != NULL && !I915CheckCompositeTexture(pMaskPicture, 1))
         I830FALLBACK("Check Mask picture texture\n");
 
-    if (!I915GetDestFormat(pDstPicture, &tmp1)) 
+    if (!I915GetDestFormat(pDstPicture, &tmp1))
 	I830FALLBACK("Get Color buffer format\n");
 
     return TRUE;
@@ -269,20 +268,20 @@ I915TextureSetup(PicturePtr pPict, Pixma
         if (I915TexFormats[i].fmt == pPict->format)
 	    break;
     }
-    if ( i == sizeof(I915TexFormats)/ sizeof(I915TexFormats[0]) )
+    if (i == sizeof(I915TexFormats)/ sizeof(I915TexFormats[0]))
 	I830FALLBACK("unknown texture format\n");
     format = I915TexFormats[i].card_fmt;
 
-    if (pPict->repeat) 
+    if (pPict->repeat)
 	wrap_mode = TEXCOORDMODE_WRAP;
 
     switch (pPict->filter) {
     case PictFilterNearest:
-        filter = (FILTER_NEAREST << SS2_MAG_FILTER_SHIFT) | 
+        filter = (FILTER_NEAREST << SS2_MAG_FILTER_SHIFT) |
 			(FILTER_NEAREST << SS2_MIN_FILTER_SHIFT);
         break;
     case PictFilterBilinear:
-        filter = (FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) | 
+        filter = (FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) |
 			(FILTER_LINEAR << SS2_MIN_FILTER_SHIFT);
         break;
     default:
@@ -305,7 +304,8 @@ I915TextureSetup(PicturePtr pPict, Pixma
 	samplerstate[unit * 3 + 1] |= MS3_USE_FENCE_REGS;
     mapstate[unit * 3 + 2] = ((pitch / 4) - 1) << MS4_PITCH_SHIFT;
 
-    samplerstate[unit * 3 + 0] = (MIPFILTER_NONE << SS2_MIP_FILTER_SHIFT) | filter;
+    samplerstate[unit * 3 + 0] = (MIPFILTER_NONE << SS2_MIP_FILTER_SHIFT);
+    samplerstate[unit * 3 + 0] |= filter;
     samplerstate[unit * 3 + 1] = SS3_NORMALIZED_COORDS;
     samplerstate[unit * 3 + 1] |= wrap_mode << SS3_TCX_ADDR_MODE_SHIFT;
     samplerstate[unit * 3 + 1] |= wrap_mode << SS3_TCY_ADDR_MODE_SHIFT;
@@ -323,7 +323,7 @@ I915TextureSetup(PicturePtr pPict, Pixma
     ErrorF("try to sync to show any errors...");
     I830Sync(pScrn);
 #endif
-	
+
     return TRUE;
 }
 
@@ -337,7 +337,7 @@ I915EXAPrepareComposite(int op, PictureP
     CARD32 dst_format, dst_offset, dst_pitch;
     CARD32 blendctl;
 
-ErrorF("i915 prepareComposite\n");
+    ErrorF("i915 prepareComposite\n");
 
     I915GetDestFormat(pDstPicture, &dst_format);
     dst_offset = exaGetPixmapOffset(pDst);
@@ -345,7 +345,7 @@ ErrorF("i915 prepareComposite\n");
     scale_units[2][0] = pDst->drawable.width;
     scale_units[2][1] = pDst->drawable.height;
     FS_LOCALS(20);
-    
+
     if (!I915TextureSetup(pSrcPicture, pSrc, 0))
 	I830FALLBACK("fail to setup src texture\n");
     if (pMask != NULL) {
@@ -396,12 +396,15 @@ ErrorF("i915 prepareComposite\n");
 	CARD32 ss2;
 
 	BEGIN_LP_RING(26);
-	/*color buffer*/
+	/* color buffer
+	 * XXX: Need to add USE_FENCE if we ever tile the X Server's pixmaps or
+	 * visible screen.
+	 */
 	OUT_RING(_3DSTATE_BUF_INFO_CMD);
-	OUT_RING(BUF_3D_ID_COLOR_BACK| BUF_3D_PITCH(dst_pitch)); /* fence, tile? */
+	OUT_RING(BUF_3D_ID_COLOR_BACK| BUF_3D_PITCH(dst_pitch));
 	OUT_RING(BUF_3D_ADDR(dst_offset));
 	OUT_RING(MI_NOOP);
-	
+
 	OUT_RING(_3DSTATE_DST_BUF_VARS_CMD);
 	OUT_RING(dst_format);
 
@@ -414,9 +417,8 @@ ErrorF("i915 prepareComposite\n");
 
 	OUT_RING(_3DSTATE_DFLT_SPEC_CMD);
 	OUT_RING(0x00000000);
-	
-	/* XXX:S3? define vertex format with tex coord sets number*/
-	OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) | 
+
+	OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) |
 		 I1_LOAD_S(3) | I1_LOAD_S(4) | I1_LOAD_S(5) | I1_LOAD_S(6) | 4);
 	ss2 = S2_TEXCOORD_FMT(0, TEXCOORDFMT_2D);
 	if (pMask)
@@ -431,8 +433,8 @@ ErrorF("i915 prepareComposite\n");
 	ss2 |= S2_TEXCOORD_FMT(7, TEXCOORDFMT_NOT_PRESENT);
 	OUT_RING(ss2);
 	OUT_RING(0x00000000); /* Disable texture coordinate wrap-shortest */
-	OUT_RING((1<<S4_POINT_WIDTH_SHIFT)|S4_LINE_WIDTH_ONE| 
-		S4_CULLMODE_NONE| S4_VFMT_XY);  
+	OUT_RING((1 << S4_POINT_WIDTH_SHIFT) | S4_LINE_WIDTH_ONE |
+		 S4_CULLMODE_NONE| S4_VFMT_XY);
 	blendctl = I915GetBlendCntl(op, pMaskPicture, pDstPicture->format);
 	OUT_RING(0x00000000); /* Disable stencil buffer */
 	OUT_RING(S6_CBUF_BLEND_ENABLE | S6_COLOR_WRITE_ENABLE |
diff-tree 30952e58ed83e2e18d1007f662d2cc9a773c876c (from cffd2cd36d0437b38ac8164d66ea71be50b19330)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Wed Jul 26 13:42:12 2006 -0700

    Limit drawing to the destination pixmap's boundaries, not the screen's.
    
    This shouldn't matter, as miComputeCompositeRegion shouldn't giving us
    anything that would draw outside the bounds, anyway.

diff --git a/src/i915_exa_render.c b/src/i915_exa_render.c
index 7b2eada..9769765 100644
--- a/src/i915_exa_render.c
+++ b/src/i915_exa_render.c
@@ -446,7 +446,8 @@ ErrorF("i915 prepareComposite\n");
 	OUT_RING(_3DSTATE_DRAW_RECT_CMD);
 	OUT_RING(0x00000000);
 	OUT_RING(0x00000000);  /* ymin, xmin*/
-	OUT_RING(DRAW_YMAX(pScrn->virtualY-1) | DRAW_XMAX(pScrn->virtualX-1));
+	OUT_RING(DRAW_YMAX(pDst->drawable.height - 1) |
+		 DRAW_XMAX(pDst->drawable.width - 1));
 	OUT_RING(0x00000000);  /* yorig, xorig (relate to color buffer?)*/
 	OUT_RING(MI_NOOP);
 	ADVANCE_LP_RING();
diff-tree cffd2cd36d0437b38ac8164d66ea71be50b19330 (from 96754b822df7ac110a70b2d08dda2ebb299772be)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Wed Jul 26 13:22:51 2006 -0700

    Fix hangs when compositing with a mask.
    
    The modify bits in the mask field for sampler/map state appear to actually
    be enable bits.  So, prepare the state values in I915TextureSetup,
    then write the sampler/map state out all at once in PrepareComposite.

diff --git a/src/i915_exa_render.c b/src/i915_exa_render.c
index 74c85e0..7b2eada 100644
--- a/src/i915_exa_render.c
+++ b/src/i915_exa_render.c
@@ -55,6 +55,8 @@ do { 							\
 extern float scale_units[2][2];
 extern Bool is_transform[2];
 extern PictTransform *transform[2];
+static CARD32 mapstate[6];
+static CARD32 samplerstate[6];
 
 struct formatinfo {
     int fmt;
@@ -288,50 +290,27 @@ I915TextureSetup(PicturePtr pPict, Pixma
         I830FALLBACK("Bad filter 0x%x\n", pPict->filter);
     }
 
-    {
-	CARD32 ms3;
-	if (pPix->drawable.bitsPerPixel == 8)
-		format |= MAPSURF_8BIT;
-	else if (pPix->drawable.bitsPerPixel == 16)
-		format |= MAPSURF_16BIT;
-	else
-		format |= MAPSURF_32BIT;
-
-	BEGIN_LP_RING(6);
-	OUT_RING(_3DSTATE_MAP_STATE | 3);
-	OUT_RING(1<<unit);
-	OUT_RING(offset); /* Must be 4-byte aligned */
-	ms3 = ((pPix->drawable.height - 1) << MS3_HEIGHT_SHIFT) | 
-		((pPix->drawable.width - 1) << MS3_WIDTH_SHIFT) | format;
-	if (!pI830->disableTiling)
-		ms3 |= MS3_USE_FENCE_REGS;
-	OUT_RING(ms3); 
-	OUT_RING(((pitch / 4) - 1) << MS4_PITCH_SHIFT);
-	OUT_RING(MI_NOOP);
-	ADVANCE_LP_RING();
-     }
-
-     {
-	CARD32 ss2, ss3;
-	BEGIN_LP_RING(6);
-	/* max & min mip level ? or base mip level? */
-
-	OUT_RING(_3DSTATE_SAMPLER_STATE | 3);
-	OUT_RING(1<<unit);
-	ss2 = (MIPFILTER_NONE << SS2_MIP_FILTER_SHIFT);
-	ss2 |= filter;
-	OUT_RING(ss2);
-	/* repeat? */
-	ss3 = wrap_mode << SS3_TCX_ADDR_MODE_SHIFT;
-	ss3 |= wrap_mode << SS3_TCY_ADDR_MODE_SHIFT;
-	ss3 |= SS3_NORMALIZED_COORDS;
-	ss3 |= (unit << SS3_TEXTUREMAP_INDEX_SHIFT);
-	OUT_RING(ss3);
-	OUT_RING(0x00000000); /* border color */
-	OUT_RING(MI_NOOP);
-
-	ADVANCE_LP_RING();
-    }
+    if (pPix->drawable.bitsPerPixel == 8)
+	format |= MAPSURF_8BIT;
+    else if (pPix->drawable.bitsPerPixel == 16)
+	format |= MAPSURF_16BIT;
+    else
+	format |= MAPSURF_32BIT;
+
+    mapstate[unit * 3 + 0] = offset;
+    mapstate[unit * 3 + 1] = format |
+	((pPix->drawable.height - 1) << MS3_HEIGHT_SHIFT) |
+	((pPix->drawable.width - 1) << MS3_WIDTH_SHIFT);
+    if (!pI830->disableTiling)
+	samplerstate[unit * 3 + 1] |= MS3_USE_FENCE_REGS;
+    mapstate[unit * 3 + 2] = ((pitch / 4) - 1) << MS4_PITCH_SHIFT;
+
+    samplerstate[unit * 3 + 0] = (MIPFILTER_NONE << SS2_MIP_FILTER_SHIFT) | filter;
+    samplerstate[unit * 3 + 1] = SS3_NORMALIZED_COORDS;
+    samplerstate[unit * 3 + 1] |= wrap_mode << SS3_TCX_ADDR_MODE_SHIFT;
+    samplerstate[unit * 3 + 1] |= wrap_mode << SS3_TCY_ADDR_MODE_SHIFT;
+    samplerstate[unit * 3 + 1] |= unit << SS3_TEXTUREMAP_INDEX_SHIFT;
+    samplerstate[unit * 3 + 2] = 0x00000000; /* border color */
 
     if (pPict->transform != 0) {
         is_transform[unit] = TRUE;
@@ -378,6 +357,41 @@ ErrorF("i915 prepareComposite\n");
 	scale_units[1][1] = -1;
     }
 
+    if (pMask == NULL) {
+	BEGIN_LP_RING(10);
+	OUT_RING(_3DSTATE_MAP_STATE | 3);
+	OUT_RING(0x00000001); /* map 0 */
+	OUT_RING(mapstate[0]);
+	OUT_RING(mapstate[1]);
+	OUT_RING(mapstate[2]);
+
+	OUT_RING(_3DSTATE_SAMPLER_STATE | 3);
+	OUT_RING(0x00000001); /* sampler 0 */
+	OUT_RING(samplerstate[0]);
+	OUT_RING(samplerstate[1]);
+	OUT_RING(samplerstate[2]);
+	ADVANCE_LP_RING();
+    } else {
+	BEGIN_LP_RING(16);
+	OUT_RING(_3DSTATE_MAP_STATE | 6);
+	OUT_RING(0x00000003); /* map 0,1 */
+	OUT_RING(mapstate[0]);
+	OUT_RING(mapstate[1]);
+	OUT_RING(mapstate[2]);
+	OUT_RING(mapstate[3]);
+	OUT_RING(mapstate[4]);
+	OUT_RING(mapstate[5]);
+
+	OUT_RING(_3DSTATE_SAMPLER_STATE | 6);
+	OUT_RING(0x00000003); /* sampler 0,1 */
+	OUT_RING(samplerstate[0]);
+	OUT_RING(samplerstate[1]);
+	OUT_RING(samplerstate[2]);
+	OUT_RING(samplerstate[3]);
+	OUT_RING(samplerstate[4]);
+	OUT_RING(samplerstate[5]);
+	ADVANCE_LP_RING();
+    }
     {
 	CARD32 ss2;
 
diff-tree 96754b822df7ac110a70b2d08dda2ebb299772be (from 9c93d1498fa2363c52ef7fbe97d781560f67acf5)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Wed Jul 26 13:19:12 2006 -0700

    Fix a couple of typos from code review.

diff --git a/src/i915_3d.h b/src/i915_3d.h
index c116200..1090218 100644
--- a/src/i915_3d.h
+++ b/src/i915_3d.h
@@ -33,7 +33,7 @@
 #define MASK_Y			0x2
 #define MASK_Z			0x4
 #define MASK_W			0x8
-#define MASK_XYZ		(MASK_X | MASK_Y | MASK_W)
+#define MASK_XYZ		(MASK_X | MASK_Y | MASK_Z)
 #define MASK_XYZW		(MASK_XYZ | MASK_W)
 #define MASK_SATURATE		0x10
 
@@ -398,7 +398,7 @@ do {									\
 do {									\
     struct i915_fs_op op;						\
 									\
-    op = i915_fs_arith(DP3, dest_reg, operand0, i915_fs_operand_none(),	\
+    op = i915_fs_arith(DP3, dest_reg, operand0, operand1,		\
 		       i915_fs_operand_none());				\
     op.ui[0] &= ~A0_DEST_CHANNEL_ALL;					\
     op.ui[0] |= ((dest_mask) & ~MASK_SATURATE) << A0_DEST_CHANNEL_SHIFT; \
diff-tree 9c93d1498fa2363c52ef7fbe97d781560f67acf5 (from 38d1a5e0dbe059f5c01bd5120a108a386ff10718)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Tue Jul 25 21:17:05 2006 -0700

    Oops, partial revert of last commit.  Some were obviously not NOOPS.

diff --git a/src/i915_exa_render.c b/src/i915_exa_render.c
index 7555b41..74c85e0 100644
--- a/src/i915_exa_render.c
+++ b/src/i915_exa_render.c
@@ -393,13 +393,13 @@ ErrorF("i915 prepareComposite\n");
 
 	/* XXX: defaults */
 	OUT_RING(_3DSTATE_DFLT_Z_CMD);
-	OUT_RING(MI_NOOP);
+	OUT_RING(0x00000000);
 
 	OUT_RING(_3DSTATE_DFLT_DIFFUSE_CMD);
-	OUT_RING(MI_NOOP);
+	OUT_RING(0x00000000);
 
 	OUT_RING(_3DSTATE_DFLT_SPEC_CMD);
-	OUT_RING(MI_NOOP);
+	OUT_RING(0x00000000);
 	
 	/* XXX:S3? define vertex format with tex coord sets number*/
 	OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) | 
diff-tree 38d1a5e0dbe059f5c01bd5120a108a386ff10718 (from aec88cf4c66833f89afa5f8fa4f8bcf30b2b6b4b)
Author: Eric Anholt <anholt at leguin.anholt.net>
Date:   Tue Jul 25 21:09:12 2006 -0700

    Replace some OUT_RING(0)s with OUT_RING(MI_NOOP) to remind me why they're there.

diff --git a/src/i915_exa_render.c b/src/i915_exa_render.c
index 08736cc..7555b41 100644
--- a/src/i915_exa_render.c
+++ b/src/i915_exa_render.c
@@ -307,7 +307,7 @@ I915TextureSetup(PicturePtr pPict, Pixma
 		ms3 |= MS3_USE_FENCE_REGS;
 	OUT_RING(ms3); 
 	OUT_RING(((pitch / 4) - 1) << MS4_PITCH_SHIFT);
-	OUT_RING(0);
+	OUT_RING(MI_NOOP);
 	ADVANCE_LP_RING();
      }
 
@@ -328,7 +328,7 @@ I915TextureSetup(PicturePtr pPict, Pixma
 	ss3 |= (unit << SS3_TEXTUREMAP_INDEX_SHIFT);
 	OUT_RING(ss3);
 	OUT_RING(0x00000000); /* border color */
-	OUT_RING(0);
+	OUT_RING(MI_NOOP);
 
 	ADVANCE_LP_RING();
     }
@@ -393,13 +393,13 @@ ErrorF("i915 prepareComposite\n");
 
 	/* XXX: defaults */
 	OUT_RING(_3DSTATE_DFLT_Z_CMD);
-	OUT_RING(0);
+	OUT_RING(MI_NOOP);
 
 	OUT_RING(_3DSTATE_DFLT_DIFFUSE_CMD);
-	OUT_RING(0);
+	OUT_RING(MI_NOOP);
 
 	OUT_RING(_3DSTATE_DFLT_SPEC_CMD);
-	OUT_RING(0);
+	OUT_RING(MI_NOOP);
 	
 	/* XXX:S3? define vertex format with tex coord sets number*/
 	OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) | 
@@ -426,7 +426,7 @@ ErrorF("i915 prepareComposite\n");
 
 	/* issue a flush */
 	OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE);
-	OUT_RING(0);
+	OUT_RING(MI_NOOP);
 
 	/* draw rect is unconditional */
 	OUT_RING(_3DSTATE_DRAW_RECT_CMD);
@@ -434,7 +434,7 @@ ErrorF("i915 prepareComposite\n");
 	OUT_RING(0x00000000);  /* ymin, xmin*/
 	OUT_RING(DRAW_YMAX(pScrn->virtualY-1) | DRAW_XMAX(pScrn->virtualX-1));
 	OUT_RING(0x00000000);  /* yorig, xorig (relate to color buffer?)*/
-	OUT_RING(0);
+	OUT_RING(MI_NOOP);
 	ADVANCE_LP_RING();
     }
 
diff-tree aec88cf4c66833f89afa5f8fa4f8bcf30b2b6b4b (from 02c5c4cd1dd44058d80ec23cccfd45a13bc3bb2c)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Mon Jul 24 15:46:19 2006 +0800

    remove crap blit in UploadToScreen, we should find a more
    efficent way and implement blit correctly.

diff --git a/src/i830_exa.c b/src/i830_exa.c
index de12c33..bb75b24 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -325,8 +325,6 @@ I830EXADoneCopy(PixmapPtr pDstPixmap)
     	return;
 }
 
-//#define UPLOAD_USE_BLIT 1
-
 static Bool
 I830EXAUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, 
 		char *src, int src_pitch)
@@ -343,7 +341,6 @@ I830EXAUploadToScreen(PixmapPtr pDst, in
     ErrorF("Up->Screen: dst offset 0x%x, dst pitch %d, x %d, y %d, src %p, src pitch %d\n",
 		dst_offset, dst_pitch, x, y, src, src_pitch);
 #endif
-#ifndef UPLOAD_USE_BLIT
     dst = pI830->FbBase + dst_offset + y*dst_pitch + 
 		x* (pDst->drawable.bitsPerPixel/8);
     w *= pDst->drawable.bitsPerPixel/8;
@@ -352,41 +349,6 @@ I830EXAUploadToScreen(PixmapPtr pDst, in
 	src += src_pitch;
 	dst += dst_pitch;
     }
-#else
-    /* setup blit engine to copy one pixel data by one */
-    {
-	int x1, x2, y1, y2, i, j;
-	CARD32 d, len, *srcp;
-	x1 = x;
-	y1 = y;
-	x2 = x + w;
-	y2 = y + h;
-
-	len = (w * (pDst->drawable.bitsPerPixel/8)) >> 2;
-
-	pI830->BR[13] = (1 << 24) | (1 << 25);
-	pI830->BR[13] |= I830CopyROP[GXcopy]<<16;
-	pI830->BR[13] |= dst_pitch & 0xffff;
-	for (i = 0; i < h; i++) {
-		srcp = (CARD32*)src;
-		for ( j = len; j > 0; j--) {
-			d = *srcp;
-			BEGIN_LP_RING(6);
-			OUT_RING(XY_COLOR_BLT_CMD | XY_COLOR_BLT_WRITE_ALPHA | 
-				XY_COLOR_BLT_WRITE_RGB);
-			OUT_RING(pI830->BR[13]);
-			OUT_RING((y1 << 16) | x1);
-			OUT_RING((y2 << 16) | x2);
-			OUT_RING(dst_offset);
-			OUT_RING(d);
-			ADVANCE_LP_RING();
-			srcp++;
-		}
-		src += src_pitch;
-	}
-
-    }
-#endif
 
     return TRUE;
 }
diff-tree 02c5c4cd1dd44058d80ec23cccfd45a13bc3bb2c (from 4f0ad337098eb0bacb1c11bc61d780ac18041e1d)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Fri Jul 21 12:54:06 2006 +0800

    add copyright info

diff --git a/src/i830_exa_render.c b/src/i830_exa_render.c
index 23a3c43..86e11d2 100644
--- a/src/i830_exa_render.c
+++ b/src/i830_exa_render.c
@@ -1,3 +1,31 @@
+/*
+ * 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:
+ *    Wang Zhenyu <zhenyu.z.wang at intel.com>
+ *    Eric Anholt <eric at anholt.net>
+ *
+ */
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
diff --git a/src/i915_exa_render.c b/src/i915_exa_render.c
index 36e6c80..08736cc 100644
--- a/src/i915_exa_render.c
+++ b/src/i915_exa_render.c
@@ -1,4 +1,30 @@
-/* -*- 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:
+ *    Wang Zhenyu <zhenyu.z.wang at intel.com>
+ *    Eric Anholt <eric at anholt.net>
+ *
+ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
diff-tree 4f0ad337098eb0bacb1c11bc61d780ac18041e1d (from 914327f40d07a3f7c069752ce005bf8e21352b03)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Fri Jul 21 11:59:04 2006 +0800

    fixup segfault in xaa when xaa not initialized in i830WaitSync.

diff --git a/src/i830_driver.c b/src/i830_driver.c
index b7a8097..ed85585 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -6425,7 +6425,8 @@ i830WaitSync(ScrnInfoPtr pScrn)
    I830Ptr pI830 = I830PTR(pScrn);
 
 #ifdef I830_USE_XAA
-   if (!pI830->noAccel && !pI830->useEXA && pI830->AccelInfoRec->NeedToSync) {
+   if (!pI830->noAccel && !pI830->useEXA && pI830->AccelInfoRec 
+	&& pI830->AccelInfoRec->NeedToSync) {
       (*pI830->AccelInfoRec->Sync)(pScrn);
       pI830->AccelInfoRec->NeedToSync = FALSE;
    }
diff-tree 914327f40d07a3f7c069752ce005bf8e21352b03 (from 45cb032e2b7ac1e4c765fc29a2e4dd0cef19066d)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Thu Jul 20 17:58:07 2006 -0400

    Disable drawing to PICT_a8, and turn on support for non-extended repeats.
    
    We don't know what COLOR_BUF_8BIT does, so it's disabled for now while we're
    stabilizing the code.
    
    The non-extended repeats appear to be working according to the rendercheck
    tests on a8 and a8r8g8b8 sources.  Masks continue to hang the card, as before
    this change.

diff --git a/src/i915_exa_render.c b/src/i915_exa_render.c
index 795c076..36e6c80 100644
--- a/src/i915_exa_render.c
+++ b/src/i915_exa_render.c
@@ -138,9 +138,16 @@ static Bool I915GetDestFormat(PicturePtr
     case PICT_x1r5g5b5:
         *dst_format = COLR_BUF_ARGB1555;
         break;
+    /* COLR_BUF_8BIT is special for YUV surfaces.  While we may end up being
+     * able to use it depending on how the hardware implements it, disable it
+     * for now while we don't know what exactly it does (what channel does it
+     * read from?
+     */
+    /*
     case PICT_a8:
         *dst_format = COLR_BUF_8BIT;
         break;
+    */
     case PICT_a4r4g4b4:
     case PICT_x4r4g4b4:
 	*dst_format = COLR_BUF_ARGB4444;
@@ -171,9 +178,9 @@ static Bool I915CheckCompositeTexture(Pi
         I830FALLBACK("Unsupported picture format 0x%x\n",
                          (int)pPict->format);
 
-    /* FIXME: fix repeat support */
-    if (pPict->repeat) 
-	I830FALLBACK("repeat not support now!\n");
+    if (pPict->repeat && pPict->repeatType != RepeatNormal)
+	I830FALLBACK("extended repeat (%d) not supported\n",
+		     pPict->repeatType);
 
     if (pPict->filter != PictFilterNearest &&
         pPict->filter != PictFilterBilinear)
diff-tree 45cb032e2b7ac1e4c765fc29a2e4dd0cef19066d (from fd6d825ae0780f3daf436f4224bf5f177cb8630e)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Thu Jul 20 17:34:50 2006 -0400

    Use MT_8BIT_A8 so PICT_a8 expands to (0,0,0,a) not (a,a,a,a)

diff --git a/src/i915_exa_render.c b/src/i915_exa_render.c
index a063d8f..795c076 100644
--- a/src/i915_exa_render.c
+++ b/src/i915_exa_render.c
@@ -88,7 +88,7 @@ static struct formatinfo I915TexFormats[
         {PICT_r5g6b5,   MT_16BIT_RGB565   },
         {PICT_a1r5g5b5, MT_16BIT_ARGB1555 },
         {PICT_x1r5g5b5, MT_16BIT_ARGB1555 },
-        {PICT_a8,       MT_8BIT_I8 	  },
+        {PICT_a8,       MT_8BIT_A8 	  },
 };
 
 static CARD32 I915GetBlendCntl(int op, PicturePtr pMask, CARD32 dst_format)
diff-tree fd6d825ae0780f3daf436f4224bf5f177cb8630e (from d6d6a44c66446f34b57394e5ea9a8e32917f7569)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Thu Jul 20 17:25:31 2006 -0400

    Move ss6 setting with other immediate state, and ensure that stencil is off.

diff --git a/src/i915_exa_render.c b/src/i915_exa_render.c
index deeac4a..a063d8f 100644
--- a/src/i915_exa_render.c
+++ b/src/i915_exa_render.c
@@ -348,7 +348,7 @@ ErrorF("i915 prepareComposite\n");
     {
 	CARD32 ss2;
 
-	BEGIN_LP_RING(24);
+	BEGIN_LP_RING(26);
 	/*color buffer*/
 	OUT_RING(_3DSTATE_BUF_INFO_CMD);
 	OUT_RING(BUF_3D_ID_COLOR_BACK| BUF_3D_PITCH(dst_pitch)); /* fence, tile? */
@@ -369,8 +369,8 @@ ErrorF("i915 prepareComposite\n");
 	OUT_RING(0);
 	
 	/* XXX:S3? define vertex format with tex coord sets number*/
-	OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) |
-		 I1_LOAD_S(3) | I1_LOAD_S(4) | 2);
+	OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) | 
+		 I1_LOAD_S(3) | I1_LOAD_S(4) | I1_LOAD_S(5) | I1_LOAD_S(6) | 4);
 	ss2 = S2_TEXCOORD_FMT(0, TEXCOORDFMT_2D);
 	if (pMask)
 		ss2 |= S2_TEXCOORD_FMT(1, TEXCOORDFMT_2D);
@@ -383,9 +383,13 @@ ErrorF("i915 prepareComposite\n");
 	ss2 |= S2_TEXCOORD_FMT(6, TEXCOORDFMT_NOT_PRESENT);
 	ss2 |= S2_TEXCOORD_FMT(7, TEXCOORDFMT_NOT_PRESENT);
 	OUT_RING(ss2);
-	OUT_RING(0x00000000); /*XXX: does ss3 needed? */
+	OUT_RING(0x00000000); /* Disable texture coordinate wrap-shortest */
 	OUT_RING((1<<S4_POINT_WIDTH_SHIFT)|S4_LINE_WIDTH_ONE| 
 		S4_CULLMODE_NONE| S4_VFMT_XY);  
+	blendctl = I915GetBlendCntl(op, pMaskPicture, pDstPicture->format);
+	OUT_RING(0x00000000); /* Disable stencil buffer */
+	OUT_RING(S6_CBUF_BLEND_ENABLE | S6_COLOR_WRITE_ENABLE |
+		 (BLENDFUNC_ADD << S6_CBUF_BLEND_FUNC_SHIFT) | blendctl);
 
 	/* issue a flush */
 	OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE);
@@ -445,17 +449,6 @@ ErrorF("i915 prepareComposite\n");
     }
     FS_END();
 
-    {
-	CARD32 ss6;
-	blendctl = I915GetBlendCntl(op, pMaskPicture, pDstPicture->format);
-
-	BEGIN_LP_RING(2);
-	OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(6) | 0);
-	ss6 = S6_CBUF_BLEND_ENABLE | S6_COLOR_WRITE_ENABLE;
-	OUT_RING(ss6 | (0 << S6_CBUF_BLEND_FUNC_SHIFT) | blendctl);
-	ADVANCE_LP_RING();
-    }
-
 #ifdef I830DEBUG
     ErrorF("try to sync to show any errors...");
     I830Sync(pScrn);
diff-tree d6d6a44c66446f34b57394e5ea9a8e32917f7569 (from 2b2173c618c080b1678990d65fe49b52bd8001b4)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Thu Jul 20 11:23:05 2006 -0400

    Try to fix up the basic RepeatNormal and RepeatNone support.
    
    With RepeatNone, access outside of the drawable should return 0 alpha values,
    which is done by using the border color.  For RepeatNormal, we use the wrap
    mode (which requires that we use normalized texture coordinates).

diff --git a/src/i915_exa_render.c b/src/i915_exa_render.c
index 6246136..deeac4a 100644
--- a/src/i915_exa_render.c
+++ b/src/i915_exa_render.c
@@ -221,7 +221,7 @@ I915TextureSetup(PicturePtr pPict, Pixma
     I830Ptr pI830 = I830PTR(pScrn);
     CARD32 format, offset, pitch, filter;
     int w, h, i;
-    CARD32 wrap_mode = TEXCOORDMODE_CLAMP_EDGE; 
+    CARD32 wrap_mode = TEXCOORDMODE_CLAMP_BORDER;
 
     offset = exaGetPixmapOffset(pPix);
     pitch = exaGetPixmapPitch(pPix);
@@ -239,8 +239,8 @@ I915TextureSetup(PicturePtr pPict, Pixma
     format = I915TexFormats[i].card_fmt;
 
     if (pPict->repeat) 
-	wrap_mode = TEXCOORDMODE_WRAP; /* XXX:correct ? */
-    
+	wrap_mode = TEXCOORDMODE_WRAP;
+
     switch (pPict->filter) {
     case PictFilterNearest:
         filter = (FILTER_NEAREST << SS2_MAG_FILTER_SHIFT) | 
@@ -289,12 +289,12 @@ I915TextureSetup(PicturePtr pPict, Pixma
 	ss2 |= filter;
 	OUT_RING(ss2);
 	/* repeat? */
-	ss3 = TEXCOORDMODE_WRAP << SS3_TCX_ADDR_MODE_SHIFT;
-	ss3 |= (TEXCOORDMODE_WRAP << SS3_TCY_ADDR_MODE_SHIFT);
+	ss3 = wrap_mode << SS3_TCX_ADDR_MODE_SHIFT;
+	ss3 |= wrap_mode << SS3_TCY_ADDR_MODE_SHIFT;
 	ss3 |= SS3_NORMALIZED_COORDS;
 	ss3 |= (unit << SS3_TEXTUREMAP_INDEX_SHIFT);
 	OUT_RING(ss3);
-	OUT_RING(0x00000000); /* default color */
+	OUT_RING(0x00000000); /* border color */
 	OUT_RING(0);
 
 	ADVANCE_LP_RING();
diff-tree 2b2173c618c080b1678990d65fe49b52bd8001b4 (from 9f1cec83e0aef36c7d3482e62e8f01595f1fd076)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Thu Jul 20 11:15:18 2006 -0400

    The pixmap's drawable x/y coordinates are always 0, so don't bother using them.

diff --git a/src/i830_exa.c b/src/i830_exa.c
index f7c79c2..de12c33 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -56,7 +56,6 @@ do { 							\
 #endif
 
 float scale_units[2][2];
-int draw_coords[3][2];
 
 const int I830CopyROP[16] =
 {
@@ -431,13 +430,12 @@ IntelEXAComposite(PixmapPtr pDst, int sr
     int pMask = 1;
 
     DPRINTF(PFX, "Composite: srcX %d, srcY %d\n\t maskX %d, maskY %d\n\t"
-	     "dstX %d, dstY %d\n\twidth %d, height %d\n\t"
-	     "src_scale_x %f, src_scale_y %f, mask_scale_x %f, mask_scale_y %f\n""\tdx0 %d, dy0 %x, dx1 %d dy1 %x\n", 
-		srcX, srcY, maskX, maskY, dstX, dstY, w, h,
-		scale_units[0][0], scale_units[0][1], 
-		scale_units[1][0], scale_units[1][1],
-		draw_coords[0][0], draw_coords[0][1], 
-		draw_coords[1][0], draw_coords[1][1]);
+	    "dstX %d, dstY %d\n\twidth %d, height %d\n\t"
+	    "src_scale_x %f, src_scale_y %f, "
+	    "mask_scale_x %f, mask_scale_y %f\n",
+	    srcX, srcY, maskX, maskY, dstX, dstY, w, h,
+	    scale_units[0][0], scale_units[0][1],
+	    scale_units[1][0], scale_units[1][1]);
 
     if (scale_units[1][0] == -1 || scale_units[1][1] == -1) {
 	ErrorF("mask is null\n");
@@ -481,13 +479,6 @@ IntelEXAComposite(PixmapPtr pDst, int sr
 		"dstX %d, dstY %d\n", srcX, srcY, srcXend, srcYend,
 		maskX, maskY, maskXend, maskYend, dstX, dstY);
 
-    draw_coords[0][0] -= draw_coords[2][0];
-    draw_coords[0][1] -= draw_coords[2][1];
-    if (pMask) {
-	draw_coords[1][0] -= draw_coords[2][0];
-	draw_coords[1][1] -= draw_coords[2][1];
-    }
-
     {
 	int vertex_count; 
 
@@ -508,38 +499,38 @@ IntelEXAComposite(PixmapPtr pDst, int sr
 
 	OUT_RING_F(dstX);
 	OUT_RING_F(dstY);
-	OUT_RING_F(((srcX - draw_coords[0][0]) / scale_units[0][0]));
-	OUT_RING_F(((srcY - draw_coords[0][1]) / scale_units[0][1]));
+	OUT_RING_F(srcX / scale_units[0][0]);
+	OUT_RING_F(srcY / scale_units[0][1]);
 	if (pMask) {
-		OUT_RING_F(((maskX - draw_coords[1][0]) / scale_units[1][0]));
-		OUT_RING_F(((maskY - draw_coords[1][1]) / scale_units[1][1]));
+		OUT_RING_F(maskX / scale_units[1][0]);
+		OUT_RING_F(maskY / scale_units[1][1]);
 	}
 
 	OUT_RING_F(dstX);
-	OUT_RING_F((dstY+h));
-	OUT_RING_F(((srcX - draw_coords[0][0]) / scale_units[0][0]));
-	OUT_RING_F(((srcYend - draw_coords[0][1]) / scale_units[0][1]));
+	OUT_RING_F(dstY + h);
+	OUT_RING_F(srcX / scale_units[0][0]);
+	OUT_RING_F(srcYend / scale_units[0][1]);
 	if (pMask) {
-		OUT_RING_F(((maskX - draw_coords[1][0]) / scale_units[1][0]));
-		OUT_RING_F(((maskYend - draw_coords[1][1]) / scale_units[1][1]));
+		OUT_RING_F(maskX / scale_units[1][0]);
+		OUT_RING_F(maskYend / scale_units[1][1]);
 	}
 
-	OUT_RING_F((dstX+w));
-	OUT_RING_F((dstY+h));
-	OUT_RING_F(((srcXend - draw_coords[0][0]) / scale_units[0][0]));
-	OUT_RING_F(((srcYend - draw_coords[0][1]) / scale_units[0][1]));
+	OUT_RING_F(dstX + w);
+	OUT_RING_F(dstY + h);
+	OUT_RING_F(srcXend / scale_units[0][0]);
+	OUT_RING_F(srcYend / scale_units[0][1]);
 	if (pMask) {
-		OUT_RING_F(((maskXend - draw_coords[1][0]) / scale_units[1][0]));
-		OUT_RING_F(((maskYend - draw_coords[1][1]) / scale_units[1][1]));
+		OUT_RING_F(maskXend / scale_units[1][0]);
+		OUT_RING_F(maskYend / scale_units[1][1]);
 	}
 
-	OUT_RING_F((dstX+w));
-	OUT_RING_F((dstY));
-	OUT_RING_F(((srcXend - draw_coords[0][0]) / scale_units[0][0]));
-	OUT_RING_F(((srcY - draw_coords[0][1]) / scale_units[0][1]));
+	OUT_RING_F(dstX + w);
+	OUT_RING_F(dstY);
+	OUT_RING_F(srcXend / scale_units[0][0]);
+	OUT_RING_F(srcY / scale_units[0][1]);
 	if (pMask) {
-		OUT_RING_F(((maskXend - draw_coords[1][0]) / scale_units[1][0]));
-		OUT_RING_F(((maskY - draw_coords[1][1]) / scale_units[1][1]));
+		OUT_RING_F(maskXend / scale_units[1][0]);
+		OUT_RING_F(maskY / scale_units[1][1]);
 	}
 	ADVANCE_LP_RING();
     }
diff --git a/src/i830_exa_render.c b/src/i830_exa_render.c
index 7a22e7d..23a3c43 100644
--- a/src/i830_exa_render.c
+++ b/src/i830_exa_render.c
@@ -24,7 +24,6 @@ do { 							\
 #endif
 
 extern float scale_units[2][2];
-extern int draw_coords[3][2];
 extern Bool is_transform[2];
 extern PictTransform *transform[2];
 
@@ -249,8 +248,6 @@ I830TextureSetup(PicturePtr pPict, Pixma
     h = pPict->pDrawable->height;
     scale_units[unit][0] = pPix->drawable.width;
     scale_units[unit][1] = pPix->drawable.height;
-    draw_coords[unit][0] = pPix->drawable.x;
-    draw_coords[unit][1] = pPix->drawable.y;
 
     for (i = 0; i < sizeof(I830TexFormats) / sizeof(I830TexFormats[0]); i++) {
         if (I830TexFormats[i].fmt == pPict->format)
@@ -378,9 +375,7 @@ I830EXAPrepareComposite(int op, PictureP
     I830GetDestFormat(pDstPicture, &dst_format);
     dst_offset = exaGetPixmapOffset(pDst);
     dst_pitch = exaGetPixmapPitch(pDst);
-    draw_coords[2][0] = pDst->drawable.x;
-    draw_coords[2][1] = pDst->drawable.y;
-    
+
     if (!I830TextureSetup(pSrcPicture, pSrc, 0))
 	I830FALLBACK("fail to setup src texture\n");
     if (pMask != NULL) {
diff --git a/src/i915_exa_render.c b/src/i915_exa_render.c
index ba54d53..6246136 100644
--- a/src/i915_exa_render.c
+++ b/src/i915_exa_render.c
@@ -27,7 +27,6 @@ do { 							\
 #endif
 
 extern float scale_units[2][2];
-extern int draw_coords[3][2];
 extern Bool is_transform[2];
 extern PictTransform *transform[2];
 
@@ -230,8 +229,6 @@ I915TextureSetup(PicturePtr pPict, Pixma
     h = pPict->pDrawable->height;
     scale_units[unit][0] = pPix->drawable.width;
     scale_units[unit][1] = pPix->drawable.height;
-    draw_coords[unit][0] = pPix->drawable.x;
-    draw_coords[unit][1] = pPix->drawable.y;
 
     for (i = 0; i < sizeof(I915TexFormats) / sizeof(I915TexFormats[0]); i++) {
         if (I915TexFormats[i].fmt == pPict->format)
@@ -333,8 +330,6 @@ ErrorF("i915 prepareComposite\n");
     I915GetDestFormat(pDstPicture, &dst_format);
     dst_offset = exaGetPixmapOffset(pDst);
     dst_pitch = exaGetPixmapPitch(pDst);
-    draw_coords[2][0] = pDst->drawable.x;
-    draw_coords[2][1] = pDst->drawable.y;
     scale_units[2][0] = pDst->drawable.width;
     scale_units[2][1] = pDst->drawable.height;
     FS_LOCALS(20);
diff-tree 9f1cec83e0aef36c7d3482e62e8f01595f1fd076 (from 4737955a62c39177e7a7ce7749a2f20e111afc68)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Thu Jul 20 11:05:49 2006 -0400

    The vertex data are all floats, so write the dest coords as floats.

diff --git a/src/i830_exa.c b/src/i830_exa.c
index 40f6868..f7c79c2 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -506,8 +506,8 @@ IntelEXAComposite(PixmapPtr pDst, int sr
 
 	OUT_RING(PRIM3D_INLINE | PRIM3D_TRIFAN | (vertex_count-1));
 
-	OUT_RING(dstX);
-	OUT_RING(dstY);
+	OUT_RING_F(dstX);
+	OUT_RING_F(dstY);
 	OUT_RING_F(((srcX - draw_coords[0][0]) / scale_units[0][0]));
 	OUT_RING_F(((srcY - draw_coords[0][1]) / scale_units[0][1]));
 	if (pMask) {
@@ -515,8 +515,8 @@ IntelEXAComposite(PixmapPtr pDst, int sr
 		OUT_RING_F(((maskY - draw_coords[1][1]) / scale_units[1][1]));
 	}
 
-	OUT_RING(dstX);
-	OUT_RING((dstY+h));
+	OUT_RING_F(dstX);
+	OUT_RING_F((dstY+h));
 	OUT_RING_F(((srcX - draw_coords[0][0]) / scale_units[0][0]));
 	OUT_RING_F(((srcYend - draw_coords[0][1]) / scale_units[0][1]));
 	if (pMask) {
@@ -524,8 +524,8 @@ IntelEXAComposite(PixmapPtr pDst, int sr
 		OUT_RING_F(((maskYend - draw_coords[1][1]) / scale_units[1][1]));
 	}
 
-	OUT_RING((dstX+w));
-	OUT_RING((dstY+h));
+	OUT_RING_F((dstX+w));
+	OUT_RING_F((dstY+h));
 	OUT_RING_F(((srcXend - draw_coords[0][0]) / scale_units[0][0]));
 	OUT_RING_F(((srcYend - draw_coords[0][1]) / scale_units[0][1]));
 	if (pMask) {
@@ -533,8 +533,8 @@ IntelEXAComposite(PixmapPtr pDst, int sr
 		OUT_RING_F(((maskYend - draw_coords[1][1]) / scale_units[1][1]));
 	}
 
-	OUT_RING((dstX+w));
-	OUT_RING((dstY));
+	OUT_RING_F((dstX+w));
+	OUT_RING_F((dstY));
 	OUT_RING_F(((srcXend - draw_coords[0][0]) / scale_units[0][0]));
 	OUT_RING_F(((srcY - draw_coords[0][1]) / scale_units[0][1]));
 	if (pMask) {
diff-tree 4737955a62c39177e7a7ce7749a2f20e111afc68 (from a7e30bb051bc03063fe699473610a57054a64973)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Fri Jul 21 01:02:38 2006 +0800

    move i830 default coord set into I830EmitInvarientState

diff --git a/src/i830_3d.c b/src/i830_3d.c
index 0efd6e4..214beb6 100644
--- a/src/i830_3d.c
+++ b/src/i830_3d.c
@@ -33,13 +33,11 @@
 
 #include "i830_reg.h"
 
-#define CMD_3D (0x3<<29)
-
 void I830EmitInvarientState( ScrnInfoPtr pScrn )
 {
    I830Ptr pI830 = I830PTR(pScrn);
 
-   BEGIN_LP_RING(38);
+   BEGIN_LP_RING(40);
 
    OUT_RING(_3DSTATE_MAP_CUBE | MAP_UNIT(0));
    OUT_RING(_3DSTATE_MAP_CUBE | MAP_UNIT(1));
@@ -98,6 +96,12 @@ void I830EmitInvarientState( ScrnInfoPtr
    OUT_RING(_3DSTATE_MAP_COORD_TRANSFORM);
    OUT_RING(DISABLE_TEX_TRANSFORM | TEXTURE_SET(3));
 
+   OUT_RING(_3DSTATE_MAP_COORD_SETBIND_CMD);
+   OUT_RING(TEXBIND_SET3(TEXCOORDSRC_VTXSET_3) |
+   	TEXBIND_SET2(TEXCOORDSRC_VTXSET_2) |
+   	TEXBIND_SET1(TEXCOORDSRC_VTXSET_1) |
+   	TEXBIND_SET0(TEXCOORDSRC_VTXSET_0));
+	
    OUT_RING(_3DSTATE_RASTER_RULES_CMD |
 	     ENABLE_POINT_RASTER_RULE |
 	     OGL_POINT_RASTER_RULE |
diff --git a/src/i830_exa_render.c b/src/i830_exa_render.c
index f51e6a4..7a22e7d 100644
--- a/src/i830_exa_render.c
+++ b/src/i830_exa_render.c
@@ -365,25 +365,6 @@ I830EXACheckComposite(int op, PicturePtr
     return TRUE;
 }
 
-
-static void
-I830DefCtxSetup(ScrnInfoPtr pScrn)
-{
-	/* coord binding */
-	CARD32 mcb;
-    	I830Ptr pI830 = I830PTR(pScrn);
-
-	BEGIN_LP_RING(2);
-	OUT_RING(_3DSTATE_MAP_COORD_SETBIND_CMD);
-	mcb = TEXBIND_SET3(TEXCOORDSRC_VTXSET_3);
-	mcb |= TEXBIND_SET2(TEXCOORDSRC_VTXSET_2);
-	mcb |= TEXBIND_SET1(TEXCOORDSRC_VTXSET_1);
-	mcb |= TEXBIND_SET0(TEXCOORDSRC_VTXSET_0);
-	OUT_RING(mcb);
-	ADVANCE_LP_RING();
-}
-
-
 Bool
 I830EXAPrepareComposite(int op, PicturePtr pSrcPicture,
 			PicturePtr pMaskPicture, PicturePtr pDstPicture,
@@ -400,8 +381,6 @@ I830EXAPrepareComposite(int op, PictureP
     draw_coords[2][0] = pDst->drawable.x;
     draw_coords[2][1] = pDst->drawable.y;
     
-    I830DefCtxSetup(pScrn);
-
     if (!I830TextureSetup(pSrcPicture, pSrc, 0))
 	I830FALLBACK("fail to setup src texture\n");
     if (pMask != NULL) {
diff-tree a7e30bb051bc03063fe699473610a57054a64973 (from ac34a37cb60d763cbd99b6e2f6fdcb639592b99b)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Fri Jul 21 00:56:58 2006 +0800

    Take from i915, blend ctl code cleanup.

diff --git a/src/i830_exa_render.c b/src/i830_exa_render.c
index cd5e69c..f51e6a4 100644
--- a/src/i830_exa_render.c
+++ b/src/i830_exa_render.c
@@ -31,7 +31,8 @@ extern PictTransform *transform[2];
 struct blendinfo {
     Bool dst_alpha;
     Bool src_alpha;
-    CARD32 blend_cntl;
+    CARD32 src_blend;
+    CARD32 dst_blend;
 };
 
 struct formatinfo {
@@ -48,41 +49,6 @@ I830EXAPrepareComposite(int op, PictureP
 			PicturePtr pMaskPicture, PicturePtr pDstPicture,
 			PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst);
 
-/* I830's Blend factor definition, LOAD_STATE_IMMEDIATE_1 */
-/* move to header...*/
-#define I830_SRC_BLENDFACTOR_ZERO 		(1 << 4)
-#define I830_SRC_BLENDFACTOR_ONE 		(2 << 4)
-#define I830_SRC_BLENDFACTOR_SRC_COLOR		(3 << 4)
-#define I830_SRC_BLENDFACTOR_INV_SRC_COLOR	(4 << 4)
-#define I830_SRC_BLENDFACTOR_SRC_ALPHA		(5 << 4)
-#define I830_SRC_BLENDFACTOR_INV_SRC_ALPHA	(6 << 4)
-#define I830_SRC_BLENDFACTOR_DST_ALPHA		(7 << 4)
-#define I830_SRC_BLENDFACTOR_INV_DST_ALPHA	(8 << 4)
-#define I830_SRC_BLENDFACTOR_DST_COLOR		(9 << 4)
-#define I830_SRC_BLENDFACTOR_INV_DST_COLOR	(0xa << 4)
-#define I830_SRC_BLENDFACTOR_SRC_ALPHA_SATURATE (0xb << 4)
-#define I830_SRC_BLENDFACTOR_CONST_COLOR	(0xc << 4)
-#define I830_SRC_BLENDFACTOR_INV_CONST_COLOR	(0xd << 4)
-#define I830_SRC_BLENDFACTOR_CONST_ALPHA	(0xe << 4)
-#define I830_SRC_BLENDFACTOR_INV_CONST_ALPHA	(0xf << 4)
-#define I830_SRC_BLENDFACTOR_MASK		(0xf << 4)
-
-#define I830_DST_BLENDFACTOR_ZERO 		(1)
-#define I830_DST_BLENDFACTOR_ONE 		(2)
-#define I830_DST_BLENDFACTOR_SRC_COLOR		(3)
-#define I830_DST_BLENDFACTOR_INV_SRC_COLOR	(4)
-#define I830_DST_BLENDFACTOR_SRC_ALPHA		(5)
-#define I830_DST_BLENDFACTOR_INV_SRC_ALPHA	(6)
-#define I830_DST_BLENDFACTOR_DST_ALPHA		(7)
-#define I830_DST_BLENDFACTOR_INV_DST_ALPHA	(8)
-#define I830_DST_BLENDFACTOR_DST_COLOR		(9)
-#define I830_DST_BLENDFACTOR_INV_DST_COLOR	(0xa)
-#define I830_DST_BLENDFACTOR_SRC_ALPHA_SATURATE (0xb)
-#define I830_DST_BLENDFACTOR_CONST_COLOR	(0xc)
-#define I830_DST_BLENDFACTOR_INV_CONST_COLOR	(0xd)
-#define I830_DST_BLENDFACTOR_CONST_ALPHA	(0xe)
-#define I830_DST_BLENDFACTOR_INV_CONST_ALPHA	(0xf)
-#define I830_DST_BLENDFACTOR_MASK		(0xf)
 
 #define TB0C_LAST_STAGE	(1 << 31)
 #define TB0C_RESULT_SCALE_1X		(0 << 29)
@@ -132,38 +98,34 @@ I830EXAPrepareComposite(int op, PictureP
 #define TB0A_ARG1_SEL_TEXEL1		(7 << 6)
 #define TB0A_ARG1_SEL_TEXEL2		(8 << 6)
 #define TB0A_ARG1_SEL_TEXEL3		(9 << 6)
-#define TB0A_ARG0_SEL_XXX
-
-/* end */
-
 
 static struct blendinfo I830BlendOp[] = { 
     /* Clear */
-    {0, 0, I830_SRC_BLENDFACTOR_ZERO           | I830_DST_BLENDFACTOR_ZERO},
+    {0, 0, BLENDFACTOR_ZERO, 		BLENDFACTOR_ZERO},
     /* Src */
-    {0, 0, I830_SRC_BLENDFACTOR_ONE            | I830_DST_BLENDFACTOR_ZERO},
+    {0, 0, BLENDFACTOR_ONE, 		BLENDFACTOR_ZERO},
     /* Dst */
-    {0, 0, I830_SRC_BLENDFACTOR_ZERO           | I830_DST_BLENDFACTOR_ONE},
+    {0, 0, BLENDFACTOR_ZERO,		BLENDFACTOR_ONE},
     /* Over */
-    {0, 1, I830_SRC_BLENDFACTOR_ONE            | I830_DST_BLENDFACTOR_INV_SRC_ALPHA},
+    {0, 1, BLENDFACTOR_ONE,		BLENDFACTOR_INV_SRC_ALPHA},
     /* OverReverse */
-    {1, 0, I830_SRC_BLENDFACTOR_INV_DST_ALPHA | I830_DST_BLENDFACTOR_ONE},
+    {1, 0, BLENDFACTOR_INV_DST_ALPHA,	BLENDFACTOR_ONE},
     /* In */
-    {1, 0, I830_SRC_BLENDFACTOR_DST_ALPHA     | I830_DST_BLENDFACTOR_ZERO},
+    {1, 0, BLENDFACTOR_DST_ALPHA,	BLENDFACTOR_ZERO},
     /* InReverse */
-    {0, 1, I830_SRC_BLENDFACTOR_ZERO           | I830_DST_BLENDFACTOR_SRC_ALPHA},
+    {0, 1, BLENDFACTOR_ZERO,		BLENDFACTOR_SRC_ALPHA},
     /* Out */
-    {1, 0, I830_SRC_BLENDFACTOR_INV_DST_ALPHA | I830_DST_BLENDFACTOR_ZERO},
+    {1, 0, BLENDFACTOR_INV_DST_ALPHA,	BLENDFACTOR_ZERO},
     /* OutReverse */
-    {0, 1, I830_SRC_BLENDFACTOR_ZERO           | I830_DST_BLENDFACTOR_INV_SRC_ALPHA},
+    {0, 1, BLENDFACTOR_ZERO,		BLENDFACTOR_INV_SRC_ALPHA},
     /* Atop */
-    {1, 1, I830_SRC_BLENDFACTOR_DST_ALPHA     | I830_DST_BLENDFACTOR_INV_SRC_ALPHA},
+    {1, 1, BLENDFACTOR_DST_ALPHA,	BLENDFACTOR_INV_SRC_ALPHA},
     /* AtopReverse */
-    {1, 1, I830_SRC_BLENDFACTOR_INV_DST_ALPHA | I830_DST_BLENDFACTOR_SRC_ALPHA},
+    {1, 1, BLENDFACTOR_INV_DST_ALPHA,	BLENDFACTOR_SRC_ALPHA},
     /* Xor */
-    {1, 1, I830_SRC_BLENDFACTOR_INV_DST_ALPHA | I830_DST_BLENDFACTOR_INV_SRC_ALPHA},
+    {1, 1, BLENDFACTOR_INV_DST_ALPHA,	BLENDFACTOR_INV_SRC_ALPHA},
     /* Add */
-    {0, 0, I830_SRC_BLENDFACTOR_ONE            | I830_DST_BLENDFACTOR_ONE},
+    {0, 0, BLENDFACTOR_ONE, 		BLENDFACTOR_ONE},
 };
 
 
@@ -213,17 +175,17 @@ static CARD32 I830GetBlendCntl(int op, P
 {
     CARD32 sblend, dblend;
 
-    sblend = I830BlendOp[op].blend_cntl & I830_SRC_BLENDFACTOR_MASK;
-    dblend = I830BlendOp[op].blend_cntl & I830_DST_BLENDFACTOR_MASK;
+    sblend = I830BlendOp[op].src_blend;
+    dblend = I830BlendOp[op].dst_blend;
 
     /* If there's no dst alpha channel, adjust the blend op so that we'll treat
      * it as always 1.
      */
     if (PICT_FORMAT_A(dst_format) == 0 && I830BlendOp[op].dst_alpha) {
-        if (sblend == I830_SRC_BLENDFACTOR_DST_ALPHA)
-            sblend = I830_SRC_BLENDFACTOR_ONE;
-        else if (sblend == I830_SRC_BLENDFACTOR_INV_DST_ALPHA)
-            sblend = I830_SRC_BLENDFACTOR_ZERO;
+        if (sblend == BLENDFACTOR_DST_ALPHA)
+            sblend = BLENDFACTOR_ONE;
+        else if (sblend == BLENDFACTOR_INV_DST_ALPHA)
+            sblend = BLENDFACTOR_ZERO;
     }
 
     /* If the source alpha is being used, then we should only be in a case where
@@ -231,14 +193,15 @@ static CARD32 I830GetBlendCntl(int op, P
      * channels multiplied by the source picture's alpha.
      */
     if (pMask && pMask->componentAlpha && I830BlendOp[op].src_alpha) {
-        if (dblend == I830_DST_BLENDFACTOR_SRC_ALPHA) {
-            dblend = I830_DST_BLENDFACTOR_SRC_COLOR;
-        } else if (dblend == I830_DST_BLENDFACTOR_INV_SRC_ALPHA) {
-            dblend = I830_DST_BLENDFACTOR_INV_SRC_COLOR;
+        if (dblend == BLENDFACTOR_SRC_ALPHA) {
+            dblend = BLENDFACTOR_SRC_COLR;
+        } else if (dblend == BLENDFACTOR_INV_SRC_ALPHA) {
+            dblend = BLENDFACTOR_INV_SRC_COLR;
         }
     }
 
-    return sblend | dblend;
+    return (sblend << S8_SRC_BLEND_FACTOR_SHIFT) | 
+		(dblend << S8_DST_BLEND_FACTOR_SHIFT);
 }
 
 static Bool I830CheckCompositeTexture(PicturePtr pPict, int unit)
@@ -386,8 +349,7 @@ I830EXACheckComposite(int op, PicturePtr
          * source value that we get to blend with.
          */
         if (I830BlendOp[op].src_alpha &&
-            (I830BlendOp[op].blend_cntl & I830_SRC_BLENDFACTOR_MASK) !=
-             I830_SRC_BLENDFACTOR_ZERO)
+            (I830BlendOp[op].src_blend != BLENDFACTOR_ZERO))
             	I830FALLBACK("Component alpha not supported with source "
                             "alpha and source value blending.\n");
     }
diff --git a/src/i830_reg.h b/src/i830_reg.h
index ae68a2e..f9c1df9 100644
--- a/src/i830_reg.h
+++ b/src/i830_reg.h
@@ -221,6 +221,22 @@
 #define ENABLE_DST_ABLEND_FACTOR	(1<<5)
 #define DST_ABLEND_FACT(x)		(x)
 
+#define BLENDFACTOR_ZERO		0x01
+#define BLENDFACTOR_ONE 		0x02
+#define BLENDFACTOR_SRC_COLR		0x03
+#define BLENDFACTOR_INV_SRC_COLR	0x04
+#define BLENDFACTOR_SRC_ALPHA		0x05
+#define BLENDFACTOR_INV_SRC_ALPHA	0x06
+#define BLENDFACTOR_DST_ALPHA		0x07
+#define BLENDFACTOR_INV_DST_ALPHA	0x08
+#define BLENDFACTOR_DST_COLR		0x09
+#define BLENDFACTOR_INV_DST_COLR	0x0a
+#define BLENDFACTOR_SRC_ALPHA_SATURATE	0x0b
+#define BLENDFACTOR_CONST_COLOR		0x0c
+#define BLENDFACTOR_INV_CONST_COLOR	0x0d
+#define BLENDFACTOR_CONST_ALPHA		0x0e
+#define BLENDFACTOR_INV_CONST_ALPHA	0x0f
+#define BLENDFACTOR_MASK		0x0f
 
 /* _3DSTATE_MAP_BLEND_ARG, p152 */
 #define _3DSTATE_MAP_BLEND_ARG_CMD(stage)	(CMD_3D|(0x0e<<24)|((stage)<<20))
diff-tree ac34a37cb60d763cbd99b6e2f6fdcb639592b99b (from 3e86bf4273241daa23645f5a8104913e4205a74b)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Fri Jul 21 00:52:59 2006 +0800

    Take instruction fixes into i830, with indent changes.

diff --git a/src/i830_exa_render.c b/src/i830_exa_render.c
index 9b4835b..cd5e69c 100644
--- a/src/i830_exa_render.c
+++ b/src/i830_exa_render.c
@@ -315,9 +315,9 @@ I830TextureSetup(PicturePtr pPict, Pixma
     }
 
     {
-	if (pI830->cpp == 1)
+	if (pPix->drawable.bitsPerPixel == 8)
 		format |= MAP_SURFACE_8BIT;
-	else if (pI830->cpp == 2)
+	else if (pPix->drawable.bitsPerPixel == 16)
 		format |= MAP_SURFACE_16BIT;
 	else
 		format |= MAP_SURFACE_32BIT;
@@ -325,9 +325,10 @@ I830TextureSetup(PicturePtr pPict, Pixma
 	BEGIN_LP_RING(6);
 	OUT_RING(_3DSTATE_MAP_INFO_CMD);
 	OUT_RING(format | TEXMAP_INDEX(unit) | MAP_FORMAT_2D);
-	OUT_RING((pPix->drawable.height<<16)|pPix->drawable.width); /* height, width */
-	OUT_RING(offset<<2); /* map address */
-	OUT_RING(pitch<<2); /* map pitch */
+	OUT_RING(((pPix->drawable.height - 1) << 16) |
+		(pPix->drawable.width - 1)); /* height, width */
+	OUT_RING(offset); /* map address */
+	OUT_RING(((pitch / 4) - 1) << 2); /* map pitch */
 	OUT_RING(0);
 	ADVANCE_LP_RING();
      }
@@ -336,8 +337,9 @@ I830TextureSetup(PicturePtr pPict, Pixma
 	BEGIN_LP_RING(2);
 	/* coord sets */
 	OUT_RING(_3DSTATE_MAP_COORD_SET_CMD | TEXCOORD_SET(unit) | 
-		ENABLE_TEXCOORD_PARAMS | TEXCOORDS_ARE_NORMAL | /*XXX, check this, and fix vertex tex coord*/
-		TEXCOORDTYPE_CARTESIAN | ENABLE_ADDR_V_CNTL | TEXCOORD_ADDR_V_MODE(wrap_mode) |
+		ENABLE_TEXCOORD_PARAMS | TEXCOORDS_ARE_NORMAL | 
+		TEXCOORDTYPE_CARTESIAN | ENABLE_ADDR_V_CNTL | 
+		TEXCOORD_ADDR_V_MODE(wrap_mode) |
 		ENABLE_ADDR_U_CNTL | TEXCOORD_ADDR_U_MODE(wrap_mode));
 	OUT_RING(MI_NOOP);
 
@@ -453,7 +455,7 @@ I830EXAPrepareComposite(int op, PictureP
 
 	CARD32 cblend, ablend, blendctl, vf2;
 
-	BEGIN_LP_RING(22);
+	BEGIN_LP_RING(22+6);
 	
 	/*color buffer*/
 	OUT_RING(_3DSTATE_BUF_INFO_CMD);
@@ -464,6 +466,8 @@ I830EXAPrepareComposite(int op, PictureP
 	OUT_RING(_3DSTATE_DST_BUF_VARS_CMD);
 	OUT_RING(dst_format);
 
+      	OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE);
+      	OUT_RING(MI_NOOP);		/* pad to quadword */
 	/* defaults */
 	OUT_RING(_3DSTATE_DFLT_Z_CMD);
 	OUT_RING(0);
@@ -474,18 +478,19 @@ I830EXAPrepareComposite(int op, PictureP
 	OUT_RING(_3DSTATE_DFLT_SPEC_CMD);
 	OUT_RING(0);
 	
-	OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1|I1_LOAD_S(3)|0);
-	OUT_RING((1<<S3_POINT_WIDTH_SHIFT) | (2<<S3_LINE_WIDTH_SHIFT) | S3_CULLMODE_NONE| S3_VERTEXHAS_XY);  
-	OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1|I1_LOAD_S(2)|0);
+	OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(3) | 0);
+	OUT_RING((1 << S3_POINT_WIDTH_SHIFT) | (2 << S3_LINE_WIDTH_SHIFT) | 
+		S3_CULLMODE_NONE | S3_VERTEXHAS_XY);  
+	OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) | 0);
 	if (pMask)
-		vf2 = 2 << 12; /* 2 texture coord sets */
+	    vf2 = 2 << 12; /* 2 texture coord sets */
 	else
-		vf2 = 1 << 12;
+	    vf2 = 1 << 12;
 	vf2 |= (TEXCOORDFMT_2D << 16);
 	if (pMask)
-		vf2 |= (TEXCOORDFMT_2D << 18);
+	    vf2 |= (TEXCOORDFMT_2D << 18);
 	else
-		vf2 |= (TEXCOORDFMT_1D << 18);
+	    vf2 |= (TEXCOORDFMT_1D << 18);
 		
 	vf2 |= (TEXCOORDFMT_1D << 20);
 	vf2 |= (TEXCOORDFMT_1D << 22);
@@ -495,21 +500,24 @@ I830EXAPrepareComposite(int op, PictureP
 	vf2 |= (TEXCOORDFMT_1D << 30);
 	OUT_RING(vf2);
 
+      	OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE);
+      	OUT_RING(MI_NOOP);		/* pad to quadword */
 	/* For (src In mask) operation */
 	/* IN operator: Multiply src by mask components or mask alpha.*/
 	/* TEXBLENDOP_MODULE: arg1*arg2 */
 	cblend = TB0C_LAST_STAGE | TB0C_RESULT_SCALE_1X | TB0C_OP_MODULE |
 		 TB0C_OUTPUT_WRITE_CURRENT;  
-	ablend = TB0A_RESULT_SCALE_1X | TB0A_OP_MODULE | TB0A_OUTPUT_WRITE_CURRENT;
+	ablend = TB0A_RESULT_SCALE_1X | TB0A_OP_MODULE | 
+		 TB0A_OUTPUT_WRITE_CURRENT;
 	
 	cblend |= TB0C_ARG1_SEL_TEXEL0;
 	ablend |= TB0A_ARG1_SEL_TEXEL0;
 	if (pMask) {
-		if (pMaskPicture->componentAlpha && pDstPicture->format != PICT_a8)
-			cblend |= TB0C_ARG2_SEL_TEXEL1;
-		else
-			cblend |= (TB0C_ARG2_SEL_TEXEL1 | TB0C_ARG2_REPLICATE_ALPHA);
-		ablend |= TB0A_ARG2_SEL_TEXEL1;
+	    if (pMaskPicture->componentAlpha && pDstPicture->format != PICT_a8)
+		cblend |= TB0C_ARG2_SEL_TEXEL1;
+	    else
+		cblend |= (TB0C_ARG2_SEL_TEXEL1 | TB0C_ARG2_REPLICATE_ALPHA);
+	    ablend |= TB0A_ARG2_SEL_TEXEL1;
 	} else {
 		cblend |= TB0C_ARG2_SEL_ONE;
 		ablend |= TB0A_ARG2_SEL_ONE;		
@@ -520,6 +528,9 @@ I830EXAPrepareComposite(int op, PictureP
 	OUT_RING(ablend);
 	OUT_RING(0);
 
+      	OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE);
+      	OUT_RING(MI_NOOP);		/* pad to quadword */
+
 	blendctl = I830GetBlendCntl(op, pMaskPicture, pDstPicture->format);
 	OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(8) | 0);
 	OUT_RING(S8_ENABLE_COLOR_BLEND | S8_BLENDFUNC_ADD |(blendctl<<4) |
diff-tree 3e86bf4273241daa23645f5a8104913e4205a74b (from 5c945bf9eb9f5bedd34d98dcc7abc3f1ea3cb962)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Thu Jul 20 13:43:27 2006 +0800

    remove i915 default ctx setup.

diff --git a/src/i915_exa_render.c b/src/i915_exa_render.c
index 4912d97..ba54d53 100644
--- a/src/i915_exa_render.c
+++ b/src/i915_exa_render.c
@@ -318,20 +318,6 @@ I915TextureSetup(PicturePtr pPict, Pixma
     return TRUE;
 }
 
-static void
-I915DefCtxSetup(ScrnInfoPtr pScrn)
-{
-    I830Ptr pI830 = I830PTR(pScrn);
-
-    BEGIN_LP_RING(2);
-    /* set default texture binding, may be in prepare better */
-    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(0);
-    ADVANCE_LP_RING();
-}
-
 Bool
 I915EXAPrepareComposite(int op, PicturePtr pSrcPicture,
 			PicturePtr pMaskPicture, PicturePtr pDstPicture,
@@ -353,8 +339,6 @@ ErrorF("i915 prepareComposite\n");
     scale_units[2][1] = pDst->drawable.height;
     FS_LOCALS(20);
     
-    I915DefCtxSetup(pScrn);
-
     if (!I915TextureSetup(pSrcPicture, pSrc, 0))
 	I830FALLBACK("fail to setup src texture\n");
     if (pMask != NULL) {
diff-tree 5c945bf9eb9f5bedd34d98dcc7abc3f1ea3cb962 (from d5243d1b35ab1db608c81889819e4d4d87048154)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Thu Jul 20 13:40:39 2006 +0800

    Revert "Fix several size error with STATE3D_LOAD_STATE_IMMEDIATE cmd."
    
    This reverts commit 433cb6ba82698676f6f72e09834aba4d64611d54.

diff --git a/src/i830_exa.c b/src/i830_exa.c
index 3975e6d..40f6868 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -55,7 +55,7 @@ do { 							\
 } while(0) 
 #endif
 
-float scale_units[3][2];
+float scale_units[2][2];
 int draw_coords[3][2];
 
 const int I830CopyROP[16] =
@@ -101,7 +101,7 @@ const int I830PatternROP[16] =
 /* move to common.h */
 union intfloat {
 	float f;
-	CARD32 ui;
+	unsigned int ui;
 };
 
 #define OUT_RING_F(x) do {			\
@@ -429,7 +429,6 @@ IntelEXAComposite(PixmapPtr pDst, int sr
     int srcXend, srcYend, maskXend, maskYend;
     PictVector v;
     int pMask = 1;
-    float src_scale_x, src_scale_y, mask_scale_x, mask_scale_y;
 
     DPRINTF(PFX, "Composite: srcX %d, srcY %d\n\t maskX %d, maskY %d\n\t"
 	     "dstX %d, dstY %d\n\twidth %d, height %d\n\t"
@@ -484,14 +483,9 @@ IntelEXAComposite(PixmapPtr pDst, int sr
 
     draw_coords[0][0] -= draw_coords[2][0];
     draw_coords[0][1] -= draw_coords[2][1];
-    src_scale_x = (float)scale_units[0][0] / (float)scale_units[2][0];
-    src_scale_y = (float)scale_units[0][1] / (float)scale_units[2][1];
-
     if (pMask) {
 	draw_coords[1][0] -= draw_coords[2][0];
 	draw_coords[1][1] -= draw_coords[2][1];
-	mask_scale_x = (float)scale_units[1][0] / (float)scale_units[2][0];
-	mask_scale_y = (float)scale_units[1][1] / (float)scale_units[2][1];
     }
 
     {
@@ -512,40 +506,40 @@ IntelEXAComposite(PixmapPtr pDst, int sr
 
 	OUT_RING(PRIM3D_INLINE | PRIM3D_TRIFAN | (vertex_count-1));
 
-	OUT_RING_F(dstX);
-	OUT_RING_F(dstY);
-	OUT_RING_F(((srcX - draw_coords[0][0]) * src_scale_x));
-	OUT_RING_F(((srcY - draw_coords[0][1]) * src_scale_y));
+	OUT_RING(dstX);
+	OUT_RING(dstY);
+	OUT_RING_F(((srcX - draw_coords[0][0]) / scale_units[0][0]));
+	OUT_RING_F(((srcY - draw_coords[0][1]) / scale_units[0][1]));
 	if (pMask) {
-		OUT_RING_F(((maskX - draw_coords[1][0]) * mask_scale_x));
-		OUT_RING_F(((maskY - draw_coords[1][1]) * mask_scale_y));
+		OUT_RING_F(((maskX - draw_coords[1][0]) / scale_units[1][0]));
+		OUT_RING_F(((maskY - draw_coords[1][1]) / scale_units[1][1]));
 	}
 
-	OUT_RING_F(dstX);
-	OUT_RING_F((dstY+h));
-	OUT_RING_F(((srcX - draw_coords[0][0]) * src_scale_x));
-	OUT_RING_F(((srcYend - draw_coords[0][1]) * src_scale_y));
+	OUT_RING(dstX);
+	OUT_RING((dstY+h));
+	OUT_RING_F(((srcX - draw_coords[0][0]) / scale_units[0][0]));
+	OUT_RING_F(((srcYend - draw_coords[0][1]) / scale_units[0][1]));
 	if (pMask) {
-		OUT_RING_F(((maskX - draw_coords[1][0]) * mask_scale_x));
-		OUT_RING_F(((maskYend - draw_coords[1][1]) * mask_scale_y));
+		OUT_RING_F(((maskX - draw_coords[1][0]) / scale_units[1][0]));
+		OUT_RING_F(((maskYend - draw_coords[1][1]) / scale_units[1][1]));
 	}
 
-	OUT_RING_F((dstX+w));
-	OUT_RING_F((dstY+h));
-	OUT_RING_F(((srcXend - draw_coords[0][0]) * src_scale_x));
-	OUT_RING_F(((srcYend - draw_coords[0][1]) * src_scale_y));
+	OUT_RING((dstX+w));
+	OUT_RING((dstY+h));
+	OUT_RING_F(((srcXend - draw_coords[0][0]) / scale_units[0][0]));
+	OUT_RING_F(((srcYend - draw_coords[0][1]) / scale_units[0][1]));
 	if (pMask) {
-		OUT_RING_F(((maskXend - draw_coords[1][0]) * mask_scale_x));
-		OUT_RING_F(((maskYend - draw_coords[1][1]) * mask_scale_y));
+		OUT_RING_F(((maskXend - draw_coords[1][0]) / scale_units[1][0]));
+		OUT_RING_F(((maskYend - draw_coords[1][1]) / scale_units[1][1]));
 	}
 
-	OUT_RING_F((dstX+w));
-	OUT_RING_F((dstY));
-	OUT_RING_F(((srcXend - draw_coords[0][0]) * src_scale_x));
-	OUT_RING_F(((srcY - draw_coords[0][1]) * src_scale_y));
+	OUT_RING((dstX+w));
+	OUT_RING((dstY));
+	OUT_RING_F(((srcXend - draw_coords[0][0]) / scale_units[0][0]));
+	OUT_RING_F(((srcY - draw_coords[0][1]) / scale_units[0][1]));
 	if (pMask) {
-		OUT_RING_F(((maskXend - draw_coords[1][0]) * mask_scale_x));
-		OUT_RING_F(((maskY - draw_coords[1][1]) * mask_scale_y));
+		OUT_RING_F(((maskXend - draw_coords[1][0]) / scale_units[1][0]));
+		OUT_RING_F(((maskY - draw_coords[1][1]) / scale_units[1][1]));
 	}
 	ADVANCE_LP_RING();
     }
diff-tree d5243d1b35ab1db608c81889819e4d4d87048154 (from 13e372c2095fde94ae41bea959fba0ad95a59c08)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Wed Jul 19 19:27:53 2006 -0400

    The height and width of texture maps are one more than the programmed values.

diff --git a/src/i915_exa_render.c b/src/i915_exa_render.c
index 4cc9e54..4912d97 100644
--- a/src/i915_exa_render.c
+++ b/src/i915_exa_render.c
@@ -271,8 +271,8 @@ I915TextureSetup(PicturePtr pPict, Pixma
 	OUT_RING(_3DSTATE_MAP_STATE | 3);
 	OUT_RING(1<<unit);
 	OUT_RING(offset); /* Must be 4-byte aligned */
-	ms3 = (pPix->drawable.height << MS3_HEIGHT_SHIFT) | 
-		(pPix->drawable.width << MS3_WIDTH_SHIFT) | format;
+	ms3 = ((pPix->drawable.height - 1) << MS3_HEIGHT_SHIFT) | 
+		((pPix->drawable.width - 1) << MS3_WIDTH_SHIFT) | format;
 	if (!pI830->disableTiling)
 		ms3 |= MS3_USE_FENCE_REGS;
 	OUT_RING(ms3); 
diff-tree 13e372c2095fde94ae41bea959fba0ad95a59c08 (from da5efb09d55291ce5bcabff7db8d1490bb5e838b)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Wed Jul 19 16:42:57 2006 -0400

    Fix the texture map pitch setting as documented, and as used by the 3d driver.

diff --git a/src/i915_exa_render.c b/src/i915_exa_render.c
index a570382..4cc9e54 100644
--- a/src/i915_exa_render.c
+++ b/src/i915_exa_render.c
@@ -270,13 +270,13 @@ I915TextureSetup(PicturePtr pPict, Pixma
 	BEGIN_LP_RING(6);
 	OUT_RING(_3DSTATE_MAP_STATE | 3);
 	OUT_RING(1<<unit);
-	OUT_RING(offset&MS2_ADDRESS_MASK);
+	OUT_RING(offset); /* Must be 4-byte aligned */
 	ms3 = (pPix->drawable.height << MS3_HEIGHT_SHIFT) | 
 		(pPix->drawable.width << MS3_WIDTH_SHIFT) | format;
 	if (!pI830->disableTiling)
 		ms3 |= MS3_USE_FENCE_REGS;
 	OUT_RING(ms3); 
-	OUT_RING(pitch<<MS4_PITCH_SHIFT);
+	OUT_RING(((pitch / 4) - 1) << MS4_PITCH_SHIFT);
 	OUT_RING(0);
 	ADVANCE_LP_RING();
      }
diff --git a/src/i915_reg.h b/src/i915_reg.h
index b9f7ef8..6751de6 100644
--- a/src/i915_reg.h
+++ b/src/i915_reg.h
@@ -688,7 +688,9 @@
 
 
 
-/* p207 */
+/* p207.
+ * The DWORD count is 3 times the number of bits set in MS1_MAPMASK_MASK
+ */
 #define _3DSTATE_MAP_STATE               (CMD_3D|(0x1d<<24)|(0x0<<16))
 
 #define MS1_MAPMASK_SHIFT               0
@@ -755,6 +757,7 @@
 #define MS3_TILED_SURFACE             (1<<1)
 #define MS3_TILE_WALK                 (1<<0)
 
+/* The pitch is the pitch measured in DWORDS, minus 1 */
 #define MS4_PITCH_SHIFT                 21
 #define MS4_CUBE_FACE_ENA_NEGX          (1<<20)
 #define MS4_CUBE_FACE_ENA_POSX          (1<<19)
@@ -771,7 +774,9 @@
 #define MS4_VOLUME_DEPTH_SHIFT          0    
 #define MS4_VOLUME_DEPTH_MASK           (0xff<<0)
 
-/* p244 */
+/* p244.
+ * The DWORD count is 3 times the number of bits set in SS1_MAPMASK_MASK.
+ */
 #define _3DSTATE_SAMPLER_STATE         (CMD_3D|(0x1d<<24)|(0x1<<16))
 
 #define SS1_MAPMASK_SHIFT               0
diff-tree da5efb09d55291ce5bcabff7db8d1490bb5e838b (from 36aa43bf73ee1268f0a250788eb637a4123f08eb)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Wed Jul 19 16:36:52 2006 -0400

    Fix the alignment padding fix (didn't bump BEGIN_LP_RING count).

diff --git a/src/i915_3d.h b/src/i915_3d.h
index 5a45882..c116200 100644
--- a/src/i915_3d.h
+++ b/src/i915_3d.h
@@ -436,13 +436,13 @@ do {									\
 
 #define FS_END()							\
 do {									\
-    int _i;								\
-    BEGIN_LP_RING(_cur_shader_commands * 3 + 1);			\
+    int _i, _pad = (_cur_shader_commands & 0x1) ? 0 : 1;		\
+    BEGIN_LP_RING(_cur_shader_commands * 3 + 1 + _pad);			\
     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]);					\
-    if ((_cur_shader_commands & 0x1) == 0)				\
+    if (_pad != 0)							\
 	OUT_RING(MI_NOOP);						\
     ADVANCE_LP_RING();							\
 } while (0);
diff-tree 36aa43bf73ee1268f0a250788eb637a4123f08eb (from adce6bd0fc9533156da09da7d029ba0d76606b4f)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Wed Jul 19 16:22:46 2006 -0400

    Force texture alpha channels to 1 if not present.

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

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

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

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

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

    Correct the DWORD count of several 3D instructions.

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

    Replace hand register setting with new i915 fragmet program API.

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

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

diff --cc src/Makefile.am
index 9c2a5c2,f97dc52..c2e49ac
@@@ -58,11 -58,8 +58,12 @@@
  	 i830_3d.c \
  	 i830_reg.h \
  	 i915_3d.c \
+ 	 i915_3d.h \
 -	 i915_reg.h
 +	 i915_reg.h \
 +	 i830_exa.c \
 +	 i830_xaa.c \
 +	 i830_exa_render.c \
 +	 i915_exa_render.c
  
  if DRI
  i810_drv_la_SOURCES += \
diff-tree 433cb6ba82698676f6f72e09834aba4d64611d54 (from 855a9f13cb7fd4f6c489ff280bf389475bbd9bbe)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Tue Jul 18 17:00:50 2006 +0800

    Fix several size error with STATE3D_LOAD_STATE_IMMEDIATE cmd.
    Issue texture coord set with proper scale value.

diff --git a/src/i830_exa.c b/src/i830_exa.c
index 40f6868..3975e6d 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -55,7 +55,7 @@ do { 							\
 } while(0) 
 #endif
 
-float scale_units[2][2];
+float scale_units[3][2];
 int draw_coords[3][2];
 
 const int I830CopyROP[16] =
@@ -101,7 +101,7 @@ const int I830PatternROP[16] =
 /* move to common.h */
 union intfloat {
 	float f;
-	unsigned int ui;
+	CARD32 ui;
 };
 
 #define OUT_RING_F(x) do {			\
@@ -429,6 +429,7 @@ IntelEXAComposite(PixmapPtr pDst, int sr
     int srcXend, srcYend, maskXend, maskYend;
     PictVector v;
     int pMask = 1;
+    float src_scale_x, src_scale_y, mask_scale_x, mask_scale_y;
 
     DPRINTF(PFX, "Composite: srcX %d, srcY %d\n\t maskX %d, maskY %d\n\t"
 	     "dstX %d, dstY %d\n\twidth %d, height %d\n\t"
@@ -483,9 +484,14 @@ IntelEXAComposite(PixmapPtr pDst, int sr
 
     draw_coords[0][0] -= draw_coords[2][0];
     draw_coords[0][1] -= draw_coords[2][1];
+    src_scale_x = (float)scale_units[0][0] / (float)scale_units[2][0];
+    src_scale_y = (float)scale_units[0][1] / (float)scale_units[2][1];
+
     if (pMask) {
 	draw_coords[1][0] -= draw_coords[2][0];
 	draw_coords[1][1] -= draw_coords[2][1];
+	mask_scale_x = (float)scale_units[1][0] / (float)scale_units[2][0];
+	mask_scale_y = (float)scale_units[1][1] / (float)scale_units[2][1];
     }
 
     {
@@ -506,40 +512,40 @@ IntelEXAComposite(PixmapPtr pDst, int sr
 
 	OUT_RING(PRIM3D_INLINE | PRIM3D_TRIFAN | (vertex_count-1));
 
-	OUT_RING(dstX);
-	OUT_RING(dstY);
-	OUT_RING_F(((srcX - draw_coords[0][0]) / scale_units[0][0]));
-	OUT_RING_F(((srcY - draw_coords[0][1]) / scale_units[0][1]));
+	OUT_RING_F(dstX);
+	OUT_RING_F(dstY);
+	OUT_RING_F(((srcX - draw_coords[0][0]) * src_scale_x));
+	OUT_RING_F(((srcY - draw_coords[0][1]) * src_scale_y));
 	if (pMask) {
-		OUT_RING_F(((maskX - draw_coords[1][0]) / scale_units[1][0]));
-		OUT_RING_F(((maskY - draw_coords[1][1]) / scale_units[1][1]));
+		OUT_RING_F(((maskX - draw_coords[1][0]) * mask_scale_x));
+		OUT_RING_F(((maskY - draw_coords[1][1]) * mask_scale_y));
 	}
 
-	OUT_RING(dstX);
-	OUT_RING((dstY+h));
-	OUT_RING_F(((srcX - draw_coords[0][0]) / scale_units[0][0]));
-	OUT_RING_F(((srcYend - draw_coords[0][1]) / scale_units[0][1]));
+	OUT_RING_F(dstX);
+	OUT_RING_F((dstY+h));
+	OUT_RING_F(((srcX - draw_coords[0][0]) * src_scale_x));
+	OUT_RING_F(((srcYend - draw_coords[0][1]) * src_scale_y));
 	if (pMask) {
-		OUT_RING_F(((maskX - draw_coords[1][0]) / scale_units[1][0]));
-		OUT_RING_F(((maskYend - draw_coords[1][1]) / scale_units[1][1]));
+		OUT_RING_F(((maskX - draw_coords[1][0]) * mask_scale_x));
+		OUT_RING_F(((maskYend - draw_coords[1][1]) * mask_scale_y));
 	}
 
-	OUT_RING((dstX+w));
-	OUT_RING((dstY+h));
-	OUT_RING_F(((srcXend - draw_coords[0][0]) / scale_units[0][0]));
-	OUT_RING_F(((srcYend - draw_coords[0][1]) / scale_units[0][1]));
+	OUT_RING_F((dstX+w));
+	OUT_RING_F((dstY+h));
+	OUT_RING_F(((srcXend - draw_coords[0][0]) * src_scale_x));
+	OUT_RING_F(((srcYend - draw_coords[0][1]) * src_scale_y));
 	if (pMask) {
-		OUT_RING_F(((maskXend - draw_coords[1][0]) / scale_units[1][0]));
-		OUT_RING_F(((maskYend - draw_coords[1][1]) / scale_units[1][1]));
+		OUT_RING_F(((maskXend - draw_coords[1][0]) * mask_scale_x));
+		OUT_RING_F(((maskYend - draw_coords[1][1]) * mask_scale_y));
 	}
 
-	OUT_RING((dstX+w));
-	OUT_RING((dstY));
-	OUT_RING_F(((srcXend - draw_coords[0][0]) / scale_units[0][0]));
-	OUT_RING_F(((srcY - draw_coords[0][1]) / scale_units[0][1]));
+	OUT_RING_F((dstX+w));
+	OUT_RING_F((dstY));
+	OUT_RING_F(((srcXend - draw_coords[0][0]) * src_scale_x));
+	OUT_RING_F(((srcY - draw_coords[0][1]) * src_scale_y));
 	if (pMask) {
-		OUT_RING_F(((maskXend - draw_coords[1][0]) / scale_units[1][0]));
-		OUT_RING_F(((maskY - draw_coords[1][1]) / scale_units[1][1]));
+		OUT_RING_F(((maskXend - draw_coords[1][0]) * mask_scale_x));
+		OUT_RING_F(((maskY - draw_coords[1][1]) * mask_scale_y));
 	}
 	ADVANCE_LP_RING();
     }
diff --git a/src/i915_exa_render.c b/src/i915_exa_render.c
index acec69f..60b8125 100644
--- a/src/i915_exa_render.c
+++ b/src/i915_exa_render.c
@@ -408,6 +408,8 @@ ErrorF("i915 prepareComposite\n");
     dst_pitch = exaGetPixmapPitch(pDst);
     draw_coords[2][0] = pDst->drawable.x;
     draw_coords[2][1] = pDst->drawable.y;
+    scale_units[2][0] = pDst->drawable.width;
+    scale_units[2][1] = pDst->drawable.height;
     
     I915DefCtxSetup(pScrn);
 
@@ -446,7 +448,7 @@ ErrorF("i915 prepareComposite\n");
 	
 	/* XXX:S3? define vertex format with tex coord sets number*/
 	OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1|I1_LOAD_S(2)|I1_LOAD_S(3)|
-		I1_LOAD_S(4)|1);
+		I1_LOAD_S(4)|3);
 	ss2 = S2_TEXCOORD_FMT(0, TEXCOORDFMT_2D);
 	if (pMask)
 		ss2 |= S2_TEXCOORD_FMT(1, TEXCOORDFMT_2D);
@@ -538,7 +540,7 @@ ErrorF("i915 prepareComposite\n");
 	blendctl = I915GetBlendCntl(op, pMaskPicture, pDstPicture->format);
 
 	BEGIN_LP_RING(2);
-	OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(6) | 0);
+	OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(6) | 1);
 	ss6 = S6_CBUF_BLEND_ENABLE | S6_COLOR_WRITE_ENABLE;
 	OUT_RING(ss6 | (0 << S6_CBUF_BLEND_FUNC_SHIFT) | blendctl);
 	ADVANCE_LP_RING();
diff-tree 855a9f13cb7fd4f6c489ff280bf389475bbd9bbe (from 04d1584737fd0d14e99608a97281fd7b1549ae0e)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Tue Jul 18 10:02:47 2006 +0800

    fallback in 'repeat' case for now

diff --git a/src/i830_exa.c b/src/i830_exa.c
index 83601dc..40f6868 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -340,8 +340,10 @@ I830EXAUploadToScreen(PixmapPtr pDst, in
 
     I830Sync(pScrn);
 
+#ifdef I830DEBUG
     ErrorF("Up->Screen: dst offset 0x%x, dst pitch %d, x %d, y %d, src %p, src pitch %d\n",
 		dst_offset, dst_pitch, x, y, src, src_pitch);
+#endif
 #ifndef UPLOAD_USE_BLIT
     dst = pI830->FbBase + dst_offset + y*dst_pitch + 
 		x* (pDst->drawable.bitsPerPixel/8);
@@ -403,8 +405,10 @@ I830EXADownloadFromScreen(PixmapPtr pSrc
 
     I830Sync(pScrn);
 
+#ifdef I830DEBUG
     ErrorF("Screen->Mem: src offset 0x%x, src %p, src pitch %d, x %d, y %d, dst %p, dst_pitch %d\n",
 	src_offset, src, src_pitch, x, y, dst, dst_pitch);
+#endif
     w *= pSrc->drawable.bitsPerPixel/8;
     while(h--) {
 	memcpy(dst, src, w);
@@ -426,7 +430,7 @@ IntelEXAComposite(PixmapPtr pDst, int sr
     PictVector v;
     int pMask = 1;
 
-ErrorF("Composite: srcX %d, srcY %d\n\t maskX %d, maskY %d\n\t"
+    DPRINTF(PFX, "Composite: srcX %d, srcY %d\n\t maskX %d, maskY %d\n\t"
 	     "dstX %d, dstY %d\n\twidth %d, height %d\n\t"
 	     "src_scale_x %f, src_scale_y %f, mask_scale_x %f, mask_scale_y %f\n""\tdx0 %d, dy0 %x, dx1 %d dy1 %x\n", 
 		srcX, srcY, maskX, maskY, dstX, dstY, w, h,
@@ -472,7 +476,7 @@ ErrorF("Composite: srcX %d, srcY %d\n\t 
         maskXend = xFixedToInt(v.vector[0]);
         maskYend = xFixedToInt(v.vector[1]);
     }
-DPRINTF(PFX, "After transform: srcX %d, srcY %d,srcXend %d, srcYend %d\n\t"
+    DPRINTF(PFX, "After transform: srcX %d, srcY %d,srcXend %d, srcYend %d\n\t"
 		"maskX %d, maskY %d, maskXend %d, maskYend %d\n\t"
 		"dstX %d, dstY %d\n", srcX, srcY, srcXend, srcYend,
 		maskX, maskY, maskXend, maskYend, dstX, dstY);
diff --git a/src/i915_exa_render.c b/src/i915_exa_render.c
index 68c929e..acec69f 100644
--- a/src/i915_exa_render.c
+++ b/src/i915_exa_render.c
@@ -231,8 +231,8 @@ static Bool I915CheckCompositeTexture(Pi
                          (int)pPict->format);
 
     /* FIXME: fix repeat support */
-    if (pPict->repeat && ((w&(w-1)) != 0) && ((h&(h-1)) != 0))
-	I830FALLBACK("repeat non log2 aligned!\n");
+    if (pPict->repeat) 
+	I830FALLBACK("repeat not support now!\n");
 
     if (pPict->filter != PictFilterNearest &&
         pPict->filter != PictFilterBilinear)
diff-tree 04d1584737fd0d14e99608a97281fd7b1549ae0e (from b85f268051a785f90e4c55bd1cac80d673388f16)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Fri Jul 14 16:14:18 2006 +0800

    Current exa render implement for i830 and i915, test on
    865GM and 915G. There is issue in picture 'repeat' support.
    And also stop recursive behavior in I830WaitLpRing to allow
    server to abort instead of system hang.

diff --git a/src/Makefile.am b/src/Makefile.am
index c9e8780..9c2a5c2 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -60,7 +60,9 @@ i810_drv_la_SOURCES = \
 	 i915_3d.c \
 	 i915_reg.h \
 	 i830_exa.c \
-	 i830_xaa.c
+	 i830_xaa.c \
+	 i830_exa_render.c \
+	 i915_exa_render.c
 
 if DRI
 i810_drv_la_SOURCES += \
diff --git a/src/i830_accel.c b/src/i830_accel.c
index f299398..6b33887 100644
--- a/src/i830_accel.c
+++ b/src/i830_accel.c
@@ -110,6 +110,9 @@ I830WaitLpRing(ScrnInfoPtr pScrn, int n,
 #ifdef I830_USE_XAA
 	 pI830->AccelInfoRec = NULL;	/* Stops recursive behavior */
 #endif
+#ifdef I830_USE_EXA
+	 pI830->EXADriverPtr = NULL;
+#endif
 	 FatalError("lockup\n");
       }
 
diff --git a/src/i830_exa.c b/src/i830_exa.c
index 665c4d7..83601dc 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -36,9 +36,10 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #include "xaarop.h"
 #include "i830.h"
 #include "i810_reg.h"
+#include "i830_reg.h"
 
 #ifdef I830DEBUG
-#define DEBUG_I830FALLBACK 0
+#define DEBUG_I830FALLBACK 1
 #endif
 
 #ifdef DEBUG_I830FALLBACK
@@ -48,9 +49,15 @@ do {							\
 	return FALSE;					\
 } while(0)
 #else
-#define I830FALLBACK(s, arg...) { return FALSE; }
+#define I830FALLBACK(s, arg...) 			\
+do { 							\
+	return FALSE;					\
+} while(0) 
 #endif
 
+float scale_units[2][2];
+int draw_coords[3][2];
+
 const int I830CopyROP[16] =
 {
    ROP_0,               /* GXclear */
@@ -91,12 +98,33 @@ const int I830PatternROP[16] =
     ROP_1
 };
 
-void i830ScratchSave(ScreenPtr pScreen, ExaOffscreenArea *area);
-Bool i830UploadToScreen(PixmapPtr pDst, char *src, int src_pitch);
-Bool i830UploadToScratch(PixmapPtr pSrc, PixmapPtr pDst);
+/* move to common.h */
+union intfloat {
+	float f;
+	unsigned int ui;
+};
+
+#define OUT_RING_F(x) do {			\
+	union intfloat tmp;			\
+	tmp.f = (float)(x);			\
+	OUT_RING(tmp.ui);			\
+} while(0)				
+
+Bool is_transform[2];
+PictTransform *transform[2];
+
+Bool i830UploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, 
+			    char *src, int src_pitch);
 Bool i830DownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h,
 			    char *dst, int dst_pitch);
 
+extern Bool I830EXACheckComposite(int, PicturePtr, PicturePtr, PicturePtr);
+extern Bool I830EXAPrepareComposite(int, PicturePtr, PicturePtr, PicturePtr, 
+				PixmapPtr, PixmapPtr, PixmapPtr);
+extern Bool I915EXACheckComposite(int, PicturePtr, PicturePtr, PicturePtr);
+extern Bool I915EXAPrepareComposite(int, PicturePtr, PicturePtr, PicturePtr, 
+				PixmapPtr, PixmapPtr, PixmapPtr);
+
 /**
  * I830EXASync - wait for a command to finish
  * @pScreen: current screen
@@ -295,27 +323,69 @@ I830EXACopy(PixmapPtr pDstPixmap, int sr
 static void
 I830EXADoneCopy(PixmapPtr pDstPixmap)
 {
-    return;
+    	return;
 }
 
-#if 0 /* Not done (or even started for that matter) */
+//#define UPLOAD_USE_BLIT 1
+
 static Bool
-I830EXAUploadToScreen(PixmapPtr pDst, char *src, int src_pitch)
+I830EXAUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, 
+		char *src, int src_pitch)
 {
     ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
     I830Ptr pI830 = I830PTR(pScrn);
-    unsigned char *dst = pDst->devPrivate.ptr;
     int dst_pitch = exaGetPixmapPitch(pDst);
-    int size = src_pitch < dst_pitch ? src_pitch : dst_pitch;
-    int h = pDst->drawable.height;
+    int dst_offset = exaGetPixmapOffset(pDst);
+    unsigned char *dst;
 
     I830Sync(pScrn);
 
+    ErrorF("Up->Screen: dst offset 0x%x, dst pitch %d, x %d, y %d, src %p, src pitch %d\n",
+		dst_offset, dst_pitch, x, y, src, src_pitch);
+#ifndef UPLOAD_USE_BLIT
+    dst = pI830->FbBase + dst_offset + y*dst_pitch + 
+		x* (pDst->drawable.bitsPerPixel/8);
+    w *= pDst->drawable.bitsPerPixel/8;
     while(h--) {
-	i830MemCopyToVideoRam(pI830, dst, (unsigned char *)src, size);
+	memcpy(dst, src, w);
 	src += src_pitch;
 	dst += dst_pitch;
     }
+#else
+    /* setup blit engine to copy one pixel data by one */
+    {
+	int x1, x2, y1, y2, i, j;
+	CARD32 d, len, *srcp;
+	x1 = x;
+	y1 = y;
+	x2 = x + w;
+	y2 = y + h;
+
+	len = (w * (pDst->drawable.bitsPerPixel/8)) >> 2;
+
+	pI830->BR[13] = (1 << 24) | (1 << 25);
+	pI830->BR[13] |= I830CopyROP[GXcopy]<<16;
+	pI830->BR[13] |= dst_pitch & 0xffff;
+	for (i = 0; i < h; i++) {
+		srcp = (CARD32*)src;
+		for ( j = len; j > 0; j--) {
+			d = *srcp;
+			BEGIN_LP_RING(6);
+			OUT_RING(XY_COLOR_BLT_CMD | XY_COLOR_BLT_WRITE_ALPHA | 
+				XY_COLOR_BLT_WRITE_RGB);
+			OUT_RING(pI830->BR[13]);
+			OUT_RING((y1 << 16) | x1);
+			OUT_RING((y2 << 16) | x2);
+			OUT_RING(dst_offset);
+			OUT_RING(d);
+			ADVANCE_LP_RING();
+			srcp++;
+		}
+		src += src_pitch;
+	}
+
+    }
+#endif
 
     return TRUE;
 }
@@ -326,14 +396,18 @@ I830EXADownloadFromScreen(PixmapPtr pSrc
 {
     ScrnInfoPtr pScrn = xf86Screens[pSrc->drawable.pScreen->myNum];
     I830Ptr pI830 = I830PTR(pScrn);
-    unsigned char *src = pSrc->devPrivate.ptr;
     int src_pitch = exaGetPixmapPitch(pSrc);
-    int size = src_pitch < dst_pitch ? src_pitch : dst_pitch;
+    int src_offset = exaGetPixmapOffset(pSrc);
+    unsigned char *src = pI830->FbBase + src_offset + y*src_pitch +
+		x*(pSrc->drawable.bitsPerPixel/8);
 
     I830Sync(pScrn);
 
+    ErrorF("Screen->Mem: src offset 0x%x, src %p, src pitch %d, x %d, y %d, dst %p, dst_pitch %d\n",
+	src_offset, src, src_pitch, x, y, dst, dst_pitch);
+    w *= pSrc->drawable.bitsPerPixel/8;
     while(h--) {
-	i830MemCopyFromVideoRam(pI830, (unsigned char *)dst, src, size);
+	memcpy(dst, src, w);
 	src += src_pitch;
 	dst += dst_pitch;
     }
@@ -341,40 +415,145 @@ I830EXADownloadFromScreen(PixmapPtr pSrc
     return TRUE;
 }
 
-static Bool
-I830EXACheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
-		      PicturePtr pDstPicture)
+static void
+IntelEXAComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
+		 int dstX, int dstY, int w, int h)
 {
-    return FALSE; /* no Composite yet */
-}
+	/* should be same like I830Composite */
+    ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
+    I830Ptr pI830 = I830PTR(pScrn);
+    int srcXend, srcYend, maskXend, maskYend;
+    PictVector v;
+    int pMask = 1;
+
+ErrorF("Composite: srcX %d, srcY %d\n\t maskX %d, maskY %d\n\t"
+	     "dstX %d, dstY %d\n\twidth %d, height %d\n\t"
+	     "src_scale_x %f, src_scale_y %f, mask_scale_x %f, mask_scale_y %f\n""\tdx0 %d, dy0 %x, dx1 %d dy1 %x\n", 
+		srcX, srcY, maskX, maskY, dstX, dstY, w, h,
+		scale_units[0][0], scale_units[0][1], 
+		scale_units[1][0], scale_units[1][1],
+		draw_coords[0][0], draw_coords[0][1], 
+		draw_coords[1][0], draw_coords[1][1]);
+
+    if (scale_units[1][0] == -1 || scale_units[1][1] == -1) {
+	ErrorF("mask is null\n");
+	pMask = 0;
+    }
 
-static Bool
-I830EXAPrepareComposite(int op, PicturePtr pSrcPicture,
-			PicturePtr pMaskPicture, PicturePtr pDstPicture,
-			PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst)
-{
-    return FALSE; /* no Composite yet */
-}
+    srcXend = srcX + w;
+    srcYend = srcY + h;
+    maskXend = maskX + w;
+    maskYend = maskY + h;
+    if (is_transform[0]) {
+        v.vector[0] = IntToxFixed(srcX);
+        v.vector[1] = IntToxFixed(srcY);
+        v.vector[2] = xFixed1;
+        PictureTransformPoint(transform[0], &v);
+        srcX = xFixedToInt(v.vector[0]);
+        srcY = xFixedToInt(v.vector[1]);
+        v.vector[0] = IntToxFixed(srcXend);
+        v.vector[1] = IntToxFixed(srcYend);
+        v.vector[2] = xFixed1;
+        PictureTransformPoint(transform[0], &v);
+        srcXend = xFixedToInt(v.vector[0]);
+        srcYend = xFixedToInt(v.vector[1]);
+    }
+    if (is_transform[1]) {
+        v.vector[0] = IntToxFixed(maskX);
+        v.vector[1] = IntToxFixed(maskY);
+        v.vector[2] = xFixed1;
+        PictureTransformPoint(transform[1], &v);
+        maskX = xFixedToInt(v.vector[0]);
+        maskY = xFixedToInt(v.vector[1]);
+        v.vector[0] = IntToxFixed(maskXend);
+        v.vector[1] = IntToxFixed(maskYend);
+        v.vector[2] = xFixed1;
+        PictureTransformPoint(transform[1], &v);
+        maskXend = xFixedToInt(v.vector[0]);
+        maskYend = xFixedToInt(v.vector[1]);
+    }
+DPRINTF(PFX, "After transform: srcX %d, srcY %d,srcXend %d, srcYend %d\n\t"
+		"maskX %d, maskY %d, maskXend %d, maskYend %d\n\t"
+		"dstX %d, dstY %d\n", srcX, srcY, srcXend, srcYend,
+		maskX, maskY, maskXend, maskYend, dstX, dstY);
+
+    draw_coords[0][0] -= draw_coords[2][0];
+    draw_coords[0][1] -= draw_coords[2][1];
+    if (pMask) {
+	draw_coords[1][0] -= draw_coords[2][0];
+	draw_coords[1][1] -= draw_coords[2][1];
+    }
+
+    {
+	int vertex_count; 
+
+	if (pMask)
+		vertex_count = 4*6;
+	else
+		vertex_count = 4*4;
+
+	BEGIN_LP_RING(6+vertex_count);
+
+	OUT_RING(MI_NOOP);
+	OUT_RING(MI_NOOP);
+	OUT_RING(MI_NOOP);
+	OUT_RING(MI_NOOP);
+	OUT_RING(MI_NOOP);
+
+	OUT_RING(PRIM3D_INLINE | PRIM3D_TRIFAN | (vertex_count-1));
+
+	OUT_RING(dstX);
+	OUT_RING(dstY);
+	OUT_RING_F(((srcX - draw_coords[0][0]) / scale_units[0][0]));
+	OUT_RING_F(((srcY - draw_coords[0][1]) / scale_units[0][1]));
+	if (pMask) {
+		OUT_RING_F(((maskX - draw_coords[1][0]) / scale_units[1][0]));
+		OUT_RING_F(((maskY - draw_coords[1][1]) / scale_units[1][1]));
+	}
+
+	OUT_RING(dstX);
+	OUT_RING((dstY+h));
+	OUT_RING_F(((srcX - draw_coords[0][0]) / scale_units[0][0]));
+	OUT_RING_F(((srcYend - draw_coords[0][1]) / scale_units[0][1]));
+	if (pMask) {
+		OUT_RING_F(((maskX - draw_coords[1][0]) / scale_units[1][0]));
+		OUT_RING_F(((maskYend - draw_coords[1][1]) / scale_units[1][1]));
+	}
+
+	OUT_RING((dstX+w));
+	OUT_RING((dstY+h));
+	OUT_RING_F(((srcXend - draw_coords[0][0]) / scale_units[0][0]));
+	OUT_RING_F(((srcYend - draw_coords[0][1]) / scale_units[0][1]));
+	if (pMask) {
+		OUT_RING_F(((maskXend - draw_coords[1][0]) / scale_units[1][0]));
+		OUT_RING_F(((maskYend - draw_coords[1][1]) / scale_units[1][1]));
+	}
+
+	OUT_RING((dstX+w));
+	OUT_RING((dstY));
+	OUT_RING_F(((srcXend - draw_coords[0][0]) / scale_units[0][0]));
+	OUT_RING_F(((srcY - draw_coords[0][1]) / scale_units[0][1]));
+	if (pMask) {
+		OUT_RING_F(((maskXend - draw_coords[1][0]) / scale_units[1][0]));
+		OUT_RING_F(((maskY - draw_coords[1][1]) / scale_units[1][1]));
+	}
+	ADVANCE_LP_RING();
+    }
+#ifdef I830DEBUG
+    ErrorF("sync after 3dprimitive");
+    I830Sync(pScrn);
+#endif
 
-static void
-I830EXAComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
-		 int dstX, int dstY, int width, int height)
-{
-    return; /* no Composite yet */
 }
 
 static void
-I830EXADoneComposite(PixmapPtr pDst)
+IntelEXADoneComposite(PixmapPtr pDst)
 {
-    return; /* no Composite yet */
+    return; 
 }
-#endif
-
 /*
  * TODO:
  *   - Dual head?
- *   - Upload/Download
- *   - Composite
  */
 Bool
 I830EXAInit(ScreenPtr pScreen)
@@ -396,6 +575,12 @@ I830EXAInit(ScreenPtr pScreen)
     pI830->EXADriverPtr->offScreenBase = pI830->Offscreen.Start;
     pI830->EXADriverPtr->memorySize = pI830->Offscreen.End;
 	   
+    DPRINTF(PFX, "EXA Mem: memoryBase 0x%x, end 0x%x, offscreen base 0x%x, memorySize 0x%x\n",
+		pI830->EXADriverPtr->memoryBase,
+		pI830->EXADriverPtr->memoryBase + pI830->EXADriverPtr->memorySize,
+		pI830->EXADriverPtr->offScreenBase,
+		pI830->EXADriverPtr->memorySize);
+
     if(pI830->EXADriverPtr->memorySize >
        pI830->EXADriverPtr->offScreenBase)
 	pI830->EXADriverPtr->flags = EXA_OFFSCREEN_PIXMAPS;
@@ -422,17 +607,23 @@ I830EXAInit(ScreenPtr pScreen)
     pI830->EXADriverPtr->PrepareCopy = I830EXAPrepareCopy;
     pI830->EXADriverPtr->Copy = I830EXACopy;
     pI830->EXADriverPtr->DoneCopy = I830EXADoneCopy;
-#if 0
-    /* Upload, download to/from Screen */
-    pI830->EXADriverPtr->UploadToScreen = I830EXAUploadToScreen;
-    pI830->EXADriverPtr->DownloadFromScreen = I830EXADownloadFromScreen;
 
     /* Composite */
-    pI830->EXADriverPtr->CheckComposite = I830EXACheckComposite;
-    pI830->EXADriverPtr->PrepareComposite = I830EXAPrepareComposite;
-    pI830->EXADriverPtr->Composite = I830EXAComposite;
-    pI830->EXADriverPtr->DoneComposite = I830EXADoneComposite;
-#endif
+    if (IS_I9XX(pI830)) {   		
+	pI830->EXADriverPtr->CheckComposite = I915EXACheckComposite;
+   	pI830->EXADriverPtr->PrepareComposite = I915EXAPrepareComposite;
+    	pI830->EXADriverPtr->Composite = IntelEXAComposite;
+    	pI830->EXADriverPtr->DoneComposite = IntelEXADoneComposite;
+    } else if (IS_I865G(pI830) || IS_I855(pI830) || IS_845G(pI830) || IS_I830(pI830)) { 
+    	pI830->EXADriverPtr->CheckComposite = I830EXACheckComposite;
+    	pI830->EXADriverPtr->PrepareComposite = I830EXAPrepareComposite;
+    	pI830->EXADriverPtr->Composite = IntelEXAComposite;
+    	pI830->EXADriverPtr->DoneComposite = IntelEXADoneComposite;
+    }
+
+    /* Upload, download to/from Screen, experimental!! */
+    pI830->EXADriverPtr->UploadToScreen = I830EXAUploadToScreen;
+    pI830->EXADriverPtr->DownloadFromScreen = I830EXADownloadFromScreen;
 
     if(!exaDriverInit(pScreen, pI830->EXADriverPtr)) {
 	xfree(pI830->EXADriverPtr);
diff --git a/src/i830_exa_render.c b/src/i830_exa_render.c
new file mode 100644
index 0000000..9b4835b
--- /dev/null
+++ b/src/i830_exa_render.c
@@ -0,0 +1,537 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "xf86.h"
+#include "i830.h"
+#include "i830_reg.h"
+
+#ifdef I830DEBUG
+#define DEBUG_I830FALLBACK 1
+#endif
+
+#ifdef DEBUG_I830FALLBACK
+#define I830FALLBACK(s, arg...)				\
+do {							\
+	DPRINTF(PFX, "EXA fallback: " s "\n", ##arg); 	\
+	return FALSE;					\
+} while(0)
+#else
+#define I830FALLBACK(s, arg...) 			\
+do { 							\
+	return FALSE;					\
+} while(0) 
+#endif
+
+extern float scale_units[2][2];
+extern int draw_coords[3][2];
+extern Bool is_transform[2];
+extern PictTransform *transform[2];
+
+struct blendinfo {
+    Bool dst_alpha;
+    Bool src_alpha;
+    CARD32 blend_cntl;
+};
+
+struct formatinfo {
+    int fmt;
+    CARD32 card_fmt;
+};
+
+extern Bool
+I830EXACheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
+		      PicturePtr pDstPicture);
+
+extern Bool
+I830EXAPrepareComposite(int op, PicturePtr pSrcPicture,
+			PicturePtr pMaskPicture, PicturePtr pDstPicture,
+			PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst);
+
+/* I830's Blend factor definition, LOAD_STATE_IMMEDIATE_1 */
+/* move to header...*/
+#define I830_SRC_BLENDFACTOR_ZERO 		(1 << 4)
+#define I830_SRC_BLENDFACTOR_ONE 		(2 << 4)
+#define I830_SRC_BLENDFACTOR_SRC_COLOR		(3 << 4)
+#define I830_SRC_BLENDFACTOR_INV_SRC_COLOR	(4 << 4)
+#define I830_SRC_BLENDFACTOR_SRC_ALPHA		(5 << 4)
+#define I830_SRC_BLENDFACTOR_INV_SRC_ALPHA	(6 << 4)
+#define I830_SRC_BLENDFACTOR_DST_ALPHA		(7 << 4)
+#define I830_SRC_BLENDFACTOR_INV_DST_ALPHA	(8 << 4)
+#define I830_SRC_BLENDFACTOR_DST_COLOR		(9 << 4)
+#define I830_SRC_BLENDFACTOR_INV_DST_COLOR	(0xa << 4)
+#define I830_SRC_BLENDFACTOR_SRC_ALPHA_SATURATE (0xb << 4)
+#define I830_SRC_BLENDFACTOR_CONST_COLOR	(0xc << 4)
+#define I830_SRC_BLENDFACTOR_INV_CONST_COLOR	(0xd << 4)
+#define I830_SRC_BLENDFACTOR_CONST_ALPHA	(0xe << 4)
+#define I830_SRC_BLENDFACTOR_INV_CONST_ALPHA	(0xf << 4)
+#define I830_SRC_BLENDFACTOR_MASK		(0xf << 4)
+
+#define I830_DST_BLENDFACTOR_ZERO 		(1)
+#define I830_DST_BLENDFACTOR_ONE 		(2)
+#define I830_DST_BLENDFACTOR_SRC_COLOR		(3)
+#define I830_DST_BLENDFACTOR_INV_SRC_COLOR	(4)
+#define I830_DST_BLENDFACTOR_SRC_ALPHA		(5)
+#define I830_DST_BLENDFACTOR_INV_SRC_ALPHA	(6)
+#define I830_DST_BLENDFACTOR_DST_ALPHA		(7)
+#define I830_DST_BLENDFACTOR_INV_DST_ALPHA	(8)
+#define I830_DST_BLENDFACTOR_DST_COLOR		(9)
+#define I830_DST_BLENDFACTOR_INV_DST_COLOR	(0xa)
+#define I830_DST_BLENDFACTOR_SRC_ALPHA_SATURATE (0xb)
+#define I830_DST_BLENDFACTOR_CONST_COLOR	(0xc)
+#define I830_DST_BLENDFACTOR_INV_CONST_COLOR	(0xd)
+#define I830_DST_BLENDFACTOR_CONST_ALPHA	(0xe)
+#define I830_DST_BLENDFACTOR_INV_CONST_ALPHA	(0xf)
+#define I830_DST_BLENDFACTOR_MASK		(0xf)
+
+#define TB0C_LAST_STAGE	(1 << 31)
+#define TB0C_RESULT_SCALE_1X		(0 << 29)
+#define TB0C_RESULT_SCALE_2X		(1 << 29)
+#define TB0C_RESULT_SCALE_4X		(2 << 29)
+#define TB0C_OP_MODULE			(3 << 25)
+#define TB0C_OUTPUT_WRITE_CURRENT	(0 << 24)
+#define TB0C_OUTPUT_WRITE_ACCUM		(1 << 24)
+#define TB0C_ARG3_REPLICATE_ALPHA 	(1<<23)
+#define TB0C_ARG3_INVERT		(1<<22)
+#define TB0C_ARG3_SEL_XXX
+#define TB0C_ARG2_REPLICATE_ALPHA 	(1<<17)
+#define TB0C_ARG2_INVERT		(1<<16)
+#define TB0C_ARG2_SEL_ONE		(0 << 12)
+#define TB0C_ARG2_SEL_FACTOR		(1 << 12)
+#define TB0C_ARG2_SEL_TEXEL0		(6 << 12)
+#define TB0C_ARG2_SEL_TEXEL1		(7 << 12)
+#define TB0C_ARG2_SEL_TEXEL2		(8 << 12)
+#define TB0C_ARG2_SEL_TEXEL3		(9 << 12)
+#define TB0C_ARG1_REPLICATE_ALPHA 	(1<<11)
+#define TB0C_ARG1_INVERT		(1<<10)
+#define TB0C_ARG1_SEL_TEXEL0		(6 << 6)
+#define TB0C_ARG1_SEL_TEXEL1		(7 << 6)
+#define TB0C_ARG1_SEL_TEXEL2		(8 << 6)
+#define TB0C_ARG1_SEL_TEXEL3		(9 << 6)
+#define TB0C_ARG0_REPLICATE_ALPHA 	(1<<5)
+#define TB0C_ARG0_SEL_XXX
+
+#define TB0A_CTR_STAGE_ENABLE 		(1<<31)
+#define TB0A_RESULT_SCALE_1X		(0 << 29)
+#define TB0A_RESULT_SCALE_2X		(1 << 29)
+#define TB0A_RESULT_SCALE_4X		(2 << 29)
+#define TB0A_OP_MODULE			(3 << 25)
+#define TB0A_OUTPUT_WRITE_CURRENT	(0<<24)
+#define TB0A_OUTPUT_WRITE_ACCUM		(1<<24)
+#define TB0A_CTR_STAGE_SEL_BITS_XXX
+#define TB0A_ARG3_SEL_XXX
+#define TB0A_ARG3_INVERT		(1<<17)
+#define TB0A_ARG2_INVERT		(1<<16)
+#define TB0A_ARG2_SEL_ONE		(0 << 12)
+#define TB0A_ARG2_SEL_TEXEL0		(6 << 12)
+#define TB0A_ARG2_SEL_TEXEL1		(7 << 12)
+#define TB0A_ARG2_SEL_TEXEL2		(8 << 12)
+#define TB0A_ARG2_SEL_TEXEL3		(9 << 12)
+#define TB0A_ARG1_INVERT		(1<<10)
+#define TB0A_ARG1_SEL_TEXEL0		(6 << 6)
+#define TB0A_ARG1_SEL_TEXEL1		(7 << 6)
+#define TB0A_ARG1_SEL_TEXEL2		(8 << 6)
+#define TB0A_ARG1_SEL_TEXEL3		(9 << 6)
+#define TB0A_ARG0_SEL_XXX
+
+/* end */
+
+
+static struct blendinfo I830BlendOp[] = { 
+    /* Clear */
+    {0, 0, I830_SRC_BLENDFACTOR_ZERO           | I830_DST_BLENDFACTOR_ZERO},
+    /* Src */
+    {0, 0, I830_SRC_BLENDFACTOR_ONE            | I830_DST_BLENDFACTOR_ZERO},
+    /* Dst */
+    {0, 0, I830_SRC_BLENDFACTOR_ZERO           | I830_DST_BLENDFACTOR_ONE},
+    /* Over */
+    {0, 1, I830_SRC_BLENDFACTOR_ONE            | I830_DST_BLENDFACTOR_INV_SRC_ALPHA},
+    /* OverReverse */
+    {1, 0, I830_SRC_BLENDFACTOR_INV_DST_ALPHA | I830_DST_BLENDFACTOR_ONE},
+    /* In */
+    {1, 0, I830_SRC_BLENDFACTOR_DST_ALPHA     | I830_DST_BLENDFACTOR_ZERO},
+    /* InReverse */
+    {0, 1, I830_SRC_BLENDFACTOR_ZERO           | I830_DST_BLENDFACTOR_SRC_ALPHA},
+    /* Out */
+    {1, 0, I830_SRC_BLENDFACTOR_INV_DST_ALPHA | I830_DST_BLENDFACTOR_ZERO},
+    /* OutReverse */
+    {0, 1, I830_SRC_BLENDFACTOR_ZERO           | I830_DST_BLENDFACTOR_INV_SRC_ALPHA},
+    /* Atop */
+    {1, 1, I830_SRC_BLENDFACTOR_DST_ALPHA     | I830_DST_BLENDFACTOR_INV_SRC_ALPHA},
+    /* AtopReverse */
+    {1, 1, I830_SRC_BLENDFACTOR_INV_DST_ALPHA | I830_DST_BLENDFACTOR_SRC_ALPHA},
+    /* Xor */
+    {1, 1, I830_SRC_BLENDFACTOR_INV_DST_ALPHA | I830_DST_BLENDFACTOR_INV_SRC_ALPHA},
+    /* Add */
+    {0, 0, I830_SRC_BLENDFACTOR_ONE            | I830_DST_BLENDFACTOR_ONE},
+};
+
+
+static struct formatinfo I830TexFormats[] = {
+        {PICT_a8r8g8b8, MT_32BIT_ARGB8888 },
+        {PICT_x8r8g8b8, MT_32BIT_ARGB8888 },
+        {PICT_a8b8g8r8, MT_32BIT_ABGR8888 },
+        {PICT_x8b8g8r8, MT_32BIT_ABGR8888 },
+        {PICT_r5g6b5,   MT_16BIT_RGB565	  },
+        {PICT_a1r5g5b5, MT_16BIT_ARGB1555 },
+        {PICT_x1r5g5b5, MT_16BIT_ARGB1555 },
+        {PICT_a8,       MT_8BIT_I8       },
+};
+
+static Bool I830GetDestFormat(PicturePtr pDstPicture, CARD32 *dst_format)
+{
+	/* XXX: color buffer format for i830 */
+    switch (pDstPicture->format) {
+    case PICT_a8r8g8b8:
+    case PICT_x8r8g8b8:
+        *dst_format = COLR_BUF_ARGB8888;
+        break;
+    case PICT_r5g6b5:
+        *dst_format = COLR_BUF_RGB565;
+        break;
+    case PICT_a1r5g5b5:
+    case PICT_x1r5g5b5:
+        *dst_format = COLR_BUF_ARGB1555;
+        break;
+    case PICT_a8:
+        *dst_format = COLR_BUF_8BIT;
+        break;
+    case PICT_a4r4g4b4:
+    case PICT_x4r4g4b4:
+	*dst_format = COLR_BUF_ARGB4444;
+	break;
+    default:
+        I830FALLBACK("Unsupported dest format 0x%x\n",
+                        (int)pDstPicture->format);
+    }
+
+    return TRUE;
+}
+
+
+static CARD32 I830GetBlendCntl(int op, PicturePtr pMask, CARD32 dst_format)
+{
+    CARD32 sblend, dblend;
+
+    sblend = I830BlendOp[op].blend_cntl & I830_SRC_BLENDFACTOR_MASK;
+    dblend = I830BlendOp[op].blend_cntl & I830_DST_BLENDFACTOR_MASK;
+
+    /* If there's no dst alpha channel, adjust the blend op so that we'll treat
+     * it as always 1.
+     */
+    if (PICT_FORMAT_A(dst_format) == 0 && I830BlendOp[op].dst_alpha) {
+        if (sblend == I830_SRC_BLENDFACTOR_DST_ALPHA)
+            sblend = I830_SRC_BLENDFACTOR_ONE;
+        else if (sblend == I830_SRC_BLENDFACTOR_INV_DST_ALPHA)
+            sblend = I830_SRC_BLENDFACTOR_ZERO;
+    }
+
+    /* If the source alpha is being used, then we should only be in a case where
+     * the source blend factor is 0, and the source blend value is the mask
+     * channels multiplied by the source picture's alpha.
+     */
+    if (pMask && pMask->componentAlpha && I830BlendOp[op].src_alpha) {
+        if (dblend == I830_DST_BLENDFACTOR_SRC_ALPHA) {
+            dblend = I830_DST_BLENDFACTOR_SRC_COLOR;
+        } else if (dblend == I830_DST_BLENDFACTOR_INV_SRC_ALPHA) {
+            dblend = I830_DST_BLENDFACTOR_INV_SRC_COLOR;
+        }
+    }
+
+    return sblend | dblend;
+}
+
+static Bool I830CheckCompositeTexture(PicturePtr pPict, int unit)
+{
+    int w = pPict->pDrawable->width;
+    int h = pPict->pDrawable->height;
+    int i;
+                                                                                                                                                            
+    if ((w > 0x7ff) || (h > 0x7ff))
+        I830FALLBACK("Picture w/h too large (%dx%d)\n", w, h);
+
+    for (i = 0; i < sizeof(I830TexFormats) / sizeof(I830TexFormats[0]); i++)
+    {
+        if (I830TexFormats[i].fmt == pPict->format)
+            break;
+    }
+    if (i == sizeof(I830TexFormats) / sizeof(I830TexFormats[0]))
+        I830FALLBACK("Unsupported picture format 0x%x\n",
+                         (int)pPict->format);
+
+    /* FIXME: fix repeat support */
+    if (pPict->repeat)
+	I830FALLBACK("repeat unsupport now\n");
+
+    if (pPict->filter != PictFilterNearest &&
+        pPict->filter != PictFilterBilinear)
+        I830FALLBACK("Unsupported filter 0x%x\n", pPict->filter);
+
+    return TRUE;
+}
+
+static Bool
+I830TextureSetup(PicturePtr pPict, PixmapPtr pPix, int unit)
+{
+
+    ScrnInfoPtr pScrn = xf86Screens[pPict->pDrawable->pScreen->myNum];
+    I830Ptr pI830 = I830PTR(pScrn);
+    CARD32 format, offset, pitch, filter;
+    int w, h, i;
+    CARD32 wrap_mode = TEXCOORDMODE_CLAMP; 
+
+    offset = exaGetPixmapOffset(pPix);
+    pitch = exaGetPixmapPitch(pPix);
+    w = pPict->pDrawable->width;
+    h = pPict->pDrawable->height;
+    scale_units[unit][0] = pPix->drawable.width;
+    scale_units[unit][1] = pPix->drawable.height;
+    draw_coords[unit][0] = pPix->drawable.x;
+    draw_coords[unit][1] = pPix->drawable.y;
+
+    for (i = 0; i < sizeof(I830TexFormats) / sizeof(I830TexFormats[0]); i++) {
+        if (I830TexFormats[i].fmt == pPict->format)
+	    break;
+    }
+    if ( i == sizeof(I830TexFormats)/ sizeof(I830TexFormats[0]) )
+	I830FALLBACK("unknown texture format\n");
+    format = I830TexFormats[i].card_fmt;
+
+    if (pPict->repeat) 
+	wrap_mode = TEXCOORDMODE_WRAP; /* XXX: correct ? */
+    
+    switch (pPict->filter) {
+    case PictFilterNearest:
+        filter = ((FILTER_NEAREST<<TM0S3_MAG_FILTER_SHIFT) | 
+			(FILTER_NEAREST<<TM0S3_MIN_FILTER_SHIFT));
+        break;
+    case PictFilterBilinear:
+        filter = ((FILTER_LINEAR<<TM0S3_MAG_FILTER_SHIFT) | 
+			(FILTER_LINEAR<<TM0S3_MIN_FILTER_SHIFT));
+        break;
+    default:
+	filter = 0;
+        I830FALLBACK("Bad filter 0x%x\n", pPict->filter);
+    }
+
+    {
+	if (pI830->cpp == 1)
+		format |= MAP_SURFACE_8BIT;
+	else if (pI830->cpp == 2)
+		format |= MAP_SURFACE_16BIT;
+	else
+		format |= MAP_SURFACE_32BIT;
+
+	BEGIN_LP_RING(6);
+	OUT_RING(_3DSTATE_MAP_INFO_CMD);
+	OUT_RING(format | TEXMAP_INDEX(unit) | MAP_FORMAT_2D);
+	OUT_RING((pPix->drawable.height<<16)|pPix->drawable.width); /* height, width */
+	OUT_RING(offset<<2); /* map address */
+	OUT_RING(pitch<<2); /* map pitch */
+	OUT_RING(0);
+	ADVANCE_LP_RING();
+     }
+
+     {
+	BEGIN_LP_RING(2);
+	/* coord sets */
+	OUT_RING(_3DSTATE_MAP_COORD_SET_CMD | TEXCOORD_SET(unit) | 
+		ENABLE_TEXCOORD_PARAMS | TEXCOORDS_ARE_NORMAL | /*XXX, check this, and fix vertex tex coord*/
+		TEXCOORDTYPE_CARTESIAN | ENABLE_ADDR_V_CNTL | TEXCOORD_ADDR_V_MODE(wrap_mode) |
+		ENABLE_ADDR_U_CNTL | TEXCOORD_ADDR_U_MODE(wrap_mode));
+	OUT_RING(MI_NOOP);
+
+	/* XXX: filter seems hang engine...*/
+#if 0
+	OUT_RING(I830_STATE3D_MAP_FILTER | FILTER_MAP_INDEX(unit) | ENABLE_KEYS| DISABLE_COLOR_KEY | DISABLE_CHROMA_KEY | DISABLE_KILL_PIXEL |ENABLE_MIP_MODE_FILTER | MIPFILTER_NONE | filter);
+	OUT_RING(0);
+#endif
+
+	/* max & min mip level ? or base mip level? */
+
+	ADVANCE_LP_RING();
+    }
+
+	/* XXX */
+    if (pPict->transform != 0) {
+        is_transform[unit] = TRUE;
+        transform[unit] = pPict->transform;
+    } else {
+        is_transform[unit] = FALSE;
+    }
+
+#ifdef I830DEBUG
+    ErrorF("try to sync to show any errors...");
+    I830Sync(pScrn);
+#endif
+	
+    return TRUE;
+}
+
+Bool
+I830EXACheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
+		      PicturePtr pDstPicture)
+{
+    CARD32 tmp1;
+    
+    /* Check for unsupported compositing operations. */
+    if (op >= sizeof(I830BlendOp) / sizeof(I830BlendOp[0]))
+        I830FALLBACK("Unsupported Composite op 0x%x\n", op);
+                                                                                                                                                            
+    if (pMaskPicture != NULL && pMaskPicture->componentAlpha) {
+        /* Check if it's component alpha that relies on a source alpha and on
+         * the source value.  We can only get one of those into the single
+         * source value that we get to blend with.
+         */
+        if (I830BlendOp[op].src_alpha &&
+            (I830BlendOp[op].blend_cntl & I830_SRC_BLENDFACTOR_MASK) !=
+             I830_SRC_BLENDFACTOR_ZERO)
+            	I830FALLBACK("Component alpha not supported with source "
+                            "alpha and source value blending.\n");
+    }
+
+    if (!I830CheckCompositeTexture(pSrcPicture, 0))
+        I830FALLBACK("Check Src picture texture\n");
+    if (pMaskPicture != NULL && !I830CheckCompositeTexture(pMaskPicture, 1))
+        I830FALLBACK("Check Mask picture texture\n");
+
+    if (!I830GetDestFormat(pDstPicture, &tmp1)) 
+	I830FALLBACK("Get Color buffer format\n");
+
+    return TRUE;
+}
+
+
+static void
+I830DefCtxSetup(ScrnInfoPtr pScrn)
+{
+	/* coord binding */
+	CARD32 mcb;
+    	I830Ptr pI830 = I830PTR(pScrn);
+
+	BEGIN_LP_RING(2);
+	OUT_RING(_3DSTATE_MAP_COORD_SETBIND_CMD);
+	mcb = TEXBIND_SET3(TEXCOORDSRC_VTXSET_3);
+	mcb |= TEXBIND_SET2(TEXCOORDSRC_VTXSET_2);
+	mcb |= TEXBIND_SET1(TEXCOORDSRC_VTXSET_1);
+	mcb |= TEXBIND_SET0(TEXCOORDSRC_VTXSET_0);
+	OUT_RING(mcb);
+	ADVANCE_LP_RING();
+}
+
+
+Bool
+I830EXAPrepareComposite(int op, PicturePtr pSrcPicture,
+			PicturePtr pMaskPicture, PicturePtr pDstPicture,
+			PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst)
+{
+/* XXX: setup texture map from pixmap, vertex format, blend cntl */
+    ScrnInfoPtr pScrn = xf86Screens[pSrcPicture->pDrawable->pScreen->myNum];
+    I830Ptr pI830 = I830PTR(pScrn);
+    CARD32 dst_format, dst_offset, dst_pitch;
+
+    I830GetDestFormat(pDstPicture, &dst_format);
+    dst_offset = exaGetPixmapOffset(pDst);
+    dst_pitch = exaGetPixmapPitch(pDst);
+    draw_coords[2][0] = pDst->drawable.x;
+    draw_coords[2][1] = pDst->drawable.y;
+    
+    I830DefCtxSetup(pScrn);
+
+    if (!I830TextureSetup(pSrcPicture, pSrc, 0))
+	I830FALLBACK("fail to setup src texture\n");
+    if (pMask != NULL) {
+	if (!I830TextureSetup(pMaskPicture, pMask, 1))
+		I830FALLBACK("fail to setup mask texture\n");
+    } else {
+	is_transform[1] = FALSE;
+	scale_units[1][0] = -1;
+	scale_units[1][1] = -1;
+    }
+
+    {
+
+	CARD32 cblend, ablend, blendctl, vf2;
+
+	BEGIN_LP_RING(22);
+	
+	/*color buffer*/
+	OUT_RING(_3DSTATE_BUF_INFO_CMD);
+	OUT_RING(BUF_3D_ID_COLOR_BACK| BUF_3D_PITCH(dst_pitch));
+	OUT_RING(BUF_3D_ADDR(dst_offset));
+	OUT_RING(MI_NOOP);
+	
+	OUT_RING(_3DSTATE_DST_BUF_VARS_CMD);
+	OUT_RING(dst_format);
+
+	/* defaults */
+	OUT_RING(_3DSTATE_DFLT_Z_CMD);
+	OUT_RING(0);
+
+	OUT_RING(_3DSTATE_DFLT_DIFFUSE_CMD);
+	OUT_RING(0);
+
+	OUT_RING(_3DSTATE_DFLT_SPEC_CMD);
+	OUT_RING(0);
+	
+	OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1|I1_LOAD_S(3)|0);
+	OUT_RING((1<<S3_POINT_WIDTH_SHIFT) | (2<<S3_LINE_WIDTH_SHIFT) | S3_CULLMODE_NONE| S3_VERTEXHAS_XY);  
+	OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1|I1_LOAD_S(2)|0);
+	if (pMask)
+		vf2 = 2 << 12; /* 2 texture coord sets */
+	else
+		vf2 = 1 << 12;
+	vf2 |= (TEXCOORDFMT_2D << 16);
+	if (pMask)
+		vf2 |= (TEXCOORDFMT_2D << 18);
+	else
+		vf2 |= (TEXCOORDFMT_1D << 18);
+		
+	vf2 |= (TEXCOORDFMT_1D << 20);
+	vf2 |= (TEXCOORDFMT_1D << 22);
+	vf2 |= (TEXCOORDFMT_1D << 24);
+	vf2 |= (TEXCOORDFMT_1D << 26);
+	vf2 |= (TEXCOORDFMT_1D << 28);
+	vf2 |= (TEXCOORDFMT_1D << 30);
+	OUT_RING(vf2);
+
+	/* For (src In mask) operation */
+	/* IN operator: Multiply src by mask components or mask alpha.*/
+	/* TEXBLENDOP_MODULE: arg1*arg2 */
+	cblend = TB0C_LAST_STAGE | TB0C_RESULT_SCALE_1X | TB0C_OP_MODULE |
+		 TB0C_OUTPUT_WRITE_CURRENT;  
+	ablend = TB0A_RESULT_SCALE_1X | TB0A_OP_MODULE | TB0A_OUTPUT_WRITE_CURRENT;
+	
+	cblend |= TB0C_ARG1_SEL_TEXEL0;
+	ablend |= TB0A_ARG1_SEL_TEXEL0;
+	if (pMask) {
+		if (pMaskPicture->componentAlpha && pDstPicture->format != PICT_a8)
+			cblend |= TB0C_ARG2_SEL_TEXEL1;
+		else
+			cblend |= (TB0C_ARG2_SEL_TEXEL1 | TB0C_ARG2_REPLICATE_ALPHA);
+		ablend |= TB0A_ARG2_SEL_TEXEL1;
+	} else {
+		cblend |= TB0C_ARG2_SEL_ONE;
+		ablend |= TB0A_ARG2_SEL_ONE;		
+	}
+		
+	OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_2 | LOAD_TEXTURE_BLEND_STAGE(0)|1);
+	OUT_RING(cblend);
+	OUT_RING(ablend);
+	OUT_RING(0);
+
+	blendctl = I830GetBlendCntl(op, pMaskPicture, pDstPicture->format);
+	OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(8) | 0);
+	OUT_RING(S8_ENABLE_COLOR_BLEND | S8_BLENDFUNC_ADD |(blendctl<<4) |
+		S8_ENABLE_COLOR_BUFFER_WRITE);	
+	ADVANCE_LP_RING();
+    }
+
+#ifdef I830DEBUG
+   Error("try to sync to show any errors...");
+   I830Sync(pScrn);
+#endif
+
+    return TRUE;
+}
+
diff --git a/src/i830_reg.h b/src/i830_reg.h
index be12e76..ae68a2e 100644
--- a/src/i830_reg.h
+++ b/src/i830_reg.h
@@ -31,6 +31,23 @@
 
 #define I830_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)
+
 #define _3DSTATE_AA_CMD			(CMD_3D | (0x06<<24))
 #define AA_LINE_ECAAR_WIDTH_ENABLE	(1<<16)
 #define AA_LINE_ECAAR_WIDTH_0_5 	0
@@ -85,6 +102,8 @@
 #define COLR_BUF_RGB555 		(1<<8)
 #define COLR_BUF_RGB565 		(2<<8)
 #define COLR_BUF_ARGB8888		(3<<8)
+#define COLR_BUF_ARGB4444		(8<<8)
+#define COLR_BUF_ARGB1555		(9<<8)
 #define DEPTH_IS_Z			0
 #define DEPTH_IS_W			(1<<6)
 #define DEPTH_FRMT_16_FIXED		0
@@ -301,6 +320,7 @@
 
 /* _3DSTATE_MAP_COORD_SETS, p164 */
 #define _3DSTATE_MAP_COORD_SET_CMD	(CMD_3D|(0x1c<<24)|(0x01<<19))
+#define TEXCOORD_SET(n)			((n)<<16)
 #define ENABLE_TEXCOORD_PARAMS		(1<<15)
 #define TEXCOORDS_ARE_NORMAL		(1<<14)
 #define TEXCOORDS_ARE_IN_TEXELUNITS	0
@@ -329,6 +349,13 @@
 #define CUBE_NEGZ_ENABLE                (1<<1)
 #define CUBE_POSZ_ENABLE                (1<<0)
 
+#define _3DSTATE_MAP_INFO_CMD		(CMD_3D|(0x1d<<24)|(0x0<<16)|3)
+#define TEXMAP_INDEX(x)			((x)<<28)
+#define MAP_SURFACE_8BIT		(1<<24)
+#define MAP_SURFACE_16BIT		(2<<24)
+#define MAP_SURFACE_32BIT		(3<<24)
+#define MAP_FORMAT_2D			(0)
+#define MAP_FORMAT_3D_CUBE		(1<<11)
 
 /* _3DSTATE_MODES_1, p190 */
 #define _3DSTATE_MODES_1_CMD		(CMD_3D|(0x08<<24))
@@ -523,14 +550,57 @@
 
 /* Stipple command, carried over from the i810, apparently:
  */
-#define _3DSTATE_STIPPLE           ((0x3<<29)|(0x1d<<24)|(0x83<<16))
+#define _3DSTATE_STIPPLE           (CMD_3D|(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 _3DSTATE_LOAD_STATE_IMMEDIATE_1	     (CMD_3D|(0x1d<<24)|(0x04<<16))
+#define I1_LOAD_S(n)			     (1<<((n)+4))
+#define S3_POINT_WIDTH_SHIFT		     23
+#define S3_LINE_WIDTH_SHIFT		     19
+#define S3_ALPHA_SHADE_MODE_SHIFT	     18
+#define S3_FOG_SHADE_MODE_SHIFT		     17
+#define S3_SPEC_SHADE_MODE_SHIFT	     16
+#define S3_COLOR_SHADE_MODE_SHIFT	     15
+#define S3_CULL_MODE_SHIFT		     13
+#define    S3_CULLMODE_BOTH		     (0)
+#define    S3_CULLMODE_NONE		     (1<<13)
+#define    S3_CULLMODE_CW		     (2<<13)
+#define    S3_CULLMODE_CCW		     (3<<13)
+#define S3_POINT_WIDTH_PRESENT		     (1<<12)
+#define S3_SPEC_FOG_PRESENT		     (1<<11)
+#define S3_DIFFUSE_PRESENT		     (1<<10)
+#define S3_DEPTH_OFFSET_PRESENT		     (1<<9)
+#define S3_POSITION_SHIFT		     6
+#define    S3_VERTEXHAS_XYZ		     (1<<6)
+#define    S3_VERTEXHAS_XYZW		     (2<<6)
+#define    S3_VERTEXHAS_XY		     (3<<6)
+#define    S3_VERTEXHAS_XYW		     (4<<6)
+#define S3_ENABLE_SPEC_ADD		     (1<<5)
+#define S3_ENABLE_FOG			     (1<<4)
+#define S3_ENABLE_LOCAL_DEPTH_BIAS	     (1<<3)
+#define S3_ENABLE_SPRITE_POINT		     (1<<1)
+#define S3_ENABLE_ANTIALIASING		     1
+#define S8_ENABLE_ALPHA_TEST		     (1<<31)
+#define S8_ALPHA_TEST_FUNC_SHIFT	     28
+#define S8_ALPHA_REFVALUE_SHIFT		     20
+#define S8_ENABLE_DEPTH_TEST		     (1<<19)
+#define S8_DEPTH_TEST_FUNC_SHIFT	     16
+#define S8_ENABLE_COLOR_BLEND		     (1<<15)
+#define S8_COLOR_BLEND_FUNC_SHIFT	     12
+#define    S8_BLENDFUNC_ADD		     (0)
+#define    S8_BLENDFUNC_SUB		     (1<<12)
+#define    S8_BLENDFUNC_RVRSE_SUB	     (2<<12)
+#define    S8_BLENDFUNC_MIN		     (3<<12)
+#define    S8_BLENDFUNC_MAX			     (4<<12)
+#define S8_SRC_BLEND_FACTOR_SHIFT	     8
+#define S8_DST_BLEND_FACTOR_SHIFT	     4
+#define S8_ENABLE_DEPTH_BUFFER_WRITE	     (1<<3)
+#define S8_ENABLE_COLOR_BUFFER_WRITE	     (1<<2)
+
+#define _3DSTATE_LOAD_STATE_IMMEDIATE_2      (CMD_3D|(0x1d<<24)|(0x03<<16))
+#define LOAD_TEXTURE_MAP(x)                   (1<<((x)+11))
+#define LOAD_TEXTURE_BLEND_STAGE(x)	      (1<<((x)+7))
 #define LOAD_GLOBAL_COLOR_FACTOR            (1<<6)
 
 #define TM0S0_ADDRESS_MASK              0xfffffffc
@@ -591,6 +661,8 @@
 #define TM0S2_CUBE_FACE_ENA_SHIFT       15
 #define TM0S2_CUBE_FACE_ENA_MASK        (1<<15)
 #define TM0S2_MAP_FORMAT                (1<<14)
+#define    TM0S2_MAP_2D			(0<<14)
+#define    TM0S2_MAP_3D_CUBE		(1<<14)
 #define TM0S2_VERTICAL_LINE_STRIDE      (1<<13)
 #define TM0S2_VERITCAL_LINE_STRIDE_OFF  (1<<12)
 #define TM0S2_OUTPUT_CHAN_SHIFT         10
@@ -634,4 +706,23 @@
 
 #define FLUSH_MAP_CACHE    (1<<0)
 
+#define _3DSTATE_MAP_FILTER_CMD    (CMD_3D|(0x1c<<24)|(0x02<<19))
+#define FILTER_TEXMAP_INDEX(x) ((x) << 16)
+#define MAG_MODE_FILTER_ENABLE (1 << 5) 
+#define MIN_MODE_FILTER_ENABLE (1 << 2) 
+#define MAG_MAPFILTER_NEAREST (0 << 3)
+#define MAG_MAPFILTER_LINEAR  (1 << 3)
+#define MAG_MAPFILTER_ANISOTROPIC (2 << 3)
+#define MIN_MAPFILTER_NEAREST (0)
+#define MIN_MAPFILTER_LINEAR  (1)
+#define MIN_MAPFILTER_ANISOTROPIC (2)
+#define ENABLE_KEYS	(1<<15)
+#define DISABLE_COLOR_KEY	0 
+#define DISABLE_CHROMA_KEY	0
+#define DISABLE_KILL_PIXEL	0
+#define ENABLE_MIP_MODE_FILTER	(1 << 9)
+#define MIPFILTER_NONE		0
+#define MIPFILTER_NEAREST	1
+#define MIPFILTER_LINEAR	3
+
 #endif
diff --git a/src/i915_exa_render.c b/src/i915_exa_render.c
new file mode 100644
index 0000000..68c929e
--- /dev/null
+++ b/src/i915_exa_render.c
@@ -0,0 +1,553 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "xf86.h"
+#include "i830.h"
+#include "i915_reg.h"
+
+#ifdef I830DEBUG
+#define DEBUG_I830FALLBACK 1
+#endif
+
+#ifdef DEBUG_I830FALLBACK
+#define I830FALLBACK(s, arg...)				\
+do {							\
+	DPRINTF(PFX, "EXA fallback: " s "\n", ##arg); 	\
+	return FALSE;					\
+} while(0)
+#else
+#define I830FALLBACK(s, arg...) 			\
+do { 							\
+	return FALSE;					\
+} while(0) 
+#endif
+
+extern float scale_units[2][2];
+extern int draw_coords[3][2];
+extern Bool is_transform[2];
+extern PictTransform *transform[2];
+
+struct formatinfo {
+    int fmt;
+    CARD32 card_fmt;
+};
+
+struct blendinfo {
+    Bool dst_alpha;
+    Bool src_alpha;
+    CARD32 blend_cntl;
+};
+
+extern Bool
+I915EXACheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
+		      PicturePtr pDstPicture);
+
+extern Bool
+I915EXAPrepareComposite(int op, PicturePtr pSrcPicture,
+			PicturePtr pMaskPicture, PicturePtr pDstPicture,
+			PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst);
+
+/* copy from Eric's texture-video branch, move to header.. */
+#define OUT_DCL(type, nr) do {                                          \
+   CARD32 chans = 0;                                                    \
+   if (REG_TYPE_##type == REG_TYPE_T)                                   \
+      chans = D0_CHANNEL_ALL;                                           \
+   else if (REG_TYPE_##type != REG_TYPE_S)                              \
+      FatalError("wrong reg type %d to declare\n", REG_TYPE_##type);    \
+   OUT_RING(D0_DCL |                                                    \
+            (REG_TYPE_##type << D0_TYPE_SHIFT) | (nr << D0_NR_SHIFT) |  \
+            chans);                                                     \
+   OUT_RING(0x00000000);                                                \
+   OUT_RING(0x00000000);                                                \
+} while (0)
+
+#define OUT_TEXLD(dest_type, dest_nr, sampler_nr, addr_type, addr_nr)   \
+do {                                                                    \
+      OUT_RING(T0_TEXLD |                                               \
+               (REG_TYPE_##dest_type << T0_DEST_TYPE_SHIFT) |           \
+               (dest_nr << T0_DEST_NR_SHIFT) |                          \
+               (sampler_nr << T0_SAMPLER_NR_SHIFT));                    \
+      OUT_RING((REG_TYPE_##addr_type << T1_ADDRESS_REG_TYPE_SHIFT) |    \
+               (addr_nr << T1_ADDRESS_REG_NR_SHIFT));                   \
+      OUT_RING(0x00000000);                                             \
+} while (0)
+
+/* XXX: It seems that offset of 915's blendfactor in Load_immediate_1
+   is _different_ with i830, so I should just define plain value
+   and use it with shift bits*/
+
+#define I915_SRC_BLENDFACTOR_ZERO 		(1 << 8)
+#define I915_SRC_BLENDFACTOR_ONE 		(2 << 8)
+#define I915_SRC_BLENDFACTOR_SRC_COLOR		(3 << 8)
+#define I915_SRC_BLENDFACTOR_INV_SRC_COLOR	(4 << 8)
+#define I915_SRC_BLENDFACTOR_SRC_ALPHA		(5 << 8)
+#define I915_SRC_BLENDFACTOR_INV_SRC_ALPHA	(6 << 8)
+#define I915_SRC_BLENDFACTOR_DST_ALPHA		(7 << 8)
+#define I915_SRC_BLENDFACTOR_INV_DST_ALPHA	(8 << 8)
+#define I915_SRC_BLENDFACTOR_DST_COLOR		(9 << 8)
+#define I915_SRC_BLENDFACTOR_INV_DST_COLOR	(0xa << 8)
+#define I915_SRC_BLENDFACTOR_SRC_ALPHA_SATURATE (0xb << 8)
+#define I915_SRC_BLENDFACTOR_CONST_COLOR	(0xc << 8)
+#define I915_SRC_BLENDFACTOR_INV_CONST_COLOR	(0xd << 8)
+#define I915_SRC_BLENDFACTOR_CONST_ALPHA	(0xe << 8)
+#define I915_SRC_BLENDFACTOR_INV_CONST_ALPHA	(0xf << 8)
+#define I915_SRC_BLENDFACTOR_MASK		(0xf << 8)
+
+#define I915_DST_BLENDFACTOR_ZERO 		(1 << 4)
+#define I915_DST_BLENDFACTOR_ONE 		(2 << 4)
+#define I915_DST_BLENDFACTOR_SRC_COLOR		(3 << 4)
+#define I915_DST_BLENDFACTOR_INV_SRC_COLOR	(4 << 4)
+#define I915_DST_BLENDFACTOR_SRC_ALPHA		(5 << 4)
+#define I915_DST_BLENDFACTOR_INV_SRC_ALPHA	(6 << 4)
+#define I915_DST_BLENDFACTOR_DST_ALPHA		(7 << 4)
+#define I915_DST_BLENDFACTOR_INV_DST_ALPHA	(8 << 4)
+#define I915_DST_BLENDFACTOR_DST_COLOR		(9 << 4)
+#define I915_DST_BLENDFACTOR_INV_DST_COLOR	(0xa << 4)
+#define I915_DST_BLENDFACTOR_SRC_ALPHA_SATURATE (0xb << 4)
+#define I915_DST_BLENDFACTOR_CONST_COLOR	(0xc << 4)
+#define I915_DST_BLENDFACTOR_INV_CONST_COLOR	(0xd << 4)
+#define I915_DST_BLENDFACTOR_CONST_ALPHA	(0xe << 4)
+#define I915_DST_BLENDFACTOR_INV_CONST_ALPHA	(0xf << 4)
+#define I915_DST_BLENDFACTOR_MASK		(0xf << 4)
+
+static struct blendinfo I915BlendOp[] = { 
+    /* Clear */
+    {0, 0, I915_SRC_BLENDFACTOR_ZERO           | I915_DST_BLENDFACTOR_ZERO},
+    /* Src */
+    {0, 0, I915_SRC_BLENDFACTOR_ONE            | I915_DST_BLENDFACTOR_ZERO},
+    /* Dst */
+    {0, 0, I915_SRC_BLENDFACTOR_ZERO           | I915_DST_BLENDFACTOR_ONE},
+    /* Over */
+    {0, 1, I915_SRC_BLENDFACTOR_ONE            | I915_DST_BLENDFACTOR_INV_SRC_ALPHA},
+    /* OverReverse */
+    {1, 0, I915_SRC_BLENDFACTOR_INV_DST_ALPHA | I915_DST_BLENDFACTOR_ONE},
+    /* In */
+    {1, 0, I915_SRC_BLENDFACTOR_DST_ALPHA     | I915_DST_BLENDFACTOR_ZERO},
+    /* InReverse */
+    {0, 1, I915_SRC_BLENDFACTOR_ZERO           | I915_DST_BLENDFACTOR_SRC_ALPHA},
+    /* Out */
+    {1, 0, I915_SRC_BLENDFACTOR_INV_DST_ALPHA | I915_DST_BLENDFACTOR_ZERO},
+    /* OutReverse */
+    {0, 1, I915_SRC_BLENDFACTOR_ZERO           | I915_DST_BLENDFACTOR_INV_SRC_ALPHA},
+    /* Atop */
+    {1, 1, I915_SRC_BLENDFACTOR_DST_ALPHA     | I915_DST_BLENDFACTOR_INV_SRC_ALPHA},
+    /* AtopReverse */
+    {1, 1, I915_SRC_BLENDFACTOR_INV_DST_ALPHA | I915_DST_BLENDFACTOR_SRC_ALPHA},
+    /* Xor */
+    {1, 1, I915_SRC_BLENDFACTOR_INV_DST_ALPHA | I915_DST_BLENDFACTOR_INV_SRC_ALPHA},
+    /* Add */
+    {0, 0, I915_SRC_BLENDFACTOR_ONE            | I915_DST_BLENDFACTOR_ONE},
+};
+
+static struct formatinfo I915TexFormats[] = {
+        {PICT_a8r8g8b8, MT_32BIT_ARGB8888 },
+        {PICT_x8r8g8b8, MT_32BIT_XRGB8888 },
+        {PICT_a8b8g8r8, MT_32BIT_ABGR8888 },
+        {PICT_x8b8g8r8, MT_32BIT_XBGR8888 },
+        {PICT_r5g6b5,   MT_16BIT_RGB565   },
+        {PICT_a1r5g5b5, MT_16BIT_ARGB1555 },
+        {PICT_x1r5g5b5, MT_16BIT_ARGB1555 },
+        {PICT_a8,       MT_8BIT_I8 	  },
+};
+
+static CARD32 I915GetBlendCntl(int op, PicturePtr pMask, CARD32 dst_format)
+{
+    CARD32 sblend, dblend;
+
+    sblend = I915BlendOp[op].blend_cntl & I915_SRC_BLENDFACTOR_MASK;
+    dblend = I915BlendOp[op].blend_cntl & I915_DST_BLENDFACTOR_MASK;
+
+    /* If there's no dst alpha channel, adjust the blend op so that we'll treat
+     * it as always 1.
+     */
+    if (PICT_FORMAT_A(dst_format) == 0 && I915BlendOp[op].dst_alpha) {
+        if (sblend == I915_SRC_BLENDFACTOR_DST_ALPHA)
+            sblend = I915_SRC_BLENDFACTOR_ONE;
+        else if (sblend == I915_SRC_BLENDFACTOR_INV_DST_ALPHA)
+            sblend = I915_SRC_BLENDFACTOR_ZERO;
+    }
+
+    /* If the source alpha is being used, then we should only be in a case where
+     * the source blend factor is 0, and the source blend value is the mask
+     * channels multiplied by the source picture's alpha.
+     */
+    if (pMask && pMask->componentAlpha && I915BlendOp[op].src_alpha) {
+        if (dblend == I915_DST_BLENDFACTOR_SRC_ALPHA) {
+            dblend = I915_DST_BLENDFACTOR_SRC_COLOR;
+        } else if (dblend == I915_DST_BLENDFACTOR_INV_SRC_ALPHA) {
+            dblend = I915_DST_BLENDFACTOR_INV_SRC_COLOR;
+        }
+    }
+
+    return sblend | dblend;
+}
+
+static Bool I915GetDestFormat(PicturePtr pDstPicture, CARD32 *dst_format)
+{
+    switch (pDstPicture->format) {
+    case PICT_a8r8g8b8:
+    case PICT_x8r8g8b8:
+        *dst_format = COLR_BUF_ARGB8888;
+        break;
+    case PICT_r5g6b5:
+        *dst_format = COLR_BUF_RGB565;
+        break;
+    case PICT_a1r5g5b5:
+    case PICT_x1r5g5b5:
+        *dst_format = COLR_BUF_ARGB1555;
+        break;
+    case PICT_a8:
+        *dst_format = COLR_BUF_8BIT;
+        break;
+    case PICT_a4r4g4b4:
+    case PICT_x4r4g4b4:
+	*dst_format = COLR_BUF_ARGB4444;
+	break;
+    default:
+        I830FALLBACK("Unsupported dest format 0x%x\n",
+                        (int)pDstPicture->format);
+    }
+
+    return TRUE;
+}
+
+static Bool I915CheckCompositeTexture(PicturePtr pPict, int unit)
+{
+    int w = pPict->pDrawable->width;
+    int h = pPict->pDrawable->height;
+    int i;
+                                                                                                                                                            
+    if ((w > 0x7ff) || (h > 0x7ff))
+        I830FALLBACK("Picture w/h too large (%dx%d)\n", w, h);
+
+    for (i = 0; i < sizeof(I915TexFormats) / sizeof(I915TexFormats[0]); i++)
+    {
+        if (I915TexFormats[i].fmt == pPict->format)
+            break;
+    }
+    if (i == sizeof(I915TexFormats) / sizeof(I915TexFormats[0]))
+        I830FALLBACK("Unsupported picture format 0x%x\n",
+                         (int)pPict->format);
+
+    /* FIXME: fix repeat support */
+    if (pPict->repeat && ((w&(w-1)) != 0) && ((h&(h-1)) != 0))
+	I830FALLBACK("repeat non log2 aligned!\n");
+
+    if (pPict->filter != PictFilterNearest &&
+        pPict->filter != PictFilterBilinear)
+        I830FALLBACK("Unsupported filter 0x%x\n", pPict->filter);
+
+    return TRUE;
+}
+
+Bool
+I915EXACheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
+		      PicturePtr pDstPicture)
+{
+    CARD32 tmp1;
+    
+    /* Check for unsupported compositing operations. */
+    if (op >= sizeof(I915BlendOp) / sizeof(I915BlendOp[0]))
+        I830FALLBACK("Unsupported Composite op 0x%x\n", op);
+                                                                                                                                                            
+    if (pMaskPicture != NULL && pMaskPicture->componentAlpha) {
+        /* Check if it's component alpha that relies on a source alpha and on
+         * the source value.  We can only get one of those into the single
+         * source value that we get to blend with.
+         */
+        if (I915BlendOp[op].src_alpha &&
+            (I915BlendOp[op].blend_cntl & I915_SRC_BLENDFACTOR_MASK) !=
+             I915_SRC_BLENDFACTOR_ZERO)
+            	I830FALLBACK("Component alpha not supported with source "
+                            "alpha and source value blending.\n");
+    }
+
+    if (!I915CheckCompositeTexture(pSrcPicture, 0))
+        I830FALLBACK("Check Src picture texture\n");
+    if (pMaskPicture != NULL && !I915CheckCompositeTexture(pMaskPicture, 1))
+        I830FALLBACK("Check Mask picture texture\n");
+
+    if (!I915GetDestFormat(pDstPicture, &tmp1)) 
+	I830FALLBACK("Get Color buffer format\n");
+
+    return TRUE;
+}
+
+static Bool
+I915TextureSetup(PicturePtr pPict, PixmapPtr pPix, int unit)
+{
+    ScrnInfoPtr pScrn = xf86Screens[pPict->pDrawable->pScreen->myNum];
+    I830Ptr pI830 = I830PTR(pScrn);
+    CARD32 format, offset, pitch, filter;
+    int w, h, i;
+    CARD32 wrap_mode = TEXCOORDMODE_CLAMP_EDGE; 
+
+    offset = exaGetPixmapOffset(pPix);
+    pitch = exaGetPixmapPitch(pPix);
+    w = pPict->pDrawable->width;
+    h = pPict->pDrawable->height;
+    scale_units[unit][0] = pPix->drawable.width;
+    scale_units[unit][1] = pPix->drawable.height;
+    draw_coords[unit][0] = pPix->drawable.x;
+    draw_coords[unit][1] = pPix->drawable.y;
+
+    for (i = 0; i < sizeof(I915TexFormats) / sizeof(I915TexFormats[0]); i++) {
+        if (I915TexFormats[i].fmt == pPict->format)
+	    break;
+    }
+    if ( i == sizeof(I915TexFormats)/ sizeof(I915TexFormats[0]) )
+	I830FALLBACK("unknown texture format\n");
+    format = I915TexFormats[i].card_fmt;
+
+    if (pPict->repeat) 
+	wrap_mode = TEXCOORDMODE_WRAP; /* XXX:correct ? */
+    
+    switch (pPict->filter) {
+    case PictFilterNearest:
+        filter = (FILTER_NEAREST << SS2_MAG_FILTER_SHIFT) | 
+			(FILTER_NEAREST << SS2_MIN_FILTER_SHIFT);
+        break;
+    case PictFilterBilinear:
+        filter = (FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) | 
+			(FILTER_LINEAR << SS2_MIN_FILTER_SHIFT);
+        break;
+    default:
+	filter = 0;
+        I830FALLBACK("Bad filter 0x%x\n", pPict->filter);
+    }
+
+    {
+	CARD32 ms3;
+	if (pI830->cpp == 1)
+		format |= MAPSURF_8BIT;
+	else if (pI830->cpp == 2)
+		format |= MAPSURF_16BIT;
+	else
+		format |= MAPSURF_32BIT;
+
+	BEGIN_LP_RING(6);
+	OUT_RING(_3DSTATE_MAP_STATE | (3 * (1 << unit)));
+	OUT_RING(1<<unit);
+	OUT_RING(offset&MS2_ADDRESS_MASK);
+	ms3 = (pPix->drawable.height << MS3_HEIGHT_SHIFT) | 
+		(pPix->drawable.width << MS3_WIDTH_SHIFT) | format;
+	if (!pI830->disableTiling)
+		ms3 |= MS3_USE_FENCE_REGS;
+	OUT_RING(ms3); 
+	OUT_RING(pitch<<MS4_PITCH_SHIFT);
+	OUT_RING(0);
+	ADVANCE_LP_RING();
+     }
+
+     {
+	CARD32 ss2, ss3;
+	BEGIN_LP_RING(6);
+	/* max & min mip level ? or base mip level? */
+
+	OUT_RING(_3DSTATE_SAMPLER_STATE | (3*(1<<unit)));
+	OUT_RING(1<<unit);
+	ss2 = (MIPFILTER_NONE << SS2_MIP_FILTER_SHIFT);
+	ss2 |= filter;
+	OUT_RING(ss2);
+	/* repeat? */
+	ss3 = TEXCOORDMODE_WRAP << SS3_TCX_ADDR_MODE_SHIFT;
+	ss3 |= (TEXCOORDMODE_WRAP << SS3_TCY_ADDR_MODE_SHIFT);
+	ss3 |= SS3_NORMALIZED_COORDS;
+	ss3 |= (unit << SS3_TEXTUREMAP_INDEX_SHIFT);
+	OUT_RING(ss3);
+	OUT_RING(0x00000000); /* default color */
+	OUT_RING(0);
+
+	ADVANCE_LP_RING();
+    }
+
+    if (pPict->transform != 0) {
+        is_transform[unit] = TRUE;
+        transform[unit] = pPict->transform;
+    } else {
+        is_transform[unit] = FALSE;
+    }
+
+#ifdef I830DEBUG
+    ErrorF("try to sync to show any errors...");
+    I830Sync(pScrn);
+#endif
+	
+    return TRUE;
+}
+
+static void
+I915DefCtxSetup(ScrnInfoPtr pScrn)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+
+    BEGIN_LP_RING(2);
+    /* set default texture binding, may be in prepare better */
+    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(0);
+    ADVANCE_LP_RING();
+}
+
+Bool
+I915EXAPrepareComposite(int op, PicturePtr pSrcPicture,
+			PicturePtr pMaskPicture, PicturePtr pDstPicture,
+			PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst)
+{
+    ScrnInfoPtr pScrn = xf86Screens[pSrcPicture->pDrawable->pScreen->myNum];
+    I830Ptr pI830 = I830PTR(pScrn);
+    CARD32 dst_format, dst_offset, dst_pitch;
+    CARD32 blendctl;
+
+ErrorF("i915 prepareComposite\n");
+
+    I915GetDestFormat(pDstPicture, &dst_format);
+    dst_offset = exaGetPixmapOffset(pDst);
+    dst_pitch = exaGetPixmapPitch(pDst);
+    draw_coords[2][0] = pDst->drawable.x;
+    draw_coords[2][1] = pDst->drawable.y;
+    
+    I915DefCtxSetup(pScrn);
+
+    if (!I915TextureSetup(pSrcPicture, pSrc, 0))
+	I830FALLBACK("fail to setup src texture\n");
+    if (pMask != NULL) {
+	if (!I915TextureSetup(pMaskPicture, pMask, 1))
+		I830FALLBACK("fail to setup mask texture\n");
+    } else {
+	is_transform[1] = FALSE;
+	scale_units[1][0] = -1;
+	scale_units[1][1] = -1;
+    }
+
+    {
+	CARD32 ss2;
+	BEGIN_LP_RING(24);
+	/*color buffer*/
+	OUT_RING(_3DSTATE_BUF_INFO_CMD);
+	OUT_RING(BUF_3D_ID_COLOR_BACK| BUF_3D_PITCH(dst_pitch)); /* fence, tile? */
+	OUT_RING(BUF_3D_ADDR(dst_offset));
+	OUT_RING(MI_NOOP);
+	
+	OUT_RING(_3DSTATE_DST_BUF_VARS_CMD);
+	OUT_RING(dst_format);
+
+	/* XXX: defaults */
+	OUT_RING(_3DSTATE_DFLT_Z_CMD);
+	OUT_RING(0);
+
+	OUT_RING(_3DSTATE_DFLT_DIFFUSE_CMD);
+	OUT_RING(0);
+
+	OUT_RING(_3DSTATE_DFLT_SPEC_CMD);
+	OUT_RING(0);
+	
+	/* XXX:S3? define vertex format with tex coord sets number*/
+	OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1|I1_LOAD_S(2)|I1_LOAD_S(3)|
+		I1_LOAD_S(4)|1);
+	ss2 = S2_TEXCOORD_FMT(0, TEXCOORDFMT_2D);
+	if (pMask)
+		ss2 |= S2_TEXCOORD_FMT(1, TEXCOORDFMT_2D);
+	else
+		ss2 |= S2_TEXCOORD_FMT(1, TEXCOORDFMT_NOT_PRESENT);
+	ss2 |= S2_TEXCOORD_FMT(2, TEXCOORDFMT_NOT_PRESENT);
+	ss2 |= S2_TEXCOORD_FMT(3, TEXCOORDFMT_NOT_PRESENT);
+	ss2 |= S2_TEXCOORD_FMT(4, TEXCOORDFMT_NOT_PRESENT);
+	ss2 |= S2_TEXCOORD_FMT(5, TEXCOORDFMT_NOT_PRESENT);
+	ss2 |= S2_TEXCOORD_FMT(6, TEXCOORDFMT_NOT_PRESENT);
+	ss2 |= S2_TEXCOORD_FMT(7, TEXCOORDFMT_NOT_PRESENT);
+	OUT_RING(ss2);
+	OUT_RING(0x00000000); /*XXX: does ss3 needed? */
+	OUT_RING((1<<S4_POINT_WIDTH_SHIFT)|S4_LINE_WIDTH_ONE| 
+		S4_CULLMODE_NONE| S4_VFMT_XY);  
+
+	/* issue a flush */
+	OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE);
+	OUT_RING(0);
+
+	/* draw rect is unconditional */
+	OUT_RING(_3DSTATE_DRAW_RECT_CMD);
+	OUT_RING(0x00000000);
+	OUT_RING(0x00000000);  /* ymin, xmin*/
+	OUT_RING(DRAW_YMAX(pScrn->virtualY-1) | DRAW_XMAX(pScrn->virtualX-1));
+	OUT_RING(0x00000000);  /* yorig, xorig (relate to color buffer?)*/
+	OUT_RING(0);
+	ADVANCE_LP_RING();
+    }
+
+	/* For (src In mask) operation */
+	/* IN operator: Multiply src by mask components or mask alpha.*/
+	/* TEXBLENDOP_MODULE: arg1*arg2 */
+
+	/* LOAD_IMMEDIATE_1 ss6 ??*/
+
+	/****
+	   shader program prototype:
+		dcl t0.xy
+		dcl t1.xy
+		dcl_2d s0   
+		dcl_2d s1
+		texld t0, s0
+		texld t1, s1
+		mul oC, t0, t1 ()
+	***/
+    if (!pMask) {
+	BEGIN_LP_RING(1+3+3+3);
+	OUT_RING(_3DSTATE_PIXEL_SHADER_PROGRAM |(3*3-1));
+	OUT_DCL(S, 0);
+	OUT_DCL(T, 0);
+	OUT_TEXLD(OC, 0, 0, T, 0);
+	ADVANCE_LP_RING();
+    } else {
+	BEGIN_LP_RING(1+3*6+3);
+	OUT_RING(_3DSTATE_PIXEL_SHADER_PROGRAM |(3*7-1));
+	OUT_DCL(S, 0);
+	OUT_DCL(S, 1);
+	OUT_DCL(T, 0);
+	OUT_DCL(T, 1);
+	OUT_TEXLD(R, 0, 0, T, 0);
+	OUT_TEXLD(R, 1, 1, T, 1);
+	if (pMaskPicture->componentAlpha && pDstPicture->format != PICT_a8) {
+		/* then just mul */
+		OUT_RING(A0_MUL | (REG_TYPE_OC << A0_DEST_TYPE_SHIFT) | 
+			(0 << A0_DEST_NR_SHIFT) | A0_DEST_CHANNEL_ALL | 
+			(REG_TYPE_R << A0_SRC0_TYPE_SHIFT) | (0 << A0_SRC0_NR_SHIFT));
+		OUT_RING((SRC_X << A1_SRC0_CHANNEL_X_SHIFT)|(SRC_Y << A1_SRC0_CHANNEL_Y_SHIFT)|
+			(SRC_Z << A1_SRC0_CHANNEL_Z_SHIFT)|(SRC_W << A1_SRC0_CHANNEL_W_SHIFT)|
+			(REG_TYPE_R << A1_SRC1_TYPE_SHIFT) | (1 << A1_SRC1_NR_SHIFT) |
+			(SRC_X << A1_SRC1_CHANNEL_X_SHIFT) | (SRC_Y << A1_SRC1_CHANNEL_Y_SHIFT));
+		OUT_RING((SRC_Z << A2_SRC1_CHANNEL_Z_SHIFT) | (SRC_W << A2_SRC1_CHANNEL_W_SHIFT));
+	} else {
+		/* we should duplicate R1's w for all channel, Arithemic can choose channel to use! */
+		OUT_RING(A0_MUL | (REG_TYPE_OC << A0_DEST_TYPE_SHIFT) |
+			(0 << A0_DEST_NR_SHIFT) | A0_DEST_CHANNEL_ALL |
+			(REG_TYPE_R << A0_SRC0_TYPE_SHIFT) | (0 << A0_SRC0_NR_SHIFT));
+		OUT_RING((SRC_X << A1_SRC0_CHANNEL_X_SHIFT) | (SRC_Y << A1_SRC0_CHANNEL_Y_SHIFT) |
+			(SRC_Z << A1_SRC0_CHANNEL_Z_SHIFT) | (SRC_W << A1_SRC0_CHANNEL_W_SHIFT) |
+			(REG_TYPE_R << A1_SRC1_TYPE_SHIFT) | (1 << A1_SRC1_NR_SHIFT) |
+			(SRC_W << A1_SRC1_CHANNEL_X_SHIFT) | (SRC_W << A1_SRC1_CHANNEL_Y_SHIFT));
+		OUT_RING((SRC_W << A2_SRC1_CHANNEL_Z_SHIFT) | (SRC_W << A2_SRC1_CHANNEL_W_SHIFT));
+	}
+	ADVANCE_LP_RING();
+    }
+		
+    {
+	CARD32 ss6;
+	blendctl = I915GetBlendCntl(op, pMaskPicture, pDstPicture->format);
+
+	BEGIN_LP_RING(2);
+	OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(6) | 0);
+	ss6 = S6_CBUF_BLEND_ENABLE | S6_COLOR_WRITE_ENABLE;
+	OUT_RING(ss6 | (0 << S6_CBUF_BLEND_FUNC_SHIFT) | blendctl);
+	ADVANCE_LP_RING();
+    }
+
+#ifdef I830DEBUG
+    ErrorF("try to sync to show any errors...");
+    I830Sync(pScrn);
+#endif
+
+    return TRUE;
+}
diff --git a/src/i915_reg.h b/src/i915_reg.h
index 886ae81..e2d7b9d 100644
--- a/src/i915_reg.h
+++ b/src/i915_reg.h
@@ -161,6 +161,9 @@
 #define COLR_BUF_RGB555 		(1<<8)
 #define COLR_BUF_RGB565 		(2<<8)
 #define COLR_BUF_ARGB8888		(3<<8)
+#define COLR_BUF_ARGB4444		(8<<8)
+#define COLR_BUF_ARGB1555		(9<<8)
+#define COLR_BUF_ARGB2AAA		(0xa<<8)
 #define DEPTH_FRMT_16_FIXED		0
 #define DEPTH_FRMT_16_FLOAT		(1<<2)
 #define DEPTH_FRMT_24_FIXED_8_OTHER	(2<<2)
diff-tree b85f268051a785f90e4c55bd1cac80d673388f16 (from 6a3f89f4b6035534c7b93a4c05fd704305349785)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Mon Jun 26 16:26:58 2006 +0200

    Fix remaining warning.

diff --git a/src/i830_memory.c b/src/i830_memory.c
index 50bbde5..c1c7cb7 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -874,7 +874,7 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, 
 	 return FALSE;
       } else {
 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Successful allocate "
-		       "offscreen memory at 0x%lx, size %d KB\n", 
+		       "offscreen memory at 0x%lx, size %ld KB\n", 
 			pI830->Offscreen.Start, pI830->Offscreen.Size/1024);
       }
 #endif
diff-tree 6a3f89f4b6035534c7b93a4c05fd704305349785 (from parents)
Merge: 3cdc53797bf6fdbfbcb53e07b269a5071f5ec97d e7723a4e5725147d3bd9ba22c5a3314b0556e440
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Mon Jun 26 16:25:58 2006 +0200

    Merge branch 'master' into exa
    
    Conflicts:
    
    	src/i830.h

diff --cc src/i830.h
index ff82c73,79eb310..d0f8bc0
@@@ -491,8 -474,16 +494,19 @@@
  extern Bool I830Rotate(ScrnInfoPtr pScrn, DisplayModePtr mode);
  extern Bool I830FixOffset(ScrnInfoPtr pScrn, I830MemRange *mem);
  
 +extern void i830MarkSync(ScrnInfoPtr pScrn);
 +extern void i830WaitSync(ScrnInfoPtr pScrn);
++
+ /* i830_memory.c */
+ Bool I830BindAGPMemory(ScrnInfoPtr pScrn);
+ Bool I830UnbindAGPMemory(ScrnInfoPtr pScrn);
+ 
+ /* i830_randr.c */
+ Bool I830RandRInit(ScreenPtr pScreen, int rotation);
+ Bool I830RandRSetConfig(ScreenPtr pScreen, Rotation rotation, int rate,
+ 			RRScreenSizePtr pSize);
+ Rotation I830GetRotation(ScreenPtr pScreen);
+ 
  /*
   * 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 --cc src/i830_dri.c
index d73c84a,7c5f795..5653434
@@@ -1176,38 -1180,10 +1178,9 @@@
        DEALLOCATE_LOCAL(pptNew1);
        DEALLOCATE_LOCAL(pboxNew1);
     }
 -
 -   pI830->AccelInfoRec->NeedToSync = TRUE;
 +   i830MarkSync(pScrn);
  }
  
- 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-tree 3cdc53797bf6fdbfbcb53e07b269a5071f5ec97d (from d7e5d996aa123e52857362fa8a1e69f709bfe218)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Mon Jun 26 16:23:55 2006 +0200

    Fix build with new EXA headers.

diff --git a/src/i830_exa.c b/src/i830_exa.c
index 7212972..665c4d7 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -149,7 +149,7 @@ I830EXAPrepareSolid(PixmapPtr pPixmap, i
     I830Ptr pI830 = I830PTR(pScrn);
     unsigned long offset, pitch;
 
-    if (planemask != (Pixel)~0 && !EXA_PM_IS_SOLID(pPixmap, planemask))
+    if (!EXA_PM_IS_SOLID(&pPixmap->drawable, planemask))
 	I830FALLBACK("planemask is not solid");
 
     offset = exaGetPixmapOffset(pPixmap);
@@ -234,7 +234,7 @@ I830EXAPrepareCopy(PixmapPtr pSrcPixmap,
     ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
     I830Ptr pI830 = I830PTR(pScrn);
 
-    if (planemask != (Pixel)~0 && !EXA_PM_IS_SOLID(pSrcPixmap, planemask))
+    if (!EXA_PM_IS_SOLID(&pSrcPixmap->drawable, planemask))
 	I830FALLBACK("planemask is not solid");
 
     pI830->copy_src_pitch = exaGetPixmapPitch(pSrcPixmap);
diff-tree d7e5d996aa123e52857362fa8a1e69f709bfe218 (from parents)
Merge: 89a5a0024a7e077a0726ffe1427e573df3bcbef5 a73ab7f0e6e3b0462e05c0031ffd602ed3e2bcd4
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Tue Jun 20 01:22:53 2006 +0800

    Merge branch 'master' into exa

diff --cc src/Makefile.am
index 83025fa,2745e8c..c9e8780
@@@ -55,8 -55,10 +55,12 @@@
           i830_video.c \
           i830_rotate.c \
  	 i830_randr.c \
+ 	 i830_3d.c \
+ 	 i830_reg.h \
+ 	 i915_3d.c \
 -	 i915_reg.h
++	 i915_reg.h \
 +	 i830_exa.c \
 +	 i830_xaa.c
  
  if DRI
  i810_drv_la_SOURCES += \
diff --cc src/i830_dri.c
index 76298a3,ed5e685..d73c84a
@@@ -1176,12 -1178,16 +1176,15 @@@
        DEALLOCATE_LOCAL(pptNew1);
        DEALLOCATE_LOCAL(pboxNew1);
     }
 -
 -   pI830->AccelInfoRec->NeedToSync = TRUE;
 +   i830MarkSync(pScrn);
  }
  
+ 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;
diff-tree 89a5a0024a7e077a0726ffe1427e573df3bcbef5 (from f2ab3aa3199e1c4b0edec72b5acea6d725cc514a)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Sun Jun 18 00:25:34 2006 -0700

    Fix crash with EXA during randr, when XAA structures were being accessed.  EXA
    shouldn't have any issues with there also being pixmaps in framebuffer while
    rotation is active.

diff --git a/src/i830_rotate.c b/src/i830_rotate.c
index e4a8064..ad4c484 100644
--- a/src/i830_rotate.c
+++ b/src/i830_rotate.c
@@ -959,21 +959,26 @@ I830Rotate(ScrnInfoPtr pScrn, DisplayMod
       }
    }
 
-   /* Don't allow pixmap cache or offscreen pixmaps when rotated */
-   /* XAA needs some serious fixing for this to happen */
-   if (pI830->rotation == RR_Rotate_0) {
-      pI830->AccelInfoRec->Flags = LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS | PIXMAP_CACHE;
-      pI830->AccelInfoRec->UsingPixmapCache = TRUE;
-      /* funny as it seems this will enable XAA's createpixmap */
-      pI830->AccelInfoRec->maxOffPixWidth = 0;
-      pI830->AccelInfoRec->maxOffPixHeight = 0;
-   } else {
-      pI830->AccelInfoRec->Flags = LINEAR_FRAMEBUFFER;
-      pI830->AccelInfoRec->UsingPixmapCache = FALSE;
-      /* funny as it seems this will disable XAA's createpixmap */
-      pI830->AccelInfoRec->maxOffPixWidth = 1;
-      pI830->AccelInfoRec->maxOffPixHeight = 1;
+#ifdef I830_USE_XAA
+   if (pI830->AccelInfoRec != NULL) {
+      /* Don't allow pixmap cache or offscreen pixmaps when rotated */
+      /* XAA needs some serious fixing for this to happen */
+      if (pI830->rotation == RR_Rotate_0) {
+	 pI830->AccelInfoRec->Flags = LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS |
+				      PIXMAP_CACHE;
+	 pI830->AccelInfoRec->UsingPixmapCache = TRUE;
+	 /* funny as it seems this will enable XAA's createpixmap */
+	 pI830->AccelInfoRec->maxOffPixWidth = 0;
+	 pI830->AccelInfoRec->maxOffPixHeight = 0;
+      } else {
+	 pI830->AccelInfoRec->Flags = LINEAR_FRAMEBUFFER;
+	 pI830->AccelInfoRec->UsingPixmapCache = FALSE;
+	 /* funny as it seems this will disable XAA's createpixmap */
+	 pI830->AccelInfoRec->maxOffPixWidth = 1;
+	 pI830->AccelInfoRec->maxOffPixHeight = 1;
+      }
    }
+#endif
 
    return TRUE;
 
diff-tree f2ab3aa3199e1c4b0edec72b5acea6d725cc514a (from bc42dbe07cbd61b357d8eed02608e026c4cf4485)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Sun Jun 18 00:32:01 2006 -0700

    Fix DRI in EXA mode: Don't attempt to use XAA symbols (use the driver's internal
    ones for EXA support when available).  Also, add an abstraction of XAA/EXA
    MarkSync and WaitSync functionality so we don't need to sprinkle the ifdefs all
    over, and correctly use them.

diff --git a/src/i830.h b/src/i830.h
index edc485b..9a8ecf8 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -491,6 +491,8 @@ extern Bool I830CheckModeSupport(ScrnInf
 extern Bool I830Rotate(ScrnInfoPtr pScrn, DisplayModePtr mode);
 extern Bool I830FixOffset(ScrnInfoPtr pScrn, I830MemRange *mem);
 
+extern void i830MarkSync(ScrnInfoPtr pScrn);
+extern void i830WaitSync(ScrnInfoPtr pScrn);
 /*
  * 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 a1a6488..f299398 100644
--- a/src/i830_accel.c
+++ b/src/i830_accel.c
@@ -208,10 +208,7 @@ I830RefreshRing(ScrnInfoPtr pScrn)
    pI830->LpRing->space = pI830->LpRing->head - (pI830->LpRing->tail + 8);
    if (pI830->LpRing->space < 0)
       pI830->LpRing->space += pI830->LpRing->mem.Size;
-#ifdef I830_USE_XAA
-   if (pI830->AccelInfoRec)
-      pI830->AccelInfoRec->NeedToSync = TRUE;
-#endif
+   i830MarkSync(pScrn);
 }
 
 /* The following function sets up the supported acceleration. Call it
diff --git a/src/i830_dri.c b/src/i830_dri.c
index c159686..76298a3 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -979,7 +979,6 @@ I830DRIInitBuffers(WindowPtr pWin, Regio
 {
    ScreenPtr pScreen = pWin->drawable.pScreen;
    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-   I830Ptr pI830 = I830PTR(pScrn);
    BoxPtr pbox = REGION_RECTS(prgn);
    int nbox = REGION_NUM_RECTS(prgn);
 
@@ -1017,9 +1016,7 @@ I830DRIInitBuffers(WindowPtr pWin, Regio
    }
 
    I830SelectBuffer(pScrn, I830_SELECT_FRONT);
-#ifdef I830_USE_XAA
-   pI830->AccelInfoRec->NeedToSync = TRUE;
-#endif
+   i830MarkSync(pScrn);
 }
 
 /* This routine is a modified form of XAADoBitBlt with the calls to
@@ -1033,7 +1030,6 @@ I830DRIMoveBuffers(WindowPtr pParent, DD
 {
    ScreenPtr pScreen = pParent->drawable.pScreen;
    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-   I830Ptr pI830 = I830PTR(pScrn);
    BoxPtr pboxTmp, pboxNext, pboxBase;
    DDXPointPtr pptTmp, pptNew2;
    int xdir, ydir;
@@ -1180,9 +1176,7 @@ I830DRIMoveBuffers(WindowPtr pParent, DD
       DEALLOCATE_LOCAL(pptNew1);
       DEALLOCATE_LOCAL(pboxNew1);
    }
-#ifdef I830_USE_XAA
-   pI830->AccelInfoRec->NeedToSync = TRUE;
-#endif
+   i830MarkSync(pScrn);
 }
 
 /* Initialize the first context */
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 5cfb6fc..fe61884 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -5258,18 +5258,8 @@ I830BIOSAdjustFrame(int scrnIndex, int x
 	   x, pI830->xoffset, y, pI830->yoffset);
 
    /* Sync the engine before adjust frame */
-#ifdef I830_USE_XAA
-   if (!pI830->noAccel && !pI830->useEXA && pI830->AccelInfoRec->NeedToSync) {
-      (*pI830->AccelInfoRec->Sync)(pScrn);
-      pI830->AccelInfoRec->NeedToSync = FALSE;
-   }
-#endif
-#ifdef I830_USE_EXA
-   if (!pI830->noAccel && pI830->useEXA) {
-	ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
-	exaWaitSync(pScreen);
-   }
-#endif
+   i830WaitSync(pScrn);
+
    if (I830IsPrimary(pScrn))
       Start = pI830->FrontBuffer.Start;
    else {
@@ -5398,16 +5388,11 @@ I830BIOSLeaveVT(int scrnIndex, int flags
    RestoreBIOSMemSize(pScrn);
    if (I830IsPrimary(pScrn))
       I830UnbindAGPMemory(pScrn);
+
 #ifdef I830_USE_XAA
    if (!pI830->useEXA && pI830->AccelInfoRec)
       pI830->AccelInfoRec->NeedToSync = FALSE;
 #endif
-#ifdef I830_USE_EXA
-   if (pI830->useEXA && pI830->EXADriverPtr) {
-      ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
-      exaMarkSync(pScreen);
-   }
-#endif
 
    /* DO IT AGAIN! AS IT SEEMS THAT SOME LFPs FLICKER OTHERWISE */
    if (I830IsPrimary(pScrn)) {
@@ -5741,18 +5726,7 @@ I830BIOSSwitchMode(int scrnIndex, Displa
 #endif
 
    /* Sync the engine before mode switch */
-#ifdef I830_USE_XAA
-   if (!pI830->noAccel && !pI830->useEXA) {
-      (*pI830->AccelInfoRec->Sync)(pScrn);
-      pI830->AccelInfoRec->NeedToSync = FALSE;
-   }
-#endif
-#ifdef I830_USE_EXA
-   if (!pI830->noAccel && pI830->useEXA) {
-      ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
-      exaWaitSync(pScreen);
-   }
-#endif
+   i830WaitSync(pScrn);
 
    /* Check if our currentmode is about to change. We do this so if we
     * are rotating, we don't need to call the mode setup again.
@@ -6122,14 +6096,8 @@ I830CheckDevicesTimer(OsTimerPtr timer, 
          xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
 		    "Hotkey switch to 0x%lx.\n", (unsigned long) temp);
 
-#ifdef I830_USE_XAA
-         if (!pI830->useEXA && pI830->AccelInfoRec && pI830->AccelInfoRec->NeedToSync) {
-            (*pI830->AccelInfoRec->Sync)(pScrn);
-            pI830->AccelInfoRec->NeedToSync = FALSE;
-            if (xf86IsEntityShared(pScrn->entityList[0]))
-               pI8302->AccelInfoRec->NeedToSync = FALSE;
-         }
-#endif
+	 i830WaitSync(pScrn);
+
          GetAttachableDisplayDeviceList(pScrn);
          
 	 pI8301->lastDevice0 = pI8301->lastDevice1;
@@ -6399,6 +6367,42 @@ I830CheckDevicesTimer(OsTimerPtr timer, 
 }
 
 void
+i830WaitSync(ScrnInfoPtr pScrn)
+{
+   I830Ptr pI830 = I830PTR(pScrn);
+
+#ifdef I830_USE_XAA
+   if (!pI830->noAccel && !pI830->useEXA && pI830->AccelInfoRec->NeedToSync) {
+      (*pI830->AccelInfoRec->Sync)(pScrn);
+      pI830->AccelInfoRec->NeedToSync = FALSE;
+   }
+#endif
+#ifdef I830_USE_EXA
+   if (!pI830->noAccel && pI830->useEXA && pI830->EXADriverPtr) {
+	ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
+	exaWaitSync(pScreen);
+   }
+#endif
+}
+
+void
+i830MarkSync(ScrnInfoPtr pScrn)
+{
+   I830Ptr pI830 = I830PTR(pScrn);
+
+#ifdef I830_USE_XAA
+   if (!pI830->useEXA && pI830->AccelInfoRec)
+      pI830->AccelInfoRec->NeedToSync = FALSE;
+#endif
+#ifdef I830_USE_EXA
+   if (pI830->useEXA && pI830->EXADriverPtr) {
+      ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
+      exaMarkSync(pScreen);
+   }
+#endif
+}
+
+void
 I830InitpScrn(ScrnInfoPtr pScrn)
 {
    pScrn->PreInit = I830BIOSPreInit;
diff --git a/src/i830_exa.c b/src/i830_exa.c
index b22430a..7212972 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -51,7 +51,7 @@ do {							\
 #define I830FALLBACK(s, arg...) { return FALSE; }
 #endif
 
-int I830CopyROP[16] =
+const int I830CopyROP[16] =
 {
    ROP_0,               /* GXclear */
    ROP_DSa,             /* GXand */
@@ -71,7 +71,7 @@ int I830CopyROP[16] =
    ROP_1                /* GXset */
 };
 
-static int I830PatternROP[16] =
+const int I830PatternROP[16] =
 {
     ROP_0,
     ROP_DPa,
diff --git a/src/i830_xaa.c b/src/i830_xaa.c
index 68ba4c7..9f3a391 100644
--- a/src/i830_xaa.c
+++ b/src/i830_xaa.c
@@ -92,6 +92,11 @@ static void I830SubsequentImageWriteScan
 #endif
 static void I830RestoreAccelState(ScrnInfoPtr pScrn);
 
+#ifdef I830_USE_EXA
+extern const int I830PatternROP[16];
+extern const int I830CopyROP[16];
+#endif
+
 Bool
 I830XAAInit(ScreenPtr pScreen)
 {
@@ -235,8 +240,17 @@ I830SetupForSolidFill(ScrnInfoPtr pScrn,
 	ErrorF("I830SetupForFillRectSolid color: %x rop: %x mask: %x\n",
 	       color, rop, planemask);
 
+#ifdef I830_USE_EXA
+    /* This function gets used by I830DRIInitBuffers(), and we might not have
+     * XAAGetPatternROP() available.  So just use the ROPs from our EXA code
+     * if available.
+     */
+    pI830->BR[13] = ((I830PatternROP[rop] << 16) |
+		     (pScrn->displayWidth * pI830->cpp));
+#else
     pI830->BR[13] = ((XAAGetPatternROP(rop) << 16) |
 		     (pScrn->displayWidth * pI830->cpp));
+#endif
 
     pI830->BR[16] = color;
 
@@ -291,7 +305,15 @@ I830SetupForScreenToScreenCopy(ScrnInfoP
 	       xdir, ydir, rop, planemask, transparency_color);
 
     pI830->BR[13] = (pScrn->displayWidth * pI830->cpp);
+#ifdef I830_USE_EXA
+    /* This function gets used by I830DRIInitBuffers(), and we might not have
+     * XAAGetCopyROP() available.  So just use the ROPs from our EXA code
+     * if available.
+     */
+    pI830->BR[13] |= I830CopyROP[rop] << 16;
+#else
     pI830->BR[13] |= XAAGetCopyROP(rop) << 16;
+#endif
 
     switch (pScrn->bitsPerPixel) {
     case 8:
diff-tree bc42dbe07cbd61b357d8eed02608e026c4cf4485 (from e70d99d51edc39ea53536c2f4d62ac622ba3e0d9)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Mon May 22 11:22:03 2006 +0800

    fix a typo

diff --git a/src/i830_exa.c b/src/i830_exa.c
index a67e549..b22430a 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -234,7 +234,7 @@ I830EXAPrepareCopy(PixmapPtr pSrcPixmap,
     ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
     I830Ptr pI830 = I830PTR(pScrn);
 
-    if (planemask != (Pixel)~0 && !EXA_PM_IS_SOLID(pScrPixmap, planemask))
+    if (planemask != (Pixel)~0 && !EXA_PM_IS_SOLID(pSrcPixmap, planemask))
 	I830FALLBACK("planemask is not solid");
 
     pI830->copy_src_pitch = exaGetPixmapPitch(pSrcPixmap);
diff-tree e70d99d51edc39ea53536c2f4d62ac622ba3e0d9 (from b3d79ad9ecc70e9f841092fc75b7e23576b685dd)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Fri May 19 15:47:19 2006 +0800

    revert wrong setting for memorySize, which should
    be at the range of pI830->Offscreen.

diff --git a/src/i830_exa.c b/src/i830_exa.c
index a37be39..a67e549 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -394,7 +394,7 @@ I830EXAInit(ScreenPtr pScreen)
     pI830->EXADriverPtr->exa_minor = 0;
     pI830->EXADriverPtr->memoryBase = pI830->FbBase;
     pI830->EXADriverPtr->offScreenBase = pI830->Offscreen.Start;
-    pI830->EXADriverPtr->memorySize = pScrn->videoRam*1024;
+    pI830->EXADriverPtr->memorySize = pI830->Offscreen.End;
 	   
     if(pI830->EXADriverPtr->memorySize >
        pI830->EXADriverPtr->offScreenBase)
diff-tree b3d79ad9ecc70e9f841092fc75b7e23576b685dd (from 33ad959323f70f76c494c66ec35a04d7d839f612)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Thu May 18 16:31:40 2006 +0800

    oop I830FALLBACK define error

diff --git a/src/i830_exa.c b/src/i830_exa.c
index 5d95ea7..a37be39 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -48,7 +48,7 @@ do {							\
 	return FALSE;					\
 } while(0)
 #else
-#define I830FALLBACK(x) { return FALSE; }
+#define I830FALLBACK(s, arg...) { return FALSE; }
 #endif
 
 int I830CopyROP[16] =
diff-tree 33ad959323f70f76c494c66ec35a04d7d839f612 (from 52af679c94a25c0c6e5df5f3647f62fdd256c826)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Thu May 18 11:32:59 2006 +0800

    Add DEBUG_I830FALLBACK for easier tracking

diff --git a/src/i830_exa.c b/src/i830_exa.c
index b250fb2..5d95ea7 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -37,6 +37,20 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #include "i830.h"
 #include "i810_reg.h"
 
+#ifdef I830DEBUG
+#define DEBUG_I830FALLBACK 0
+#endif
+
+#ifdef DEBUG_I830FALLBACK
+#define I830FALLBACK(s, arg...)				\
+do {							\
+	DPRINTF(PFX, "EXA fallback: " s "\n", ##arg); 	\
+	return FALSE;					\
+} while(0)
+#else
+#define I830FALLBACK(x) { return FALSE; }
+#endif
+
 int I830CopyROP[16] =
 {
    ROP_0,               /* GXclear */
@@ -136,15 +150,15 @@ I830EXAPrepareSolid(PixmapPtr pPixmap, i
     unsigned long offset, pitch;
 
     if (planemask != (Pixel)~0 && !EXA_PM_IS_SOLID(pPixmap, planemask))
-	return FALSE;
+	I830FALLBACK("planemask is not solid");
 
     offset = exaGetPixmapOffset(pPixmap);
     pitch = exaGetPixmapPitch(pPixmap);
 
     if ( offset % pI830->EXADriverPtr->pixmapOffsetAlign != 0)
-	return FALSE;
+	I830FALLBACK("pixmap offset not aligned");
     if ( pitch % pI830->EXADriverPtr->pixmapPitchAlign != 0)
-	return FALSE;
+	I830FALLBACK("pixmap pitch not aligned");
 
     pI830->BR[13] = pitch;
     pI830->BR[13] |= I830PatternROP[alu] << 16;
@@ -221,7 +235,7 @@ I830EXAPrepareCopy(PixmapPtr pSrcPixmap,
     I830Ptr pI830 = I830PTR(pScrn);
 
     if (planemask != (Pixel)~0 && !EXA_PM_IS_SOLID(pScrPixmap, planemask))
-	return FALSE;
+	I830FALLBACK("planemask is not solid");
 
     pI830->copy_src_pitch = exaGetPixmapPitch(pSrcPixmap);
     pI830->copy_src_off = exaGetPixmapOffset(pSrcPixmap);
diff-tree 52af679c94a25c0c6e5df5f3647f62fdd256c826 (from fdb52a8c6da0f3d3f4cfbf1583b2dc4d91f7e933)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Thu May 18 11:31:14 2006 +0800

    Check alignment require in PrepareSolid, noticed by Eric,
    as pixmap offset align set is violated in Solid.

diff --git a/src/i830_exa.c b/src/i830_exa.c
index 6726a0e..b250fb2 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -133,11 +133,20 @@ I830EXAPrepareSolid(PixmapPtr pPixmap, i
 {
     ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
     I830Ptr pI830 = I830PTR(pScrn);
+    unsigned long offset, pitch;
 
     if (planemask != (Pixel)~0 && !EXA_PM_IS_SOLID(pPixmap, planemask))
 	return FALSE;
 
-    pI830->BR[13] = exaGetPixmapPitch(pPixmap);
+    offset = exaGetPixmapOffset(pPixmap);
+    pitch = exaGetPixmapPitch(pPixmap);
+
+    if ( offset % pI830->EXADriverPtr->pixmapOffsetAlign != 0)
+	return FALSE;
+    if ( pitch % pI830->EXADriverPtr->pixmapPitchAlign != 0)
+	return FALSE;
+
+    pI830->BR[13] = pitch;
     pI830->BR[13] |= I830PatternROP[alu] << 16;
 
     pI830->BR[16] = fg;
@@ -165,8 +174,10 @@ I830EXASolid(PixmapPtr pPixmap, int x1, 
     ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
     I830Ptr pI830 = I830PTR(pScrn);
     int h, w;
-    unsigned int offset;
+    unsigned long offset;
 
+    /* pixmap's offset and pitch is aligned, 
+       otherwise it falls back in PrepareSolid */
     offset = exaGetPixmapOffset(pPixmap) + y1 * exaGetPixmapPitch(pPixmap) +
 	x1 * (pPixmap->drawable.bitsPerPixel / 8);
     
diff-tree fdb52a8c6da0f3d3f4cfbf1583b2dc4d91f7e933 (from 011a1c99d49c1c69b5fa81ade6a2ed73e84276ae)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Thu May 18 11:24:46 2006 +0800

    Solid planemask in PrepareSolid/Copy might be 0xffffffff
    or bits up to the depth. This should save some fallback
    case, noticed by Eric.

diff --git a/src/i830_exa.c b/src/i830_exa.c
index 6acc00c..6726a0e 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -134,7 +134,7 @@ I830EXAPrepareSolid(PixmapPtr pPixmap, i
     ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
     I830Ptr pI830 = I830PTR(pScrn);
 
-    if (planemask != (Pixel)~0)
+    if (planemask != (Pixel)~0 && !EXA_PM_IS_SOLID(pPixmap, planemask))
 	return FALSE;
 
     pI830->BR[13] = exaGetPixmapPitch(pPixmap);
@@ -209,7 +209,7 @@ I830EXAPrepareCopy(PixmapPtr pSrcPixmap,
     ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
     I830Ptr pI830 = I830PTR(pScrn);
 
-    if (planemask != (Pixel)~0)
+    if (planemask != (Pixel)~0 && !EXA_PM_IS_SOLID(pScrPixmap, planemask))
 	return FALSE;
 
     pI830->copy_src_pitch = exaGetPixmapPitch(pSrcPixmap);
diff-tree 011a1c99d49c1c69b5fa81ade6a2ed73e84276ae (from fcec956807038a2e90287850df8b4410b1f8b3c2)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Wed May 17 11:16:00 2006 +0800

    Fix memorySize to enable offscreen mem manage.

diff --git a/src/i830_exa.c b/src/i830_exa.c
index 59c2d51..6acc00c 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -369,7 +369,7 @@ I830EXAInit(ScreenPtr pScreen)
     pI830->EXADriverPtr->exa_minor = 0;
     pI830->EXADriverPtr->memoryBase = pI830->FbBase;
     pI830->EXADriverPtr->offScreenBase = pI830->Offscreen.Start;
-    pI830->EXADriverPtr->memorySize = pI830->Offscreen.Size;
+    pI830->EXADriverPtr->memorySize = pScrn->videoRam*1024;
 	   
     if(pI830->EXADriverPtr->memorySize >
        pI830->EXADriverPtr->offScreenBase)
diff --git a/src/i830_memory.c b/src/i830_memory.c
index 5fbc8cf..50bbde5 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -872,6 +872,10 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, 
 		       "offscreen memory.  Not enough VRAM?\n");
 	 }
 	 return FALSE;
+      } else {
+	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Successful allocate "
+		       "offscreen memory at 0x%lx, size %d KB\n", 
+			pI830->Offscreen.Start, pI830->Offscreen.Size/1024);
       }
 #endif
    } else {
diff-tree fcec956807038a2e90287850df8b4410b1f8b3c2 (from 0be9bc604420e4433697cc31e8ac58c9f36185e1)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Sat Apr 29 10:55:25 2006 +0800

    Save initialize EXADriverPtr, and free it in failure.

diff --git a/src/i830_exa.c b/src/i830_exa.c
index 6db94d9..59c2d51 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -362,7 +362,8 @@ I830EXAInit(ScreenPtr pScreen)
 	pI830->noAccel = TRUE;
 	return FALSE;
     }
-
+    memset(pI830->EXADriverPtr, 0, sizeof(*pI830->EXADriverPtr));
+    
     pI830->bufferOffset = 0;
     pI830->EXADriverPtr->exa_major = 2;
     pI830->EXADriverPtr->exa_minor = 0;
@@ -409,6 +410,7 @@ I830EXAInit(ScreenPtr pScreen)
 #endif
 
     if(!exaDriverInit(pScreen, pI830->EXADriverPtr)) {
+	xfree(pI830->EXADriverPtr);
 	pI830->noAccel = TRUE;
 	return FALSE;
     }
diff-tree 0be9bc604420e4433697cc31e8ac58c9f36185e1 (from a00a3d198aee7c173c2c36858f4447e13c86eb7f)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Sat Apr 29 10:54:02 2006 +0800

    I830CheckDevicesTimer() sync should be in I830_USE_XAA case.

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 50f2059..5cfb6fc 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -6122,13 +6122,14 @@ I830CheckDevicesTimer(OsTimerPtr timer, 
          xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
 		    "Hotkey switch to 0x%lx.\n", (unsigned long) temp);
 
-         if (pI830->AccelInfoRec && pI830->AccelInfoRec->NeedToSync) {
+#ifdef I830_USE_XAA
+         if (!pI830->useEXA && pI830->AccelInfoRec && pI830->AccelInfoRec->NeedToSync) {
             (*pI830->AccelInfoRec->Sync)(pScrn);
             pI830->AccelInfoRec->NeedToSync = FALSE;
             if (xf86IsEntityShared(pScrn->entityList[0]))
                pI8302->AccelInfoRec->NeedToSync = FALSE;
          }
-
+#endif
          GetAttachableDisplayDeviceList(pScrn);
          
 	 pI8301->lastDevice0 = pI8301->lastDevice1;
diff-tree a00a3d198aee7c173c2c36858f4447e13c86eb7f (from c94cc67bcc507e8256ae4b51b84dfe3f4aa12ab5)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Sat Apr 29 10:52:45 2006 +0800

    fix I830BIOSAdjustFrame() sync in I830_USE_EXA case, use exaWaitSync() helper.

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 6b03c0f..50f2059 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -196,6 +196,7 @@ const char *I830exaSymbols[] = {
     "exaDriverFini",
     "exaOffscreenAlloc",
     "exaOffscreenFree",
+    "exaWaitSync",
     NULL
 };
 #endif
@@ -5257,11 +5258,18 @@ I830BIOSAdjustFrame(int scrnIndex, int x
 	   x, pI830->xoffset, y, pI830->yoffset);
 
    /* Sync the engine before adjust frame */
-   if (pI830->AccelInfoRec && pI830->AccelInfoRec->NeedToSync) {
+#ifdef I830_USE_XAA
+   if (!pI830->noAccel && !pI830->useEXA && pI830->AccelInfoRec->NeedToSync) {
       (*pI830->AccelInfoRec->Sync)(pScrn);
       pI830->AccelInfoRec->NeedToSync = FALSE;
    }
-
+#endif
+#ifdef I830_USE_EXA
+   if (!pI830->noAccel && pI830->useEXA) {
+	ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
+	exaWaitSync(pScreen);
+   }
+#endif
    if (I830IsPrimary(pScrn))
       Start = pI830->FrontBuffer.Start;
    else {
diff-tree c94cc67bcc507e8256ae4b51b84dfe3f4aa12ab5 (from a4a4ced50cc235e79013ce8dd78e35c6eb4c98ca)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Fri Apr 28 15:33:57 2006 -0700

    Update to EXA 2.0 API.

diff --git a/src/i830_driver.c b/src/i830_driver.c
index d6f686d..6b03c0f 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -3533,7 +3533,15 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int f
 
 #ifdef I830_USE_EXA
    if (!pI830->noAccel && pI830->useEXA) {
-      if (!xf86LoadSubModule(pScrn, "exa")) {
+      XF86ModReqInfo req;
+      int errmaj, errmin;
+
+      memset(&req, 0, sizeof(req));
+      req.majorversion = 2;
+      req.minorversion = 0;
+      if (!LoadSubModule(pScrn->module, "exa", NULL, NULL, NULL, &req,
+		&errmaj, &errmin)) {
+	 LoaderErrorMsg(NULL, "exa", errmaj, errmin);
 	 PreInitCleanup(pScrn);
 	 return FALSE;
       }
@@ -5387,8 +5395,10 @@ I830BIOSLeaveVT(int scrnIndex, int flags
       pI830->AccelInfoRec->NeedToSync = FALSE;
 #endif
 #ifdef I830_USE_EXA
-   if (pI830->useEXA && pI830->EXADriverPtr)
-       pI830->EXADriverPtr->card.needsSync = TRUE;
+   if (pI830->useEXA && pI830->EXADriverPtr) {
+      ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
+      exaMarkSync(pScreen);
+   }
 #endif
 
    /* DO IT AGAIN! AS IT SEEMS THAT SOME LFPs FLICKER OTHERWISE */
@@ -5732,7 +5742,7 @@ I830BIOSSwitchMode(int scrnIndex, Displa
 #ifdef I830_USE_EXA
    if (!pI830->noAccel && pI830->useEXA) {
       ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
-      (*pI830->EXADriverPtr->accel.WaitMarker)(pScreen, 0);
+      exaWaitSync(pScreen);
    }
 #endif
 
diff --git a/src/i830_exa.c b/src/i830_exa.c
index a6aa6a7..6db94d9 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -357,54 +357,55 @@ I830EXAInit(ScreenPtr pScreen)
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
     I830Ptr pI830 = I830PTR(pScrn);
 
-    if(pI830->useEXA) {
-	if(!(pI830->EXADriverPtr = xnfcalloc(sizeof(ExaDriverRec), 1))) {
-	    pI830->noAccel = TRUE;
-	    return FALSE;
-	}
+    pI830->EXADriverPtr = exaDriverAlloc();
+    if (pI830->EXADriverPtr == NULL) {
+	pI830->noAccel = TRUE;
+	return FALSE;
     }
 
     pI830->bufferOffset = 0;
-    pI830->EXADriverPtr->card.memoryBase = pI830->FbBase;
-    pI830->EXADriverPtr->card.offScreenBase = pI830->Offscreen.Start;
-    pI830->EXADriverPtr->card.memorySize = pI830->Offscreen.Size;
+    pI830->EXADriverPtr->exa_major = 2;
+    pI830->EXADriverPtr->exa_minor = 0;
+    pI830->EXADriverPtr->memoryBase = pI830->FbBase;
+    pI830->EXADriverPtr->offScreenBase = pI830->Offscreen.Start;
+    pI830->EXADriverPtr->memorySize = pI830->Offscreen.Size;
 	   
-    if(pI830->EXADriverPtr->card.memorySize >
-       pI830->EXADriverPtr->card.offScreenBase)
-	pI830->EXADriverPtr->card.flags = EXA_OFFSCREEN_PIXMAPS;
+    if(pI830->EXADriverPtr->memorySize >
+       pI830->EXADriverPtr->offScreenBase)
+	pI830->EXADriverPtr->flags = EXA_OFFSCREEN_PIXMAPS;
     else {
 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Not enough video RAM for "
 		   "offscreen memory manager. Xv disabled\n");
 	/* disable Xv here... */
     }
 
-    pI830->EXADriverPtr->card.pixmapOffsetAlign = 256;
-    pI830->EXADriverPtr->card.pixmapPitchAlign = 64;
-    pI830->EXADriverPtr->card.maxX = 4095;
-    pI830->EXADriverPtr->card.maxY = 4095;
+    pI830->EXADriverPtr->pixmapOffsetAlign = 256;
+    pI830->EXADriverPtr->pixmapPitchAlign = 64;
+    pI830->EXADriverPtr->maxX = 4095;
+    pI830->EXADriverPtr->maxY = 4095;
 
     /* Sync */
-    pI830->EXADriverPtr->accel.WaitMarker = I830EXASync;
+    pI830->EXADriverPtr->WaitMarker = I830EXASync;
 
     /* Solid fill */
-    pI830->EXADriverPtr->accel.PrepareSolid = I830EXAPrepareSolid;
-    pI830->EXADriverPtr->accel.Solid = I830EXASolid;
-    pI830->EXADriverPtr->accel.DoneSolid = I830EXADoneSolid;
+    pI830->EXADriverPtr->PrepareSolid = I830EXAPrepareSolid;
+    pI830->EXADriverPtr->Solid = I830EXASolid;
+    pI830->EXADriverPtr->DoneSolid = I830EXADoneSolid;
 
     /* Copy */
-    pI830->EXADriverPtr->accel.PrepareCopy = I830EXAPrepareCopy;
-    pI830->EXADriverPtr->accel.Copy = I830EXACopy;
-    pI830->EXADriverPtr->accel.DoneCopy = I830EXADoneCopy;
+    pI830->EXADriverPtr->PrepareCopy = I830EXAPrepareCopy;
+    pI830->EXADriverPtr->Copy = I830EXACopy;
+    pI830->EXADriverPtr->DoneCopy = I830EXADoneCopy;
 #if 0
     /* Upload, download to/from Screen */
-    pI830->EXADriverPtr->accel.UploadToScreen = I830EXAUploadToScreen;
-    pI830->EXADriverPtr->accel.DownloadFromScreen = I830EXADownloadFromScreen;
+    pI830->EXADriverPtr->UploadToScreen = I830EXAUploadToScreen;
+    pI830->EXADriverPtr->DownloadFromScreen = I830EXADownloadFromScreen;
 
     /* Composite */
-    pI830->EXADriverPtr->accel.CheckComposite = I830EXACheckComposite;
-    pI830->EXADriverPtr->accel.PrepareComposite = I830EXAPrepareComposite;
-    pI830->EXADriverPtr->accel.Composite = I830EXAComposite;
-    pI830->EXADriverPtr->accel.DoneComposite = I830EXADoneComposite;
+    pI830->EXADriverPtr->CheckComposite = I830EXACheckComposite;
+    pI830->EXADriverPtr->PrepareComposite = I830EXAPrepareComposite;
+    pI830->EXADriverPtr->Composite = I830EXAComposite;
+    pI830->EXADriverPtr->DoneComposite = I830EXADoneComposite;
 #endif
 
     if(!exaDriverInit(pScreen, pI830->EXADriverPtr)) {
diff-tree a4a4ced50cc235e79013ce8dd78e35c6eb4c98ca (from 941a49f91eac02e256706d8821a2cb069ff7ffef)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Fri Apr 28 14:59:52 2006 -0700

    Get it to compile.

diff --git a/src/Makefile.am b/src/Makefile.am
index c64c203..83025fa 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -24,7 +24,7 @@ SUBDIRS = xvmc
 # -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 = @XORG_CFLAGS@ @DRI_CFLAGS@ -DI830_XV -DI830_USE_XAA -DI830_USE_EXA
 
 i810_drv_la_LTLIBRARIES = i810_drv.la
 i810_drv_la_LDFLAGS = -module -avoid-version
@@ -54,7 +54,9 @@ i810_drv_la_SOURCES = \
          i830_modes.c \
          i830_video.c \
          i830_rotate.c \
-	 i830_randr.c
+	 i830_randr.c \
+	 i830_exa.c \
+	 i830_xaa.c
 
 if DRI
 i810_drv_la_SOURCES += \
diff --git a/src/i830_driver.c b/src/i830_driver.c
index de510e6..d6f686d 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -5724,7 +5724,7 @@ I830BIOSSwitchMode(int scrnIndex, Displa
 
    /* Sync the engine before mode switch */
 #ifdef I830_USE_XAA
-   if (!pI830->noAccel && !pI830->useEXA)
+   if (!pI830->noAccel && !pI830->useEXA) {
       (*pI830->AccelInfoRec->Sync)(pScrn);
       pI830->AccelInfoRec->NeedToSync = FALSE;
    }
diff-tree 941a49f91eac02e256706d8821a2cb069ff7ffef (from 1dbb19059f5dd5cd2ad386c4f73498095987b943)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Fri Apr 28 14:57:03 2006 -0700

    Commit what applied from Jesse Barnes's i830-exa-latest.patch.

diff --git a/man/i810.man b/man/i810.man
index 099e1f8..62d6b73 100644
--- a/man/i810.man
+++ b/man/i810.man
@@ -204,6 +204,12 @@ Allows more memory for the offscreen all
 situations where HDTV movies are required to play but not enough offscreen
 memory is usually available. Set this to 6144 for upto 1920x1080 HDTV support.
 Default 0KB (off).
+.TP
+.BI "Option \*qAccelMethod\*q \*q" string \*q
+Choose acceleration architecture, either "XAA" or "EXA".  XAA is the old
+(but stable) XFree86 based acceleration architecture.  EXA is a newer and
+simpler acceleration architecture designed to better accelerate the X Render
+extension.  Default: "XAA".
 
 .SH "SEE ALSO"
 __xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), xorgconfig(__appmansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__)
@@ -213,4 +219,5 @@ Jeff Hartmann, Mark Vojkovich, Alan Hour
 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.
+Dual Head, Clone and lid status support added by Alan Hourihane.  EXA support
+added by Jesse Barnes.
diff --git a/src/i830.h b/src/i830.h
index d227662..edc485b 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -68,6 +68,15 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #include "i830_dri.h"
 #endif
 
+#ifdef I830_USE_EXA
+#include "exa.h"
+Bool I830EXAInit(ScreenPtr pScreen);
+#endif
+
+#ifdef I830_USE_XAA
+Bool I830XAAInit(ScreenPtr pScreen);
+#endif
+
 #include "common.h"
 
 /* I830 Video BIOS support */
@@ -203,7 +212,9 @@ typedef struct _I830Rec {
    I830MemRange FrontBuffer2;
    I830MemRange Scratch;
    I830MemRange Scratch2;
-
+#ifdef I830_USE_EXA
+   I830MemRange Offscreen;
+#endif
    /* Regions allocated either from the above pools, or from agpgart. */
    I830MemRange	*CursorMem;
    I830MemRange	*CursorMemARGB;
@@ -279,13 +290,22 @@ typedef struct _I830Rec {
    I830RegRec SavedReg;
    I830RegRec ModeReg;
 
+   Bool useEXA;
    Bool noAccel;
    Bool SWCursor;
    Bool cursorOn;
+#ifdef I830_USE_XAA
    XAAInfoRecPtr AccelInfoRec;
+#endif
    xf86CursorInfoPtr CursorInfoRec;
    CloseScreenProcPtr CloseScreen;
 
+#ifdef I830_USE_EXA
+   unsigned int copy_src_pitch;
+   unsigned int copy_src_off;
+   ExaDriverPtr	EXADriverPtr;
+#endif
+
    I830WriteIndexedByteFunc writeControl;
    I830ReadIndexedByteFunc readControl;
    I830WriteByteFunc writeStandard;
diff --git a/src/i830_accel.c b/src/i830_accel.c
index a11f64b..a1a6488 100644
--- a/src/i830_accel.c
+++ b/src/i830_accel.c
@@ -7,10 +7,6 @@
 #include "config.h"
 #endif
 
-#ifndef DO_SCANLINE_IMAGE_WRITE
-#define DO_SCANLINE_IMAGE_WRITE 0
-#endif
-
 /**************************************************************************
 
 Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
@@ -111,7 +107,9 @@ I830WaitLpRing(ScrnInfoPtr pScrn, int n,
 	    DRICloseScreen(screenInfo.screens[pScrn->scrnIndex]);
 	 }
 #endif
+#ifdef I830_USE_XAA
 	 pI830->AccelInfoRec = NULL;	/* Stops recursive behavior */
+#endif
 	 FatalError("lockup\n");
       }
 
@@ -210,46 +208,11 @@ I830RefreshRing(ScrnInfoPtr pScrn)
    pI830->LpRing->space = pI830->LpRing->head - (pI830->LpRing->tail + 8);
    if (pI830->LpRing->space < 0)
       pI830->LpRing->space += pI830->LpRing->mem.Size;
-
+#ifdef I830_USE_XAA
    if (pI830->AccelInfoRec)
       pI830->AccelInfoRec->NeedToSync = TRUE;
-}
-
-/* I830 Accel Functions */
-
-static void I830SetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
-					   int pattx, int patty,
-					   int fg, int bg, int rop,
-					   unsigned int planemask);
-static void I830SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,
-						 int pattx, int patty,
-						 int x, int y, int w, int h);
-
-static void I830SetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
-							   int fg, int bg,
-							   int rop,
-							   unsigned int mask);
-
-static void I830SubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr
-							     pScrn, int x,
-							     int y, int w,
-							     int h,
-							     int skipleft);
-
-static void I830SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno);
-
-#if DO_SCANLINE_IMAGE_WRITE
-static void I830SetupForScanlineImageWrite(ScrnInfoPtr pScrn, int rop,
-					   unsigned int planemask,
-					   int trans_color, int bpp,
-					   int depth);
-static void I830SubsequentScanlineImageWriteRect(ScrnInfoPtr pScrn,
-						 int x, int y, int w, int h,
-						 int skipleft);
-static void I830SubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno);
 #endif
-static void I830RestoreAccelState(ScrnInfoPtr pScrn);
-
+}
 
 /* The following function sets up the supported acceleration. Call it
  * from the FbInit() function in the SVGA driver, or before ScreenInit
@@ -258,539 +221,16 @@ static void I830RestoreAccelState(ScrnIn
 Bool
 I830AccelInit(ScreenPtr pScreen)
 {
-   XAAInfoRecPtr infoPtr;
-   ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-   I830Ptr pI830 = I830PTR(pScrn);
-   int i;
-   int width = 0;
-   int nr_buffers = 0;
-   unsigned char *ptr = NULL;
-
-   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
-      ErrorF("I830AccelInit\n");
-
-   pI830->AccelInfoRec = infoPtr = XAACreateInfoRec();
-   if (!infoPtr)
-      return FALSE;
-
-   pI830->bufferOffset = 0;
-   infoPtr->Flags = LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS | PIXMAP_CACHE;
-
-   /* Use the same sync function as the I830.
-    */
-   infoPtr->Sync = I830Sync;
-
-   /* Everything else is different enough to justify different functions */
-   {
-      infoPtr->SolidFillFlags = NO_PLANEMASK;
-      infoPtr->SetupForSolidFill = I830SetupForSolidFill;
-      infoPtr->SubsequentSolidFillRect = I830SubsequentSolidFillRect;
-   }
-
-   {
-      infoPtr->ScreenToScreenCopyFlags = (NO_PLANEMASK | NO_TRANSPARENCY);
-
-      infoPtr->SetupForScreenToScreenCopy = I830SetupForScreenToScreenCopy;
-      infoPtr->SubsequentScreenToScreenCopy =
-	    I830SubsequentScreenToScreenCopy;
-   }
-
-   {
-      infoPtr->SetupForMono8x8PatternFill = I830SetupForMono8x8PatternFill;
-      infoPtr->SubsequentMono8x8PatternFillRect =
-	    I830SubsequentMono8x8PatternFillRect;
-
-      infoPtr->Mono8x8PatternFillFlags = (HARDWARE_PATTERN_PROGRAMMED_BITS |
-					  HARDWARE_PATTERN_SCREEN_ORIGIN |
-					  HARDWARE_PATTERN_PROGRAMMED_ORIGIN |
-					  BIT_ORDER_IN_BYTE_MSBFIRST |
-					  NO_PLANEMASK);
-
-   }
+#ifdef I830_USE_EXA
+    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+    I830Ptr pI830 = I830PTR(pScrn);
 
-   /* On the primary screen */
-   if (pI830->init == 0) {
-      if (pI830->Scratch.Size != 0) {
-         width = ((pScrn->displayWidth + 31) & ~31) / 8;
-         nr_buffers = pI830->Scratch.Size / width;
-         ptr = pI830->FbBase + pI830->Scratch.Start;
-      }
-   } else {
-   /* On the secondary screen */
-      I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
-      if (pI8301->Scratch2.Size != 0) {
-         width = ((pScrn->displayWidth + 31) & ~31) / 8;
-         nr_buffers = pI8301->Scratch2.Size / width;
-         /* We have to use the primary screen's FbBase, as that's where
-          * we allocated Scratch2, so we get the correct pointer */
-         ptr = pI8301->FbBase + pI8301->Scratch2.Start;
-      }
-   }
-
-   if (nr_buffers) {
-      pI830->NumScanlineColorExpandBuffers = nr_buffers;
-      pI830->ScanlineColorExpandBuffers = (unsigned char **)
-	    xnfcalloc(nr_buffers, sizeof(unsigned char *));
-
-      for (i = 0; i < nr_buffers; i++, ptr += width)
-	 pI830->ScanlineColorExpandBuffers[i] = ptr;
-
-      infoPtr->ScanlineCPUToScreenColorExpandFillFlags =
-	    (NO_PLANEMASK | ROP_NEEDS_SOURCE | BIT_ORDER_IN_BYTE_MSBFIRST);
-
-      infoPtr->ScanlineColorExpandBuffers = (unsigned char **)
-	    xnfcalloc(1, sizeof(unsigned char *));
-      infoPtr->NumScanlineColorExpandBuffers = 1;
-
-      infoPtr->ScanlineColorExpandBuffers[0] =
-	    pI830->ScanlineColorExpandBuffers[0];
-      pI830->nextColorExpandBuf = 0;
-
-      infoPtr->SetupForScanlineCPUToScreenColorExpandFill =
-	    I830SetupForScanlineCPUToScreenColorExpandFill;
-
-      infoPtr->SubsequentScanlineCPUToScreenColorExpandFill =
-	    I830SubsequentScanlineCPUToScreenColorExpandFill;
-
-      infoPtr->SubsequentColorExpandScanline =
-	    I830SubsequentColorExpandScanline;
-
-#if DO_SCANLINE_IMAGE_WRITE
-      infoPtr->NumScanlineImageWriteBuffers = 1;
-      infoPtr->ScanlineImageWriteBuffers = infoPtr->ScanlineColorExpandBuffers;
-      infoPtr->SetupForScanlineImageWrite = I830SetupForScanlineImageWrite;
-      infoPtr->SubsequentScanlineImageWriteRect =
-	    I830SubsequentScanlineImageWriteRect;
-      infoPtr->SubsequentImageWriteScanline = I830SubsequentImageWriteScanline;
-      infoPtr->ScanlineImageWriteFlags = NO_GXCOPY |
-					 NO_PLANEMASK |
-					 ROP_NEEDS_SOURCE |
-					 SCANLINE_PAD_DWORD;
+    if (pI830->useEXA)
+	return I830EXAInit(pScreen);
 #endif
-   }
-
-   {
-      Bool shared_accel = FALSE;
-      int i;
-
-      for(i = 0; i < pScrn->numEntities; i++) {
-         if(xf86IsEntityShared(pScrn->entityList[i]))
-            shared_accel = TRUE;
-      }
-      if(shared_accel == TRUE)
-         infoPtr->RestoreAccelState = I830RestoreAccelState;
-   }
-
-   I830SelectBuffer(pScrn, I830_SELECT_FRONT);
-
-   return XAAInit(pScreen, infoPtr);
-}
-
-void
-I830SetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
-		      unsigned int planemask)
-{
-   I830Ptr pI830 = I830PTR(pScrn);
-
-   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
-      ErrorF("I830SetupForFillRectSolid color: %x rop: %x mask: %x\n",
-	     color, rop, planemask);
-
-   pI830->BR[13] = ((XAAGetPatternROP(rop) << 16) |
-		    (pScrn->displayWidth * pI830->cpp));
-
-   pI830->BR[16] = color;
-
-   switch (pScrn->bitsPerPixel) {
-   case 8:
-      break;
-   case 16:
-      pI830->BR[13] |= (1 << 24);
-      break;
-   case 32:
-      pI830->BR[13] |= ((1 << 25) | (1 << 24));
-      break;
-   }
-}
-
-void
-I830SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h)
-{
-   I830Ptr pI830 = I830PTR(pScrn);
-
-   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
-      ErrorF("I830SubsequentFillRectSolid %d,%d %dx%d\n", x, y, w, h);
-
-   {
-      BEGIN_LP_RING(6);
-
-      if (pScrn->bitsPerPixel == 32) {
-	 OUT_RING(COLOR_BLT_CMD | COLOR_BLT_WRITE_ALPHA |
-		  COLOR_BLT_WRITE_RGB);
-      } else {
-	 OUT_RING(COLOR_BLT_CMD);
-      }
-      OUT_RING(pI830->BR[13]);
-      OUT_RING((h << 16) | (w * pI830->cpp));
-      OUT_RING(pI830->bufferOffset + (y * pScrn->displayWidth + x) *
-	       pI830->cpp);
-      OUT_RING(pI830->BR[16]);
-      OUT_RING(0);
-
-      ADVANCE_LP_RING();
-   }
-}
-
-void
-I830SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, int rop,
-			       unsigned int planemask, int transparency_color)
-{
-   I830Ptr pI830 = I830PTR(pScrn);
-
-   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
-      ErrorF("I830SetupForScreenToScreenCopy %d %d %x %x %d\n",
-	     xdir, ydir, rop, planemask, transparency_color);
-
-   pI830->BR[13] = (pScrn->displayWidth * pI830->cpp);
-   pI830->BR[13] |= XAAGetCopyROP(rop) << 16;
-
-   switch (pScrn->bitsPerPixel) {
-   case 8:
-      break;
-   case 16:
-      pI830->BR[13] |= (1 << 24);
-      break;
-   case 32:
-      pI830->BR[13] |= ((1 << 25) | (1 << 24));
-      break;
-   }
-
-}
-
-void
-I830SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int src_x1, int src_y1,
-				 int dst_x1, int dst_y1, int w, int h)
-{
-   I830Ptr pI830 = I830PTR(pScrn);
-   int dst_x2, dst_y2;
-
-   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
-      ErrorF("I830SubsequentScreenToScreenCopy %d,%d - %d,%d %dx%d\n",
-	     src_x1, src_y1, dst_x1, dst_y1, w, h);
-
-   dst_x2 = dst_x1 + w;
-   dst_y2 = dst_y1 + h;
-
-   {
-      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);
-      } else {
-	 OUT_RING(XY_SRC_COPY_BLT_CMD);
-      }
-      OUT_RING(pI830->BR[13]);
-      OUT_RING((dst_y1 << 16) | (dst_x1 & 0xffff));
-      OUT_RING((dst_y2 << 16) | (dst_x2 & 0xffff));
-      OUT_RING(pI830->bufferOffset);
-      OUT_RING((src_y1 << 16) | (src_x1 & 0xffff));
-      OUT_RING(pI830->BR[13] & 0xFFFF);
-      OUT_RING(pI830->bufferOffset);
-
-      ADVANCE_LP_RING();
-   }
-}
-
-static void
-I830SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int pattx, int patty,
-			       int fg, int bg, int rop,
-			       unsigned int planemask)
-{
-   I830Ptr pI830 = I830PTR(pScrn);
-
-   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
-      ErrorF("I830SetupForMono8x8PatternFill\n");
-
-   pI830->BR[16] = pattx;
-   pI830->BR[17] = patty;
-   pI830->BR[18] = bg;
-   pI830->BR[19] = fg;
-
-   pI830->BR[13] = (pScrn->displayWidth * pI830->cpp);	/* In bytes */
-   pI830->BR[13] |= XAAGetPatternROP(rop) << 16;
-   if (bg == -1)
-      pI830->BR[13] |= (1 << 28);
-
-   switch (pScrn->bitsPerPixel) {
-   case 8:
-      break;
-   case 16:
-      pI830->BR[13] |= (1 << 24);
-      break;
-   case 32:
-      pI830->BR[13] |= ((1 << 25) | (1 << 24));
-      break;
-   }
-
-}
-
-static void
-I830SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int pattx, int patty,
-				     int x, int y, int w, int h)
-{
-   I830Ptr pI830 = I830PTR(pScrn);
-   int x1, x2, y1, y2;
-
-   x1 = x;
-   x2 = x + w;
-   y1 = y;
-   y2 = y + h;
-
-   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
-      ErrorF("I830SubsequentMono8x8PatternFillRect\n");
-
-   {
-      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 |
-		  ((patty << 8) & XY_MONO_PAT_VERT_SEED) |
-		  ((pattx << 12) & XY_MONO_PAT_HORT_SEED));
-      } else {
-	 OUT_RING(XY_MONO_PAT_BLT_CMD |
-		  ((patty << 8) & XY_MONO_PAT_VERT_SEED) |
-		  ((pattx << 12) & XY_MONO_PAT_HORT_SEED));
-      }
-      OUT_RING(pI830->BR[13]);
-      OUT_RING((y1 << 16) | x1);
-      OUT_RING((y2 << 16) | x2);
-      OUT_RING(pI830->bufferOffset);
-      OUT_RING(pI830->BR[18]);		/* bg */
-      OUT_RING(pI830->BR[19]);		/* fg */
-      OUT_RING(pI830->BR[16]);		/* pattern data */
-      OUT_RING(pI830->BR[17]);
-      OUT_RING(0);
-      ADVANCE_LP_RING();
-   }
-}
-
-static void
-I830GetNextScanlineColorExpandBuffer(ScrnInfoPtr pScrn)
-{
-   I830Ptr pI830 = I830PTR(pScrn);
-   XAAInfoRecPtr infoPtr = pI830->AccelInfoRec;
-
-   if (pI830->nextColorExpandBuf == pI830->NumScanlineColorExpandBuffers)
-      I830Sync(pScrn);
-
-   infoPtr->ScanlineColorExpandBuffers[0] =
-	 pI830->ScanlineColorExpandBuffers[pI830->nextColorExpandBuf];
-
-   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
-      ErrorF("using color expand buffer %d\n", pI830->nextColorExpandBuf);
-
-   pI830->nextColorExpandBuf++;
-}
-
-static void
-I830SetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
-					       int fg, int bg, int rop,
-					       unsigned int planemask)
-{
-   I830Ptr pI830 = I830PTR(pScrn);
-
-   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
-      ErrorF("I830SetupForScanlineScreenToScreenColorExpand %d %d %x %x\n",
-	     fg, bg, rop, planemask);
-
-   /* Fill out register values */
-   pI830->BR[13] = (pScrn->displayWidth * pI830->cpp);
-   pI830->BR[13] |= XAAGetCopyROP(rop) << 16;
-   if (bg == -1)
-      pI830->BR[13] |= (1 << 29);
-
-   switch (pScrn->bitsPerPixel) {
-   case 8:
-      break;
-   case 16:
-      pI830->BR[13] |= (1 << 24);
-      break;
-   case 32:
-      pI830->BR[13] |= ((1 << 25) | (1 << 24));
-      break;
-   }
-
-   pI830->BR[18] = bg;
-   pI830->BR[19] = fg;
-
-   I830GetNextScanlineColorExpandBuffer(pScrn);
-}
-
-static void
-I830SubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
-						 int x, int y,
-						 int w, int h, int skipleft)
-{
-   I830Ptr pI830 = I830PTR(pScrn);
-
-   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
-      ErrorF("I830SubsequentScanlineCPUToScreenColorExpandFill "
-	     "%d,%d %dx%x %d\n", x, y, w, h, skipleft);
-
-   /* Fill out register values */
-   pI830->BR[9] = (pI830->bufferOffset +
-		   (y * pScrn->displayWidth + x) * pI830->cpp);
-   pI830->BR[11] = ((1 << 16) | w);
-}
-
-static void
-I830SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
-{
-   I830Ptr pI830 = I830PTR(pScrn);
-
-   if (pI830->init == 0) {
-      pI830->BR[12] = (pI830->AccelInfoRec->ScanlineColorExpandBuffers[0] -
-		       pI830->FbBase);
-   } else {
-      I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
-
-      /* We have to use the primary screen's FbBase, as that's where
-       * we allocated Scratch2, so we get the correct pointer */
-      pI830->BR[12] = (pI830->AccelInfoRec->ScanlineColorExpandBuffers[0] -
-		       pI8301->FbBase);
-   }
-
-   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
-      ErrorF("I830SubsequentColorExpandScanline %d (addr %x)\n",
-	     bufno, pI830->BR[12]);
-
-   {
-      BEGIN_LP_RING(8);
-
-      if (pScrn->bitsPerPixel == 32) {
-	 OUT_RING(XY_MONO_SRC_BLT_CMD | XY_MONO_SRC_BLT_WRITE_ALPHA |
-		  XY_MONO_SRC_BLT_WRITE_RGB);
-      } else {
-	 OUT_RING(XY_MONO_SRC_BLT_CMD);
-      }
-      OUT_RING(pI830->BR[13]);
-      OUT_RING(0);			/* x1 = 0, y1 = 0 */
-      OUT_RING(pI830->BR[11]);		/* x2 = w, y2 = 1 */
-      OUT_RING(pI830->BR[9]);		/* dst addr */
-      OUT_RING(pI830->BR[12]);		/* src addr */
-      OUT_RING(pI830->BR[18]);		/* bg */
-      OUT_RING(pI830->BR[19]);		/* fg */
-
-      ADVANCE_LP_RING();
-   }
-
-   /* Advance to next scanline.
-    */
-   pI830->BR[9] += pScrn->displayWidth * pI830->cpp;
-   I830GetNextScanlineColorExpandBuffer(pScrn);
-}
-
-#if DO_SCANLINE_IMAGE_WRITE
-static void
-I830SetupForScanlineImageWrite(ScrnInfoPtr pScrn, int rop,
-			       unsigned int planemask, int trans_color,
-			       int bpp, int depth)
-{
-   I830Ptr pI830 = I830PTR(pScrn);
-
-   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
-      ErrorF("I830SetupForScanlineImageWrite %x %x\n", rop, planemask);
-
-   /* Fill out register values */
-   pI830->BR[13] = (pScrn->displayWidth * pI830->cpp);
-   pI830->BR[13] |= XAAGetCopyROP(rop) << 16;
-
-   switch (pScrn->bitsPerPixel) {
-   case 8:
-      break;
-   case 16:
-      pI830->BR[13] |= (1 << 24);
-      break;
-   case 32:
-      pI830->BR[13] |= ((1 << 25) | (1 << 24));
-      break;
-   }
-
-   I830GetNextScanlineColorExpandBuffer(pScrn);
-}
-
-static void
-I830SubsequentScanlineImageWriteRect(ScrnInfoPtr pScrn, int x, int y,
-				     int w, int h, int skipleft)
-{
-   I830Ptr pI830 = I830PTR(pScrn);
-
-   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
-      ErrorF("I830SubsequentScanlineImageWriteRect "
-	     "%d,%d %dx%x %d\n", x, y, w, h, skipleft);
-
-   /* Fill out register values */
-   pI830->BR[9] = (pI830->bufferOffset +
-		   (y * pScrn->displayWidth + x) * pI830->cpp);
-   pI830->BR[11] = ((1 << 16) | w);
-}
-
-static void
-I830SubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno)
-{
-   I830Ptr pI830 = I830PTR(pScrn);
-
-   if (pI830->init == 0) {
-      pI830->BR[12] = (pI830->AccelInfoRec->ScanlineColorExpandBuffers[0] -
-		       pI830->FbBase);
-   } else {
-      I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
-
-      /* We have to use the primary screen's FbBase, as that's where
-       * we allocated Scratch2, so we get the correct pointer */
-      pI830->BR[12] = (pI830->AccelInfoRec->ScanlineColorExpandBuffers[0] -
-		       pI8301->FbBase);
-   }
-
-   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
-      ErrorF("I830SubsequentImageWriteScanline %d (addr %x)\n",
-	     bufno, pI830->BR[12]);
-
-   {
-      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);
-      } else {
-	 OUT_RING(XY_SRC_COPY_BLT_CMD);
-      }
-      OUT_RING(pI830->BR[13]);
-      OUT_RING(0);			/* x1 = 0, y1 = 0 */
-      OUT_RING(pI830->BR[11]);		/* x2 = w, y2 = 1 */
-      OUT_RING(pI830->BR[9]);		/* dst addr */
-      OUT_RING(0);			/* source origin (0,0) */
-      OUT_RING(pI830->BR[11] & 0xffff);	/* source pitch */
-      OUT_RING(pI830->BR[12]);		/* src addr */
-
-      ADVANCE_LP_RING();
-   }
-
-   /* Advance to next scanline.
-    */
-   pI830->BR[9] += pScrn->displayWidth * pI830->cpp;
-   I830GetNextScanlineColorExpandBuffer(pScrn);
-}
-#endif
-
-/* Support for multiscreen */
-static void
-I830RestoreAccelState(ScrnInfoPtr pScrn)
-{
-#if 0
-   /* might be needed, but everything is on a ring, so I don't think so */
-   I830Sync(pScrn);
+#ifdef I830_USE_XAA
+    return I830XAAInit(pScreen);
 #endif
+    return FALSE;
 }
+
diff --git a/src/i830_dga.c b/src/i830_dga.c
index 1129fa3..08207d3 100644
--- a/src/i830_dga.c
+++ b/src/i830_dga.c
@@ -238,6 +238,7 @@ static void
 I830_FillRect(ScrnInfoPtr pScrn,
 	      int x, int y, int w, int h, unsigned long color)
 {
+#ifdef I830_USE_XAA
    I830Ptr pI830 = I830PTR(pScrn);
 
    MARKER();
@@ -247,11 +248,13 @@ I830_FillRect(ScrnInfoPtr pScrn,
       (*pI830->AccelInfoRec->SubsequentSolidFillRect) (pScrn, x, y, w, h);
       SET_SYNC_FLAG(pI830->AccelInfoRec);
    }
+#endif
 }
 
 static void
 I830_Sync(ScrnInfoPtr pScrn)
 {
+#ifdef I830_USE_XAA
    I830Ptr pI830 = I830PTR(pScrn);
 
    MARKER();
@@ -259,12 +262,14 @@ I830_Sync(ScrnInfoPtr pScrn)
    if (pI830->AccelInfoRec) {
       (*pI830->AccelInfoRec->Sync) (pScrn);
    }
+#endif
 }
 
 static void
 I830_BlitRect(ScrnInfoPtr pScrn,
 	      int srcx, int srcy, int w, int h, int dstx, int dsty)
 {
+#ifdef I830_USE_XAA
    I830Ptr pI830 = I830PTR(pScrn);
 
    MARKER();
@@ -279,6 +284,7 @@ I830_BlitRect(ScrnInfoPtr pScrn,
 							    dstx, dsty, w, h);
       SET_SYNC_FLAG(pI830->AccelInfoRec);
    }
+#endif
 }
 
 #if 0
diff --git a/src/i830_dri.c b/src/i830_dri.c
index 13d2cfd..c159686 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -1017,7 +1017,9 @@ I830DRIInitBuffers(WindowPtr pWin, Regio
    }
 
    I830SelectBuffer(pScrn, I830_SELECT_FRONT);
+#ifdef I830_USE_XAA
    pI830->AccelInfoRec->NeedToSync = TRUE;
+#endif
 }
 
 /* This routine is a modified form of XAADoBitBlt with the calls to
@@ -1178,8 +1180,9 @@ I830DRIMoveBuffers(WindowPtr pParent, DD
       DEALLOCATE_LOCAL(pptNew1);
       DEALLOCATE_LOCAL(pboxNew1);
    }
-
+#ifdef I830_USE_XAA
    pI830->AccelInfoRec->NeedToSync = TRUE;
+#endif
 }
 
 /* Initialize the first context */
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 053ccd1..de510e6 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -189,6 +189,17 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "dri.h"
 #endif
 
+#ifdef I830_USE_EXA
+const char *I830exaSymbols[] = {
+    "exaGetVersion",
+    "exaDriverInit",
+    "exaDriverFini",
+    "exaOffscreenAlloc",
+    "exaOffscreenFree",
+    NULL
+};
+#endif
+
 #define BIT(x) (1 << (x))
 #define MAX(a,b) ((a) > (b) ? (a) : (b))
 #define NB_OF(x) (sizeof (x) / sizeof (*x))
@@ -227,6 +238,9 @@ static PciChipsets I830BIOSPciChipsets[]
  */
 
 typedef enum {
+#if defined(I830_USE_XAA) && defined(I830_USE_EXA)
+   OPTION_ACCELMETHOD,
+#endif
    OPTION_NOACCEL,
    OPTION_SW_CURSOR,
    OPTION_CACHE_LINES,
@@ -248,6 +262,9 @@ typedef enum {
 } I830Opts;
 
 static OptionInfoRec I830BIOSOptions[] = {
+#if defined(I830_USE_XAA) && defined(I830_USE_EXA)
+   {OPTION_ACCELMETHOD,	"AccelMethod",	OPTV_ANYSTR,	{0},	FALSE},
+#endif
    {OPTION_NOACCEL,	"NoAccel",	OPTV_BOOLEAN,	{0},	FALSE},
    {OPTION_SW_CURSOR,	"SWcursor",	OPTV_BOOLEAN,	{0},	FALSE},
    {OPTION_CACHE_LINES,	"CacheLines",	OPTV_INTEGER,	{0},	FALSE},
@@ -2448,6 +2465,42 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int f
    if (xf86ReturnOptValBool(pI830->Options, OPTION_NOACCEL, FALSE)) {
       pI830->noAccel = TRUE;
    }
+
+   /*
+    * The ugliness below:
+    * If either XAA or EXA (exclusive) is compiled in, default to it.
+    * 
+    * If both are compiled in, and the user didn't specify noAccel, use the
+    * config option AccelMethod to determine which to use, defaulting to XAA
+    * if none is specified, or if the string was unrecognized.
+    *
+    * All this *could* go away if we removed XAA support from this driver,
+    * for example. :)
+    */
+   if (!pI830->noAccel) {
+#if (defined(I830_USE_EXA) && defined(I830_USE_XAA)) || !defined(I830_USE_EXA)
+       pI830->useEXA = FALSE;
+#else
+       pI830->useEXA = TRUE;
+#endif
+#if defined(I830_USE_XAA) && defined(I830_USE_EXA)
+       int from = X_DEFAULT;
+       if ((s = (char *)xf86GetOptValString(pI830->Options,
+					    OPTION_ACCELMETHOD))) {
+	   if (!xf86NameCmp(s, "EXA")) {
+	       from = X_CONFIG;
+	       pI830->useEXA = TRUE;
+	   }
+	   else if (!xf86NameCmp(s, "XAA")) {
+	       from = X_CONFIG;
+	       pI830->useEXA = FALSE;
+	   }
+       }
+#endif
+       xf86DrvMsg(pScrn->scrnIndex, from, "Using %s for acceleration\n",
+		  pI830->useEXA ? "EXA" : "XAA");
+   }
+
    if (xf86ReturnOptValBool(pI830->Options, OPTION_SW_CURSOR, FALSE)) {
       pI830->SWCursor = TRUE;
    }
@@ -3468,14 +3521,25 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int f
 
    xf86LoaderReqSymLists(I810fbSymbols, NULL);
 
-   if (!pI830->noAccel) {
+#ifdef I830_USE_XAA
+   if (!pI830->noAccel && !pI830->useEXA) {
       if (!xf86LoadSubModule(pScrn, "xaa")) {
 	 PreInitCleanup(pScrn);
 	 return FALSE;
       }
       xf86LoaderReqSymLists(I810xaaSymbols, NULL);
    }
+#endif
 
+#ifdef I830_USE_EXA
+   if (!pI830->noAccel && pI830->useEXA) {
+      if (!xf86LoadSubModule(pScrn, "exa")) {
+	 PreInitCleanup(pScrn);
+	 return FALSE;
+      }
+      xf86LoaderReqSymLists(I830exaSymbols, NULL);
+   }
+#endif
    if (!pI830->SWCursor) {
       if (!xf86LoadSubModule(pScrn, "ramdac")) {
 	 PreInitCleanup(pScrn);
@@ -3622,16 +3686,25 @@ ResetState(ScrnInfoPtr pScrn, Bool flush
    /* Reset the fence registers to 0 */
    for (i = 0; i < 8; i++)
       OUTREG(FENCE + i * 4, 0);
-
    /* Flush the ring buffer (if enabled), then disable it. */
-   if (pI830->AccelInfoRec != NULL && flush) {
-      temp = INREG(LP_RING + RING_LEN);
-      if (temp & 1) {
-	 I830RefreshRing(pScrn);
-	 I830Sync(pScrn);
-	 DO_RING_IDLE();
-      }
-   }
+   /* God this is ugly */
+#define flush_ring() do { \
+      temp = INREG(LP_RING + RING_LEN); \
+      if (temp & 1) { \
+	 I830RefreshRing(pScrn); \
+	 I830Sync(pScrn); \
+	 DO_RING_IDLE(); \
+      } \
+   } while(0)
+#ifdef I830_USE_XAA
+   if (!pI830->useEXA && flush && pI830->AccelInfoRec)
+       flush_ring();
+#endif
+#ifdef I830_USE_XAA
+   if (pI830->useEXA && flush && pI830->EXADriverPtr)
+       flush_ring();
+#endif
+
    OUTREG(LP_RING + RING_LEN, 0);
    OUTREG(LP_RING + RING_HEAD, 0);
    OUTREG(LP_RING + RING_TAIL, 0);
@@ -5309,8 +5382,14 @@ I830BIOSLeaveVT(int scrnIndex, int flags
    RestoreBIOSMemSize(pScrn);
    if (I830IsPrimary(pScrn))
       I830UnbindAGPMemory(pScrn);
-   if (pI830->AccelInfoRec)
+#ifdef I830_USE_XAA
+   if (!pI830->useEXA && pI830->AccelInfoRec)
       pI830->AccelInfoRec->NeedToSync = FALSE;
+#endif
+#ifdef I830_USE_EXA
+   if (pI830->useEXA && pI830->EXADriverPtr)
+       pI830->EXADriverPtr->card.needsSync = TRUE;
+#endif
 
    /* DO IT AGAIN! AS IT SEEMS THAT SOME LFPs FLICKER OTHERWISE */
    if (I830IsPrimary(pScrn)) {
@@ -5644,10 +5723,18 @@ I830BIOSSwitchMode(int scrnIndex, Displa
 #endif
 
    /* Sync the engine before mode switch */
-   if (pI830->AccelInfoRec && pI830->AccelInfoRec->NeedToSync) {
+#ifdef I830_USE_XAA
+   if (!pI830->noAccel && !pI830->useEXA)
       (*pI830->AccelInfoRec->Sync)(pScrn);
       pI830->AccelInfoRec->NeedToSync = FALSE;
    }
+#endif
+#ifdef I830_USE_EXA
+   if (!pI830->noAccel && pI830->useEXA) {
+      ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
+      (*pI830->EXADriverPtr->accel.WaitMarker)(pScreen, 0);
+   }
+#endif
 
    /* Check if our currentmode is about to change. We do this so if we
     * are rotating, we don't need to call the mode setup again.
@@ -5801,7 +5888,9 @@ I830BIOSCloseScreen(int scrnIndex, Scree
 {
    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
    I830Ptr pI830 = I830PTR(pScrn);
+#ifdef I830_USE_XAA
    XAAInfoRecPtr infoPtr = pI830->AccelInfoRec;
+#endif
 
    pI830->closing = TRUE;
 #ifdef XF86DRI
@@ -5827,14 +5916,21 @@ I830BIOSCloseScreen(int scrnIndex, Scree
       xfree(pI830->ScanlineColorExpandBuffers);
       pI830->ScanlineColorExpandBuffers = 0;
    }
-
+#ifdef I830_USE_XAA
    if (infoPtr) {
       if (infoPtr->ScanlineColorExpandBuffers)
 	 xfree(infoPtr->ScanlineColorExpandBuffers);
       XAADestroyInfoRec(infoPtr);
       pI830->AccelInfoRec = NULL;
    }
-
+#endif
+#ifdef I830_USE_EXA
+   if (pI830->useEXA && pI830->EXADriverPtr) {
+       exaDriverFini(pScreen);
+       xfree(pI830->EXADriverPtr);
+       pI830->EXADriverPtr = NULL;
+   }
+#endif
    if (pI830->CursorInfoRec) {
       xf86DestroyCursorInfoRec(pI830->CursorInfoRec);
       pI830->CursorInfoRec = 0;
diff --git a/src/i830_exa.c b/src/i830_exa.c
new file mode 100644
index 0000000..a6aa6a7
--- /dev/null
+++ b/src/i830_exa.c
@@ -0,0 +1,418 @@
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+All Rights Reserved.
+Copyright (c) 2005 Jesse Barnes <jbarnes at virtuousgeek.org>
+  Based on code from i830_xaa.c.
+
+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 PRECISION INSIGHT 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 "xf86_ansic.h"
+#include "xf86.h"
+#include "xaarop.h"
+#include "i830.h"
+#include "i810_reg.h"
+
+int I830CopyROP[16] =
+{
+   ROP_0,               /* GXclear */
+   ROP_DSa,             /* GXand */
+   ROP_SDna,            /* GXandReverse */
+   ROP_S,               /* GXcopy */
+   ROP_DSna,            /* GXandInverted */
+   ROP_D,               /* GXnoop */
+   ROP_DSx,             /* GXxor */
+   ROP_DSo,             /* GXor */
+   ROP_DSon,            /* GXnor */
+   ROP_DSxn,            /* GXequiv */
+   ROP_Dn,              /* GXinvert*/
+   ROP_SDno,            /* GXorReverse */
+   ROP_Sn,              /* GXcopyInverted */
+   ROP_DSno,            /* GXorInverted */
+   ROP_DSan,            /* GXnand */
+   ROP_1                /* GXset */
+};
+
+static int I830PatternROP[16] =
+{
+    ROP_0,
+    ROP_DPa,
+    ROP_PDna,
+    ROP_P,
+    ROP_DPna,
+    ROP_D,
+    ROP_DPx,
+    ROP_DPo,
+    ROP_DPon,
+    ROP_PDxn,
+    ROP_Dn,
+    ROP_PDno,
+    ROP_Pn,
+    ROP_DPno,
+    ROP_DPan,
+    ROP_1
+};
+
+void i830ScratchSave(ScreenPtr pScreen, ExaOffscreenArea *area);
+Bool i830UploadToScreen(PixmapPtr pDst, char *src, int src_pitch);
+Bool i830UploadToScratch(PixmapPtr pSrc, PixmapPtr pDst);
+Bool i830DownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h,
+			    char *dst, int dst_pitch);
+
+/**
+ * I830EXASync - wait for a command to finish
+ * @pScreen: current screen
+ * @marker: marker command to wait for
+ *
+ * Wait for the command specified by @marker to finish, then return.
+ */
+static void
+I830EXASync(ScreenPtr pScreen, int marker)
+{
+    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+    I830Ptr pI830 = I830PTR(pScrn);
+
+#ifdef XF86DRI
+    /* VT switching tries to do this. */
+    if (!pI830->LockHeld && pI830->directRenderingEnabled)
+	return;
+#endif
+
+    if (pI830->entityPrivate && !pI830->entityPrivate->RingRunning)
+	return;
+
+    /* 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_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;
+}
+
+/**
+ * I830EXAPrepareSolid - prepare for a Solid operation, if possible
+ *
+ * TODO:
+ *   - support planemask using FILL_MONO_SRC_BLT_CMD?
+ */
+static Bool
+I830EXAPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg)
+{
+    ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
+    I830Ptr pI830 = I830PTR(pScrn);
+
+    if (planemask != (Pixel)~0)
+	return FALSE;
+
+    pI830->BR[13] = exaGetPixmapPitch(pPixmap);
+    pI830->BR[13] |= I830PatternROP[alu] << 16;
+
+    pI830->BR[16] = fg;
+
+    /*
+     * Depth: 00 - 8 bit, 01 - 16 bit, 10 - 24 bit, 11 - 32 bit
+     */
+    switch (pScrn->bitsPerPixel) {
+    case 8:
+	pI830->BR[13] |= ((0 << 25) | (0 << 24));
+	break;
+    case 16:
+	pI830->BR[13] |= ((0 << 25) | (1 << 24));
+	break;
+    case 32:
+	pI830->BR[13] |= ((1 << 25) | (1 << 24));
+	break;
+    }
+    return TRUE;
+}
+
+static void
+I830EXASolid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2)
+{
+    ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
+    I830Ptr pI830 = I830PTR(pScrn);
+    int h, w;
+    unsigned int offset;
+
+    offset = exaGetPixmapOffset(pPixmap) + y1 * exaGetPixmapPitch(pPixmap) +
+	x1 * (pPixmap->drawable.bitsPerPixel / 8);
+    
+    h = y2 - y1;
+    w = x2 - x1;
+
+    {
+	BEGIN_LP_RING(6);
+
+	if (pScrn->bitsPerPixel == 32)
+	    OUT_RING(COLOR_BLT_CMD | COLOR_BLT_WRITE_ALPHA |
+		     COLOR_BLT_WRITE_RGB);
+	else
+	    OUT_RING(COLOR_BLT_CMD);
+
+	OUT_RING(pI830->BR[13]);
+	OUT_RING((h << 16) | (w * (pPixmap->drawable.bitsPerPixel/8)));
+	OUT_RING(offset);
+	OUT_RING(pI830->BR[16]);
+	OUT_RING(0);
+
+	ADVANCE_LP_RING();
+    }
+}
+
+static void
+I830EXADoneSolid(PixmapPtr pPixmap)
+{
+    return;
+}
+
+/**
+ * TODO:
+ *   - support planemask using FULL_BLT_CMD?
+ */
+static Bool
+I830EXAPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir,
+		   int ydir, int alu, Pixel planemask)
+{
+    ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
+    I830Ptr pI830 = I830PTR(pScrn);
+
+    if (planemask != (Pixel)~0)
+	return FALSE;
+
+    pI830->copy_src_pitch = exaGetPixmapPitch(pSrcPixmap);
+    pI830->copy_src_off = exaGetPixmapOffset(pSrcPixmap);
+
+    pI830->BR[13] = exaGetPixmapPitch(pDstPixmap);
+    pI830->BR[13] |= I830CopyROP[alu] << 16;
+
+    switch (pScrn->bitsPerPixel) {
+    case 8:
+	break;
+    case 16:
+	pI830->BR[13] |= (1 << 24);
+	break;
+    case 32:
+	pI830->BR[13] |= ((1 << 25) | (1 << 24));
+	break;
+    }
+    return TRUE;
+}
+
+static void
+I830EXACopy(PixmapPtr pDstPixmap, int src_x1, int src_y1, int dst_x1,
+	    int dst_y1, int w, int h)
+{
+    ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
+    I830Ptr pI830 = I830PTR(pScrn);
+    int dst_x2, dst_y2;
+    unsigned int src_off, dst_off;
+
+    dst_x2 = dst_x1 + w;
+    dst_y2 = dst_y1 + h;
+
+    src_off = pI830->copy_src_off;
+    dst_off = exaGetPixmapOffset(pDstPixmap);
+
+    {
+	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);
+	else
+	    OUT_RING(XY_SRC_COPY_BLT_CMD);
+
+	OUT_RING(pI830->BR[13]);
+	OUT_RING((dst_y1 << 16) | (dst_x1 & 0xffff));
+	OUT_RING((dst_y2 << 16) | (dst_x2 & 0xffff));
+	OUT_RING(dst_off);
+	OUT_RING((src_y1 << 16) | (src_x1 & 0xffff));
+	OUT_RING(pI830->copy_src_pitch);
+	OUT_RING(src_off);
+
+	ADVANCE_LP_RING();
+    }
+}
+
+static void
+I830EXADoneCopy(PixmapPtr pDstPixmap)
+{
+    return;
+}
+
+#if 0 /* Not done (or even started for that matter) */
+static Bool
+I830EXAUploadToScreen(PixmapPtr pDst, char *src, int src_pitch)
+{
+    ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
+    I830Ptr pI830 = I830PTR(pScrn);
+    unsigned char *dst = pDst->devPrivate.ptr;
+    int dst_pitch = exaGetPixmapPitch(pDst);
+    int size = src_pitch < dst_pitch ? src_pitch : dst_pitch;
+    int h = pDst->drawable.height;
+
+    I830Sync(pScrn);
+
+    while(h--) {
+	i830MemCopyToVideoRam(pI830, dst, (unsigned char *)src, size);
+	src += src_pitch;
+	dst += dst_pitch;
+    }
+
+    return TRUE;
+}
+
+static Bool
+I830EXADownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h,
+			  char *dst, int dst_pitch)
+{
+    ScrnInfoPtr pScrn = xf86Screens[pSrc->drawable.pScreen->myNum];
+    I830Ptr pI830 = I830PTR(pScrn);
+    unsigned char *src = pSrc->devPrivate.ptr;
+    int src_pitch = exaGetPixmapPitch(pSrc);
+    int size = src_pitch < dst_pitch ? src_pitch : dst_pitch;
+
+    I830Sync(pScrn);
+
+    while(h--) {
+	i830MemCopyFromVideoRam(pI830, (unsigned char *)dst, src, size);
+	src += src_pitch;
+	dst += dst_pitch;
+    }
+
+    return TRUE;
+}
+
+static Bool
+I830EXACheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
+		      PicturePtr pDstPicture)
+{
+    return FALSE; /* no Composite yet */
+}
+
+static Bool
+I830EXAPrepareComposite(int op, PicturePtr pSrcPicture,
+			PicturePtr pMaskPicture, PicturePtr pDstPicture,
+			PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst)
+{
+    return FALSE; /* no Composite yet */
+}
+
+static void
+I830EXAComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
+		 int dstX, int dstY, int width, int height)
+{
+    return; /* no Composite yet */
+}
+
+static void
+I830EXADoneComposite(PixmapPtr pDst)
+{
+    return; /* no Composite yet */
+}
+#endif
+
+/*
+ * TODO:
+ *   - Dual head?
+ *   - Upload/Download
+ *   - Composite
+ */
+Bool
+I830EXAInit(ScreenPtr pScreen)
+{
+    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+    I830Ptr pI830 = I830PTR(pScrn);
+
+    if(pI830->useEXA) {
+	if(!(pI830->EXADriverPtr = xnfcalloc(sizeof(ExaDriverRec), 1))) {
+	    pI830->noAccel = TRUE;
+	    return FALSE;
+	}
+    }
+
+    pI830->bufferOffset = 0;
+    pI830->EXADriverPtr->card.memoryBase = pI830->FbBase;
+    pI830->EXADriverPtr->card.offScreenBase = pI830->Offscreen.Start;
+    pI830->EXADriverPtr->card.memorySize = pI830->Offscreen.Size;
+	   
+    if(pI830->EXADriverPtr->card.memorySize >
+       pI830->EXADriverPtr->card.offScreenBase)
+	pI830->EXADriverPtr->card.flags = EXA_OFFSCREEN_PIXMAPS;
+    else {
+	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Not enough video RAM for "
+		   "offscreen memory manager. Xv disabled\n");
+	/* disable Xv here... */
+    }
+
+    pI830->EXADriverPtr->card.pixmapOffsetAlign = 256;
+    pI830->EXADriverPtr->card.pixmapPitchAlign = 64;
+    pI830->EXADriverPtr->card.maxX = 4095;
+    pI830->EXADriverPtr->card.maxY = 4095;
+
+    /* Sync */
+    pI830->EXADriverPtr->accel.WaitMarker = I830EXASync;
+
+    /* Solid fill */
+    pI830->EXADriverPtr->accel.PrepareSolid = I830EXAPrepareSolid;
+    pI830->EXADriverPtr->accel.Solid = I830EXASolid;
+    pI830->EXADriverPtr->accel.DoneSolid = I830EXADoneSolid;
+
+    /* Copy */
+    pI830->EXADriverPtr->accel.PrepareCopy = I830EXAPrepareCopy;
+    pI830->EXADriverPtr->accel.Copy = I830EXACopy;
+    pI830->EXADriverPtr->accel.DoneCopy = I830EXADoneCopy;
+#if 0
+    /* Upload, download to/from Screen */
+    pI830->EXADriverPtr->accel.UploadToScreen = I830EXAUploadToScreen;
+    pI830->EXADriverPtr->accel.DownloadFromScreen = I830EXADownloadFromScreen;
+
+    /* Composite */
+    pI830->EXADriverPtr->accel.CheckComposite = I830EXACheckComposite;
+    pI830->EXADriverPtr->accel.PrepareComposite = I830EXAPrepareComposite;
+    pI830->EXADriverPtr->accel.Composite = I830EXAComposite;
+    pI830->EXADriverPtr->accel.DoneComposite = I830EXADoneComposite;
+#endif
+
+    if(!exaDriverInit(pScreen, pI830->EXADriverPtr)) {
+	pI830->noAccel = TRUE;
+	return FALSE;
+    }
+
+    I830SelectBuffer(pScrn, I830_SELECT_FRONT);
+
+    return TRUE;
+}
diff --git a/src/i830_memory.c b/src/i830_memory.c
index 433aa47..5fbc8cf 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -850,6 +850,30 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, 
 	 }
 	 return FALSE;
       }
+#ifdef I830_USE_EXA
+      size = lineSize * pScrn->virtualY;
+      size = ROUND_TO_PAGE(size);
+
+      if (tileable) {
+	 align = KB(512);
+	 alignflags = ALIGN_BOTH_ENDS;
+      } else {
+	 align = KB(64);
+	 alignflags = 0;
+      }
+
+      alloced = I830AllocVidMem(pScrn, &(pI830->Offscreen),
+				&(pI830->StolenPool), size, align,
+				flags | alignflags |
+				FROM_ANYWHERE | ALLOCATE_AT_BOTTOM);
+      if (alloced < size) {
+	 if (!dryrun) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate "
+		       "offscreen memory.  Not enough VRAM?\n");
+	 }
+	 return FALSE;
+      }
+#endif
    } else {
       long lineSize;
       long extra = 0;
diff --git a/src/i830_video.c b/src/i830_video.c
index 0ae6860..e6f6341 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -1830,8 +1830,6 @@ I830AllocateMemory(ScrnInfoPtr pScrn, FB
    ScreenPtr pScreen;
    FBLinearPtr new_linear = NULL;
 
-   DPRINTF(PFX, "I830AllocateMemory\n");
-
    if (linear) {
       if (linear->size >= size)
 	 return linear;
diff --git a/src/i830_xaa.c b/src/i830_xaa.c
new file mode 100644
index 0000000..68ba4c7
--- /dev/null
+++ b/src/i830_xaa.c
@@ -0,0 +1,636 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "xf86_ansic.h"
+#include "xf86.h"
+#include "xaarop.h"
+#include "i830.h"
+#include "i810_reg.h"
+
+#ifndef DO_SCANLINE_IMAGE_WRITE
+#define DO_SCANLINE_IMAGE_WRITE 0
+#endif
+
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, 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 PRECISION INSIGHT 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.
+
+**************************************************************************/
+
+/*
+ * Reformatted with GNU indent (2.2.8), using the following options:
+ *
+ *    -bad -bap -c41 -cd0 -ncdb -ci6 -cli0 -cp0 -ncs -d0 -di3 -i3 -ip3 -l78
+ *    -lp -npcs -psl -sob -ss -br -ce -sc -hnl
+ *
+ * This provides a good match with the original i810 code and preferred
+ * XFree86 formatting conventions.
+ *
+ * When editing this driver, please follow the existing formatting, and edit
+ * with <TAB> characters expanded at 8-column intervals.
+ */
+
+/*
+ * Authors:
+ *   Keith Whitwell <keith at tungstengraphics.com>
+ *
+ */
+
+/* I830 Accel Functions */
+static void I830SetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
+					   int pattx, int patty,
+					   int fg, int bg, int rop,
+					   unsigned int planemask);
+static void I830SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,
+						 int pattx, int patty,
+						 int x, int y, int w, int h);
+
+static void I830SetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+							   int fg, int bg,
+							   int rop,
+							   unsigned int mask);
+
+static void I830SubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr
+							     pScrn, int x,
+							     int y, int w,
+							     int h,
+							     int skipleft);
+
+static void I830SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno);
+
+#if DO_SCANLINE_IMAGE_WRITE
+static void I830SetupForScanlineImageWrite(ScrnInfoPtr pScrn, int rop,
+					   unsigned int planemask,
+					   int trans_color, int bpp,
+					   int depth);
+static void I830SubsequentScanlineImageWriteRect(ScrnInfoPtr pScrn,
+						 int x, int y, int w, int h,
+						 int skipleft);
+static void I830SubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno);
+#endif
+static void I830RestoreAccelState(ScrnInfoPtr pScrn);
+
+Bool
+I830XAAInit(ScreenPtr pScreen)
+{
+    XAAInfoRecPtr infoPtr;
+    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+    I830Ptr pI830 = I830PTR(pScrn);
+    int i;
+    int width = 0;
+    int nr_buffers = 0;
+    unsigned char *ptr = NULL;
+
+    if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
+	ErrorF("I830XAAInit\n");
+
+    pI830->AccelInfoRec = infoPtr = XAACreateInfoRec();
+    if (!infoPtr)
+	return FALSE;
+
+    pI830->bufferOffset = 0;
+    infoPtr->Flags = LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS | PIXMAP_CACHE;
+
+    /* Use the same sync function as the I830.
+     */
+    infoPtr->Sync = I830Sync;
+
+    /* Everything else is different enough to justify different functions */
+    {
+	infoPtr->SolidFillFlags = NO_PLANEMASK;
+	infoPtr->SetupForSolidFill = I830SetupForSolidFill;
+	infoPtr->SubsequentSolidFillRect = I830SubsequentSolidFillRect;
+    }
+
+    {
+	infoPtr->ScreenToScreenCopyFlags = (NO_PLANEMASK | NO_TRANSPARENCY);
+
+	infoPtr->SetupForScreenToScreenCopy = I830SetupForScreenToScreenCopy;
+	infoPtr->SubsequentScreenToScreenCopy =
+	    I830SubsequentScreenToScreenCopy;
+    }
+
+    {
+	infoPtr->SetupForMono8x8PatternFill = I830SetupForMono8x8PatternFill;
+	infoPtr->SubsequentMono8x8PatternFillRect =
+	    I830SubsequentMono8x8PatternFillRect;
+
+	infoPtr->Mono8x8PatternFillFlags = (HARDWARE_PATTERN_PROGRAMMED_BITS |
+					    HARDWARE_PATTERN_SCREEN_ORIGIN |
+					    HARDWARE_PATTERN_PROGRAMMED_ORIGIN|
+					    BIT_ORDER_IN_BYTE_MSBFIRST |
+					    NO_PLANEMASK);
+
+    }
+
+    /* On the primary screen */
+    if (pI830->init == 0) {
+	if (pI830->Scratch.Size != 0) {
+	    width = ((pScrn->displayWidth + 31) & ~31) / 8;
+	    nr_buffers = pI830->Scratch.Size / width;
+	    ptr = pI830->FbBase + pI830->Scratch.Start;
+	}
+    } else {
+	/* On the secondary screen */
+	I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
+	if (pI8301->Scratch2.Size != 0) {
+	    width = ((pScrn->displayWidth + 31) & ~31) / 8;
+	    nr_buffers = pI8301->Scratch2.Size / width;
+	    /* We have to use the primary screen's FbBase, as that's where
+	     * we allocated Scratch2, so we get the correct pointer */
+	    ptr = pI8301->FbBase + pI8301->Scratch2.Start;
+	}
+    }
+
+    if (nr_buffers) {
+	pI830->NumScanlineColorExpandBuffers = nr_buffers;
+	pI830->ScanlineColorExpandBuffers = (unsigned char **)
+	    xnfcalloc(nr_buffers, sizeof(unsigned char *));
+
+	for (i = 0; i < nr_buffers; i++, ptr += width)
+	    pI830->ScanlineColorExpandBuffers[i] = ptr;
+
+	infoPtr->ScanlineCPUToScreenColorExpandFillFlags =
+	    (NO_PLANEMASK | ROP_NEEDS_SOURCE | BIT_ORDER_IN_BYTE_MSBFIRST);
+
+	infoPtr->ScanlineColorExpandBuffers = (unsigned char **)
+	    xnfcalloc(1, sizeof(unsigned char *));
+	infoPtr->NumScanlineColorExpandBuffers = 1;
+
+	infoPtr->ScanlineColorExpandBuffers[0] =
+	    pI830->ScanlineColorExpandBuffers[0];
+	pI830->nextColorExpandBuf = 0;
+
+	infoPtr->SetupForScanlineCPUToScreenColorExpandFill =
+	    I830SetupForScanlineCPUToScreenColorExpandFill;
+
+	infoPtr->SubsequentScanlineCPUToScreenColorExpandFill =
+	    I830SubsequentScanlineCPUToScreenColorExpandFill;
+
+	infoPtr->SubsequentColorExpandScanline =
+	    I830SubsequentColorExpandScanline;
+
+#if DO_SCANLINE_IMAGE_WRITE
+	infoPtr->NumScanlineImageWriteBuffers = 1;
+	infoPtr->ScanlineImageWriteBuffers =
+	    infoPtr->ScanlineColorExpandBuffers;
+	infoPtr->SetupForScanlineImageWrite = I830SetupForScanlineImageWrite;
+	infoPtr->SubsequentScanlineImageWriteRect =
+	    I830SubsequentScanlineImageWriteRect;
+	infoPtr->SubsequentImageWriteScanline =
+	    I830SubsequentImageWriteScanline;
+	infoPtr->ScanlineImageWriteFlags = NO_GXCOPY |
+	    NO_PLANEMASK |
+	    ROP_NEEDS_SOURCE |
+	    SCANLINE_PAD_DWORD;
+#endif
+    }
+
+    {
+	Bool shared_accel = FALSE;
+	int i;
+
+	for(i = 0; i < pScrn->numEntities; i++) {
+	    if(xf86IsEntityShared(pScrn->entityList[i]))
+		shared_accel = TRUE;
+	}
+	if(shared_accel == TRUE)
+	    infoPtr->RestoreAccelState = I830RestoreAccelState;
+    }
+
+    I830SelectBuffer(pScrn, I830_SELECT_FRONT);
+
+    return XAAInit(pScreen, infoPtr);
+}
+
+void
+I830SetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
+		      unsigned int planemask)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+
+    if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
+	ErrorF("I830SetupForFillRectSolid color: %x rop: %x mask: %x\n",
+	       color, rop, planemask);
+
+    pI830->BR[13] = ((XAAGetPatternROP(rop) << 16) |
+		     (pScrn->displayWidth * pI830->cpp));
+
+    pI830->BR[16] = color;
+
+    switch (pScrn->bitsPerPixel) {
+    case 8:
+	break;
+    case 16:
+	pI830->BR[13] |= (1 << 24);
+	break;
+    case 32:
+	pI830->BR[13] |= ((1 << 25) | (1 << 24));
+	break;
+    }
+}
+
+void
+I830SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+
+    if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
+	ErrorF("I830SubsequentFillRectSolid %d,%d %dx%d\n", x, y, w, h);
+
+    {
+	BEGIN_LP_RING(6);
+
+	if (pScrn->bitsPerPixel == 32) {
+	    OUT_RING(COLOR_BLT_CMD | COLOR_BLT_WRITE_ALPHA |
+		     COLOR_BLT_WRITE_RGB);
+	} else {
+	    OUT_RING(COLOR_BLT_CMD);
+	}
+	OUT_RING(pI830->BR[13]);
+	OUT_RING((h << 16) | (w * pI830->cpp));
+	OUT_RING(pI830->bufferOffset + (y * pScrn->displayWidth + x) *
+		 pI830->cpp);
+	OUT_RING(pI830->BR[16]);
+	OUT_RING(0);
+
+	ADVANCE_LP_RING();
+    }
+}
+
+void
+I830SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, int rop,
+			       unsigned int planemask, int transparency_color)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+
+    if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
+	ErrorF("I830SetupForScreenToScreenCopy %d %d %x %x %d\n",
+	       xdir, ydir, rop, planemask, transparency_color);
+
+    pI830->BR[13] = (pScrn->displayWidth * pI830->cpp);
+    pI830->BR[13] |= XAAGetCopyROP(rop) << 16;
+
+    switch (pScrn->bitsPerPixel) {
+    case 8:
+	break;
+    case 16:
+	pI830->BR[13] |= (1 << 24);
+	break;
+    case 32:
+	pI830->BR[13] |= ((1 << 25) | (1 << 24));
+	break;
+    }
+
+}
+
+void
+I830SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int src_x1, int src_y1,
+				 int dst_x1, int dst_y1, int w, int h)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+    int dst_x2, dst_y2;
+
+    if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
+	ErrorF("I830SubsequentScreenToScreenCopy %d,%d - %d,%d %dx%d\n",
+	       src_x1, src_y1, dst_x1, dst_y1, w, h);
+
+    dst_x2 = dst_x1 + w;
+    dst_y2 = dst_y1 + h;
+
+    {
+	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);
+	} else {
+	    OUT_RING(XY_SRC_COPY_BLT_CMD);
+	}
+	OUT_RING(pI830->BR[13]);
+	OUT_RING((dst_y1 << 16) | (dst_x1 & 0xffff));
+	OUT_RING((dst_y2 << 16) | (dst_x2 & 0xffff));
+	OUT_RING(pI830->bufferOffset);
+	OUT_RING((src_y1 << 16) | (src_x1 & 0xffff));
+	OUT_RING(pI830->BR[13] & 0xFFFF);
+	OUT_RING(pI830->bufferOffset);
+
+	ADVANCE_LP_RING();
+    }
+}
+
+static void
+I830SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int pattx, int patty,
+			       int fg, int bg, int rop,
+			       unsigned int planemask)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+
+    if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
+	ErrorF("I830SetupForMono8x8PatternFill\n");
+
+    pI830->BR[16] = pattx;
+    pI830->BR[17] = patty;
+    pI830->BR[18] = bg;
+    pI830->BR[19] = fg;
+
+    pI830->BR[13] = (pScrn->displayWidth * pI830->cpp);	/* In bytes */
+    pI830->BR[13] |= XAAGetPatternROP(rop) << 16;
+    if (bg == -1)
+	pI830->BR[13] |= (1 << 28);
+
+    switch (pScrn->bitsPerPixel) {
+    case 8:
+	break;
+    case 16:
+	pI830->BR[13] |= (1 << 24);
+	break;
+    case 32:
+	pI830->BR[13] |= ((1 << 25) | (1 << 24));
+	break;
+    }
+
+}
+
+static void
+I830SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int pattx, int patty,
+				     int x, int y, int w, int h)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+    int x1, x2, y1, y2;
+
+    x1 = x;
+    x2 = x + w;
+    y1 = y;
+    y2 = y + h;
+
+    if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
+	ErrorF("I830SubsequentMono8x8PatternFillRect\n");
+
+    {
+	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 |
+		     ((patty << 8) & XY_MONO_PAT_VERT_SEED) |
+		     ((pattx << 12) & XY_MONO_PAT_HORT_SEED));
+	} else {
+	    OUT_RING(XY_MONO_PAT_BLT_CMD |
+		     ((patty << 8) & XY_MONO_PAT_VERT_SEED) |
+		     ((pattx << 12) & XY_MONO_PAT_HORT_SEED));
+	}
+	OUT_RING(pI830->BR[13]);
+	OUT_RING((y1 << 16) | x1);
+	OUT_RING((y2 << 16) | x2);
+	OUT_RING(pI830->bufferOffset);
+	OUT_RING(pI830->BR[18]);		/* bg */
+	OUT_RING(pI830->BR[19]);		/* fg */
+	OUT_RING(pI830->BR[16]);		/* pattern data */
+	OUT_RING(pI830->BR[17]);
+	OUT_RING(0);
+	ADVANCE_LP_RING();
+    }
+}
+
+static void
+I830GetNextScanlineColorExpandBuffer(ScrnInfoPtr pScrn)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+    XAAInfoRecPtr infoPtr = pI830->AccelInfoRec;
+
+    if (pI830->nextColorExpandBuf == pI830->NumScanlineColorExpandBuffers)
+	I830Sync(pScrn);
+
+    infoPtr->ScanlineColorExpandBuffers[0] =
+	pI830->ScanlineColorExpandBuffers[pI830->nextColorExpandBuf];
+
+    if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
+	ErrorF("using color expand buffer %d\n", pI830->nextColorExpandBuf);
+
+    pI830->nextColorExpandBuf++;
+}
+
+static void
+I830SetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+					       int fg, int bg, int rop,
+					       unsigned int planemask)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+
+    if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
+	ErrorF("I830SetupForScanlineScreenToScreenColorExpand %d %d %x %x\n",
+	       fg, bg, rop, planemask);
+
+    /* Fill out register values */
+    pI830->BR[13] = (pScrn->displayWidth * pI830->cpp);
+    pI830->BR[13] |= XAAGetCopyROP(rop) << 16;
+    if (bg == -1)
+	pI830->BR[13] |= (1 << 29);
+
+    switch (pScrn->bitsPerPixel) {
+    case 8:
+	break;
+    case 16:
+	pI830->BR[13] |= (1 << 24);
+	break;
+    case 32:
+	pI830->BR[13] |= ((1 << 25) | (1 << 24));
+	break;
+    }
+
+    pI830->BR[18] = bg;
+    pI830->BR[19] = fg;
+
+    I830GetNextScanlineColorExpandBuffer(pScrn);
+}
+
+static void
+I830SubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+						 int x, int y,
+						 int w, int h, int skipleft)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+
+    if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
+	ErrorF("I830SubsequentScanlineCPUToScreenColorExpandFill "
+	       "%d,%d %dx%x %d\n", x, y, w, h, skipleft);
+
+    /* Fill out register values */
+    pI830->BR[9] = (pI830->bufferOffset +
+		    (y * pScrn->displayWidth + x) * pI830->cpp);
+    pI830->BR[11] = ((1 << 16) | w);
+}
+
+static void
+I830SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+
+    if (pI830->init == 0) {
+	pI830->BR[12] = (pI830->AccelInfoRec->ScanlineColorExpandBuffers[0] -
+			 pI830->FbBase);
+    } else {
+	I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
+
+	/* We have to use the primary screen's FbBase, as that's where
+	 * we allocated Scratch2, so we get the correct pointer */
+	pI830->BR[12] = (pI830->AccelInfoRec->ScanlineColorExpandBuffers[0] -
+			 pI8301->FbBase);
+    }
+
+    if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
+	ErrorF("I830SubsequentColorExpandScanline %d (addr %x)\n",
+	       bufno, pI830->BR[12]);
+
+    {
+	BEGIN_LP_RING(8);
+
+	if (pScrn->bitsPerPixel == 32) {
+	    OUT_RING(XY_MONO_SRC_BLT_CMD | XY_MONO_SRC_BLT_WRITE_ALPHA |
+		     XY_MONO_SRC_BLT_WRITE_RGB);
+	} else {
+	    OUT_RING(XY_MONO_SRC_BLT_CMD);
+	}
+	OUT_RING(pI830->BR[13]);
+	OUT_RING(0);			/* x1 = 0, y1 = 0 */
+	OUT_RING(pI830->BR[11]);		/* x2 = w, y2 = 1 */
+	OUT_RING(pI830->BR[9]);		/* dst addr */
+	OUT_RING(pI830->BR[12]);		/* src addr */
+	OUT_RING(pI830->BR[18]);		/* bg */
+	OUT_RING(pI830->BR[19]);		/* fg */
+
+	ADVANCE_LP_RING();
+    }
+
+    /* Advance to next scanline.
+     */
+    pI830->BR[9] += pScrn->displayWidth * pI830->cpp;
+    I830GetNextScanlineColorExpandBuffer(pScrn);
+}
+
+#if DO_SCANLINE_IMAGE_WRITE
+static void
+I830SetupForScanlineImageWrite(ScrnInfoPtr pScrn, int rop,
+			       unsigned int planemask, int trans_color,
+			       int bpp, int depth)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+
+    if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
+	ErrorF("I830SetupForScanlineImageWrite %x %x\n", rop, planemask);
+
+    /* Fill out register values */
+    pI830->BR[13] = (pScrn->displayWidth * pI830->cpp);
+    pI830->BR[13] |= XAAGetCopyROP(rop) << 16;
+
+    switch (pScrn->bitsPerPixel) {
+    case 8:
+	break;
+    case 16:
+	pI830->BR[13] |= (1 << 24);
+	break;
+    case 32:
+	pI830->BR[13] |= ((1 << 25) | (1 << 24));
+	break;
+    }
+
+    I830GetNextScanlineColorExpandBuffer(pScrn);
+}
+
+static void
+I830SubsequentScanlineImageWriteRect(ScrnInfoPtr pScrn, int x, int y,
+				     int w, int h, int skipleft)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+
+    if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
+	ErrorF("I830SubsequentScanlineImageWriteRect "
+	       "%d,%d %dx%x %d\n", x, y, w, h, skipleft);
+
+    /* Fill out register values */
+    pI830->BR[9] = (pI830->bufferOffset +
+		    (y * pScrn->displayWidth + x) * pI830->cpp);
+    pI830->BR[11] = ((1 << 16) | w);
+}
+
+static void
+I830SubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+
+    if (pI830->init == 0) {
+	pI830->BR[12] = (pI830->AccelInfoRec->ScanlineColorExpandBuffers[0] -
+			 pI830->FbBase);
+    } else {
+	I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
+
+	/* We have to use the primary screen's FbBase, as that's where
+	 * we allocated Scratch2, so we get the correct pointer */
+	pI830->BR[12] = (pI830->AccelInfoRec->ScanlineColorExpandBuffers[0] -
+			 pI8301->FbBase);
+    }
+
+    if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
+	ErrorF("I830SubsequentImageWriteScanline %d (addr %x)\n",
+	       bufno, pI830->BR[12]);
+
+    {
+	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);
+	} else {
+	    OUT_RING(XY_SRC_COPY_BLT_CMD);
+	}
+	OUT_RING(pI830->BR[13]);
+	OUT_RING(0);			/* x1 = 0, y1 = 0 */
+	OUT_RING(pI830->BR[11]);		/* x2 = w, y2 = 1 */
+	OUT_RING(pI830->BR[9]);		/* dst addr */
+	OUT_RING(0);			/* source origin (0,0) */
+	OUT_RING(pI830->BR[11] & 0xffff);	/* source pitch */
+	OUT_RING(pI830->BR[12]);		/* src addr */
+
+	ADVANCE_LP_RING();
+    }
+
+    /* Advance to next scanline.
+     */
+    pI830->BR[9] += pScrn->displayWidth * pI830->cpp;
+    I830GetNextScanlineColorExpandBuffer(pScrn);
+}
+#endif /* DO_SCANLINE_IMAGE_WRITE */
+/* Support for multiscreen */
+
+static void
+I830RestoreAccelState(ScrnInfoPtr pScrn)
+{
+#if 0
+   /* might be needed, but everything is on a ring, so I don't think so */
+   I830Sync(pScrn);
+#endif
+}
+



More information about the xorg-commit mailing list