xf86-video-intel: 10 commits - src/common.h src/i830_driver.c src/i830.h src/i830_hwmc.c src/i830_hwmc.h src/i830_video.c src/i830_video.h src/i915_hwmc.c src/i915_hwmc.h src/i915_video.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
Fri Jun 27 20:23:50 PDT 2008


 src/common.h               |    1 
 src/i830.h                 |    1 
 src/i830_driver.c          |    2 
 src/i830_hwmc.c            |    5 
 src/i830_hwmc.h            |    7 
 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/xvmc/i915_structs.h    |   81 ++
 src/xvmc/i915_xvmc.c       | 1312 ++++++++++++++++++++++-----------------------
 src/xvmc/intel_xvmc.c      |   10 
 src/xvmc/intel_xvmc.h      |    3 
 src/xvmc/intel_xvmc_dump.c |   31 -
 15 files changed, 829 insertions(+), 743 deletions(-)

New commits:
commit 37661d916e8384f537d5ed8cbec66a93795c6a05
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Fri Jun 27 11:21:59 2008 +0800

    Fix SDVOC typo

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 7834a3b118ae4e034f064257762d5c25ada5fe52
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

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 989ec9e8a69f909cb64f17e4465982613b4b054d
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.

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 550082070a3fdb951e3cf08974dc56276c0a739c
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Thu Jun 26 14:22:34 2008 +0800

    xvmc: enlarge batch buffer size

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

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 d1c34d8c0e7ae2a1d952791343e131837fbfda99
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

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 75e38fa8348198ba151afa37e10be3b0b0b468f8
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.

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

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 54f3f528e4804b958936ac773e7a507b2676f815
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

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

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;
     }
 


More information about the xorg-commit mailing list