xf86-video-intel: Branch 'xf86-video-intel-2.4-branch' - 41 commits - configure.ac src/common.h src/i810_driver.c src/i830_bios.c src/i830_bios.h src/i830_debug.c src/i830_display.c src/i830_driver.c src/i830.h src/i830_hdmi.c src/i830_hwmc.c src/i830_hwmc.h src/i830_lvds.c src/i830_memory.c src/i830_quirks.c src/i830_tv.c src/i830_video.c src/i830_video.h src/i915_hwmc.c src/i915_hwmc.h src/i915_video.c src/i965_render.c src/i965_video.c src/Makefile.am src/xvmc/I810XvMC.c src/xvmc/i915_structs.h src/xvmc/i915_xvmc.c src/xvmc/intel_xvmc.c src/xvmc/intel_xvmc_dump.c src/xvmc/intel_xvmc.h

Zhenyu Wang zhen at kemper.freedesktop.org
Tue Jul 22 01:55:35 PDT 2008


 configure.ac               |    2 
 src/Makefile.am            |   12 
 src/common.h               |   21 
 src/i810_driver.c          |    8 
 src/i830.h                 |    5 
 src/i830_bios.c            |   90 ++
 src/i830_bios.h            |   93 +++
 src/i830_debug.c           |   20 
 src/i830_display.c         |  113 +++
 src/i830_driver.c          |   89 --
 src/i830_hdmi.c            |    2 
 src/i830_hwmc.c            |    5 
 src/i830_hwmc.h            |    7 
 src/i830_lvds.c            |   13 
 src/i830_memory.c          |    4 
 src/i830_quirks.c          |   25 
 src/i830_tv.c              |    5 
 src/i830_video.c           |   71 +-
 src/i830_video.h           |    2 
 src/i915_hwmc.c            |   35 -
 src/i915_hwmc.h            |    1 
 src/i915_video.c           |   10 
 src/i965_render.c          |   75 +-
 src/i965_video.c           |    2 
 src/xvmc/I810XvMC.c        |    2 
 src/xvmc/i915_structs.h    |   81 ++
 src/xvmc/i915_xvmc.c       | 1385 +++++++++++++++++++++------------------------
 src/xvmc/intel_xvmc.c      |   10 
 src/xvmc/intel_xvmc.h      |    3 
 src/xvmc/intel_xvmc_dump.c |   31 -
 30 files changed, 1289 insertions(+), 933 deletions(-)

New commits:
commit b9250913ab57ecade1c3011415c666e8516fce47
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Tue Jul 22 15:29:34 2008 +0800

    Bug #16801: fix X crash when NoAccel on 965
    (cherry picked from commit fd060ce89d86f6e8ff742d5b287abe8ecea32927)

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 5a06079..4bb9b81 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -3307,7 +3307,7 @@ I830LeaveVT(int scrnIndex, int flags)
    }
 #endif /* XF86DRI_MM */
 
-   if (IS_I965G(pI830))
+   if (pI830->useEXA && IS_I965G(pI830))
       gen4_render_state_cleanup(pScrn);
 
    if (pI830->AccelInfoRec)
@@ -3356,7 +3356,7 @@ I830EnterVT(int scrnIndex, int flags)
    /* Update the screen pixmap in case the buffer moved */
    i830_update_front_offset(pScrn);
 
-   if (IS_I965G(pI830))
+   if (pI830->useEXA && IS_I965G(pI830))
       gen4_render_state_init(pScrn);
 
    if (i830_check_error_state(pScrn)) {
commit 0403234dd1cdf4aa02709c1fbd815f002e1ace63
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Tue Jul 22 15:14:14 2008 +0800

    only check pipe underrun if vtSema is true.
    (cherry picked from commit 577c4d1a0c753fb46d43be05a9781d2e204fac45)

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 390b5e7..5a06079 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -2512,16 +2512,18 @@ I830BlockHandler(int i,
      * (except for mode setting, where it may occur naturally).
      * Check & ack the condition.
      */
-    if (xf86_config->crtc[0]->enabled &&
-	    (INREG(PIPEASTAT) & FIFO_UNDERRUN)) {
+    if (pScrn->vtSema) {
+	if (xf86_config->crtc[0]->enabled &&
+		(INREG(PIPEASTAT) & FIFO_UNDERRUN)) {
 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "underrun on pipe A!\n");
 	    OUTREG(PIPEASTAT, INREG(PIPEASTAT) | FIFO_UNDERRUN);
-    }
-    if (xf86_config->num_crtc > 1 &&
-	    xf86_config->crtc[1]->enabled &&
-	    (INREG(PIPEBSTAT) & FIFO_UNDERRUN)) {
+	}
+	if (xf86_config->num_crtc > 1 &&
+		xf86_config->crtc[1]->enabled &&
+		(INREG(PIPEBSTAT) & FIFO_UNDERRUN)) {
 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "underrun on pipe B!\n");
 	    OUTREG(PIPEBSTAT, INREG(PIPEBSTAT) | FIFO_UNDERRUN);
+	}
     }
 
     I830VideoBlockHandler(i, blockData, pTimeout, pReadmask);
commit e7533a253178a867a9ad37f5fd3789b21ff38162
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Tue Jul 22 15:08:57 2008 +0800

    SSC is LVDS only
    
    Fix regression on my 855GM for VGA output.
    (cherry picked from commit 04bbed2248e3e8f86efd64225abf2db8eb552653)

diff --git a/src/i830_display.c b/src/i830_display.c
index 69bf7f7..6176447 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -1249,7 +1249,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
 	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "clone detected, disabling SSC\n");
 
     /* Don't use SSC when cloned */
-    if (pI830->lvds_use_ssc && num_outputs < 2) {
+    if (is_lvds && pI830->lvds_use_ssc && num_outputs < 2) {
 	refclk = pI830->lvds_ssc_freq * 1000;
 	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 		   "using SSC reference clock of %d MHz\n", refclk / 1000);
commit 7f040c63bbfef0b577eeac2052c1951bdbfa3386
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Tue Jul 22 10:51:01 2008 +0800

    Check underrun on enabled pipe
    (cherry picked from commit 7defa4f1f0eba82f39e74f96d2ad7ed2481b537e)

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 84aedba..390b5e7 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -2487,6 +2487,7 @@ I830BlockHandler(int i,
     ScreenPtr pScreen = screenInfo.screens[i];
     ScrnInfoPtr pScrn = xf86Screens[i];
     I830Ptr pI830 = I830PTR(pScrn);
+    xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
 
     pScreen->BlockHandler = pI830->BlockHandler;
 
@@ -2511,11 +2512,14 @@ I830BlockHandler(int i,
      * (except for mode setting, where it may occur naturally).
      * Check & ack the condition.
      */
-    if (INREG(PIPEASTAT) & FIFO_UNDERRUN) {
+    if (xf86_config->crtc[0]->enabled &&
+	    (INREG(PIPEASTAT) & FIFO_UNDERRUN)) {
 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "underrun on pipe A!\n");
 	    OUTREG(PIPEASTAT, INREG(PIPEASTAT) | FIFO_UNDERRUN);
     }
-    if (INREG(PIPEBSTAT) & FIFO_UNDERRUN) {
+    if (xf86_config->num_crtc > 1 &&
+	    xf86_config->crtc[1]->enabled &&
+	    (INREG(PIPEBSTAT) & FIFO_UNDERRUN)) {
 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "underrun on pipe B!\n");
 	    OUTREG(PIPEBSTAT, INREG(PIPEBSTAT) | FIFO_UNDERRUN);
     }
commit 06c5a72a496fabace408fbb8733f299a408d1c7c
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Tue Jul 22 09:51:54 2008 +0800

    Thinkpad R60e TV quirk via DMI info
    (cherry picked from commit b7765b0837af4cc80f1257ba04495140ef5d536e)

diff --git a/src/i830_quirks.c b/src/i830_quirks.c
index 164a70c..5ae2898 100644
--- a/src/i830_quirks.c
+++ b/src/i830_quirks.c
@@ -203,7 +203,8 @@ static void quirk_lenovo_tv_dmi (I830Ptr pI830)
 	ErrorF("Failed to load DMI info, X60 TV quirk not applied.\n");
 	return;
     }
-    if (!strncmp(i830_dmi_data[bios_version], "7B", 2))
+    if (!strncmp(i830_dmi_data[bios_version], "7B", 2) || /* X60, X60s */
+	    !strncmp(i830_dmi_data[bios_version], "7E", 2)) /* R60e */
 	pI830->quirk_flag |= QUIRK_IGNORE_TV;
 }
 
commit 13959ee3984d5f34c976287c8f5406393ceacc30
Author: Jesse Barnes <jbarnes at hobbes.lan>
Date:   Mon Jul 21 11:48:38 2008 -0700

    Add no LVDS quirk for Transtec Senyo 610 mini PC
    
    Fixes FDO #16757.
    (cherry picked from commit ed0fbd016b8fbcf01eddfd17fd25e745e7af2ba4)

diff --git a/src/i830_quirks.c b/src/i830_quirks.c
index 3becf35..164a70c 100644
--- a/src/i830_quirks.c
+++ b/src/i830_quirks.c
@@ -222,6 +222,9 @@ static i830_quirk i830_quirk_list[] = {
     /* Apple Mac mini has no lvds, but macbook pro does */
     { PCI_CHIP_I945_GM, 0x8086, 0x7270, quirk_mac_mini },
 
+    /* Transtec Senyo 610 mini pc */
+    { PCI_CHIP_I965_GM, 0x1509, 0x2f15, quirk_ignore_lvds },
+
     /* Clevo M720R has no tv output */
     { PCI_CHIP_I965_GM, 0x1558, 0x0721, quirk_ignore_tv },
 
commit fe4e1376dbb143665d7d98b04cd9ee2309911b54
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Jul 18 14:50:08 2008 -0700

    Fix distcheck.
    (cherry picked from commit 62a037b0585d6ecb43daac9d4eb0927a4618a367)

diff --git a/src/Makefile.am b/src/Makefile.am
index 1e4ad28..594416d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -139,7 +139,6 @@ INTEL_G4A =				\
 	exa_wm_src_sample_argb.g4a 	\
 	exa_wm_src_sample_a.g4a 	\
 	exa_wm_src_sample_planar.g4a 	\
-	exa_wm_src_data.g4a		\
 	exa_wm_mask_affine.g4a 		\
 	exa_wm_mask_projective.g4a 	\
 	exa_wm_mask_sample_argb.g4a 	\
@@ -148,6 +147,7 @@ INTEL_G4A =				\
 	exa_wm_ca.g4a			\
 	exa_wm_ca_srcalpha.g4a		\
 	exa_wm_write.g4a 		\
+	exa_wm_yuv_rgb.g4a		\
 	exa_wm_xy.g4a
 
 INTEL_G4I =				\
@@ -166,7 +166,6 @@ INTEL_G4B = 				\
 	exa_wm_src_sample_argb.g4b 	\
 	exa_wm_src_sample_a.g4b 	\
 	exa_wm_src_sample_planar.g4b 	\
-	exa_wm_src_data.g4b		\
 	exa_wm_mask_affine.g4b 		\
 	exa_wm_mask_projective.g4b 	\
 	exa_wm_mask_sample_argb.g4b 	\
@@ -175,6 +174,7 @@ INTEL_G4B = 				\
 	exa_wm_ca.g4b			\
 	exa_wm_ca_srcalpha.g4b		\
 	exa_wm_write.g4b 		\
+	exa_wm_yuv_rgb.g4b		\
 	exa_wm_xy.g4b
 	
 EXTRA_DIST = 		\
commit c5df5912025b432476d9c8bcafd669974ec296c7
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Jul 18 14:56:18 2008 -0700

    Fix uninitialized-use warning in i830_debug.c ring dumping.
    (cherry picked from commit 3cbfc6c76bcd2bc9194a944092f6ce0881ff9da2)

diff --git a/src/i830_debug.c b/src/i830_debug.c
index 00f18e5..856e31a 100644
--- a/src/i830_debug.c
+++ b/src/i830_debug.c
@@ -1308,8 +1308,6 @@ i830_valid_command (uint32_t cmd)
 	if (!mi_cmds[opcode])
 	    return -1;
 	break;
-    case 1:
-	break;
     case 2:			    /* 2D */
 	count = (cmd & 0x1f) + 2;
 	opcode = (cmd >> 22) & 0x7f;
commit 139659f722c20525bb24879528dc90e0e09af49f
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Jul 18 14:53:26 2008 -0700

    Get prototype for i830_bios_get_tv().
    (cherry picked from commit 1b1c4975768f63ed0f3933ec384d24c324a383b3)

diff --git a/src/i830_tv.c b/src/i830_tv.c
index 651f77b..1022c46 100644
--- a/src/i830_tv.c
+++ b/src/i830_tv.c
@@ -36,6 +36,7 @@
 #include "xf86.h"
 #include "i830.h"
 #include "i830_display.h"
+#include "i830_bios.h"
 #include "X11/Xatom.h"
 #include <string.h>
 
commit 37848925c4557385f154443ffbb917a8203506f8
Author: Jesse Barnes <jbarnes at nietzche.virtuousgeek.org>
Date:   Thu Jul 17 14:41:51 2008 -0700

    Choose a split for DSPARB based on the configured modes for both planes.
    
    Previously, we were attempting to give both planes equal space in the FIFO
    to be fair.  However, larger modes require more fifo space, so split it based
    on the relative HDisplay of the modes.  This should resolve some fifo underrun
    issues with differently-sized displays, or single large ones.
    
    Bug #16169.
    (cherry picked from commit b8ca1c747a679c931267363639fc0bc690cae2d6)

diff --git a/src/i830_display.c b/src/i830_display.c
index 3967b69..69bf7f7 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -1093,6 +1093,79 @@ i830_panel_fitter_pipe(I830Ptr pI830)
 }
 
 /**
+ * Sets up the DSPARB register to split the display fifo appropriately between
+ * the display planes.
+ *
+ * Adjusting this register requires that the planes be off.
+ */
+static void
+i830_update_dsparb(ScrnInfoPtr pScrn)
+{
+   xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+   I830Ptr pI830 = I830PTR(pScrn);
+   uint32_t dspacntr, dspbcntr;
+   int total_hdisplay = 0, planea_hdisplay = 0, planeb_hdisplay = 0;
+   int fifo_entries = 0, planea_entries = 0, planeb_entries = 0, i;
+
+   dspacntr = INREG(DSPACNTR);
+   dspbcntr = INREG(DSPBCNTR);
+
+   /* Disable planes since DSPARB can only be updated when they're
+    * off.
+    */
+   OUTREG(DSPACNTR, dspacntr & ~DISPLAY_PLANE_ENABLE);
+   OUTREG(DSPBCNTR, dspbcntr & ~DISPLAY_PLANE_ENABLE);
+   i830WaitForVblank(pScrn);
+
+   /*
+    * FIFO entries will be split based on programmed modes
+    */
+   if (IS_I965GM(pI830) || IS_GM45(pI830))
+       fifo_entries = 127;
+   else if (IS_I9XX(pI830))
+       fifo_entries = 95;
+   else if (IS_MOBILE(pI830)) {
+       fifo_entries = 255;
+   } else {
+	/* The 845/865 only have a AEND field.  Though the field size would
+	* allow 128 entries, the 865 rendered the cursor wrong then.
+	* The BIOS set it up for 96.
+	*/
+	fifo_entries = 95;
+   }
+
+   for (i = 0; i < xf86_config->num_crtc; i++) {
+      xf86CrtcPtr crtc = xf86_config->crtc[i];
+      I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
+      if (crtc->enabled) {
+	  total_hdisplay += crtc->mode.HDisplay;
+	  if (intel_crtc->plane == 0)
+	      planea_hdisplay = crtc->mode.HDisplay;
+	  else
+	      planeb_hdisplay = crtc->mode.HDisplay;
+      }
+   }
+
+   planea_entries = fifo_entries * planea_hdisplay / total_hdisplay;
+   planeb_entries = fifo_entries * planeb_hdisplay / total_hdisplay;
+
+   if (IS_I9XX(pI830))
+       OUTREG(DSPARB,
+	      ((planea_entries + planeb_entries) << DSPARB_CSTART_SHIFT) |
+	      (planea_entries << DSPARB_BSTART_SHIFT));
+   else if (IS_MOBILE(pI830))
+       OUTREG(DSPARB,
+	      ((planea_entries + planeb_entries) << DSPARB_BEND_SHIFT) |
+	      (planea_entries << DSPARB_AEND_SHIFT));
+   else
+       OUTREG(DSPARB, planea_entries << DSPARB_AEND_SHIFT);
+
+   OUTREG(DSPACNTR, dspacntr);
+   OUTREG(DSPBCNTR, dspbcntr);
+   i830WaitForVblank(pScrn);
+}
+
+/**
  * Sets up registers for the given mode/adjusted_mode pair.
  *
  * The clocks, CRTCs and outputs attached to this CRTC must be off.
@@ -1437,6 +1510,8 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
     
     i830WaitForVblank(pScrn);
 
+    i830_update_dsparb(pScrn);
+
     /* Clear any FIFO underrun status that may have occurred normally */
     OUTREG(pipestat_reg, INREG(pipestat_reg) | FIFO_UNDERRUN);
 }
diff --git a/src/i830_driver.c b/src/i830_driver.c
index e29dd10..84aedba 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -1954,59 +1954,6 @@ i830_refresh_ring(ScrnInfoPtr pScrn)
    i830MarkSync(pScrn);
 }
 
-/**
- * Sets up the DSPARB register to split the display fifo appropriately between
- * the display planes.
- *
- * Adjusting this register requires that the planes be off, thus as a side
- * effect they are disabled by this function.
- */
-static void
-i830_set_dsparb(ScrnInfoPtr pScrn)
-{
-   xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-   I830Ptr pI830 = I830PTR(pScrn);
-   int i;
-
-   /* Disable outputs & pipes since DSPARB can only be updated when they're
-    * off.
-    */
-   for (i = 0; i < xf86_config->num_output; i++) {
-       xf86OutputPtr   output = xf86_config->output[i];
-       output->funcs->dpms(output, DPMSModeOff);
-   }
-   i830WaitForVblank(pScrn);
-   for (i = 0; i < xf86_config->num_crtc; i++) {
-       xf86CrtcPtr crtc = xf86_config->crtc[i];
-       crtc->funcs->dpms(crtc, DPMSModeOff);
-   }
-   i830WaitForVblank(pScrn);
-
-   /* Fixup FIFO defaults:
-    * we don't use plane C at all so we can allocate all but one of the 96
-    * FIFO RAM entries equally between planes A and B.
-    */
-   if (IS_I9XX(pI830)) {
-       if (IS_I965GM(pI830) || IS_GM45(pI830))
-	   OUTREG(DSPARB, (127 << DSPARB_CSTART_SHIFT) |
-		  (64 << DSPARB_BSTART_SHIFT));
-       else
-	   OUTREG(DSPARB, (95 << DSPARB_CSTART_SHIFT) |
-		  (48 << DSPARB_BSTART_SHIFT));
-   } else {
-       if (IS_MOBILE(pI830)) {
-	   /* The 830 has 288 entries, and the 855 has 256. */
-	   OUTREG(DSPARB, 254 << DSPARB_BEND_SHIFT | 128 << DSPARB_AEND_SHIFT);
-       } else {
-	   /* The 845/865 only have a AEND field.  Though the field size would
-	    * allow 128 entries, the 865 rendered the cursor wrong then.
-	    * The BIOS set it up for 96.
-	    */
-	   OUTREG(DSPARB, 95 << DSPARB_AEND_SHIFT);
-       }
-   }
-}
-
 enum pipe {
     PIPE_A = 0,
     PIPE_B,
@@ -3416,11 +3363,6 @@ I830EnterVT(int scrnIndex, int flags)
    if (!pI830->SWCursor)
       I830InitHWCursor(pScrn);
 
-   /* Set the DSPARB register.  This disables the outputs, which is about to
-    * happen (likely) in xf86SetDesiredModes anyway.
-    */
-   i830_set_dsparb(pScrn);
-
    /* Tell the BIOS that we're in control of mode setting now. */
    i830_init_bios_control(pScrn);
 
commit 91cbb5b8ad1fbc22dd77c0329fc3962b1ca99b9e
Author: Jesse Barnes <jbarnes at hobbes.lan>
Date:   Thu Jul 17 12:30:57 2008 -0700

    Don't disable pipe A on 855 chips
    
    It needs to stay enabled or we may see hangs when trying to re-enable it (say
    at VT switch time).
    
    Fixes FDO bug #15168.
    (cherry picked from commit b37a2a8ca82279468e3806dcf77d5fa7bdd0e874)

diff --git a/src/i830_quirks.c b/src/i830_quirks.c
index 5eb01be..3becf35 100644
--- a/src/i830_quirks.c
+++ b/src/i830_quirks.c
@@ -309,6 +309,9 @@ static i830_quirk i830_quirk_list[] = {
     /* Littlebit Sepia X35 (rebranded Asus Z37E) (See LP: #201257) */
     { PCI_CHIP_I965_GM, 0x1043, 0x8265, quirk_ignore_tv },
 
+    /* 855 & before need to leave pipe A & dpll A up */
+    { PCI_CHIP_I855_GM, SUBSYS_ANY, SUBSYS_ANY, quirk_pipea_force },
+
     { 0, 0, 0, NULL },
 };
 
@@ -325,9 +328,10 @@ void i830_fixup_devices(ScrnInfoPtr scrn)
 
     while (p && p->chipType != 0) {
 	if (DEVICE_ID(pI830->PciInfo) == p->chipType &&
-		SUBVENDOR_ID(pI830->PciInfo) == p->subsysVendor &&
-		(SUBSYS_ID(pI830->PciInfo) == p->subsysCard ||
-		 p->subsysCard == SUBSYS_ANY))
+	    (SUBVENDOR_ID(pI830->PciInfo) == p->subsysVendor ||
+	     p->subsysVendor == SUBSYS_ANY) &&
+	    (SUBSYS_ID(pI830->PciInfo) == p->subsysCard ||
+	     p->subsysCard == SUBSYS_ANY))
 	    p->hook(pI830);
 	++p;
     }
commit a0e7b79b34940d646949512bd24c96372031888d
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Wed Jul 16 10:45:28 2008 +0800

    Only initialize integrated TV encoder for mobile chips
    (cherry picked from commit c4565a9811487402d899d0933cc63e27ffe1ff08)

diff --git a/src/i830_driver.c b/src/i830_driver.c
index c880833..e29dd10 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -940,7 +940,7 @@ I830SetupOutputs(ScrnInfoPtr pScrn)
    } else {
       i830_dvo_init(pScrn);
    }
-   if (IS_I9XX(pI830) && !IS_I915G(pI830))
+   if (IS_I9XX(pI830) && IS_MOBILE(pI830))
       i830_tv_init(pScrn);
    
    for (o = 0; o < config->num_output; o++)
commit a4845dcdcb9b7becf8e47d3a781ecce74527d7c0
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Tue Jul 15 13:35:21 2008 +0800

    xvmc: use vector based structure
    
    This is more clear to read MV components.
    (cherry picked from commit bca316863b79148b2f51a97d58b94e52ba3eae9f)

diff --git a/src/xvmc/i915_xvmc.c b/src/xvmc/i915_xvmc.c
index 27d1380..c32073a 100644
--- a/src/xvmc/i915_xvmc.c
+++ b/src/xvmc/i915_xvmc.c
@@ -39,9 +39,9 @@
                                  SIZE_Y420(surface->width, surface->height))
 
 typedef union {
-    short s[4];
-    uint  u[2];
-} su_t;
+    int16_t component[2];
+    int32_t v;
+} vector_t;
 
 #if 0
 static int findOverlap(unsigned int width, unsigned int height,
@@ -835,10 +835,7 @@ static void i915_mc_mpeg_macroblock_0mv(XvMCContext *context, XvMCMacroBlock *mb
 static void i915_mc_mpeg_macroblock_1fbmv(XvMCContext *context, XvMCMacroBlock *mb)
 {
     struct i915_3dmpeg_macroblock_1fbmv macroblock_1fbmv;
-
-    /* Motion Vectors */
-    su_t fmv;
-    su_t bmv;
+    vector_t mv0[2];
 
     /* 3DMPEG_MACROBLOCK(1fbmv) */
     memset(&macroblock_1fbmv, 0, sizeof(macroblock_1fbmv));
@@ -859,13 +856,13 @@ static void i915_mc_mpeg_macroblock_1fbmv(XvMCContext *context, XvMCMacroBlock *
     macroblock_1fbmv.header.dw1.coded_block_pattern = mb->coded_block_pattern;
     macroblock_1fbmv.header.dw1.skipped_macroblocks = 0;
 
-    fmv.s[0] = mb->PMV[0][0][0];
-    fmv.s[1] = mb->PMV[0][0][1];
-    bmv.s[0] = mb->PMV[0][1][0];
-    bmv.s[1] = mb->PMV[0][1][1];
+    mv0[0].component[0] = mb->PMV[0][0][0];
+    mv0[0].component[1] = mb->PMV[0][0][1];
+    mv0[1].component[0] = mb->PMV[0][1][0];
+    mv0[1].component[1] = mb->PMV[0][1][1];
 
-    macroblock_1fbmv.dw2 = fmv.u[0];
-    macroblock_1fbmv.dw3 = bmv.u[0];
+    macroblock_1fbmv.dw2 = mv0[0].v;
+    macroblock_1fbmv.dw3 = mv0[1].v;
 
     intelBatchbufferData(&macroblock_1fbmv, sizeof(macroblock_1fbmv), 0);
 }
@@ -873,10 +870,8 @@ static void i915_mc_mpeg_macroblock_1fbmv(XvMCContext *context, XvMCMacroBlock *
 static void i915_mc_mpeg_macroblock_2fbmv(XvMCContext *context, XvMCMacroBlock *mb, unsigned int ps)
 {
     struct i915_3dmpeg_macroblock_2fbmv macroblock_2fbmv;
-
-    /* Motion Vectors */
-    su_t fmv;
-    su_t bmv;
+    vector_t mv0[2];
+    vector_t mv1[2];
 
     /* 3DMPEG_MACROBLOCK(2fbmv) */
     memset(&macroblock_2fbmv, 0, sizeof(macroblock_2fbmv));
@@ -897,41 +892,33 @@ static void i915_mc_mpeg_macroblock_2fbmv(XvMCContext *context, XvMCMacroBlock *
     macroblock_2fbmv.header.dw1.coded_block_pattern = mb->coded_block_pattern;
     macroblock_2fbmv.header.dw1.skipped_macroblocks = 0;
 
-    fmv.s[0] = mb->PMV[0][0][0];
-    fmv.s[1] = mb->PMV[0][0][1];
-    fmv.s[2] = mb->PMV[1][0][0];
-    fmv.s[3] = mb->PMV[1][0][1];
-    bmv.s[0] = mb->PMV[0][1][0];
-    bmv.s[1] = mb->PMV[0][1][1];
-    bmv.s[2] = mb->PMV[1][1][0];
-    bmv.s[3] = mb->PMV[1][1][1];
+    mv0[0].component[0] = mb->PMV[0][0][0];
+    mv0[0].component[1] = mb->PMV[0][0][1];
+    mv0[1].component[0] = mb->PMV[0][1][0];
+    mv0[1].component[1] = mb->PMV[0][1][1];
+    mv1[0].component[0] = mb->PMV[1][0][0];
+    mv1[0].component[1] = mb->PMV[1][0][1];
+    mv1[1].component[0] = mb->PMV[1][1][0];
+    mv1[1].component[1] = mb->PMV[1][1][1];
 
     if ((ps & XVMC_FRAME_PICTURE) == XVMC_FRAME_PICTURE) {
         if ((mb->motion_type & 3) == XVMC_PREDICTION_FIELD) {
-            fmv.s[0] = mb->PMV[0][0][0];
-            fmv.s[1] = mb->PMV[0][0][1] >> 1;
-            fmv.s[2] = mb->PMV[1][0][0];
-            fmv.s[3] = mb->PMV[1][0][1] >> 1;
-            bmv.s[0] = mb->PMV[0][1][0];
-            bmv.s[1] = mb->PMV[0][1][1] >> 1;
-            bmv.s[2] = mb->PMV[1][1][0];
-            bmv.s[3] = mb->PMV[1][1][1] >> 1;
+            mv0[0].component[1] = mb->PMV[0][0][1] >> 1;
+            mv0[1].component[1] = mb->PMV[0][1][1] >> 1;
+            mv1[0].component[1] = mb->PMV[1][0][1] >> 1;
+            mv1[1].component[1] = mb->PMV[1][1][1] >> 1;
         } else if ((mb->motion_type & 3) == XVMC_PREDICTION_DUAL_PRIME) {
-            fmv.s[0] = mb->PMV[0][0][0];
-            fmv.s[1] = mb->PMV[0][0][1] >> 1;
-            fmv.s[2] = mb->PMV[0][0][0];
-            fmv.s[3] = mb->PMV[0][0][1] >> 1;  // MPEG2 MV[0][1] isn't used
-            bmv.s[0] = mb->PMV[1][0][0];
-            bmv.s[1] = mb->PMV[1][0][1] >> 1;
-            bmv.s[2] = mb->PMV[1][1][0];
-            bmv.s[3] = mb->PMV[1][1][1] >> 1;
+            mv0[0].component[1] = mb->PMV[0][0][1] >> 1;
+            mv0[1].component[1] = mb->PMV[0][1][1] >> 1;  // MPEG2 MV[0][1] isn't used
+            mv1[0].component[1] = mb->PMV[1][0][1] >> 1;
+            mv1[1].component[1] = mb->PMV[1][1][1] >> 1;
         }
     }
 
-    macroblock_2fbmv.dw2 = fmv.u[0];
-    macroblock_2fbmv.dw3 = bmv.u[0];
-    macroblock_2fbmv.dw4 = fmv.u[1];
-    macroblock_2fbmv.dw5 = bmv.u[1];
+    macroblock_2fbmv.dw2 = mv0[0].v;
+    macroblock_2fbmv.dw3 = mv0[1].v;
+    macroblock_2fbmv.dw4 = mv1[0].v;
+    macroblock_2fbmv.dw5 = mv1[1].v;
 
     intelBatchbufferData(&macroblock_2fbmv, sizeof(macroblock_2fbmv), 0);
 }
commit 607a68a81d28d49ebcb0f6a8b9267f1d85d7bac5
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Tue Jul 15 13:29:33 2008 +0800

    move FBC register dump out of display registers
    
    This makes it easier to read.
    (cherry picked from commit 0c67219d0e6cfc858af2eb375c2f9473d0f6db60)

diff --git a/src/i830_debug.c b/src/i830_debug.c
index 8830050..00f18e5 100644
--- a/src/i830_debug.c
+++ b/src/i830_debug.c
@@ -537,15 +537,6 @@ static struct i830SnapshotRec {
     DEFINEREG2(PIPEASRC, i830_debug_yxminus1),
     DEFINEREG2(PIPEASTAT, i830_debug_pipestat),
 
-    DEFINEREG(FBC_CFB_BASE),
-    DEFINEREG(FBC_LL_BASE),
-    DEFINEREG(FBC_CONTROL),
-    DEFINEREG(FBC_COMMAND),
-    DEFINEREG(FBC_STATUS),
-    DEFINEREG(FBC_CONTROL2),
-    DEFINEREG(FBC_FENCE_OFF),
-    DEFINEREG(FBC_MOD_NUM),
-
     DEFINEREG2(FPA0, i830_debug_fp),
     DEFINEREG2(FPA1, i830_debug_fp),
     DEFINEREG2(DPLL_A, i830_debug_dpll),
@@ -623,6 +614,15 @@ static struct i830SnapshotRec {
     DEFINEREG(TV_H_CHROMA_0),
     DEFINEREG(TV_H_CHROMA_59),
 
+    DEFINEREG(FBC_CFB_BASE),
+    DEFINEREG(FBC_LL_BASE),
+    DEFINEREG(FBC_CONTROL),
+    DEFINEREG(FBC_COMMAND),
+    DEFINEREG(FBC_STATUS),
+    DEFINEREG(FBC_CONTROL2),
+    DEFINEREG(FBC_FENCE_OFF),
+    DEFINEREG(FBC_MOD_NUM),
+
     DEFINEREG(MI_MODE),
     /* DEFINEREG(MI_DISPLAY_POWER_DOWN), CRL only */
     DEFINEREG(MI_ARB_STATE),
commit 5d0f981ee00fbcdee44d38d94acfd2c68f9082d3
Author: lipeng <peng.li at linux.intel.com>
Date:   Tue Jul 15 10:26:33 2008 -0700

    Fix GPIO pin usage for DDC on second HDMI port.
    (cherry picked from commit a76ae7cab3001ce6639ae23fb0769c4e46b57e71)

diff --git a/src/i830_hdmi.c b/src/i830_hdmi.c
index 72d4c63..b738463 100644
--- a/src/i830_hdmi.c
+++ b/src/i830_hdmi.c
@@ -225,7 +225,7 @@ i830_hdmi_init(ScrnInfoPtr pScrn, int output_reg)
     if (output_reg == SDVOB)
 	I830I2CInit(pScrn, &intel_output->pDDCBus, GPIOE, "HDMIDDC_B");
     else
-	I830I2CInit(pScrn, &intel_output->pDDCBus, GPIOE, "HDMIDDC_C");
+	I830I2CInit(pScrn, &intel_output->pDDCBus, GPIOD, "HDMIDDC_C");
 
     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 	       "HDMI output %d detected\n",
commit 4709bf48bdc61666fcdf0e13e863f1f5f9131882
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Jul 14 13:43:31 2008 -0700

    Fix DSPARB setting on 845/865, which have only the AEND field and 96 entries.
    (cherry picked from commit 5054a86b1b362f3f63310afb9ef2d37c9f1cfca5)

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 0a49d3a..c880833 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -1994,7 +1994,16 @@ i830_set_dsparb(ScrnInfoPtr pScrn)
 	   OUTREG(DSPARB, (95 << DSPARB_CSTART_SHIFT) |
 		  (48 << DSPARB_BSTART_SHIFT));
    } else {
-       OUTREG(DSPARB, 254 << DSPARB_BEND_SHIFT | 128 << DSPARB_AEND_SHIFT);
+       if (IS_MOBILE(pI830)) {
+	   /* The 830 has 288 entries, and the 855 has 256. */
+	   OUTREG(DSPARB, 254 << DSPARB_BEND_SHIFT | 128 << DSPARB_AEND_SHIFT);
+       } else {
+	   /* The 845/865 only have a AEND field.  Though the field size would
+	    * allow 128 entries, the 865 rendered the cursor wrong then.
+	    * The BIOS set it up for 96.
+	    */
+	   OUTREG(DSPARB, 95 << DSPARB_AEND_SHIFT);
+       }
    }
 }
 
commit 0a7b753d70e1fd494430c496e19fb672258b5ac6
Author: Julien Cristau <jcristau at debian.org>
Date:   Fri Jun 6 13:40:20 2008 +0200

    Link the driver with -lpciaccess and -ldrm if needed
    
    This makes sure the driver ends up with a DT_NEEDED reference to
    the libraries it's using.
    (cherry picked from commit 8ac00ca97995e36514ff593fec3c0f0d316ed138)

diff --git a/src/Makefile.am b/src/Makefile.am
index 45f8b19..1e4ad28 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -36,6 +36,10 @@ AM_CFLAGS = @WARN_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@ @PCIACCESS_CFLAGS@ \
 intel_drv_la_LTLIBRARIES = intel_drv.la
 intel_drv_la_LDFLAGS = -module -avoid-version
 intel_drv_ladir = @moduledir@/drivers
+intel_drv_la_LIBADD =
+if XSERVER_LIBPCIACCESS
+intel_drv_la_LIBADD += @PCIACCESS_LIBS@
+endif
 
 XMODE_SRCS=\
 	 local_xf86Rename.h \
@@ -203,6 +207,8 @@ endif
 if DRI
 intel_drv_la_SOURCES += \
 	$(INTEL_DRI_SRCS)
+intel_drv_la_LIBADD += \
+	$(DRI_LIBS)
 endif
 
 if XVMC
commit b27776f498c23787629a229f5d9c07eb3b383333
Author: Julien Cristau <jcristau at debian.org>
Date:   Sun Jul 6 12:00:52 2008 +0200

    Fix gen4asm rule to work with a build dir
    (cherry picked from commit d61182511b1520b04133d28480e1ffaacbaeb753)

diff --git a/src/Makefile.am b/src/Makefile.am
index 9dd9b37..45f8b19 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -185,7 +185,7 @@ if HAVE_GEN4ASM
 
 SUFFIXES = .g4a .g4b
 .g4a.g4b:
-	m4 -s $*.g4a > $*.g4m && intel-gen4asm -o $@ $*.g4m && rm $*.g4m
+	m4 -I$(srcdir) -s $< > $*.g4m && intel-gen4asm -o $@ $*.g4m && rm $*.g4m
 
 $(INTEL_G4B): $(INTEL_G4I)
 
commit 618968c3dc88b16b079061066c5772754ebeaa26
Author: Carl Worth <cworth at cworth.org>
Date:   Mon Jul 7 15:58:27 2008 -0700

    Use up to 256 separate vertex buffers
    
    This allows us to only call i830WaitSync once every 128 calls to composite
    rather than on every call. However, we do need to also call MI_FLUSH to
    avoid the vertex cache getting in our way, (since our "separate" buffers
    are all allocated as one contiguous chunk).
    (cherry picked from commit 757c00927a6f5760135136450b8d02d0f999ac1c)

diff --git a/src/i965_render.c b/src/i965_render.c
index 3c7379c..1cbfe24 100644
--- a/src/i965_render.c
+++ b/src/i965_render.c
@@ -60,7 +60,7 @@ do { 							\
 #endif
 
 #define MAX_VERTEX_PER_COMPOSITE    24
-#define MAX_VERTEX_BUFFERS	    1
+#define MAX_VERTEX_BUFFERS	    256
 
 struct blendinfo {
     Bool dst_alpha;
@@ -1401,7 +1401,8 @@ i965_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
     }
     assert (i * 4 <= sizeof(card_state->vb));
 
-    BEGIN_BATCH(11);
+    BEGIN_BATCH(12);
+    OUT_BATCH(MI_FLUSH);
     /* Set up the pointer to our (single) vertex buffer */
     OUT_BATCH(BRW_3DSTATE_VERTEX_BUFFERS | 3);
     OUT_BATCH((0 << VB0_BUFFER_INDEX_SHIFT) |
commit bfcc2957023f74e8167f9c501245492feaa5ae76
Author: Carl Worth <cworth at cworth.org>
Date:   Mon Jul 7 14:01:15 2008 -0700

    Allow for multiple vertex buffers (though only use one for now)
    
    Using more than one (in the future) will allow for doing less frequent calls
    to i830WaitSync.
    (cherry picked from commit 0c548cd040d0c5e1812470ccdf6de86b6a2926d7)

diff --git a/src/i965_render.c b/src/i965_render.c
index a9e3227..3c7379c 100644
--- a/src/i965_render.c
+++ b/src/i965_render.c
@@ -59,6 +59,9 @@ do { 							\
 } while(0)
 #endif
 
+#define MAX_VERTEX_PER_COMPOSITE    24
+#define MAX_VERTEX_BUFFERS	    1
+
 struct blendinfo {
     Bool dst_alpha;
     Bool src_alpha;
@@ -500,7 +503,7 @@ typedef struct _gen4_state {
     struct brw_cc_viewport cc_viewport;
     PAD64 (brw_cc_viewport, 0);
 
-    float vb[(2 + 3 + 3) * 3];   /* (dst, src, mask) 3 vertices, 4 bytes */
+    float vb[MAX_VERTEX_PER_COMPOSITE * MAX_VERTEX_BUFFERS];
 } gen4_state_t;
 
 /** Private data for gen4 render accel implementation. */
@@ -510,6 +513,7 @@ struct gen4_render_state {
 
     int binding_table_index;
     int surface_state_index;
+    int vb_offset;
     int vertex_size;
 };
 
@@ -969,6 +973,7 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture,
 	i830WaitSync(pScrn);
 	render_state->binding_table_index = 0;
 	render_state->surface_state_index = 0;
+	render_state->vb_offset = 0;
     }
 
     binding_table = card_state->binding_table +
@@ -1347,12 +1352,12 @@ i965_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
 	}
     }
 
-    /* Wait for any existing composite rectangles to land before we overwrite
-     * the VB with the next one.
-     */
-    i830WaitSync(pScrn);
+    if (render_state->vb_offset + MAX_VERTEX_PER_COMPOSITE >= ARRAY_SIZE(card_state->vb)) {
+	i830WaitSync(pScrn);
+	render_state->vb_offset = 0;
+    }
 
-    i = 0;
+    i = render_state->vb_offset;
     /* rect (x2,y2) */
     vb[i++] = (float)(dstX + w);
     vb[i++] = (float)(dstY + h);
@@ -1402,7 +1407,8 @@ i965_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
     OUT_BATCH((0 << VB0_BUFFER_INDEX_SHIFT) |
 	      VB0_VERTEXDATA |
 	      (render_state->vertex_size << VB0_BUFFER_PITCH_SHIFT));
-    OUT_BATCH(render_state->card_state_offset + offsetof(gen4_state_t, vb));
+    OUT_BATCH(render_state->card_state_offset + offsetof(gen4_state_t, vb) +
+	      render_state->vb_offset * 4);
     OUT_BATCH(3);
     OUT_BATCH(0); // ignore for VERTEXDATA, but still there
 
@@ -1418,6 +1424,8 @@ i965_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
     OUT_BATCH(0); /* index buffer offset, ignored */
     ADVANCE_BATCH();
 
+    render_state->vb_offset = i;
+
 #ifdef I830DEBUG
     ErrorF("sync after 3dprimitive\n");
     I830Sync(pScrn);
commit 7dfebaa4f749869914feb1db9a2fa1ab9762c640
Author: Carl Worth <cworth at cworth.org>
Date:   Mon Jul 7 13:25:42 2008 -0700

    Move VERTEX_BUFFERS setup from prepare_composite to composite
    
    This is in preparation for having larger (or multiple) vertex buffers
    in the future.
    (cherry picked from commit cc2249333cd462b4d99d110a12c454ca141b2be8)

diff --git a/src/i965_render.c b/src/i965_render.c
index a13aec2..a9e3227 100644
--- a/src/i965_render.c
+++ b/src/i965_render.c
@@ -510,6 +510,7 @@ struct gen4_render_state {
 
     int binding_table_index;
     int surface_state_index;
+    int vertex_size;
 };
 
 /**
@@ -1195,6 +1196,8 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture,
 	int selem = is_affine ? 2 : 3;
 	uint32_t    w_component;
 	uint32_t    src_format;
+
+	render_state->vertex_size = 4 * (2 + nelem * selem);
 	
 	if (is_affine)
 	{
@@ -1206,17 +1209,9 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture,
 	    src_format = BRW_SURFACEFORMAT_R32G32B32_FLOAT;
 	    w_component = BRW_VFCOMPONENT_STORE_SRC;
 	}
-	BEGIN_BATCH(pMask?12:10);
-	/* Set up the pointer to our (single) vertex buffer */
-	OUT_BATCH(BRW_3DSTATE_VERTEX_BUFFERS | 3);
-	OUT_BATCH((0 << VB0_BUFFER_INDEX_SHIFT) |
-		  VB0_VERTEXDATA |
-		  ((4 * (2 + nelem * selem)) << VB0_BUFFER_PITCH_SHIFT));
-	OUT_BATCH(state_base_offset + offsetof(gen4_state_t, vb));
-        OUT_BATCH(3);
-	OUT_BATCH(0); // ignore for VERTEXDATA, but still there
-
+	BEGIN_BATCH(pMask?7:5);
 	/* Set up our vertex elements, sourced from the single vertex buffer.
+	 * that will be set up later.
 	 */
 	
 	OUT_BATCH(BRW_3DSTATE_VERTEX_ELEMENTS | ((2 * (1 + nelem)) - 1));
@@ -1271,6 +1266,7 @@ i965_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
     ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
     I830Ptr pI830 = I830PTR(pScrn);
     gen4_state_t *card_state = pI830->gen4_render_state->card_state;
+    struct gen4_render_state *render_state = pI830->gen4_render_state;
     Bool has_mask;
     Bool is_affine_src, is_affine_mask, is_affine;
     float src_x[3], src_y[3], src_w[3], mask_x[3], mask_y[3], mask_w[3];
@@ -1400,20 +1396,28 @@ i965_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
     }
     assert (i * 4 <= sizeof(card_state->vb));
 
-    {
-      BEGIN_BATCH(6);
-      OUT_BATCH(BRW_3DPRIMITIVE |
-		BRW_3DPRIMITIVE_VERTEX_SEQUENTIAL |
-		(_3DPRIM_RECTLIST << BRW_3DPRIMITIVE_TOPOLOGY_SHIFT) |
-		(0 << 9) |  /* CTG - indirect vertex count */
-		4);
-      OUT_BATCH(3);  /* vertex count per instance */
-      OUT_BATCH(0); /* start vertex offset */
-      OUT_BATCH(1); /* single instance */
-      OUT_BATCH(0); /* start instance location */
-      OUT_BATCH(0); /* index buffer offset, ignored */
-      ADVANCE_BATCH();
-    }
+    BEGIN_BATCH(11);
+    /* Set up the pointer to our (single) vertex buffer */
+    OUT_BATCH(BRW_3DSTATE_VERTEX_BUFFERS | 3);
+    OUT_BATCH((0 << VB0_BUFFER_INDEX_SHIFT) |
+	      VB0_VERTEXDATA |
+	      (render_state->vertex_size << VB0_BUFFER_PITCH_SHIFT));
+    OUT_BATCH(render_state->card_state_offset + offsetof(gen4_state_t, vb));
+    OUT_BATCH(3);
+    OUT_BATCH(0); // ignore for VERTEXDATA, but still there
+
+    OUT_BATCH(BRW_3DPRIMITIVE |
+	      BRW_3DPRIMITIVE_VERTEX_SEQUENTIAL |
+	      (_3DPRIM_RECTLIST << BRW_3DPRIMITIVE_TOPOLOGY_SHIFT) |
+	      (0 << 9) |  /* CTG - indirect vertex count */
+	      4);
+    OUT_BATCH(3);  /* vertex count per instance */
+    OUT_BATCH(0); /* start vertex offset */
+    OUT_BATCH(1); /* single instance */
+    OUT_BATCH(0); /* start instance location */
+    OUT_BATCH(0); /* index buffer offset, ignored */
+    ADVANCE_BATCH();
+
 #ifdef I830DEBUG
     ErrorF("sync after 3dprimitive\n");
     I830Sync(pScrn);
commit 891a25c2f7b24668dff59940d0b989a5cd23478f
Author: Jesse Barnes <jbarnes at jbarnes-t61.(none)>
Date:   Thu Jul 10 12:57:25 2008 -0700

    Add VBIOS based TV connector detection
    
    Now that the VBIOS code supports it, we can use the general features block to
    detect whether a TV connector is present on a given platform.
    
    Reviewed by Nanhai Zou.
    (cherry picked from commit 3c0f2bcc9965155fecab606edae68874427d3423)

diff --git a/src/i830_tv.c b/src/i830_tv.c
index cde929a..651f77b 100644
--- a/src/i830_tv.c
+++ b/src/i830_tv.c
@@ -1715,6 +1715,10 @@ i830_tv_init(ScrnInfoPtr pScrn)
 	    (tv_dac_off & TVDAC_STATE_CHG_EN) != 0)
 	return;
 
+    i830_bios_get_tv(pScrn);
+    if (!pI830->tv_present) /* VBIOS claims no TV connector */
+	return;
+
     output = xf86OutputCreate (pScrn, &i830_tv_output_funcs, "TV");
 
     if (!output)
commit e1ef5fc04907e02a38c518c868f39a897f81cd1e
Author: Jesse Barnes <jbarnes at jbarnes-t61.(none)>
Date:   Thu Jul 10 12:55:12 2008 -0700

    Improve VBIOS feature detection, add SSC support
    
    Improve the VBIOS feature detection and use it to find whether the platform
    supports spread spectrum clocking.  Use the specified reference clock, but
    disable SSC if multiple heads are active, since it can cause problems in cloned
    configurations.
    
    Reviewed by Nanhai Zou.
    (cherry picked from commit e00d9435609bcff1afb71aa6638a6b42a64f5178)

diff --git a/src/i830.h b/src/i830.h
index 570db13..68690f7 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -554,6 +554,10 @@ typedef struct _I830Rec {
    OptionInfoPtr Options;
 
    Bool lvds_24_bit_mode;
+   Bool lvds_use_ssc;
+   int lvds_ssc_freq; /* in MHz */
+
+   Bool tv_present; /* TV connector present (from VBIOS) */
 
    Bool StolenOnly;
 
diff --git a/src/i830_bios.c b/src/i830_bios.c
index 57ee278..a8193fc 100644
--- a/src/i830_bios.c
+++ b/src/i830_bios.c
@@ -70,6 +70,32 @@ i830DumpBIOSToFile(ScrnInfoPtr pScrn, unsigned char *bios)
     fclose(f);
 }
 
+static void *
+find_section(struct bdb_header *bdb, int section_id)
+{
+	unsigned char *base = (unsigned char *)bdb;
+	int index = 0;
+	uint16_t total, current_size;
+	unsigned char current_id;
+
+	/* skip to first section */
+	index += bdb->header_size;
+	total = bdb->bdb_size;
+
+	/* walk the sections looking for section_id */
+	while (index < total) {
+		current_id = *(base + index);
+		index++;
+		current_size = *((uint16_t *)(base + index));
+		index += 2;
+		if (current_id == section_id)
+			return base + index;
+		index += current_size;
+	}
+
+	return NULL;
+}
+
 /**
  * Loads the Video BIOS and checks that the VBT exists.
  *
@@ -127,6 +153,70 @@ i830_bios_get (ScrnInfoPtr pScrn)
     return bios;
 }
 
+void
+i830_bios_get_ssc(ScrnInfoPtr pScrn)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+    struct vbt_header *vbt;
+    struct bdb_header *bdb;
+    struct bdb_general_features *bdb_features;
+    int vbt_off, bdb_off;
+    unsigned char *bios;
+
+    bios = i830_bios_get(pScrn);
+
+    if (bios == NULL)
+	return;
+
+    vbt_off = INTEL_BIOS_16(0x1a);
+    vbt = (struct vbt_header *)(bios + vbt_off);
+    bdb_off = vbt_off + vbt->bdb_offset;
+    bdb = (struct bdb_header *)(bios + bdb_off);
+
+    bdb_features = find_section(bdb, BDB_GENERAL_FEATURES);
+    if (!bdb_features)
+	return;
+
+    pI830->lvds_use_ssc = bdb_features->enable_ssc;
+    if (pI830->lvds_use_ssc) {
+	if (IS_I855(pI830))
+	    pI830->lvds_ssc_freq = bdb_features->ssc_freq ? 66 : 48;
+	else
+	    pI830->lvds_ssc_freq = bdb_features->ssc_freq ? 100 : 96;
+    }
+
+    xfree(bios);
+}
+
+void
+i830_bios_get_tv(ScrnInfoPtr pScrn)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+    struct vbt_header *vbt;
+    struct bdb_header *bdb;
+    struct bdb_general_features *bdb_features;
+    int vbt_off, bdb_off;
+    unsigned char *bios;
+
+    bios = i830_bios_get(pScrn);
+
+    if (bios == NULL)
+	return;
+
+    vbt_off = INTEL_BIOS_16(0x1a);
+    vbt = (struct vbt_header *)(bios + vbt_off);
+    bdb_off = vbt_off + vbt->bdb_offset;
+    bdb = (struct bdb_header *)(bios + bdb_off);
+
+    bdb_features = find_section(bdb, BDB_GENERAL_FEATURES);
+    if (!bdb_features)
+	return;
+
+    pI830->tv_present = bdb_features->int_tv_support;
+
+    xfree(bios);
+}
+
 /**
  * Returns the BIOS's fixed panel mode.
  *
diff --git a/src/i830_bios.h b/src/i830_bios.h
index 95230f5..c1ba50d 100644
--- a/src/i830_bios.h
+++ b/src/i830_bios.h
@@ -49,6 +49,97 @@ struct bdb_header {
     uint16_t bdb_size;			/**< in bytes */
 } __attribute__((packed));
 
+/*
+ * There are several types of BIOS data blocks (BDBs), each block has
+ * an ID and size in the first 3 bytes (ID in first, size in next 2).
+ * Known types are listed below.
+ */
+#define BDB_GENERAL_FEATURES	  1
+#define BDB_GENERAL_DEFINITIONS	  2
+#define BDB_OLD_TOGGLE_LIST	  3
+#define BDB_MODE_SUPPORT_LIST	  4
+#define BDB_GENERIC_MODE_TABLE	  5
+#define BDB_EXT_MMIO_REGS	  6
+#define BDB_SWF_IO		  7
+#define BDB_SWF_MMIO		  8
+#define BDB_DOT_CLOCK_TABLE	  9
+#define BDB_MODE_REMOVAL_TABLE	 10
+#define BDB_CHILD_DEVICE_TABLE	 11
+#define BDB_DRIVER_FEATURES	 12
+#define BDB_DRIVER_PERSISTENCE	 13
+#define BDB_EXT_TABLE_PTRS	 14
+#define BDB_DOT_CLOCK_OVERRIDE	 15
+#define BDB_DISPLAY_SELECT	 16
+/* 17 rsvd */
+#define BDB_DRIVER_ROTATION	 18
+#define BDB_DISPLAY_REMOVE	 19
+#define BDB_OEM_CUSTOM		 20
+#define BDB_EFP_LIST		 21 /* workarounds for VGA hsync/vsync */
+#define BDB_SDVO_LVDS_OPTIONS	 22
+#define BDB_SDVO_PANEL_DTDS	 23
+#define BDB_SDVO_LVDS_PNP_IDS	 24
+#define BDB_SDVO_LVDS_POWER_SEQ	 25
+#define BDB_TV_OPTIONS		 26
+#define BDB_LVDS_OPTIONS	 40
+#define BDB_LVDS_LFP_DATA_PTRS	 41
+#define BDB_LVDS_LFP_DATA	 42
+#define BDB_LVDS_BACKLIGHT	 43
+#define BDB_LVDS_POWER		 44
+#define BDB_SKIP		254 /* VBIOS private block, ignore */
+
+struct bdb_general_features {
+        /* bits 1 */
+	unsigned char panel_fitting:2;
+	unsigned char flexaim:1;
+	unsigned char msg_enable:1;
+	unsigned char clear_screen:3;
+	unsigned char color_flip:1;
+
+        /* bits 2 */
+	unsigned char download_ext_vbt:1;
+	unsigned char enable_ssc:1;
+	unsigned char ssc_freq:1;
+	unsigned char enable_lfp_on_override:1;
+	unsigned char disable_ssc_ddt:1;
+	unsigned char rsvd8:3; /* finish byte */
+
+        /* bits 3 */
+	unsigned char disable_smooth_vision:1;
+	unsigned char single_dvi:1;
+	unsigned char rsvd9:6; /* finish byte */
+
+        /* bits 4 */
+	unsigned char legacy_monitor_detect;
+
+        /* bits 5 */
+	unsigned char int_crt_support:1;
+	unsigned char int_tv_support:1;
+	unsigned char rsvd11:6; /* finish byte */
+} __attribute__((packed));
+
+struct bdb_general_definitions {
+	/* DDC GPIO */
+	unsigned char crt_ddc_gmbus_pin;
+
+	/* DPMS bits */
+	unsigned char dpms_acpi:1;
+	unsigned char skip_boot_crt_detect:1;
+	unsigned char dpms_aim:1;
+	unsigned char rsvd1:5; /* finish byte */
+
+	/* boot device bits */
+	unsigned char boot_display[2];
+	unsigned char child_dev_size;
+
+	/* device info */
+	unsigned char tv_or_lvds_info[33];
+	unsigned char dev1[33];
+	unsigned char dev2[33];
+	unsigned char dev3[33];
+	unsigned char dev4[33];
+	/* may be another device block here on some platforms */
+};
+
 #define LVDS_CAP_EDID			(1 << 6)
 #define LVDS_CAP_DITHER			(1 << 5)
 #define LVDS_CAP_PFIT_AUTO_RATIO	(1 << 4)
@@ -150,6 +241,8 @@ struct vch_bdb_22 {
 unsigned char *
 i830_bios_get (ScrnInfoPtr pScrn);
 
+void i830_bios_get_ssc(ScrnInfoPtr pScrn);
+void i830_bios_get_tv(ScrnInfoPtr pScrn);
 DisplayModePtr i830_bios_get_panel_mode(ScrnInfoPtr pScrn, Bool *wants_dither);
 
 unsigned char *
diff --git a/src/i830_display.c b/src/i830_display.c
index 306fed4..3967b69 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -1128,7 +1128,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
     int dsppos_reg = (plane == 0) ? DSPAPOS : DSPBPOS;
     int dspsize_reg = (plane == 0) ? DSPASIZE : DSPBSIZE;
     int pipestat_reg = (pipe == 0) ? PIPEASTAT : PIPEBSTAT;
-    int i;
+    int i, num_outputs = 0;
     int refclk;
     intel_clock_t clock;
     uint32_t dpll = 0, fp = 0, dspcntr, pipeconf, lvds_bits = 0;
@@ -1168,9 +1168,19 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
 	    is_crt = TRUE;
 	    break;
 	}
+
+	num_outputs++;
     }
 
-    if (IS_I9XX(pI830)) {
+    if (num_outputs > 1)
+	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "clone detected, disabling SSC\n");
+
+    /* Don't use SSC when cloned */
+    if (pI830->lvds_use_ssc && num_outputs < 2) {
+	refclk = pI830->lvds_ssc_freq * 1000;
+	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+		   "using SSC reference clock of %d MHz\n", refclk / 1000);
+    } else if (IS_I9XX(pI830)) {
 	refclk = 96000;
     } else {
 	refclk = 48000;
@@ -1246,10 +1256,8 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
 /*	dpll |= PLL_REF_INPUT_TVCLKINBC; */
 	dpll |= 3;
     }
-#if 0
-    else if (is_lvds)
+    else if (is_lvds && pI830->lvds_use_ssc && num_outputs < 2)
 	dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
-#endif
     else
 	dpll |= PLL_REF_INPUT_DREFCLK;
 
diff --git a/src/i830_lvds.c b/src/i830_lvds.c
index d1bbb3a..c7f2434 100644
--- a/src/i830_lvds.c
+++ b/src/i830_lvds.c
@@ -1341,6 +1341,9 @@ i830_lvds_init(ScrnInfoPtr pScrn)
 	goto disable_exit;
     }
 
+    /* Update pI830 w/SSC info, if any */
+    i830_bios_get_ssc(pScrn);
+
  skip_panel_fixed_mode_setup:
 
     /* Blacklist machines with BIOSes that list an LVDS panel without actually
commit 7d1aa118a24195833466a4a4342c71f37db673f8
Author: Jesse Barnes <jbarnes at jbarnes-t61.(none)>
Date:   Mon Jul 7 10:48:56 2008 -0700

    Improve FBC size checking
    
    In hindsight, this is obvious, since nowhere do we tell the FBC unit how much
    memory it has available.  We need to make sure the compressed buffer is big
    enough to handle the uncompresed buffer, both in terms of vertical size and
    total framebuffer size, or the compressor could overwrite the memory
    immediately following the compressed buffer.
    (cherry picked from commit 7332132a79e5b5c208d43e93dfe0c8b12eb1728d)

diff --git a/src/i830_display.c b/src/i830_display.c
index df3a6be..306fed4 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -693,6 +693,7 @@ i830_use_fb_compression(xf86CrtcPtr crtc)
     xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
     I830Ptr pI830 = I830PTR(pScrn);
     I830CrtcPrivatePtr	intel_crtc = crtc->driver_private;
+    unsigned long uncompressed_size;
     int plane = (intel_crtc->plane == 0 ? FBC_CTL_PLANEA : FBC_CTL_PLANEB);
     int i, count = 0;
 
@@ -724,6 +725,19 @@ i830_use_fb_compression(xf86CrtcPtr crtc)
 	  pScrn->bitsPerPixel == 32)) /* mode_set dtrt if fbc is in use */
 	return FALSE;
 
+    /* Can't cache more lines than we can track */
+    if (crtc->mode.VDisplay > FBC_LL_SIZE)
+	return FALSE;
+
+    /*
+     * Make sure the compressor doesn't go past the end of our compressed
+     * buffer if the uncompressed size is large.
+     */
+    uncompressed_size = crtc->mode.HDisplay * crtc->mode.VDisplay *
+	pI830->cpp;
+    if (pI830->compressed_front_buffer->size < uncompressed_size)
+	return FALSE;
+
     /*
      * No checks for pixel multiply, incl. horizontal, or interlaced modes
      * since they're currently unused.
commit 92ec2fc750ce17b1ec36493e8d731ef4b0bb772d
Author: Stefan Dirsch <sndirsch at suse.de>
Date:   Thu Jul 3 23:12:13 2008 +0200

    Add pipea force enable quirk for another 855GM machine.
    
    Fixes Novell Bug #406123, thanks Christoph.
    (cherry picked from commit f2ec3fd8f2c63b1bc0745802dcf737eda4bb42b6)

diff --git a/src/i830_quirks.c b/src/i830_quirks.c
index e81b27c..5eb01be 100644
--- a/src/i830_quirks.c
+++ b/src/i830_quirks.c
@@ -286,6 +286,8 @@ static i830_quirk i830_quirk_list[] = {
     { PCI_CHIP_I915_GM, 0x1179, 0x0001, quirk_pipea_force },
     /* Intel 855GM hardware (See LP: #216490) */
     { PCI_CHIP_I855_GM, 0x1028, 0x00c8, quirk_pipea_force },
+    /* Intel 855GM hardware (See Novell Bugzilla #406123) */
+    { PCI_CHIP_I855_GM, 0x10cf, 0x1215, quirk_pipea_force },
 
     /* ThinkPad X40 needs pipe A force quirk */
     { PCI_CHIP_I855_GM, 0x1014, 0x0557, quirk_pipea_force },
commit 483cba52ef62565fff3b21eb8ca2b00ab3075fa6
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Thu Jul 3 01:03:14 2008 +0800

    Fix official name for GM45 chipset
    (cherry picked from commit a34a4e3f6420e2b06bbdaa124fe0ccb1bc6a0bd9)

diff --git a/src/common.h b/src/common.h
index b67b20b..57db6cb 100644
--- a/src/common.h
+++ b/src/common.h
@@ -303,9 +303,9 @@ extern int I810_DEBUG;
 #define PCI_CHIP_Q33_G_BRIDGE 	0x29D0
 #endif
 
-#ifndef PCI_CHIP_IGD_GM
-#define PCI_CHIP_IGD_GM		0x2A42
-#define PCI_CHIP_IGD_GM_BRIDGE  0x2A40
+#ifndef PCI_CHIP_GM45_GM
+#define PCI_CHIP_GM45_GM	0x2A42
+#define PCI_CHIP_GM45_BRIDGE    0x2A40
 #endif
 
 #ifndef PCI_CHIP_IGD_E_G
@@ -354,26 +354,26 @@ extern int I810_DEBUG;
 #define IS_I915GM(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I915_GM)
 #define IS_I945G(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I945_G)
 #define IS_I945GM(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I945_GM || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I945_GME)
-#define IS_IGD_GM(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_IGD_GM)
+#define IS_GM45(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_GM45_GM)
 #define IS_G4X(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_IGD_E_G || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_G45_G || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_Q45_G)
 #define IS_I965GM(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_GM || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_GME)
-#define IS_I965G(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_G || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_G35_G || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_Q || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I946_GZ || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_GM || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_GME || IS_IGD_GM(pI810) || IS_G4X(pI810))
+#define IS_I965G(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_G || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_G35_G || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_Q || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I946_GZ || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_GM || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_GME || IS_GM45(pI810) || IS_G4X(pI810))
 #define IS_G33CLASS(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_G33_G ||\
  			    DEVICE_ID(pI810->PciInfo) == PCI_CHIP_Q35_G ||\
  			    DEVICE_ID(pI810->PciInfo) == PCI_CHIP_Q33_G)
 #define IS_I9XX(pI810) (IS_I915G(pI810) || IS_I915GM(pI810) || IS_I945G(pI810) || IS_I945GM(pI810) || IS_I965G(pI810) || IS_G33CLASS(pI810))
 #define IS_I915(pI810) (IS_I915G(pI810) || IS_I915GM(pI810) || IS_I945G(pI810) || IS_I945GM(pI810) || IS_G33CLASS(pI810))
 
-#define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810) || IS_I915GM(pI810) || IS_I945GM(pI810) || IS_I965GM(pI810) || IS_IGD_GM(pI810))
+#define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810) || IS_I915GM(pI810) || IS_I945GM(pI810) || IS_I965GM(pI810) || IS_GM45(pI810))
 /* mark chipsets for using gfx VM offset for overlay */
 #define OVERLAY_NOPHYSICAL(pI810) (IS_G33CLASS(pI810) || IS_I965G(pI810))
 /* mark chipsets without overlay hw */
-#define OVERLAY_NOEXIST(pI810) (IS_IGD_GM(pI810) || IS_G4X(pI810))
+#define OVERLAY_NOEXIST(pI810) (IS_GM45(pI810) || IS_G4X(pI810))
 /* chipsets require graphics mem for hardware status page */
-#define HWS_NEED_GFX(pI810) (IS_G33CLASS(pI810) || IS_IGD_GM(pI810) || IS_G4X(pI810))
+#define HWS_NEED_GFX(pI810) (IS_G33CLASS(pI810) || IS_GM45(pI810) || IS_G4X(pI810))
 /* chipsets require status page in non stolen memory */
-#define HWS_NEED_NONSTOLEN(pI810) (IS_IGD_GM(pI810) || IS_G4X(pI810))
-#define SUPPORTS_INTEGRATED_HDMI(pI810) (IS_IGD_GM(pI810) || IS_G4X(pI810))
+#define HWS_NEED_NONSTOLEN(pI810) (IS_GM45(pI810) || IS_G4X(pI810))
+#define SUPPORTS_INTEGRATED_HDMI(pI810) (IS_GM45(pI810) || IS_G4X(pI810))
 
 #define GTT_PAGE_SIZE			KB(4)
 #define ROUND_TO(x, y)			(((x) + (y) - 1) / (y) * (y))
diff --git a/src/i810_driver.c b/src/i810_driver.c
index de4f3cb..8540646 100644
--- a/src/i810_driver.c
+++ b/src/i810_driver.c
@@ -152,7 +152,7 @@ static const struct pci_id_match intel_device_match[] = {
    INTEL_DEVICE_MATCH (PCI_CHIP_G33_G, 0 ),
    INTEL_DEVICE_MATCH (PCI_CHIP_Q35_G, 0 ),
    INTEL_DEVICE_MATCH (PCI_CHIP_Q33_G, 0 ),
-   INTEL_DEVICE_MATCH (PCI_CHIP_IGD_GM, 0 ),
+   INTEL_DEVICE_MATCH (PCI_CHIP_GM45_GM, 0 ),
    INTEL_DEVICE_MATCH (PCI_CHIP_IGD_E_G, 0 ),
    INTEL_DEVICE_MATCH (PCI_CHIP_G45_G, 0 ),
    INTEL_DEVICE_MATCH (PCI_CHIP_Q45_G, 0 ),
@@ -208,7 +208,7 @@ static SymTabRec I810Chipsets[] = {
    {PCI_CHIP_G33_G,		"G33"},
    {PCI_CHIP_Q35_G,		"Q35"},
    {PCI_CHIP_Q33_G,		"Q33"},
-   {PCI_CHIP_IGD_GM,		"Intel Integrated Graphics Device"},
+   {PCI_CHIP_GM45_GM,		"Mobile Intel® GM45 Express Chipset"},
    {PCI_CHIP_IGD_E_G,		"Intel Integrated Graphics Device"},
    {PCI_CHIP_G45_G,		"G45/G43"},
    {PCI_CHIP_Q45_G,		"Q45/Q43"},
@@ -241,7 +241,7 @@ static PciChipsets I810PciChipsets[] = {
    {PCI_CHIP_G33_G,		PCI_CHIP_G33_G,		RES_SHARED_VGA},
    {PCI_CHIP_Q35_G,		PCI_CHIP_Q35_G,		RES_SHARED_VGA},
    {PCI_CHIP_Q33_G,		PCI_CHIP_Q33_G,		RES_SHARED_VGA},
-   {PCI_CHIP_IGD_GM,		PCI_CHIP_IGD_GM,	RES_SHARED_VGA},
+   {PCI_CHIP_GM45_GM,		PCI_CHIP_GM45_GM,	RES_SHARED_VGA},
    {PCI_CHIP_IGD_E_G,		PCI_CHIP_IGD_E_G,	RES_SHARED_VGA},
    {PCI_CHIP_G45_G,		PCI_CHIP_G45_G,		RES_SHARED_VGA},
    {PCI_CHIP_Q45_G,		PCI_CHIP_Q45_G,		RES_SHARED_VGA},
@@ -808,7 +808,7 @@ I810Probe(DriverPtr drv, int flags)
  	    case PCI_CHIP_G33_G:
  	    case PCI_CHIP_Q35_G:
  	    case PCI_CHIP_Q33_G:
- 	    case PCI_CHIP_IGD_GM:
+ 	    case PCI_CHIP_GM45_GM:
 	    case PCI_CHIP_IGD_E_G:
 	    case PCI_CHIP_G45_G:
 	    case PCI_CHIP_Q45_G:
diff --git a/src/i830_display.c b/src/i830_display.c
index abe9875..df3a6be 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -668,7 +668,7 @@ i830_enable_fb_compression(xf86CrtcPtr crtc)
     ScrnInfoPtr pScrn = crtc->scrn;
     I830Ptr pI830 = I830PTR(pScrn);
 
-    if (IS_IGD_GM(pI830))
+    if (IS_GM45(pI830))
 	return i830_enable_fb_compression2(crtc);
 
     i830_enable_fb_compression_8xx(crtc);
@@ -680,7 +680,7 @@ i830_disable_fb_compression(xf86CrtcPtr crtc)
     ScrnInfoPtr pScrn = crtc->scrn;
     I830Ptr pI830 = I830PTR(pScrn);
 
-    if (IS_IGD_GM(pI830))
+    if (IS_GM45(pI830))
 	return i830_disable_fb_compression2(crtc);
 
     i830_disable_fb_compression_8xx(crtc);
@@ -1209,7 +1209,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
 	    dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14;
 	    break;
 	}
-	if (IS_I965G(pI830) && !IS_IGD_GM(pI830))
+	if (IS_I965G(pI830) && !IS_GM45(pI830))
 	    dpll |= (6 << PLL_LOAD_PULSE_PHASE_SHIFT);
     } else {
 	if (is_lvds) {
diff --git a/src/i830_driver.c b/src/i830_driver.c
index dff7d51..0a49d3a 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -251,7 +251,7 @@ static SymTabRec I830Chipsets[] = {
    {PCI_CHIP_G33_G,		"G33"},
    {PCI_CHIP_Q35_G,		"Q35"},
    {PCI_CHIP_Q33_G,		"Q33"},
-   {PCI_CHIP_IGD_GM,		"Intel Integrated Graphics Device"},
+   {PCI_CHIP_GM45_GM,		"Mobile Intel® GM45 Express Chipset"},
    {PCI_CHIP_IGD_E_G,		"Intel Integrated Graphics Device"},
    {PCI_CHIP_G45_G,		"G45/G43"},
    {PCI_CHIP_Q45_G,		"Q45/Q43"},
@@ -278,7 +278,7 @@ static PciChipsets I830PciChipsets[] = {
    {PCI_CHIP_G33_G,		PCI_CHIP_G33_G,		RES_SHARED_VGA},
    {PCI_CHIP_Q35_G,		PCI_CHIP_Q35_G,		RES_SHARED_VGA},
    {PCI_CHIP_Q33_G,		PCI_CHIP_Q33_G,		RES_SHARED_VGA},
-   {PCI_CHIP_IGD_GM,		PCI_CHIP_IGD_GM,	RES_SHARED_VGA},
+   {PCI_CHIP_GM45_GM,		PCI_CHIP_GM45_GM,	RES_SHARED_VGA},
    {PCI_CHIP_IGD_E_G,		PCI_CHIP_IGD_E_G,	RES_SHARED_VGA},
    {PCI_CHIP_G45_G,		PCI_CHIP_G45_G,		RES_SHARED_VGA},
    {PCI_CHIP_Q45_G,		PCI_CHIP_Q45_G,		RES_SHARED_VGA},
@@ -653,7 +653,7 @@ I830MapMMIO(ScrnInfoPtr pScrn)
 
       if (IS_I965G(pI830)) 
       {
-	 if (IS_IGD_GM(pI830) || IS_G4X(pI830)) {
+	 if (IS_GM45(pI830) || IS_G4X(pI830)) {
 	     gttaddr = pI830->MMIOAddr + MB(2);
 	     pI830->GTTMapSize = MB(2);
 	 } else {
@@ -973,7 +973,7 @@ i830_init_clock_gating(ScrnInfoPtr pScrn)
 
     /* Disable clock gating reported to work incorrectly according to the specs.
      */
-    if (IS_IGD_GM(pI830)) {
+    if (IS_GM45(pI830)) {
 	OUTREG(RENCLK_GATE_D1, 0);
 	OUTREG(RENCLK_GATE_D2, 0);
 	OUTREG(RAMCLK_GATE_D, 0);
@@ -1218,7 +1218,9 @@ i830_detect_chipset(ScrnInfoPtr pScrn)
     case PCI_CHIP_Q33_G:
 	chipname = "Q33";
 	break;
-    case PCI_CHIP_IGD_GM:
+    case PCI_CHIP_GM45_GM:
+	chipname = "Mobile Intel® GM45 Express Chipset";
+	break;
     case PCI_CHIP_IGD_E_G:
 	chipname = "Intel Integrated Graphics Device";
 	break;
@@ -1985,7 +1987,7 @@ i830_set_dsparb(ScrnInfoPtr pScrn)
     * FIFO RAM entries equally between planes A and B.
     */
    if (IS_I9XX(pI830)) {
-       if (IS_I965GM(pI830) || IS_IGD_GM(pI830))
+       if (IS_I965GM(pI830) || IS_GM45(pI830))
 	   OUTREG(DSPARB, (127 << DSPARB_CSTART_SHIFT) |
 		  (64 << DSPARB_BSTART_SHIFT));
        else
@@ -2143,7 +2145,7 @@ SaveHWState(ScrnInfoPtr pScrn)
       pI830->saveRAMCLK_GATE_D = INREG(RAMCLK_GATE_D);
    }
 
-   if (IS_I965GM(pI830) || IS_IGD_GM(pI830))
+   if (IS_I965GM(pI830) || IS_GM45(pI830))
       pI830->savePWRCTXA = INREG(PWRCTXA);
 
    if (IS_MOBILE(pI830) && !IS_I830(pI830))
@@ -2213,7 +2215,7 @@ RestoreHWState(ScrnInfoPtr pScrn)
       OUTREG(RAMCLK_GATE_D, pI830->saveRAMCLK_GATE_D);
    }
 
-   if (IS_I965GM(pI830) || IS_IGD_GM(pI830))
+   if (IS_I965GM(pI830) || IS_GM45(pI830))
       OUTREG(PWRCTXA, pI830->savePWRCTXA);
 
    /*
@@ -2623,7 +2625,7 @@ i830_try_memory_allocation(ScrnInfoPtr pScrn)
     if (!i830_allocate_2d_memory(pScrn))
 	goto failed;
 
-    if (IS_I965GM(pI830) || IS_IGD_GM(pI830))
+    if (IS_I965GM(pI830) || IS_GM45(pI830))
 	if (!i830_allocate_pwrctx(pScrn))
 	    goto failed;
 
@@ -3036,7 +3038,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
     *       alone in that case.
     * Also make sure the DRM can handle the swap.
     */
-   if (I830LVDSPresent(pScrn) && !IS_I965GM(pI830) && !IS_IGD_GM(pI830) &&
+   if (I830LVDSPresent(pScrn) && !IS_I965GM(pI830) && !IS_GM45(pI830) &&
        (!pI830->directRenderingEnabled ||
 	(pI830->directRenderingEnabled && pI830->drmMinor >= 10))) {
        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "adjusting plane->pipe mappings "
diff --git a/src/i830_lvds.c b/src/i830_lvds.c
index b5e0c45..d1bbb3a 100644
--- a/src/i830_lvds.c
+++ b/src/i830_lvds.c
@@ -134,7 +134,7 @@ i830_set_lvds_backlight_method(xf86OutputPtr output)
 
     if (i830_kernel_backlight_available(output)) {
 	    method = BCM_KERNEL;
-    } else if (IS_I965GM(pI830) || IS_IGD_GM(pI830)) {
+    } else if (IS_I965GM(pI830) || IS_GM45(pI830)) {
 	blc_pwm_ctl2 = INREG(BLC_PWM_CTL2);
 	if (blc_pwm_ctl2 & BLM_LEGACY_MODE2)
 	    method = BCM_COMBO;
@@ -182,7 +182,7 @@ i830_lvds_get_backlight_max_native(xf86OutputPtr output)
     uint32_t pwm_ctl = INREG(BLC_PWM_CTL);
     int val;
 
-    if (IS_I965GM(pI830) || IS_IGD_GM(pI830)) {
+    if (IS_I965GM(pI830) || IS_GM45(pI830)) {
 	val = ((pwm_ctl & BACKLIGHT_MODULATION_FREQ_MASK2) >>
 	       BACKLIGHT_MODULATION_FREQ_SHIFT2);
     } else {
@@ -453,7 +453,7 @@ i830_lvds_save (xf86OutputPtr output)
     ScrnInfoPtr		    pScrn = output->scrn;
     I830Ptr		    pI830 = I830PTR(pScrn);
 
-    if (IS_I965GM(pI830) || IS_IGD_GM(pI830))
+    if (IS_I965GM(pI830) || IS_GM45(pI830))
 	pI830->saveBLC_PWM_CTL2 = INREG(BLC_PWM_CTL2);
     pI830->savePP_ON = INREG(LVDSPP_ON);
     pI830->savePP_OFF = INREG(LVDSPP_OFF);
@@ -470,7 +470,7 @@ i830_lvds_restore(xf86OutputPtr output)
     ScrnInfoPtr	pScrn = output->scrn;
     I830Ptr	pI830 = I830PTR(pScrn);
 
-    if (IS_I965GM(pI830) || IS_IGD_GM(pI830))
+    if (IS_I965GM(pI830) || IS_GM45(pI830))
 	OUTREG(BLC_PWM_CTL2, pI830->saveBLC_PWM_CTL2);
     OUTREG(BLC_PWM_CTL, pI830->saveBLC_PWM_CTL);
     OUTREG(LVDSPP_ON, pI830->savePP_ON);
diff --git a/src/i830_memory.c b/src/i830_memory.c
index 6e7a838..0a2faeb 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -1282,7 +1282,7 @@ static void i830_setup_fb_compression(ScrnInfoPtr pScrn)
 	goto out;
     }
 
-    if (IS_IGD_GM(pI830)) {
+    if (IS_GM45(pI830)) {
 	/* Update i830_display.c too if compression ratio changes */
 	compressed_size = fb_height * (pScrn->displayWidth / 4);
     } else {
@@ -1309,7 +1309,7 @@ static void i830_setup_fb_compression(ScrnInfoPtr pScrn)
 	goto out;
     }
 
-    if (!IS_IGD_GM(pI830)) {
+    if (!IS_GM45(pI830)) {
 	pI830->compressed_ll_buffer =
 	    i830_allocate_memory(pScrn, "compressed ll buffer",
 				 FBC_LL_SIZE + FBC_LL_PAD, KB(4),
diff --git a/src/i830_quirks.c b/src/i830_quirks.c
index f7659f0..e81b27c 100644
--- a/src/i830_quirks.c
+++ b/src/i830_quirks.c
@@ -266,9 +266,9 @@ static i830_quirk i830_quirk_list[] = {
     { PCI_CHIP_I965_GM, 0x144d, 0xc510, quirk_ignore_tv },
 
     /* HP Compaq 6730s has no TV output */
-    { PCI_CHIP_IGD_GM, 0x103c, 0x30e8, quirk_ignore_tv },
+    { PCI_CHIP_GM45_GM, 0x103c, 0x30e8, quirk_ignore_tv },
     /* HP Pavilion ze4944ea needs pipe A force quirk (See LP: #242389) */
-    { PCI_CHIP_IGD_GM, 0x103c, 0x3084, quirk_pipea_force },
+    { PCI_CHIP_GM45_GM, 0x103c, 0x3084, quirk_pipea_force },
 
     /* Thinkpad R31 needs pipe A force quirk */
     { PCI_CHIP_I830_M, 0x1014, 0x0505, quirk_pipea_force },
diff --git a/src/i965_render.c b/src/i965_render.c
index a3c7f49..a13aec2 100644
--- a/src/i965_render.c
+++ b/src/i965_render.c
@@ -1035,7 +1035,7 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture,
         BEGIN_BATCH(12);
 
         /* Match Mesa driver setup */
-	if (IS_IGD_GM(pI830) || IS_G4X(pI830))
+	if (IS_GM45(pI830) || IS_G4X(pI830))
 	    OUT_BATCH(NEW_PIPELINE_SELECT | PIPELINE_SELECT_3D);
 	else
 	    OUT_BATCH(BRW_PIPELINE_SELECT | PIPELINE_SELECT_3D);
diff --git a/src/i965_video.c b/src/i965_video.c
index 4572e13..4c79259 100644
--- a/src/i965_video.c
+++ b/src/i965_video.c
@@ -584,7 +584,7 @@ I965DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
     {
 	BEGIN_BATCH(12);
 	/* Match Mesa driver setup */
-	if (IS_IGD_GM(pI830) || IS_G4X(pI830))
+	if (IS_GM45(pI830) || IS_G4X(pI830))
 	    OUT_BATCH(NEW_PIPELINE_SELECT | PIPELINE_SELECT_3D);
 	else
 	    OUT_BATCH(BRW_PIPELINE_SELECT | PIPELINE_SELECT_3D);
commit cb4c1fa7499d82beb01566aaf1f323a03ebc1ae4
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Wed Jul 2 11:12:54 2008 +0800

    Give asus and eeepc backlight method higher priority
    
    On #16418, Evgeniy Manachkin <sfstudio at mail.ru> reported that
    last asus and eeepc backlight patch is wrong, as acpi_video0 method
    will take priority and doesn't work.
    (cherry picked from commit 6506ac7aa008436158db4f4196802cab462f3446)

diff --git a/src/i830_lvds.c b/src/i830_lvds.c
index 4f62a2b..b5e0c45 100644
--- a/src/i830_lvds.c
+++ b/src/i830_lvds.c
@@ -83,6 +83,8 @@ struct i830_lvds_priv {
  * List of available kernel interfaces in priority order
  */
 static char *backlight_interfaces[] = {
+    "asus-laptop",
+    "eeepc",
     "thinkpad_screen",
     "acpi_video1",
     "acpi_video0",
commit 1bfafe075b1db12d42ce40393d0be2137644489a
Author: Dave Airlie <airlied at linux.ie>
Date:   Tue Jul 1 18:51:18 2008 +1000

    intel: fix drm check.
    
    The -mm check is broken now that 2.3.1 is out.. make it 2.4.0, to be fixed
    with GEM etc.
    (cherry picked from commit 55678c64bc6e3ed613ea6db14c105c18a0cf28ce)

diff --git a/configure.ac b/configure.ac
index af87299..2dabd4f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -201,7 +201,7 @@ if test "$DRI" = yes; then
         PKG_CHECK_MODULES(DRI, [libdrm xf86driproto glproto])
         AC_DEFINE(XF86DRI,1,[Enable DRI driver support])
         AC_DEFINE(XF86DRI_DEVEL,1,[Enable developmental DRI driver support])
-	PKG_CHECK_MODULES(DRI_MM, [libdrm >= 2.3.1],[DRI_MM=yes], [DRI_MM=no])
+	PKG_CHECK_MODULES(DRI_MM, [libdrm >= 2.4.0],[DRI_MM=yes], [DRI_MM=no])
 	if test "x$DRI_MM" = xyes; then
 		AC_DEFINE(XF86DRI_MM,1,[Extended DRI memory management])
 	fi
commit 696f9783cc0e269ac8c5c65d8889f22524b5c5e4
Author: Roland Test-tools Bär <roland at verifysoft.de>
Date:   Mon Jun 30 10:32:42 2008 -0700

    i810: Remove an effectively unused variable (only used in an incorrect free())
    
    Bug #15401.
    (cherry picked from commit 0597d94001afe0a9a34104285ce4dffc75b68071)

diff --git a/src/xvmc/I810XvMC.c b/src/xvmc/I810XvMC.c
index 03be251..ce5395a 100644
--- a/src/xvmc/I810XvMC.c
+++ b/src/xvmc/I810XvMC.c
@@ -130,7 +130,6 @@ Status XvMCCreateContext(Display *display, XvPortID port,
 			 int surface_type_id, int width, int height, int flags,
 			 XvMCContext *context) {  
   i810XvMCContext *pI810XvMC;
-  char busIdString[10];
   int priv_count;
   uint *priv_data;
   uint magic;
@@ -217,7 +216,6 @@ Status XvMCCreateContext(Display *display, XvPortID port,
   /* Open DRI Device */
   if((pI810XvMC->fd = drmOpen("i810",NULL)) < 0) {
     printf("DRM Device for i810 could not be opened.\n");
-    free(busIdString);
     free(pI810XvMC);
     return BadAccess;
   } /* !pI810XvMC->fd */
commit 8fea51cf37c613881a2655ea7a57a5b500b63770
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Fri Jun 27 11:21:59 2008 +0800

    Fix SDVOC typo
    (cherry picked from commit 37661d916e8384f537d5ed8cbec66a93795c6a05)

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 28505c8..dff7d51 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -931,7 +931,7 @@ I830SetupOutputs(ScrnInfoPtr pScrn)
 	    i830_hdmi_init(pScrn, SDVOB);
       }
 
-      if (INREG(SDVOB) & SDVO_DETECTED) {
+      if (INREG(SDVOC) & SDVO_DETECTED) {
 	 Bool found = i830_sdvo_init(pScrn, SDVOC);
 
 	 if (!found && SUPPORTS_INTEGRATED_HDMI(pI830))
commit 6b661fd325408156d563e192d0ea3456b77c1256
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Fri Jun 27 09:54:35 2008 +0800

    xvmc: fix motion_type dump for frame/field picture
    (cherry picked from commit 7834a3b118ae4e034f064257762d5c25ada5fe52)

diff --git a/src/xvmc/intel_xvmc_dump.c b/src/xvmc/intel_xvmc_dump.c
index 12fc52a..419bd0d 100644
--- a/src/xvmc/intel_xvmc_dump.c
+++ b/src/xvmc/intel_xvmc_dump.c
@@ -116,18 +116,25 @@ void intel_xvmc_dump_render(XvMCContext *context, unsigned int picture_structure
 	    fprintf(fp, "intra ");
 	fprintf(fp, ")  ");
 	fprintf(fp, "mc type ");
-	if (mb->motion_type & XVMC_PREDICTION_FIELD)
-	    fprintf(fp, "(field)  ");
-	else if (mb->motion_type & XVMC_PREDICTION_FRAME)
-	    fprintf(fp, "(frame)  ");
-	else if (mb->motion_type & XVMC_PREDICTION_DUAL_PRIME)
-	    fprintf(fp, "(dual-prime)  ");
-	else if (mb->motion_type & XVMC_PREDICTION_16x8)
-	    fprintf(fp, "(16x8)  ");
-	else if (mb->motion_type & XVMC_PREDICTION_4MV)
-	    fprintf(fp, "(4MV)  ");
-	else
-	    fprintf(fp, "(none)  ");
+	if (picture_structure == XVMC_FRAME_PICTURE) {
+	    if (mb->motion_type & XVMC_PREDICTION_FIELD)
+		fprintf(fp, "(field)  ");
+	    else if (mb->motion_type & XVMC_PREDICTION_FRAME)
+		fprintf(fp, "(frame)  ");
+	    else if (mb->motion_type & XVMC_PREDICTION_DUAL_PRIME)
+		fprintf(fp, "(dual-prime)  ");
+	    else
+		fprintf(fp, "(unknown %d)  ", mb->motion_type);
+	} else { /* field */
+	    if (mb->motion_type & XVMC_PREDICTION_FIELD)
+		fprintf(fp, "(field)  ");
+	    else if (mb->motion_type & XVMC_PREDICTION_DUAL_PRIME)
+		fprintf(fp, "(dual-prime)  ");
+	    else if (mb->motion_type & XVMC_PREDICTION_16x8)
+		fprintf(fp, "(16x8)  ");
+	    else
+		fprintf(fp, "(unknown %d)  ", mb->motion_type);
+	}
 
 	if (mb->dct_type == XVMC_DCT_TYPE_FRAME)
 	    fprintf(fp, "dct type (frame)  ");
commit ed051008e77536dc3ab55b1343d0248f121416c1
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Fri Jun 27 09:39:02 2008 +0800

    xvmc: Don't copy on xvmc surface in PutImage
    
    As xvmc rendering result has already been in fb, we shouldn't
    do extra copy on it. Although special care is required for i915
    xvmc surface pitch alignment, which must be at least 1KB aligned.
    So video display function should take it into acount instead of
    always setting Y pitch to be double of U/V pitch.
    (cherry picked from commit 989ec9e8a69f909cb64f17e4465982613b4b054d)

diff --git a/src/common.h b/src/common.h
index 1765bb5..b67b20b 100644
--- a/src/common.h
+++ b/src/common.h
@@ -362,6 +362,7 @@ extern int I810_DEBUG;
  			    DEVICE_ID(pI810->PciInfo) == PCI_CHIP_Q35_G ||\
  			    DEVICE_ID(pI810->PciInfo) == PCI_CHIP_Q33_G)
 #define IS_I9XX(pI810) (IS_I915G(pI810) || IS_I915GM(pI810) || IS_I945G(pI810) || IS_I945GM(pI810) || IS_I965G(pI810) || IS_G33CLASS(pI810))
+#define IS_I915(pI810) (IS_I915G(pI810) || IS_I915GM(pI810) || IS_I945G(pI810) || IS_I945GM(pI810) || IS_G33CLASS(pI810))
 
 #define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810) || IS_I915GM(pI810) || IS_I945GM(pI810) || IS_I965GM(pI810) || IS_IGD_GM(pI810))
 /* mark chipsets for using gfx VM offset for overlay */
diff --git a/src/i830.h b/src/i830.h
index 00a5059..570db13 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -417,7 +417,6 @@ typedef struct _I830Rec {
 #ifdef INTEL_XVMC
    /* For XvMC */
    Bool XvMCEnabled;
-   Bool IsXvMCSurface;
 #endif
 
    XF86ModReqInfo shadowReq; /* to test for later libshadow */
diff --git a/src/i830_hwmc.c b/src/i830_hwmc.c
index 22fb69e..787d93d 100644
--- a/src/i830_hwmc.c
+++ b/src/i830_hwmc.c
@@ -56,7 +56,7 @@ Bool intel_xvmc_probe(ScrnInfoPtr pScrn)
 	return FALSE;
 
     if (IS_I9XX(pI830)) {
-	if (!IS_I965G(pI830))
+	if (IS_I915(pI830))
 	    ret = intel_xvmc_set_driver(&i915_xvmc_driver);
 	/*
 	else
diff --git a/src/i830_video.c b/src/i830_video.c
index 7b81b04..486f670 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2210,7 +2210,8 @@ I830PutImage(ScrnInfoPtr pScrn,
     I830OverlayRegPtr overlay;
     PixmapPtr pPixmap;
     INT32 x1, x2, y1, y2;
-    int srcPitch, srcPitch2 = 0, dstPitch, destId;
+    int srcPitch = 0, srcPitch2 = 0, dstPitch, destId;
+    int dstPitch2 = 0;
     int top, left, npixels, nlines, size;
     BoxRec dstBox;
     int pitchAlignMask;
@@ -2285,13 +2286,11 @@ I830PutImage(ScrnInfoPtr pScrn,
     case FOURCC_I420:
 	srcPitch = (width + 0x3) & ~0x3;
 	srcPitch2 = ((width >> 1) + 0x3) & ~0x3;
+	break;
 #ifdef INTEL_XVMC
-        if (pI830->IsXvMCSurface) {
-            srcPitch = (width + 0x3ff) & ~0x3ff;
-            srcPitch2 = ((width >> 1) + 0x3ff) & ~0x3ff;
-        }
-#endif
+    case FOURCC_XVMC:
 	break;
+#endif
     case FOURCC_UYVY:
     case FOURCC_YUY2:
     default:
@@ -2304,6 +2303,11 @@ I830PutImage(ScrnInfoPtr pScrn,
      */
     if (pPriv->textured) {
 	pitchAlignMask = 3;
+#ifdef INTEL_XVMC
+	/* for i915 xvmc, hw requires at least 1kb aligned surface */
+	if ((id == FOURCC_XVMC) && IS_I915(pI830))
+	    pitchAlignMask = 0x3ff;
+#endif
     } else {
 	if (IS_I965G(pI830))
 	    pitchAlignMask = 255;
@@ -2317,9 +2321,6 @@ I830PutImage(ScrnInfoPtr pScrn,
     switch (destId) {
     case FOURCC_YV12:
     case FOURCC_I420:
-#ifdef INTEL_XVMC
-    case FOURCC_XVMC:
-#endif
 	if (pPriv->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
 	    dstPitch = ((height / 2) + pitchAlignMask) & ~pitchAlignMask;
 	    size = dstPitch * width * 3;
@@ -2339,7 +2340,14 @@ I830PutImage(ScrnInfoPtr pScrn,
 	    size = dstPitch * height;
 	}
 	break;
-    default:  
+#ifdef INTEL_XVMC
+    case FOURCC_XVMC:
+	dstPitch = ((width / 2) + pitchAlignMask ) & ~pitchAlignMask;
+	dstPitch2 = (width + pitchAlignMask ) & ~pitchAlignMask;
+	size = 0;
+	break;
+#endif
+    default:
 	dstPitch = 0;
 	size = 0;
 	break;
@@ -2384,24 +2392,35 @@ I830PutImage(ScrnInfoPtr pScrn,
     (pPriv->doubleBuffer ? size * 2 : size);
 
     /* fixup pointers */
-    pPriv->YBuf0offset = pPriv->buf->offset;
-    if (pPriv->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
-	pPriv->UBuf0offset = pPriv->YBuf0offset + (dstPitch * 2 * width);
-	pPriv->VBuf0offset = pPriv->UBuf0offset + (dstPitch * width / 2);
-	if(pPriv->doubleBuffer) {
-	    pPriv->YBuf1offset = pPriv->YBuf0offset + size;
-	    pPriv->UBuf1offset = pPriv->YBuf1offset + (dstPitch * 2 * width);
-	    pPriv->VBuf1offset = pPriv->UBuf1offset + (dstPitch * width / 2);
-	}
+#ifdef INTEL_XVMC
+    if (id == FOURCC_XVMC && IS_I915(pI830)) {
+	pPriv->YBuf0offset = (uint32_t)buf;
+	pPriv->VBuf0offset = pPriv->YBuf0offset + (dstPitch2 * height);
+	pPriv->UBuf0offset = pPriv->VBuf0offset + (dstPitch * height / 2);
+	destId = FOURCC_YV12;
     } else {
-	pPriv->UBuf0offset = pPriv->YBuf0offset + (dstPitch * 2 * height);
-	pPriv->VBuf0offset = pPriv->UBuf0offset + (dstPitch * height / 2);
-	if(pPriv->doubleBuffer) {
-	    pPriv->YBuf1offset = pPriv->YBuf0offset + size;
-	    pPriv->UBuf1offset = pPriv->YBuf1offset + (dstPitch * 2 * height);
-	    pPriv->VBuf1offset = pPriv->UBuf1offset + (dstPitch * height / 2);
+#endif
+	pPriv->YBuf0offset = pPriv->buf->offset;
+	if (pPriv->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
+	    pPriv->UBuf0offset = pPriv->YBuf0offset + (dstPitch * 2 * width);
+	    pPriv->VBuf0offset = pPriv->UBuf0offset + (dstPitch * width / 2);
+	    if(pPriv->doubleBuffer) {
+		pPriv->YBuf1offset = pPriv->YBuf0offset + size;
+		pPriv->UBuf1offset = pPriv->YBuf1offset + (dstPitch * 2 * width);
+		pPriv->VBuf1offset = pPriv->UBuf1offset + (dstPitch * width / 2);
+	    }
+	} else {
+	    pPriv->UBuf0offset = pPriv->YBuf0offset + (dstPitch * 2 * height);
+	    pPriv->VBuf0offset = pPriv->UBuf0offset + (dstPitch * height / 2);
+	    if(pPriv->doubleBuffer) {
+		pPriv->YBuf1offset = pPriv->YBuf0offset + size;
+		pPriv->UBuf1offset = pPriv->YBuf1offset + (dstPitch * 2 * height);
+		pPriv->VBuf1offset = pPriv->UBuf1offset + (dstPitch * height / 2);
+	    }
 	}
+#ifdef INTEL_XVMC
     }
+#endif
 
     /* Pick the idle buffer */
     if (!pPriv->textured && *pI830->overlayOn && pPriv->doubleBuffer)
@@ -2473,7 +2492,7 @@ I830PutImage(ScrnInfoPtr pScrn,
 				 src_w, src_h, drw_w, drw_h, pPixmap);
     } else {
 	I915DisplayVideoTextured(pScrn, pPriv, destId, clipBoxes, width, height,
-				 dstPitch, x1, y1, x2, y2,
+				 dstPitch, dstPitch2, x1, y1, x2, y2,
 				 src_w, src_h, drw_w, drw_h, pPixmap);
     }
     if (pPriv->textured) {
diff --git a/src/i830_video.h b/src/i830_video.h
index 52e6b4f..91f767f 100644
--- a/src/i830_video.h
+++ b/src/i830_video.h
@@ -78,7 +78,7 @@ typedef struct {
 
 void I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv,
 			      int id, RegionPtr dstRegion, short width,
-			      short height, int video_pitch,
+			      short height, int video_pitch, int video_pitch2,
 			      int x1, int y1, int x2, int y2,
 			      short src_w, short src_h,
 			      short drw_w, short drw_h,
diff --git a/src/i915_hwmc.c b/src/i915_hwmc.c
index c345175..659638e 100644
--- a/src/i915_hwmc.c
+++ b/src/i915_hwmc.c
@@ -790,7 +790,6 @@ static int i915_xvmc_put_image(ScrnInfoPtr pScrn,
 	short height, Bool sync, RegionPtr clipBoxes, pointer data,
 	DrawablePtr pDraw)
 {
-    I830Ptr pI830 = I830PTR(pScrn);
     I915XvMCPtr pXvMC = (I915XvMCPtr)xvmc_driver->devPrivate;
     struct intel_xvmc_command *xvmc_cmd = (struct intel_xvmc_command *)buf;
     int ret;
@@ -806,10 +805,8 @@ static int i915_xvmc_put_image(ScrnInfoPtr pScrn,
 		    return 1;
 		}
 
-		buf = pI830->FbBase +
-		    pXvMC->sfprivs[xvmc_cmd->srfNo]->surface->offset;
-		id = xvmc_cmd->real_id;
-		pI830->IsXvMCSurface = 1;
+		/* use char *buf to hold our surface offset...hacky! */
+		buf = (unsigned char *)pXvMC->sfprivs[xvmc_cmd->srfNo]->surface->offset;
 		break;
 	    default:
 		return 0;
@@ -819,7 +816,6 @@ static int i915_xvmc_put_image(ScrnInfoPtr pScrn,
     ret = pXvMC->savePutImage(pScrn, src_x, src_y, drw_x, drw_y, src_w, src_h,
                         drw_w, drw_h, id, buf, width, height, sync, clipBoxes,
 			data, pDraw);
-    pI830->IsXvMCSurface = 0;
     return ret;
 }
 
diff --git a/src/i915_hwmc.h b/src/i915_hwmc.h
index 7d90afc..8f6557d 100644
--- a/src/i915_hwmc.h
+++ b/src/i915_hwmc.h
@@ -29,6 +29,7 @@
 
 #include "i830_hwmc.h"
 
+/* i915 hw requires surface to be at least 1KB aligned */
 #define STRIDE(w)               (((w) + 0x3ff) & ~0x3ff)
 #define SIZE_Y420(w, h)         (h * STRIDE(w))
 #define SIZE_UV420(w, h)        ((h >> 1) * STRIDE(w >> 1))
diff --git a/src/i915_video.c b/src/i915_video.c
index aeb3729..d2da94b 100644
--- a/src/i915_video.c
+++ b/src/i915_video.c
@@ -42,7 +42,7 @@
 void
 I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
 			 RegionPtr dstRegion,
-			 short width, short height, int video_pitch,
+			 short width, short height, int video_pitch, int video_pitch2,
 			 int x1, int y1, int x2, int y2,
 			 short src_w, short src_h, short drw_w, short drw_h,
 			 PixmapPtr pPixmap)
@@ -271,7 +271,13 @@ I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
       ms3 |= (height - 1) << MS3_HEIGHT_SHIFT;
       ms3 |= (width - 1) << MS3_WIDTH_SHIFT;
       OUT_BATCH(ms3);
-      OUT_BATCH(((video_pitch * 2 / 4) - 1) << MS4_PITCH_SHIFT);
+      /* check to see if Y has special pitch than normal double u/v pitch,
+       * e.g i915 XvMC hw requires at least 1K alignment, so Y pitch might
+       * be same as U/V's.*/
+      if (video_pitch2)
+	  OUT_BATCH(((video_pitch2 / 4) - 1) << MS4_PITCH_SHIFT);
+      else
+	  OUT_BATCH(((video_pitch * 2 / 4) - 1) << MS4_PITCH_SHIFT);
 
       OUT_BATCH(pPriv->UBuf0offset);
       ms3 = MAPSURF_8BIT | MT_8BIT_I8 | MS3_USE_FENCE_REGS;
commit eae16b3b3e46177f882555c15751ff1219701e7c
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Thu Jun 26 14:22:34 2008 +0800

    xvmc: enlarge batch buffer size
    (cherry picked from commit 550082070a3fdb951e3cf08974dc56276c0a739c)

diff --git a/src/i830_hwmc.c b/src/i830_hwmc.c
index 7586ff7..22fb69e 100644
--- a/src/i830_hwmc.c
+++ b/src/i830_hwmc.c
@@ -122,9 +122,10 @@ Bool intel_xvmc_screen_init(ScreenPtr pScreen)
 Bool intel_xvmc_init_batch(ScrnInfoPtr pScrn)
 {
     I830Ptr pI830 = I830PTR(pScrn);
+    int size = KB(64);
 
     if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC] batch buffer",
-                                   &(xvmc_driver->batch), 8 * 1024,
+                                   &(xvmc_driver->batch), size,
                                    ALIGN_BOTH_ENDS))
         return FALSE;
 
commit a5867a55abca1d16ff57c0e39008e7c7738a724c
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Thu Jun 26 14:20:05 2008 +0800

    xvmc: only allocate memory requiring physical address on 915G
    
    Later 945-ish chipset can use graphics address instead.
    (cherry picked from commit d50cec6ef9e2178ea663e58d548390f0f3da7692)

diff --git a/src/i915_hwmc.c b/src/i915_hwmc.c
index 973cabf..c345175 100644
--- a/src/i915_hwmc.c
+++ b/src/i915_hwmc.c
@@ -319,8 +319,8 @@ static Bool i915_allocate_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *c
     I830Ptr pI830 = I830PTR(pScrn);
     int flags = ALIGN_BOTH_ENDS;
 
-    if (IS_I915G(pI830) || IS_I915GM(pI830) ||
-	    IS_I945G(pI830) || IS_I945GM(pI830))
+    /* on 915G/GM, load indirect can only use physical address...sigh */
+    if (IS_I915G(pI830) || IS_I915GM(pI830))
         flags |= NEED_PHYSICAL_ADDR;
 
     if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC]Static Indirect State",
@@ -353,14 +353,14 @@ static Bool i915_allocate_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *c
         return FALSE;
     }
 
-    if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC]Correction Data Buffer", 
+    if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC]Correction Data Buffer",
                                    &(ctxpriv->mcCorrdata), 512 * 1024,
                                    ALIGN_BOTH_ENDS)) {
         return FALSE;
     }
 
-    if (0)
-	i830_describe_allocations(pScrn, 1, "");
+    if (1)
+	i830_describe_allocations(pScrn, 1, "i915_mc: ");
 
     return TRUE;
 }
@@ -500,29 +500,32 @@ static int i915_xvmc_create_context (ScrnInfoPtr pScrn, XvMCContextPtr pContext,
     contextRec->sis.handle = ctxpriv->sis_handle;
     contextRec->sis.offset = ctxpriv->mcStaticIndirectState->offset;
     contextRec->sis.size = ctxpriv->mcStaticIndirectState->size;
-    contextRec->sis.bus_addr = ctxpriv->mcStaticIndirectState->bus_addr;
     contextRec->ssb.handle = ctxpriv->ssb_handle;
     contextRec->ssb.offset = ctxpriv->mcSamplerState->offset;
     contextRec->ssb.size = ctxpriv->mcSamplerState->size;
-    contextRec->ssb.bus_addr = ctxpriv->mcSamplerState->bus_addr;
     contextRec->msb.handle = ctxpriv->msb_handle;
     contextRec->msb.offset = ctxpriv->mcMapState->offset;
     contextRec->msb.size = ctxpriv->mcMapState->size;
-    contextRec->msb.bus_addr = ctxpriv->mcMapState->bus_addr;
     contextRec->psp.handle = ctxpriv->psp_handle;
     contextRec->psp.offset = ctxpriv->mcPixelShaderProgram->offset;
     contextRec->psp.size = ctxpriv->mcPixelShaderProgram->size;
-    contextRec->psp.bus_addr = ctxpriv->mcPixelShaderProgram->bus_addr;
     contextRec->psc.handle = ctxpriv->psc_handle;
     contextRec->psc.offset = ctxpriv->mcPixelShaderConstants->offset;
     contextRec->psc.size = ctxpriv->mcPixelShaderConstants->size;
-    contextRec->psc.bus_addr = ctxpriv->mcPixelShaderConstants->bus_addr;
     contextRec->corrdata.handle = ctxpriv->corrdata_handle;
     contextRec->corrdata.offset = ctxpriv->mcCorrdata->offset;
     contextRec->corrdata.size = ctxpriv->mcCorrdata->size;
     contextRec->sarea_priv_offset = sizeof(XF86DRISAREARec);
     contextRec->deviceID = pI830DRI->deviceID;
 
+    if (IS_I915G(pI830) || IS_I915GM(pI830)) {
+	contextRec->sis.bus_addr = ctxpriv->mcStaticIndirectState->bus_addr;
+	contextRec->ssb.bus_addr = ctxpriv->mcSamplerState->bus_addr;
+	contextRec->msb.bus_addr = ctxpriv->mcMapState->bus_addr;
+	contextRec->psp.bus_addr = ctxpriv->mcPixelShaderProgram->bus_addr;
+	contextRec->psc.bus_addr = ctxpriv->mcPixelShaderConstants->bus_addr;
+    }
+
     pXvMC->ncontexts++;
     pXvMC->contexts[i] = pContext->context_id;
     pXvMC->ctxprivs[i] = ctxpriv;
diff --git a/src/xvmc/i915_xvmc.c b/src/xvmc/i915_xvmc.c
index f412125..27d1380 100644
--- a/src/xvmc/i915_xvmc.c
+++ b/src/xvmc/i915_xvmc.c
@@ -350,9 +350,9 @@ static void i915_mc_one_time_state_init(XvMCContext *context)
     psp_state *psp = NULL;
     psc_state *psc = NULL;
     i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
-    int mem_select = 1;
     struct i915_3dstate_load_state_immediate_1 *load_state_immediate_1;
     struct i915_3dstate_load_indirect *load_indirect;
+    int mem_select;
 
     /* 3DSTATE_LOAD_STATE_IMMEDIATE_1 */
     one_time_load_state_imm1_size = sizeof(*load_state_immediate_1) + sizeof(*s3) + sizeof(*s6);
@@ -398,13 +398,14 @@ static void i915_mc_one_time_state_init(XvMCContext *context)
     load_indirect->dw0.length = (one_time_load_indirect_size >> 2) - 2;
 
     if (pI915XvMC->deviceID == PCI_CHIP_I915_G ||
-        pI915XvMC->deviceID == PCI_CHIP_I915_GM ||
-        pI915XvMC->deviceID == PCI_CHIP_I945_G ||
-        pI915XvMC->deviceID == PCI_CHIP_I945_GM)
-        mem_select = 0;
+        pI915XvMC->deviceID == PCI_CHIP_I915_GM)
+	mem_select = 0; /* use physical address */
+    else
+	mem_select = 1; /* use gfx address */
 
     load_indirect->dw0.mem_select = mem_select;
 
+
     /* Dynamic indirect state buffer */
     dis = (dis_state *)(++load_indirect);
     dis->dw0.valid = 0;
@@ -420,7 +421,7 @@ static void i915_mc_one_time_state_init(XvMCContext *context)
     if (mem_select)
         ssb->dw0.buffer_address = (pI915XvMC->ssb.offset >> 2);
     else
-        ssb->dw0.buffer_address = (pI915XvMC->ssb.bus_addr >> 2);
+	ssb->dw0.buffer_address = (pI915XvMC->ssb.bus_addr >> 2);
 
     /* Pixel shader program buffer */
     psp = (psp_state *)(++ssb);
@@ -429,9 +430,9 @@ static void i915_mc_one_time_state_init(XvMCContext *context)
     psp->dw1.length = 66; /* 4 + 16 + 16 + 31 - 1 */
 
     if (mem_select)
-        psp->dw0.buffer_address = (pI915XvMC->psp.offset >> 2);
+	psp->dw0.buffer_address = (pI915XvMC->psp.offset >> 2);
     else
-        psp->dw0.buffer_address = (pI915XvMC->psp.bus_addr >> 2);
+	psp->dw0.buffer_address = (pI915XvMC->psp.bus_addr >> 2);
 
     /* Pixel shader constant buffer */
     psc = (psc_state *)(++psp);
@@ -725,7 +726,7 @@ static void i915_mc_load_indirect_render_init(XvMCContext *context)
     sis_state *sis;
     msb_state *msb;
     struct i915_3dstate_load_indirect *load_indirect;
-    int mem_select = 1;
+    int mem_select;
 
     mc_render_load_indirect_size = sizeof(*load_indirect) + sizeof(*sis)
 					+ sizeof(*msb);
@@ -738,10 +739,10 @@ static void i915_mc_load_indirect_render_init(XvMCContext *context)
     load_indirect->dw0.length = (mc_render_load_indirect_size >> 2) - 2;
 
     if (pI915XvMC->deviceID == PCI_CHIP_I915_G ||
-        pI915XvMC->deviceID == PCI_CHIP_I915_GM ||
-        pI915XvMC->deviceID == PCI_CHIP_I945_G ||
-        pI915XvMC->deviceID == PCI_CHIP_I945_GM)
+        pI915XvMC->deviceID == PCI_CHIP_I915_GM)
         mem_select = 0;
+    else
+	mem_select = 1;
 
     load_indirect->dw0.mem_select = mem_select;
 
@@ -752,9 +753,9 @@ static void i915_mc_load_indirect_render_init(XvMCContext *context)
     sis->dw1.length = 16; /* 4 * 3 + 2 + 3 - 1 */
 
     if (mem_select)
-        sis->dw0.buffer_address = (pI915XvMC->sis.offset >> 2);
+	sis->dw0.buffer_address = (pI915XvMC->sis.offset >> 2);
     else
-        sis->dw0.buffer_address = (pI915XvMC->sis.bus_addr >> 2);
+	sis->dw0.buffer_address = (pI915XvMC->sis.bus_addr >> 2);
 
     /* Map state buffer (reference buffer info) */
     msb = (msb_state *)(++sis);
@@ -763,9 +764,9 @@ static void i915_mc_load_indirect_render_init(XvMCContext *context)
     msb->dw1.length = 23; /* 3 * 8 - 1 */
 
     if (mem_select)
-        msb->dw0.buffer_address = (pI915XvMC->msb.offset >> 2);
+	msb->dw0.buffer_address = (pI915XvMC->msb.offset >> 2);
     else
-        msb->dw0.buffer_address = (pI915XvMC->msb.bus_addr >> 2);
+	msb->dw0.buffer_address = (pI915XvMC->msb.bus_addr >> 2);
 }
 
 static void i915_mc_load_indirect_render_emit(void)
@@ -1613,9 +1614,7 @@ static Status i915_xvmc_mc_create_context(Display *display, XvMCContext *context
     pI915XvMC->psc.size = tmpComm->psc.size;
 
     if (pI915XvMC->deviceID == PCI_CHIP_I915_G ||
-        pI915XvMC->deviceID == PCI_CHIP_I915_GM ||
-        pI915XvMC->deviceID == PCI_CHIP_I945_G ||
-        pI915XvMC->deviceID == PCI_CHIP_I945_GM) {
+        pI915XvMC->deviceID == PCI_CHIP_I915_GM) {
         pI915XvMC->sis.bus_addr = tmpComm->sis.bus_addr;
         pI915XvMC->ssb.bus_addr = tmpComm->ssb.bus_addr;
         pI915XvMC->msb.bus_addr = tmpComm->msb.bus_addr;
commit 35a40f3df2d8707f61a3f9f0d3357bfe6bd57ed6
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Thu Jun 26 10:05:21 2008 +0800

    xvmc: init mc render load indirect command once
    (cherry picked from commit d1c34d8c0e7ae2a1d952791343e131837fbfda99)

diff --git a/src/xvmc/i915_xvmc.c b/src/xvmc/i915_xvmc.c
index f04eb51..f412125 100644
--- a/src/xvmc/i915_xvmc.c
+++ b/src/xvmc/i915_xvmc.c
@@ -134,6 +134,10 @@ static uint32_t *one_time_load_state_imm1;
 static uint32_t *one_time_load_indirect;
 static int one_time_load_state_imm1_size, one_time_load_indirect_size;
 
+/* load indirect buffer for mc rendering */
+static uint32_t *mc_render_load_indirect;
+static int mc_render_load_indirect_size;
+
 static void i915_mc_one_time_context_init(XvMCContext *context)
 {
     unsigned int dest, src0, src1, src2;
@@ -715,24 +719,23 @@ static void i915_flush(int map, int render)
     intelBatchbufferData(&mi_flush, sizeof(mi_flush), 0);
 }
 
-static void i915_mc_load_sis_msb_buffers(XvMCContext *context)
+static void i915_mc_load_indirect_render_init(XvMCContext *context)
 {
-    struct i915_3dstate_load_indirect *load_indirect;
-    sis_state *sis = NULL;
-    msb_state *msb = NULL;
     i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
-    void *base = NULL;
-    unsigned int size;
+    sis_state *sis;
+    msb_state *msb;
+    struct i915_3dstate_load_indirect *load_indirect;
     int mem_select = 1;
 
-    /* 3DSTATE_LOAD_INDIRECT */
-    size = sizeof(*load_indirect) + sizeof(*sis) + sizeof(*msb);
-    base = calloc(1, size);
-    load_indirect = (struct i915_3dstate_load_indirect *)base;
+    mc_render_load_indirect_size = sizeof(*load_indirect) + sizeof(*sis)
+					+ sizeof(*msb);
+    mc_render_load_indirect = calloc(1, mc_render_load_indirect_size);
+
+    load_indirect = (struct i915_3dstate_load_indirect *)mc_render_load_indirect;
     load_indirect->dw0.type = CMD_3D;
     load_indirect->dw0.opcode = OPC_3DSTATE_LOAD_INDIRECT;
     load_indirect->dw0.block_mask = BLOCK_SIS | BLOCK_MSB;
-    load_indirect->dw0.length = (size >> 2) - 2;
+    load_indirect->dw0.length = (mc_render_load_indirect_size >> 2) - 2;
 
     if (pI915XvMC->deviceID == PCI_CHIP_I915_G ||
         pI915XvMC->deviceID == PCI_CHIP_I915_GM ||
@@ -742,30 +745,32 @@ static void i915_mc_load_sis_msb_buffers(XvMCContext *context)
 
     load_indirect->dw0.mem_select = mem_select;
 
-    /* SIS */
+    /* Static Indirect state buffer (dest buffer info) */
     sis = (sis_state *)(++load_indirect);
     sis->dw0.valid = 1;
     sis->dw0.force = 1;
-    sis->dw1.length = 16; // 4 * 3 + 2 + 3 - 1
+    sis->dw1.length = 16; /* 4 * 3 + 2 + 3 - 1 */
 
     if (mem_select)
         sis->dw0.buffer_address = (pI915XvMC->sis.offset >> 2);
     else
         sis->dw0.buffer_address = (pI915XvMC->sis.bus_addr >> 2);
 
-    /* MSB */
+    /* Map state buffer (reference buffer info) */
     msb = (msb_state *)(++sis);
     msb->dw0.valid = 1;
     msb->dw0.force = 1;
-    msb->dw1.length = 23; // 3 * 8 - 1
+    msb->dw1.length = 23; /* 3 * 8 - 1 */
 
     if (mem_select)
         msb->dw0.buffer_address = (pI915XvMC->msb.offset >> 2);
     else
         msb->dw0.buffer_address = (pI915XvMC->msb.bus_addr >> 2);
+}
 
-    intelBatchbufferData(base, size, 0);
-    free(base);
+static void i915_mc_load_indirect_render_emit(void)
+{
+    i915_emit_batch(mc_render_load_indirect, mc_render_load_indirect_size, 0);
 }
 
 static void i915_mc_mpeg_set_origin(XvMCContext *context, XvMCMacroBlock *mb)
@@ -1646,7 +1651,7 @@ static Status i915_xvmc_mc_create_context(Display *display, XvMCContext *context
     pI915XvMC->port = context->port;
     pI915XvMC->ref = 1;
 
-    /* preinit state buffers */
+    /* pre-init state buffers */
     i915_mc_one_time_context_init(context);
     i915_mc_one_time_state_init(context);
 
@@ -1654,6 +1659,7 @@ static Status i915_xvmc_mc_create_context(Display *display, XvMCContext *context
 
     i915_mc_map_state_init(context);
 
+    i915_mc_load_indirect_render_init(context);
     return Success;
 }
 
@@ -1669,6 +1675,7 @@ static int i915_xvmc_mc_destroy_context(Display *display, XvMCContext *context)
 
     free(one_time_load_state_imm1);
     free(one_time_load_indirect);
+    free(mc_render_load_indirect);
     return Success;
 }
 
@@ -1917,7 +1924,9 @@ static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context,
 	    flags, picture_coding_type);
     /* setup reference surfaces */
     i915_mc_map_state_set(context, privPast, privFuture);
-    i915_mc_load_sis_msb_buffers(context);
+
+    i915_mc_load_indirect_render_emit();
+
     i915_mc_mpeg_set_origin(context, &macroblock_array->macro_blocks[first_macroblock]);
 
     for (i = first_macroblock; i < (num_macroblocks + first_macroblock); i++) {
commit a5959d3dd31b33e81e4bca85ace377001b0f2cfe
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Thu Jun 26 09:47:28 2008 +0800

    xvmc: init dest and reference buffer once
    
    Init them right after context create, and only update buffer address
    info later.
    (cherry picked from commit 75e38fa8348198ba151afa37e10be3b0b0b468f8)

diff --git a/src/xvmc/i915_structs.h b/src/xvmc/i915_structs.h
index 7e786e7..b5185cb 100644
--- a/src/xvmc/i915_structs.h
+++ b/src/xvmc/i915_structs.h
@@ -354,7 +354,7 @@ struct i915_3dstate_dest_buffer_variables_mpeg
         unsigned rcontrol : 1;
         unsigned decode_mode : 2;
     } dw1;
-        
+
     struct {
         unsigned pad0 : 1;
         unsigned picture_coding_type : 2;
@@ -374,6 +374,15 @@ struct i915_3dstate_dest_buffer_variables_mpeg
     } dw2;
 };
 
+struct i915_mc_static_indirect_state_buffer {
+    struct i915_3dstate_buffer_info dest_y;
+    struct i915_3dstate_buffer_info dest_u;
+    struct i915_3dstate_buffer_info dest_v;
+    struct i915_3dstate_dest_buffer_variables dest_buf;
+    struct i915_3dstate_dest_buffer_variables_mpeg dest_buf_mpeg;
+    struct i915_3dstate_buffer_info corr;
+};
+
 #define MAP_MAP0        0x0001
 #define MAP_MAP1        0x0002
 #define MAP_MAP2        0x0004
@@ -434,7 +443,18 @@ struct i915_3dstate_map_state
         unsigned map_mask : 16;
         unsigned pad0 : 16;
     } dw1;
-//    struct texture_map *tms;
+};
+
+struct i915_mc_map_state {
+    struct i915_3dstate_map_state y_map;
+    struct texture_map y_forward;
+    struct texture_map y_backward;
+    struct i915_3dstate_map_state u_map;
+    struct texture_map u_forward;
+    struct texture_map u_backward;
+    struct i915_3dstate_map_state v_map;
+    struct texture_map v_forward;
+    struct texture_map v_backward;
 };
 
 #define SAMPLER_SAMPLER0        0x0001
diff --git a/src/xvmc/i915_xvmc.c b/src/xvmc/i915_xvmc.c
index 45acf9b..f04eb51 100644
--- a/src/xvmc/i915_xvmc.c
+++ b/src/xvmc/i915_xvmc.c
@@ -447,290 +447,272 @@ static void i915_mc_one_time_state_emit(void)
     i915_emit_batch(one_time_load_indirect, one_time_load_indirect_size, 0);
 }
 
-static void i915_flush(int map, int render)
+static void i915_mc_static_indirect_state_init(XvMCContext *context)
 {
-    struct i915_mi_flush mi_flush;
-
-    memset(&mi_flush, 0, sizeof(mi_flush));
-    mi_flush.dw0.type = CMD_MI;
-    mi_flush.dw0.opcode = OPC_MI_FLUSH;
-    mi_flush.dw0.map_cache_invalidate = map;
-    mi_flush.dw0.render_cache_flush_inhibit = render;
+    i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
+    struct i915_mc_static_indirect_state_buffer *buffer_info =
+	(struct i915_mc_static_indirect_state_buffer *)pI915XvMC->sis.map;
 
-    intelBatchbufferData(&mi_flush, sizeof(mi_flush), 0);
+    memset(buffer_info, 0, sizeof(*buffer_info));
+    /* dest Y */
+    buffer_info->dest_y.dw0.type = CMD_3D;
+    buffer_info->dest_y.dw0.opcode = OPC_3DSTATE_BUFFER_INFO;
+    buffer_info->dest_y.dw0.length = 1;
+    buffer_info->dest_y.dw1.aux_id = 0;
+    buffer_info->dest_y.dw1.buffer_id = BUFFERID_COLOR_BACK;
+    buffer_info->dest_y.dw1.fence_regs = 0;    /* disabled */ /* FIXME: tiled y for performance */
+    buffer_info->dest_y.dw1.tiled_surface = 0; /* linear */
+    buffer_info->dest_y.dw1.walk = TILEWALK_XMAJOR;
+
+    /* dest U */
+    buffer_info->dest_u.dw0.type = CMD_3D;
+    buffer_info->dest_u.dw0.opcode = OPC_3DSTATE_BUFFER_INFO;
+    buffer_info->dest_u.dw0.length = 1;
+    buffer_info->dest_u.dw1.aux_id = 0;
+    buffer_info->dest_u.dw1.buffer_id = BUFFERID_COLOR_AUX;
+    buffer_info->dest_u.dw1.fence_regs = 0;
+    buffer_info->dest_u.dw1.tiled_surface = 0;
+    buffer_info->dest_u.dw1.walk = TILEWALK_XMAJOR;
+
+    /* dest V */
+    buffer_info->dest_v.dw0.type = CMD_3D;
+    buffer_info->dest_v.dw0.opcode = OPC_3DSTATE_BUFFER_INFO;
+    buffer_info->dest_v.dw0.length = 1;
+    buffer_info->dest_v.dw1.aux_id = 1;
+    buffer_info->dest_v.dw1.buffer_id = BUFFERID_COLOR_AUX;
+    buffer_info->dest_v.dw1.fence_regs = 0;
+    buffer_info->dest_v.dw1.tiled_surface = 0;
+    buffer_info->dest_v.dw1.walk = TILEWALK_XMAJOR;
+
+    buffer_info->dest_buf.dw0.type = CMD_3D;
+    buffer_info->dest_buf.dw0.opcode = OPC_3DSTATE_DEST_BUFFER_VARIABLES;
+    buffer_info->dest_buf.dw0.length = 0;
+    buffer_info->dest_buf.dw1.dest_v_bias = 8; /* 0.5 */
+    buffer_info->dest_buf.dw1.dest_h_bias = 8; /* 0.5 */
+    buffer_info->dest_buf.dw1.color_fmt = COLORBUFFER_8BIT;
+    buffer_info->dest_buf.dw1.v_ls = 0; /* fill later */
+    buffer_info->dest_buf.dw1.v_ls_offset = 0; /* fill later */
+
+    buffer_info->dest_buf_mpeg.dw0.type = CMD_3D;
+    buffer_info->dest_buf_mpeg.dw0.opcode = OPC_3DSTATE_DEST_BUFFER_VARIABLES_MPEG;
+    buffer_info->dest_buf_mpeg.dw0.length = 1;
+    buffer_info->dest_buf_mpeg.dw1.decode_mode = MPEG_DECODE_MC;
+    buffer_info->dest_buf_mpeg.dw1.rcontrol = 0;               /* for MPEG-1/MPEG-2 */
+    buffer_info->dest_buf_mpeg.dw1.bidir_avrg_control = 0;     /* for MPEG-1/MPEG-2/MPEG-4 */
+    buffer_info->dest_buf_mpeg.dw1.abort_on_error = 1;
+    buffer_info->dest_buf_mpeg.dw1.intra8 = 0;         /* 16-bit formatted correction data */
+    buffer_info->dest_buf_mpeg.dw1.tff = 1; /* fill later */
+
+    buffer_info->dest_buf_mpeg.dw1.v_subsample_factor = MC_SUB_1V;
+    buffer_info->dest_buf_mpeg.dw1.h_subsample_factor = MC_SUB_1H;
+
+    buffer_info->corr.dw0.type = CMD_3D;
+    buffer_info->corr.dw0.opcode = OPC_3DSTATE_BUFFER_INFO;
+    buffer_info->corr.dw0.length = 1;
+    buffer_info->corr.dw1.aux_id = 0;
+    buffer_info->corr.dw1.buffer_id = BUFFERID_MC_INTRA_CORR;
+    buffer_info->corr.dw1.aux_id = 0;
+    buffer_info->corr.dw1.fence_regs = 0;
+    buffer_info->corr.dw1.tiled_surface = 0;
+    buffer_info->corr.dw1.walk = 0;
+    buffer_info->corr.dw1.pitch = 0;
+    buffer_info->corr.dw2.base_address = (pI915XvMC->corrdata.offset >> 2);  /* starting DWORD address */
 }
 
-/* for MC picture rendering */
-static void i915_mc_static_indirect_state_buffer(XvMCContext *context,
-	XvMCSurface *surface,
-	unsigned int picture_structure,
-	unsigned int flags,
-	unsigned int picture_coding_type)
+static void i915_mc_static_indirect_state_set(XvMCContext *context, XvMCSurface *dest,
+	unsigned int picture_structure, unsigned int flags, unsigned int picture_coding_type)
 {
-    struct i915_3dstate_buffer_info *buffer_info;
-    struct i915_3dstate_dest_buffer_variables *dest_buffer_variables;
-    struct i915_3dstate_dest_buffer_variables_mpeg *dest_buffer_variables_mpeg;
-    i915XvMCSurface *pI915Surface = (i915XvMCSurface *)surface->privData;
     i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
-    unsigned int w = surface->width;
-
-    /* 3DSTATE_BUFFER_INFO */
-    /* DEST Y */
-    buffer_info = (struct i915_3dstate_buffer_info *)pI915XvMC->sis.map;
-    memset(buffer_info, 0, sizeof(*buffer_info));
-    buffer_info->dw0.type = CMD_3D;
-    buffer_info->dw0.opcode = OPC_3DSTATE_BUFFER_INFO;
-    buffer_info->dw0.length = 1;
-    buffer_info->dw1.aux_id = 0;
-    buffer_info->dw1.buffer_id = BUFFERID_COLOR_BACK;
-    buffer_info->dw1.fence_regs = 0;    /* disabled */ /* FIXME: tiled y for performance */
-    buffer_info->dw1.tiled_surface = 0; /* linear */
-    buffer_info->dw1.walk = TILEWALK_XMAJOR;
-    buffer_info->dw1.pitch = (pI915Surface->yStride >> 2);      /* in DWords */
-    buffer_info->dw2.base_address = (YOFFSET(pI915Surface) >> 2);    /* starting DWORD address */
-
-    /* DEST U */
-    ++buffer_info;
-    memset(buffer_info, 0, sizeof(*buffer_info));
-    buffer_info->dw0.type = CMD_3D;
-    buffer_info->dw0.opcode = OPC_3DSTATE_BUFFER_INFO;
-    buffer_info->dw0.length = 1;
-    buffer_info->dw1.aux_id = 0;
-    buffer_info->dw1.buffer_id = BUFFERID_COLOR_AUX;
-    buffer_info->dw1.fence_regs = 0;
-    buffer_info->dw1.tiled_surface = 0;
-    buffer_info->dw1.walk = TILEWALK_XMAJOR;
-    buffer_info->dw1.pitch = (pI915Surface->uvStride >> 2);      /* in DWords */
-    buffer_info->dw2.base_address = (UOFFSET(pI915Surface) >> 2);      /* starting DWORD address */
-
-    /* DEST V */
-    ++buffer_info;
-    memset(buffer_info, 0, sizeof(*buffer_info));
-    buffer_info->dw0.type = CMD_3D;
-    buffer_info->dw0.opcode = OPC_3DSTATE_BUFFER_INFO;
-    buffer_info->dw0.length = 1;
-    buffer_info->dw1.aux_id = 1;
-    buffer_info->dw1.buffer_id = BUFFERID_COLOR_AUX;
-    buffer_info->dw1.fence_regs = 0;
-    buffer_info->dw1.tiled_surface = 0;
-    buffer_info->dw1.walk = TILEWALK_XMAJOR;
-    buffer_info->dw1.pitch = (pI915Surface->uvStride >> 2);      /* in Dwords */
-    buffer_info->dw2.base_address = (VOFFSET(pI915Surface) >> 2);      /* starting DWORD address */
-
-    /* 3DSTATE_DEST_BUFFER_VARIABLES */
-    dest_buffer_variables = (struct i915_3dstate_dest_buffer_variables *)(++buffer_info);
-    memset(dest_buffer_variables, 0, sizeof(*dest_buffer_variables));
-    dest_buffer_variables->dw0.type = CMD_3D;
-    dest_buffer_variables->dw0.opcode = OPC_3DSTATE_DEST_BUFFER_VARIABLES;
-    dest_buffer_variables->dw0.length = 0;
-    dest_buffer_variables->dw1.dest_v_bias = 8; /* 0.5 */
-    dest_buffer_variables->dw1.dest_h_bias = 8; /* 0.5 */
-    dest_buffer_variables->dw1.color_fmt = COLORBUFFER_8BIT;
-    dest_buffer_variables->dw1.v_ls = 0;
-    dest_buffer_variables->dw1.v_ls_offset = 0;
+    i915XvMCSurface *pI915Surface = (i915XvMCSurface *)dest->privData;
+    struct i915_mc_static_indirect_state_buffer *buffer_info =
+	(struct i915_mc_static_indirect_state_buffer *)pI915XvMC->sis.map;
+    unsigned int w = dest->width;
+
+    buffer_info->dest_y.dw1.pitch = (pI915Surface->yStride >> 2);      /* in DWords */
+    buffer_info->dest_y.dw2.base_address = (YOFFSET(pI915Surface) >> 2);    /* starting DWORD address */
+    buffer_info->dest_u.dw1.pitch = (pI915Surface->uvStride >> 2);      /* in DWords */
+    buffer_info->dest_u.dw2.base_address = (UOFFSET(pI915Surface) >> 2);      /* starting DWORD address */
+    buffer_info->dest_v.dw1.pitch = (pI915Surface->uvStride >> 2);      /* in Dwords */
+    buffer_info->dest_v.dw2.base_address = (VOFFSET(pI915Surface) >> 2);      /* starting DWORD address */
 
     if ((picture_structure & XVMC_FRAME_PICTURE) == XVMC_FRAME_PICTURE) {
         ;
     } else if ((picture_structure & XVMC_FRAME_PICTURE) == XVMC_TOP_FIELD) {
-        dest_buffer_variables->dw1.v_ls = 1;
+        buffer_info->dest_buf.dw1.v_ls = 1;
     } else if ((picture_structure & XVMC_FRAME_PICTURE) == XVMC_BOTTOM_FIELD) {
-        dest_buffer_variables->dw1.v_ls = 1;
-        dest_buffer_variables->dw1.v_ls_offset = 1;
+        buffer_info->dest_buf.dw1.v_ls = 1;
+        buffer_info->dest_buf.dw1.v_ls_offset = 1;
     }
 
-    /* 3DSTATE_DEST_BUFFER_VARIABLES_MPEG */
-    dest_buffer_variables_mpeg = (struct i915_3dstate_dest_buffer_variables_mpeg *)(++dest_buffer_variables);
-    memset(dest_buffer_variables_mpeg, 0, sizeof(*dest_buffer_variables_mpeg));
-    dest_buffer_variables_mpeg->dw0.type = CMD_3D;
-    dest_buffer_variables_mpeg->dw0.opcode = OPC_3DSTATE_DEST_BUFFER_VARIABLES_MPEG;
-    dest_buffer_variables_mpeg->dw0.length = 1;
-    dest_buffer_variables_mpeg->dw1.decode_mode = MPEG_DECODE_MC;
-    dest_buffer_variables_mpeg->dw1.rcontrol = 0;               /* for MPEG-1/MPEG-2 */
-    dest_buffer_variables_mpeg->dw1.bidir_avrg_control = 0;     /* for MPEG-1/MPEG-2/MPEG-4 */
-    dest_buffer_variables_mpeg->dw1.abort_on_error = 1;
-    dest_buffer_variables_mpeg->dw1.intra8 = 0;         /* 16-bit formatted correction data */
-    dest_buffer_variables_mpeg->dw1.tff = 1;
-
     if (picture_structure & XVMC_FRAME_PICTURE) {
         ;
     } else if (picture_structure & XVMC_TOP_FIELD) {
         if (flags & XVMC_SECOND_FIELD)
-            dest_buffer_variables_mpeg->dw1.tff = 0;
+            buffer_info->dest_buf_mpeg.dw1.tff = 0;
         else
-            dest_buffer_variables_mpeg->dw1.tff = 1;
+            buffer_info->dest_buf_mpeg.dw1.tff = 1;
     } else if (picture_structure & XVMC_BOTTOM_FIELD) {
         if (flags & XVMC_SECOND_FIELD)
-            dest_buffer_variables_mpeg->dw1.tff = 1;
+            buffer_info->dest_buf_mpeg.dw1.tff = 1;
         else
-            dest_buffer_variables_mpeg->dw1.tff = 0;
+            buffer_info->dest_buf_mpeg.dw1.tff = 0;
     }
 
-    dest_buffer_variables_mpeg->dw1.v_subsample_factor = MC_SUB_1V;
-    dest_buffer_variables_mpeg->dw1.h_subsample_factor = MC_SUB_1H;
-    dest_buffer_variables_mpeg->dw1.picture_width = (w >> 4);     /* in macroblocks */
-    dest_buffer_variables_mpeg->dw2.picture_coding_type = picture_coding_type;
-
-    /* 3DSATE_BUFFER_INFO */
-    /* CORRECTION DATA */
-    buffer_info = (struct i915_3dstate_buffer_info *)(++dest_buffer_variables_mpeg);
-    memset(buffer_info, 0, sizeof(*buffer_info));
-    buffer_info->dw0.type = CMD_3D;
-    buffer_info->dw0.opcode = OPC_3DSTATE_BUFFER_INFO;
-    buffer_info->dw0.length = 1;
-    buffer_info->dw1.aux_id = 0;
-    buffer_info->dw1.buffer_id = BUFFERID_MC_INTRA_CORR;
-    buffer_info->dw1.aux_id = 0;
-    buffer_info->dw1.fence_regs = 0;
-    buffer_info->dw1.tiled_surface = 0;
-    buffer_info->dw1.walk = 0;
-    buffer_info->dw1.pitch = 0;
-    buffer_info->dw2.base_address = (pI915XvMC->corrdata.offset >> 2);  /* starting DWORD address */
+    buffer_info->dest_buf_mpeg.dw1.picture_width = (dest->width >> 4);     /* in macroblocks */
+    buffer_info->dest_buf_mpeg.dw2.picture_coding_type = picture_coding_type;
 }
 
-static void i915_mc_map_state_buffer(XvMCContext *context,
-                                       i915XvMCSurface *privTarget,
-                                       i915XvMCSurface *privPast,
-                                       i915XvMCSurface *privFuture)
+static void i915_mc_map_state_init(XvMCContext *context)
 {
-    struct i915_3dstate_map_state *map_state;
-    struct texture_map *tm;
     i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
-    unsigned int w = context->width, h = context->height;
+    unsigned int w = context->width;
+    unsigned int h = context->height;
+    struct i915_mc_map_state *map_state;
 
-    /* 3DSATE_MAP_STATE: Y */
-    map_state = (struct i915_3dstate_map_state *)pI915XvMC->msb.map;
-    memset(map_state, 0, sizeof(*map_state));
-    map_state->dw0.type = CMD_3D;
-    map_state->dw0.opcode = OPC_3DSTATE_MAP_STATE;
-    map_state->dw0.retain = 1;
-    map_state->dw0.length = 6;
-    map_state->dw1.map_mask = MAP_MAP0 | MAP_MAP1;
+    map_state = (struct i915_mc_map_state *)pI915XvMC->msb.map;
 
-    /* texture map: Forward (Past) */
-    tm = (struct texture_map *)(++map_state);
-    memset(tm, 0, sizeof(*tm));
-    tm->tm0.v_ls_offset = 0;
-    tm->tm0.v_ls = 0;
-    tm->tm0.base_address = (YOFFSET(privPast) >> 2);
-    tm->tm1.tile_walk = TILEWALK_XMAJOR;        /* FIXME: tiled y for performace */
-    tm->tm1.tiled_surface = 0;
-    tm->tm1.utilize_fence_regs = 0;
-    tm->tm1.texel_fmt = 0;      /* 8bit */
-    tm->tm1.surface_fmt = 1;    /* 8bit */
-    tm->tm1.width = w - 1;
-    tm->tm1.height = h - 1;
-    tm->tm2.depth = 0;
-    tm->tm2.max_lod = 0;
-    tm->tm2.cube_face = 0;
-    tm->tm2.pitch = (privPast->yStride >> 2) - 1;       /* in DWords - 1 */
+    memset(map_state, 0, sizeof(*map_state));
 
-    /* texture map: Backward (Future) */
-    ++tm;
-    memset(tm, 0, sizeof(*tm));
-    tm->tm0.v_ls_offset = 0;
-    tm->tm0.v_ls = 0;
-    tm->tm0.base_address = (YOFFSET(privFuture) >> 2);
-    tm->tm1.tile_walk = TILEWALK_XMAJOR;
-    tm->tm1.tiled_surface = 0;
-    tm->tm1.utilize_fence_regs = 0;
-    tm->tm1.texel_fmt = 0;      /* 8bit */
-    tm->tm1.surface_fmt = 1;    /* 8bit */
-    tm->tm1.width = w - 1;
-    tm->tm1.height = h - 1;
-    tm->tm2.depth = 0;
-    tm->tm2.max_lod = 0;
-    tm->tm2.cube_face = 0;
-    tm->tm2.pitch = (privFuture->yStride >> 2) - 1;
+    /* 3DSATE_MAP_STATE: Y */
+    map_state->y_map.dw0.type = CMD_3D;
+    map_state->y_map.dw0.opcode = OPC_3DSTATE_MAP_STATE;
+    map_state->y_map.dw0.retain = 1;
+    map_state->y_map.dw0.length = 6;
+    map_state->y_map.dw1.map_mask = MAP_MAP0 | MAP_MAP1;
+
+    /* Y Forward (Past) */
+    map_state->y_forward.tm0.v_ls_offset = 0;
+    map_state->y_forward.tm0.v_ls = 0;
+    map_state->y_forward.tm1.tile_walk = TILEWALK_XMAJOR;
+    map_state->y_forward.tm1.tiled_surface = 0;
+    map_state->y_forward.tm1.utilize_fence_regs = 0;
+    map_state->y_forward.tm1.texel_fmt = 0;      /* 8bit */
+    map_state->y_forward.tm1.surface_fmt = 1;    /* 8bit */
+    map_state->y_forward.tm1.width = w - 1;
+    map_state->y_forward.tm1.height = h - 1;
+    map_state->y_forward.tm2.depth = 0;
+    map_state->y_forward.tm2.max_lod = 0;
+    map_state->y_forward.tm2.cube_face = 0;
+
+    /* Y Backward (Future) */
+    map_state->y_backward.tm0.v_ls_offset = 0;
+    map_state->y_backward.tm0.v_ls = 0;
+    map_state->y_backward.tm1.tile_walk = TILEWALK_XMAJOR;
+    map_state->y_backward.tm1.tiled_surface = 0;
+    map_state->y_backward.tm1.utilize_fence_regs = 0;
+    map_state->y_backward.tm1.texel_fmt = 0;      /* 8bit */
+    map_state->y_backward.tm1.surface_fmt = 1;    /* 8bit */
+    map_state->y_backward.tm1.width = w - 1;
+    map_state->y_backward.tm1.height = h - 1;
+    map_state->y_backward.tm2.depth = 0;
+    map_state->y_backward.tm2.max_lod = 0;
+    map_state->y_backward.tm2.cube_face = 0;
 
     /* 3DSATE_MAP_STATE: U */
-    map_state = (struct i915_3dstate_map_state *)(++tm);
-    memset(map_state, 0, sizeof(*map_state));
-    map_state->dw0.type = CMD_3D;
-    map_state->dw0.opcode = OPC_3DSTATE_MAP_STATE;
-    map_state->dw0.retain = 1;
-    map_state->dw0.length = 6;
-    map_state->dw1.map_mask = MAP_MAP0 | MAP_MAP1;
+    map_state->u_map.dw0.type = CMD_3D;
+    map_state->u_map.dw0.opcode = OPC_3DSTATE_MAP_STATE;
+    map_state->u_map.dw0.retain = 1;
+    map_state->u_map.dw0.length = 6;
+    map_state->u_map.dw1.map_mask = MAP_MAP0 | MAP_MAP1;
+
+    /* U Forward */
+    map_state->u_forward.tm0.v_ls_offset = 0;
+    map_state->u_forward.tm0.v_ls = 0;
+    map_state->u_forward.tm1.tile_walk = TILEWALK_XMAJOR;
+    map_state->u_forward.tm1.tiled_surface = 0;
+    map_state->u_forward.tm1.utilize_fence_regs = 0;
+    map_state->u_forward.tm1.texel_fmt = 0;      /* 8bit */
+    map_state->u_forward.tm1.surface_fmt = 1;    /* 8bit */
+    map_state->u_forward.tm1.width = (w >> 1) - 1;
+    map_state->u_forward.tm1.height = (h >> 1) - 1;
+    map_state->u_forward.tm2.depth = 0;
+    map_state->u_forward.tm2.max_lod = 0;
+    map_state->u_forward.tm2.cube_face = 0;
+
+    /* U Backward */
+    map_state->u_backward.tm0.v_ls_offset = 0;
+    map_state->u_backward.tm0.v_ls = 0;
+    map_state->u_backward.tm1.tile_walk = TILEWALK_XMAJOR;
+    map_state->u_backward.tm1.tiled_surface = 0;
+    map_state->u_backward.tm1.utilize_fence_regs = 0;
+    map_state->u_backward.tm1.texel_fmt = 0;
+    map_state->u_backward.tm1.surface_fmt = 1;
+    map_state->u_backward.tm1.width = (w >> 1) - 1;
+    map_state->u_backward.tm1.height = (h >> 1) - 1;
+    map_state->u_backward.tm2.depth = 0;
+    map_state->u_backward.tm2.max_lod = 0;
+    map_state->u_backward.tm2.cube_face = 0;
 
-    /* texture map: Forward */
-    tm = (struct texture_map *)(++map_state);
-    memset(tm, 0, sizeof(*tm));
-    tm->tm0.v_ls_offset = 0;
-    tm->tm0.v_ls = 0;
-    tm->tm0.base_address = (UOFFSET(privPast) >> 2);
-    tm->tm1.tile_walk = TILEWALK_XMAJOR;
-    tm->tm1.tiled_surface = 0;
-    tm->tm1.utilize_fence_regs = 0;
-    tm->tm1.texel_fmt = 0;      /* 8bit */
-    tm->tm1.surface_fmt = 1;    /* 8bit */
-    tm->tm1.width = (w >> 1) - 1;
-    tm->tm1.height = (h >> 1) - 1;
-    tm->tm2.depth = 0;
-    tm->tm2.max_lod = 0;
-    tm->tm2.cube_face = 0;
-    tm->tm2.pitch = (privPast->uvStride >> 2) - 1;       /* in DWords - 1 */
+    /* 3DSATE_MAP_STATE: V */
+    map_state->v_map.dw0.type = CMD_3D;
+    map_state->v_map.dw0.opcode = OPC_3DSTATE_MAP_STATE;
+    map_state->v_map.dw0.retain = 1;
+    map_state->v_map.dw0.length = 6;
+    map_state->v_map.dw1.map_mask = MAP_MAP0 | MAP_MAP1;
+
+    /* V Forward */
+    map_state->v_forward.tm0.v_ls_offset = 0;
+    map_state->v_forward.tm0.v_ls = 0;
+    map_state->v_forward.tm1.tile_walk = TILEWALK_XMAJOR;
+    map_state->v_forward.tm1.tiled_surface = 0;
+    map_state->v_forward.tm1.utilize_fence_regs = 0;
+    map_state->v_forward.tm1.texel_fmt = 0;
+    map_state->v_forward.tm1.surface_fmt = 1;
+    map_state->v_forward.tm1.width = (w >> 1) - 1;
+    map_state->v_forward.tm1.height = (h >> 1) - 1;
+    map_state->v_forward.tm2.depth = 0;
+    map_state->v_forward.tm2.max_lod = 0;
+    map_state->v_forward.tm2.cube_face = 0;
+
+    /* V Backward */
+    map_state->v_backward.tm0.v_ls_offset = 0;
+    map_state->v_backward.tm0.v_ls = 0;
+    map_state->v_backward.tm1.tile_walk = TILEWALK_XMAJOR;
+    map_state->v_backward.tm1.tiled_surface = 0;
+    map_state->v_backward.tm1.utilize_fence_regs = 0;
+    map_state->v_backward.tm1.texel_fmt = 0;
+    map_state->v_backward.tm1.surface_fmt = 1;
+    map_state->v_backward.tm1.width = (w >> 1) - 1;
+    map_state->v_backward.tm1.height = (h >> 1) - 1;
+    map_state->v_backward.tm2.depth = 0;
+    map_state->v_backward.tm2.max_lod = 0;
+    map_state->v_backward.tm2.cube_face = 0;
+}
 
-    /* texture map: Backward */
-    ++tm;
-    memset(tm, 0, sizeof(*tm));
-    tm->tm0.v_ls_offset = 0;
-    tm->tm0.v_ls = 0;
-    tm->tm0.base_address = (UOFFSET(privFuture) >> 2);
-    tm->tm1.tile_walk = TILEWALK_XMAJOR;
-    tm->tm1.tiled_surface = 0;
-    tm->tm1.utilize_fence_regs = 0;
-    tm->tm1.texel_fmt = 0;
-    tm->tm1.surface_fmt = 1;
-    tm->tm1.width = (w >> 1) - 1;
-    tm->tm1.height = (h >> 1) - 1;
-    tm->tm2.depth = 0;
-    tm->tm2.max_lod = 0;
-    tm->tm2.cube_face = 0;
-    tm->tm2.pitch = (privFuture->uvStride >> 2) - 1;
+static void i915_mc_map_state_set(XvMCContext *context,
+	i915XvMCSurface *privPast,
+	i915XvMCSurface *privFuture)
+{
+    i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
+    struct i915_mc_map_state *map_state;
+
+    map_state = (struct i915_mc_map_state *)pI915XvMC->msb.map;
+
+    map_state->y_forward.tm0.base_address = (YOFFSET(privPast) >> 2);
+    map_state->y_forward.tm2.pitch = (privPast->yStride >> 2) - 1;       /* in DWords - 1 */
+    map_state->y_backward.tm0.base_address = (YOFFSET(privFuture) >> 2);
+    map_state->y_backward.tm2.pitch = (privFuture->yStride >> 2) - 1;
+    map_state->u_forward.tm0.base_address = (UOFFSET(privPast) >> 2);
+    map_state->u_forward.tm2.pitch = (privPast->uvStride >> 2) - 1;       /* in DWords - 1 */
+    map_state->u_backward.tm0.base_address = (UOFFSET(privFuture) >> 2);
+    map_state->u_backward.tm2.pitch = (privFuture->uvStride >> 2) - 1;
+    map_state->v_forward.tm0.base_address = (VOFFSET(privPast) >> 2);
+    map_state->v_forward.tm2.pitch = (privPast->uvStride >> 2) - 1;       /* in DWords - 1 */
+    map_state->v_backward.tm0.base_address = (VOFFSET(privFuture) >> 2);
+    map_state->v_backward.tm2.pitch = (privFuture->uvStride >> 2) - 1;
+}
 
-    /* 3DSATE_MAP_STATE: V */
-    map_state = (struct i915_3dstate_map_state *)(++tm);
-    memset(map_state, 0, sizeof(*map_state));
-    map_state->dw0.type = CMD_3D;
-    map_state->dw0.opcode = OPC_3DSTATE_MAP_STATE;
-    map_state->dw0.retain = 1;
-    map_state->dw0.length = 6;
-    map_state->dw1.map_mask = MAP_MAP0 | MAP_MAP1;
+static void i915_flush(int map, int render)
+{
+    struct i915_mi_flush mi_flush;
 
-    /* texture map: Forward */
-    tm = (struct texture_map *)(++map_state);
-    memset(tm, 0, sizeof(*tm));
-    tm->tm0.v_ls_offset = 0;
-    tm->tm0.v_ls = 0;
-    tm->tm0.base_address = (VOFFSET(privPast) >> 2);
-    tm->tm1.tile_walk = TILEWALK_XMAJOR;
-    tm->tm1.tiled_surface = 0;
-    tm->tm1.utilize_fence_regs = 0;
-    tm->tm1.texel_fmt = 0;
-    tm->tm1.surface_fmt = 1;
-    tm->tm1.width = (w >> 1) - 1;
-    tm->tm1.height = (h >> 1) - 1;
-    tm->tm2.depth = 0;
-    tm->tm2.max_lod = 0;
-    tm->tm2.cube_face = 0;
-    tm->tm2.pitch = (privPast->uvStride >> 2) - 1;       /* in DWords - 1 */
+    memset(&mi_flush, 0, sizeof(mi_flush));
+    mi_flush.dw0.type = CMD_MI;
+    mi_flush.dw0.opcode = OPC_MI_FLUSH;
+    mi_flush.dw0.map_cache_invalidate = map;
+    mi_flush.dw0.render_cache_flush_inhibit = render;
 
-    /* texture map: Backward */
-    ++tm;
-    memset(tm, 0, sizeof(*tm));
-    tm->tm0.v_ls_offset = 0;
-    tm->tm0.v_ls = 0;
-    tm->tm0.base_address = (VOFFSET(privFuture) >> 2);
-    tm->tm1.tile_walk = TILEWALK_XMAJOR;
-    tm->tm1.tiled_surface = 0;
-    tm->tm1.utilize_fence_regs = 0;
-    tm->tm1.texel_fmt = 0;
-    tm->tm1.surface_fmt = 1;
-    tm->tm1.width = (w >> 1) - 1;
-    tm->tm1.height = (h >> 1) - 1;
-    tm->tm2.depth = 0;
-    tm->tm2.max_lod = 0;
-    tm->tm2.cube_face = 0;
-    tm->tm2.pitch = (privFuture->uvStride >> 2) - 1;
+    intelBatchbufferData(&mi_flush, sizeof(mi_flush), 0);
 }
 
 static void i915_mc_load_sis_msb_buffers(XvMCContext *context)
@@ -1668,6 +1650,10 @@ static Status i915_xvmc_mc_create_context(Display *display, XvMCContext *context
     i915_mc_one_time_context_init(context);
     i915_mc_one_time_state_init(context);
 
+    i915_mc_static_indirect_state_init(context);
+
+    i915_mc_map_state_init(context);
+
     return Success;
 }
 
@@ -1927,10 +1913,10 @@ static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context,
 
     i915_mc_one_time_state_emit();
 
-    i915_mc_static_indirect_state_buffer(context, target_surface,
-                                         picture_structure, flags,
-                                         picture_coding_type);
-    i915_mc_map_state_buffer(context, privTarget, privPast, privFuture);
+    i915_mc_static_indirect_state_set(context, target_surface, picture_structure,
+	    flags, picture_coding_type);
+    /* setup reference surfaces */
+    i915_mc_map_state_set(context, privPast, privFuture);
     i915_mc_load_sis_msb_buffers(context);
     i915_mc_mpeg_set_origin(context, &macroblock_array->macro_blocks[first_macroblock]);
 
commit 9d08874d309132444b92f333963aa3fe5a2340ca
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Wed Jun 25 14:27:16 2008 +0800

    xvmc: init one-time mc context once
    
    Don't setup one-time mc context everytime, as the content is always
    unchanged. And several structs got packed layout inside to ease static
    state initialization.
    (cherry picked from commit b4d8ca8b38e495b56bb3b4143e5dfe91ee651f15)

diff --git a/src/xvmc/i915_structs.h b/src/xvmc/i915_structs.h
index a25d734..7e786e7 100644
--- a/src/xvmc/i915_structs.h
+++ b/src/xvmc/i915_structs.h
@@ -28,6 +28,8 @@
 #ifndef _I915_STRUCTS_H
 #define _I915_STRUCTS_H
 
+#include <stdint.h>
+
 /* MI_INSTRUCTION */
 #define CMD_MI          0x00
 
@@ -532,6 +534,9 @@ struct i915_3dstate_sampler_state
         unsigned sampler_masker : 16;
         unsigned pad0 : 16;
     } dw1;
+    /* we always use two samplers for mc */
+    struct texture_sampler sampler0;
+    struct texture_sampler sampler1;
 };
 
 struct arithmetic_inst
@@ -641,17 +646,48 @@ union shader_inst
     struct declaration_inst d;
 };
 
+struct i915_3dstate_pixel_shader_header {
+    unsigned length : 9;
+    unsigned pad0 : 6;
+    unsigned retain : 1;
+    unsigned opcode : 13;
+    unsigned type : 3;
+};
+
 struct i915_3dstate_pixel_shader_program
 {
-    struct {
-        unsigned length : 9;
-        unsigned pad0 : 6;
-        unsigned retain : 1;
-        unsigned opcode : 13;
-        unsigned type : 3;
-    } dw0;
-
-    // union shader_inst *insts;
+    struct i915_3dstate_pixel_shader_header shader0;
+    /* mov oC, c0.0000 */
+    uint32_t inst0[3];
+
+    struct i915_3dstate_pixel_shader_header shader1;
+    /* dcl t0.xy */
+    /* dcl t1.xy */
+    /* dcl_2D s0 */
+    /* texld r0, t0, s0 */
+    /* mov oC, r0 */
+    uint32_t inst1[3*5];
+
+    struct i915_3dstate_pixel_shader_header shader2;
+    /* dcl t2.xy */
+    /* dcl t3.xy */
+    /* dcl_2D s1 */
+    /* texld r0, t2, s1 */
+    /* mov oC, r0 */
+    uint32_t inst2[3*5];
+
+    struct i915_3dstate_pixel_shader_header shader3;
+    /* dcl t0.xy */
+    /* dcl t1.xy */
+    /* dcl t2.xy */
+    /* dcl t3.xy */
+    /* dcl_2D s0 */
+    /* dcl_2D s1 */
+    /* texld r0, t0, s0 */
+    /* texld r0, t2, s1 */
+    /* add r0, r0, r1*/
+    /* mov oC, r0 */
+    uint32_t inst3[3*10];
 };
 
 #define REG_CR0         0x00000001
@@ -707,7 +743,8 @@ struct i915_3dstate_pixel_shader_constants
     struct {
         unsigned reg_mask;
     } dw1;
-    // struct shader_constant *consts;
+    /* we only need one constant */
+    struct shader_constant value;
 };
 
 #define BLOCK_SIS       0x01
diff --git a/src/xvmc/i915_xvmc.c b/src/xvmc/i915_xvmc.c
index bd31de4..45acf9b 100644
--- a/src/xvmc/i915_xvmc.c
+++ b/src/xvmc/i915_xvmc.c
@@ -81,6 +81,372 @@ static int findOverlap(unsigned int width, unsigned int height,
 }
 #endif
 
+static void i915_inst_arith(unsigned int *inst,
+                            unsigned int op,
+                            unsigned int dest,
+                            unsigned int mask,
+                            unsigned int saturate,
+                            unsigned int src0, unsigned int src1, unsigned int src2)
+{
+    dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest));
+    *inst = (op | A0_DEST(dest) | mask | saturate | A0_SRC0(src0));
+    inst++;
+    *inst = (A1_SRC0(src0) | A1_SRC1(src1));
+    inst++;
+    *inst = (A2_SRC1(src1) | A2_SRC2(src2));
+}
+
+static void i915_inst_decl(unsigned int *inst,
+                           unsigned int type,
+                           unsigned int nr,
+                           unsigned int d0_flags)
+{
+    unsigned int reg = UREG(type, nr);
+
+    *inst = (D0_DCL | D0_DEST(reg) | d0_flags);
+    inst++;
+    *inst = D1_MBZ;
+    inst++;
+    *inst = D2_MBZ;
+}
+
+static void i915_inst_texld(unsigned int *inst,
+                              unsigned int op,
+                              unsigned int dest,
+                              unsigned int coord,
+                              unsigned int sampler)
+{
+   dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest));
+   *inst = (op | T0_DEST(dest) | T0_SAMPLER(sampler));
+   inst++;
+   *inst = T1_ADDRESS_REG(coord);
+   inst++;
+   *inst = T2_MBZ;
+}
+
+static void i915_emit_batch(void *data, int size, int flag)
+{
+    intelBatchbufferData(data, size, flag);
+}
+
+/* one time context initialization buffer */
+static uint32_t *one_time_load_state_imm1;
+static uint32_t *one_time_load_indirect;
+static int one_time_load_state_imm1_size, one_time_load_indirect_size;
+
+static void i915_mc_one_time_context_init(XvMCContext *context)
+{
+    unsigned int dest, src0, src1, src2;
+    i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
+    int i;
+    struct i915_3dstate_sampler_state *sampler_state;
+    struct i915_3dstate_pixel_shader_program *pixel_shader_program;
+    struct i915_3dstate_pixel_shader_constants *pixel_shader_constants;
+
+    /* sampler static state */
+    sampler_state = (struct i915_3dstate_sampler_state *)pI915XvMC->ssb.map;
+    /* pixel shader static state */
+    pixel_shader_program = (struct i915_3dstate_pixel_shader_program *)pI915XvMC->psp.map;
+    /* pixel shader contant static state */
+    pixel_shader_constants = (struct i915_3dstate_pixel_shader_constants *)pI915XvMC->psc.map;
+
+    memset(sampler_state, 0, sizeof(*sampler_state));
+    sampler_state->dw0.type = CMD_3D;
+    sampler_state->dw0.opcode = OPC_3DSTATE_SAMPLER_STATE;
+    sampler_state->dw0.length = 6;
+    sampler_state->dw1.sampler_masker = SAMPLER_SAMPLER0 | SAMPLER_SAMPLER1;
+
+    sampler_state->sampler0.ts0.reverse_gamma = 0;
+    sampler_state->sampler0.ts0.planar2packet = 0;
+    sampler_state->sampler0.ts0.color_conversion = 0;
+    sampler_state->sampler0.ts0.chromakey_index = 0;
+    sampler_state->sampler0.ts0.base_level = 0;
+    sampler_state->sampler0.ts0.mip_filter = MIPFILTER_NONE;        /* NONE */
+    sampler_state->sampler0.ts0.mag_filter = MAPFILTER_LINEAR;      /* LINEAR */
+    sampler_state->sampler0.ts0.min_filter = MAPFILTER_LINEAR;      /* LINEAR */
+    sampler_state->sampler0.ts0.lod_bias = 0;       /* 0.0 */
+    sampler_state->sampler0.ts0.shadow_enable = 0;
+    sampler_state->sampler0.ts0.max_anisotropy = ANISORATIO_2;
+    sampler_state->sampler0.ts0.shadow_function = PREFILTEROP_ALWAYS;
+    sampler_state->sampler0.ts1.min_lod = 0;        /* 0.0 Maximum Mip Level */
+    sampler_state->sampler0.ts1.kill_pixel = 0;
+    sampler_state->sampler0.ts1.keyed_texture_filter = 0;
+    sampler_state->sampler0.ts1.chromakey_enable = 0;
+    sampler_state->sampler0.ts1.tcx_control = TEXCOORDMODE_CLAMP;
+    sampler_state->sampler0.ts1.tcy_control = TEXCOORDMODE_CLAMP;
+    sampler_state->sampler0.ts1.tcz_control = TEXCOORDMODE_CLAMP;
+    sampler_state->sampler0.ts1.normalized_coor = 0;
+    sampler_state->sampler0.ts1.map_index = 0;
+    sampler_state->sampler0.ts1.east_deinterlacer = 0;
+    sampler_state->sampler0.ts2.default_color = 0;
+
+    sampler_state->sampler1.ts0.reverse_gamma = 0;
+    sampler_state->sampler1.ts0.planar2packet = 0;
+    sampler_state->sampler1.ts0.color_conversion = 0;
+    sampler_state->sampler1.ts0.chromakey_index = 0;
+    sampler_state->sampler1.ts0.base_level = 0;
+    sampler_state->sampler1.ts0.mip_filter = MIPFILTER_NONE;        /* NONE */
+    sampler_state->sampler1.ts0.mag_filter = MAPFILTER_LINEAR;      /* LINEAR */
+    sampler_state->sampler1.ts0.min_filter = MAPFILTER_LINEAR;      /* LINEAR */
+    sampler_state->sampler1.ts0.lod_bias = 0;       /* 0.0 */
+    sampler_state->sampler1.ts0.shadow_enable = 0;
+    sampler_state->sampler1.ts0.max_anisotropy = ANISORATIO_2;
+    sampler_state->sampler1.ts0.shadow_function = PREFILTEROP_ALWAYS;
+    sampler_state->sampler1.ts1.min_lod = 0;        /* 0.0 Maximum Mip Level */
+    sampler_state->sampler1.ts1.kill_pixel = 0;
+    sampler_state->sampler1.ts1.keyed_texture_filter = 0;
+    sampler_state->sampler1.ts1.chromakey_enable = 0;
+    sampler_state->sampler1.ts1.tcx_control = TEXCOORDMODE_CLAMP;
+    sampler_state->sampler1.ts1.tcy_control = TEXCOORDMODE_CLAMP;
+    sampler_state->sampler1.ts1.tcz_control = TEXCOORDMODE_CLAMP;
+    sampler_state->sampler1.ts1.normalized_coor = 0;
+    sampler_state->sampler1.ts1.map_index = 1;
+    sampler_state->sampler1.ts1.east_deinterlacer = 0;
+    sampler_state->sampler1.ts2.default_color = 0;
+
+    memset(pixel_shader_program, 0, sizeof(*pixel_shader_program));
+    pixel_shader_program->shader0.type = CMD_3D;
+    pixel_shader_program->shader0.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM;
+    pixel_shader_program->shader0.retain = 1;
+    pixel_shader_program->shader0.length = 2; /* 1 inst */
+    i = 0;
+
+    dest = UREG(REG_TYPE_OC, 0);
+    src0 = UREG(REG_TYPE_CONST, 0);
+    src1 = 0;
+    src2 = 0;
+    i915_inst_arith(&pixel_shader_program->inst0[i], A0_MOV,
+	    dest, A0_DEST_CHANNEL_ALL, A0_DEST_SATURATE, src0, src1, src2);
+
+    pixel_shader_program->shader1.type = CMD_3D;
+    pixel_shader_program->shader1.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM;
+    pixel_shader_program->shader1.retain = 1;
+    pixel_shader_program->shader1.length = 14; /* 5 inst */
+    i = 0;
+    /* dcl t0.xy */
+    i915_inst_decl(&pixel_shader_program->inst1[i], REG_TYPE_T, T_TEX0, D0_CHANNEL_XY);
+    i+=3;
+    /* dcl t1.xy */
+    i915_inst_decl(&pixel_shader_program->inst1[i], REG_TYPE_T, T_TEX1, D0_CHANNEL_XY);
+    /* dcl_2D s0 */
+    i += 3;
+    i915_inst_decl(&pixel_shader_program->inst1[i], REG_TYPE_S, 0, D0_SAMPLE_TYPE_2D);
+    /* texld r0, t0, s0 */
+    i += 3;
+    dest = UREG(REG_TYPE_R, 0);
+    src0 = UREG(REG_TYPE_T, 0); /* COORD */
+    src1 = UREG(REG_TYPE_S, 0); /* SAMPLER */
+    i915_inst_texld(&pixel_shader_program->inst1[i], T0_TEXLD, dest, src0, src1);
+    /* mov oC, r0 */
+    i += 3;
+    dest = UREG(REG_TYPE_OC, 0);
+    src0 = UREG(REG_TYPE_R, 0);
+    src1 = src2 = 0;
+    i915_inst_arith(&pixel_shader_program->inst1[i], A0_MOV, dest, A0_DEST_CHANNEL_ALL,
+                    A0_DEST_SATURATE, src0, src1, src2);
+
+
+    pixel_shader_program->shader2.type = CMD_3D;
+    pixel_shader_program->shader2.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM;
+    pixel_shader_program->shader2.retain = 1;
+    pixel_shader_program->shader2.length = 14; /* 5 inst */
+    i = 0;
+    /* dcl t2.xy */
+    i915_inst_decl(&pixel_shader_program->inst2[i], REG_TYPE_T, T_TEX2, D0_CHANNEL_XY);
+    /* dcl t3.xy */
+    i += 3;
+    i915_inst_decl(&pixel_shader_program->inst2[i], REG_TYPE_T, T_TEX3, D0_CHANNEL_XY);
+    /* dcl_2D s1 */
+    i += 3;
+    i915_inst_decl(&pixel_shader_program->inst2[i], REG_TYPE_S, 1, D0_SAMPLE_TYPE_2D);
+    /* texld r0, t2, s1 */
+    i += 3;
+    dest = UREG(REG_TYPE_R, 0);
+    src0 = UREG(REG_TYPE_T, 2); /* COORD */
+    src1 = UREG(REG_TYPE_S, 1); /* SAMPLER */
+    i915_inst_texld(&pixel_shader_program->inst2[i], T0_TEXLD, dest, src0, src1);
+    /* mov oC, r0 */
+    i += 3;
+    dest = UREG(REG_TYPE_OC, 0);
+    src0 = UREG(REG_TYPE_R, 0);
+    src1 = src2 = 0;
+    i915_inst_arith(&pixel_shader_program->inst2[i], A0_MOV, dest, A0_DEST_CHANNEL_ALL,
+                    A0_DEST_SATURATE, src0, src1, src2);
+
+    /* Shader 3 */
+    pixel_shader_program->shader3.type = CMD_3D;
+    pixel_shader_program->shader3.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM;
+    pixel_shader_program->shader3.retain = 1;
+    pixel_shader_program->shader3.length = 29; /* 10 inst */
+    i = 0;
+    /* dcl t0.xy */
+    i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_T, T_TEX0, D0_CHANNEL_XY);
+    /* dcl t1.xy */
+    i += 3;
+    i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_T, T_TEX1, D0_CHANNEL_XY);
+    /* dcl t2.xy */
+    i += 3;
+    i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_T, T_TEX2, D0_CHANNEL_XY);
+    /* dcl t3.xy */
+    i += 3;
+    i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_T, T_TEX3, D0_CHANNEL_XY);
+    /* dcl_2D s0 */
+    i += 3;
+    i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_S, 0, D0_SAMPLE_TYPE_2D);
+    /* dcl_2D s1 */
+    i += 3;
+    i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_S, 1, D0_SAMPLE_TYPE_2D);
+    /* texld r0, t0, s0 */
+    i += 3;
+    dest = UREG(REG_TYPE_R, 0);
+    src0 = UREG(REG_TYPE_T, 0); /* COORD */
+    src1 = UREG(REG_TYPE_S, 0); /* SAMPLER */
+    i915_inst_texld(&pixel_shader_program->inst3[i], T0_TEXLD, dest, src0, src1);
+    /* texld r1, t2, s1 */
+    i += 3;
+    dest = UREG(REG_TYPE_R, 1);
+    src0 = UREG(REG_TYPE_T, 2); /* COORD */
+    src1 = UREG(REG_TYPE_S, 1); /* SAMPLER */
+    i915_inst_texld(&pixel_shader_program->inst3[i], T0_TEXLD, dest, src0, src1);
+    /* add r0, r0, r1 */
+    i += 3;
+    dest = UREG(REG_TYPE_R, 0);
+    src0 = UREG(REG_TYPE_R, 0);
+    src1 = UREG(REG_TYPE_R, 1);
+    src2 = 0;
+    i915_inst_arith(&pixel_shader_program->inst3[i], A0_ADD, dest, A0_DEST_CHANNEL_ALL,
+                    0 /* A0_DEST_SATURATE */, src0, src1, src2);
+    /* mul oC, r0, c0 */
+    i += 3;
+    dest = UREG(REG_TYPE_OC, 0);
+    src0 = UREG(REG_TYPE_R, 0);
+    src1 = UREG(REG_TYPE_CONST, 0);
+    src2 = 0;
+    i915_inst_arith(&pixel_shader_program->inst3[i], A0_MUL, dest, A0_DEST_CHANNEL_ALL,
+                    A0_DEST_SATURATE, src0, src1, src2);
+
+    memset(pixel_shader_constants, 0, sizeof(*pixel_shader_constants));
+    pixel_shader_constants->dw0.type = CMD_3D;
+    pixel_shader_constants->dw0.opcode = OPC_3DSTATE_PIXEL_SHADER_CONSTANTS;
+    pixel_shader_constants->dw0.length = 4;
+    pixel_shader_constants->dw1.reg_mask = REG_CR0;
+    pixel_shader_constants->value.x = 0.5;
+    pixel_shader_constants->value.y = 0.5;
+    pixel_shader_constants->value.z = 0.5;
+    pixel_shader_constants->value.w = 0.5;
+
+}
+
+static void i915_mc_one_time_state_init(XvMCContext *context)
+{
+    struct s3_dword *s3 = NULL;
+    struct s6_dword *s6 = NULL;
+    dis_state *dis = NULL;
+    ssb_state *ssb = NULL;
+    psp_state *psp = NULL;
+    psc_state *psc = NULL;
+    i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
+    int mem_select = 1;
+    struct i915_3dstate_load_state_immediate_1 *load_state_immediate_1;
+    struct i915_3dstate_load_indirect *load_indirect;
+
+    /* 3DSTATE_LOAD_STATE_IMMEDIATE_1 */
+    one_time_load_state_imm1_size = sizeof(*load_state_immediate_1) + sizeof(*s3) + sizeof(*s6);
+    one_time_load_state_imm1 = calloc(1, one_time_load_state_imm1_size);
+    load_state_immediate_1 = (struct i915_3dstate_load_state_immediate_1 *)one_time_load_state_imm1;
+    load_state_immediate_1->dw0.type = CMD_3D;
+    load_state_immediate_1->dw0.opcode = OPC_3DSTATE_LOAD_STATE_IMMEDIATE_1;
+    load_state_immediate_1->dw0.load_s3 = 1;
+    load_state_immediate_1->dw0.load_s6 = 1;
+    load_state_immediate_1->dw0.length = (one_time_load_state_imm1_size >> 2) - 2;
+
+    s3 = (struct s3_dword *)(++load_state_immediate_1);
+    s3->set0_pcd = 1;
+    s3->set1_pcd = 1;
+    s3->set2_pcd = 1;
+    s3->set3_pcd = 1;
+    s3->set4_pcd = 1;
+    s3->set5_pcd = 1;
+    s3->set6_pcd = 1;
+    s3->set7_pcd = 1;
+
+    s6 = (struct s6_dword *)(++s3);
+    s6->alpha_test_enable = 0;
+    s6->alpha_test_function = 0;
+    s6->alpha_reference_value = 0;
+    s6->depth_test_enable = 1;
+    s6->depth_test_function = 0;
+    s6->color_buffer_blend = 0;
+    s6->color_blend_function = 0;
+    s6->src_blend_factor = 1;
+    s6->dest_blend_factor = 1;
+    s6->depth_buffer_write = 0;
+    s6->color_buffer_write = 1;
+    s6->triangle_pv = 0;
+
+    /* 3DSTATE_LOAD_INDIRECT */
+    one_time_load_indirect_size = sizeof(*load_indirect) + sizeof(*dis) + sizeof(*ssb) + sizeof(*psp) + sizeof(*psc);
+    one_time_load_indirect = calloc(1, one_time_load_indirect_size);
+    load_indirect = (struct i915_3dstate_load_indirect *)one_time_load_indirect;
+    load_indirect->dw0.type = CMD_3D;
+    load_indirect->dw0.opcode = OPC_3DSTATE_LOAD_INDIRECT;
+    load_indirect->dw0.block_mask = BLOCK_DIS | BLOCK_SSB | BLOCK_PSP | BLOCK_PSC;
+    load_indirect->dw0.length = (one_time_load_indirect_size >> 2) - 2;
+
+    if (pI915XvMC->deviceID == PCI_CHIP_I915_G ||
+        pI915XvMC->deviceID == PCI_CHIP_I915_GM ||
+        pI915XvMC->deviceID == PCI_CHIP_I945_G ||
+        pI915XvMC->deviceID == PCI_CHIP_I945_GM)
+        mem_select = 0;
+
+    load_indirect->dw0.mem_select = mem_select;
+
+    /* Dynamic indirect state buffer */
+    dis = (dis_state *)(++load_indirect);
+    dis->dw0.valid = 0;
+    dis->dw0.reset = 0;
+    dis->dw0.buffer_address = 0;
+
+    /* Sample state buffer */
+    ssb = (ssb_state *)(++dis);
+    ssb->dw0.valid = 1;
+    ssb->dw0.force = 1;
+    ssb->dw1.length = 7; /* 8 - 1 */
+
+    if (mem_select)
+        ssb->dw0.buffer_address = (pI915XvMC->ssb.offset >> 2);
+    else
+        ssb->dw0.buffer_address = (pI915XvMC->ssb.bus_addr >> 2);
+
+    /* Pixel shader program buffer */
+    psp = (psp_state *)(++ssb);
+    psp->dw0.valid = 1;
+    psp->dw0.force = 1;
+    psp->dw1.length = 66; /* 4 + 16 + 16 + 31 - 1 */
+
+    if (mem_select)
+        psp->dw0.buffer_address = (pI915XvMC->psp.offset >> 2);
+    else
+        psp->dw0.buffer_address = (pI915XvMC->psp.bus_addr >> 2);
+
+    /* Pixel shader constant buffer */
+    psc = (psc_state *)(++psp);
+    psc->dw0.valid = 1;
+    psc->dw0.force = 1;
+    psc->dw1.length = 5; /* 6 - 1 */
+
+    if (mem_select)
+        psc->dw0.buffer_address = (pI915XvMC->psc.offset >> 2);
+    else
+        psc->dw0.buffer_address = (pI915XvMC->psc.bus_addr >> 2);
+}
+
+static void i915_mc_one_time_state_emit(void)
+{
+    i915_emit_batch(one_time_load_state_imm1, one_time_load_state_imm1_size, 0);
+    i915_emit_batch(one_time_load_indirect, one_time_load_indirect_size, 0);
+}
+
 static void i915_flush(int map, int render)
 {
     struct i915_mi_flush mi_flush;
@@ -582,392 +948,6 @@ static void i915_mc_mpeg_macroblock_2fbmv(XvMCContext *context, XvMCMacroBlock *
     intelBatchbufferData(&macroblock_2fbmv, sizeof(macroblock_2fbmv), 0);
 }
 
-/* for MC context initialization */
-static void i915_mc_sampler_state_buffer(XvMCContext *context)
-{
-    struct i915_3dstate_sampler_state *sampler_state;
-    struct texture_sampler *ts;
-    i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
-
-    /* 3DSATE_SAMPLER_STATE */
-    sampler_state = (struct i915_3dstate_sampler_state *)pI915XvMC->ssb.map;
-    memset(sampler_state, 0, sizeof(*sampler_state));
-    sampler_state->dw0.type = CMD_3D;
-    sampler_state->dw0.opcode = OPC_3DSTATE_SAMPLER_STATE;
-    sampler_state->dw0.length = 6;
-    sampler_state->dw1.sampler_masker = SAMPLER_SAMPLER0 | SAMPLER_SAMPLER1;
-
-    /* Sampler 0 */
-    ts = (struct texture_sampler *)(++sampler_state);
-    memset(ts, 0, sizeof(*ts));
-    ts->ts0.reverse_gamma = 0;
-    ts->ts0.planar2packet = 0;
-    ts->ts0.color_conversion = 0;
-    ts->ts0.chromakey_index = 0;
-    ts->ts0.base_level = 0;
-    ts->ts0.mip_filter = MIPFILTER_NONE;        /* NONE */
-    ts->ts0.mag_filter = MAPFILTER_LINEAR;      /* LINEAR */
-    ts->ts0.min_filter = MAPFILTER_LINEAR;      /* LINEAR */
-    ts->ts0.lod_bias = 0;       /* 0.0 */
-    ts->ts0.shadow_enable = 0;
-    ts->ts0.max_anisotropy = ANISORATIO_2;
-    ts->ts0.shadow_function = PREFILTEROP_ALWAYS;
-    ts->ts1.min_lod = 0;        /* 0.0 Maximum Mip Level */
-    ts->ts1.kill_pixel = 0;
-    ts->ts1.keyed_texture_filter = 0;
-    ts->ts1.chromakey_enable = 0;
-    ts->ts1.tcx_control = TEXCOORDMODE_CLAMP;
-    ts->ts1.tcy_control = TEXCOORDMODE_CLAMP;
-    ts->ts1.tcz_control = TEXCOORDMODE_CLAMP;
-    ts->ts1.normalized_coor = 0;
-    ts->ts1.map_index = 0;
-    ts->ts1.east_deinterlacer = 0;
-    ts->ts2.default_color = 0;
-
-    /* Sampler 1 */
-    ++ts;
-    memset(ts, 0, sizeof(*ts));
-    ts->ts0.reverse_gamma = 0;
-    ts->ts0.planar2packet = 0;
-    ts->ts0.color_conversion = 0;
-    ts->ts0.chromakey_index = 0;
-    ts->ts0.base_level = 0;
-    ts->ts0.mip_filter = MIPFILTER_NONE;        /* NONE */
-    ts->ts0.mag_filter = MAPFILTER_LINEAR;      /* LINEAR */
-    ts->ts0.min_filter = MAPFILTER_LINEAR;      /* LINEAR */
-    ts->ts0.lod_bias = 0;       /* 0.0 */
-    ts->ts0.shadow_enable = 0;
-    ts->ts0.max_anisotropy = ANISORATIO_2;
-    ts->ts0.shadow_function = PREFILTEROP_ALWAYS;
-    ts->ts1.min_lod = 0;        /* 0.0 Maximum Mip Level */
-    ts->ts1.kill_pixel = 0;
-    ts->ts1.keyed_texture_filter = 0;
-    ts->ts1.chromakey_enable = 0;
-    ts->ts1.tcx_control = TEXCOORDMODE_CLAMP;
-    ts->ts1.tcy_control = TEXCOORDMODE_CLAMP;
-    ts->ts1.tcz_control = TEXCOORDMODE_CLAMP;
-    ts->ts1.normalized_coor = 0;
-    ts->ts1.map_index = 1;
-    ts->ts1.east_deinterlacer = 0;
-    ts->ts2.default_color = 0;
-}
-
-static void i915_inst_arith(unsigned int *inst,
-                            unsigned int op,
-                            unsigned int dest,
-                            unsigned int mask,
-                            unsigned int saturate,
-                            unsigned int src0, unsigned int src1, unsigned int src2)
-{
-    dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest));
-    *inst = (op | A0_DEST(dest) | mask | saturate | A0_SRC0(src0));
-    inst++;
-    *inst = (A1_SRC0(src0) | A1_SRC1(src1));
-    inst++;
-    *inst = (A2_SRC1(src1) | A2_SRC2(src2));
-}
-
-static void i915_inst_decl(unsigned int *inst,
-                           unsigned int type,
-                           unsigned int nr,
-                           unsigned int d0_flags)
-{
-    unsigned int reg = UREG(type, nr);
-
-    *inst = (D0_DCL | D0_DEST(reg) | d0_flags);
-    inst++;
-    *inst = D1_MBZ;
-    inst++;
-    *inst = D2_MBZ;
-}
-
-static void i915_inst_texld(unsigned int *inst,
-                              unsigned int op,
-                              unsigned int dest,
-                              unsigned int coord,
-                              unsigned int sampler)
-{
-   dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest));
-   *inst = (op | T0_DEST(dest) | T0_SAMPLER(sampler));
-   inst++;
-   *inst = T1_ADDRESS_REG(coord);
-   inst++;
-   *inst = T2_MBZ;
-}
-
-static void i915_mc_pixel_shader_program_buffer(XvMCContext *context)
-{
-    struct i915_3dstate_pixel_shader_program *pixel_shader_program;
-    i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
-    unsigned int *inst;
-    unsigned int dest, src0, src1, src2;
-
-    /* Shader 0 */
-    pixel_shader_program = (struct i915_3dstate_pixel_shader_program *)pI915XvMC->psp.map;
-    memset(pixel_shader_program, 0, sizeof(*pixel_shader_program));
-    pixel_shader_program->dw0.type = CMD_3D;
-    pixel_shader_program->dw0.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM;
-    pixel_shader_program->dw0.retain = 1;
-    pixel_shader_program->dw0.length = 2;
-    /* mov oC, c0.0000 */
-    inst = (unsigned int*)(++pixel_shader_program);
-    dest = UREG(REG_TYPE_OC, 0);
-    src0 = UREG(REG_TYPE_CONST, 0);
-    src1 = 0;
-    src2 = 0;
-    i915_inst_arith(inst, A0_MOV, dest, A0_DEST_CHANNEL_ALL,
-                    A0_DEST_SATURATE, src0, src1, src2);
-    inst += 3;
-
-    /* Shader 1 */
-    pixel_shader_program = (struct i915_3dstate_pixel_shader_program *)inst;
-    memset(pixel_shader_program, 0, sizeof(*pixel_shader_program));
-    pixel_shader_program->dw0.type = CMD_3D;
-    pixel_shader_program->dw0.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM;
-    pixel_shader_program->dw0.retain = 1;
-    pixel_shader_program->dw0.length = 14;
-    /* dcl t0.xy */
-    inst = (unsigned int*)(++pixel_shader_program);
-    i915_inst_decl(inst, REG_TYPE_T, T_TEX0, D0_CHANNEL_XY);
-    /* dcl t1.xy */
-    inst += 3;
-    i915_inst_decl(inst, REG_TYPE_T, T_TEX1, D0_CHANNEL_XY);
-    /* dcl_2D s0 */
-    inst += 3;
-    i915_inst_decl(inst, REG_TYPE_S, 0, D0_SAMPLE_TYPE_2D);
-    /* texld r0, t0, s0 */
-    inst += 3;
-    dest = UREG(REG_TYPE_R, 0);
-    src0 = UREG(REG_TYPE_T, 0); /* COORD */
-    src1 = UREG(REG_TYPE_S, 0); /* SAMPLER */
-    i915_inst_texld(inst, T0_TEXLD, dest, src0, src1);
-    /* mov oC, r0 */
-    inst += 3;
-    dest = UREG(REG_TYPE_OC, 0);
-    src0 = UREG(REG_TYPE_R, 0);
-    src1 = src2 = 0;
-    i915_inst_arith(inst, A0_MOV, dest, A0_DEST_CHANNEL_ALL,
-                    A0_DEST_SATURATE, src0, src1, src2);
-    inst += 3;
-
-    /* Shader 2 */
-    pixel_shader_program = (struct i915_3dstate_pixel_shader_program *)inst;
-    memset(pixel_shader_program, 0, sizeof(*pixel_shader_program));
-    pixel_shader_program->dw0.type = CMD_3D;
-    pixel_shader_program->dw0.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM;
-    pixel_shader_program->dw0.retain = 1;
-    pixel_shader_program->dw0.length = 14;
-    /* dcl t2.xy */
-    inst = (unsigned int*)(++pixel_shader_program);
-    i915_inst_decl(inst, REG_TYPE_T, T_TEX2, D0_CHANNEL_XY);
-    /* dcl t3.xy */
-    inst += 3;
-    i915_inst_decl(inst, REG_TYPE_T, T_TEX3, D0_CHANNEL_XY);
-    /* dcl_2D s1 */
-    inst += 3;
-    i915_inst_decl(inst, REG_TYPE_S, 1, D0_SAMPLE_TYPE_2D);
-    /* texld r0, t2, s1 */
-    inst += 3;
-    dest = UREG(REG_TYPE_R, 0);
-    src0 = UREG(REG_TYPE_T, 2); /* COORD */
-    src1 = UREG(REG_TYPE_S, 1); /* SAMPLER */
-    i915_inst_texld(inst, T0_TEXLD, dest, src0, src1);
-    /* mov oC, r0 */
-    inst += 3;
-    dest = UREG(REG_TYPE_OC, 0);
-    src0 = UREG(REG_TYPE_R, 0);
-    src1 = src2 = 0;
-    i915_inst_arith(inst, A0_MOV, dest, A0_DEST_CHANNEL_ALL,
-                    A0_DEST_SATURATE, src0, src1, src2);
-    inst += 3;
-
-    /* Shader 3 */
-    pixel_shader_program = (struct i915_3dstate_pixel_shader_program *)inst;
-    memset(pixel_shader_program, 0, sizeof(*pixel_shader_program));
-    pixel_shader_program->dw0.type = CMD_3D;
-    pixel_shader_program->dw0.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM;
-    pixel_shader_program->dw0.retain = 1;
-    pixel_shader_program->dw0.length = 29;
-    /* dcl t0.xy */
-    inst = (unsigned int*)(++pixel_shader_program);
-    i915_inst_decl(inst, REG_TYPE_T, T_TEX0, D0_CHANNEL_XY);
-    /* dcl t1.xy */
-    inst += 3;
-    i915_inst_decl(inst, REG_TYPE_T, T_TEX1, D0_CHANNEL_XY);
-    /* dcl t2.xy */
-    inst += 3;
-    i915_inst_decl(inst, REG_TYPE_T, T_TEX2, D0_CHANNEL_XY);
-    /* dcl t3.xy */
-    inst += 3;
-    i915_inst_decl(inst, REG_TYPE_T, T_TEX3, D0_CHANNEL_XY);
-    /* dcl_2D s0 */
-    inst += 3;
-    i915_inst_decl(inst, REG_TYPE_S, 0, D0_SAMPLE_TYPE_2D);
-    /* dcl_2D s1 */
-    inst += 3;
-    i915_inst_decl(inst, REG_TYPE_S, 1, D0_SAMPLE_TYPE_2D);
-    /* texld r0, t0, s0 */
-    inst += 3;
-    dest = UREG(REG_TYPE_R, 0);
-    src0 = UREG(REG_TYPE_T, 0); /* COORD */
-    src1 = UREG(REG_TYPE_S, 0); /* SAMPLER */
-    i915_inst_texld(inst, T0_TEXLD, dest, src0, src1);
-    /* texld r1, t2, s1 */
-    inst += 3;
-    dest = UREG(REG_TYPE_R, 1);
-    src0 = UREG(REG_TYPE_T, 2); /* COORD */
-    src1 = UREG(REG_TYPE_S, 1); /* SAMPLER */
-    i915_inst_texld(inst, T0_TEXLD, dest, src0, src1);
-    /* add r0, r0, r1 */
-    inst += 3;
-    dest = UREG(REG_TYPE_R, 0);
-    src0 = UREG(REG_TYPE_R, 0);
-    src1 = UREG(REG_TYPE_R, 1);
-    src2 = 0;
-    i915_inst_arith(inst, A0_ADD, dest, A0_DEST_CHANNEL_ALL,
-                    0 /* A0_DEST_SATURATE */, src0, src1, src2);
-    /* mul oC, r0, c0 */
-    inst += 3;
-    dest = UREG(REG_TYPE_OC, 0);
-    src0 = UREG(REG_TYPE_R, 0);
-    src1 = UREG(REG_TYPE_CONST, 0);
-    src2 = 0;
-    i915_inst_arith(inst, A0_MUL, dest, A0_DEST_CHANNEL_ALL,
-                    A0_DEST_SATURATE, src0, src1, src2);
-    inst += 3;
-}
-
-static void i915_mc_pixel_shader_constants_buffer(XvMCContext *context)
-{
-    struct i915_3dstate_pixel_shader_constants *pixel_shader_constants;
-    i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
-    float *value;
-
-    pixel_shader_constants = (struct i915_3dstate_pixel_shader_constants *)pI915XvMC->psc.map;
-    memset(pixel_shader_constants, 0, sizeof(*pixel_shader_constants));
-    pixel_shader_constants->dw0.type = CMD_3D;
-    pixel_shader_constants->dw0.opcode = OPC_3DSTATE_PIXEL_SHADER_CONSTANTS;
-    pixel_shader_constants->dw0.length = 4;
-    pixel_shader_constants->dw1.reg_mask = REG_CR0;
-    value = (float *)(++pixel_shader_constants);
-    *(value++) = 0.5;
-    *(value++) = 0.5;
-    *(value++) = 0.5;
-    *(value++) = 0.5;
-}
-
-static void i915_mc_one_time_state_initialization(XvMCContext *context)
-{
-    struct i915_3dstate_load_state_immediate_1 *load_state_immediate_1 = NULL;
-    struct s3_dword *s3 = NULL;
-    struct s6_dword *s6 = NULL;
-    struct i915_3dstate_load_indirect *load_indirect = NULL;
-    dis_state *dis = NULL;
-    ssb_state *ssb = NULL;
-    psp_state *psp = NULL;
-    psc_state *psc = NULL;
-    i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
-    unsigned int size;
-    void *base = NULL;
-    int mem_select = 1;
-
-    /* 3DSTATE_LOAD_STATE_IMMEDIATE_1 */
-    size = sizeof(*load_state_immediate_1) + sizeof(*s3) + sizeof(*s6);
-    base = calloc(1, size);
-    load_state_immediate_1 = (struct i915_3dstate_load_state_immediate_1 *)base;
-    load_state_immediate_1->dw0.type = CMD_3D;
-    load_state_immediate_1->dw0.opcode = OPC_3DSTATE_LOAD_STATE_IMMEDIATE_1;
-    load_state_immediate_1->dw0.load_s3 = 1;
-    load_state_immediate_1->dw0.load_s6 = 1;
-    load_state_immediate_1->dw0.length = (size >> 2) - 2;
-
-    s3 = (struct s3_dword *)(++load_state_immediate_1);
-    s3->set0_pcd = 1;
-    s3->set1_pcd = 1;
-    s3->set2_pcd = 1;
-    s3->set3_pcd = 1;
-    s3->set4_pcd = 1;
-    s3->set5_pcd = 1;
-    s3->set6_pcd = 1;
-    s3->set7_pcd = 1;
-
-    s6 = (struct s6_dword *)(++s3);
-    s6->alpha_test_enable = 0;
-    s6->alpha_test_function = 0;
-    s6->alpha_reference_value = 0;
-    s6->depth_test_enable = 1;
-    s6->depth_test_function = 0;
-    s6->color_buffer_blend = 0;
-    s6->color_blend_function = 0;
-    s6->src_blend_factor = 1;
-    s6->dest_blend_factor = 1;
-    s6->depth_buffer_write = 0;
-    s6->color_buffer_write = 1;
-    s6->triangle_pv = 0;
-
-    intelBatchbufferData(base, size, 0);
-    free(base);
-
-    /* 3DSTATE_LOAD_INDIRECT */
-    size = sizeof(*load_indirect) + sizeof(*dis) + sizeof(*ssb) + sizeof(*psp) + sizeof(*psc);
-    base = calloc(1, size);
-    load_indirect = (struct i915_3dstate_load_indirect *)base;
-    load_indirect->dw0.type = CMD_3D;
-    load_indirect->dw0.opcode = OPC_3DSTATE_LOAD_INDIRECT;
-    load_indirect->dw0.block_mask = BLOCK_DIS | BLOCK_SSB | BLOCK_PSP | BLOCK_PSC;
-    load_indirect->dw0.length = (size >> 2) - 2;
-
-    if (pI915XvMC->deviceID == PCI_CHIP_I915_G ||
-        pI915XvMC->deviceID == PCI_CHIP_I915_GM ||
-        pI915XvMC->deviceID == PCI_CHIP_I945_G ||
-        pI915XvMC->deviceID == PCI_CHIP_I945_GM)
-        mem_select = 0;
-
-    load_indirect->dw0.mem_select = mem_select;
-
-    /* DIS */
-    dis = (dis_state *)(++load_indirect);
-    dis->dw0.valid = 0;
-    dis->dw0.reset = 0;
-    dis->dw0.buffer_address = 0;
-
-    /* SSB */
-    ssb = (ssb_state *)(++dis);
-    ssb->dw0.valid = 1;
-    ssb->dw0.force = 1;
-    ssb->dw1.length = 7; /* 8 - 1 */
-
-    if (mem_select)
-        ssb->dw0.buffer_address = (pI915XvMC->ssb.offset >> 2);
-    else
-        ssb->dw0.buffer_address = (pI915XvMC->ssb.bus_addr >> 2);
-
-    /* PSP */
-    psp = (psp_state *)(++ssb);
-    psp->dw0.valid = 1;
-    psp->dw0.force = 1;
-    psp->dw1.length = 66; /* 4 + 16 + 16 + 31 - 1 */
-
-    if (mem_select)
-        psp->dw0.buffer_address = (pI915XvMC->psp.offset >> 2);
-    else
-        psp->dw0.buffer_address = (pI915XvMC->psp.bus_addr >> 2);
-
-    /* PSC */
-    psc = (psc_state *)(++psp);
-    psc->dw0.valid = 1;
-    psc->dw0.force = 1;
-    psc->dw1.length = 5; /* 6 - 1 */
-
-    if (mem_select)
-        psc->dw0.buffer_address = (pI915XvMC->psc.offset >> 2);
-    else
-        psc->dw0.buffer_address = (pI915XvMC->psc.bus_addr >> 2);
-
-    intelBatchbufferData(base, size, 0);
-    free(base);
-}
-
 #if 0
 static void i915_mc_invalidate_subcontext_buffers(XvMCContext *context, unsigned int mask)
 {
@@ -1683,6 +1663,11 @@ static Status i915_xvmc_mc_create_context(Display *display, XvMCContext *context
     pI915XvMC->last_flip = 0;
     pI915XvMC->port = context->port;
     pI915XvMC->ref = 1;
+
+    /* preinit state buffers */
+    i915_mc_one_time_context_init(context);
+    i915_mc_one_time_state_init(context);
+
     return Success;
 }
 
@@ -1695,6 +1680,9 @@ static int i915_xvmc_mc_destroy_context(Display *display, XvMCContext *context)
 
     /* Pass Control to the X server to destroy the drm_context_t */
     i915_release_resource(display,context);
+
+    free(one_time_load_state_imm1);
+    free(one_time_load_indirect);
     return Success;
 }
 
@@ -1937,10 +1925,7 @@ static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context,
     // i915_mc_invalidate_subcontext_buffers(context, BLOCK_SIS | BLOCK_DIS | BLOCK_SSB
     // | BLOCK_MSB | BLOCK_PSP | BLOCK_PSC);
 
-    i915_mc_sampler_state_buffer(context);
-    i915_mc_pixel_shader_program_buffer(context);
-    i915_mc_pixel_shader_constants_buffer(context);
-    i915_mc_one_time_state_initialization(context);
+    i915_mc_one_time_state_emit();
 
     i915_mc_static_indirect_state_buffer(context, target_surface,
                                          picture_structure, flags,
diff --git a/src/xvmc/intel_xvmc.h b/src/xvmc/intel_xvmc.h
index 4d8b605..c4dfd77 100644
--- a/src/xvmc/intel_xvmc.h
+++ b/src/xvmc/intel_xvmc.h
@@ -38,6 +38,7 @@
 #include <string.h>
 #include <assert.h>
 #include <signal.h>
+#include <stdint.h>
 
 #include <xf86drm.h>
 #include "i830_common.h"
commit 3f57fd5fef6bb6baefa3d157d4e5d9c6154c67d5
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Mon Jun 23 15:51:49 2008 +0800

    xvmc: environ debug option support
    
    export INTEL_XVMC_DEBUG=1
    (cherry picked from commit 54f3f528e4804b958936ac773e7a507b2676f815)

diff --git a/src/xvmc/intel_xvmc.c b/src/xvmc/intel_xvmc.c
index 0db3ca6..8fabb35 100644
--- a/src/xvmc/intel_xvmc.c
+++ b/src/xvmc/intel_xvmc.c
@@ -98,9 +98,17 @@ unsigned int mb_bytes_420[] = {
     768  /* 111111 */
 };
 
+int DEBUG;
+
 static int error_base;
 static int event_base;
 
+static void intel_xvmc_debug_init(void)
+{
+    if (getenv("INTEL_XVMC_DEBUG"))
+	DEBUG = 1;
+}
+
 /* locking */
 static void intel_xvmc_try_heavy_lock(drm_context_t ctx)
 {
@@ -282,6 +290,8 @@ Status XvMCCreateContext(Display *display, XvPortID port,
         return BadValue;
     }
 
+    intel_xvmc_debug_init();
+
     /* Open DRI Device */
     if((fd = drmOpen("i915", NULL)) < 0) {
         XVMC_ERR("DRM Device could not be opened.");
diff --git a/src/xvmc/intel_xvmc.h b/src/xvmc/intel_xvmc.h
index 3119623..4d8b605 100644
--- a/src/xvmc/intel_xvmc.h
+++ b/src/xvmc/intel_xvmc.h
@@ -56,7 +56,7 @@
 
 #include "intel_batchbuffer.h"
 
-#define DEBUG 0
+extern int DEBUG;
 
 #define XVMC_ERR(s, arg...)					\
     do {							\
commit 736bed6734cf1a070fc7da6a1384edc5fd466887
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Mon Jun 23 15:49:29 2008 +0800

    xvmc: formalize surface type definition
    
    We should also carefully select surface type id.
    (cherry picked from commit 7a705081788bf957409e17baa5f189241589057c)

diff --git a/src/i830_hwmc.h b/src/i830_hwmc.h
index 6920e01..4db9aea 100644
--- a/src/i830_hwmc.h
+++ b/src/i830_hwmc.h
@@ -47,6 +47,13 @@
 #define XVMC_I945_MPEG2_VLD	0x04
 #define XVMC_I965_MPEG2_VLD	0x08
 
+/* supported surface types */
+enum {
+    SURFACE_TYPE_MPEG2_MPML = FOURCC_XVMC, /* mpeg2 MP at ML */
+    SURFACE_TYPE_MPEG1_MPML,		   /* mpeg1 MP at ML */
+    SURFACE_TYPE_MAX
+};
+
 /* common header for context private */
 struct hwmc_buffer
 {
diff --git a/src/i915_hwmc.c b/src/i915_hwmc.c
index 50e1106..973cabf 100644
--- a/src/i915_hwmc.c
+++ b/src/i915_hwmc.c
@@ -111,7 +111,7 @@ static XF86MCImageIDList yv12_subpicture_list =
 
 static XF86MCSurfaceInfoRec i915_YV12_mpg2_surface =
 {
-    FOURCC_YV12,
+    SURFACE_TYPE_MPEG2_MPML,
     XVMC_CHROMA_FORMAT_420,
     0,
     720,
@@ -127,7 +127,7 @@ static XF86MCSurfaceInfoRec i915_YV12_mpg2_surface =
 
 static XF86MCSurfaceInfoRec i915_YV12_mpg1_surface =
 {
-    FOURCC_YV12,
+    SURFACE_TYPE_MPEG1_MPML,
     XVMC_CHROMA_FORMAT_420,
     0,
     720,
diff --git a/src/xvmc/i915_xvmc.c b/src/xvmc/i915_xvmc.c
index 519de5a..bd31de4 100644
--- a/src/xvmc/i915_xvmc.c
+++ b/src/xvmc/i915_xvmc.c
@@ -1850,9 +1850,8 @@ static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context,
     if (!(privTarget = target_surface->privData))
         return XvMCBadSurface;
 
-    /* Test For YV12 Surface */
-    if (context->surface_type_id != FOURCC_YV12) {
-        XVMC_ERR("HWMC only possible on YV12 Surfaces.");
+    if (context->surface_type_id >= SURFACE_TYPE_MAX) {
+        XVMC_ERR("Unsupprted surface_type_id %d.", context->surface_type_id);
         return BadValue;
     }
 
commit c61480f420445f7e3341305362b8cea656b0f7a2
Author: Jesse Barnes <jbarnes at jbarnes-t61.(none)>
Date:   Fri Jun 27 13:39:31 2008 -0700

    Add pipea force enable quirk for HP Pavilion ze4944ea
    
    Fixes bug #16540, thanks Bryce.
    (cherry picked from commit 0283d22f510ba47dfdac2806a58e46649c26580b)

diff --git a/src/i830_quirks.c b/src/i830_quirks.c
index 1beda4b..f7659f0 100644
--- a/src/i830_quirks.c
+++ b/src/i830_quirks.c
@@ -267,6 +267,8 @@ static i830_quirk i830_quirk_list[] = {
 
     /* HP Compaq 6730s has no TV output */
     { PCI_CHIP_IGD_GM, 0x103c, 0x30e8, quirk_ignore_tv },
+    /* HP Pavilion ze4944ea needs pipe A force quirk (See LP: #242389) */
+    { PCI_CHIP_IGD_GM, 0x103c, 0x3084, quirk_pipea_force },
 
     /* Thinkpad R31 needs pipe A force quirk */
     { PCI_CHIP_I830_M, 0x1014, 0x0505, quirk_pipea_force },
commit 9869cd11549cd608593fea111880502192e93fd5
Author: Jesse Barnes <jbarnes at jbarnes-t61.(none)>
Date:   Fri Jun 27 13:37:10 2008 -0700

    Add pipe a force enable quirk for Lenovo T60
    
    Fixes bug #16494.
    (cherry picked from commit 08903abe4dc0295c7ed7d1ff1a22e0e579540c15)

diff --git a/src/i830_quirks.c b/src/i830_quirks.c
index 1bd8885..1beda4b 100644
--- a/src/i830_quirks.c
+++ b/src/i830_quirks.c
@@ -288,6 +288,9 @@ static i830_quirk i830_quirk_list[] = {
     /* ThinkPad X40 needs pipe A force quirk */
     { PCI_CHIP_I855_GM, 0x1014, 0x0557, quirk_pipea_force },
 
+    /* ThinkPad T60 needs pipe A force quirk (bug #16494) */
+    { PCI_CHIP_I945_GM, 0x17aa, 0x201a, quirk_pipea_force },
+
     /* Sony vaio PCG-r600HFP (fix bug 13722) */
     { PCI_CHIP_I830_M, 0x104d, 0x8100, quirk_ivch_dvob },
     /* Sony vaio VGN-SZ4MN (See LP: #212163) */


More information about the xorg-commit mailing list