xf86-video-intel: Branch 'pfit' - 105 commits - configure.ac man/intel.man src/brw_defines.h src/brw_structs.h src/i830_crt.c src/i830_dri.c src/i830_driver.c src/i830_dvo.c src/i830_exa.c src/i830.h src/i830_hwmc.c src/i830_hwmc.h src/i830_lvds.c src/i830_memory.c src/i830_quirks.c src/i830_render.c src/i830_sdvo.c src/i830_tv.c src/i830_video.c src/i915_3d.h src/i915_hwmc.c src/i915_hwmc.h src/i915_reg.h src/i915_render.c src/i965_render.c src/Makefile.am src/xvmc/driDrawable.c src/xvmc/driDrawable.h src/xvmc/i915_program.h src/xvmc/i915_structs.h src/xvmc/i915_xvmc.c src/xvmc/i915_xvmc.h src/xvmc/intel_batchbuffer.c src/xvmc/intel_batchbuffer.h src/xvmc/intel_xvmc.c src/xvmc/intel_xvmc.h src/xvmc/Makefile.am src/xvmc/xf86dri.c src/xvmc/xf86dri.h src/xvmc/xf86dristr.h

Jesse Barnes jbarnes at kemper.freedesktop.org
Wed Mar 26 14:53:29 PDT 2008


 configure.ac                 |   24 
 man/intel.man                |    5 
 src/Makefile.am              |   17 
 src/brw_defines.h            |   26 
 src/brw_structs.h            |  107 +
 src/i830.h                   |   26 
 src/i830_crt.c               |    2 
 src/i830_dri.c               |    2 
 src/i830_driver.c            |   55 
 src/i830_dvo.c               |    2 
 src/i830_exa.c               |   74 +
 src/i830_hwmc.c              |  154 ++
 src/i830_hwmc.h              |  106 +
 src/i830_lvds.c              |    2 
 src/i830_memory.c            |   39 
 src/i830_quirks.c            |    2 
 src/i830_render.c            |  207 ++-
 src/i830_sdvo.c              |    2 
 src/i830_tv.c                |    2 
 src/i830_video.c             |   78 +
 src/i915_3d.h                |    5 
 src/i915_hwmc.c              |  876 ++++++++++++++
 src/i915_hwmc.h              |   61 +
 src/i915_reg.h               |   10 
 src/i915_render.c            |   34 
 src/i965_render.c            |   44 
 src/xvmc/Makefile.am         |   22 
 src/xvmc/driDrawable.c       |  174 ++
 src/xvmc/driDrawable.h       |   64 +
 src/xvmc/i915_program.h      |  276 ++++
 src/xvmc/i915_structs.h      |  973 ++++++++++++++++
 src/xvmc/i915_xvmc.c         | 2540 +++++++++++++++++++++++++++++++++++++++++++
 src/xvmc/i915_xvmc.h         |  117 +
 src/xvmc/intel_batchbuffer.c |  272 ++++
 src/xvmc/intel_batchbuffer.h |   42 
 src/xvmc/intel_xvmc.c        | 1069 ++++++++++++++++++
 src/xvmc/intel_xvmc.h        |  253 ++++
 src/xvmc/xf86dri.c           |  566 +++++++++
 src/xvmc/xf86dri.h           |  118 +
 src/xvmc/xf86dristr.h        |  390 ++++++
 40 files changed, 8696 insertions(+), 142 deletions(-)

New commits:
commit 588371ba15afffa9343629f0ea7ce530586eef0b
Merge: 52d6ced... c13efdd...
Author: Jesse Barnes <jbarnes at hobbes.virtuousgeek.org>
Date:   Wed Mar 26 14:53:15 2008 -0700

    Merge branch 'master' into pfit

commit c13efdd3d6d3846078766814b57306a7519bce18
Author: Paulo Cesar Pereira de Andrade <pcpa at mandriva.com.br>
Date:   Wed Mar 26 10:11:36 2008 +0800

    More compile warning fixes.
    
    o Check for RANDR_GET_CRTC_INTERFACE before defining functions that
      are used only if it is defined.
    o Declare a variable before code, and rename it from ret to xvmc_status
      to better describe it.
    o if 0 some static functions not used.
    o Don't declare some unused variables.
    o Declare as static some functions that are used only in the file defining it.
    o Add a default/fallback return True to the Bool function
      src/xvmc/intel_batchbuffer.c:intelInitBatchBuffer().
    o Ansify src/xvmc/xf86dri.c.
    o Add missing prototype to src/xvmc/xf86dri.h and follow pattern of other
      headers by adding "extern" before function prototype.

diff --git a/src/i830_crt.c b/src/i830_crt.c
index d1ed3a8..2a99f9c 100644
--- a/src/i830_crt.c
+++ b/src/i830_crt.c
@@ -391,6 +391,7 @@ i830_crt_destroy (xf86OutputPtr output)
 	xfree (output->driver_private);
 }
 
+#ifdef RANDR_GET_CRTC_INTERFACE
 static xf86CrtcPtr
 i830_crt_get_crtc(xf86OutputPtr output)
 {
@@ -400,6 +401,7 @@ i830_crt_get_crtc(xf86OutputPtr output)
    
     return i830_pipe_to_crtc(pScrn, pipe);
 }
+#endif
 
 static const xf86OutputFuncsRec i830_crt_output_funcs = {
     .dpms = i830_crt_dpms,
diff --git a/src/i830_dvo.c b/src/i830_dvo.c
index 7561833..9e82171 100644
--- a/src/i830_dvo.c
+++ b/src/i830_dvo.c
@@ -330,6 +330,7 @@ i830_dvo_destroy (xf86OutputPtr output)
     }
 }
 
+#ifdef RANDR_GET_CRTC_INTERFACE
 static xf86CrtcPtr
 i830_dvo_get_crtc(xf86OutputPtr output)
 {
@@ -341,6 +342,7 @@ i830_dvo_get_crtc(xf86OutputPtr output)
    
     return i830_pipe_to_crtc(pScrn, pipe);
 }
+#endif
 
 static const xf86OutputFuncsRec i830_dvo_output_funcs = {
     .dpms = i830_dvo_dpms,
diff --git a/src/i830_lvds.c b/src/i830_lvds.c
index 0b331ef..772a8b8 100644
--- a/src/i830_lvds.c
+++ b/src/i830_lvds.c
@@ -879,6 +879,7 @@ i830_lvds_get_property(xf86OutputPtr output, Atom property)
 }
 #endif /* RANDR_13_INTERFACE */
 
+#ifdef RANDR_GET_CRTC_INTERFACE
 static xf86CrtcPtr
 i830_lvds_get_crtc(xf86OutputPtr output)
 {
@@ -888,6 +889,7 @@ i830_lvds_get_crtc(xf86OutputPtr output)
    
     return i830_pipe_to_crtc(pScrn, pipe);
 }
+#endif
 
 static const xf86OutputFuncsRec i830_lvds_output_funcs = {
     .create_resources = i830_lvds_create_resources,
diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c
index d72b913..f60e38c 100644
--- a/src/i830_sdvo.c
+++ b/src/i830_sdvo.c
@@ -1146,6 +1146,7 @@ i830_sdvo_destroy (xf86OutputPtr output)
     }
 }
 
+#ifdef RANDR_GET_CRTC_INTERFACE
 static xf86CrtcPtr
 i830_sdvo_get_crtc(xf86OutputPtr output)
 {
@@ -1157,6 +1158,7 @@ i830_sdvo_get_crtc(xf86OutputPtr output)
    
     return i830_pipe_to_crtc(pScrn, pipe);
 }
+#endif
 
 static const xf86OutputFuncsRec i830_sdvo_output_funcs = {
     .dpms = i830_sdvo_dpms,
diff --git a/src/i830_tv.c b/src/i830_tv.c
index b478cc7..6adb9f2 100644
--- a/src/i830_tv.c
+++ b/src/i830_tv.c
@@ -1640,6 +1640,7 @@ i830_tv_set_property(xf86OutputPtr output, Atom property,
 }
 #endif /* RANDR_12_INTERFACE */
 
+#ifdef RANDR_GET_CRTC_INTERFACE
 static xf86CrtcPtr
 i830_tv_get_crtc(xf86OutputPtr output)
 {
@@ -1649,6 +1650,7 @@ i830_tv_get_crtc(xf86OutputPtr output)
    
     return i830_pipe_to_crtc(pScrn, pipe);
 }
+#endif
 
 static const xf86OutputFuncsRec i830_tv_output_funcs = {
     .create_resources = i830_tv_create_resources,
diff --git a/src/i830_video.c b/src/i830_video.c
index 5939634..04ce0d6 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -565,6 +565,9 @@ I830InitVideo(ScreenPtr pScreen)
     XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL;
     XF86VideoAdaptorPtr overlayAdaptor = NULL, texturedAdaptor = NULL;
     int num_adaptors;
+#ifdef INTEL_XVMC
+    Bool xvmc_status = FALSE;
+#endif
 
 #if 0
     {
@@ -627,10 +630,9 @@ I830InitVideo(ScreenPtr pScreen)
 	I830InitOffscreenImages(pScreen);
     }
 #ifdef INTEL_XVMC
-    Bool ret = FALSE;
     if (intel_xvmc_probe(pScrn)) {
 	if (texturedAdaptor)
-	    ret = intel_xvmc_driver_init(pScreen, texturedAdaptor);
+	    xvmc_status = intel_xvmc_driver_init(pScreen, texturedAdaptor);
     }
 #endif
 
@@ -638,7 +640,7 @@ I830InitVideo(ScreenPtr pScreen)
 	xf86XVScreenInit(pScreen, adaptors, num_adaptors);
 
 #ifdef INTEL_XVMC
-    if (ret)
+    if (xvmc_status)
 	intel_xvmc_screen_init(pScreen);
 #endif
     xfree(adaptors);
diff --git a/src/i915_hwmc.c b/src/i915_hwmc.c
index cdcef5a..c3d3c75 100644
--- a/src/i915_hwmc.c
+++ b/src/i915_hwmc.c
@@ -97,6 +97,7 @@ typedef struct _I915XvMC
 
 #define ARRARY_SIZE(a) (sizeof(a) / sizeof(a[0]))
 
+/*
 static int yv12_subpicture_index_list[2] =
 {
     FOURCC_IA44,
@@ -108,6 +109,7 @@ static XF86MCImageIDList yv12_subpicture_list =
     ARRARY_SIZE(yv12_subpicture_index_list),
     yv12_subpicture_index_list
 };
+ */
 
 static XF86MCSurfaceInfoRec i915_YV12_mpg2_surface =
 {
@@ -147,6 +149,7 @@ static XF86MCSurfaceInfoPtr ppSI[2] =
     (XF86MCSurfaceInfoPtr)&i915_YV12_mpg1_surface
 };
 
+#if 0
 /* List of subpicture types that we support */
 static XF86ImageRec ia44_subpicture = XVIMAGE_IA44;
 static XF86ImageRec ai44_subpicture = XVIMAGE_AI44;
@@ -156,7 +159,7 @@ static XF86ImagePtr i915_subpicture_list[2] =
     (XF86ImagePtr)&ia44_subpicture,
     (XF86ImagePtr)&ai44_subpicture
 };
-
+#endif
 
 /*
  * Init and clean up the screen private parts of XvMC.
diff --git a/src/xvmc/i915_xvmc.c b/src/xvmc/i915_xvmc.c
index b30facd..20b2e61 100644
--- a/src/xvmc/i915_xvmc.c
+++ b/src/xvmc/i915_xvmc.c
@@ -25,7 +25,6 @@
  *
  */
 
-#include <pthread.h>
 #include <sys/ioctl.h>
 
 #include "i915_xvmc.h"
@@ -56,6 +55,7 @@ typedef union {
     uint  u[2];
 } su_t;
 
+#if 0
 static int findOverlap(unsigned int width, unsigned int height,
                        short *dstX, short *dstY,
                        short *srcX, short *srcY,
@@ -91,6 +91,7 @@ static int findOverlap(unsigned int width, unsigned int height,
     *areaH = (h <= mHeight) ? h : mHeight;
     return 0;
 }
+#endif
 
 static void i915_flush(int map, int render)
 {
@@ -117,7 +118,7 @@ static void i915_mc_static_indirect_state_buffer(XvMCContext *context,
     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, h = surface->height;
+    unsigned int w = surface->width;
 
     /* 3DSTATE_BUFFER_INFO */
     /* DEST Y */
@@ -459,7 +460,7 @@ static void i915_mc_mpeg_macroblock_ipicture(XvMCContext *context, XvMCMacroBloc
     intelBatchbufferData(&macroblock_ipicture, sizeof(macroblock_ipicture), 0);
 }
 
-
+#if 0
 static void i915_mc_mpeg_macroblock_0mv(XvMCContext *context, XvMCMacroBlock *mb)
 {
     struct i915_3dmpeg_macroblock_0mv macroblock_0mv;
@@ -487,6 +488,7 @@ static void i915_mc_mpeg_macroblock_0mv(XvMCContext *context, XvMCMacroBlock *mb
 
     intelBatchbufferData(&macroblock_0mv, sizeof(macroblock_0mv), 0);
 }
+#endif
 
 static void i915_mc_mpeg_macroblock_1fbmv(XvMCContext *context, XvMCMacroBlock *mb)
 {
@@ -529,7 +531,6 @@ 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;
-    i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
 
     /* Motion Vectors */
     su_t fmv;
@@ -979,6 +980,7 @@ static void i915_mc_one_time_state_initialization(XvMCContext *context)
     free(base);
 }
 
+#if 0
 static void i915_mc_invalidate_subcontext_buffers(XvMCContext *context, unsigned int mask)
 {
     struct i915_3dstate_load_indirect *load_indirect = NULL;
@@ -1086,6 +1088,7 @@ static void i915_mc_invalidate_subcontext_buffers(XvMCContext *context, unsigned
     intelBatchbufferData(base, size, 0);
     free(base);
 }
+#endif
 
 static int i915_xvmc_map_buffers(i915XvMCContext *pI915XvMC)
 {
@@ -1167,6 +1170,7 @@ static void i915_xvmc_unmap_buffers(i915XvMCContext *pI915XvMC)
     }
 }
 
+#if 0
 /*
  * Video post processing
  */
@@ -1243,7 +1247,9 @@ static void i915_yuv2rgb_map_state_buffer(XvMCSurface *target_surface)
     tm->tm2.cube_face = 0;
     tm->tm2.pitch = (privTarget->uvStride >> 2) - 1;    /* in DWords - 1 */
 }
+#endif
 
+#if 0
 static void i915_yuv2rgb_sampler_state_buffer(XvMCSurface *surface)
 {
     struct i915_3dstate_sampler_state *sampler_state;
@@ -1340,7 +1346,9 @@ static void i915_yuv2rgb_sampler_state_buffer(XvMCSurface *surface)
     ts->ts1.east_deinterlacer = 0;
     ts->ts2.default_color = 0;
 }
+#endif
 
+#if 0
 static void i915_yuv2rgb_static_indirect_state_buffer(XvMCSurface *surface,
                                                       unsigned int dstaddr,
                                                       int dstpitch)
@@ -1374,7 +1382,9 @@ static void i915_yuv2rgb_static_indirect_state_buffer(XvMCSurface *surface,
     dest_buffer_variables->dw1.dest_h_bias = 8;
     dest_buffer_variables->dw1.color_fmt = COLORBUFFER_A8R8G8B8;  /* FIXME */
 }
+#endif
 
+#if 0
 static void i915_yuv2rgb_pixel_shader_program_buffer(XvMCSurface *surface)
 {
     struct i915_3dstate_pixel_shader_program *pixel_shader_program;
@@ -1424,7 +1434,9 @@ static void i915_yuv2rgb_pixel_shader_program_buffer(XvMCSurface *surface)
     src1 = UREG(REG_TYPE_S, 2); /* SAMPLER */
     i915_inst_texld(inst, T0_TEXLD, dest, src0, src1);
 }
+#endif
 
+#if 0
 static void i915_yuv2rgb_proc(XvMCSurface *surface)
 {
     i915XvMCSurface *privSurface = (i915XvMCSurface *)surface->privData;
@@ -1581,6 +1593,7 @@ static void i915_yuv2rgb_proc(XvMCSurface *surface)
     intelBatchbufferData(base, size, 0);
     free(base);
 }
+#endif
 
 /*
  * Function: i915_release_resource
@@ -1588,7 +1601,6 @@ static void i915_yuv2rgb_proc(XvMCSurface *surface)
 static void i915_release_resource(Display *display, XvMCContext *context)
 {
     i915XvMCContext *pI915XvMC;
-    int screen = DefaultScreen(display);
 
     if (!(pI915XvMC = context->privData))
         return;
@@ -1608,13 +1620,7 @@ static Status i915_xvmc_mc_create_context(Display *display, XvMCContext *context
 {
     i915XvMCContext *pI915XvMC = NULL;
     I915XvMCCreateContextRec *tmpComm = NULL;
-    Status ret;
     drm_sarea_t *pSAREA;
-    char *curBusID;
-    uint magic;
-    int major, minor;
-    int isCapable;
-    int screen = DefaultScreen(display);
 
     XVMC_DBG("%s\n", __FUNCTION__);
 
@@ -1718,7 +1724,6 @@ static Status i915_xvmc_mc_create_surface(Display *display,
 	XvMCContext *context, XvMCSurface *surface, int priv_count,
 	CARD32 *priv_data)
 {
-    Status ret;
     i915XvMCContext *pI915XvMC;
     i915XvMCSurface *pI915Surface;
     I915XvMCCreateSurfaceRec *tmpComm = NULL;
diff --git a/src/xvmc/intel_batchbuffer.c b/src/xvmc/intel_batchbuffer.c
index a3f82ff..224d0de 100644
--- a/src/xvmc/intel_batchbuffer.c
+++ b/src/xvmc/intel_batchbuffer.c
@@ -48,7 +48,7 @@
 
 #define MI_BATCH_BUFFER_END     (0xA << 23)
 
-int intelEmitIrqLocked(void)
+static int intelEmitIrqLocked(void)
 {
    drmI830IrqEmit ie;
    int ret, seq;
@@ -65,7 +65,7 @@ int intelEmitIrqLocked(void)
    return seq;
 }
 
-void intelWaitIrq(int seq)
+static void intelWaitIrq(int seq)
 {
    int ret;
    drmI830IrqWait iw;
@@ -118,6 +118,7 @@ Bool intelInitBatchBuffer(void)
 
     xvmc_driver->alloc.active_buf = 0;
     assert(xvmc_driver->alloc.ptr);
+    return True;
 }
 
 void intelFiniBatchBuffer(void)
@@ -129,7 +130,7 @@ void intelFiniBatchBuffer(void)
     intelDestroyBatchBuffer();
 }
 
-void intelBatchbufferRequireSpace(unsigned int sz)
+static void intelBatchbufferRequireSpace(unsigned int sz)
 {
    if (xvmc_driver->batch.space < sz)
       intelFlushBatch(TRUE);
@@ -152,7 +153,7 @@ void intelBatchbufferData(const void *data, unsigned bytes, unsigned flags)
 #define FLUSH_RENDER_CACHE      (0 << 2)
 #define FLUSH_WRITE_DIRTY_STATE (1 << 4)
 
-void intelRefillBatchLocked(Bool allow_unlock )
+static void intelRefillBatchLocked(Bool allow_unlock)
 {
    unsigned half = xvmc_driver->alloc.size >> 1;
    unsigned buf = (xvmc_driver->alloc.active_buf ^= 1);
@@ -175,9 +176,9 @@ void intelRefillBatchLocked(Bool allow_unlock )
 }
 
 
-void intelFlushBatchLocked(Bool ignore_cliprects,
-                           Bool refill,
-                           Bool allow_unlock)
+static void intelFlushBatchLocked(Bool ignore_cliprects,
+				  Bool refill,
+				  Bool allow_unlock)
 {
    drmI830BatchBuffer batch;
 
diff --git a/src/xvmc/intel_xvmc.c b/src/xvmc/intel_xvmc.c
index 489a2c2..1be8cc6 100644
--- a/src/xvmc/intel_xvmc.c
+++ b/src/xvmc/intel_xvmc.c
@@ -250,7 +250,7 @@ Status XvMCCreateContext(Display *display, XvPortID port,
         XVMC_ERR("Unable to create XvMC Context.");
         return ret;
     }
-    XVMC_DBG("new context %d created\n", context->context_id);
+    XVMC_DBG("new context %d created\n", (int)context->context_id);
 
     comm = (struct _intel_xvmc_common *)priv_data;
 
@@ -341,7 +341,7 @@ Status XvMCCreateContext(Display *display, XvPortID port,
 			     context->context_id,
                              &intel_ctx->hw_context)) {
         XVMC_ERR("Could not create DRI context for xvmc ctx %d.",
-			context->context_id);
+		 (int)context->context_id);
 	XFree(priv_data);
         context->privData = NULL;
         drmUnmap(xvmc_driver->sarea_address, xvmc_driver->sarea_size);
diff --git a/src/xvmc/intel_xvmc.h b/src/xvmc/intel_xvmc.h
index 3375ffc..5506683 100644
--- a/src/xvmc/intel_xvmc.h
+++ b/src/xvmc/intel_xvmc.h
@@ -27,6 +27,7 @@
 #ifndef INTEL_XVMC_H
 #define INTEL_XVMC_H
 
+#include <pthread.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
diff --git a/src/xvmc/xf86dri.c b/src/xvmc/xf86dri.c
index 798c1a8..96987bf 100644
--- a/src/xvmc/xf86dri.c
+++ b/src/xvmc/xf86dri.c
@@ -88,9 +88,8 @@ XEXT_GENERATE_FIND_DISPLAY(find_display, xf86dri_info,
 #else
 #define TRACE(msg, arg...)
 #endif
-    Bool uniDRIQueryExtension(dpy, event_basep, error_basep)
-    Display *dpy;
-    int *event_basep, *error_basep;
+Bool
+uniDRIQueryExtension(Display *dpy, int *event_basep, int *error_basep)
 {
     XExtDisplayInfo *info = find_display(dpy);
 
@@ -107,11 +106,8 @@ XEXT_GENERATE_FIND_DISPLAY(find_display, xf86dri_info,
 }
 
 Bool
-uniDRIQueryVersion(dpy, majorVersion, minorVersion, patchVersion)
-    Display *dpy;
-    int *majorVersion;
-    int *minorVersion;
-    int *patchVersion;
+uniDRIQueryVersion(Display *dpy, int *majorVersion, int *minorVersion,
+		   int *patchVersion)
 {
     XExtDisplayInfo *info = find_display(dpy);
     xXF86DRIQueryVersionReply rep;
@@ -141,10 +137,7 @@ uniDRIQueryVersion(dpy, majorVersion, minorVersion, patchVersion)
 }
 
 Bool
-uniDRIQueryDirectRenderingCapable(dpy, screen, isCapable)
-    Display *dpy;
-    int screen;
-    Bool *isCapable;
+uniDRIQueryDirectRenderingCapable(Display *dpy, int screen, Bool *isCapable)
 {
     XExtDisplayInfo *info = find_display(dpy);
     xXF86DRIQueryDirectRenderingCapableReply rep;
@@ -173,11 +166,8 @@ uniDRIQueryDirectRenderingCapable(dpy, screen, isCapable)
 }
 
 Bool
-uniDRIOpenConnection(dpy, screen, hSAREA, busIdString)
-    Display *dpy;
-    int screen;
-    drm_handle_t *hSAREA;
-    char **busIdString;
+uniDRIOpenConnection(Display *dpy, int screen,
+		     drm_handle_t *hSAREA, char **busIdString)
 {
     XExtDisplayInfo *info = find_display(dpy);
     xXF86DRIOpenConnectionReply rep;
@@ -224,10 +214,7 @@ uniDRIOpenConnection(dpy, screen, hSAREA, busIdString)
 }
 
 Bool
-uniDRIAuthConnection(dpy, screen, magic)
-    Display *dpy;
-    int screen;
-    drm_magic_t magic;
+uniDRIAuthConnection(Display *dpy, int screen, drm_magic_t magic)
 {
     XExtDisplayInfo *info = find_display(dpy);
     xXF86DRIAuthConnectionReq *req;
@@ -256,9 +243,7 @@ uniDRIAuthConnection(dpy, screen, magic)
 }
 
 Bool
-uniDRICloseConnection(dpy, screen)
-    Display *dpy;
-    int screen;
+uniDRICloseConnection(Display *dpy, int screen)
 {
     XExtDisplayInfo *info = find_display(dpy);
     xXF86DRICloseConnectionReq *req;
@@ -279,14 +264,9 @@ uniDRICloseConnection(dpy, screen)
 }
 
 Bool
-uniDRIGetClientDriverName(dpy, screen, ddxDriverMajorVersion,
-    ddxDriverMinorVersion, ddxDriverPatchVersion, clientDriverName)
-    Display *dpy;
-    int screen;
-    int *ddxDriverMajorVersion;
-    int *ddxDriverMinorVersion;
-    int *ddxDriverPatchVersion;
-    char **clientDriverName;
+uniDRIGetClientDriverName(Display *dpy, int screen, int *ddxDriverMajorVersion,
+			  int *ddxDriverMinorVersion, int *ddxDriverPatchVersion,
+			  char **clientDriverName)
 {
     XExtDisplayInfo *info = find_display(dpy);
     xXF86DRIGetClientDriverNameReply rep;
@@ -331,12 +311,8 @@ uniDRIGetClientDriverName(dpy, screen, ddxDriverMajorVersion,
 }
 
 Bool
-uniDRICreateContextWithConfig(dpy, screen, configID, context, hHWContext)
-    Display *dpy;
-    int screen;
-    int configID;
-    XID context;
-    drm_context_t *hHWContext;
+uniDRICreateContextWithConfig(Display *dpy, int screen, int configID,
+			      XID context, drm_context_t *hHWContext)
 {
     XExtDisplayInfo *info = find_display(dpy);
     xXF86DRICreateContextReply rep;
@@ -366,12 +342,8 @@ uniDRICreateContextWithConfig(dpy, screen, configID, context, hHWContext)
 }
 
 Bool
-uniDRICreateContext(dpy, screen, visual, context, hHWContext)
-    Display *dpy;
-    int screen;
-    Visual *visual;
-    XID context;
-    drm_context_t *hHWContext;
+uniDRICreateContext(Display *dpy, int screen, Visual *visual,
+		    XID context, drm_context_t *hHWContext)
 {
     return uniDRICreateContextWithConfig(dpy, screen,
 	   visual->visualid, context, hHWContext);
@@ -539,16 +511,9 @@ uniDRIGetDrawableInfo(Display * dpy, int screen, Drawable drawable,
 }
 
 Bool
-uniDRIGetDeviceInfo(dpy, screen, hFrameBuffer,
-    fbOrigin, fbSize, fbStride, devPrivateSize, pDevPrivate)
-    Display *dpy;
-    int screen;
-    drm_handle_t *hFrameBuffer;
-    int *fbOrigin;
-    int *fbSize;
-    int *fbStride;
-    int *devPrivateSize;
-    void **pDevPrivate;
+uniDRIGetDeviceInfo(Display *dpy, int screen, drm_handle_t *hFrameBuffer,
+		    int *fbOrigin, int *fbSize, int *fbStride,
+		    int *devPrivateSize, void **pDevPrivate)
 {
     XExtDisplayInfo *info = find_display(dpy);
     xXF86DRIGetDeviceInfoReply rep;
diff --git a/src/xvmc/xf86dri.h b/src/xvmc/xf86dri.h
index 7598bc8..81cfdfd 100644
--- a/src/xvmc/xf86dri.h
+++ b/src/xvmc/xf86dri.h
@@ -66,33 +66,33 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #ifndef _XF86DRI_SERVER_
 
 _XFUNCPROTOBEGIN
-    Bool uniDRIQueryExtension(Display * dpy, int *event_base,
+extern Bool uniDRIQueryExtension(Display * dpy, int *event_base,
     int *error_base);
 
-Bool uniDRIQueryVersion(Display * dpy, int *majorVersion, int *minorVersion,
-    int *patchVersion);
+extern Bool uniDRIQueryVersion(Display * dpy, int *majorVersion,
+    int *minorVersion, int *patchVersion);
 
-Bool uniDRIQueryDirectRenderingCapable(Display * dpy, int screen,
+extern Bool uniDRIQueryDirectRenderingCapable(Display * dpy, int screen,
     Bool * isCapable);
 
-Bool uniDRIOpenConnection(Display * dpy, int screen, drm_handle_t * hSAREA,
+extern Bool uniDRIOpenConnection(Display * dpy, int screen, drm_handle_t * hSAREA,
     char **busIDString);
 
-Bool uniDRIAuthConnection(Display * dpy, int screen, drm_magic_t magic);
+extern Bool uniDRIAuthConnection(Display * dpy, int screen, drm_magic_t magic);
 
-Bool uniDRICloseConnection(Display * dpy, int screen);
+extern Bool uniDRICloseConnection(Display * dpy, int screen);
 
-Bool uniDRIGetClientDriverName(Display * dpy, int screen,
+extern Bool uniDRIGetClientDriverName(Display * dpy, int screen,
     int *ddxDriverMajorVersion, int *ddxDriverMinorVersion,
     int *ddxDriverPatchVersion, char **clientDriverName);
 
 /* XvMC context XID is alloced in _xvmc_create_context, so
  * don't recreate here */
-Bool uniDRICreateContext(Display * dpy, int screen, Visual * visual,
+extern Bool uniDRICreateContext(Display * dpy, int screen, Visual * visual,
     XID context_id, drm_context_t * hHWContext);
 
-Bool uniDRICreateContextWithConfig(Display * dpy, int screen, int configID,
-    XID context_id, drm_context_t * hHWContext);
+extern Bool uniDRICreateContextWithConfig(Display * dpy, int screen,
+    int configID, XID context_id, drm_context_t * hHWContext);
 
 extern Bool uniDRIDestroyContext(Display * dpy, int screen, XID context_id);
 
@@ -102,10 +102,17 @@ extern Bool uniDRICreateDrawable(Display * dpy, int screen,
 extern Bool uniDRIDestroyDrawable(Display * dpy, int screen,
     Drawable drawable);
 
-Bool uniDRIGetDeviceInfo(Display * dpy, int screen,
+extern Bool uniDRIGetDeviceInfo(Display * dpy, int screen,
     drm_handle_t * hFrameBuffer, int *fbOrigin, int *fbSize,
     int *fbStride, int *devPrivateSize, void **pDevPrivate);
 
+extern Bool uniDRIGetDrawableInfo(Display * dpy, int screen,
+    Drawable drawable, unsigned int *index, unsigned int *stamp,
+    int *X, int *Y, int *W, int *H,
+    int *numClipRects, drm_clip_rect_t ** pClipRects,
+    int *backX, int *backY,
+    int *numBackClipRects, drm_clip_rect_t ** pBackClipRects);
+
 _XFUNCPROTOEND
 #endif /* _XF86DRI_SERVER_ */
 #endif /* _XF86DRI_H_ */
commit 8cdbd55f8075cd18b563badde35815665d7d053e
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Mar 25 10:06:14 2008 -0700

    Fix 965+ rendering issues with DRI disabled.
    
    The new chips no longer automatically flush the rendering cache, so if we
    don't flush the RC at blockhandler, the last rendering done may not
    appear on the screen.  This was particularly noticable with a bare Xorg with
    some missing root weave, and terminals where the last character wouldn't
    appear until the cursor blinked.  A flush in the DRI blockhandler path had
    hidden this issue for most people.

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 50d9808..b0bb9da 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -2387,6 +2387,15 @@ I830BlockHandler(int i,
     pI830->BlockHandler = pScreen->BlockHandler;
     pScreen->BlockHandler = I830BlockHandler;
 
+    /* Emit a flush of the rendering cache, or on the 965 and beyond
+     * rendering results may not hit the framebuffer until significantly
+     * later.  In the direct rendering case this is already done just
+     * after the page flipping updates, so there's no need to duplicate
+     * the effort here.
+     */
+    if (!pI830->noAccel && !pI830->directRenderingEnabled)
+	I830EmitFlush(pScrn);
+
     I830VideoBlockHandler(i, blockData, pTimeout, pReadmask);
 }
 
commit c02ab432dd7058c700c35eecf6215daf5f262c51
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Mar 24 13:48:20 2008 -0700

    Revert "Use mprotect on unbound AGP memory to attempt to catch use while unbound."
    
    While I still like the idea, the mprotect calls themselves are failing on
    Linux and causing more trouble than they're worth.
    
    This reverts commit a1612b7728d4153499fe86b6713a13c8702cc7d9.
    
    Conflicts:
    
    	src/i830_driver.c
    	src/i830_memory.c

diff --git a/src/i830_driver.c b/src/i830_driver.c
index c2ddf45..50d9808 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -171,7 +171,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include <unistd.h>
 #include <stdlib.h>
 #include <stdio.h>
-#include <sys/mman.h>
 #include <errno.h>
 
 #include "xf86.h"
@@ -697,15 +696,6 @@ I830MapMem(ScrnInfoPtr pScrn)
 	 pI830->FbBase + pI830->LpRing->mem->offset;
    }
 
-   /* Mark the pages we haven't yet bound into AGP as inaccessible. */
-   if (pI830->FbMapSize > pI830->stolen_size) {
-      if (mprotect(pI830->FbBase + pI830->stolen_size,
-		   pI830->FbMapSize - pI830->stolen_size, PROT_NONE) != 0) {
-	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-		    "Failed to mprotect unbound AGP: %s\n", strerror(errno));
-      }
-   }
-
    return TRUE;
 }
 
diff --git a/src/i830_memory.c b/src/i830_memory.c
index 9e23c3c..a38ee78 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -101,7 +101,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include <string.h>
 #include <errno.h>
 #include <sys/types.h>
-#include <sys/mman.h>
 
 #include "xf86.h"
 #include "xf86_OSproc.h"
@@ -204,31 +203,15 @@ i830_bind_memory(ScrnInfoPtr pScrn, i830_memory *mem)
 					mem->allocated_size, mem->tiling);
     }
 
-    /* Mark the pages accessible now that they're bound. */
-    if (mprotect(pI830->FbBase + mem->offset, ALIGN(mem->size, GTT_PAGE_SIZE),
-		 PROT_READ | PROT_WRITE) != 0) {
-	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-		   "Failed to mprotect %s: %s\n", mem->name, strerror(errno));
-    }
-
     return TRUE;
 }
 
 static Bool
 i830_unbind_memory(ScrnInfoPtr pScrn, i830_memory *mem)
 {
-    I830Ptr pI830 = I830PTR(pScrn);
-
     if (mem == NULL || !mem->bound)
 	return TRUE;
 
-    /* Mark the pages accessible now that they're bound. */
-    if (mprotect(pI830->FbBase + mem->offset, ALIGN(mem->size, GTT_PAGE_SIZE),
-		 PROT_NONE) != 0) {
-	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-		   "Failed to mprotect %s: %s\n", mem->name, strerror(errno));
-    }
-
     if (mem->tiling != TILE_NONE)
 	i830_clear_tiling(pScrn, mem->fence_nr);
 
commit 552a1b824db31a234d7c5cb71057ed0e0ce64477
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Mar 24 13:25:37 2008 -0700

    Disable a bunch of clock gating disables on IGD_GM, which doesn't need them.
    
    Besides our driver having fallen through to the GM965 path for
    RENCLK_GATE_D1, the BIOS was turning some of these on.  It may be relevant
    for previous platforms as well to zero out the fields that should be zero
    in the other registers.

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 98f4261..c2ddf45 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -1887,7 +1887,11 @@ SetHWOperatingState(ScrnInfoPtr pScrn)
 
    /* Disable clock gating reported to work incorrectly according to the specs.
     */
-   if (IS_I965GM(pI830)) {
+   if (IS_IGD_GM(pI830)) {
+      OUTREG(RENCLK_GATE_D1, 0);
+      OUTREG(RENCLK_GATE_D2, 0);
+      OUTREG(DSPCLK_GATE_D, VRHUNIT_CLOCK_GATE_DISABLE);
+   } else if (IS_I965GM(pI830)) {
       OUTREG(RENCLK_GATE_D1, I965_RCC_CLOCK_GATE_DISABLE);
    } else if (IS_I965G(pI830)) {
       OUTREG(RENCLK_GATE_D1,
commit c1a2bc357fc122d3718eca771530367ba2915815
Author: Julien Cristau <jcristau at debian.org>
Date:   Mon Mar 24 13:29:24 2008 +0800

    Don't try to build XvMC if DRI is disabled
    
    Instead of failing the build, don't even try unless --enable-xvmc was used.

diff --git a/configure.ac b/configure.ac
index 5b677f0..9965e0b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -67,9 +67,9 @@ AC_ARG_WITH(xserver-source,AC_HELP_STRING([--with-xserver-source=XSERVER_SOURCE]
 			   [ XSERVER_SOURCE="" ])
 
 AC_ARG_ENABLE(xvmc, AC_HELP_STRING([--disable-xvmc],
-                                  [Disable XvMC support [[default=yes]]]),
+                                  [Disable XvMC support [[default=auto]]]),
               [XVMC="$enableval"],
-              [XVMC=yes])
+              [XVMC=auto])
 
 # Checks for extensions
 XORG_DRIVER_CHECK_EXT(XINERAMA, xineramaproto)
@@ -211,6 +211,12 @@ if test "$VIDEO_DEBUG" = yes; then
 fi
 
 AC_MSG_CHECKING([whether to include XvMC support])
+if test "$XVMC" = auto; then
+	XVMC="$DRI"
+fi
+if test "$XVMC" = yes && test "$DRI" = no; then
+	AC_MSG_ERROR([XvMC can't be enabled without DRI])
+fi
 AC_MSG_RESULT([$XVMC])
 AM_CONDITIONAL(XVMC, test x$XVMC = xyes)
 if test "$XVMC" = yes; then
commit 5fcc002f77ebb66c1dc0f901a377ccf9bbc1d0bd
Author: Maxim Levitsky <maximlevitsky at gmail.com>
Date:   Mon Mar 24 13:24:12 2008 +0800

    Fix crash triggered by dpms low power mode with hardware overlay running
    
    When overlay switch crtc, it ignores current crtc dpms mode which
    might lead to hang.

diff --git a/src/i830_video.c b/src/i830_video.c
index 0d0a9a0..5939634 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -385,11 +385,13 @@ i830_overlay_switch_to_crtc (ScrnInfoPtr pScrn, xf86CrtcPtr crtc)
     I830CrtcPrivatePtr  intel_crtc = crtc->driver_private;
     int			pipeconf_reg = intel_crtc->pipe == 0 ? PIPEACONF : PIPEBCONF;
 
-    if (!IS_I965G(pI830) && (INREG(pipeconf_reg) & PIPEACONF_DOUBLE_WIDE))
+    /* overlay can't be used on pipe with double wide, and pipe must be enabled. */
+    if ((!IS_I965G(pI830) && (INREG(pipeconf_reg) & PIPEACONF_DOUBLE_WIDE))
+	    || (intel_crtc->dpms_mode == DPMSModeOff))
 	pPriv->overlayOK = FALSE;
     else
 	pPriv->overlayOK = TRUE;
-    
+
     if (!pPriv->overlayOK)
 	return;
 
@@ -1829,10 +1831,11 @@ i830_display_video(ScrnInfoPtr pScrn, xf86CrtcPtr crtc,
     
     if (crtc != pPriv->current_crtc)
     {
-        pPriv->current_crtc = crtc;
 	i830_overlay_switch_to_crtc (pScrn, crtc);
-	if (pPriv->overlayOK)
+	if (pPriv->overlayOK) {
+	    pPriv->current_crtc = crtc;
 	    I830ResetVideo (pScrn);
+	}
     }
 
     if (!pPriv->overlayOK)
commit 645980596450ed21c3b8927410a6bfe38a0c55d1
Author: Keith Packard <keithp at keithp.com>
Date:   Fri Mar 21 03:08:24 2008 -0700

    Transformed coord computed using floats. Don't move bilinear composite dst.
    
    The homogeneous coordinate computation in the core server cannot be used for
    many legal matrices as it overflows. Just use floats in the driver; faster
    and avoids troubles.
    
    When compositing with bilinear filter, don't push the dst coordinates around
    as that makes the output blurry when pixels are aligned.

diff --git a/src/i830.h b/src/i830.h
index c84e802..1319c6a 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -524,6 +524,7 @@ typedef struct _I830Rec {
    float scale_units[2][2];
   /** Transform pointers for src/mask, or NULL if identity */
    PictTransform *transform[2];
+   float coord_adjust;
    /* i915 EXA render state */
    uint32_t mapstate[6];
    uint32_t samplerstate[6];
@@ -827,11 +828,11 @@ Bool i965_prepare_composite(int op, PicturePtr pSrc, PicturePtr pMask,
 void i965_composite(PixmapPtr pDst, int srcX, int srcY,
 		    int maskX, int maskY, int dstX, int dstY, int w, int h);
 
-void
+Bool
 i830_get_transformed_coordinates(int x, int y, PictTransformPtr transform,
 				 float *x_out, float *y_out);
 
-void
+Bool
 i830_get_transformed_coordinates_3d(int x, int y, PictTransformPtr transform,
 				    float *x_out, float *y_out, float *z_out);
 
diff --git a/src/i830_exa.c b/src/i830_exa.c
index f9df277..9b5bb93 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -339,12 +339,31 @@ I830EXADoneCopy(PixmapPtr pDstPixmap)
 #define xFixedToFloat(val) \
 	((float)xFixedToInt(val) + ((float)xFixedFrac(val) / 65536.0))
 
+static Bool
+_i830_transform_point (PictTransformPtr transform,
+		       float		x,
+		       float		y,
+		       float		result[3])
+{
+    int		    j;
+
+    for (j = 0; j < 3; j++)
+    {
+	result[j] = (xFixedToFloat (transform->matrix[j][0]) * x +
+		     xFixedToFloat (transform->matrix[j][1]) * y +
+		     xFixedToFloat (transform->matrix[j][2]));
+    }
+    if (!result[2])
+	return FALSE;
+    return TRUE;
+}
+
 /**
  * Returns the floating-point coordinates transformed by the given transform.
  *
  * transform may be null.
  */
-void
+Bool
 i830_get_transformed_coordinates(int x, int y, PictTransformPtr transform,
 				 float *x_out, float *y_out)
 {
@@ -352,15 +371,14 @@ i830_get_transformed_coordinates(int x, int y, PictTransformPtr transform,
 	*x_out = x;
 	*y_out = y;
     } else {
-	PictVector v;
-
-        v.vector[0] = IntToxFixed(x);
-        v.vector[1] = IntToxFixed(y);
-        v.vector[2] = xFixed1;
-        PictureTransformPoint(transform, &v);
-	*x_out = xFixedToFloat(v.vector[0]);
-	*y_out = xFixedToFloat(v.vector[1]);
+	float	result[3];
+
+	if (!_i830_transform_point (transform, (float) x, (float) y, result))
+	    return FALSE;
+	*x_out = result[0] / result[2];
+	*y_out = result[1] / result[2];
     }
+    return TRUE;
 }
 
 /**
@@ -368,7 +386,7 @@ i830_get_transformed_coordinates(int x, int y, PictTransformPtr transform,
  *
  * transform may be null.
  */
-void
+Bool
 i830_get_transformed_coordinates_3d(int x, int y, PictTransformPtr transform,
 				    float *x_out, float *y_out, float *w_out)
 {
@@ -377,16 +395,15 @@ i830_get_transformed_coordinates_3d(int x, int y, PictTransformPtr transform,
 	*y_out = y;
 	*w_out = 1;
     } else {
-	PictVector v;
-
-        v.vector[0] = IntToxFixed(x);
-        v.vector[1] = IntToxFixed(y);
-        v.vector[2] = xFixed1;
-        PictureTransformPoint3d(transform, &v);
-	*x_out = xFixedToFloat(v.vector[0]);
-	*y_out = xFixedToFloat(v.vector[1]);
-	*w_out = xFixedToFloat(v.vector[2]);
+	float    result[3];
+
+	if (!_i830_transform_point (transform, (float) x, (float) y, result))
+	    return FALSE;
+	*x_out = result[0];
+	*y_out = result[1];
+	*w_out = result[2];
     }
+    return TRUE;
 }
 
 /**
diff --git a/src/i830_render.c b/src/i830_render.c
index 87543ef..195e9a8 100644
--- a/src/i830_render.c
+++ b/src/i830_render.c
@@ -396,6 +396,7 @@ i830_prepare_composite(int op, PicturePtr pSrcPicture,
     I830Ptr pI830 = I830PTR(pScrn);
     uint32_t dst_format, dst_offset, dst_pitch;
     Bool is_affine_src, is_affine_mask;
+    Bool is_nearest = FALSE;
 
     IntelEmitInvarientState(pScrn);
     *pI830->last_3d = LAST_3D_RENDER;
@@ -407,9 +408,13 @@ i830_prepare_composite(int op, PicturePtr pSrcPicture,
 
     if (!i830_texture_setup(pSrcPicture, pSrc, 0))
 	I830FALLBACK("fail to setup src texture\n");
+    if (pSrcPicture->filter == PictFilterNearest)
+	is_nearest = TRUE;
     if (pMask != NULL) {
 	if (!i830_texture_setup(pMaskPicture, pMask, 1))
 	    I830FALLBACK("fail to setup mask texture\n");
+	if (pMaskPicture->filter == PictFilterNearest)
+	    is_nearest = TRUE;
     } else {
 	pI830->transform[1] = NULL;
 	pI830->scale_units[1][0] = -1;
@@ -419,6 +424,11 @@ i830_prepare_composite(int op, PicturePtr pSrcPicture,
     is_affine_src = i830_transform_is_affine (pI830->transform[0]);
     is_affine_mask = i830_transform_is_affine (pI830->transform[1]);
 
+    if (is_nearest)
+	pI830->coord_adjust = -0.125;
+    else
+	pI830->coord_adjust = 0;
+
     if (!is_affine_src || !is_affine_mask)
 	I830FALLBACK("non-affine transform unsupported on 8xx hardware\n");
 
@@ -591,56 +601,68 @@ i830_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
     per_vertex = 2; /* dest x/y */
     if (is_affine_src)
     {
-	i830_get_transformed_coordinates(srcX, srcY,
-					 pI830->transform[0],
-					 &src_x[0], &src_y[0]);
-	i830_get_transformed_coordinates(srcX, srcY + h,
-					 pI830->transform[0],
-					 &src_x[1], &src_y[1]);
-	i830_get_transformed_coordinates(srcX + w, srcY + h,
-					 pI830->transform[0],
-					 &src_x[2], &src_y[2]);
+	if (!i830_get_transformed_coordinates(srcX, srcY,
+					      pI830->transform[0],
+					      &src_x[0], &src_y[0]))
+	    return;
+	if (!i830_get_transformed_coordinates(srcX, srcY + h,
+					      pI830->transform[0],
+					      &src_x[1], &src_y[1]))
+	    return;
+	if (!i830_get_transformed_coordinates(srcX + w, srcY + h,
+					      pI830->transform[0],
+					      &src_x[2], &src_y[2]))
+	    return;
 	per_vertex += 2;    /* src x/y */
     } else {
-	i830_get_transformed_coordinates_3d(srcX, srcY,
-					    pI830->transform[0],
-					    &src_x[0], &src_y[0],
-					    &src_w[0]);
-	i830_get_transformed_coordinates_3d(srcX, srcY + h,
-					    pI830->transform[0],
-					    &src_x[1], &src_y[1],
-					    &src_w[1]);
-	i830_get_transformed_coordinates_3d(srcX + w, srcY + h,
-					    pI830->transform[0],
-					    &src_x[2], &src_y[2],
-					    &src_w[2]);
+	if (!i830_get_transformed_coordinates_3d(srcX, srcY,
+						 pI830->transform[0],
+						 &src_x[0], &src_y[0],
+						 &src_w[0]))
+	    return;
+	if (!i830_get_transformed_coordinates_3d(srcX, srcY + h,
+						 pI830->transform[0],
+						 &src_x[1], &src_y[1],
+						 &src_w[1]))
+	    return;
+	if (!i830_get_transformed_coordinates_3d(srcX + w, srcY + h,
+						 pI830->transform[0],
+						 &src_x[2], &src_y[2],
+						 &src_w[2]))
+	    return;
 	per_vertex += 4;    /* src x/y/z/w */
     }
     if (has_mask) {
 	if (is_affine_mask) {
-	    i830_get_transformed_coordinates(maskX, maskY,
-					     pI830->transform[1],
-					     &mask_x[0], &mask_y[0]);
-	    i830_get_transformed_coordinates(maskX, maskY + h,
-					     pI830->transform[1],
-					     &mask_x[1], &mask_y[1]);
-	    i830_get_transformed_coordinates(maskX + w, maskY + h,
-					     pI830->transform[1],
-					     &mask_x[2], &mask_y[2]);
+	    if (!i830_get_transformed_coordinates(maskX, maskY,
+						  pI830->transform[1],
+						  &mask_x[0], &mask_y[0]))
+		return;
+	    if (!i830_get_transformed_coordinates(maskX, maskY + h,
+						  pI830->transform[1],
+						  &mask_x[1], &mask_y[1]))
+		return;
+	    if (!i830_get_transformed_coordinates(maskX + w, maskY + h,
+						  pI830->transform[1],
+						  &mask_x[2], &mask_y[2]))
+		return;
 	    per_vertex += 2;	/* mask x/y */
 	} else {
-	    i830_get_transformed_coordinates_3d(maskX, maskY,
-						pI830->transform[1],
-						&mask_x[0], &mask_y[0],
-						&mask_w[0]);
-	    i830_get_transformed_coordinates_3d(maskX, maskY + h,
-						pI830->transform[1],
-						&mask_x[1], &mask_y[1],
-						&mask_w[1]);
-	    i830_get_transformed_coordinates_3d(maskX + w, maskY + h,
-						pI830->transform[1],
-						&mask_x[2], &mask_y[2],
-						&mask_w[2]);
+	    if (!i830_get_transformed_coordinates_3d(maskX, maskY,
+						     pI830->transform[1],
+						     &mask_x[0], &mask_y[0],
+						     &mask_w[0]))
+		return;
+	    if (!i830_get_transformed_coordinates_3d(maskX, maskY + h,
+						     pI830->transform[1],
+						     &mask_x[1], &mask_y[1],
+						     &mask_w[1]))
+		return;
+	    if (!i830_get_transformed_coordinates_3d(maskX + w, maskY + h,
+						     pI830->transform[1],
+						     &mask_x[2], &mask_y[2],
+						     &mask_w[2]))
+		return;
 	    per_vertex += 4;	/* mask x/y/z/w */
 	}
     }
@@ -655,8 +677,8 @@ i830_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
     OUT_BATCH(MI_NOOP);
 
     OUT_BATCH(PRIM3D_INLINE | PRIM3D_RECTLIST | (num_floats-1));
-    OUT_BATCH_F(-0.125 + dstX + w);
-    OUT_BATCH_F(-0.125 + dstY + h);
+    OUT_BATCH_F(pI830->coord_adjust + dstX + w);
+    OUT_BATCH_F(pI830->coord_adjust + dstY + h);
     OUT_BATCH_F(src_x[2] / pI830->scale_units[0][0]);
     OUT_BATCH_F(src_y[2] / pI830->scale_units[0][1]);
     if (!is_affine_src) {
@@ -672,8 +694,8 @@ i830_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
 	}
     }
 
-    OUT_BATCH_F(-0.125 + dstX);
-    OUT_BATCH_F(-0.125 + dstY + h);
+    OUT_BATCH_F(pI830->coord_adjust + dstX);
+    OUT_BATCH_F(pI830->coord_adjust + dstY + h);
     OUT_BATCH_F(src_x[1] / pI830->scale_units[0][0]);
     OUT_BATCH_F(src_y[1] / pI830->scale_units[0][1]);
     if (!is_affine_src) {
@@ -689,8 +711,8 @@ i830_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
 	}
     }
 
-    OUT_BATCH_F(-0.125 + dstX);
-    OUT_BATCH_F(-0.125 + dstY);
+    OUT_BATCH_F(pI830->coord_adjust + dstX);
+    OUT_BATCH_F(pI830->coord_adjust + dstY);
     OUT_BATCH_F(src_x[0] / pI830->scale_units[0][0]);
     OUT_BATCH_F(src_y[0] / pI830->scale_units[0][1]);
     if (!is_affine_src) {
diff --git a/src/i915_render.c b/src/i915_render.c
index 9c6da09..2b9ed04 100644
--- a/src/i915_render.c
+++ b/src/i915_render.c
@@ -321,6 +321,7 @@ i915_prepare_composite(int op, PicturePtr pSrcPicture,
     int out_reg = FS_OC;
     FS_LOCALS(20);
     Bool is_affine_src, is_affine_mask;
+    Bool is_nearest = FALSE;
 
     IntelEmitInvarientState(pScrn);
     *pI830->last_3d = LAST_3D_RENDER;
@@ -332,9 +333,13 @@ i915_prepare_composite(int op, PicturePtr pSrcPicture,
 
     if (!i915_texture_setup(pSrcPicture, pSrc, 0))
 	I830FALLBACK("fail to setup src texture\n");
+    if (pSrcPicture->filter == PictFilterNearest)
+	is_nearest = TRUE;
     if (pMask != NULL) {
 	if (!i915_texture_setup(pMaskPicture, pMask, 1))
 	    I830FALLBACK("fail to setup mask texture\n");
+	if (pMaskPicture->filter == PictFilterNearest)
+	    is_nearest = TRUE;
     } else {
 	pI830->transform[1] = NULL;
 	pI830->scale_units[1][0] = -1;
@@ -343,6 +348,11 @@ i915_prepare_composite(int op, PicturePtr pSrcPicture,
     is_affine_src = i830_transform_is_affine (pI830->transform[0]);
     is_affine_mask = i830_transform_is_affine (pI830->transform[1]);
 
+    if (is_nearest)
+	pI830->coord_adjust = -0.125;
+    else
+	pI830->coord_adjust = 0;
+
     if (pMask == NULL) {
 	BEGIN_BATCH(10);
 	OUT_BATCH(_3DSTATE_MAP_STATE | 3);
diff --git a/src/i965_render.c b/src/i965_render.c
index ada3919..93583b0 100644
--- a/src/i965_render.c
+++ b/src/i965_render.c
@@ -1093,29 +1093,35 @@ i965_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
     float src_x[3], src_y[3], mask_x[3], mask_y[3];
     int i;
 
-    i830_get_transformed_coordinates(srcX, srcY,
-				     pI830->transform[0],
-				     &src_x[0], &src_y[0]);
-    i830_get_transformed_coordinates(srcX, srcY + h,
-				     pI830->transform[0],
-				     &src_x[1], &src_y[1]);
-    i830_get_transformed_coordinates(srcX + w, srcY + h,
-				     pI830->transform[0],
-				     &src_x[2], &src_y[2]);
+    if (!i830_get_transformed_coordinates(srcX, srcY,
+					  pI830->transform[0],
+					  &src_x[0], &src_y[0]))
+	return;
+    if (!i830_get_transformed_coordinates(srcX, srcY + h,
+					  pI830->transform[0],
+					  &src_x[1], &src_y[1]))
+	return;
+    if (!i830_get_transformed_coordinates(srcX + w, srcY + h,
+					  pI830->transform[0],
+					  &src_x[2], &src_y[2]))
+	return;
 
     if (pI830->scale_units[1][0] == -1 || pI830->scale_units[1][1] == -1) {
 	has_mask = FALSE;
     } else {
 	has_mask = TRUE;
-	i830_get_transformed_coordinates(maskX, maskY,
-					 pI830->transform[1],
-					 &mask_x[0], &mask_y[0]);
-	i830_get_transformed_coordinates(maskX, maskY + h,
-					 pI830->transform[1],
-					 &mask_x[1], &mask_y[1]);
-	i830_get_transformed_coordinates(maskX + w, maskY + h,
-					 pI830->transform[1],
-					 &mask_x[2], &mask_y[2]);
+	if (!i830_get_transformed_coordinates(maskX, maskY,
+					      pI830->transform[1],
+					      &mask_x[0], &mask_y[0]))
+	    return;
+	if (!i830_get_transformed_coordinates(maskX, maskY + h,
+					      pI830->transform[1],
+					      &mask_x[1], &mask_y[1]))
+	    return;
+	if (!i830_get_transformed_coordinates(maskX + w, maskY + h,
+					      pI830->transform[1],
+					      &mask_x[2], &mask_y[2]))
+	    return;
     }
 
     /* Wait for any existing composite rectangles to land before we overwrite
commit bf725b92cf93d74a6f414f81f319dddbc2c78525
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Fri Mar 21 11:50:27 2008 +0800

    xvmc: fix distcheck
    
    Add i915 headers in Makefile.am

diff --git a/src/xvmc/Makefile.am b/src/xvmc/Makefile.am
index cde41f9..7ae429a 100644
--- a/src/xvmc/Makefile.am
+++ b/src/xvmc/Makefile.am
@@ -11,6 +11,8 @@ libI810XvMC_la_LIBADD = @DRI_LIBS@
 
 libIntelXvMC_la_SOURCES = intel_xvmc.c \
 			 intel_xvmc.h \
+			 i915_structs.h \
+			 i915_program.h \
 			 i915_xvmc.c \
                          i915_xvmc.h \
                          intel_batchbuffer.c \
commit e8da1a5418ab240ae7b1ef95bfea6bee22f1e0c1
Author: Joerg Sonnenberger <joerg at britannica.bec.de>
Date:   Fri Mar 21 11:41:49 2008 +0800

    Fix DRI config for NetBSD
    
    Reported by Joerg. This does a little more clearn up.

diff --git a/configure.ac b/configure.ac
index 0ea974f..5b677f0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -87,7 +87,8 @@ sdkdir=$(pkg-config --variable=sdkdir xorg-server)
 # Checks for header files.
 AC_HEADER_STDC
 
-if test "$DRI" != no; then
+AC_MSG_CHECKING([whether to include DRI support])
+if test x$DRI = xauto; then
         AC_CHECK_FILE([${sdkdir}/dri.h],
                       [have_dri_h="yes"], [have_dri_h="no"])
         AC_CHECK_FILE([${sdkdir}/sarea.h],
@@ -96,10 +97,7 @@ if test "$DRI" != no; then
                       [have_dristruct_h="yes"], [have_dristruct_h="no"])
 	AC_CHECK_FILE([${sdkdir}/damage.h],
                       [have_damage_h="yes"], [have_damage_h="no"])
-fi
 
-AC_MSG_CHECKING([whether to include DRI support])
-if test x$DRI = xauto; then
         if test "$have_dri_h" = yes -a \
                 "$have_sarea_h" = yes -a \
                 "$have_dristruct_h" = yes; then
commit 224c36cc14a7552bc5df793ad582f0ea5349eb1e
Merge: 4b9b7b0... 03ccffd...
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Thu Mar 20 10:31:57 2008 +0800

    Merge branch 'xvmc'

commit 4b9b7b007d729f94b01b0031d8ae478134b501da
Author: Keith Packard <keithp at keithp.com>
Date:   Tue Mar 18 14:08:19 2008 -0700

    Handle projective transforms on 9xx for Composite.
    
    Projective transforms require un-normalized texture coordinates and the use
    of the texldp instruction. The coordinates are passed as x/y/z/w (the z is
    unused, but there isn't a vertext format for just x/y/w).

diff --git a/src/i830_exa.c b/src/i830_exa.c
index 0206ab9..f9df277 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -363,7 +363,7 @@ i830_get_transformed_coordinates(int x, int y, PictTransformPtr transform,
     }
 }
 
-**
+/**
  * Returns the un-normalized floating-point coordinates transformed by the given transform.
  *
  * transform may be null.
diff --git a/src/i830_render.c b/src/i830_render.c
index 78ae40a..87543ef 100644
--- a/src/i830_render.c
+++ b/src/i830_render.c
@@ -395,6 +395,7 @@ i830_prepare_composite(int op, PicturePtr pSrcPicture,
     ScrnInfoPtr pScrn = xf86Screens[pSrcPicture->pDrawable->pScreen->myNum];
     I830Ptr pI830 = I830PTR(pScrn);
     uint32_t dst_format, dst_offset, dst_pitch;
+    Bool is_affine_src, is_affine_mask;
 
     IntelEmitInvarientState(pScrn);
     *pI830->last_3d = LAST_3D_RENDER;
@@ -415,6 +416,12 @@ i830_prepare_composite(int op, PicturePtr pSrcPicture,
 	pI830->scale_units[1][1] = -1;
     }
 
+    is_affine_src = i830_transform_is_affine (pI830->transform[0]);
+    is_affine_mask = i830_transform_is_affine (pI830->transform[1]);
+
+    if (!is_affine_src || !is_affine_mask)
+	I830FALLBACK("non-affine transform unsupported on 8xx hardware\n");
+
     {
 	uint32_t cblend, ablend, blendctl, vf2;
 
@@ -556,7 +563,6 @@ i830_prepare_composite(int op, PicturePtr pSrcPicture,
     return TRUE;
 }
 
-
 /**
  * Do a single rectangle composite operation.
  *
@@ -569,79 +575,138 @@ i830_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
     ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
     I830Ptr pI830 = I830PTR(pScrn);
     Bool has_mask;
-    float src_x[3], src_y[3], mask_x[3], mask_y[3];
-
-    i830_get_transformed_coordinates(srcX, srcY,
-				     pI830->transform[0],
-				     &src_x[0], &src_y[0]);
-    i830_get_transformed_coordinates(srcX, srcY + h,
-				     pI830->transform[0],
-				     &src_x[1], &src_y[1]);
-    i830_get_transformed_coordinates(srcX + w, srcY + h,
-				     pI830->transform[0],
-				     &src_x[2], &src_y[2]);
+    Bool is_affine_src, is_affine_mask;
+    int per_vertex, num_floats;
+    float src_x[3], src_y[3], src_w[3], mask_x[3], mask_y[3], mask_w[3];
+
+    is_affine_src = i830_transform_is_affine (pI830->transform[0]);
+    is_affine_mask = i830_transform_is_affine (pI830->transform[1]);
 
     if (pI830->scale_units[1][0] == -1 || pI830->scale_units[1][1] == -1) {
 	has_mask = FALSE;
     } else {
 	has_mask = TRUE;
-	i830_get_transformed_coordinates(maskX, maskY,
-					 pI830->transform[1],
-					 &mask_x[0], &mask_y[0]);
-	i830_get_transformed_coordinates(maskX, maskY + h,
-					 pI830->transform[1],
-					 &mask_x[1], &mask_y[1]);
-	i830_get_transformed_coordinates(maskX + w, maskY + h,
-					 pI830->transform[1],
-					 &mask_x[2], &mask_y[2]);
     }
 
+    per_vertex = 2; /* dest x/y */
+    if (is_affine_src)
     {
-	int vertex_count;
-
-	if (has_mask)
-		vertex_count = 3*6;
-	else
-		vertex_count = 3*4;
-
-	BEGIN_BATCH(6+vertex_count);
-
-	OUT_BATCH(MI_NOOP);
-	OUT_BATCH(MI_NOOP);
-	OUT_BATCH(MI_NOOP);
-	OUT_BATCH(MI_NOOP);
-	OUT_BATCH(MI_NOOP);
-
-	OUT_BATCH(PRIM3D_INLINE | PRIM3D_RECTLIST | (vertex_count-1));
+	i830_get_transformed_coordinates(srcX, srcY,
+					 pI830->transform[0],
+					 &src_x[0], &src_y[0]);
+	i830_get_transformed_coordinates(srcX, srcY + h,
+					 pI830->transform[0],
+					 &src_x[1], &src_y[1]);
+	i830_get_transformed_coordinates(srcX + w, srcY + h,
+					 pI830->transform[0],
+					 &src_x[2], &src_y[2]);
+	per_vertex += 2;    /* src x/y */
+    } else {
+	i830_get_transformed_coordinates_3d(srcX, srcY,
+					    pI830->transform[0],
+					    &src_x[0], &src_y[0],
+					    &src_w[0]);
+	i830_get_transformed_coordinates_3d(srcX, srcY + h,
+					    pI830->transform[0],
+					    &src_x[1], &src_y[1],
+					    &src_w[1]);
+	i830_get_transformed_coordinates_3d(srcX + w, srcY + h,
+					    pI830->transform[0],
+					    &src_x[2], &src_y[2],
+					    &src_w[2]);
+	per_vertex += 4;    /* src x/y/z/w */
+    }
+    if (has_mask) {
+	if (is_affine_mask) {
+	    i830_get_transformed_coordinates(maskX, maskY,
+					     pI830->transform[1],
+					     &mask_x[0], &mask_y[0]);
+	    i830_get_transformed_coordinates(maskX, maskY + h,
+					     pI830->transform[1],
+					     &mask_x[1], &mask_y[1]);
+	    i830_get_transformed_coordinates(maskX + w, maskY + h,
+					     pI830->transform[1],
+					     &mask_x[2], &mask_y[2]);
+	    per_vertex += 2;	/* mask x/y */
+	} else {
+	    i830_get_transformed_coordinates_3d(maskX, maskY,
+						pI830->transform[1],
+						&mask_x[0], &mask_y[0],
+						&mask_w[0]);
+	    i830_get_transformed_coordinates_3d(maskX, maskY + h,
+						pI830->transform[1],
+						&mask_x[1], &mask_y[1],
+						&mask_w[1]);
+	    i830_get_transformed_coordinates_3d(maskX + w, maskY + h,
+						pI830->transform[1],
+						&mask_x[2], &mask_y[2],
+						&mask_w[2]);
+	    per_vertex += 4;	/* mask x/y/z/w */
+	}
+    }
 
-	OUT_BATCH_F(-0.125 + dstX + w);
-	OUT_BATCH_F(-0.125 + dstY + h);
-	OUT_BATCH_F(src_x[2] / pI830->scale_units[0][0]);
-	OUT_BATCH_F(src_y[2] / pI830->scale_units[0][1]);
-	if (has_mask) {
-	    OUT_BATCH_F(mask_x[2] / pI830->scale_units[1][0]);
-	    OUT_BATCH_F(mask_y[2] / pI830->scale_units[1][1]);
+    num_floats = 3 * per_vertex;
+    BEGIN_BATCH(6 + num_floats);
+
+    OUT_BATCH(MI_NOOP);
+    OUT_BATCH(MI_NOOP);
+    OUT_BATCH(MI_NOOP);
+    OUT_BATCH(MI_NOOP);
+    OUT_BATCH(MI_NOOP);
+
+    OUT_BATCH(PRIM3D_INLINE | PRIM3D_RECTLIST | (num_floats-1));
+    OUT_BATCH_F(-0.125 + dstX + w);
+    OUT_BATCH_F(-0.125 + dstY + h);
+    OUT_BATCH_F(src_x[2] / pI830->scale_units[0][0]);
+    OUT_BATCH_F(src_y[2] / pI830->scale_units[0][1]);
+    if (!is_affine_src) {
+	OUT_BATCH_F(0.0);
+	OUT_BATCH_F(src_w[2]);
+    }
+    if (has_mask) {
+	OUT_BATCH_F(mask_x[2] / pI830->scale_units[1][0]);
+	OUT_BATCH_F(mask_y[2] / pI830->scale_units[1][1]);
+	if (!is_affine_mask) {
+	    OUT_BATCH_F(0.0);
+	    OUT_BATCH_F(mask_w[2]);
 	}
+    }
 
-	OUT_BATCH_F(-0.125 + dstX);
-	OUT_BATCH_F(-0.125 + dstY + h);
-	OUT_BATCH_F(src_x[1] / pI830->scale_units[0][0]);
-	OUT_BATCH_F(src_y[1] / pI830->scale_units[0][1]);
-	if (has_mask) {
-	    OUT_BATCH_F(mask_x[1] / pI830->scale_units[1][0]);
-	    OUT_BATCH_F(mask_y[1] / pI830->scale_units[1][1]);
+    OUT_BATCH_F(-0.125 + dstX);
+    OUT_BATCH_F(-0.125 + dstY + h);
+    OUT_BATCH_F(src_x[1] / pI830->scale_units[0][0]);
+    OUT_BATCH_F(src_y[1] / pI830->scale_units[0][1]);
+    if (!is_affine_src) {
+	OUT_BATCH_F(0.0);
+	OUT_BATCH_F(src_w[1]);
+    }
+    if (has_mask) {
+	OUT_BATCH_F(mask_x[1] / pI830->scale_units[1][0]);
+	OUT_BATCH_F(mask_y[1] / pI830->scale_units[1][1]);
+	if (!is_affine_mask) {
+	    OUT_BATCH_F(0.0);
+	    OUT_BATCH_F(mask_w[1]);
 	}
+    }
 
-	OUT_BATCH_F(-0.125 + dstX);
-	OUT_BATCH_F(-0.125 + dstY);
-	OUT_BATCH_F(src_x[0] / pI830->scale_units[0][0]);
-	OUT_BATCH_F(src_y[0] / pI830->scale_units[0][1]);
-	if (has_mask) {
-	    OUT_BATCH_F(mask_x[0] / pI830->scale_units[1][0]);
-	    OUT_BATCH_F(mask_y[0] / pI830->scale_units[1][1]);
+    OUT_BATCH_F(-0.125 + dstX);
+    OUT_BATCH_F(-0.125 + dstY);
+    OUT_BATCH_F(src_x[0] / pI830->scale_units[0][0]);
+    OUT_BATCH_F(src_y[0] / pI830->scale_units[0][1]);
+    if (!is_affine_src) {
+	OUT_BATCH_F(0.0);
+	OUT_BATCH_F(src_w[0]);
+    }
+    if (has_mask) {
+	OUT_BATCH_F(mask_x[0] / pI830->scale_units[1][0]);
+	OUT_BATCH_F(mask_y[0] / pI830->scale_units[1][1]);
+	if (!is_affine_mask) {
+	    OUT_BATCH_F(0.0);
+	    OUT_BATCH_F(mask_w[0]);
 	}
-	ADVANCE_BATCH();
     }
+
+    ADVANCE_BATCH();
 }
 
 /**
diff --git a/src/i915_3d.h b/src/i915_3d.h
index c2efe9a..1a0bd45 100644
--- a/src/i915_3d.h
+++ b/src/i915_3d.h
@@ -236,6 +236,11 @@ do {									\
      FS_OUT(_i915_fs_texld(T0_TEXLD, dest_reg, sampler_reg, address_reg)); \
 } while (0)
 
+#define i915_fs_texldp(dest_reg, sampler_reg, address_reg)		\
+do {									\
+     FS_OUT(_i915_fs_texld(T0_TEXLDP, dest_reg, sampler_reg, address_reg)); \
+} while (0)
+
 static inline struct i915_fs_op
 _i915_fs_texld(int load_op, int dest_reg, int sampler_reg, int address_reg)
 {
diff --git a/src/i915_render.c b/src/i915_render.c
index 8ac1b78..9c6da09 100644
--- a/src/i915_render.c
+++ b/src/i915_render.c
@@ -320,6 +320,7 @@ i915_prepare_composite(int op, PicturePtr pSrcPicture,
     uint32_t blendctl;
     int out_reg = FS_OC;
     FS_LOCALS(20);
+    Bool is_affine_src, is_affine_mask;
 
     IntelEmitInvarientState(pScrn);
     *pI830->last_3d = LAST_3D_RENDER;
@@ -339,6 +340,8 @@ i915_prepare_composite(int op, PicturePtr pSrcPicture,
 	pI830->scale_units[1][0] = -1;
 	pI830->scale_units[1][1] = -1;
     }
+    is_affine_src = i830_transform_is_affine (pI830->transform[0]);
+    is_affine_mask = i830_transform_is_affine (pI830->transform[1]);
 
     if (pMask == NULL) {
 	BEGIN_BATCH(10);
@@ -389,9 +392,9 @@ i915_prepare_composite(int op, PicturePtr pSrcPicture,
 
 	OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) |
 		  I1_LOAD_S(4) | I1_LOAD_S(5) | I1_LOAD_S(6) | 3);
-	ss2 = S2_TEXCOORD_FMT(0, TEXCOORDFMT_2D);
+	ss2 = S2_TEXCOORD_FMT(0, is_affine_src ? TEXCOORDFMT_2D : TEXCOORDFMT_4D);
 	if (pMask)
-		ss2 |= S2_TEXCOORD_FMT(1, TEXCOORDFMT_2D);
+		ss2 |= S2_TEXCOORD_FMT(1, is_affine_mask ? TEXCOORDFMT_2D : TEXCOORDFMT_4D);
 	else
 		ss2 |= S2_TEXCOORD_FMT(1, TEXCOORDFMT_NOT_PRESENT);
 	ss2 |= S2_TEXCOORD_FMT(2, TEXCOORDFMT_NOT_PRESENT);
@@ -435,7 +438,12 @@ i915_prepare_composite(int op, PicturePtr pSrcPicture,
 	i915_fs_dcl(FS_T1);
 
     /* Load the pSrcPicture texel */
-    i915_fs_texld(FS_R0, FS_S0, FS_T0);
+    if (is_affine_src) {
+	i915_fs_texld(FS_R0, FS_S0, FS_T0);
+    } else {
+	i915_fs_texldp(FS_R0, FS_S0, FS_T0);
+    }
+
     /* If the texture lacks an alpha channel, force the alpha to 1. */
     if (PICT_FORMAT_A(pSrcPicture->format) == 0)
 	i915_fs_mov_masked(FS_R0, MASK_W, i915_fs_operand_one());
@@ -445,7 +453,11 @@ i915_prepare_composite(int op, PicturePtr pSrcPicture,
 	i915_fs_mov(out_reg, i915_fs_operand_reg(FS_R0));
     } else {
 	/* Load the pMaskPicture texel */
-	i915_fs_texld(FS_R1, FS_S1, FS_T1);
+	if (is_affine_mask) {
+	    i915_fs_texld(FS_R1, FS_S1, FS_T1);
+	} else {
+	    i915_fs_texldp(FS_R1, FS_S1, FS_T1);
+	}
 	/* If the texture lacks an alpha channel, force the alpha to 1. */
 	if (PICT_FORMAT_A(pMaskPicture->format) == 0)
 	    i915_fs_mov_masked(FS_R1, MASK_W, i915_fs_operand_one());
commit f699389818f1f11f3edddcdddcd0a43be21ba4c0
Author: Keith Packard <keithp at keithp.com>
Date:   Tue Mar 18 14:06:47 2008 -0700

    Add i830_transform_is_affine and i830_get_transformed_coordinates_3d.
    
    These are needed to deal with projective transforms in the composite
    operation.

diff --git a/src/i830.h b/src/i830.h
index ee0f03a..512938c 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -790,6 +790,9 @@ Bool i830_check_composite(int op, PicturePtr pSrc, PicturePtr pMask,
 Bool i830_prepare_composite(int op, PicturePtr pSrc, PicturePtr pMask,
 			    PicturePtr pDst, PixmapPtr pSrcPixmap,
 			    PixmapPtr pMaskPixmap, PixmapPtr pDstPixmap);
+Bool
+i830_transform_is_affine (PictTransformPtr t);
+
 void i830_composite(PixmapPtr pDst, int srcX, int srcY,
 		    int maskX, int maskY, int dstX, int dstY, int w, int h);
 void i830_done_composite(PixmapPtr pDst);
@@ -812,6 +815,10 @@ void
 i830_get_transformed_coordinates(int x, int y, PictTransformPtr transform,
 				 float *x_out, float *y_out);
 
+void
+i830_get_transformed_coordinates_3d(int x, int y, PictTransformPtr transform,
+				    float *x_out, float *y_out, float *z_out);
+
 void i830_enter_render(ScrnInfoPtr);
 
 static inline int i830_fb_compression_supported(I830Ptr pI830)
diff --git a/src/i830_exa.c b/src/i830_exa.c
index bf9fc66..0206ab9 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -363,6 +363,45 @@ i830_get_transformed_coordinates(int x, int y, PictTransformPtr transform,
     }
 }
 
+**
+ * Returns the un-normalized floating-point coordinates transformed by the given transform.
+ *
+ * transform may be null.
+ */
+void
+i830_get_transformed_coordinates_3d(int x, int y, PictTransformPtr transform,
+				    float *x_out, float *y_out, float *w_out)
+{
+    if (transform == NULL) {
+	*x_out = x;
+	*y_out = y;
+	*w_out = 1;
+    } else {
+	PictVector v;
+
+        v.vector[0] = IntToxFixed(x);
+        v.vector[1] = IntToxFixed(y);
+        v.vector[2] = xFixed1;
+        PictureTransformPoint3d(transform, &v);
+	*x_out = xFixedToFloat(v.vector[0]);
+	*y_out = xFixedToFloat(v.vector[1]);
+	*w_out = xFixedToFloat(v.vector[2]);
+    }
+}
+
+/**
+ * Returns whether the provided transform is affine.
+ *
+ * transform may be null.
+ */
+Bool
+i830_transform_is_affine (PictTransformPtr t)
+{
+    if (t == NULL)
+	return TRUE;
+    return t->matrix[2][0] == 0 && t->matrix[2][1] == 0;
+}
+
 /*
  * TODO:
  *   - Dual head?
commit a55974b435224fe5726fa44298d051c71e4056a5
Author: Keith Packard <keithp at keithp.com>
Date:   Tue Mar 18 13:47:20 2008 -0700

    Add defines for 9xx S3 word in 3D_STATE_LOAD_STATE_IMMEDIATE
    
    These aren't used at this point, but what the heck.

diff --git a/src/i915_reg.h b/src/i915_reg.h
index 682a157..4340de9 100644
--- a/src/i915_reg.h
+++ b/src/i915_reg.h
@@ -360,6 +360,16 @@
 #define S2_TEXCOORD_FMT(unit, type)    ((type)<<(unit*4))
 #define S2_TEXCOORD_NONE               (~0)
 
+#define TEXCOORD_WRAP_SHORTEST_TCX	8
+#define TEXCOORD_WRAP_SHORTEST_TCY	4
+#define TEXCOORD_WRAP_SHORTEST_TCZ	2
+#define TEXCOORD_PERSPECTIVE_DISABLE	1
+
+#define S3_WRAP_SHORTEST_TCX(unit)	(TEXCOORD_WRAP_SHORTEST_TCX << ((unit) * 4))
+#define S3_WRAP_SHORTEST_TCY(unit)	(TEXCOORD_WRAP_SHORTEST_TCY << ((unit) * 4))
+#define S3_WRAP_SHORTEST_TCZ(unit)	(TEXCOORD_WRAP_SHORTEST_TCZ << ((unit) * 4))
+#define S3_PERSPECTIVE_DISABLE(unit)	(TEXCOORD_PERSPECTIVE_DISABLE << ((unit) * 4))
+
 /* S3 not interesting */
 
 #define S4_POINT_WIDTH_SHIFT           23
commit 4f5500abe209b92b39ae1f2d7a1118362ac95034
Author: Keith Packard <keithp at keithp.com>
Date:   Tue Mar 18 13:45:46 2008 -0700

    8xx/9xx can handle textures to 2kx2k. 965 can do 8kx8k

diff --git a/src/i830_render.c b/src/i830_render.c
index 949c700..78ae40a 100644
--- a/src/i830_render.c
+++ b/src/i830_render.c
@@ -231,7 +231,7 @@ static Bool i830_check_composite_texture(PicturePtr pPict, int unit)
     int h = pPict->pDrawable->height;
     int i;
 
-    if ((w > 0x7ff) || (h > 0x7ff))
+    if ((w > 2048) || (h > 2048))
         I830FALLBACK("Picture w/h too large (%dx%d)\n", w, h);
 
     for (i = 0; i < sizeof(i830_tex_formats) / sizeof(i830_tex_formats[0]);
diff --git a/src/i915_render.c b/src/i915_render.c
index b15beef..8ac1b78 100644
--- a/src/i915_render.c
+++ b/src/i915_render.c
@@ -188,7 +188,7 @@ static Bool i915_check_composite_texture(PicturePtr pPict, int unit)
     int h = pPict->pDrawable->height;
     int i;
 
-    if ((w > 0x7ff) || (h > 0x7ff))
+    if ((w > 2048) || (h > 2048))
         I830FALLBACK("Picture w/h too large (%dx%d)\n", w, h);
 
     for (i = 0; i < sizeof(i915_tex_formats) / sizeof(i915_tex_formats[0]);
diff --git a/src/i965_render.c b/src/i965_render.c
index 7f798e6..ada3919 100644
--- a/src/i965_render.c
+++ b/src/i965_render.c
@@ -182,7 +182,7 @@ static Bool i965_check_composite_texture(PicturePtr pPict, int unit)
     int h = pPict->pDrawable->height;
     int i;
 
-    if ((w > 0x7ff) || (h > 0x7ff))
+    if ((w > 8192) || (h > 8192))
         I830FALLBACK("Picture w/h too large (%dx%d)\n", w, h);
 
     for (i = 0; i < sizeof(i965_tex_formats) / sizeof(i965_tex_formats[0]);
commit b1b173d03b3acd300c3b0f0ceffeddf1a8137839
Author: Julien Cristau <jcristau at debian.org>
Date:   Tue Mar 18 12:02:25 2008 +0100

    Add i8[13]0_ring.h to _SOURCES to fix distcheck
    
    Thanks to Bruno <bonbons67 at internet.lu>.

diff --git a/src/Makefile.am b/src/Makefile.am
index 1c0133f..8fc21d3 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -77,6 +77,7 @@ intel_drv_la_SOURCES = \
          i810_io.c \
          i810_memory.c \
          i810_reg.h \
+         i810_ring.h \
          i810_video.c \
          i810_wmark.c \
 	 i830_3d.c \
@@ -102,6 +103,7 @@ intel_drv_la_SOURCES = \
          i830_video.c \
          i830_video.h \
 	 i830_reg.h \
+         i830_ring.h \
 	 i830_sdvo.c \
 	 i830_sdvo.h \
 	 i830_sdvo_regs.h \
commit 03ccffd5b9b8108166ea143884a1a0a6417f3236
Merge: ac76363... d72e18c...
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Tue Mar 18 16:54:15 2008 +0800

    Merge branch 'master' into xvmc

commit ac763634069fe070b3afc073ce437959612d39fe
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Tue Mar 18 16:52:29 2008 +0800

    Disable XvMC if DRI is not enabled.
    
    Default XvMC to disabled.

diff --git a/man/intel.man b/man/intel.man
index b9b64b9..c26264f 100644
--- a/man/intel.man
+++ b/man/intel.man
@@ -186,7 +186,7 @@ the output of 'lspci -v' and 'lspci -vn'.
 .BI "Option \*qXvMC\*q \*q" boolean \*q
 Enable XvMC driver. Current support MPEG2 MC on 915/945 and G33 series.
 User should provide absolute path to libIntelXvMC.so in XvMCConfig file.
-Default: Enabled.
+Default: Disabled.
 
 .SH OUTPUT CONFIGURATION
 On 830M and better chipsets, the driver supports runtime configuration of
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 3938e74..a40d8ce 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -1632,8 +1632,11 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
 #endif
 
 #ifdef INTEL_XVMC
-   pI830->XvMCEnabled = xf86ReturnOptValBool(pI830->Options, OPTION_XVMC, TRUE);
-   xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Intel XvMC decoder %sabled\n",
+   pI830->XvMCEnabled = FALSE;
+   from =  (!pI830->directRenderingDisabled &&
+	    xf86GetOptValBool(pI830->Options, OPTION_XVMC,
+			      &pI830->XvMCEnabled)) ? X_CONFIG : X_DEFAULT;
+   xf86DrvMsg(pScrn->scrnIndex, from, "Intel XvMC decoder %sabled\n",
 	   pI830->XvMCEnabled ? "en" : "dis");
 #endif
 
commit d72e18c10995079121eded758a60ed99b5b8ce1a
Author: Paulo Cesar Pereira de Andrade <pcpa at mandriva.com.br>
Date:   Mon Mar 17 16:59:12 2008 +0800

    Compile warning fixes.
    
    Move some declarations and don't declare an extra variable with the
    same name, to fix warnings about mixed declarations and code.

diff --git a/src/i830_dri.c b/src/i830_dri.c
index 5d2539e..3493eb9 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -747,12 +747,12 @@ static void
 I830InitTextureHeap(ScrnInfoPtr pScrn)
 {
    I830Ptr pI830 = I830PTR(pScrn);
+   drmI830MemInitHeap drmHeap;
 
    if (pI830->textures == NULL)
        return;
 
    /* Start up the simple memory manager for agp space */
-   drmI830MemInitHeap drmHeap;
    drmHeap.region = I830_MEM_REGION_AGP;
    drmHeap.start  = 0;
    drmHeap.size   = pI830->textures->size;
diff --git a/src/i830_driver.c b/src/i830_driver.c
index e1ab536..d5b260c 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -1479,7 +1479,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
        pI830->useEXA = FALSE;
 #endif
 #if defined(I830_USE_XAA) && defined(I830_USE_EXA)
-       int from = X_DEFAULT;
+       from = X_DEFAULT;
        if ((s = (char *)xf86GetOptValString(pI830->Options,
 					    OPTION_ACCELMETHOD))) {
 	   if (!xf86NameCmp(s, "EXA")) {
diff --git a/src/i915_render.c b/src/i915_render.c
index fe02e63..b15beef 100644
--- a/src/i915_render.c
+++ b/src/i915_render.c
@@ -319,6 +319,7 @@ i915_prepare_composite(int op, PicturePtr pSrcPicture,
     uint32_t dst_format, dst_offset, dst_pitch;
     uint32_t blendctl;
     int out_reg = FS_OC;
+    FS_LOCALS(20);
 
     IntelEmitInvarientState(pScrn);
     *pI830->last_3d = LAST_3D_RENDER;
@@ -327,7 +328,6 @@ i915_prepare_composite(int op, PicturePtr pSrcPicture,
 	return FALSE;
     dst_offset = intel_get_pixmap_offset(pDst);
     dst_pitch = intel_get_pixmap_pitch(pDst);
-    FS_LOCALS(20);
 
     if (!i915_texture_setup(pSrcPicture, pSrc, 0))
 	I830FALLBACK("fail to setup src texture\n");
commit 81df48d8d151907c2e9dd33a729860c39aa78175
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Mon Mar 17 10:05:57 2008 +0800

    bug 15060: Dell Latitude X300 needs pipe A quirk

diff --git a/src/i830_quirks.c b/src/i830_quirks.c
index 7d0d142..f29083b 100644
--- a/src/i830_quirks.c
+++ b/src/i830_quirks.c
@@ -253,6 +253,8 @@ static i830_quirk i830_quirk_list[] = {
     { PCI_CHIP_I830_M, 0x1014, 0x0505, quirk_pipea_force },
     /* Dell Latitude D500 needs pipe A force quirk */
     { PCI_CHIP_I855_GM, 0x1028, 0x0152, quirk_pipea_force },
+    /* Dell Latitude X300 needs pipe A force quirk */
+    { PCI_CHIP_I855_GM, 0x1028, 0x014f, quirk_pipea_force },
     /* Dell Inspiron 510m needs pipe A force quirk */
     { PCI_CHIP_I855_GM, 0x1028, 0x0164, quirk_pipea_force },
     /* Toshiba Protege R-205, S-209 needs pipe A force quirk */
commit f425181695b1b3864373e1919cf651229f19fa69
Merge: f4cfc98... 1c0e495...
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Thu Mar 13 23:58:56 2008 +0800

    Merge branch 'master' into xvmc

commit f4cfc98ab038af4d5d52af12e4d60ded62cf4a6e
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Thu Mar 13 23:56:48 2008 +0800

    nuke unneed error_base and event_base

diff --git a/src/xvmc/i915_xvmc.c b/src/xvmc/i915_xvmc.c
index 983b6fd..b30facd 100644
--- a/src/xvmc/i915_xvmc.c
+++ b/src/xvmc/i915_xvmc.c
@@ -56,10 +56,6 @@ typedef union {
     uint  u[2];
 } su_t;
 
-static char I915KernelDriverName[] = "i915";
-static int error_base;
-static int event_base;
-
 static int findOverlap(unsigned int width, unsigned int height,
                        short *dstX, short *dstY,
                        short *srcX, short *srcY,
@@ -1728,7 +1724,7 @@ static Status i915_xvmc_mc_create_surface(Display *display,
     I915XvMCCreateSurfaceRec *tmpComm = NULL;
 
     if (!(pI915XvMC = context->privData))
-        return (error_base + XvMCBadContext);
+        return XvMCBadContext;
 
     XVMC_DBG("%s\n", __FUNCTION__);
 
@@ -1796,10 +1792,10 @@ static int i915_xvmc_mc_destroy_surface(Display *display, XvMCSurface *surface)
         return BadValue;
 
     if (!(pI915Surface = surface->privData))
-        return (error_base + XvMCBadSurface);
+        return XvMCBadSurface;
 
     if (!(pI915XvMC = pI915Surface->privContext))
-        return (error_base + XvMCBadSurface);
+        return XvMCBadSurface;
 
     if (pI915Surface->last_flip)
         XvMCSyncSurface(display,surface);
@@ -1866,10 +1862,10 @@ static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context,
     }
 
     if (!(pI915XvMC = context->privData))
-        return (error_base + XvMCBadContext);
+        return XvMCBadContext;
 
     if (!(privTarget = target_surface->privData))
-        return (error_base + XvMCBadSurface);
+        return XvMCBadSurface;
 
     /* Test For YV12 Surface */
     if (context->surface_type_id != FOURCC_YV12) {
@@ -1890,7 +1886,7 @@ static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context,
     } else {
         if (!(privPast = past_surface->privData)) {
             XVMC_ERR("Invalid Past Surface!");
-            return (error_base + XvMCBadSurface);
+            return XvMCBadSurface;
         }
         picture_coding_type = MPEG_P_PICTURE;
     }
@@ -1906,7 +1902,7 @@ static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context,
 
         if (!(privFuture = future_surface->privData)) {
             XVMC_ERR("Invalid Future Surface!");
-            return (error_base + XvMCBadSurface);
+            return XvMCBadSurface;
         }
 
         picture_coding_type = MPEG_B_PICTURE;
@@ -2037,10 +2033,10 @@ static int i915_xvmc_mc_put_surface(Display *display,XvMCSurface *surface,
     i915XvMCSubpicture *pI915SubPic;
 
     if (!(pI915Surface = surface->privData))
-        return (error_base + XvMCBadSurface);
+        return XvMCBadSurface;
 
     if (!(pI915XvMC = pI915Surface->privContext))
-        return (error_base + XvMCBadSurface);
+        return XvMCBadSurface;
 
     PPTHREAD_MUTEX_LOCK();
 
@@ -2069,10 +2065,10 @@ static int i915_xvmc_mc_get_surface_status(Display *display,
     *stat = 0;
 
     if (!(pI915Surface = surface->privData))
-        return (error_base + XvMCBadSurface);
+        return XvMCBadSurface;
 
     if (!(pI915XvMC = pI915Surface->privContext))
-        return (error_base + XvMCBadSurface);
+        return XvMCBadSurface;
 
     PPTHREAD_MUTEX_LOCK();
     if (pI915Surface->last_flip) {
@@ -2119,11 +2115,11 @@ Status XvMCHideSurface(Display *display, XvMCSurface *surface)
         return BadValue;
 
     if (!(pI915Surface = surface->privData))
-        return (error_base + XvMCBadSurface);
+        return XvMCBadSurface;
 
     /* Get the associated context pointer */
     if (!(pI915XvMC = pI915Surface->privContext))
-        return (error_base + XvMCBadSurface);
+        return XvMCBadSurface;
 
     XvMCSyncSurface(display, surface);
 
@@ -2159,7 +2155,7 @@ Status i915_xvmc_create_subpict(Display *display, XvMCContext *context,
     pI915XvMC = (i915XvMCContext *)context->privData;
 
     if (!pI915XvMC)
-        return (error_base + XvMCBadContext);
+        return XvMCBadContext;
 
     subpicture->privData =
         (i915XvMCSubpicture *)malloc(sizeof(i915XvMCSubpicture));
@@ -2264,10 +2260,10 @@ Status i915_xvmc_clear_subpict(Display *display, XvMCSubpicture *subpicture,
         return BadValue;
 
     if (!(pI915Subpicture = subpicture->privData))
-        return (error_base + XvMCBadSubpicture);
+        return XvMCBadSubpicture;
 
     if (!(pI915XvMC = pI915Subpicture->privContext))
-        return (error_base + XvMCBadSubpicture);
+        return XvMCBadSubpicture;
 
     if ((x < 0) || (x + width) > subpicture->width)
         return BadValue;
@@ -2293,10 +2289,10 @@ Status i915_xvmc_composite_subpict(Display *display, XvMCSubpicture *subpicture,
         return BadValue;
 
     if (!(pI915Subpicture = subpicture->privData))
-        return (error_base + XvMCBadSubpicture);
+        return XvMCBadSubpicture;
 
     if (!(pI915XvMC = pI915Subpicture->privContext))
-        return (error_base + XvMCBadSubpicture);
+        return XvMCBadSubpicture;
 
     if ((srcx < 0) || (srcx + width) > subpicture->width)
         return BadValue;
@@ -2327,10 +2323,10 @@ Status i915_xvmc_destroy_subpict(Display *display, XvMCSubpicture *subpicture)
         return BadValue;
 
     if (!(pI915Subpicture = subpicture->privData))
-        return (error_base + XvMCBadSubpicture);
+        return XvMCBadSubpicture;
 
     if (!(pI915XvMC = pI915Subpicture->privContext))
-        return (error_base + XvMCBadSubpicture);
+        return XvMCBadSubpicture;
 
     if (pI915Subpicture->last_render)
         XvMCSyncSubpicture(display, subpicture);
@@ -2363,7 +2359,7 @@ Status i915_xvmc_set_subpict_palette(Display *display,
         return BadValue;
 
     if (!(pI915Subpicture = subpicture->privData))
-        return (error_base + XvMCBadSubpicture);
+        return XvMCBadSubpicture;
 
     j = 0;
     for (i = 0; i < 16; i++) {
@@ -2390,15 +2386,15 @@ Status i915_xvmc_blend_subpict(Display *display, XvMCSurface *target_surface,
         return BadValue;
 
     if (!(privTargetSurface = target_surface->privData))
-        return (error_base + XvMCBadSurface);
+        return XvMCBadSurface;
 
     if (subpicture) {
         if (!(pI915Subpicture = subpicture->privData))
-            return (error_base + XvMCBadSubpicture);
+            return XvMCBadSubpicture;
 
         if ((FOURCC_AI44 != subpicture->xvimage_id) &&
             (FOURCC_IA44 != subpicture->xvimage_id))
-            return (error_base + XvMCBadSubpicture);
+            return XvMCBadSubpicture;
 
         privTargetSurface->privSubPic = pI915Subpicture;
     } else {
@@ -2426,13 +2422,13 @@ Status i915_xvmc_blend_subpict2(Display *display,
         return BadValue;
 
     if (!(privSourceSurface = source_surface->privData))
-        return (error_base + XvMCBadSurface);
+        return XvMCBadSurface;
 
     if (!(privTargetSurface = target_surface->privData))
-        return (error_base + XvMCBadSurface);
+        return XvMCBadSurface;
 
     if (!(pI915XvMC = privTargetSurface->privContext))
-        return (error_base + XvMCBadSurface);
+        return XvMCBadSurface;
 
     if (((surfx + surfw) > privTargetSurface->width) ||
         ((surfy + surfh) > privTargetSurface->height))
@@ -2453,11 +2449,11 @@ Status i915_xvmc_blend_subpict2(Display *display,
             return BadValue;
 
         if (!(pI915Subpicture = subpicture->privData))
-            return (error_base + XvMCBadSubpicture);
+            return XvMCBadSubpicture;
 
         if ((FOURCC_AI44 != subpicture->xvimage_id) &&
             (FOURCC_IA44 != subpicture->xvimage_id))
-            return (error_base + XvMCBadSubpicture);
+            return XvMCBadSubpicture;
 
         privTargetSurface->privSubPic = pI915Subpicture;
     } else {
@@ -2490,7 +2486,7 @@ Status i915_xvmc_flush_subpict(Display *display, XvMCSubpicture *subpicture)
         return BadValue;
 
     if (!(pI915Subpicture = subpicture->privData))
-        return (error_base + XvMCBadSubpicture);
+        return XvMCBadSubpicture;
 
     return Success;
 }
@@ -2507,10 +2503,10 @@ Status i915_xvmc_get_subpict_status(Display *display, XvMCSubpicture *subpicture
     *stat = 0;
 
     if (!(pI915Subpicture = subpicture->privData))
-        return (error_base + XvMCBadSubpicture);
+        return XvMCBadSubpicture;
 
     if (!(pI915XvMC = pI915Subpicture->privContext))
-        return (error_base + XvMCBadSubpicture);
+        return XvMCBadSubpicture;
 
     PPTHREAD_MUTEX_LOCK();
     /* FIXME: */
commit f269c69b4e7be076dc9838d0e0801c940ccdba08
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Thu Mar 13 23:41:22 2008 +0800

    remove unused init/fini hooks for xvmc driver

diff --git a/src/xvmc/i915_xvmc.c b/src/xvmc/i915_xvmc.c
index d27384d..983b6fd 100644
--- a/src/xvmc/i915_xvmc.c
+++ b/src/xvmc/i915_xvmc.c
@@ -60,15 +60,6 @@ static char I915KernelDriverName[] = "i915";
 static int error_base;
 static int event_base;
 
-static int i915_xvmc_mc_init()
-{
-    return 0;
-}
-
-static void i915_xvmc_mc_fini()
-{}
-
-
 static int findOverlap(unsigned int width, unsigned int height,
                        short *dstX, short *dstY,
                        short *srcX, short *srcY,
@@ -2538,8 +2529,6 @@ struct _intel_xvmc_driver i915_xvmc_mc_driver = {
     .type		= XVMC_I915_MPEG2_MC,
     .num_ctx		= 0,
     .ctx_list		= NULL,
-    .init		= i915_xvmc_mc_init,
-    .fini		= i915_xvmc_mc_fini,
     .create_context	= i915_xvmc_mc_create_context,
     .destroy_context	= i915_xvmc_mc_destroy_context,
     .create_surface	= i915_xvmc_mc_create_surface,
diff --git a/src/xvmc/intel_xvmc.h b/src/xvmc/intel_xvmc.h
index 8ebb14b..3375ffc 100644
--- a/src/xvmc/intel_xvmc.h
+++ b/src/xvmc/intel_xvmc.h
@@ -165,10 +165,6 @@ typedef struct _intel_xvmc_driver {
 
     void *private;
 
-    /* XXX: remove? */
-    int (*init)(void);
-    void (*fini)(void);
-
     /* driver specific xvmc callbacks */
     Status (*create_context)(Display* display, XvMCContext *context,
 	    int priv_count, CARD32 *priv_data);
@@ -191,7 +187,6 @@ typedef struct _intel_xvmc_driver {
 	    XvMCMacroBlockArray *macroblock_array,
 	    XvMCBlockArray *blocks);
 
-    /* XXX this should be same for all drivers */
     Status (*put_surface)(Display *display, XvMCSurface *surface,
 	    Drawable draw, short srcx, short srcy,
 	    unsigned short srcw, unsigned short srch,
commit cd73c6a5a78eac726b14ef242b8452c559c4c003
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Wed Mar 12 20:37:41 2008 +0800

    Pass default visual in dri context create

diff --git a/src/xvmc/intel_xvmc.c b/src/xvmc/intel_xvmc.c
index 91a050f..489a2c2 100644
--- a/src/xvmc/intel_xvmc.c
+++ b/src/xvmc/intel_xvmc.c
@@ -337,7 +337,7 @@ Status XvMCCreateContext(Display *display, XvPortID port,
     pthread_mutex_init(&xvmc_driver->ctxmutex, NULL);
 
     /* context_id is alloc in _xvmc_create_context */
-    if (!uniDRICreateContext(display, screen, NULL,
+    if (!uniDRICreateContext(display, screen, DefaultVisual(display, screen),
 			     context->context_id,
                              &intel_ctx->hw_context)) {
         XVMC_ERR("Could not create DRI context for xvmc ctx %d.",
diff --git a/src/xvmc/xf86dri.c b/src/xvmc/xf86dri.c
index 97022e4..798c1a8 100644
--- a/src/xvmc/xf86dri.c
+++ b/src/xvmc/xf86dri.c
@@ -374,8 +374,7 @@ uniDRICreateContext(dpy, screen, visual, context, hHWContext)
     drm_context_t *hHWContext;
 {
     return uniDRICreateContextWithConfig(dpy, screen,
-	   visual ? visual->visualid : 0,
-	context, hHWContext);
+	   visual->visualid, context, hHWContext);
 }
 
 Bool
commit 21580add63307ca68790bf911243b8675f5f7c64
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Wed Mar 12 20:37:17 2008 +0800

    disable memory alloc debug

diff --git a/src/i915_hwmc.c b/src/i915_hwmc.c
index a8daf3e..cdcef5a 100644
--- a/src/i915_hwmc.c
+++ b/src/i915_hwmc.c
@@ -342,8 +342,9 @@ static Bool i915_allocate_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *c
         return FALSE;
     }
 
+    if (0)
+	i830_describe_allocations(pScrn, 1, "");
 
-    i830_describe_allocations(pScrn, 1, "");
     return TRUE;
 }
 
@@ -577,7 +578,10 @@ static int i915_xvmc_create_surface (ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf,
         *num_priv = 0;
         return BadAlloc;
     }
-    i830_describe_allocations(pScrn, 1, "");
+
+    if (0)
+	i830_describe_allocations(pScrn, 1, "");
+
     if (drmAddMap(pI830->drmSubFD,
                   (drm_handle_t)(sfpriv->surface->offset + pI830->LinearAddr),
                   sfpriv->surface->size, DRM_AGP, 0,
commit 31654f52b084ebb32f69854dfb1c342c9da07928
Merge: a03aca1... 02c0ffb...
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Tue Mar 11 14:37:41 2008 +0800

    Merge branch 'master' into xvmc
    
    Conflicts:
    
    	man/intel.man
    	src/i830_driver.c

diff --cc man/intel.man
index c048f01,e5736e5..b9b64b9
--- a/man/intel.man
+++ b/man/intel.man
@@@ -176,10 -176,12 +176,17 @@@ Default: "EXA"
  Enable printing of additional debugging information about modesetting to
  the server log.
  .TP
+ .BI "Option \*qForceEnablePipeA\*q \*q" boolean \*q
+ Force the driver to leave pipe A enabled.  May be necessary in configurations
+ where the BIOS accesses pipe registers during display hotswitch or lid close,
+ causing a crash.  If you find that your platform needs this option, please file
+ a bug against xf86-video-intel at http://bugs.freedesktop.org which includes
+ the output of 'lspci -v' and 'lspci -vn'.
++.TP
 +.BI "Option \*qXvMC\*q \*q" boolean \*q
 +Enable XvMC driver. Current support MPEG2 MC on 915/945 and G33 series.
 +User should provide absolute path to libIntelXvMC.so in XvMCConfig file.
 +Default: Enabled.
  
  .SH OUTPUT CONFIGURATION
  On 830M and better chipsets, the driver supports runtime configuration of
diff --cc src/i830_driver.c
index 1b0d07a,854e377..41362d9
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@@ -301,9 -298,7 +303,10 @@@ typedef enum 
     OPTION_INTELTEXPOOL,
  #endif
     OPTION_TRIPLEBUFFER,
 -   OPTION_FORCEENABLEPIPEA
++   OPTION_FORCEENABLEPIPEA,
 +#ifdef INTEL_XVMC
 +   OPTION_XVMC,
 +#endif
  } I830Opts;
  
  static OptionInfoRec I830Options[] = {
@@@ -326,9 -321,7 +329,10 @@@
     {OPTION_INTELTEXPOOL,"Legacy3D",     OPTV_BOOLEAN,	{0},	FALSE},
  #endif
     {OPTION_TRIPLEBUFFER, "TripleBuffer", OPTV_BOOLEAN,	{0},	FALSE},
+    {OPTION_FORCEENABLEPIPEA, "ForceEnablePipeA", OPTV_BOOLEAN,	{0},	FALSE},
 +#ifdef INTEL_XVMC
 +   {OPTION_XVMC,	"XvMC",		OPTV_BOOLEAN,	{0},	TRUE},
 +#endif
     {-1,			NULL,		OPTV_NONE,	{0},	FALSE}
  };
  /* *INDENT-ON* */
commit a03aca101d4d51ed2279a99d1137ce3b7ef364e2
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Wed Jan 2 14:11:31 2008 +0800

    xvmc: setup driver info for XvMCGetDRInfo request
    
    User don't need to have XvMCConfig file then, if ld.so can
    find libIntelXvMC.so in ld path.

diff --git a/src/i830_hwmc.c b/src/i830_hwmc.c
index acb89e6..7586ff7 100644
--- a/src/i830_hwmc.c
+++ b/src/i830_hwmc.c
@@ -96,6 +96,7 @@ Bool intel_xvmc_screen_init(ScreenPtr pScreen)
 {
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
     I830Ptr pI830 = I830PTR(pScrn);
+    DRIInfoPtr pDRIInfo = pI830->pDRIInfo;
 
     if (!xvmc_driver)
 	return FALSE;
@@ -111,6 +112,10 @@ Bool intel_xvmc_screen_init(ScreenPtr pScreen)
 		"[XvMC] Failed to initialize XvMC.\n");
 	return FALSE;
     }
+
+    xf86XvMCRegisterDRInfo(pScreen, INTEL_XVMC_LIBNAME,
+		    pDRIInfo->busIdString,
+		    INTEL_XVMC_MAJOR, INTEL_XVMC_MINOR, INTEL_XVMC_PATCHLEVEL);
     return TRUE;
 }
 
diff --git a/src/i830_hwmc.h b/src/i830_hwmc.h
index 3464d01..6920e01 100644
--- a/src/i830_hwmc.h
+++ b/src/i830_hwmc.h
@@ -27,6 +27,11 @@
 #ifndef I830_HWMC_H
 #define I830_HWMC_H
 
+#define INTEL_XVMC_LIBNAME	"IntelXvMC"
+#define INTEL_XVMC_MAJOR	0
+#define INTEL_XVMC_MINOR	1
+#define INTEL_XVMC_PATCHLEVEL	0
+
 #define FOURCC_XVMC     (('C' << 24) + ('M' << 16) + ('V' << 8) + 'X')
 
 /*
commit 0fd769b5882058e5ebf17ee1c1e35b4a3d46e6b0
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Wed Jan 2 13:57:23 2008 +0800

    xvmc: add context id info in debug/trace

diff --git a/src/xvmc/i915_xvmc.c b/src/xvmc/i915_xvmc.c
index 10b60ce..d27384d 100644
--- a/src/xvmc/i915_xvmc.c
+++ b/src/xvmc/i915_xvmc.c
@@ -1629,7 +1629,7 @@ static Status i915_xvmc_mc_create_context(Display *display, XvMCContext *context
     int isCapable;
     int screen = DefaultScreen(display);
 
-    XVMC_DBG("i915_xvmc_mc_create_context\n");
+    XVMC_DBG("%s\n", __FUNCTION__);
 
     if (priv_count != (sizeof(I915XvMCCreateContextRec) >> 2)) {
         XVMC_ERR("_xvmc_create_context() returned incorrect data size!");
diff --git a/src/xvmc/intel_xvmc.c b/src/xvmc/intel_xvmc.c
index b4a34fc..91a050f 100644
--- a/src/xvmc/intel_xvmc.c
+++ b/src/xvmc/intel_xvmc.c
@@ -250,6 +250,7 @@ Status XvMCCreateContext(Display *display, XvPortID port,
         XVMC_ERR("Unable to create XvMC Context.");
         return ret;
     }
+    XVMC_DBG("new context %d created\n", context->context_id);
 
     comm = (struct _intel_xvmc_common *)priv_data;
 
@@ -339,7 +340,8 @@ Status XvMCCreateContext(Display *display, XvPortID port,
     if (!uniDRICreateContext(display, screen, NULL,
 			     context->context_id,
                              &intel_ctx->hw_context)) {
-        XVMC_ERR("Could not create DRI context.");
+        XVMC_ERR("Could not create DRI context for xvmc ctx %d.",
+			context->context_id);
 	XFree(priv_data);
         context->privData = NULL;
         drmUnmap(xvmc_driver->sarea_address, xvmc_driver->sarea_size);
diff --git a/src/xvmc/xf86dri.c b/src/xvmc/xf86dri.c
index 2b60348..97022e4 100644
--- a/src/xvmc/xf86dri.c
+++ b/src/xvmc/xf86dri.c
@@ -84,9 +84,9 @@ XEXT_GENERATE_FIND_DISPLAY(find_display, xf86dri_info,
  *****************************************************************************/
 #if 0
 #include <stdio.h>
-#define TRACE(msg)  fprintf(stderr,"uniDRI%s\n", msg);
+#define TRACE(msg, arg...)  fprintf(stderr,"uniDRI" msg "\n", ##arg);
 #else
-#define TRACE(msg)
+#define TRACE(msg, arg...)
 #endif
     Bool uniDRIQueryExtension(dpy, event_basep, error_basep)
     Display *dpy;
@@ -135,7 +135,8 @@ uniDRIQueryVersion(dpy, majorVersion, minorVersion, patchVersion)
     *patchVersion = rep.patchVersion;
     UnlockDisplay(dpy);
     SyncHandle();
-    TRACE("QueryVersion... return True");
+    TRACE("QueryVersion... %d.%d.%d return True", rep.majorVersion,
+		    rep.minorVersion, rep.patchVersion);
     return True;
 }
 
@@ -166,7 +167,8 @@ uniDRIQueryDirectRenderingCapable(dpy, screen, isCapable)
     *isCapable = rep.isCapable;
     UnlockDisplay(dpy);
     SyncHandle();
-    TRACE("QueryDirectRenderingCapable... return True");
+    TRACE("QueryDirectRenderingCapable... %s return True",
+		    rep.isCapable ? "true" : "false");
     return True;
 }
 
@@ -216,7 +218,8 @@ uniDRIOpenConnection(dpy, screen, hSAREA, busIdString)
     }
     UnlockDisplay(dpy);
     SyncHandle();
-    TRACE("OpenConnection... return True");
+    TRACE("OpenConnection... busid %s return True",
+		   *busIdString ? *busIdString : "null");
     return True;
 }
 
@@ -339,7 +342,7 @@ uniDRICreateContextWithConfig(dpy, screen, configID, context, hHWContext)
     xXF86DRICreateContextReply rep;
     xXF86DRICreateContextReq *req;
 
-    TRACE("CreateContext...");
+    TRACE("CreateContext... id %d", context);
     uniDRICheckExtension(dpy, info, False);
 
     LockDisplay(dpy);
@@ -382,7 +385,7 @@ uniDRIDestroyContext(Display * ndpy, int screen, XID context)
     XExtDisplayInfo *info = find_display(dpy);
     xXF86DRIDestroyContextReq *req;
 
-    TRACE("DestroyContext...");
+    TRACE("DestroyContext... id %d", context);
     uniDRICheckExtension(dpy, info, False);
 
     LockDisplay(dpy);
commit a2bb2afd24c95e056b801c85dc12daeac54b37f0
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Fri Dec 28 15:52:12 2007 +0800

    xvmc: move drmOpen earlier
    
    remove wrong comments

diff --git a/src/xvmc/intel_xvmc.c b/src/xvmc/intel_xvmc.c
index 0ce3cc2..b4a34fc 100644
--- a/src/xvmc/intel_xvmc.c
+++ b/src/xvmc/intel_xvmc.c
@@ -200,6 +200,7 @@ Status XvMCCreateContext(Display *display, XvPortID port,
     int isCapable;
     int screen = DefaultScreen(display);
     intel_xvmc_context_ptr intel_ctx;
+    int fd;
 
     /* Verify Obvious things first */
     if (!display || !context)
@@ -210,14 +211,12 @@ Status XvMCCreateContext(Display *display, XvPortID port,
         return BadValue;
     }
 
-    /* Limit use to root for now */
-    /* FIXME: remove it ??? */
-/*
-    if (geteuid()) {
-        printf("Use of XvMC on i915 is currently limited to root\n");
-        return BadAccess;
+    /* Open DRI Device */
+    if((fd = drmOpen("i915", NULL)) < 0) {
+        XVMC_ERR("DRM Device could not be opened.");
+        return BadValue;
     }
-*/
+
     /*
        Width, Height, and flags are checked against surface_type_id
        and port for validity inside the X server, no need to check
@@ -275,6 +274,8 @@ Status XvMCCreateContext(Display *display, XvPortID port,
 	return BadValue;
     }
 
+    xvmc_driver->fd = fd;
+
     XVMC_INFO("decoder type is %s", intel_xvmc_decoder_string(comm->type));
 
     xvmc_driver->sarea_size = comm->sarea_size;
@@ -309,15 +310,6 @@ Status XvMCCreateContext(Display *display, XvPortID port,
     xvmc_driver->busID[20] = '\0';
     XFree(curBusID);
 
-    /* Open DRI Device */
-    if((xvmc_driver->fd = drmOpen("i915", NULL)) < 0) {
-        XVMC_ERR("DRM Device could not be opened.");
-	//(xvmc_driver->fini)();
-	xvmc_driver = NULL;
-	XFree(priv_data);
-        return BadValue;
-    }
-
     /* Get magic number */
     drmGetMagic(xvmc_driver->fd, &magic);
     // context->flags = (unsigned long)magic;
commit 666e01bd426a553f23eeb5040ecbc28b4abb87da
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Wed Dec 26 09:51:09 2007 +0800

    xvmc: add info in intel.man

diff --git a/man/intel.man b/man/intel.man
index d46e3f9..c048f01 100644
--- a/man/intel.man
+++ b/man/intel.man
@@ -175,6 +175,11 @@ Default: "EXA".
 .BI "Option \*qModeDebug\*q \*q" boolean \*q
 Enable printing of additional debugging information about modesetting to
 the server log.
+.TP
+.BI "Option \*qXvMC\*q \*q" boolean \*q
+Enable XvMC driver. Current support MPEG2 MC on 915/945 and G33 series.
+User should provide absolute path to libIntelXvMC.so in XvMCConfig file.
+Default: Enabled.
 
 .SH OUTPUT CONFIGURATION
 On 830M and better chipsets, the driver supports runtime configuration of
commit e75d0c20e3b02f649b62ac9da7f41bb43d0f3d80
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Wed Dec 26 09:37:34 2007 +0800

    xvmc: make XvMC default on

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 529ea0c..1b0d07a 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -327,7 +327,7 @@ static OptionInfoRec I830Options[] = {
 #endif
    {OPTION_TRIPLEBUFFER, "TripleBuffer", OPTV_BOOLEAN,	{0},	FALSE},
 #ifdef INTEL_XVMC
-   {OPTION_XVMC,	"XvMC",		OPTV_BOOLEAN,	{0},	FALSE},
+   {OPTION_XVMC,	"XvMC",		OPTV_BOOLEAN,	{0},	TRUE},
 #endif
    {-1,			NULL,		OPTV_NONE,	{0},	FALSE}
 };
@@ -1595,7 +1595,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
 #endif
 
 #ifdef INTEL_XVMC
-   pI830->XvMCEnabled = xf86ReturnOptValBool(pI830->Options, OPTION_XVMC, FALSE);
+   pI830->XvMCEnabled = xf86ReturnOptValBool(pI830->Options, OPTION_XVMC, TRUE);
    xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Intel XvMC decoder %sabled\n",
 	   pI830->XvMCEnabled ? "en" : "dis");
 #endif
commit ed9ff6f30fff33fe2d60715f1b503047f8e1ef01
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Tue Dec 25 08:32:47 2007 +0800

    xvmc: consolidate put surface interfaces
    
    Make surface list track like context list, and move
    generic PutSurface code out of i915. So MC driver just
    needs to fill specific the command params, and we can
    get one single type of intel xvmc command to issue,
    ddx driver's put_image_size got removed.
    
    Fix last commit with missing XvMCContext assignment.
    
    Fix priv_data free with apropriate X11 XFree.

diff --git a/src/i830_hwmc.c b/src/i830_hwmc.c
index 189c2e5..acb89e6 100644
--- a/src/i830_hwmc.c
+++ b/src/i830_hwmc.c
@@ -114,12 +114,6 @@ Bool intel_xvmc_screen_init(ScreenPtr pScreen)
     return TRUE;
 }
 
-int intel_xvmc_put_image_size(ScrnInfoPtr pScrn)
-{
-    return (*xvmc_driver->put_image_size)(pScrn);
-}
-
-
 Bool intel_xvmc_init_batch(ScrnInfoPtr pScrn)
 {
     I830Ptr pI830 = I830PTR(pScrn);
diff --git a/src/i830_hwmc.h b/src/i830_hwmc.h
index 073fe44..3464d01 100644
--- a/src/i830_hwmc.h
+++ b/src/i830_hwmc.h
@@ -57,6 +57,17 @@ struct _intel_xvmc_common {
     struct hwmc_buffer batchbuffer;
 };
 
+/* Intel private XvMC command to DDX driver */
+struct intel_xvmc_command {
+    unsigned int command;
+    unsigned int ctxNo;
+    unsigned int srfNo;
+    unsigned int subPicNo;
+    unsigned int flags;
+    unsigned int real_id;
+    unsigned int pad[6];
+};
+
 #ifdef _INTEL_XVMC_SERVER_
 #include <xf86xvmc.h>
 
@@ -70,7 +81,6 @@ struct intel_xvmc_driver {
     /* more items for xvmv surface manage? */
     Bool (*init)(ScrnInfoPtr, XF86VideoAdaptorPtr);
     void (*fini)(ScrnInfoPtr);
-    int (*put_image_size)(ScrnInfoPtr);
     void* devPrivate;
 };
 
diff --git a/src/i830_video.c b/src/i830_video.c
index 1f82ce4..967fda9 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2552,7 +2552,7 @@ I830QueryImageAttributes(ScrnInfoPtr pScrn,
 #ifdef INTEL_XVMC
     case FOURCC_XVMC:
         *h = (*h + 1) & ~1;
-        size = intel_xvmc_put_image_size(pScrn);
+        size = sizeof(struct intel_xvmc_command);
         if (pitches)
             pitches[0] = size;
         break;
diff --git a/src/i915_hwmc.c b/src/i915_hwmc.c
index e41d148..a8daf3e 100644
--- a/src/i915_hwmc.c
+++ b/src/i915_hwmc.c
@@ -766,24 +766,24 @@ static int i915_xvmc_put_image(ScrnInfoPtr pScrn,
 {
     I830Ptr pI830 = I830PTR(pScrn);
     I915XvMCPtr pXvMC = (I915XvMCPtr)xvmc_driver->devPrivate;
-    I915XvMCCommandBuffer *i915XvMCData = (I915XvMCCommandBuffer *)buf;
+    struct intel_xvmc_command *xvmc_cmd = (struct intel_xvmc_command *)buf;
     int ret;
 
     if (pI830->XvMCEnabled) {
         if (FOURCC_XVMC == id) {
-            switch (i915XvMCData->command) {
+            switch (xvmc_cmd->command) {
             case INTEL_XVMC_COMMAND_DISPLAY:
-		if ((i915XvMCData->srfNo >= I915_XVMC_MAX_SURFACES) ||
-			!pXvMC->surfaces[i915XvMCData->srfNo] ||
-			!pXvMC->sfprivs[i915XvMCData->srfNo]) {
+		if ((xvmc_cmd->srfNo >= I915_XVMC_MAX_SURFACES) ||
+			!pXvMC->surfaces[xvmc_cmd->srfNo] ||
+			!pXvMC->sfprivs[xvmc_cmd->srfNo]) {
 		    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 			    "[XvMC] i915 put image: Invalid parameters!\n");
 		    return 1;
 		}
 
 		buf = pI830->FbBase +
-		    pXvMC->sfprivs[i915XvMCData->srfNo]->surface->offset;
-		id = i915XvMCData->real_id;
+		    pXvMC->sfprivs[xvmc_cmd->srfNo]->surface->offset;
+		id = xvmc_cmd->real_id;
 		pI830->IsXvMCSurface = 1;
 		break;
             default:
@@ -799,12 +799,6 @@ static int i915_xvmc_put_image(ScrnInfoPtr pScrn,
     return ret;
 }
 
-static int i915_xvmc_put_image_size(ScrnInfoPtr pScrn)
-{
-    return sizeof(I915XvMCCommandBuffer);
-}
-
-
 static Bool i915_xvmc_init(ScrnInfoPtr pScrn, XF86VideoAdaptorPtr XvAdapt)
 {
     I915XvMCPtr pXvMC;
@@ -872,5 +866,4 @@ struct intel_xvmc_driver i915_xvmc_driver = {
     .flag		= XVMC_I915_MPEG2_MC,
     .init		= i915_xvmc_init,
     .fini		= i915_xvmc_fini,
-    .put_image_size	= i915_xvmc_put_image_size,
 };
diff --git a/src/i915_hwmc.h b/src/i915_hwmc.h
index 9da3747..0141fb2 100644
--- a/src/i915_hwmc.h
+++ b/src/i915_hwmc.h
@@ -40,16 +40,6 @@
 
 typedef struct
 {
-    unsigned int command;
-    unsigned int ctxNo;
-    unsigned int srfNo;
-    unsigned int subPicNo;
-    int real_id;
-} I915XvMCCommandBuffer;
-
-
-typedef struct
-{
     struct _intel_xvmc_common comm;
     unsigned int ctxno; /* XvMC private context reference number */
     struct hwmc_buffer sis;
diff --git a/src/xvmc/i915_xvmc.c b/src/xvmc/i915_xvmc.c
index 44ccdc1..10b60ce 100644
--- a/src/xvmc/i915_xvmc.c
+++ b/src/xvmc/i915_xvmc.c
@@ -1636,7 +1636,7 @@ static Status i915_xvmc_mc_create_context(Display *display, XvMCContext *context
         XVMC_INFO("\tExpected %d, got %d",
                (int)(sizeof(I915XvMCCreateContextRec) >> 2),priv_count);
         _xvmc_destroy_context(display, context);
-        free(priv_data);
+        XFree(priv_data);
         context->privData = NULL;
         return BadValue;
     }
@@ -1684,7 +1684,7 @@ static Status i915_xvmc_mc_create_context(Display *display, XvMCContext *context
     pI915XvMC->sarea_priv_offset = tmpComm->sarea_priv_offset;
 
     /* Must free the private data we were passed from X */
-    free(priv_data);
+    XFree(priv_data);
     priv_data = NULL;
 
     pSAREA = (drm_sarea_t *)xvmc_driver->sarea_address;
@@ -1741,6 +1741,14 @@ static Status i915_xvmc_mc_create_surface(Display *display,
 
     XVMC_DBG("%s\n", __FUNCTION__);
 
+    if (priv_count != (sizeof(I915XvMCCreateSurfaceRec) >> 2)) {
+        XVMC_ERR("_xvmc_create_surface() returned incorrect data size!");
+        XVMC_INFO("\tExpected %d, got %d",
+               (int)(sizeof(I915XvMCCreateSurfaceRec) >> 2), priv_count);
+        _xvmc_destroy_surface(display, surface);
+        XFree(priv_data);
+        return BadAlloc;
+    }
 
     PPTHREAD_MUTEX_LOCK();
     surface->privData = (i915XvMCSurface *)malloc(sizeof(i915XvMCSurface));
@@ -1761,25 +1769,14 @@ static Status i915_xvmc_mc_create_surface(Display *display,
     pI915Surface->privSubPic = NULL;
     pI915Surface->srf.map = NULL;
 
-    if (priv_count != (sizeof(I915XvMCCreateSurfaceRec) >> 2)) {
-        XVMC_ERR("_xvmc_create_surface() returned incorrect data size!");
-        XVMC_INFO("\tExpected %d, got %d",
-               (int)(sizeof(I915XvMCCreateSurfaceRec) >> 2), priv_count);
-        _xvmc_destroy_surface(display, surface);
-        free(priv_data);
-        free(pI915Surface);
-        surface->privData = NULL;
-        PPTHREAD_MUTEX_UNLOCK();
-        return BadAlloc;
-    }
-
     tmpComm = (I915XvMCCreateSurfaceRec *)priv_data;
 
     pI915Surface->srfNo = tmpComm->srfno;
     pI915Surface->srf.handle = tmpComm->srf.handle;
     pI915Surface->srf.offset = tmpComm->srf.offset;
     pI915Surface->srf.size = tmpComm->srf.size;
-    free(priv_data);
+
+    XFree(priv_data);
 
     if (drmMap(xvmc_driver->fd,
                pI915Surface->srf.handle,
@@ -1894,7 +1891,6 @@ static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context,
 	XVMC_ERR("Can't find intel xvmc context\n");
 	return BadValue;
     }
-    XVMC_DBG("intel ctx found\n");
 
     /* P Frame Test */
     if (!past_surface) {
@@ -2043,18 +2039,11 @@ static int i915_xvmc_mc_put_surface(Display *display,XvMCSurface *surface,
                       unsigned short srcw, unsigned short srch,
                       short destx, short desty,
                       unsigned short destw, unsigned short desth,
-                      int flags)
+                      int flags, struct intel_xvmc_command *data)
 {
     i915XvMCContext *pI915XvMC;
     i915XvMCSurface *pI915Surface;
     i915XvMCSubpicture *pI915SubPic;
-    I915XvMCCommandBuffer buf;
-
-    // drawableInfo *drawInfo;
-    Status ret;
-
-    if (!display || !surface)
-        return BadValue;
 
     if (!(pI915Surface = surface->privData))
         return (error_base + XvMCBadSurface);
@@ -2064,37 +2053,14 @@ static int i915_xvmc_mc_put_surface(Display *display,XvMCSurface *surface,
 
     PPTHREAD_MUTEX_LOCK();
 
-    if (!pI915XvMC->haveXv) {
-        pI915XvMC->xvImage =
-            XvCreateImage(display, pI915XvMC->port, FOURCC_XVMC,
-                          (char *)&buf, pI915Surface->width, pI915Surface->height);
-        pI915XvMC->gc = XCreateGC(display, draw, 0, 0);
-        pI915XvMC->haveXv = 1;
-    }
-
-    pI915XvMC->draw = draw;
-    pI915XvMC->xvImage->data = (char *)&buf;
-
-    buf.command = INTEL_XVMC_COMMAND_DISPLAY;
-    buf.ctxNo = pI915XvMC->ctxno;
-    buf.srfNo = pI915Surface->srfNo;
+    data->command = INTEL_XVMC_COMMAND_DISPLAY;
+    data->ctxNo = pI915XvMC->ctxno;
+    data->srfNo = pI915Surface->srfNo;
     pI915SubPic = pI915Surface->privSubPic;
-    buf.subPicNo = (!pI915SubPic ? 0 : pI915SubPic->srfNo);
-    buf.real_id = FOURCC_YV12;
+    data->subPicNo = (!pI915SubPic ? 0 : pI915SubPic->srfNo);
+    data->real_id = FOURCC_YV12;
+    data->flags = flags;
 
-    XLockDisplay(display);
-
-    if ((ret = XvPutImage(display, pI915XvMC->port, draw, pI915XvMC->gc,
-                          pI915XvMC->xvImage, srcx, srcy, srcw, srch,
-                          destx, desty, destw, desth))) {
-        XUnlockDisplay(display);
-        PPTHREAD_MUTEX_UNLOCK();
-
-        return ret;
-    }
-
-    XSync(display, 0);
-    XUnlockDisplay(display);
     PPTHREAD_MUTEX_UNLOCK();
 
     return 0;
@@ -2236,7 +2202,7 @@ Status i915_xvmc_create_subpict(Display *display, XvMCContext *context,
         XLockDisplay(display);
         _xvmc_destroy_subpicture(display, subpicture);
         XUnlockDisplay(display);
-        free(priv_data);
+        XFree(priv_data);
         free(pI915Subpicture);
         subpicture->privData = NULL;
         PPTHREAD_MUTEX_UNLOCK();
@@ -2248,7 +2214,7 @@ Status i915_xvmc_create_subpict(Display *display, XvMCContext *context,
     pI915Subpicture->srf.handle = tmpComm->srf.handle;
     pI915Subpicture->srf.offset = tmpComm->srf.offset;
     pI915Subpicture->srf.size = tmpComm->srf.size;
-    free(priv_data);
+    XFree(priv_data);
 
     if (drmMap(pI915XvMC->fd,
                pI915Subpicture->srf.handle,
diff --git a/src/xvmc/intel_xvmc.c b/src/xvmc/intel_xvmc.c
index fead3a4..0ce3cc2 100644
--- a/src/xvmc/intel_xvmc.c
+++ b/src/xvmc/intel_xvmc.c
@@ -84,7 +84,7 @@ static void intel_xvmc_free_context(XID id)
     intel_xvmc_context_ptr pre = p;
 
     while(p) {
-	if (p->context->context_id == id) {
+	if (p->context && p->context->context_id == id) {
 	    if (p == xvmc_driver->ctx_list)
 		xvmc_driver->ctx_list = p->next;
 	    else
@@ -95,9 +95,10 @@ static void intel_xvmc_free_context(XID id)
 	p = p->next;
     }
 
-    if (p)
+    if (p) {
 	free(p);
-    xvmc_driver->num_ctx--;
+	xvmc_driver->num_ctx--;
+    }
 }
 
 intel_xvmc_context_ptr intel_xvmc_find_context(XID id)
@@ -105,13 +106,69 @@ intel_xvmc_context_ptr intel_xvmc_find_context(XID id)
     intel_xvmc_context_ptr p = xvmc_driver->ctx_list;
 
     while(p) {
-	if (p->context->context_id == id)
+	if (p->context && p->context->context_id == id)
 	    return p;
 	p = p->next;
     }
     return NULL;
 }
 
+static intel_xvmc_surface_ptr intel_xvmc_new_surface(Display *dpy)
+{
+    intel_xvmc_surface_ptr ret;
+
+    ret = (intel_xvmc_surface_ptr)calloc(1, sizeof(intel_xvmc_surface_t));
+    if (!ret)
+	return NULL;
+
+    if (!xvmc_driver->surf_list)
+	ret->next = NULL;
+    else
+	ret->next = xvmc_driver->surf_list;
+    xvmc_driver->surf_list = ret;
+    xvmc_driver->num_surf++;
+
+    ret->image = NULL;
+    ret->gc_init = FALSE;
+
+    return ret;
+
+}
+
+static void intel_xvmc_free_surface(XID id)
+{
+    intel_xvmc_surface_ptr p = xvmc_driver->surf_list;
+    intel_xvmc_surface_ptr pre = p;
+
+    while(p) {
+	if (p->surface && p->surface->surface_id == id) {
+	    if (p == xvmc_driver->surf_list)
+		xvmc_driver->surf_list = p->next;
+	    else
+		pre->next = p->next;
+	    break;
+	}
+	pre = p;
+	p = p->next;
+    }
+
+    if (p) {
+	free(p);
+	xvmc_driver->num_surf--;
+    }
+}
+
+intel_xvmc_surface_ptr intel_xvmc_find_surface(XID id)
+{
+    intel_xvmc_surface_ptr p = xvmc_driver->surf_list;
+
+    while(p) {
+	if (p->surface && p->surface->surface_id == id)
+	    return p;
+	p = p->next;
+    }
+    return NULL;
+}
 /*
 * Function: XvMCCreateContext
 * Description: Create a XvMC context for the given surface parameters.
@@ -207,7 +264,7 @@ Status XvMCCreateContext(Display *display, XvPortID port,
 	    case XVMC_I965_MPEG2_VLD:
 	    default:
 		XVMC_ERR("unimplemented xvmc type %d", comm->type);
-		free(priv_data);
+		XFree(priv_data);
 		priv_data = NULL;
 		return BadValue;
 	}
@@ -231,32 +288,33 @@ Status XvMCCreateContext(Display *display, XvPortID port,
 	XVMC_ERR("Intel XvMC context create fail\n");
 	return BadAlloc;
     }
+    intel_ctx->context = context;
 
     ret = uniDRIQueryDirectRenderingCapable(display, screen,
                                             &isCapable);
     if (!ret || !isCapable) {
 	XVMC_ERR("Direct Rendering is not available on this system!");
-	free(priv_data);
+	XFree(priv_data);
         return BadValue;
     }
 
     if (!uniDRIOpenConnection(display, screen,
                               &xvmc_driver->hsarea, &curBusID)) {
         XVMC_ERR("Could not open DRI connection to X server!");
-	free(priv_data);
+	XFree(priv_data);
         return BadValue;
     }
 
     strncpy(xvmc_driver->busID, curBusID, 20);
     xvmc_driver->busID[20] = '\0';
-    free(curBusID);
+    XFree(curBusID);
 
     /* Open DRI Device */
     if((xvmc_driver->fd = drmOpen("i915", NULL)) < 0) {
         XVMC_ERR("DRM Device could not be opened.");
 	//(xvmc_driver->fini)();
 	xvmc_driver = NULL;
-	free(priv_data);
+	XFree(priv_data);
         return BadValue;
     }
 
@@ -267,7 +325,7 @@ Status XvMCCreateContext(Display *display, XvPortID port,
     if (!uniDRIAuthConnection(display, screen, magic)) {
 	XVMC_ERR("[XvMC]: X server did not allow DRI. Check permissions.");
 	xvmc_driver = NULL;
-	free(priv_data);
+	XFree(priv_data);
         return BadAlloc;
     }
 
@@ -278,7 +336,7 @@ Status XvMCCreateContext(Display *display, XvPortID port,
                xvmc_driver->sarea_size, &xvmc_driver->sarea_address) < 0) {
         XVMC_ERR("Unable to map DRI SAREA.\n");
 	xvmc_driver = NULL;
-	free(priv_data);
+	XFree(priv_data);
         return BadAlloc;
     }
     pSAREA = (drm_sarea_t *)xvmc_driver->sarea_address;
@@ -290,7 +348,7 @@ Status XvMCCreateContext(Display *display, XvPortID port,
 			     context->context_id,
                              &intel_ctx->hw_context)) {
         XVMC_ERR("Could not create DRI context.");
-	free(priv_data);
+	XFree(priv_data);
         context->privData = NULL;
         drmUnmap(xvmc_driver->sarea_address, xvmc_driver->sarea_size);
         return BadAlloc;
@@ -301,7 +359,7 @@ Status XvMCCreateContext(Display *display, XvPortID port,
     ret = (xvmc_driver->create_context)(display, context, priv_count, priv_data);
     if (ret) {
 	XVMC_ERR("driver create context failed\n");
-	free(priv_data);
+	XFree(priv_data);
 	drmUnmap(xvmc_driver->sarea_address, xvmc_driver->sarea_size);
 	return ret;
     }
@@ -367,6 +425,7 @@ Status XvMCCreateSurface(Display *display, XvMCContext *context, XvMCSurface *su
     Status ret;
     int priv_count;
     CARD32 *priv_data;
+    intel_xvmc_surface_ptr intel_surf = NULL;
 
     if (!display || !context)
         return XvMCBadContext;
@@ -374,12 +433,28 @@ Status XvMCCreateSurface(Display *display, XvMCContext *context, XvMCSurface *su
     if (!surface)
 	return XvMCBadSurface;
 
+    intel_surf = intel_xvmc_new_surface(display);
+    if (!intel_surf)
+	return BadAlloc;
+    intel_surf->surface = surface;
+
     if ((ret = _xvmc_create_surface(display, context, surface,
                                     &priv_count, &priv_data))) {
         XVMC_ERR("Unable to create XvMCSurface.");
         return ret;
     }
 
+    intel_surf->image = XvCreateImage(display, context->port,
+	    FOURCC_XVMC, (char *)&intel_surf->data, surface->width,
+	    surface->height);
+    if (!intel_surf->image) {
+	XVMC_ERR("Can't create XvImage for surface\n");
+	_xvmc_destroy_surface(display, surface);
+	intel_xvmc_free_surface(surface->surface_id);
+	return BadAlloc;
+    }
+    intel_surf->image->data = (char *)&intel_surf->data;
+
     ret = (xvmc_driver->create_surface)(display, context, surface, priv_count,
 	    priv_data);
     if (ret) {
@@ -396,9 +471,20 @@ Status XvMCCreateSurface(Display *display, XvMCContext *context, XvMCSurface *su
  */
 Status XvMCDestroySurface(Display *display, XvMCSurface *surface)
 {
+    intel_xvmc_surface_ptr intel_surf;
+
     if (!display || !surface)
         return XvMCBadSurface;
 
+    intel_surf = intel_xvmc_find_surface(surface->surface_id);
+    if (!intel_surf)
+	return XvMCBadSurface;
+
+    XFree(intel_surf->image);
+    if (intel_surf->gc_init)
+	XFreeGC(display, intel_surf->gc);
+    intel_xvmc_free_surface(surface->surface_id);
+
     (xvmc_driver->destroy_surface)(display, surface);
 
     _xvmc_destroy_surface(display, surface);
@@ -559,19 +645,42 @@ Status XvMCPutSurface(Display *display,XvMCSurface *surface,
                       unsigned short destw, unsigned short desth,
                       int flags)
 {
-    Status ret;
+    Status ret = Success;
+    XvMCContext *context;
+    intel_xvmc_context_ptr intel_ctx;
+    intel_xvmc_surface_ptr intel_surf;
 
     if (!display || !surface)
         return XvMCBadSurface;
 
+    intel_ctx = intel_xvmc_find_context(surface->context_id);
+    intel_surf = intel_xvmc_find_surface(surface->surface_id);
+    if (!intel_ctx || !intel_surf)
+	return XvMCBadSurface;
+    context = intel_ctx->context;
+
+    if (intel_surf->gc_init == FALSE) {
+	intel_surf->gc = XCreateGC(display, draw, 0, NULL);
+	intel_surf->gc_init = TRUE;
+    } else if (draw != intel_surf->last_draw) {
+	XFreeGC(display, intel_surf->gc);
+	intel_surf->gc = XCreateGC(display, draw, 0, NULL);
+    }
+    intel_surf->last_draw = draw;
+
+    /* fill intel_surf->data */
     ret = (xvmc_driver->put_surface)(display, surface, draw, srcx, srcy,
-	    srcw, srch, destx, desty, destw, desth, flags);
+	    srcw, srch, destx, desty, destw, desth, flags, &intel_surf->data);
     if (ret) {
 	XVMC_ERR("put surface fail\n");
 	return ret;
     }
 
-    return Success;
+    ret = XvPutImage(display, context->port, draw, intel_surf->gc,
+	    intel_surf->image, srcx, srcy, srcw, srch, destx, desty,
+	    destw, desth);
+
+    return ret;
 }
 
 /*
diff --git a/src/xvmc/intel_xvmc.h b/src/xvmc/intel_xvmc.h
index 19c5f4c..8ebb14b 100644
--- a/src/xvmc/intel_xvmc.h
+++ b/src/xvmc/intel_xvmc.h
@@ -88,7 +88,7 @@ extern Status _xvmc_destroy_context(Display *dpy, XvMCContext *context);
 
 extern Status _xvmc_create_surface(Display *dpy, XvMCContext *context,
 				   XvMCSurface *surface, int *priv_count,
-				   uint **priv_data);
+				   CARD32 **priv_data);
 
 extern Status _xvmc_destroy_surface(Display *dpy, XvMCSurface *surface);
 
@@ -105,6 +105,16 @@ typedef struct _intel_xvmc_context {
     struct _intel_xvmc_context *next;
 } intel_xvmc_context_t, *intel_xvmc_context_ptr;
 
+typedef struct _intel_xvmc_surface {
+    XvMCSurface *surface;
+    XvImage *image;
+    GC gc;
+    Bool gc_init;
+    Drawable last_draw;
+    struct intel_xvmc_command data;
+    struct _intel_xvmc_surface *next;
+} intel_xvmc_surface_t, *intel_xvmc_surface_ptr;
+
 typedef struct _intel_xvmc_drm_map {
     drm_handle_t handle;
     unsigned long offset;
@@ -150,6 +160,8 @@ typedef struct _intel_xvmc_driver {
 
     int num_ctx;
     intel_xvmc_context_ptr ctx_list;
+    int num_surf;
+    intel_xvmc_surface_ptr surf_list;
 
     void *private;
 
@@ -185,7 +197,7 @@ typedef struct _intel_xvmc_driver {
 	    unsigned short srcw, unsigned short srch,
 	    short destx, short desty,
 	    unsigned short destw, unsigned short desth,
-	    int flags);
+	    int flags, struct intel_xvmc_command *data);
 
     Status (*get_surface_status)(Display *display, XvMCSurface *surface, int *stat);
 
@@ -240,5 +252,6 @@ static inline const char* intel_xvmc_decoder_string(int flag)
 }
 
 extern intel_xvmc_context_ptr intel_xvmc_find_context(XID id);
+extern intel_xvmc_surface_ptr intel_xvmc_find_surface(XID id);
 
 #endif
commit f0ced5edaeec3e7741828eab728417843326d56f
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Mon Dec 24 10:53:57 2007 +0800

    xvmc: store XvMCContext pointer instead of context_id in internal ctx list

diff --git a/src/xvmc/intel_xvmc.c b/src/xvmc/intel_xvmc.c
index 0b6e5a3..fead3a4 100644
--- a/src/xvmc/intel_xvmc.c
+++ b/src/xvmc/intel_xvmc.c
@@ -84,7 +84,7 @@ static void intel_xvmc_free_context(XID id)
     intel_xvmc_context_ptr pre = p;
 
     while(p) {
-	if (p->id == id) {
+	if (p->context->context_id == id) {
 	    if (p == xvmc_driver->ctx_list)
 		xvmc_driver->ctx_list = p->next;
 	    else
@@ -105,7 +105,7 @@ intel_xvmc_context_ptr intel_xvmc_find_context(XID id)
     intel_xvmc_context_ptr p = xvmc_driver->ctx_list;
 
     while(p) {
-	if (p->id == id)
+	if (p->context->context_id == id)
 	    return p;
 	p = p->next;
     }
@@ -231,8 +231,6 @@ Status XvMCCreateContext(Display *display, XvPortID port,
 	XVMC_ERR("Intel XvMC context create fail\n");
 	return BadAlloc;
     }
-    /* context_id is alloc in _xvmc_create_context */
-    intel_ctx->id = context->context_id;
 
     ret = uniDRIQueryDirectRenderingCapable(display, screen,
                                             &isCapable);
@@ -287,6 +285,7 @@ Status XvMCCreateContext(Display *display, XvPortID port,
     xvmc_driver->driHwLock = (drmLock *)&pSAREA->lock;
     pthread_mutex_init(&xvmc_driver->ctxmutex, NULL);
 
+    /* context_id is alloc in _xvmc_create_context */
     if (!uniDRICreateContext(display, screen, NULL,
 			     context->context_id,
                              &intel_ctx->hw_context)) {
diff --git a/src/xvmc/intel_xvmc.h b/src/xvmc/intel_xvmc.h
index 961a2e1..19c5f4c 100644
--- a/src/xvmc/intel_xvmc.h
+++ b/src/xvmc/intel_xvmc.h
@@ -100,7 +100,7 @@ extern Status   _xvmc_destroy_subpicture(Display *dpy,
 					 XvMCSubpicture *subpicture);
 
 typedef struct _intel_xvmc_context {
-    XID	id;	/* context id to X system */
+    XvMCContext *context;
     drm_context_t hw_context;	/* context id to kernel drm */
     struct _intel_xvmc_context *next;
 } intel_xvmc_context_t, *intel_xvmc_context_ptr;
commit 216ad7398742f2f80b5477e89f827acb351b4d72
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Thu Dec 20 13:39:32 2007 +0800

    xvmc: add disable xvmc build support
    
    Move xvmc source files under XVMC config

diff --git a/configure.ac b/configure.ac
index 334a1f4..b46b97a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -66,6 +66,10 @@ AC_ARG_WITH(xserver-source,AC_HELP_STRING([--with-xserver-source=XSERVER_SOURCE]
 			   [ XSERVER_SOURCE="$withval" ],
 			   [ XSERVER_SOURCE="" ])
 
+AC_ARG_ENABLE(xvmc, AC_HELP_STRING([--disable-xvmc],
+                                  [Disable XvMC support [[default=yes]]]),
+              [XVMC="$enableval"],
+              [XVMC=yes])
 
 # Checks for extensions
 XORG_DRIVER_CHECK_EXT(XINERAMA, xineramaproto)
@@ -208,6 +212,14 @@ if test "$VIDEO_DEBUG" = yes; then
 	AC_DEFINE(VIDEO_DEBUG,1,[Enable debug support])
 fi
 
+AC_MSG_CHECKING([whether to include XvMC support])
+AC_MSG_RESULT([$XVMC])
+AM_CONDITIONAL(XVMC, test x$XVMC = xyes)
+if test "$XVMC" = yes; then
+	AC_DEFINE(ENABLE_XVMC,1,[Enable XvMC support])
+fi
+
+
 AC_SUBST([DRI_CFLAGS])
 AC_SUBST([XORG_CFLAGS])
 AC_SUBST([WARN_CFLAGS])
diff --git a/src/Makefile.am b/src/Makefile.am
index 7ae552e..b2b08f2 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -59,11 +59,14 @@ INTEL_DRI_SRCS = \
          i810_dri.h \
          i830_dri.c \
          i810_hwmc.c \
+         i830_dri.h
+
+INTEL_XVMC_SRCS = \
 	 i830_hwmc.h \
 	 i830_hwmc.c \
          i915_hwmc.c \
-         i915_hwmc.h \
-         i830_dri.h
+         i915_hwmc.h
+
 
 intel_drv_la_SOURCES = \
          brw_defines.h \
@@ -149,7 +152,8 @@ EXTRA_DIST = 		\
 	$(XMODE_SRCS)	\
 	$(INTEL_G4A)	\
 	$(INTEL_G4H)	\
-	$(INTEL_DRI_SRCS)
+	$(INTEL_DRI_SRCS) \
+	$(INTEL_XVMC_SRCS)
 
 if HAVE_GEN4ASM
 
@@ -195,6 +199,11 @@ intel_drv_la_SOURCES += \
 	$(INTEL_DRI_SRCS)
 endif
 
+if XVMC
+intel_drv_la_SOURCES += \
+	$(INTEL_XVMC_SRCS)
+endif
+
 install-data-local: install-intel_drv_laLTLIBRARIES
 	(cd $(DESTDIR)$(intel_drv_ladir) && rm -f i810_drv.so && ln -s intel_drv.so i810_drv.so)
 
diff --git a/src/i830.h b/src/i830.h
index 3d105bd..ca69e65 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -116,6 +116,12 @@ typedef struct _I830OutputRec I830OutputRec, *I830OutputPtr;
 #define I830_KERNEL_TEX (1 << 1) /* Allocate texture memory pool */
 #endif
 
+#ifdef XvMCExtension
+#ifdef ENABLE_XVMC
+#define INTEL_XVMC 1
+#endif
+#endif
+
 typedef struct _I830Rec *I830Ptr;
 
 typedef void (*I830WriteIndexedByteFunc)(I830Ptr pI830, IOADDRESS addr,
@@ -396,7 +402,7 @@ typedef struct _I830Rec {
    /* For Xvideo */
    i830_memory *overlay_regs;
 #endif
-#ifdef XvMCExtension
+#ifdef INTEL_XVMC
    /* For XvMC */
    Bool XvMCEnabled;
    Bool IsXvMCSurface;
@@ -737,7 +743,7 @@ extern long I830CheckAvailableMemory(ScrnInfoPtr pScrn);
 Bool i830_allocate_2d_memory(ScrnInfoPtr pScrn);
 Bool i830_allocate_texture_memory(ScrnInfoPtr pScrn);
 Bool i830_allocate_3d_memory(ScrnInfoPtr pScrn);
-#ifdef XvMCExtension
+#ifdef INTEL_XVMC
 Bool i830_allocate_xvmc_buffer(ScrnInfoPtr pScrn, const char *name,
                                i830_memory **buffer, unsigned long size, int flags);
 #endif
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 07fefae..529ea0c 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -199,7 +199,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "i830_bios.h"
 #include "i830_video.h"
 
-#ifdef XvMCExtension
+#ifdef INTEL_XVMC
 #define _INTEL_XVMC_SERVER_
 #include "i830_hwmc.h"
 #endif
@@ -301,7 +301,7 @@ typedef enum {
    OPTION_INTELTEXPOOL,
 #endif
    OPTION_TRIPLEBUFFER,
-#ifdef XvMCExtension
+#ifdef INTEL_XVMC
    OPTION_XVMC,
 #endif
 } I830Opts;
@@ -326,7 +326,7 @@ static OptionInfoRec I830Options[] = {
    {OPTION_INTELTEXPOOL,"Legacy3D",     OPTV_BOOLEAN,	{0},	FALSE},
 #endif
    {OPTION_TRIPLEBUFFER, "TripleBuffer", OPTV_BOOLEAN,	{0},	FALSE},
-#ifdef XvMCExtension
+#ifdef INTEL_XVMC
    {OPTION_XVMC,	"XvMC",		OPTV_BOOLEAN,	{0},	FALSE},
 #endif
    {-1,			NULL,		OPTV_NONE,	{0},	FALSE}
@@ -1594,7 +1594,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
 	      pI830->TripleBuffer ? "en" : "dis");
 #endif
 
-#ifdef XvMCExtension
+#ifdef INTEL_XVMC
    pI830->XvMCEnabled = xf86ReturnOptValBool(pI830->Options, OPTION_XVMC, FALSE);
    xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Intel XvMC decoder %sabled\n",
 	   pI830->XvMCEnabled ? "en" : "dis");
@@ -3027,7 +3027,7 @@ i830AdjustFrame(int scrnIndex, int x, int y, int flags)
 static void
 I830FreeScreen(int scrnIndex, int flags)
 {
-#ifdef XvMCExtension
+#ifdef INTEL_XVMC
     ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
     I830Ptr pI830 = I830PTR(pScrn);
     if (pI830->XvMCEnabled)
diff --git a/src/i830_video.c b/src/i830_video.c
index c0a57b5..1f82ce4 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -74,7 +74,7 @@
 #include "dixstruct.h"
 #include "fourcc.h"
 
-#ifdef XvMCExtension
+#ifdef INTEL_XVMC
 #define _INTEL_XVMC_SERVER_
 #include "i830_hwmc.h"
 #include "i915_hwmc.h"
@@ -265,6 +265,7 @@ static XF86ImageRec Images[NUM_IMAGES] = {
     XVIMAGE_YV12,
     XVIMAGE_I420,
     XVIMAGE_UYVY,
+#ifdef INTEL_XVMC
     {
         /*
          * Below, a dummy picture type that is used in XvPutImage only to do
@@ -289,6 +290,7 @@ static XF86ImageRec Images[NUM_IMAGES] = {
          0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
         XvTopToBottom
     },
+#endif
 };
 
 typedef struct {
@@ -559,7 +561,6 @@ I830InitVideo(ScreenPtr pScreen)
     XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL;
     XF86VideoAdaptorPtr overlayAdaptor = NULL, texturedAdaptor = NULL;
     int num_adaptors;
-    Bool ret = FALSE;
 
 #if 0
     {
@@ -622,7 +623,8 @@ I830InitVideo(ScreenPtr pScreen)
 	}
 	I830InitOffscreenImages(pScreen);
     }
-#ifdef XvMCExtension
+#ifdef INTEL_XVMC
+    Bool ret = FALSE;
     if (intel_xvmc_probe(pScrn)) {
 	if (texturedAdaptor)
 	    ret = intel_xvmc_driver_init(pScreen, texturedAdaptor);
@@ -632,7 +634,7 @@ I830InitVideo(ScreenPtr pScreen)
     if (num_adaptors)
 	xf86XVScreenInit(pScreen, adaptors, num_adaptors);
 
-#ifdef XvMCExtension
+#ifdef INTEL_XVMC
     if (ret)
 	intel_xvmc_screen_init(pScreen);
 #endif
@@ -2285,15 +2287,14 @@ I830PutImage(ScrnInfoPtr pScrn,
     switch (id) {
     case FOURCC_YV12:
     case FOURCC_I420:
-	//XXX
+	srcPitch = (width + 0x3) & ~0x3;
+	srcPitch2 = ((width >> 1) + 0x3) & ~0x3;
+#ifdef INTEL_XVMC
         if (pI830->IsXvMCSurface) {
             srcPitch = (width + 0x3ff) & ~0x3ff;
             srcPitch2 = ((width >> 1) + 0x3ff) & ~0x3ff;
-        } else {
-            srcPitch = (width + 0x3) & ~0x3;
-            srcPitch2 = ((width >> 1) + 0x3) & ~0x3;
         }
-
+#endif
 	if (pPriv->textured && IS_I965G(pI830))
 	    destId = FOURCC_YUY2;
 	break;
@@ -2548,12 +2549,14 @@ I830QueryImageAttributes(ScrnInfoPtr pScrn,
 	    ErrorF("size is %d\n", size);
 #endif
 	break;
+#ifdef INTEL_XVMC
     case FOURCC_XVMC:
         *h = (*h + 1) & ~1;
         size = intel_xvmc_put_image_size(pScrn);
         if (pitches)
             pitches[0] = size;
         break;
+#endif
     case FOURCC_UYVY:
     case FOURCC_YUY2:
     default:
diff --git a/src/xvmc/Makefile.am b/src/xvmc/Makefile.am
index 17867db..cde41f9 100644
--- a/src/xvmc/Makefile.am
+++ b/src/xvmc/Makefile.am
@@ -1,4 +1,4 @@
-if DRI
+if XVMC
 lib_LTLIBRARIES=libI810XvMC.la libIntelXvMC.la
 
 libI810XvMC_la_SOURCES = I810XvMC.c \
commit a811ca30659e8c477027ea9c91fb9fc516fdabc7
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Thu Dec 20 13:08:07 2007 +0800

    xvmc: handle surface create/destory in generic code

diff --git a/src/xvmc/i915_xvmc.c b/src/xvmc/i915_xvmc.c
index bc219d4..44ccdc1 100644
--- a/src/xvmc/i915_xvmc.c
+++ b/src/xvmc/i915_xvmc.c
@@ -1728,17 +1728,13 @@ static int i915_xvmc_mc_destroy_context(Display *display, XvMCContext *context)
 }
 
 static Status i915_xvmc_mc_create_surface(Display *display,
-	XvMCContext *context, XvMCSurface *surface)
+	XvMCContext *context, XvMCSurface *surface, int priv_count,
+	CARD32 *priv_data)
 {
     Status ret;
     i915XvMCContext *pI915XvMC;
     i915XvMCSurface *pI915Surface;
     I915XvMCCreateSurfaceRec *tmpComm = NULL;
-    int priv_count;
-    uint *priv_data;
-
-    if (!display || !context)
-        return BadValue;
 
     if (!(pI915XvMC = context->privData))
         return (error_base + XvMCBadContext);
@@ -1764,19 +1760,6 @@ static Status i915_xvmc_mc_create_surface(Display *display,
     pI915Surface->privContext = pI915XvMC;
     pI915Surface->privSubPic = NULL;
     pI915Surface->srf.map = NULL;
-    XLockDisplay(display);
-
-    if ((ret = _xvmc_create_surface(display, context, surface,
-                                    &priv_count, &priv_data))) {
-        XUnlockDisplay(display);
-        XVMC_ERR("Unable to create XvMCSurface.");
-        free(pI915Surface);
-        surface->privData = NULL;
-        PPTHREAD_MUTEX_UNLOCK();
-        return ret;
-    }
-
-    XUnlockDisplay(display);
 
     if (priv_count != (sizeof(I915XvMCCreateSurfaceRec) >> 2)) {
         XVMC_ERR("_xvmc_create_surface() returned incorrect data size!");
@@ -1836,10 +1819,6 @@ static int i915_xvmc_mc_destroy_surface(Display *display, XvMCSurface *surface)
     if (pI915Surface->srf.map)
         drmUnmap(pI915Surface->srf.map, pI915Surface->srf.size);
 
-    XLockDisplay(display);
-    _xvmc_destroy_surface(display, surface);
-    XUnlockDisplay(display);
-
     free(pI915Surface);
     surface->privData = NULL;
     pI915XvMC->ref--;
diff --git a/src/xvmc/intel_xvmc.c b/src/xvmc/intel_xvmc.c
index 9b80eb4..0b6e5a3 100644
--- a/src/xvmc/intel_xvmc.c
+++ b/src/xvmc/intel_xvmc.c
@@ -366,6 +366,8 @@ Status XvMCDestroyContext(Display *display, XvMCContext *context)
 Status XvMCCreateSurface(Display *display, XvMCContext *context, XvMCSurface *surface)
 {
     Status ret;
+    int priv_count;
+    CARD32 *priv_data;
 
     if (!display || !context)
         return XvMCBadContext;
@@ -373,7 +375,14 @@ Status XvMCCreateSurface(Display *display, XvMCContext *context, XvMCSurface *su
     if (!surface)
 	return XvMCBadSurface;
 
-    ret = (xvmc_driver->create_surface)(display, context, surface);
+    if ((ret = _xvmc_create_surface(display, context, surface,
+                                    &priv_count, &priv_data))) {
+        XVMC_ERR("Unable to create XvMCSurface.");
+        return ret;
+    }
+
+    ret = (xvmc_driver->create_surface)(display, context, surface, priv_count,
+	    priv_data);
     if (ret) {
 	XVMC_ERR("create surface failed\n");
 	return ret;
@@ -393,6 +402,8 @@ Status XvMCDestroySurface(Display *display, XvMCSurface *surface)
 
     (xvmc_driver->destroy_surface)(display, surface);
 
+    _xvmc_destroy_surface(display, surface);
+
     return Success;
 }
 
diff --git a/src/xvmc/intel_xvmc.h b/src/xvmc/intel_xvmc.h
index 8a6f874..961a2e1 100644
--- a/src/xvmc/intel_xvmc.h
+++ b/src/xvmc/intel_xvmc.h
@@ -164,7 +164,7 @@ typedef struct _intel_xvmc_driver {
     Status (*destroy_context)(Display* display, XvMCContext *context);
 
     Status (*create_surface)(Display* display, XvMCContext *context,
-	    XvMCSurface *surface);
+	    XvMCSurface *surface, int priv_count, CARD32 *priv_data);
 
     Status (*destroy_surface)(Display* display, XvMCSurface *surface);
 
commit 5f961f28310a1cd19967df2034b0452bf4446394
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Thu Dec 20 12:51:06 2007 +0800

    xvmc: move dri context handling to generic code
    
    Use XvMCContext's context_id for dri context handling instead
    of driver private id. Remove unnecessary field for i915 private
    structs.

diff --git a/src/i915_hwmc.c b/src/i915_hwmc.c
index 262c63b..e41d148 100644
--- a/src/i915_hwmc.c
+++ b/src/i915_hwmc.c
@@ -501,7 +501,6 @@ static int i915_xvmc_create_context (ScrnInfoPtr pScrn, XvMCContextPtr pContext,
     contextRec->corrdata.offset = ctxpriv->mcCorrdata->offset;
     contextRec->corrdata.size = ctxpriv->mcCorrdata->size;
     contextRec->sarea_priv_offset = sizeof(XF86DRISAREARec);
-    contextRec->depth = pScrn->bitsPerPixel;
     contextRec->deviceID = pI830DRI->deviceID;
 
     pXvMC->ncontexts++;
diff --git a/src/i915_hwmc.h b/src/i915_hwmc.h
index 684ed94..9da3747 100644
--- a/src/i915_hwmc.h
+++ b/src/i915_hwmc.h
@@ -59,7 +59,6 @@ typedef struct
     struct hwmc_buffer psc;
     struct hwmc_buffer corrdata;/* Correction Data Buffer */
     unsigned int sarea_priv_offset;
-    unsigned int depth;
     int deviceID;
 } I915XvMCCreateContextRec;
 
diff --git a/src/xvmc/i915_xvmc.c b/src/xvmc/i915_xvmc.c
index 53dfbdf..bc219d4 100644
--- a/src/xvmc/i915_xvmc.c
+++ b/src/xvmc/i915_xvmc.c
@@ -1612,10 +1612,6 @@ static void i915_release_resource(Display *display, XvMCContext *context)
     driDestroyHashContents(pI915XvMC->drawHash);
     drmHashDestroy(pI915XvMC->drawHash);
 
-    XLockDisplay(display);
-    uniDRIDestroyContext(display, screen, pI915XvMC->id);
-    XUnlockDisplay(display);
-
     free(pI915XvMC);
     context->privData = NULL;
 }
@@ -1633,6 +1629,8 @@ static Status i915_xvmc_mc_create_context(Display *display, XvMCContext *context
     int isCapable;
     int screen = DefaultScreen(display);
 
+    XVMC_DBG("i915_xvmc_mc_create_context\n");
+
     if (priv_count != (sizeof(I915XvMCCreateContextRec) >> 2)) {
         XVMC_ERR("_xvmc_create_context() returned incorrect data size!");
         XVMC_INFO("\tExpected %d, got %d",
@@ -1684,7 +1682,6 @@ static Status i915_xvmc_mc_create_context(Display *display, XvMCContext *context
     pI915XvMC->corrdata.offset = tmpComm->corrdata.offset;
     pI915XvMC->corrdata.size = tmpComm->corrdata.size;
     pI915XvMC->sarea_priv_offset = tmpComm->sarea_priv_offset;
-    pI915XvMC->depth = tmpComm->depth;
 
     /* Must free the private data we were passed from X */
     free(priv_data);
@@ -1692,27 +1689,6 @@ static Status i915_xvmc_mc_create_context(Display *display, XvMCContext *context
 
     pSAREA = (drm_sarea_t *)xvmc_driver->sarea_address;
     pI915XvMC->sarea = (drmI830Sarea*)((char*)pSAREA + pI915XvMC->sarea_priv_offset);
-    ret = XMatchVisualInfo(display, screen,
-                           (pI915XvMC->depth == 32) ? 24 : pI915XvMC->depth, TrueColor,
-                           &pI915XvMC->visualInfo);
-
-    if (!ret) {
-	XVMC_ERR("Could not find a matching TrueColor visual.");
-        free(pI915XvMC);
-        context->privData = NULL;
-        drmUnmap(xvmc_driver->sarea_address, xvmc_driver->sarea_size);
-        return BadAlloc;
-    }
-
-    if (!uniDRICreateContext(display, screen,
-                             pI915XvMC->visualInfo.visual, &pI915XvMC->id,
-                             &pI915XvMC->hHWContext)) {
-        XVMC_ERR("Could not create DRI context.");
-        free(pI915XvMC);
-        context->privData = NULL;
-        drmUnmap(xvmc_driver->sarea_address, xvmc_driver->sarea_size);
-        return BadAlloc;
-    }
 
     if (NULL == (pI915XvMC->drawHash = drmHashCreate())) {
 	XVMC_ERR("Could not allocate drawable hash table.");
@@ -1761,12 +1737,15 @@ static Status i915_xvmc_mc_create_surface(Display *display,
     int priv_count;
     uint *priv_data;
 
-    if (!display || !context || !display)
+    if (!display || !context)
         return BadValue;
 
     if (!(pI915XvMC = context->privData))
         return (error_base + XvMCBadContext);
 
+    XVMC_DBG("%s\n", __FUNCTION__);
+
+
     PPTHREAD_MUTEX_LOCK();
     surface->privData = (i915XvMCSurface *)malloc(sizeof(i915XvMCSurface));
 
@@ -1823,6 +1802,7 @@ static Status i915_xvmc_mc_create_surface(Display *display,
                pI915Surface->srf.handle,
                pI915Surface->srf.size,
                (drmAddress *)&pI915Surface->srf.map) != 0) {
+	XVMC_ERR("mapping surface memory failed!\n");
         _xvmc_destroy_surface(display, surface);
         free(pI915Surface);
         surface->privData = NULL;
@@ -1890,11 +1870,15 @@ static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context,
     /* Current Macroblock Pointer */
     XvMCMacroBlock *mb;
 
+    intel_xvmc_context_ptr intel_ctx;
+
     i915XvMCSurface *privTarget = NULL;
     i915XvMCSurface *privFuture = NULL;
     i915XvMCSurface *privPast = NULL;
     i915XvMCContext *pI915XvMC = NULL;
 
+    XVMC_DBG("%s\n", __FUNCTION__);
+
     /* Check Parameters for validity */
     if (!display || !context || !target_surface) {
         XVMC_ERR("Invalid Display, Context or Target!");
@@ -1926,6 +1910,13 @@ static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context,
         return BadValue;
     }
 
+    intel_ctx = intel_xvmc_find_context(context->context_id);
+    if (!intel_ctx) {
+	XVMC_ERR("Can't find intel xvmc context\n");
+	return BadValue;
+    }
+    XVMC_DBG("intel ctx found\n");
+
     /* P Frame Test */
     if (!past_surface) {
         /* Just to avoid some ifs later. */
@@ -1955,7 +1946,7 @@ static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context,
         picture_coding_type = MPEG_B_PICTURE;
     }
 
-    LOCK_HARDWARE(pI915XvMC->hHWContext);
+    LOCK_HARDWARE(intel_ctx->hw_context);
     corrdata_ptr = pI915XvMC->corrdata.map;
     corrdata_size = 0;
 
@@ -2064,7 +2055,7 @@ static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context,
     xvmc_driver->last_render = xvmc_driver->alloc.irq_emitted;
     privTarget->last_render = xvmc_driver->last_render;
 
-    UNLOCK_HARDWARE(pI915XvMC->hHWContext);
+    UNLOCK_HARDWARE(intel_ctx->hw_context);
     return 0;
 }
 
@@ -2093,14 +2084,7 @@ static int i915_xvmc_mc_put_surface(Display *display,XvMCSurface *surface,
         return (error_base + XvMCBadSurface);
 
     PPTHREAD_MUTEX_LOCK();
-    /*
-    if (getDRIDrawableInfoLocked(pI915XvMC->drawHash, display,
-                                 pI915XvMC->screen, draw, 0, pI915XvMC->fd, pI915XvMC->hHWContext,
-                                 pI915XvMC->sarea_address, FALSE, &drawInfo, sizeof(*drawInfo))) {
-        PPTHREAD_MUTEX_UNLOCK();
-        return BadAccess;
-    }
-    */
+
     if (!pI915XvMC->haveXv) {
         pI915XvMC->xvImage =
             XvCreateImage(display, pI915XvMC->port, FOURCC_XVMC,
@@ -2154,7 +2138,6 @@ static int i915_xvmc_mc_get_surface_status(Display *display,
     if (!(pI915XvMC = pI915Surface->privContext))
         return (error_base + XvMCBadSurface);
 
-    // LOCK_HARDWARE(pI915XvMC->hHWContext);
     PPTHREAD_MUTEX_LOCK();
     if (pI915Surface->last_flip) {
         /* This can not happen */
@@ -2184,7 +2167,6 @@ static int i915_xvmc_mc_get_surface_status(Display *display,
         *stat |= XVMC_RENDERING;
     }
 
-    // UNLOCK_HARDWARE(pI915XvMC->hHWContext);
     PPTHREAD_MUTEX_UNLOCK();
     return 0;
 }
@@ -2594,7 +2576,6 @@ Status i915_xvmc_get_subpict_status(Display *display, XvMCSubpicture *subpicture
     if (!(pI915XvMC = pI915Subpicture->privContext))
         return (error_base + XvMCBadSubpicture);
 
-    // LOCK_HARDWARE(pI915XvMC->hHWContext);
     PPTHREAD_MUTEX_LOCK();
     /* FIXME: */
     if (pI915Subpicture->last_render &&
@@ -2602,7 +2583,6 @@ Status i915_xvmc_get_subpict_status(Display *display, XvMCSubpicture *subpicture
         *stat |= XVMC_RENDERING;
     }
 
-    // UNLOCK_HARDWARE(pI915XvMC->hHWContext);
     PPTHREAD_MUTEX_UNLOCK();
     return Success;
 }
@@ -2610,14 +2590,16 @@ Status i915_xvmc_get_subpict_status(Display *display, XvMCSubpicture *subpicture
 #endif
 
 struct _intel_xvmc_driver i915_xvmc_mc_driver = {
-    .type = XVMC_I915_MPEG2_MC,
-    .init = i915_xvmc_mc_init,
-    .fini = i915_xvmc_mc_fini,
-    .create_context = i915_xvmc_mc_create_context,
-    .destroy_context = i915_xvmc_mc_destroy_context,
-    .create_surface = i915_xvmc_mc_create_surface,
-    .destroy_surface = i915_xvmc_mc_destroy_surface,
-    .render_surface = i915_xvmc_mc_render_surface,
-    .put_surface = i915_xvmc_mc_put_surface,
-    .get_surface_status = i915_xvmc_mc_get_surface_status,
+    .type		= XVMC_I915_MPEG2_MC,
+    .num_ctx		= 0,
+    .ctx_list		= NULL,
+    .init		= i915_xvmc_mc_init,
+    .fini		= i915_xvmc_mc_fini,
+    .create_context	= i915_xvmc_mc_create_context,
+    .destroy_context	= i915_xvmc_mc_destroy_context,
+    .create_surface	= i915_xvmc_mc_create_surface,
+    .destroy_surface	= i915_xvmc_mc_destroy_surface,
+    .render_surface	= i915_xvmc_mc_render_surface,
+    .put_surface	= i915_xvmc_mc_put_surface,
+    .get_surface_status	= i915_xvmc_mc_get_surface_status,
 };
diff --git a/src/xvmc/i915_xvmc.h b/src/xvmc/i915_xvmc.h
index 9a72738..af0a77d 100644
--- a/src/xvmc/i915_xvmc.h
+++ b/src/xvmc/i915_xvmc.h
@@ -56,7 +56,6 @@ typedef struct _i915XvMCContext {
     unsigned int uvStride;
     unsigned short ref;
     volatile drmI830Sarea *sarea;
-    drm_context_t hHWContext; /* drmcontext; */
     unsigned int sarea_priv_offset;	        /* Offset in sarea to private part */
     unsigned int depth;
     XvPortID port;		       /* Xv Port ID when displaying */
@@ -66,8 +65,6 @@ typedef struct _i915XvMCContext {
                                         * buffer transport to the X server */
     GC  gc;                            /* X GC needed for displaying */
     Drawable draw;                     /* Drawable to undisplay from */
-    XID id;
-    XVisualInfo visualInfo;
     void *drawHash;
     int deviceID;
 
diff --git a/src/xvmc/intel_xvmc.c b/src/xvmc/intel_xvmc.c
index 0b90e81..9b80eb4 100644
--- a/src/xvmc/intel_xvmc.c
+++ b/src/xvmc/intel_xvmc.c
@@ -59,6 +59,59 @@ void UNLOCK_HARDWARE(drm_context_t ctx)
     PPTHREAD_MUTEX_UNLOCK();
 }
 
+static intel_xvmc_context_ptr intel_xvmc_new_context(Display *dpy)
+{
+    intel_xvmc_context_ptr ret;
+
+    ret = (intel_xvmc_context_ptr)calloc(1, sizeof(intel_xvmc_context_t));
+    if (!ret)
+	return NULL;
+
+    if (!xvmc_driver->ctx_list)
+	ret->next = NULL;
+    else
+	ret->next = xvmc_driver->ctx_list;
+    xvmc_driver->ctx_list = ret;
+    xvmc_driver->num_ctx++;
+
+    return ret;
+
+}
+
+static void intel_xvmc_free_context(XID id)
+{
+    intel_xvmc_context_ptr p = xvmc_driver->ctx_list;
+    intel_xvmc_context_ptr pre = p;
+
+    while(p) {
+	if (p->id == id) {
+	    if (p == xvmc_driver->ctx_list)
+		xvmc_driver->ctx_list = p->next;
+	    else
+		pre->next = p->next;
+	    break;
+	}
+	pre = p;
+	p = p->next;
+    }
+
+    if (p)
+	free(p);
+    xvmc_driver->num_ctx--;
+}
+
+intel_xvmc_context_ptr intel_xvmc_find_context(XID id)
+{
+    intel_xvmc_context_ptr p = xvmc_driver->ctx_list;
+
+    while(p) {
+	if (p->id == id)
+	    return p;
+	p = p->next;
+    }
+    return NULL;
+}
+
 /*
 * Function: XvMCCreateContext
 * Description: Create a XvMC context for the given surface parameters.
@@ -89,6 +142,7 @@ Status XvMCCreateContext(Display *display, XvPortID port,
     int priv_count;
     int isCapable;
     int screen = DefaultScreen(display);
+    intel_xvmc_context_ptr intel_ctx;
 
     /* Verify Obvious things first */
     if (!display || !context)
@@ -171,6 +225,15 @@ Status XvMCCreateContext(Display *display, XvPortID port,
     xvmc_driver->batchbuffer.offset = comm->batchbuffer.offset;
     xvmc_driver->batchbuffer.size = comm->batchbuffer.size;
 
+    /* assign local ctx info */
+    intel_ctx = intel_xvmc_new_context(display);
+    if (!intel_ctx) {
+	XVMC_ERR("Intel XvMC context create fail\n");
+	return BadAlloc;
+    }
+    /* context_id is alloc in _xvmc_create_context */
+    intel_ctx->id = context->context_id;
+
     ret = uniDRIQueryDirectRenderingCapable(display, screen,
                                             &isCapable);
     if (!ret || !isCapable) {
@@ -205,7 +268,6 @@ Status XvMCCreateContext(Display *display, XvPortID port,
 
     if (!uniDRIAuthConnection(display, screen, magic)) {
 	XVMC_ERR("[XvMC]: X server did not allow DRI. Check permissions.");
-	//(xvmc_driver->fini)();
 	xvmc_driver = NULL;
 	free(priv_data);
         return BadAlloc;
@@ -217,7 +279,6 @@ Status XvMCCreateContext(Display *display, XvPortID port,
     if (drmMap(xvmc_driver->fd, xvmc_driver->hsarea,
                xvmc_driver->sarea_size, &xvmc_driver->sarea_address) < 0) {
         XVMC_ERR("Unable to map DRI SAREA.\n");
-	//(xvmc_driver->fini)();
 	xvmc_driver = NULL;
 	free(priv_data);
         return BadAlloc;
@@ -226,6 +287,16 @@ Status XvMCCreateContext(Display *display, XvPortID port,
     xvmc_driver->driHwLock = (drmLock *)&pSAREA->lock;
     pthread_mutex_init(&xvmc_driver->ctxmutex, NULL);
 
+    if (!uniDRICreateContext(display, screen, NULL,
+			     context->context_id,
+                             &intel_ctx->hw_context)) {
+        XVMC_ERR("Could not create DRI context.");
+	free(priv_data);
+        context->privData = NULL;
+        drmUnmap(xvmc_driver->sarea_address, xvmc_driver->sarea_size);
+        return BadAlloc;
+    }
+
     /* call driver hook.
      * driver hook should free priv_data after return if success.*/
     ret = (xvmc_driver->create_context)(display, context, priv_count, priv_data);
@@ -264,22 +335,28 @@ Status XvMCDestroyContext(Display *display, XvMCContext *context)
 	return ret;
     }
 
+    uniDRIDestroyContext(display, screen, context->context_id);
+    intel_xvmc_free_context(context->context_id);
+
     ret = _xvmc_destroy_context(display, context);
     if (ret != Success) {
 	XVMC_ERR("_xvmc_destroy_context fail\n");
 	return ret;
     }
-    uniDRICloseConnection(display, screen);
 
-    pthread_mutex_destroy(&xvmc_driver->ctxmutex);
+    if (xvmc_driver->num_ctx == 0) {
+	uniDRICloseConnection(display, screen);
+
+	pthread_mutex_destroy(&xvmc_driver->ctxmutex);
 
-    drmUnmap(xvmc_driver->sarea_address, xvmc_driver->sarea_size);
+	drmUnmap(xvmc_driver->sarea_address, xvmc_driver->sarea_size);
 
-    if (xvmc_driver->fd >= 0)
-        drmClose(xvmc_driver->fd);
-    xvmc_driver->fd = -1;
+	if (xvmc_driver->fd >= 0)
+	    drmClose(xvmc_driver->fd);
+	xvmc_driver->fd = -1;
 
-    intelFiniBatchBuffer();
+	intelFiniBatchBuffer();
+    }
     return Success;
 }
 
diff --git a/src/xvmc/intel_xvmc.h b/src/xvmc/intel_xvmc.h
index d3dc5b2..8a6f874 100644
--- a/src/xvmc/intel_xvmc.h
+++ b/src/xvmc/intel_xvmc.h
@@ -99,6 +99,12 @@ extern Status  _xvmc_create_subpicture(Display *dpy, XvMCContext *context,
 extern Status   _xvmc_destroy_subpicture(Display *dpy,
 					 XvMCSubpicture *subpicture);
 
+typedef struct _intel_xvmc_context {
+    XID	id;	/* context id to X system */
+    drm_context_t hw_context;	/* context id to kernel drm */
+    struct _intel_xvmc_context *next;
+} intel_xvmc_context_t, *intel_xvmc_context_ptr;
+
 typedef struct _intel_xvmc_drm_map {
     drm_handle_t handle;
     unsigned long offset;
@@ -142,6 +148,9 @@ typedef struct _intel_xvmc_driver {
     int locked;
     drmLock *driHwLock;
 
+    int num_ctx;
+    intel_xvmc_context_ptr ctx_list;
+
     void *private;
 
     /* XXX: remove? */
@@ -229,4 +238,7 @@ static inline const char* intel_xvmc_decoder_string(int flag)
 	    return "Unknown decoder";
     }
 }
+
+extern intel_xvmc_context_ptr intel_xvmc_find_context(XID id);
+
 #endif
diff --git a/src/xvmc/xf86dri.c b/src/xvmc/xf86dri.c
index 1feb232..2b60348 100644
--- a/src/xvmc/xf86dri.c
+++ b/src/xvmc/xf86dri.c
@@ -332,7 +332,7 @@ uniDRICreateContextWithConfig(dpy, screen, configID, context, hHWContext)
     Display *dpy;
     int screen;
     int configID;
-    XID *context;
+    XID context;
     drm_context_t *hHWContext;
 {
     XExtDisplayInfo *info = find_display(dpy);
@@ -348,8 +348,7 @@ uniDRICreateContextWithConfig(dpy, screen, configID, context, hHWContext)
     req->driReqType = X_XF86DRICreateContext;
     req->visual = configID;
     req->screen = screen;
-    *context = XAllocID(dpy);
-    req->context = *context;
+    req->context = context;
     if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
 	UnlockDisplay(dpy);
 	SyncHandle();
@@ -368,10 +367,11 @@ uniDRICreateContext(dpy, screen, visual, context, hHWContext)
     Display *dpy;
     int screen;
     Visual *visual;
-    XID *context;
+    XID context;
     drm_context_t *hHWContext;
 {
-    return uniDRICreateContextWithConfig(dpy, screen, visual->visualid,
+    return uniDRICreateContextWithConfig(dpy, screen,
+	   visual ? visual->visualid : 0,
 	context, hHWContext);
 }
 
diff --git a/src/xvmc/xf86dri.h b/src/xvmc/xf86dri.h
index d7580a1..7598bc8 100644
--- a/src/xvmc/xf86dri.h
+++ b/src/xvmc/xf86dri.h
@@ -86,11 +86,13 @@ Bool uniDRIGetClientDriverName(Display * dpy, int screen,
     int *ddxDriverMajorVersion, int *ddxDriverMinorVersion,
     int *ddxDriverPatchVersion, char **clientDriverName);
 
+/* XvMC context XID is alloced in _xvmc_create_context, so
+ * don't recreate here */
 Bool uniDRICreateContext(Display * dpy, int screen, Visual * visual,
-    XID * ptr_to_returned_context_id, drm_context_t * hHWContext);
+    XID context_id, drm_context_t * hHWContext);
 
 Bool uniDRICreateContextWithConfig(Display * dpy, int screen, int configID,
-    XID * ptr_to_returned_context_id, drm_context_t * hHWContext);
+    XID context_id, drm_context_t * hHWContext);
 
 extern Bool uniDRIDestroyContext(Display * dpy, int screen, XID context_id);
 
commit 73827e78357ab3f30a21f159ecdfb26dd0ea889b
Merge: 3cf8627... f69b48f...
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Wed Dec 19 22:47:02 2007 +0800

    Merge branch 'master' into xvmc

commit 3cf862717688aa679b5e667cd041ddd6f5db0b58
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Thu Nov 29 23:12:16 2007 +0800

    xvmc: add "XvMC" option, default is false.

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 0a05934..d2d405d 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -301,6 +301,9 @@ typedef enum {
    OPTION_INTELTEXPOOL,
 #endif
    OPTION_TRIPLEBUFFER,
+#ifdef XvMCExtension
+   OPTION_XVMC,
+#endif
 } I830Opts;
 
 static OptionInfoRec I830Options[] = {
@@ -323,6 +326,9 @@ static OptionInfoRec I830Options[] = {
    {OPTION_INTELTEXPOOL,"Legacy3D",     OPTV_BOOLEAN,	{0},	FALSE},
 #endif
    {OPTION_TRIPLEBUFFER, "TripleBuffer", OPTV_BOOLEAN,	{0},	FALSE},
+#ifdef XvMCExtension
+   {OPTION_XVMC,	"XvMC",		OPTV_BOOLEAN,	{0},	FALSE},
+#endif
    {-1,			NULL,		OPTV_NONE,	{0},	FALSE}
 };
 /* *INDENT-ON* */
@@ -1588,6 +1594,12 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
 	      pI830->TripleBuffer ? "en" : "dis");
 #endif
 
+#ifdef XvMCExtension
+   pI830->XvMCEnabled = xf86ReturnOptValBool(pI830->Options, OPTION_XVMC, FALSE);
+   xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Intel XvMC decoder %sabled\n",
+	   pI830->XvMCEnabled ? "en" : "dis");
+#endif
+
    /*
     * If the driver can do gamma correction, it should call xf86SetGamma() here.
     */
diff --git a/src/i830_hwmc.c b/src/i830_hwmc.c
index 721616c..189c2e5 100644
--- a/src/i830_hwmc.c
+++ b/src/i830_hwmc.c
@@ -52,6 +52,9 @@ Bool intel_xvmc_probe(ScrnInfoPtr pScrn)
     I830Ptr pI830 = I830PTR(pScrn);
     Bool ret = FALSE;
 
+    if (!pI830->XvMCEnabled)
+	return FALSE;
+
     if (IS_I9XX(pI830)) {
 	if (!IS_I965G(pI830))
 	    ret = intel_xvmc_set_driver(&i915_xvmc_driver);
@@ -101,7 +104,6 @@ Bool intel_xvmc_screen_init(ScreenPtr pScreen)
 	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 		"[XvMC] %s driver initialized.\n",
 		xvmc_driver->name);
-	pI830->XvMCEnabled = TRUE;
     } else {
 	intel_xvmc_finish(pScrn);
 	pI830->XvMCEnabled = FALSE;
commit 6da4b7a80cdf730018435fe84485ecdad62bc860
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Thu Nov 29 22:56:13 2007 +0800

    xvmc: move batch buffer init/fini code into generic

diff --git a/src/i830_hwmc.c b/src/i830_hwmc.c
index aed8631..721616c 100644
--- a/src/i830_hwmc.c
+++ b/src/i830_hwmc.c
@@ -116,3 +116,38 @@ int intel_xvmc_put_image_size(ScrnInfoPtr pScrn)
 {
     return (*xvmc_driver->put_image_size)(pScrn);
 }
+
+
+Bool intel_xvmc_init_batch(ScrnInfoPtr pScrn)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+
+    if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC] batch buffer",
+                                   &(xvmc_driver->batch), 8 * 1024,
+                                   ALIGN_BOTH_ENDS))
+        return FALSE;
+
+    if (drmAddMap(pI830->drmSubFD,
+                  (drm_handle_t)(xvmc_driver->batch->offset+pI830->LinearAddr),
+                  xvmc_driver->batch->size, DRM_AGP, 0,
+                  &xvmc_driver->batch_handle) < 0) {
+        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                   "[drm] drmAddMap(batchbuffer_handle) failed!\n");
+        return FALSE;
+    }
+    return TRUE;
+}
+
+void intel_xvmc_fini_batch(ScrnInfoPtr pScrn)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+
+    if (xvmc_driver->batch_handle) {
+        drmRmMap(pI830->drmSubFD, xvmc_driver->batch_handle);
+        xvmc_driver->batch_handle = 0;
+    }
+    if (xvmc_driver->batch) {
+        i830_free_memory(pScrn, xvmc_driver->batch);
+        xvmc_driver->batch = NULL;
+    }
+}
diff --git a/src/i830_hwmc.h b/src/i830_hwmc.h
index c5b3c17..073fe44 100644
--- a/src/i830_hwmc.h
+++ b/src/i830_hwmc.h
@@ -84,6 +84,8 @@ extern Bool intel_xvmc_driver_init(ScreenPtr, XF86VideoAdaptorPtr);
 extern Bool intel_xvmc_screen_init(ScreenPtr);
 extern void intel_xvmc_finish(ScrnInfoPtr);
 extern int  intel_xvmc_put_image_size(ScrnInfoPtr);
+extern Bool intel_xvmc_init_batch(ScrnInfoPtr);
+extern void intel_xvmc_fini_batch(ScrnInfoPtr);
 #endif
 
 #endif
diff --git a/src/i915_hwmc.c b/src/i915_hwmc.c
index 9e28d16..262c63b 100644
--- a/src/i915_hwmc.c
+++ b/src/i915_hwmc.c
@@ -805,39 +805,6 @@ static int i915_xvmc_put_image_size(ScrnInfoPtr pScrn)
     return sizeof(I915XvMCCommandBuffer);
 }
 
-static Bool i915_xvmc_init_batch(ScrnInfoPtr pScrn)
-{
-    I830Ptr pI830 = I830PTR(pScrn);
-
-    if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC] batch buffer",
-                                   &(xvmc_driver->batch), 8 * 1024,
-                                   ALIGN_BOTH_ENDS))
-        return FALSE;
-
-    if (drmAddMap(pI830->drmSubFD,
-                  (drm_handle_t)(xvmc_driver->batch->offset+pI830->LinearAddr),
-                  xvmc_driver->batch->size, DRM_AGP, 0,
-                  &xvmc_driver->batch_handle) < 0) {
-        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-                   "[drm] drmAddMap(batchbuffer_handle) failed!\n");
-        return FALSE;
-    }
-    return TRUE;
-}
-
-static void i915_xvmc_fini_batch(ScrnInfoPtr pScrn)
-{
-    I830Ptr pI830 = I830PTR(pScrn);
-
-    if (xvmc_driver->batch_handle) {
-        drmRmMap(pI830->drmSubFD, xvmc_driver->batch_handle);
-        xvmc_driver->batch_handle = 0;
-    }
-    if (xvmc_driver->batch) {
-        i830_free_memory(pScrn, xvmc_driver->batch);
-        xvmc_driver->batch = NULL;
-    }
-}
 
 static Bool i915_xvmc_init(ScrnInfoPtr pScrn, XF86VideoAdaptorPtr XvAdapt)
 {
@@ -850,7 +817,7 @@ static Bool i915_xvmc_init(ScrnInfoPtr pScrn, XF86VideoAdaptorPtr XvAdapt)
         return FALSE;
     }
     xvmc_driver->devPrivate = (void*)pXvMC;
-    if (!i915_xvmc_init_batch(pScrn)) {
+    if (!intel_xvmc_init_batch(pScrn)) {
         xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 		"[XvMC] fail to init batch buffer\n");
 	xfree(pXvMC);
@@ -869,7 +836,7 @@ static void i915_xvmc_fini(ScrnInfoPtr pScrn)
     I915XvMCPtr pXvMC = (I915XvMCPtr)xvmc_driver->devPrivate;
 
     cleanupI915XvMC(pXvMC);
-    i915_xvmc_fini_batch(pScrn);
+    intel_xvmc_fini_batch(pScrn);
     xfree(xvmc_driver->devPrivate);
 }
 
commit df47b7ba57f3e7dc8bac1898679186d9d48639ac
Merge: df718a7... 7f9ceff...
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Tue Nov 27 01:13:43 2007 +0800

    Merge branch 'master' into xvmc

commit df718a77c854c9110a81c2bc2a32a9aac85850f2
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Fri Nov 16 16:08:06 2007 +0800

    xvmc: add xvmc decoder type string

diff --git a/src/xvmc/intel_xvmc.c b/src/xvmc/intel_xvmc.c
index 1de53f3..0b90e81 100644
--- a/src/xvmc/intel_xvmc.c
+++ b/src/xvmc/intel_xvmc.c
@@ -142,8 +142,7 @@ Status XvMCCreateContext(Display *display, XvPortID port,
     }
 
     comm = (struct _intel_xvmc_common *)priv_data;
-    XVMC_INFO("hw xvmc type %d", comm->type);
-    //XXX: how to handle different driver types
+
     if (xvmc_driver == NULL || xvmc_driver->type != comm->type) {
 	switch (comm->type) {
 	    case XVMC_I915_MPEG2_MC:
@@ -158,17 +157,15 @@ Status XvMCCreateContext(Display *display, XvPortID port,
 		priv_data = NULL;
 		return BadValue;
 	}
-    } else {
-	XVMC_ERR("wrong hw xvmc type returned\n");
-	free(priv_data);
-	priv_data = NULL;
-	return BadValue;
     }
 
     if (xvmc_driver == NULL || xvmc_driver->type != comm->type) {
 	XVMC_ERR("fail to load xvmc driver for type %d\n", comm->type);
 	return BadValue;
     }
+
+    XVMC_INFO("decoder type is %s", intel_xvmc_decoder_string(comm->type));
+
     xvmc_driver->sarea_size = comm->sarea_size;
     xvmc_driver->batchbuffer.handle = comm->batchbuffer.handle;
     xvmc_driver->batchbuffer.offset = comm->batchbuffer.offset;
diff --git a/src/xvmc/intel_xvmc.h b/src/xvmc/intel_xvmc.h
index 28390af..d3dc5b2 100644
--- a/src/xvmc/intel_xvmc.h
+++ b/src/xvmc/intel_xvmc.h
@@ -60,18 +60,18 @@
 
 #define XVMC_ERR(s, arg...)					\
     do {							\
-	fprintf(stderr, "intel_xvmc err: " s "\n", ##arg);	\
+	fprintf(stderr, "[intel_xvmc] err: " s "\n", ##arg);	\
     } while (0)
 
 #define XVMC_INFO(s, arg...)					\
     do {							\
-	fprintf(stderr, "intel_xvmc info: " s "\n", ##arg);	\
+	fprintf(stderr, "[intel_xvmc] info: " s "\n", ##arg);	\
     } while (0)
 
 #define XVMC_DBG(s, arg...)						\
     do {								\
 	if (DEBUG)							\
-	    fprintf(stderr, "intel_xvmc debug: " s "\n", ##arg);	\
+	    fprintf(stderr, "[intel_xvmc] debug: " s "\n", ##arg);	\
     } while (0)
 
 /* Subpicture fourcc */
@@ -213,4 +213,20 @@ extern struct _intel_xvmc_driver *xvmc_driver;
 
 extern void LOCK_HARDWARE(drm_context_t);
 extern void UNLOCK_HARDWARE(drm_context_t);
+
+static inline const char* intel_xvmc_decoder_string(int flag)
+{
+    switch (flag) {
+	case XVMC_I915_MPEG2_MC:
+	    return "i915/945 MPEG2 MC decoder";
+	case XVMC_I965_MPEG2_MC:
+	    return "i965 MPEG2 MC decoder";
+	case XVMC_I945_MPEG2_VLD:
+	    return "i945 MPEG2 VLD decoder";
+	case XVMC_I965_MPEG2_VLD:
+	    return "i965 MPEG2 VLD decoder";
+	default:
+	    return "Unknown decoder";
+    }
+}
 #endif
commit a03a758db0df615fbb44dae1ab6910bfeaeb54f9
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Fri Nov 16 15:49:10 2007 +0800

    xvmc: move some i915 context destroy code to generic function

diff --git a/src/xvmc/i915_xvmc.c b/src/xvmc/i915_xvmc.c
index 404edc0..53dfbdf 100644
--- a/src/xvmc/i915_xvmc.c
+++ b/src/xvmc/i915_xvmc.c
@@ -1612,23 +1612,10 @@ static void i915_release_resource(Display *display, XvMCContext *context)
     driDestroyHashContents(pI915XvMC->drawHash);
     drmHashDestroy(pI915XvMC->drawHash);
 
-    pthread_mutex_destroy(&xvmc_driver->ctxmutex);
-
     XLockDisplay(display);
     uniDRIDestroyContext(display, screen, pI915XvMC->id);
     XUnlockDisplay(display);
 
-    drmUnmap(xvmc_driver->sarea_address, xvmc_driver->sarea_size);
-
-    if (xvmc_driver->fd >= 0)
-        drmClose(xvmc_driver->fd);
-    xvmc_driver->fd = -1;
-
-    XLockDisplay(display);
-    uniDRICloseConnection(display, screen);
-    _xvmc_destroy_context(display, context);
-    XUnlockDisplay(display);
-
     free(pI915XvMC);
     context->privData = NULL;
 }
diff --git a/src/xvmc/intel_xvmc.c b/src/xvmc/intel_xvmc.c
index 164b4b2..1de53f3 100644
--- a/src/xvmc/intel_xvmc.c
+++ b/src/xvmc/intel_xvmc.c
@@ -256,6 +256,7 @@ Status XvMCCreateContext(Display *display, XvPortID port,
 Status XvMCDestroyContext(Display *display, XvMCContext *context)
 {
     Status ret;
+    int screen = DefaultScreen(display);
 
     if (!display || !context)
         return XvMCBadContext;
@@ -266,9 +267,21 @@ Status XvMCDestroyContext(Display *display, XvMCContext *context)
 	return ret;
     }
 
-    /* Pass Control to the X server to destroy the drm_context_t */
-    //XXX move generic destroy method here
-    //i915_release_resource(display,context);
+    ret = _xvmc_destroy_context(display, context);
+    if (ret != Success) {
+	XVMC_ERR("_xvmc_destroy_context fail\n");
+	return ret;
+    }
+    uniDRICloseConnection(display, screen);
+
+    pthread_mutex_destroy(&xvmc_driver->ctxmutex);
+
+    drmUnmap(xvmc_driver->sarea_address, xvmc_driver->sarea_size);
+
+    if (xvmc_driver->fd >= 0)
+        drmClose(xvmc_driver->fd);
+    xvmc_driver->fd = -1;
+
     intelFiniBatchBuffer();
     return Success;
 }
commit 7bfbcb4dc7806ae7543f230373e67f35ba30668d
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Fri Nov 16 15:43:04 2007 +0800

    xvmc: clean batch buffer finish

diff --git a/src/xvmc/i915_xvmc.c b/src/xvmc/i915_xvmc.c
index 0623c53..404edc0 100644
--- a/src/xvmc/i915_xvmc.c
+++ b/src/xvmc/i915_xvmc.c
@@ -1618,8 +1618,6 @@ static void i915_release_resource(Display *display, XvMCContext *context)
     uniDRIDestroyContext(display, screen, pI915XvMC->id);
     XUnlockDisplay(display);
 
-    intelDestroyBatchBuffer();
-
     drmUnmap(xvmc_driver->sarea_address, xvmc_driver->sarea_size);
 
     if (xvmc_driver->fd >= 0)
diff --git a/src/xvmc/intel_batchbuffer.c b/src/xvmc/intel_batchbuffer.c
index 82a7bf2..a3f82ff 100644
--- a/src/xvmc/intel_batchbuffer.c
+++ b/src/xvmc/intel_batchbuffer.c
@@ -82,7 +82,7 @@ void intelWaitIrq(int seq)
    }
 }
 
-void intelDestroyBatchBuffer(void)
+static void intelDestroyBatchBuffer(void)
 {
    if (xvmc_driver->alloc.offset) {
        xvmc_driver->alloc.ptr = NULL;
@@ -122,12 +122,11 @@ Bool intelInitBatchBuffer(void)
 
 void intelFiniBatchBuffer(void)
 {
-    intelFlushBatch(TRUE);
-
     if (xvmc_driver->batchbuffer.map) {
         drmUnmap(xvmc_driver->batchbuffer.map, xvmc_driver->batchbuffer.size);
         xvmc_driver->batchbuffer.map = NULL;
     }
+    intelDestroyBatchBuffer();
 }
 
 void intelBatchbufferRequireSpace(unsigned int sz)
diff --git a/src/xvmc/intel_batchbuffer.h b/src/xvmc/intel_batchbuffer.h
index 20e7406..aec71e4 100644
--- a/src/xvmc/intel_batchbuffer.h
+++ b/src/xvmc/intel_batchbuffer.h
@@ -37,7 +37,6 @@ extern int VERBOSE;
 extern void intelFlushBatch(Bool);
 extern void intelBatchbufferData(const void *, unsigned, unsigned);
 extern Bool intelInitBatchBuffer(void);
-extern Bool intelFnitBatchBuffer(void);
-extern void intelDestroyBatchBuffer(void);
+extern void intelFiniBatchBuffer(void);
 extern void intelCmdIoctl(char *, unsigned);
 #endif /* _INTEL_BATCHBUFFER_H */
commit a6e8f4ef0481c66fda4f22fcc4bb0ef9c000f0cd
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Fri Nov 16 13:51:44 2007 +0800

    xvmc: remove i915 drm map type

diff --git a/src/xvmc/i915_xvmc.h b/src/xvmc/i915_xvmc.h
index 4c7aaa7..9a72738 100644
--- a/src/xvmc/i915_xvmc.h
+++ b/src/xvmc/i915_xvmc.h
@@ -44,17 +44,6 @@
 #define PCI_CHIP_Q33_G                  0x29D2
 
 /*
- * i915XvMCDrmMap: Holds the data about the DRM maps
- */
-typedef struct _i915XvMCDrmMap {
-    drm_handle_t handle;
-    unsigned long offset;
-    unsigned long size;
-    unsigned long bus_addr;
-    drmAddress map;
-} i915XvMCDrmMap, *i915XvMCDrmMapPtr;
-
-/*
  * i915XvMCContext:
  *	Private Context data referenced via the privData
  *      pointer in the XvMCContext structure.
@@ -82,12 +71,12 @@ typedef struct _i915XvMCContext {
     void *drawHash;
     int deviceID;
 
-    i915XvMCDrmMap sis;
-    i915XvMCDrmMap msb;
-    i915XvMCDrmMap ssb;
-    i915XvMCDrmMap psp;
-    i915XvMCDrmMap psc;
-    i915XvMCDrmMap corrdata;
+    intel_xvmc_drm_map_t sis;
+    intel_xvmc_drm_map_t msb;
+    intel_xvmc_drm_map_t ssb;
+    intel_xvmc_drm_map_t psp;
+    intel_xvmc_drm_map_t psc;
+    intel_xvmc_drm_map_t corrdata;
 } i915XvMCContext;
 
 /*
@@ -102,7 +91,7 @@ typedef struct _i915XvMCSubpicture {
     unsigned int last_flip;
     unsigned int pitch;
     unsigned char palette[3][16];
-    i915XvMCDrmMap srf;
+    intel_xvmc_drm_map_t srf;
     i915XvMCContext *privContext;
 } i915XvMCSubpicture;
 
@@ -122,7 +111,7 @@ typedef struct _i915XvMCSurface {
     unsigned int uvStride;
     unsigned int width;                    /* Dimensions */
     unsigned int height;
-    i915XvMCDrmMap srf;
+    intel_xvmc_drm_map_t srf;
     i915XvMCContext *privContext;
     i915XvMCSubpicture *privSubPic;     /* Subpicture to be blended when
                                          * displaying. NULL if none. */
commit 6c68fcc93917565712b6a9386df54d0204e4ea8f
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Fri Nov 16 10:04:46 2007 +0800

    xvmc: more i915 xvmc cleanups

diff --git a/src/xvmc/i915_xvmc.c b/src/xvmc/i915_xvmc.c
index a2c3e54..0623c53 100644
--- a/src/xvmc/i915_xvmc.c
+++ b/src/xvmc/i915_xvmc.c
@@ -46,7 +46,7 @@ static unsigned int mb_bytes[] = {
     128, 256, 256, 384, 256, 384, 384, 512,  // 10
     256, 384, 384, 512, 384, 512, 512, 640,  // 11
     128, 256, 256, 384, 256, 384, 384, 512,  // 100
-    256, 384, 384, 512, 384, 512, 512, 640,  // 101    
+    256, 384, 384, 512, 384, 512, 512, 640,  // 101
     256, 384, 384, 512, 384, 512, 512, 640,  // 110
     384, 512, 512, 640, 512, 640, 640, 768   // 111
 };
@@ -60,49 +60,18 @@ static char I915KernelDriverName[] = "i915";
 static int error_base;
 static int event_base;
 
-static Status i915_xvmc_mc_create_context(Display* display, XvMCContext *context, int priv_count, CARD32* priv_data);
-static Status i915_xvmc_mc_destroy_context(Display* display, XvMCContext *context);
-static Status i915_xvmc_mc_create_surface(Display* display, XvMCContext *context, XvMCSurface *surface);
-static Status i915_xvmc_mc_destroy_surface(Display* display, XvMCSurface *surface);
-static Status i915_xvmc_mc_render_surface(Display *display, XvMCContext *context,
-                         unsigned int picture_structure,
-                         XvMCSurface *target_surface,
-                         XvMCSurface *past_surface,
-                         XvMCSurface *future_surface,
-                         unsigned int flags,
-                         unsigned int num_macroblocks,
-                         unsigned int first_macroblock,
-                         XvMCMacroBlockArray *macroblock_array,
-                         XvMCBlockArray *blocks);
-static Status i915_xvmc_mc_put_surface(Display *display,XvMCSurface *surface,
-                      Drawable draw, short srcx, short srcy,
-                      unsigned short srcw, unsigned short srch,
-                      short destx, short desty,
-                      unsigned short destw, unsigned short desth,
-                      int flags);
-static Status i915_xvmc_mc_get_surface_status(Display *display, XvMCSurface *surface, int *stat);
-//XXX
 static int i915_xvmc_mc_init()
-{return 0;}
+{
+    return 0;
+}
+
 static void i915_xvmc_mc_fini()
 {}
 
-struct _intel_xvmc_driver i915_xvmc_mc_driver = {
-    .type = XVMC_I915_MPEG2_MC,
-    .init = i915_xvmc_mc_init,
-    .fini = i915_xvmc_mc_fini,
-    .create_context = i915_xvmc_mc_create_context,
-    .destroy_context = i915_xvmc_mc_destroy_context,
-    .create_surface = i915_xvmc_mc_create_surface,
-    .destroy_surface = i915_xvmc_mc_destroy_surface,
-    .render_surface = i915_xvmc_mc_render_surface,
-    .put_surface = i915_xvmc_mc_put_surface,
-    .get_surface_status = i915_xvmc_mc_get_surface_status,
-};
 
 static int findOverlap(unsigned int width, unsigned int height,
                        short *dstX, short *dstY,
-                       short *srcX, short *srcY, 
+                       short *srcX, short *srcY,
                        unsigned short *areaW, unsigned short *areaH)
 {
     int w, h;
@@ -136,11 +105,6 @@ static int findOverlap(unsigned int width, unsigned int height,
     return 0;
 }
 
-static __inline__ void renderError(void) 
-{
-    XVMC_ERR("Invalid Macroblock Parameters found.");
-}
-
 static void i915_flush(int map, int render)
 {
     struct i915_mi_flush mi_flush;
@@ -155,11 +119,11 @@ static void i915_flush(int map, int render)
 }
 
 /* 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_buffer(XvMCContext *context,
+	XvMCSurface *surface,
+	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;
@@ -193,7 +157,7 @@ static void i915_mc_static_indirect_state_buffer(XvMCContext *context,
     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.walk = TILEWALK_XMAJOR;
     buffer_info->dw1.pitch = (pI915Surface->uvStride >> 2);      /* in DWords */
     buffer_info->dw2.base_address = (UOFFSET(pI915Surface) >> 2);      /* starting DWORD address */
 
@@ -207,7 +171,7 @@ static void i915_mc_static_indirect_state_buffer(XvMCContext *context,
     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.walk = TILEWALK_XMAJOR;
     buffer_info->dw1.pitch = (pI915Surface->uvStride >> 2);      /* in Dwords */
     buffer_info->dw2.base_address = (VOFFSET(pI915Surface) >> 2);      /* starting DWORD address */
 
@@ -220,7 +184,7 @@ static void i915_mc_static_indirect_state_buffer(XvMCContext *context,
     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 = 0;
     dest_buffer_variables->dw1.v_ls_offset = 0;
 
     if ((picture_structure & XVMC_FRAME_PICTURE) == XVMC_FRAME_PICTURE) {
@@ -240,10 +204,10 @@ static void i915_mc_static_indirect_state_buffer(XvMCContext *context,
     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.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;            
+    dest_buffer_variables_mpeg->dw1.tff = 1;
 
     if (picture_structure & XVMC_FRAME_PICTURE) {
         ;
@@ -258,7 +222,7 @@ static void i915_mc_static_indirect_state_buffer(XvMCContext *context,
         else
             dest_buffer_variables_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 */
@@ -274,14 +238,14 @@ static void i915_mc_static_indirect_state_buffer(XvMCContext *context,
     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.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 */
 }
 
-static void i915_mc_map_state_buffer(XvMCContext *context, 
+static void i915_mc_map_state_buffer(XvMCContext *context,
                                        i915XvMCSurface *privTarget,
                                        i915XvMCSurface *privPast,
                                        i915XvMCSurface *privFuture)
@@ -290,7 +254,7 @@ static void i915_mc_map_state_buffer(XvMCContext *context,
     struct texture_map *tm;
     i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
     unsigned int w = context->width, h = context->height;
- 
+
     /* 3DSATE_MAP_STATE: Y */
     map_state = (struct i915_3dstate_map_state *)pI915XvMC->msb.map;
     memset(map_state, 0, sizeof(*map_state));
@@ -379,7 +343,7 @@ static void i915_mc_map_state_buffer(XvMCContext *context,
     tm->tm2.depth = 0;
     tm->tm2.max_lod = 0;
     tm->tm2.cube_face = 0;
-    tm->tm2.pitch = (privFuture->uvStride >> 2) - 1;     
+    tm->tm2.pitch = (privFuture->uvStride >> 2) - 1;
 
     /* 3DSATE_MAP_STATE: V */
     map_state = (struct i915_3dstate_map_state *)(++tm);
@@ -518,12 +482,12 @@ static void i915_mc_mpeg_macroblock_0mv(XvMCContext *context, XvMCMacroBlock *mb
     macroblock_0mv.header.dw0.type = CMD_3D;
     macroblock_0mv.header.dw0.opcode = OPC_3DMPEG_MACROBLOCK;
     macroblock_0mv.header.dw0.length = 0;
-    macroblock_0mv.header.dw1.mb_intra = 1;     /* should be 1 */ 
+    macroblock_0mv.header.dw1.mb_intra = 1;     /* should be 1 */
     macroblock_0mv.header.dw1.forward = 0;      /* should be 0 */
     macroblock_0mv.header.dw1.backward = 0;     /* should be 0 */
     macroblock_0mv.header.dw1.h263_4mv = 0;     /* should be 0 */
     macroblock_0mv.header.dw1.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD);
-    
+
 /*
     if (!mb->coded_block_pattern)
         macroblock_0mv.header.dw1.dct_type = XVMC_DCT_TYPE_FRAME;
@@ -540,7 +504,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;
@@ -550,19 +514,19 @@ static void i915_mc_mpeg_macroblock_1fbmv(XvMCContext *context, XvMCMacroBlock *
     macroblock_1fbmv.header.dw0.type = CMD_3D;
     macroblock_1fbmv.header.dw0.opcode = OPC_3DMPEG_MACROBLOCK;
     macroblock_1fbmv.header.dw0.length = 2;
-    macroblock_1fbmv.header.dw1.mb_intra = 0;   /* should be 0 */ 
+    macroblock_1fbmv.header.dw1.mb_intra = 0;   /* should be 0 */
     macroblock_1fbmv.header.dw1.forward = ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_FORWARD) ? 1 : 0);
     macroblock_1fbmv.header.dw1.backward = ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_BACKWARD) ? 1 : 0);
     macroblock_1fbmv.header.dw1.h263_4mv = 0;   /* should be 0 */
     macroblock_1fbmv.header.dw1.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD);
-    
+
     if (!(mb->coded_block_pattern & 0x3f))
         macroblock_1fbmv.header.dw1.dct_type = XVMC_DCT_TYPE_FRAME;
 
     macroblock_1fbmv.header.dw1.motion_type = (mb->motion_type & 0x03);
     macroblock_1fbmv.header.dw1.vertical_field_select = (mb->motion_vertical_field_select & 0x0f);
-    macroblock_1fbmv.header.dw1.coded_block_pattern = mb->coded_block_pattern; 
-    macroblock_1fbmv.header.dw1.skipped_macroblocks = 0;      
+    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];
@@ -571,7 +535,7 @@ static void i915_mc_mpeg_macroblock_1fbmv(XvMCContext *context, XvMCMacroBlock *
 
     macroblock_1fbmv.dw2 = fmv.u[0];
     macroblock_1fbmv.dw3 = bmv.u[0];
-    
+
     intelBatchbufferData(&macroblock_1fbmv, sizeof(macroblock_1fbmv), 0);
 }
 
@@ -579,7 +543,7 @@ static void i915_mc_mpeg_macroblock_2fbmv(XvMCContext *context, XvMCMacroBlock *
 {
     struct i915_3dmpeg_macroblock_2fbmv macroblock_2fbmv;
     i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
-    
+
     /* Motion Vectors */
     su_t fmv;
     su_t bmv;
@@ -594,7 +558,7 @@ static void i915_mc_mpeg_macroblock_2fbmv(XvMCContext *context, XvMCMacroBlock *
     macroblock_2fbmv.header.dw1.backward = ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_BACKWARD) ? 1 : 0);
     macroblock_2fbmv.header.dw1.h263_4mv = 0;   /* should be 0 */
     macroblock_2fbmv.header.dw1.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD);
-    
+
     if (!(mb->coded_block_pattern & 0x3f))
         macroblock_2fbmv.header.dw1.dct_type = XVMC_DCT_TYPE_FRAME;
 
@@ -648,7 +612,7 @@ 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));
@@ -727,13 +691,13 @@ static void i915_inst_arith(unsigned int *inst,
     *inst = (A2_SRC1(src1) | A2_SRC2(src2));
 }
 
-static void i915_inst_decl(unsigned int *inst, 
+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;
@@ -797,7 +761,7 @@ static void i915_mc_pixel_shader_program_buffer(XvMCContext *context)
     i915_inst_decl(inst, REG_TYPE_S, 0, D0_SAMPLE_TYPE_2D);
     /* texld r0, t0, s0 */
     inst += 3;
-    dest = UREG(REG_TYPE_R, 0); 
+    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);
@@ -828,7 +792,7 @@ static void i915_mc_pixel_shader_program_buffer(XvMCContext *context)
     i915_inst_decl(inst, REG_TYPE_S, 1, D0_SAMPLE_TYPE_2D);
     /* texld r0, t2, s1 */
     inst += 3;
-    dest = UREG(REG_TYPE_R, 0); 
+    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);
@@ -868,13 +832,13 @@ static void i915_mc_pixel_shader_program_buffer(XvMCContext *context)
     i915_inst_decl(inst, REG_TYPE_S, 1, D0_SAMPLE_TYPE_2D);
     /* texld r0, t0, s0 */
     inst += 3;
-    dest = UREG(REG_TYPE_R, 0); 
+    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); 
+    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);
@@ -1007,7 +971,7 @@ static void i915_mc_one_time_state_initialization(XvMCContext *context)
     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
@@ -1217,7 +1181,7 @@ static void i915_xvmc_unmap_buffers(i915XvMCContext *pI915XvMC)
 }
 
 /*
- * Video post processing 
+ * Video post processing
  */
 static void i915_yuv2rgb_map_state_buffer(XvMCSurface *target_surface)
 {
@@ -1299,7 +1263,7 @@ static void i915_yuv2rgb_sampler_state_buffer(XvMCSurface *surface)
     struct texture_sampler *ts;
     i915XvMCSurface *privSurface = (i915XvMCSurface *)surface->privData;
     i915XvMCContext *pI915XvMC = (i915XvMCContext *)privSurface->privContext;
-    
+
     /* 3DSATE_SAMPLER_STATE */
     sampler_state = (struct i915_3dstate_sampler_state *)pI915XvMC->ssb.map;
     memset(sampler_state, 0, sizeof(*sampler_state));
@@ -1391,7 +1355,7 @@ static void i915_yuv2rgb_sampler_state_buffer(XvMCSurface *surface)
 }
 
 static void i915_yuv2rgb_static_indirect_state_buffer(XvMCSurface *surface,
-                                                      unsigned int dstaddr, 
+                                                      unsigned int dstaddr,
                                                       int dstpitch)
 {
     struct i915_3dstate_buffer_info *buffer_info;
@@ -1407,7 +1371,7 @@ static void i915_yuv2rgb_static_indirect_state_buffer(XvMCSurface *surface,
     buffer_info->dw0.length = 1;
     buffer_info->dw1.aux_id = 0;
     buffer_info->dw1.buffer_id = BUFFERID_COLOR_BACK;
-    buffer_info->dw1.fence_regs = 1;   
+    buffer_info->dw1.fence_regs = 1;
     buffer_info->dw1.tiled_surface = 0;   /* linear */
     buffer_info->dw1.walk = TILEWALK_XMAJOR;
     buffer_info->dw1.pitch = dstpitch;
@@ -1456,13 +1420,13 @@ static void i915_yuv2rgb_pixel_shader_program_buffer(XvMCSurface *surface)
     i915_inst_decl(inst, REG_TYPE_S, 2, D0_SAMPLE_TYPE_2D);
     /* texld    r0 t1 s0 */
     inst += 3;
-    dest = UREG(REG_TYPE_R, 0); 
+    dest = UREG(REG_TYPE_R, 0);
     src0 = UREG(REG_TYPE_T, 1); /* COORD */
     src1 = UREG(REG_TYPE_S, 0); /* SAMPLER */
     i915_inst_texld(inst, T0_TEXLD, dest, src0, src1);
     /* texld    r0 t0 s1 */
     inst += 3;
-    dest = UREG(REG_TYPE_R, 0); 
+    dest = UREG(REG_TYPE_R, 0);
     src0 = UREG(REG_TYPE_T, 0); /* COORD */
     src1 = UREG(REG_TYPE_S, 1); /* SAMPLER */
     i915_inst_texld(inst, T0_TEXLD, dest, src0, src1);
@@ -1530,7 +1494,7 @@ static void i915_yuv2rgb_proc(XvMCSurface *surface)
     s4->fog_shade_mode = SHADEMODE_FLAT;
     s4->alpha_shade_mode = SHADEMODE_FLAT;
     s4->line_width = 0x2;     /* FIXME: 1.0??? */
-    s4->point_width = 0x1; 
+    s4->point_width = 0x1;
 
     s5 = (struct s5_dword *)(++s4);
     s6 = (struct s6_dword *)(++s5);
@@ -1573,14 +1537,14 @@ static void i915_yuv2rgb_proc(XvMCSurface *surface)
     ssb = (ssb_state *)(++sis);
     ssb->dw0.valid = 1;
     ssb->dw0.buffer_address = pI915XvMC->ssb.offset;
-    ssb->dw1.length = ((sizeof(struct i915_3dstate_sampler_state) + 
+    ssb->dw1.length = ((sizeof(struct i915_3dstate_sampler_state) +
                         sizeof(struct texture_sampler) * 3) >> 2) - 1;
 
     /* MSB */
     msb = (msb_state *)(++ssb);
     msb->dw0.valid = 1;
     msb->dw0.buffer_address = pI915XvMC->msb.offset;
-    msb->dw1.length = ((sizeof(struct i915_3dstate_map_state) + 
+    msb->dw1.length = ((sizeof(struct i915_3dstate_map_state) +
                         sizeof(struct texture_map) * 3) >> 2) - 1;
 
     /* PSP */
@@ -1631,11 +1595,9 @@ static void i915_yuv2rgb_proc(XvMCSurface *surface)
     free(base);
 }
 
-/***************************************************************************
-// Function: i915_release_resource
-// Description:
-***************************************************************************/
-//XXX
+/*
+ * Function: i915_release_resource
+ */
 static void i915_release_resource(Display *display, XvMCContext *context)
 {
     i915XvMCContext *pI915XvMC;
@@ -1792,16 +1754,6 @@ static Status i915_xvmc_mc_create_context(Display *display, XvMCContext *context
     return Success;
 }
 
-/***************************************************************************
-// Function: XvMCDestroyContext
-// Description: Destorys the specified context.
-//
-// Arguments:
-//   display - Specifies the connection to the server.
-//   context - The context to be destroyed.
-//
-// Returns: Status
-***************************************************************************/
 static int i915_xvmc_mc_destroy_context(Display *display, XvMCContext *context)
 {
     i915XvMCContext *pI915XvMC;
@@ -1814,10 +1766,8 @@ static int i915_xvmc_mc_destroy_context(Display *display, XvMCContext *context)
     return Success;
 }
 
-/***************************************************************************
-// Function: XvMCCreateSurface
-***************************************************************************/
-static Status i915_xvmc_mc_create_surface(Display *display, XvMCContext *context, XvMCSurface *surface) 
+static Status i915_xvmc_mc_create_surface(Display *display,
+	XvMCContext *context, XvMCSurface *surface)
 {
     Status ret;
     i915XvMCContext *pI915XvMC;
@@ -1901,10 +1851,7 @@ static Status i915_xvmc_mc_create_surface(Display *display, XvMCContext *context
 }
 
 
-/***************************************************************************
-// Function: XvMCDestroySurface
-***************************************************************************/
-static int i915_xvmc_mc_destroy_surface(Display *display, XvMCSurface *surface) 
+static int i915_xvmc_mc_destroy_surface(Display *display, XvMCSurface *surface)
 {
     i915XvMCSurface *pI915Surface;
     i915XvMCContext *pI915XvMC;
@@ -1936,12 +1883,6 @@ static int i915_xvmc_mc_destroy_surface(Display *display, XvMCSurface *surface)
 }
 
 
-/***************************************************************************
-// Function: XvMCRenderSurface
-// Description: This function does the actual HWMC. Given a list of
-//  macroblock structures it dispatched the hardware commands to execute
-//  them. 
-***************************************************************************/
 static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context,
                          unsigned int picture_structure,
                          XvMCSurface *target_surface,
@@ -2009,7 +1950,6 @@ static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context,
             XVMC_ERR("Invalid Past Surface!");
             return (error_base + XvMCBadSurface);
         }
-        
         picture_coding_type = MPEG_P_PICTURE;
     }
 
@@ -2057,7 +1997,7 @@ static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context,
             mb->coded_block_pattern = 0;
             XVMC_INFO("no coded blocks present!");
         }
-        
+
         bspm = mb_bytes[mb->coded_block_pattern];
 
         if (!bspm)
@@ -2071,10 +2011,10 @@ static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context,
         }
         memcpy(corrdata_ptr, block_ptr, bspm);
         corrdata_ptr += bspm;
-    } 
+    }
 
     i915_flush(1, 0);
-    // i915_mc_invalidate_subcontext_buffers(context, BLOCK_SIS | BLOCK_DIS | BLOCK_SSB 
+    // i915_mc_invalidate_subcontext_buffers(context, BLOCK_SIS | BLOCK_DIS | BLOCK_SSB
     // | BLOCK_MSB | BLOCK_PSP | BLOCK_PSC);
 
     i915_mc_sampler_state_buffer(context);
@@ -2082,7 +2022,7 @@ static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context,
     i915_mc_pixel_shader_constants_buffer(context);
     i915_mc_one_time_state_initialization(context);
 
-    i915_mc_static_indirect_state_buffer(context, target_surface, 
+    i915_mc_static_indirect_state_buffer(context, target_surface,
                                          picture_structure, flags,
                                          picture_coding_type);
     i915_mc_map_state_buffer(context, privTarget, privPast, privFuture);
@@ -2095,7 +2035,8 @@ static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context,
         /* Intra Blocks */
         if (mb->macroblock_type & XVMC_MB_TYPE_INTRA) {
             i915_mc_mpeg_macroblock_ipicture(context, mb);
-        } else if ((picture_structure & XVMC_FRAME_PICTURE) == XVMC_FRAME_PICTURE) { /* Frame Picture */
+        } else if ((picture_structure & XVMC_FRAME_PICTURE) == XVMC_FRAME_PICTURE) {
+	    /* Frame Picture */
             switch (mb->motion_type & 3) {
             case XVMC_PREDICTION_FIELD: /* Field Based */
                 i915_mc_mpeg_macroblock_2fbmv(context, mb, picture_structure);
@@ -2110,9 +2051,9 @@ static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context,
                 break;
 
             default:    /* No Motion Type */
-                renderError();
+		XVMC_ERR("Invalid Macroblock Parameters found.");
                 break;
-            }   
+            }
         } else {        /* Frame Picture */
             switch (mb->motion_type & 3) {
             case XVMC_PREDICTION_FIELD: /* Field Based */
@@ -2122,13 +2063,13 @@ static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context,
             case XVMC_PREDICTION_16x8:  /* 16x8 MC */
                 i915_mc_mpeg_macroblock_2fbmv(context, mb, picture_structure);
                 break;
-                
+
             case XVMC_PREDICTION_DUAL_PRIME:    /* Dual Prime */
                 i915_mc_mpeg_macroblock_1fbmv(context, mb);
                 break;
 
             default:    /* No Motion Type */
-                renderError();
+		XVMC_ERR("Invalid Macroblock Parameters found.");
                 break;
             }
         }       /* Field Picture */
@@ -2142,44 +2083,12 @@ static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context,
     return 0;
 }
 
-/***************************************************************************
-// Function: XvMCPutSurface
-// Description:
-// Arguments:
-//  display: Connection to X server
-//  surface: Surface to be displayed
-//  draw: X Drawable on which to display the surface
-//  srcx: X coordinate of the top left corner of the region to be
-//          displayed within the surface.
-//  srcy: Y coordinate of the top left corner of the region to be
-//          displayed within the surface.
-//  srcw: Width of the region to be displayed.
-//  srch: Height of the region to be displayed.
-//  destx: X cordinate of the top left corner of the destination region
-//         in the drawable coordinates.
-//  desty: Y cordinate of the top left corner of the destination region
-//         in the drawable coordinates.
-//  destw: Width of the destination region.
-//  desth: Height of the destination region.
-//  flags: One or more of the following.
-//     XVMC_TOP_FIELD - Display only the Top field of the surface.
-//     XVMC_BOTTOM_FIELD - Display only the Bottom Field of the surface.
-//     XVMC_FRAME_PICTURE - Display both fields or frame.
-//
-// Info: Portions of this function derived from i915_video.c (XFree86)
-//
-//   This function is organized so that we wait as long as possible before
-//   touching the overlay registers. Since we don't know that the last
-//   flip has happened yet we want to give the overlay as long as
-//   possible to catch up before we have to check on its progress. This
-//   makes it unlikely that we have to wait on the last flip.
-***************************************************************************/
 static int i915_xvmc_mc_put_surface(Display *display,XvMCSurface *surface,
                       Drawable draw, short srcx, short srcy,
                       unsigned short srcw, unsigned short srch,
                       short destx, short desty,
                       unsigned short destw, unsigned short desth,
-                      int flags) 
+                      int flags)
 {
     i915XvMCContext *pI915XvMC;
     i915XvMCSurface *pI915Surface;
@@ -2243,63 +2152,15 @@ static int i915_xvmc_mc_put_surface(Display *display,XvMCSurface *surface,
     return 0;
 }
 
-/***************************************************************************
-// Function: XvMCSyncSurface
-// Arguments:
-//   display - Connection to the X server
-//   surface - The surface to synchronize
-// Info:
-// Returns: Status
-***************************************************************************/
-#if 0
-Status XvMCSyncSurface(Display *display, XvMCSurface *surface) 
-{
-    Status ret;
-    int stat = 0;
-
-    do {
-        ret = XvMCGetSurfaceStatus(display, surface, &stat);
-    } while (!ret && (stat & XVMC_RENDERING));
-
-    return ret;
-}
-
-/***************************************************************************
-// Function: XvMCFlushSurface
-// Description:
-//   This function commits pending rendering requests to ensure that they
-//   wll be completed in a finite amount of time.
-// Arguments:
-//   display - Connection to X server
-//   surface - Surface to flush
-// Returns: Status
-***************************************************************************/
-Status XvMCFlushSurface(Display * display, XvMCSurface *surface) 
-{
-    return Success;
-}
-#endif
-
-/***************************************************************************
-// Function: XvMCGetSurfaceStatus
-// Description:
-// Arguments:
-//  display: connection to X server
-//  surface: The surface to query
-//  stat: One of the Following
-//    XVMC_RENDERING - The last XvMCRenderSurface command has not
-//                     completed.
-//    XVMC_DISPLAYING - The surface is currently being displayed or a
-//                     display is pending.
-***************************************************************************/
-static int i915_xvmc_mc_get_surface_status(Display *display, XvMCSurface *surface, int *stat) 
+static int i915_xvmc_mc_get_surface_status(Display *display,
+	XvMCSurface *surface, int *stat)
 {
     i915XvMCSurface *pI915Surface;
     i915XvMCContext *pI915XvMC;
 
     if (!display || !surface || !stat)
         return BadValue;
-    
+
     *stat = 0;
 
     if (!(pI915Surface = surface->privData))
@@ -2343,23 +2204,9 @@ static int i915_xvmc_mc_get_surface_status(Display *display, XvMCSurface *surfac
     return 0;
 }
 
-/***************************************************************************
-// 
-//  Surface manipulation functions
-//
-***************************************************************************/
-
-/***************************************************************************
-// Function: XvMCHideSurface
-// Description: Stops the display of a surface.
-// Arguments:
-//   display - Connection to the X server.
-//   surface - surface to be hidden.
-//
-// Returns: Status
-***************************************************************************/
+/* XXX WIP code */
 #if 0
-Status XvMCHideSurface(Display *display, XvMCSurface *surface) 
+Status XvMCHideSurface(Display *display, XvMCSurface *surface)
 {
     i915XvMCSurface *pI915Surface;
     i915XvMCContext *pI915XvMC;
@@ -2391,32 +2238,10 @@ Status XvMCHideSurface(Display *display, XvMCSurface *surface)
     return Success;
 }
 
-/***************************************************************************
-//
-// Functions that deal with subpictures
-//
-***************************************************************************/
-
-
-
-/***************************************************************************
-// Function: XvMCCreateSubpicture
-// Description: This creates a subpicture by filling out the XvMCSubpicture
-//              structure passed to it and returning Success.
-// Arguments:
-//   display - Connection to the X server.
-//   context - The context to create the subpicture for.
-//   subpicture - Pre-allocated XvMCSubpicture structure to be filled in.
-//   width - of subpicture
-//   height - of subpicture
-//   xvimage_id - The id describing the XvImage format.
-//
-// Returns: Status
-***************************************************************************/
-Status XvMCCreateSubpicture(Display *display, XvMCContext *context,
+Status i915_xvmc_create_subpict(Display *display, XvMCContext *context,
                             XvMCSubpicture *subpicture,
                             unsigned short width, unsigned short height,
-                            int xvimage_id) 
+                            int xvimage_id)
 {
     Status ret;
     i915XvMCContext *pI915XvMC;
@@ -2427,7 +2252,7 @@ Status XvMCCreateSubpicture(Display *display, XvMCContext *context,
 
     if (!subpicture || !context || !display)
         return BadValue;
-  
+
     pI915XvMC = (i915XvMCContext *)context->privData;
 
     if (!pI915XvMC)
@@ -2460,7 +2285,7 @@ Status XvMCCreateSubpicture(Display *display, XvMCContext *context,
 
     if (priv_count != (sizeof(I915XvMCCreateSurfaceRec) >> 2)) {
         XVMC_ERR("_xvmc_create_subpicture() returned incorrect data size!");
-        XVMC_INFO("\tExpected %d, got %d", 
+        XVMC_INFO("\tExpected %d, got %d",
                (int)(sizeof(I915XvMCCreateSurfaceRec) >> 2), priv_count);
         XLockDisplay(display);
         _xvmc_destroy_subpicture(display, subpicture);
@@ -2524,22 +2349,10 @@ Status XvMCCreateSubpicture(Display *display, XvMCContext *context,
     return Success;
 }
 
-/***************************************************************************
-// Function: XvMCClearSubpicture
-// Description: Clear the area of the given subpicture to "color".
-//              structure passed to it and returning Success.
-// Arguments:
-//   display - Connection to the X server.
-//   subpicture - Subpicture to clear.
-//   x, y, width, height - rectangle in the subpicture to clear.
-//   color - The data to file the rectangle with.
-//
-// Returns: Status
-***************************************************************************/
-Status XvMCClearSubpicture(Display *display, XvMCSubpicture *subpicture,
+Status i915_xvmc_clear_subpict(Display *display, XvMCSubpicture *subpicture,
                            short x, short y,
                            unsigned short width, unsigned short height,
-                           unsigned int color) 
+                           unsigned int color)
 {
     i915XvMCContext *pI915XvMC;
     i915XvMCSubpicture *pI915Subpicture;
@@ -2564,26 +2377,11 @@ Status XvMCClearSubpicture(Display *display, XvMCSubpicture *subpicture,
     return Success;
 }
 
-/***************************************************************************
-// Function: XvMCCompositeSubpicture
-// Description: Composite the XvImae on the subpicture. This composit uses
-//              non-premultiplied alpha. Destination alpha is utilized
-//              except for with indexed subpictures. Indexed subpictures
-//              use a simple "replace".
-// Arguments:
-//   display - Connection to the X server.
-//   subpicture - Subpicture to clear.
-//   image - the XvImage to be used as the source of the composite.
-//   srcx, srcy, width, height - The rectangle from the image to be used.
-//   dstx, dsty - location in the subpicture to composite the source.
-//
-// Returns: Status
-***************************************************************************/
-Status XvMCCompositeSubpicture(Display *display, XvMCSubpicture *subpicture,
+Status i915_xvmc_composite_subpict(Display *display, XvMCSubpicture *subpicture,
                                XvImage *image,
                                short srcx, short srcy,
                                unsigned short width, unsigned short height,
-                               short dstx, short dsty) 
+                               short dstx, short dsty)
 {
     i915XvMCContext *pI915XvMC;
     i915XvMCSubpicture *pI915Subpicture;
@@ -2617,16 +2415,7 @@ Status XvMCCompositeSubpicture(Display *display, XvMCSubpicture *subpicture,
 }
 
 
-/***************************************************************************
-// Function: XvMCDestroySubpicture
-// Description: Destroys the specified subpicture.
-// Arguments:
-//   display - Connection to the X server.
-//   subpicture - Subpicture to be destroyed.
-//
-// Returns: Status
-***************************************************************************/
-Status XvMCDestroySubpicture(Display *display, XvMCSubpicture *subpicture) 
+Status i915_xvmc_destroy_subpict(Display *display, XvMCSubpicture *subpicture)
 {
     i915XvMCSubpicture *pI915Subpicture;
     i915XvMCContext *pI915XvMC;
@@ -2660,19 +2449,9 @@ Status XvMCDestroySubpicture(Display *display, XvMCSubpicture *subpicture)
 }
 
 
-/***************************************************************************
-// Function: XvMCSetSubpicturePalette
-// Description: Set the subpictures palette
-// Arguments:
-//   display - Connection to the X server.
-//   subpicture - Subpiture to set palette for.
-//   palette - A pointer to an array holding the palette data. The array
-//     is num_palette_entries * entry_bytes in size.
-// Returns: Status
-***************************************************************************/
-
-Status XvMCSetSubpicturePalette(Display *display, XvMCSubpicture *subpicture,
-                                unsigned char *palette) 
+Status i915_xvmc_set_subpict_palette(Display *display,
+	XvMCSubpicture *subpicture,
+	unsigned char *palette)
 {
     i915XvMCSubpicture *pI915Subpicture;
     int i, j;
@@ -2694,35 +2473,12 @@ Status XvMCSetSubpicturePalette(Display *display, XvMCSubpicture *subpicture,
     return Success;
 }
 
-/***************************************************************************
-// Function: XvMCBlendSubpicture
-// Description: 
-//    The behavior of this function is different depending on whether
-//    or not the XVMC_BACKEND_SUBPICTURE flag is set in the XvMCSurfaceInfo.
-//    i915 only support frontend behavior.
-//  
-//    XVMC_BACKEND_SUBPICTURE not set ("frontend" behavior):
-//   
-//    XvMCBlendSubpicture is a no-op in this case.
-//   
-// Arguments:
-//   display - Connection to the X server.
-//   subpicture - The subpicture to be blended into the video.
-//   target_surface - The surface to be displayed with the blended subpic.
-//   source_surface - Source surface prior to blending.
-//   subx, suby, subw, subh - The rectangle from the subpicture to use.
-//   surfx, surfy, surfw, surfh - The rectangle in the surface to blend
-//      blend the subpicture rectangle into. Scaling can ocure if 
-//      XVMC_SUBPICTURE_INDEPENDENT_SCALING is set.
-//
-// Returns: Status
-***************************************************************************/
-Status XvMCBlendSubpicture(Display *display, XvMCSurface *target_surface,
+Status i915_xvmc_blend_subpict(Display *display, XvMCSurface *target_surface,
                            XvMCSubpicture *subpicture,
                            short subx, short suby,
                            unsigned short subw, unsigned short subh,
                            short surfx, short surfy,
-                           unsigned short surfw, unsigned short surfh) 
+                           unsigned short surfw, unsigned short surfh)
 {
     i915XvMCSubpicture *pI915Subpicture;
     i915XvMCSurface *privTargetSurface;
@@ -2749,33 +2505,7 @@ Status XvMCBlendSubpicture(Display *display, XvMCSurface *target_surface,
     return Success;
 }
 
-/***************************************************************************
-// Function: XvMCBlendSubpicture2
-// Description: 
-//    The behavior of this function is different depending on whether
-//    or not the XVMC_BACKEND_SUBPICTURE flag is set in the XvMCSurfaceInfo.
-//    i915 only supports frontend blending.
-//  
-//    XVMC_BACKEND_SUBPICTURE not set ("frontend" behavior):
-//   
-//    XvMCBlendSubpicture2 blends the source_surface and subpicture and
-//    puts it in the target_surface.  This does not effect the status of
-//    the source surface but will cause the target_surface to query
-//    XVMC_RENDERING until the blend is completed.
-//   
-// Arguments:
-//   display - Connection to the X server.
-//   subpicture - The subpicture to be blended into the video.
-//   target_surface - The surface to be displayed with the blended subpic.
-//   source_surface - Source surface prior to blending.
-//   subx, suby, subw, subh - The rectangle from the subpicture to use.
-//   surfx, surfy, surfw, surfh - The rectangle in the surface to blend
-//      blend the subpicture rectangle into. Scaling can ocure if 
-//      XVMC_SUBPICTURE_INDEPENDENT_SCALING is set.
-//
-// Returns: Status
-***************************************************************************/
-Status XvMCBlendSubpicture2(Display *display, 
+Status i915_xvmc_blend_subpict2(Display *display,
                             XvMCSurface *source_surface,
                             XvMCSurface *target_surface,
                             XvMCSubpicture *subpicture,
@@ -2834,17 +2564,7 @@ Status XvMCBlendSubpicture2(Display *display,
     return Success;
 }
 
-/***************************************************************************
-// Function: XvMCSyncSubpicture
-// Description: This function blocks until all composite/clear requests on
-//              the subpicture have been complete.
-// Arguments:
-//   display - Connection to the X server.
-//   subpicture - The subpicture to synchronize
-//
-// Returns: Status
-***************************************************************************/
-Status XvMCSyncSubpicture(Display *display, XvMCSubpicture *subpicture) 
+Status i915_xvmc_sync_subpict(Display *display, XvMCSubpicture *subpicture)
 {
     Status ret;
     int stat = 0;
@@ -2859,18 +2579,7 @@ Status XvMCSyncSubpicture(Display *display, XvMCSubpicture *subpicture)
     return ret;
 }
 
-/***************************************************************************
-// Function: XvMCFlushSubpicture
-// Description: This function commits pending composite/clear requests to
-//              ensure that they will be completed in a finite amount of
-//              time.
-// Arguments:
-//   display - Connection to the X server.
-//   subpicture - The subpicture whos compsiting should be flushed
-//
-// Returns: Status
-***************************************************************************/
-Status XvMCFlushSubpicture(Display *display, XvMCSubpicture *subpicture) 
+Status i915_xvmc_flush_subpict(Display *display, XvMCSubpicture *subpicture)
 {
     i915XvMCSubpicture *pI915Subpicture;
 
@@ -2883,22 +2592,8 @@ Status XvMCFlushSubpicture(Display *display, XvMCSubpicture *subpicture)
     return Success;
 }
 
-/***************************************************************************
-// Function: XvMCGetSubpictureStatus
-// Description: This function gets the current status of a subpicture
-//
-// Arguments:
-//   display - Connection to the X server.
-//   subpicture - The subpicture whos status is being queried
-//   stat - The status of the subpicture. It can be any of the following
-//          OR'd together:
-//          XVMC_RENDERING  - Last composite or clear request not completed
-//          XVMC_DISPLAYING - Suppicture currently being displayed.
-//
-// Returns: Status
-***************************************************************************/
-Status XvMCGetSubpictureStatus(Display *display, XvMCSubpicture *subpicture,
-                               int *stat) 
+Status i915_xvmc_get_subpict_status(Display *display, XvMCSubpicture *subpicture,
+                               int *stat)
 {
     i915XvMCSubpicture *pI915Subpicture;
     i915XvMCContext *pI915XvMC;
@@ -2928,3 +2623,16 @@ Status XvMCGetSubpictureStatus(Display *display, XvMCSubpicture *subpicture,
 }
 
 #endif
+
+struct _intel_xvmc_driver i915_xvmc_mc_driver = {
+    .type = XVMC_I915_MPEG2_MC,
+    .init = i915_xvmc_mc_init,
+    .fini = i915_xvmc_mc_fini,
+    .create_context = i915_xvmc_mc_create_context,
+    .destroy_context = i915_xvmc_mc_destroy_context,
+    .create_surface = i915_xvmc_mc_create_surface,
+    .destroy_surface = i915_xvmc_mc_destroy_surface,
+    .render_surface = i915_xvmc_mc_render_surface,
+    .put_surface = i915_xvmc_mc_put_surface,
+    .get_surface_status = i915_xvmc_mc_get_surface_status,
+};
diff --git a/src/xvmc/i915_xvmc.h b/src/xvmc/i915_xvmc.h
index a470558..4c7aaa7 100644
--- a/src/xvmc/i915_xvmc.h
+++ b/src/xvmc/i915_xvmc.h
@@ -28,9 +28,6 @@
 #ifndef _I915XVMC_H
 #define _I915XVMC_H
 
-/* #define XVMC_DEBUG(x) do {x; }while(0); */
-#define XVMC_DEBUG(x)
-
 #include "intel_xvmc.h"
 #include "i915_hwmc.h"
 
@@ -46,9 +43,9 @@
 #define PCI_CHIP_Q35_G                  0x29B2
 #define PCI_CHIP_Q33_G                  0x29D2
 
-/***************************************************************************
-// i915XvMCDrmMap: Holds the data about the DRM maps
-***************************************************************************/
+/*
+ * i915XvMCDrmMap: Holds the data about the DRM maps
+ */
 typedef struct _i915XvMCDrmMap {
     drm_handle_t handle;
     unsigned long offset;
@@ -57,10 +54,11 @@ typedef struct _i915XvMCDrmMap {
     drmAddress map;
 } i915XvMCDrmMap, *i915XvMCDrmMapPtr;
 
-/***************************************************************************
-// i915XvMCContext: Private Context data referenced via the privData
-//  pointer in the XvMCContext structure.
-***************************************************************************/
+/*
+ * i915XvMCContext:
+ *	Private Context data referenced via the privData
+ *      pointer in the XvMCContext structure.
+ */
 typedef struct _i915XvMCContext {
     unsigned int ctxno;
     unsigned int last_flip;
@@ -92,11 +90,12 @@ typedef struct _i915XvMCContext {
     i915XvMCDrmMap corrdata;
 } i915XvMCContext;
 
-/***************************************************************************
-// i915XvMCSubpicture: Private data structure for each XvMCSubpicture. This
-//  structure is referenced by the privData pointer in the XvMCSubpicture
-//  structure.
-***************************************************************************/
+/*
+ * i915XvMCSubpicture:
+ *  Private data structure for each XvMCSubpicture. This
+ *  structure is referenced by the privData pointer in the XvMCSubpicture
+ *  structure.
+ */
 typedef struct _i915XvMCSubpicture {
     unsigned int srfNo;
     unsigned int last_render;
@@ -107,12 +106,14 @@ typedef struct _i915XvMCSubpicture {
     i915XvMCContext *privContext;
 } i915XvMCSubpicture;
 
-/***************************************************************************
-// i915XvMCSurface: Private data structure for each XvMCSurface. This
-//  structure is referenced by the privData pointer in the XvMCSurface
-//  structure.
-***************************************************************************/
-#define I830_MAX_BUFS 2                   /*Number of YUV buffers per surface */
+/* Number of YUV buffers per surface */
+#define I830_MAX_BUFS 2
+
+/*
+ * i915XvMCSurface: Private data structure for each XvMCSurface. This
+ *  structure is referenced by the privData pointer in the XvMCSurface
+ *  structure.
+ */
 typedef struct _i915XvMCSurface {
     unsigned int srfNo;                    /* XvMC private surface numbers */
     unsigned int last_render;
commit 1ff97991a4954d508cc260dda82b7678010d13c9
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Thu Nov 15 17:01:31 2007 +0800

    xvmc: intel_xvmc.c cleanups

diff --git a/src/xvmc/intel_xvmc.c b/src/xvmc/intel_xvmc.c
index 21eb607..164b4b2 100644
--- a/src/xvmc/intel_xvmc.c
+++ b/src/xvmc/intel_xvmc.c
@@ -70,7 +70,7 @@ void UNLOCK_HARDWARE(drm_context_t ctx)
 *   height - Height of the surfaces.
 *   flags - one or more of the following
 *      XVMC_DIRECT - A direct rendered context is requested.
-
+*
 * Notes: surface_type_id and width/height parameters must match those
 *        returned by XvMCListSurfaceTypes.
 * Returns: Status
@@ -244,16 +244,15 @@ Status XvMCCreateContext(Display *display, XvPortID port,
     return Success;
 }
 
-/***************************************************************************
-// Function: XvMCDestroyContext
-// Description: Destorys the specified context.
-//
-// Arguments:
-//   display - Specifies the connection to the server.
-//   context - The context to be destroyed.
-//
-// Returns: Status
-***************************************************************************/
+/*
+ * Function: XvMCDestroyContext
+ * Description: Destorys the specified context.
+ *
+ * Arguments:
+ *   display - Specifies the connection to the server.
+ *   context - The context to be destroyed.
+ *
+ */
 Status XvMCDestroyContext(Display *display, XvMCContext *context)
 {
     Status ret;
@@ -274,17 +273,12 @@ Status XvMCDestroyContext(Display *display, XvMCContext *context)
     return Success;
 }
 
-/***************************************************************************
-// Function: XvMCCreateSurface
-***************************************************************************/
-Status XvMCCreateSurface(Display *display, XvMCContext *context, XvMCSurface *surface) 
+/*
+ * Function: XvMCCreateSurface
+ */
+Status XvMCCreateSurface(Display *display, XvMCContext *context, XvMCSurface *surface)
 {
     Status ret;
-//    i915XvMCContext *pI915XvMC;
-//    i915XvMCSurface *pI915Surface;
-//    I915XvMCCreateSurfaceRec *tmpComm = NULL;
-//    int priv_count;
-//    uint *priv_data;
 
     if (!display || !context)
         return XvMCBadContext;
@@ -298,125 +292,29 @@ Status XvMCCreateSurface(Display *display, XvMCContext *context, XvMCSurface *su
 	return ret;
     }
 
-#if 0
-    if (!(pI915XvMC = context->privData))
-        return (error_base + XvMCBadContext);
-
-    PPTHREAD_MUTEX_LOCK(pI915XvMC);
-    surface->privData = (i915XvMCSurface *)malloc(sizeof(i915XvMCSurface));
-
-    if (!(pI915Surface = surface->privData)) {
-        PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
-        return BadAlloc;
-    }
-
-    /* Initialize private values */
-    pI915Surface->last_render = 0;
-    pI915Surface->last_flip = 0;
-    pI915Surface->yStride = pI915XvMC->yStride;
-    pI915Surface->uvStride = pI915XvMC->uvStride;
-    pI915Surface->width = context->width;
-    pI915Surface->height = context->height;
-    pI915Surface->privContext = pI915XvMC;
-    pI915Surface->privSubPic = NULL;
-    pI915Surface->srf.map = NULL;
-    XLockDisplay(display);
-
-    if ((ret = _xvmc_create_surface(display, context, surface,
-                                    &priv_count, &priv_data))) {
-        XUnlockDisplay(display);
-        XVMC_ERR("Unable to create XvMCSurface.");
-        free(pI915Surface);
-        surface->privData = NULL;
-        PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
-        return ret;
-    }
-
-    XUnlockDisplay(display);
-
-    if (priv_count != (sizeof(I915XvMCCreateSurfaceRec) >> 2)) {
-        XVMC_ERR("_xvmc_create_surface() returned incorrect data size!");
-        XVMC_INFO("\tExpected %d, got %d",
-               (int)(sizeof(I915XvMCCreateSurfaceRec) >> 2), priv_count);
-        _xvmc_destroy_surface(display, surface);
-        free(priv_data);
-        free(pI915Surface);
-        surface->privData = NULL;
-        PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
-        return BadAlloc;
-    }
-
-    tmpComm = (I915XvMCCreateSurfaceRec *)priv_data;
-
-    pI915Surface->srfNo = tmpComm->srfno;
-    pI915Surface->srf.handle = tmpComm->srf.handle;
-    pI915Surface->srf.offset = tmpComm->srf.offset;
-    pI915Surface->srf.size = tmpComm->srf.size;
-    free(priv_data);
-
-    if (drmMap(pI915XvMC->fd,
-               pI915Surface->srf.handle,
-               pI915Surface->srf.size,
-               (drmAddress *)&pI915Surface->srf.map) != 0) {
-        _xvmc_destroy_surface(display, surface);
-        free(pI915Surface);
-        surface->privData = NULL;
-        PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
-        return BadAlloc;
-    }
-
-    pI915XvMC->ref++;
-    PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
-#endif
-
     return Success;
 }
 
 
-/***************************************************************************
-// Function: XvMCDestroySurface
-***************************************************************************/
-Status XvMCDestroySurface(Display *display, XvMCSurface *surface) 
+/*
+ * Function: XvMCDestroySurface
+ */
+Status XvMCDestroySurface(Display *display, XvMCSurface *surface)
 {
-//    i915XvMCSurface *pI915Surface;
-//    i915XvMCContext *pI915XvMC;
-
     if (!display || !surface)
         return XvMCBadSurface;
 
     (xvmc_driver->destroy_surface)(display, surface);
 
-#if 0
-    if (!(pI915Surface = surface->privData))
-        return (error_base + XvMCBadSurface);
-
-    if (!(pI915XvMC = pI915Surface->privContext))
-        return (error_base + XvMCBadSurface);
-
-    if (pI915Surface->last_flip)
-        XvMCSyncSurface(display,surface);
-
-    if (pI915Surface->srf.map)
-        drmUnmap(pI915Surface->srf.map, pI915Surface->srf.size);
-
-    XLockDisplay(display);
-    _xvmc_destroy_surface(display, surface);
-    XUnlockDisplay(display);
-
-    free(pI915Surface);
-    surface->privData = NULL;
-    pI915XvMC->ref--;
-#endif
-
     return Success;
 }
 
-/***************************************************************************
-// Function: XvMCCreateBlocks
-***************************************************************************/
+/*
+ * Function: XvMCCreateBlocks
+ */
 Status XvMCCreateBlocks(Display *display, XvMCContext *context,
-                        unsigned int num_blocks, 
-                        XvMCBlockArray *block) 
+                        unsigned int num_blocks,
+                        XvMCBlockArray *block)
 {
     if (!display || !context || !num_blocks || !block)
         return BadValue;
@@ -433,10 +331,10 @@ Status XvMCCreateBlocks(Display *display, XvMCContext *context,
     return Success;
 }
 
-/***************************************************************************
-// Function: XvMCDestroyBlocks
-***************************************************************************/
-Status XvMCDestroyBlocks(Display *display, XvMCBlockArray *block) 
+/*
+ * Function: XvMCDestroyBlocks
+ */
+Status XvMCDestroyBlocks(Display *display, XvMCBlockArray *block)
 {
     if (!display || block)
         return BadValue;
@@ -452,12 +350,12 @@ Status XvMCDestroyBlocks(Display *display, XvMCBlockArray *block)
     return Success;
 }
 
-/***************************************************************************
-// Function: XvMCCreateMacroBlocks
-***************************************************************************/
+/*
+ * Function: XvMCCreateMacroBlocks
+ */
 Status XvMCCreateMacroBlocks(Display *display, XvMCContext *context,
                              unsigned int num_blocks,
-                             XvMCMacroBlockArray *blocks) 
+                             XvMCMacroBlockArray *blocks)
 {
     if (!display || !context || !blocks || !num_blocks)
         return BadValue;
@@ -475,10 +373,10 @@ Status XvMCCreateMacroBlocks(Display *display, XvMCContext *context,
     return Success;
 }
 
-/***************************************************************************
-// Function: XvMCDestroyMacroBlocks
-***************************************************************************/
-Status XvMCDestroyMacroBlocks(Display *display, XvMCMacroBlockArray *block) 
+/*
+ * Function: XvMCDestroyMacroBlocks
+ */
+Status XvMCDestroyMacroBlocks(Display *display, XvMCMacroBlockArray *block)
 {
     if (!display || !block)
         return BadValue;
@@ -493,12 +391,13 @@ Status XvMCDestroyMacroBlocks(Display *display, XvMCMacroBlockArray *block)
     return Success;
 }
 
-/***************************************************************************
-// Function: XvMCRenderSurface
-// Description: This function does the actual HWMC. Given a list of
-//  macroblock structures it dispatched the hardware commands to execute
-//  them. 
-***************************************************************************/
+/*
+ * Function: XvMCRenderSurface
+ *
+ * Description: This function does the actual HWMC. Given a list of
+ *  macroblock structures it dispatched the hardware commands to execute
+ *  them.
+ */
 Status XvMCRenderSurface(Display *display, XvMCContext *context,
                          unsigned int picture_structure,
                          XvMCSurface *target_surface,
@@ -528,229 +427,34 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context,
 	XVMC_ERR("render surface fail\n");
 	return ret;
     }
-#if 0
-    int i;
-    int picture_coding_type = MPEG_I_PICTURE;
-    /* correction data buffer */
-    char *corrdata_ptr;
-    int corrdata_size = 0;
-
-    /* Block Pointer */
-    short *block_ptr;
-    /* Current Macroblock Pointer */
-    XvMCMacroBlock *mb;
-
-    i915XvMCSurface *privTarget = NULL;
-    i915XvMCSurface *privFuture = NULL;
-    i915XvMCSurface *privPast = NULL;
-    i915XvMCContext *pI915XvMC = NULL;
-
-    /* Check Parameters for validity */
-    if (!display || !context || !target_surface) {
-        XVMC_ERR("Invalid Display, Context or Target!");
-        return BadValue;
-    }
-
-    if (!num_macroblocks)
-        return Success;
-
-    if (!macroblock_array || !blocks) {
-        XVMC_ERR("Invalid block data!");
-        return BadValue;
-    }
-
-    if (macroblock_array->num_blocks < (num_macroblocks + first_macroblock)) {
-        XVMC_ERR("Too many macroblocks requested for MB array size.");
-        return BadValue;
-    }
-
-    if (!(pI915XvMC = context->privData))
-        return (error_base + XvMCBadContext);
-
-    if (!(privTarget = target_surface->privData))
-        return (error_base + XvMCBadSurface);
-
-    /* Test For YV12 Surface */
-    if (context->surface_type_id != FOURCC_YV12) {
-        XVMC_ERR("HWMC only possible on YV12 Surfaces.");
-        return BadValue;
-    }
-
-    /* P Frame Test */
-    if (!past_surface) {
-        /* Just to avoid some ifs later. */
-        privPast = privTarget;
-    } else {
-        if (!(privPast = past_surface->privData)) {
-            XVMC_ERR("Invalid Past Surface!");
-            return (error_base + XvMCBadSurface);
-        }
-        
-        picture_coding_type = MPEG_P_PICTURE;
-    }
-
-    /* B Frame Test */
-    if (!future_surface) {
-        privFuture = privPast; // privTarget;
-    } else {
-        if (!past_surface) {
-            XVMC_ERR("No Past Surface!");
-            return BadValue;
-        }
-
-        if (!(privFuture = future_surface->privData)) {
-            XVMC_ERR("Invalid Future Surface!");
-            return (error_base + XvMCBadSurface);
-        }
-
-        picture_coding_type = MPEG_B_PICTURE;
-    }
-
-    LOCK_HARDWARE(pI915XvMC);
-    corrdata_ptr = pI915XvMC->corrdata.map;
-    corrdata_size = 0;
-
-    for (i = first_macroblock; i < (num_macroblocks + first_macroblock); i++) {
-        int bspm = 0;
-        mb = &macroblock_array->macro_blocks[i];
-        block_ptr = &(blocks->blocks[mb->index << 6]);
-
-        /* Lockup can happen if the coordinates are too far out of range */
-        if (mb->x > (target_surface->width >> 4)) {
-            mb->x = 0;
-            XVMC_INFO("reset x");
-        }
-
-        if (mb->y > (target_surface->height >> 4)) {
-            mb->y = 0;
-            XVMC_INFO("reset y");
-        }
-
-        /* Catch no pattern case */
-        if (!(mb->macroblock_type & XVMC_MB_TYPE_PATTERN) &&
-            !(mb->macroblock_type & XVMC_MB_TYPE_INTRA) &&
-            mb->coded_block_pattern) {
-            mb->coded_block_pattern = 0;
-            XVMC_INFO("no coded blocks present!");
-        }
-        
-        bspm = mb_bytes[mb->coded_block_pattern];
-
-        if (!bspm)
-            continue;
-
-        corrdata_size += bspm;
-
-        if (corrdata_size > pI915XvMC->corrdata.size) {
-            XVMC_ERR("correction data buffer overflow.");
-            break;
-        }
-        memcpy(corrdata_ptr, block_ptr, bspm);
-        corrdata_ptr += bspm;
-    } 
-
-    i915_flush(pI915XvMC, 1, 0);
-    // 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_static_indirect_state_buffer(context, target_surface, 
-                                         picture_structure, flags,
-                                         picture_coding_type);
-    i915_mc_map_state_buffer(context, privTarget, privPast, privFuture);
-    i915_mc_load_sis_msb_buffers(context);
-    i915_mc_mpeg_set_origin(context, &macroblock_array->macro_blocks[first_macroblock]);
-
-    for (i = first_macroblock; i < (num_macroblocks + first_macroblock); i++) {
-        mb = &macroblock_array->macro_blocks[i];
-
-        /* Intra Blocks */
-        if (mb->macroblock_type & XVMC_MB_TYPE_INTRA) {
-            i915_mc_mpeg_macroblock_ipicture(context, mb);
-        } else if ((picture_structure & XVMC_FRAME_PICTURE) == XVMC_FRAME_PICTURE) { /* Frame Picture */
-            switch (mb->motion_type & 3) {
-            case XVMC_PREDICTION_FIELD: /* Field Based */
-                i915_mc_mpeg_macroblock_2fbmv(context, mb, picture_structure);
-                break;
-
-            case XVMC_PREDICTION_FRAME: /* Frame Based */
-                i915_mc_mpeg_macroblock_1fbmv(context, mb);
-                break;
-
-            case XVMC_PREDICTION_DUAL_PRIME:    /* Dual Prime */
-                i915_mc_mpeg_macroblock_2fbmv(context, mb, picture_structure);
-                break;
-
-            default:    /* No Motion Type */
-                renderError();
-                break;
-            }   
-        } else {        /* Frame Picture */
-            switch (mb->motion_type & 3) {
-            case XVMC_PREDICTION_FIELD: /* Field Based */
-                i915_mc_mpeg_macroblock_1fbmv(context, mb);
-                break;
-
-            case XVMC_PREDICTION_16x8:  /* 16x8 MC */
-                i915_mc_mpeg_macroblock_2fbmv(context, mb, picture_structure);
-                break;
-                
-            case XVMC_PREDICTION_DUAL_PRIME:    /* Dual Prime */
-                i915_mc_mpeg_macroblock_1fbmv(context, mb);
-                break;
-
-            default:    /* No Motion Type */
-                renderError();
-                break;
-            }
-        }       /* Field Picture */
-    }
-
-    intelFlushBatch(TRUE);
-    pI915XvMC->last_render = pI915XvMC->alloc.irq_emitted;
-    privTarget->last_render = pI915XvMC->last_render;
-
-    UNLOCK_HARDWARE(pI915XvMC);
-#endif
     return Success;
 }
 
-/***************************************************************************
-// Function: XvMCPutSurface
-// Description:
-// Arguments:
-//  display: Connection to X server
-//  surface: Surface to be displayed
-//  draw: X Drawable on which to display the surface
-//  srcx: X coordinate of the top left corner of the region to be
-//          displayed within the surface.
-//  srcy: Y coordinate of the top left corner of the region to be
-//          displayed within the surface.
-//  srcw: Width of the region to be displayed.
-//  srch: Height of the region to be displayed.
-//  destx: X cordinate of the top left corner of the destination region
-//         in the drawable coordinates.
-//  desty: Y cordinate of the top left corner of the destination region
-//         in the drawable coordinates.
-//  destw: Width of the destination region.
-//  desth: Height of the destination region.
-//  flags: One or more of the following.
-//     XVMC_TOP_FIELD - Display only the Top field of the surface.
-//     XVMC_BOTTOM_FIELD - Display only the Bottom Field of the surface.
-//     XVMC_FRAME_PICTURE - Display both fields or frame.
-//
-// Info: Portions of this function derived from i915_video.c (XFree86)
-//
-//   This function is organized so that we wait as long as possible before
-//   touching the overlay registers. Since we don't know that the last
-//   flip has happened yet we want to give the overlay as long as
-//   possible to catch up before we have to check on its progress. This
-//   makes it unlikely that we have to wait on the last flip.
-***************************************************************************/
+/*
+ * Function: XvMCPutSurface
+ *
+ * Description:
+ * Arguments:
+ *  display: Connection to X server
+ *  surface: Surface to be displayed
+ *  draw: X Drawable on which to display the surface
+ *  srcx: X coordinate of the top left corner of the region to be
+ *          displayed within the surface.
+ *  srcy: Y coordinate of the top left corner of the region to be
+ *          displayed within the surface.
+ *  srcw: Width of the region to be displayed.
+ *  srch: Height of the region to be displayed.
+ *  destx: X cordinate of the top left corner of the destination region
+ *         in the drawable coordinates.
+ *  desty: Y cordinate of the top left corner of the destination region
+ *         in the drawable coordinates.
+ *  destw: Width of the destination region.
+ *  desth: Height of the destination region.
+ *  flags: One or more of the following.
+ *	XVMC_TOP_FIELD - Display only the Top field of the surface.
+ *	XVMC_BOTTOM_FIELD - Display only the Bottom Field of the surface.
+ *	XVMC_FRAME_PICTURE - Display both fields or frame.
+ */
 Status XvMCPutSurface(Display *display,XvMCSurface *surface,
                       Drawable draw, short srcx, short srcy,
                       unsigned short srcw, unsigned short srch,
@@ -770,79 +474,16 @@ Status XvMCPutSurface(Display *display,XvMCSurface *surface,
 	return ret;
     }
 
-#if 0
-    i915XvMCContext *pI915XvMC;
-    i915XvMCSurface *pI915Surface;
-    i915XvMCSubpicture *pI915SubPic;
-    I915XvMCCommandBuffer buf;
-
-    // drawableInfo *drawInfo;
-    Status ret;
-
-    if (!display || !surface)
-        return BadValue;
-
-    if (!(pI915Surface = surface->privData))
-        return (error_base + XvMCBadSurface);
-
-    if (!(pI915XvMC = pI915Surface->privContext))
-        return (error_base + XvMCBadSurface);
-
-    PPTHREAD_MUTEX_LOCK(pI915XvMC);
-    /*
-    if (getDRIDrawableInfoLocked(pI915XvMC->drawHash, display,
-                                 pI915XvMC->screen, draw, 0, pI915XvMC->fd, pI915XvMC->hHWContext,
-                                 pI915XvMC->sarea_address, FALSE, &drawInfo, sizeof(*drawInfo))) {
-        PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
-        return BadAccess;
-    }
-    */
-    if (!pI915XvMC->haveXv) {
-        pI915XvMC->xvImage =
-            XvCreateImage(display, pI915XvMC->port, FOURCC_XVMC,
-                          (char *)&buf, pI915Surface->width, pI915Surface->height);
-        pI915XvMC->gc = XCreateGC(display, draw, 0, 0);
-        pI915XvMC->haveXv = 1;
-    }
-
-    pI915XvMC->draw = draw;
-    pI915XvMC->xvImage->data = (char *)&buf;
-
-    buf.command = INTEL_XVMC_COMMAND_DISPLAY;
-    buf.ctxNo = pI915XvMC->ctxno;
-    buf.srfNo = pI915Surface->srfNo;
-    pI915SubPic = pI915Surface->privSubPic;
-    buf.subPicNo = (!pI915SubPic ? 0 : pI915SubPic->srfNo);
-    buf.real_id = FOURCC_YV12;
-
-    XLockDisplay(display);
-
-    if ((ret = XvPutImage(display, pI915XvMC->port, draw, pI915XvMC->gc,
-                          pI915XvMC->xvImage, srcx, srcy, srcw, srch,
-                          destx, desty, destw, desth))) {
-        XUnlockDisplay(display);
-        PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
-
-        return ret;
-    }
-
-    XSync(display, 0);
-    XUnlockDisplay(display);
-    PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
-#endif
-
     return Success;
 }
 
-/***************************************************************************
-// Function: XvMCSyncSurface
-// Arguments:
-//   display - Connection to the X server
-//   surface - The surface to synchronize
-// Info:
-// Returns: Status
-***************************************************************************/
-Status XvMCSyncSurface(Display *display, XvMCSurface *surface) 
+/*
+ * Function: XvMCSyncSurface
+ * Arguments:
+ *   display - Connection to the X server
+ *   surface - The surface to synchronize
+ */
+Status XvMCSyncSurface(Display *display, XvMCSurface *surface)
 {
     Status ret;
     int stat = 0;
@@ -857,36 +498,36 @@ Status XvMCSyncSurface(Display *display, XvMCSurface *surface)
     return ret;
 }
 
-/***************************************************************************
-// Function: XvMCFlushSurface
-// Description:
-//   This function commits pending rendering requests to ensure that they
-//   wll be completed in a finite amount of time.
-// Arguments:
-//   display - Connection to X server
-//   surface - Surface to flush
-// Returns: Status
-***************************************************************************/
-Status XvMCFlushSurface(Display * display, XvMCSurface *surface) 
+/*
+ * Function: XvMCFlushSurface
+ * Description:
+ *   This function commits pending rendering requests to ensure that they
+ *   wll be completed in a finite amount of time.
+ * Arguments:
+ *   display - Connection to X server
+ *   surface - Surface to flush
+ * Returns: Status
+ */
+Status XvMCFlushSurface(Display * display, XvMCSurface *surface)
 {
     if (!display || !surface)
 	return XvMCBadSurface;
     return Success;
 }
 
-/***************************************************************************
-// Function: XvMCGetSurfaceStatus
-// Description:
-// Arguments:
-//  display: connection to X server
-//  surface: The surface to query
-//  stat: One of the Following
-//    XVMC_RENDERING - The last XvMCRenderSurface command has not
-//                     completed.
-//    XVMC_DISPLAYING - The surface is currently being displayed or a
-//                     display is pending.
-***************************************************************************/
-Status XvMCGetSurfaceStatus(Display *display, XvMCSurface *surface, int *stat) 
+/*
+ * Function: XvMCGetSurfaceStatus
+ * Description:
+ * Arguments:
+ *  display: connection to X server
+ *  surface: The surface to query
+ *  stat: One of the Following
+ *    XVMC_RENDERING - The last XvMCRenderSurface command has not
+ *                     completed.
+ *    XVMC_DISPLAYING - The surface is currently being displayed or a
+ *                     display is pending.
+ */
+Status XvMCGetSurfaceStatus(Display *display, XvMCSurface *surface, int *stat)
 {
     Status ret;
 
@@ -899,93 +540,26 @@ Status XvMCGetSurfaceStatus(Display *display, XvMCSurface *surface, int *stat)
 	return ret;
     }
 
-#if 0
-    i915XvMCSurface *pI915Surface;
-    i915XvMCContext *pI915XvMC;
-
-    if (!display || !surface || !stat)
-        return BadValue;
-    
-    *stat = 0;
-
-    if (!(pI915Surface = surface->privData))
-        return (error_base + XvMCBadSurface);
-
-    if (!(pI915XvMC = pI915Surface->privContext))
-        return (error_base + XvMCBadSurface);
-
-    // LOCK_HARDWARE(pI915XvMC);
-    PPTHREAD_MUTEX_LOCK(pI915XvMC);
-    if (pI915Surface->last_flip) {
-        /* This can not happen */
-        if (pI915XvMC->last_flip < pI915Surface->last_flip) {
-            XVMC_ERR("Context last flip is less than surface last flip.");
-            PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
-            return BadValue;
-        }
-
-        /*
-          If the context has 2 or more flips after this surface it
-          cannot be displaying. Don't bother to check.
-        */
-        if (!(pI915XvMC->last_flip > (pI915Surface->last_flip + 1))) {
-            /*
-              If this surface was the last flipped it is either displaying
-              or about to be so don't bother checking.
-            */
-            if (pI915XvMC->last_flip == pI915Surface->last_flip) {
-                *stat |= XVMC_DISPLAYING;
-            }
-        }
-    }
-
-    if (pI915Surface->last_render &&
-        (pI915Surface->last_render > pI915XvMC->sarea->last_dispatch)) {
-        *stat |= XVMC_RENDERING;
-    }
-
-    // UNLOCK_HARDWARE(pI915XvMC);
-    PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
-#endif
-
     return Success;
 }
 
-/***************************************************************************
-// 
-//  Surface manipulation functions
-//
-***************************************************************************/
-
-/***************************************************************************
-// Function: XvMCHideSurface
-// Description: Stops the display of a surface.
-// Arguments:
-//   display - Connection to the X server.
-//   surface - surface to be hidden.
-//
-// Returns: Status
-***************************************************************************/
-//XXX this seems broken now
-Status XvMCHideSurface(Display *display, XvMCSurface *surface) 
+/*
+ * Function: XvMCHideSurface
+ * Description: Stops the display of a surface.
+ * Arguments:
+ *   display - Connection to the X server.
+ *   surface - surface to be hidden.
+ *
+ * Returns: Status
+ */
+Status XvMCHideSurface(Display *display, XvMCSurface *surface)
 {
-//    i915XvMCSurface *pI915Surface;
-//    i915XvMCContext *pI915XvMC;
     int stat = 0;
     Status ret;
 
     if (!display || !surface)
         return XvMCBadSurface;
 
-#if 0
-    if (!(pI915Surface = surface->privData))
-        return (error_base + XvMCBadSurface);
-
-    /* Get the associated context pointer */
-    if (!(pI915XvMC = pI915Surface->privContext))
-        return (error_base + XvMCBadSurface);
-#endif
-
     XvMCSyncSurface(display, surface);
 
     /*
@@ -999,176 +573,174 @@ Status XvMCHideSurface(Display *display, XvMCSurface *surface)
         return Success;
 
     /* FIXME: */
-    return Success;
+    XVMC_ERR("XvMCHideSurface not implemented!\n");
+    return BadValue;
 }
 
-/***************************************************************************
-//
-// Functions that deal with subpictures
-//
-***************************************************************************/
-
-
-
-/***************************************************************************
-// Function: XvMCCreateSubpicture
-// Description: This creates a subpicture by filling out the XvMCSubpicture
-//              structure passed to it and returning Success.
-// Arguments:
-//   display - Connection to the X server.
-//   context - The context to create the subpicture for.
-//   subpicture - Pre-allocated XvMCSubpicture structure to be filled in.
-//   width - of subpicture
-//   height - of subpicture
-//   xvimage_id - The id describing the XvImage format.
-//
-// Returns: Status
-***************************************************************************/
+/*
+ * Function: XvMCCreateSubpicture
+ * Description: This creates a subpicture by filling out the XvMCSubpicture
+ *              structure passed to it and returning Success.
+ * Arguments:
+ *   display - Connection to the X server.
+ *   context - The context to create the subpicture for.
+ *   subpicture - Pre-allocated XvMCSubpicture structure to be filled in.
+ *   width - of subpicture
+ *   height - of subpicture
+ *   xvimage_id - The id describing the XvImage format.
+ *
+ * Returns: Status
+ */
 Status XvMCCreateSubpicture(Display *display, XvMCContext *context,
                             XvMCSubpicture *subpicture,
                             unsigned short width, unsigned short height,
-                            int xvimage_id) 
+                            int xvimage_id)
 {
+    XVMC_ERR("XvMCCreateSubpicture not implemented!\n");
     return BadValue;
 }
 
-/***************************************************************************
-// Function: XvMCClearSubpicture
-// Description: Clear the area of the given subpicture to "color".
-//              structure passed to it and returning Success.
-// Arguments:
-//   display - Connection to the X server.
-//   subpicture - Subpicture to clear.
-//   x, y, width, height - rectangle in the subpicture to clear.
-//   color - The data to file the rectangle with.
-//
-// Returns: Status
-***************************************************************************/
+/*
+ * Function: XvMCClearSubpicture
+ * Description: Clear the area of the given subpicture to "color".
+ *              structure passed to it and returning Success.
+ * Arguments:
+ *   display - Connection to the X server.
+ *   subpicture - Subpicture to clear.
+ *   x, y, width, height - rectangle in the subpicture to clear.
+ *   color - The data to file the rectangle with.
+ *
+ * Returns: Status
+ */
 Status XvMCClearSubpicture(Display *display, XvMCSubpicture *subpicture,
                            short x, short y,
                            unsigned short width, unsigned short height,
-                           unsigned int color) 
+                           unsigned int color)
 {
+    XVMC_ERR("XvMCClearSubpicture not implemented!");
     return BadValue;
 }
 
-/***************************************************************************
-// Function: XvMCCompositeSubpicture
-// Description: Composite the XvImae on the subpicture. This composit uses
-//              non-premultiplied alpha. Destination alpha is utilized
-//              except for with indexed subpictures. Indexed subpictures
-//              use a simple "replace".
-// Arguments:
-//   display - Connection to the X server.
-//   subpicture - Subpicture to clear.
-//   image - the XvImage to be used as the source of the composite.
-//   srcx, srcy, width, height - The rectangle from the image to be used.
-//   dstx, dsty - location in the subpicture to composite the source.
-//
-// Returns: Status
-***************************************************************************/
+/*
+ * Function: XvMCCompositeSubpicture
+ * Description: Composite the XvImae on the subpicture. This composit uses
+ *              non-premultiplied alpha. Destination alpha is utilized
+ *              except for with indexed subpictures. Indexed subpictures
+ *              use a simple "replace".
+ * Arguments:
+ *   display - Connection to the X server.
+ *   subpicture - Subpicture to clear.
+ *   image - the XvImage to be used as the source of the composite.
+ *   srcx, srcy, width, height - The rectangle from the image to be used.
+ *   dstx, dsty - location in the subpicture to composite the source.
+ *
+ * Returns: Status
+ */
 Status XvMCCompositeSubpicture(Display *display, XvMCSubpicture *subpicture,
                                XvImage *image,
                                short srcx, short srcy,
                                unsigned short width, unsigned short height,
-                               short dstx, short dsty) 
+                               short dstx, short dsty)
 {
+    XVMC_ERR("XvMCCompositeSubpicture not implemented!");
     return BadValue;
 }
 
 
-/***************************************************************************
-// Function: XvMCDestroySubpicture
-// Description: Destroys the specified subpicture.
-// Arguments:
-//   display - Connection to the X server.
-//   subpicture - Subpicture to be destroyed.
-//
-// Returns: Status
-***************************************************************************/
-Status XvMCDestroySubpicture(Display *display, XvMCSubpicture *subpicture) 
+/*
+ * Function: XvMCDestroySubpicture
+ * Description: Destroys the specified subpicture.
+ * Arguments:
+ *   display - Connection to the X server.
+ *   subpicture - Subpicture to be destroyed.
+ *
+ * Returns: Status
+ */
+Status XvMCDestroySubpicture(Display *display, XvMCSubpicture *subpicture)
 {
+    XVMC_ERR("XvMCDestroySubpicture not implemented!");
     return BadValue;
 }
 
 
-/***************************************************************************
-// Function: XvMCSetSubpicturePalette
-// Description: Set the subpictures palette
-// Arguments:
-//   display - Connection to the X server.
-//   subpicture - Subpiture to set palette for.
-//   palette - A pointer to an array holding the palette data. The array
-//     is num_palette_entries * entry_bytes in size.
-// Returns: Status
-***************************************************************************/
-
+/*
+ * Function: XvMCSetSubpicturePalette
+ * Description: Set the subpictures palette
+ * Arguments:
+ *   display - Connection to the X server.
+ *   subpicture - Subpiture to set palette for.
+ *   palette - A pointer to an array holding the palette data. The array
+ *     is num_palette_entries * entry_bytes in size.
+ * Returns: Status
+ */
 Status XvMCSetSubpicturePalette(Display *display, XvMCSubpicture *subpicture,
-                                unsigned char *palette) 
+                                unsigned char *palette)
 {
+    XVMC_ERR("XvMCSetSubpicturePalette not implemented!");
     return BadValue;
 }
 
-/***************************************************************************
-// Function: XvMCBlendSubpicture
-// Description: 
-//    The behavior of this function is different depending on whether
-//    or not the XVMC_BACKEND_SUBPICTURE flag is set in the XvMCSurfaceInfo.
-//    i915 only support frontend behavior.
-//  
-//    XVMC_BACKEND_SUBPICTURE not set ("frontend" behavior):
-//   
-//    XvMCBlendSubpicture is a no-op in this case.
-//   
-// Arguments:
-//   display - Connection to the X server.
-//   subpicture - The subpicture to be blended into the video.
-//   target_surface - The surface to be displayed with the blended subpic.
-//   source_surface - Source surface prior to blending.
-//   subx, suby, subw, subh - The rectangle from the subpicture to use.
-//   surfx, surfy, surfw, surfh - The rectangle in the surface to blend
-//      blend the subpicture rectangle into. Scaling can ocure if 
-//      XVMC_SUBPICTURE_INDEPENDENT_SCALING is set.
-//
-// Returns: Status
-***************************************************************************/
+/*
+ * Function: XvMCBlendSubpicture
+ * Description:
+ *    The behavior of this function is different depending on whether
+ *    or not the XVMC_BACKEND_SUBPICTURE flag is set in the XvMCSurfaceInfo.
+ *    i915 only support frontend behavior.
+ *
+ *    XVMC_BACKEND_SUBPICTURE not set ("frontend" behavior):
+ *
+ *    XvMCBlendSubpicture is a no-op in this case.
+ *
+ * Arguments:
+ *   display - Connection to the X server.
+ *   subpicture - The subpicture to be blended into the video.
+ *   target_surface - The surface to be displayed with the blended subpic.
+ *   source_surface - Source surface prior to blending.
+ *   subx, suby, subw, subh - The rectangle from the subpicture to use.
+ *   surfx, surfy, surfw, surfh - The rectangle in the surface to blend
+ *      blend the subpicture rectangle into. Scaling can ocure if
+ *      XVMC_SUBPICTURE_INDEPENDENT_SCALING is set.
+ *
+ * Returns: Status
+ */
 Status XvMCBlendSubpicture(Display *display, XvMCSurface *target_surface,
                            XvMCSubpicture *subpicture,
                            short subx, short suby,
                            unsigned short subw, unsigned short subh,
                            short surfx, short surfy,
-                           unsigned short surfw, unsigned short surfh) 
+                           unsigned short surfw, unsigned short surfh)
 {
+    XVMC_ERR("XvMCBlendSubpicture not implemented!");
     return BadValue;
 }
 
-/***************************************************************************
-// Function: XvMCBlendSubpicture2
-// Description: 
-//    The behavior of this function is different depending on whether
-//    or not the XVMC_BACKEND_SUBPICTURE flag is set in the XvMCSurfaceInfo.
-//    i915 only supports frontend blending.
-//  
-//    XVMC_BACKEND_SUBPICTURE not set ("frontend" behavior):
-//   
-//    XvMCBlendSubpicture2 blends the source_surface and subpicture and
-//    puts it in the target_surface.  This does not effect the status of
-//    the source surface but will cause the target_surface to query
-//    XVMC_RENDERING until the blend is completed.
-//   
-// Arguments:
-//   display - Connection to the X server.
-//   subpicture - The subpicture to be blended into the video.
-//   target_surface - The surface to be displayed with the blended subpic.
-//   source_surface - Source surface prior to blending.
-//   subx, suby, subw, subh - The rectangle from the subpicture to use.
-//   surfx, surfy, surfw, surfh - The rectangle in the surface to blend
-//      blend the subpicture rectangle into. Scaling can ocure if 
-//      XVMC_SUBPICTURE_INDEPENDENT_SCALING is set.
-//
-// Returns: Status
-***************************************************************************/
-Status XvMCBlendSubpicture2(Display *display, 
+/*
+ * Function: XvMCBlendSubpicture2
+ * Description:
+ *    The behavior of this function is different depending on whether
+ *    or not the XVMC_BACKEND_SUBPICTURE flag is set in the XvMCSurfaceInfo.
+ *    i915 only supports frontend blending.
+ *
+ *    XVMC_BACKEND_SUBPICTURE not set ("frontend" behavior):
+ *
+ *    XvMCBlendSubpicture2 blends the source_surface and subpicture and
+ *    puts it in the target_surface.  This does not effect the status of
+ *    the source surface but will cause the target_surface to query
+ *    XVMC_RENDERING until the blend is completed.
+ *
+ * Arguments:
+ *   display - Connection to the X server.
+ *   subpicture - The subpicture to be blended into the video.
+ *   target_surface - The surface to be displayed with the blended subpic.
+ *   source_surface - Source surface prior to blending.
+ *   subx, suby, subw, subh - The rectangle from the subpicture to use.
+ *   surfx, surfy, surfw, surfh - The rectangle in the surface to blend
+ *      blend the subpicture rectangle into. Scaling can ocure if
+ *      XVMC_SUBPICTURE_INDEPENDENT_SCALING is set.
+ *
+ * Returns: Status
+ */
+Status XvMCBlendSubpicture2(Display *display,
                             XvMCSurface *source_surface,
                             XvMCSurface *target_surface,
                             XvMCSubpicture *subpicture,
@@ -1177,168 +749,121 @@ Status XvMCBlendSubpicture2(Display *display,
                             short surfx, short surfy,
                             unsigned short surfw, unsigned short surfh)
 {
+    XVMC_ERR("XvMCBlendSubpicture2 not implemented!");
     return BadValue;
 }
 
-/***************************************************************************
-// Function: XvMCSyncSubpicture
-// Description: This function blocks until all composite/clear requests on
-//              the subpicture have been complete.
-// Arguments:
-//   display - Connection to the X server.
-//   subpicture - The subpicture to synchronize
-//
-// Returns: Status
-***************************************************************************/
-Status XvMCSyncSubpicture(Display *display, XvMCSubpicture *subpicture) 
+/*
+ * Function: XvMCSyncSubpicture
+ * Description: This function blocks until all composite/clear requests on
+ *              the subpicture have been complete.
+ * Arguments:
+ *   display - Connection to the X server.
+ *   subpicture - The subpicture to synchronize
+ *
+ * Returns: Status
+ */
+Status XvMCSyncSubpicture(Display *display, XvMCSubpicture *subpicture)
 {
+    XVMC_ERR("XvMCSyncSubpicture not implemented!");
     return BadValue;
-#if 0
-    Status ret;
-    int stat = 0;
-
-    if (!display || !subpicture)
-
-    do {
-        ret = XvMCGetSubpictureStatus(display, subpicture, &stat);
-    } while(!ret && (stat & XVMC_RENDERING));
-
-    return ret;
-#endif
 }
 
-/***************************************************************************
-// Function: XvMCFlushSubpicture
-// Description: This function commits pending composite/clear requests to
-//              ensure that they will be completed in a finite amount of
-//              time.
-// Arguments:
-//   display - Connection to the X server.
-//   subpicture - The subpicture whos compsiting should be flushed
-//
-// Returns: Status
-***************************************************************************/
-Status XvMCFlushSubpicture(Display *display, XvMCSubpicture *subpicture) 
+/*
+ * Function: XvMCFlushSubpicture
+ * Description: This function commits pending composite/clear requests to
+ *              ensure that they will be completed in a finite amount of
+ *              time.
+ * Arguments:
+ *   display - Connection to the X server.
+ *   subpicture - The subpicture whos compsiting should be flushed
+ *
+ * Returns: Status
+ */
+Status XvMCFlushSubpicture(Display *display, XvMCSubpicture *subpicture)
 {
+    XVMC_ERR("XvMCFlushSubpicture not implemented!");
     return BadValue;
-#if 0
-    i915XvMCSubpicture *pI915Subpicture;
-
-    if (!display || !subpicture)
-        return BadValue;
-
-    if (!(pI915Subpicture = subpicture->privData))
-        return (error_base + XvMCBadSubpicture);
-
-    return Success;
-#endif
 }
 
-/***************************************************************************
-// Function: XvMCGetSubpictureStatus
-// Description: This function gets the current status of a subpicture
-//
-// Arguments:
-//   display - Connection to the X server.
-//   subpicture - The subpicture whos status is being queried
-//   stat - The status of the subpicture. It can be any of the following
-//          OR'd together:
-//          XVMC_RENDERING  - Last composite or clear request not completed
-//          XVMC_DISPLAYING - Suppicture currently being displayed.
-//
-// Returns: Status
-***************************************************************************/
+/*
+ * Function: XvMCGetSubpictureStatus
+ * Description: This function gets the current status of a subpicture
+ *
+ * Arguments:
+ *   display - Connection to the X server.
+ *   subpicture - The subpicture whos status is being queried
+ *   stat - The status of the subpicture. It can be any of the following
+ *          OR'd together:
+ *          XVMC_RENDERING  - Last composite or clear request not completed
+ *          XVMC_DISPLAYING - Suppicture currently being displayed.
+ *
+ * Returns: Status
+ */
 Status XvMCGetSubpictureStatus(Display *display, XvMCSubpicture *subpicture,
-                               int *stat) 
+                               int *stat)
 {
+    XVMC_ERR("XvMCGetSubpictureStatus not implemented!");
     return BadValue;
-#if 0
-    i915XvMCSubpicture *pI915Subpicture;
-    i915XvMCContext *pI915XvMC;
-
-    if (!display || !subpicture || stat)
-        return BadValue;
-
-    *stat = 0;
-
-    if (!(pI915Subpicture = subpicture->privData))
-        return (error_base + XvMCBadSubpicture);
-
-    if (!(pI915XvMC = pI915Subpicture->privContext))
-        return (error_base + XvMCBadSubpicture);
-
-    // LOCK_HARDWARE(pI915XvMC);
-    PPTHREAD_MUTEX_LOCK(pI915XvMC);
-    /* FIXME: */
-    if (pI915Subpicture->last_render &&
-        (pI915Subpicture->last_render > pI915XvMC->sarea->last_dispatch)) {
-        *stat |= XVMC_RENDERING;
-    }
-
-    // UNLOCK_HARDWARE(pI915XvMC);
-    PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
-    return Success;
-#endif
 }
 
-/***************************************************************************
-// Function: XvMCQueryAttributes
-// Description: An array of XvAttributes of size "number" is returned by
-//   this function. If there are no attributes, NULL is returned and number
-//   is set to 0. The array may be freed with xfree().
-//
-// Arguments:
-//   display - Connection to the X server.
-//   context - The context whos attributes we are querying.
-//   number - The returned number of recognized atoms
-//
-// Returns:
-//  An array of XvAttributes.
-***************************************************************************/
+/*
+ * Function: XvMCQueryAttributes
+ * Description: An array of XvAttributes of size "number" is returned by
+ *   this function. If there are no attributes, NULL is returned and number
+ *   is set to 0. The array may be freed with xfree().
+ *
+ * Arguments:
+ *   display - Connection to the X server.
+ *   context - The context whos attributes we are querying.
+ *   number - The returned number of recognized atoms
+ *
+ * Returns:
+ *  An array of XvAttributes.
+ */
 XvAttribute *XvMCQueryAttributes(Display *display, XvMCContext *context,
-                                 int *number) 
+                                 int *number)
 {
     /* now XvMC has no extra attribs than Xv */
     *number = 0;
     return NULL;
 }
 
-/***************************************************************************
-// Function: XvMCSetAttribute
-// Description: This function sets a context-specific attribute.
-//
-// Arguments:
-//   display - Connection to the X server.
-//   context - The context whos attributes we are querying.
-//   attribute - The X atom of the attribute to be changed.
-//   value - The new value for the attribute.
-//
-// Returns:
-//  Status
-***************************************************************************/
+/*
+ * Function: XvMCSetAttribute
+ * Description: This function sets a context-specific attribute.
+ *
+ * Arguments:
+ *   display - Connection to the X server.
+ *   context - The context whos attributes we are querying.
+ *   attribute - The X atom of the attribute to be changed.
+ *   value - The new value for the attribute.
+ *
+ * Returns:
+ *  Status
+ */
 Status XvMCSetAttribute(Display *display, XvMCContext *context,
                         Atom attribute, int value)
 {
     return Success;
 }
 
-/***************************************************************************
-// Function: XvMCGetAttribute
-// Description: This function queries a context-specific attribute and
-//   returns the value.
-//
-// Arguments:
-//   display - Connection to the X server.
-//   context - The context whos attributes we are querying.
-//   attribute - The X atom of the attribute to be queried
-//   value - The returned attribute value
-//
-// Returns:
-//  Status
-// Notes:
-***************************************************************************/
+/*
+ * Function: XvMCGetAttribute
+ * Description: This function queries a context-specific attribute and
+ *   returns the value.
+ *
+ * Arguments:
+ *   display - Connection to the X server.
+ *   context - The context whos attributes we are querying.
+ *   attribute - The X atom of the attribute to be queried
+ *   value - The returned attribute value
+ *
+ * Returns:
+ *  Status
+ */
 Status XvMCGetAttribute(Display *display, XvMCContext *context,
-                        Atom attribute, int *value) 
+                        Atom attribute, int *value)
 {
     return Success;
 }
commit 1cfdf192882b856bfc93b735cfb9cb813cac3fdb
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Thu Nov 15 16:38:21 2007 +0800

    xvmc: remove unused SAREAPTR macro

diff --git a/src/xvmc/i915_xvmc.c b/src/xvmc/i915_xvmc.c
index 911b80e..a2c3e54 100644
--- a/src/xvmc/i915_xvmc.c
+++ b/src/xvmc/i915_xvmc.c
@@ -32,10 +32,6 @@
 #include "i915_structs.h"
 #include "i915_program.h"
 
-#define SAREAPTR(ctx) ((drmI830Sarea *)                     \
-                       (((CARD8 *)(ctx)->sarea_address) +   \
-                        (ctx)->sarea_priv_offset))
-
 #define YOFFSET(surface)        (surface->srf.offset)
 #define UOFFSET(surface)        (surface->srf.offset + \
                                  SIZE_Y420(surface->width, surface->height) + \
commit d9ea2fbdcce3c7c91428846eff43b65ac340f38d
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Thu Nov 15 15:25:35 2007 +0800

    xvmc: i915 rename files

diff --git a/src/xvmc/I915XvMC.c b/src/xvmc/I915XvMC.c
deleted file mode 100644
index d34808f..0000000
--- a/src/xvmc/I915XvMC.c
+++ /dev/null
@@ -1,2934 +0,0 @@
-/*
- * Copyright © 2006 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Authors:
- *    Xiang Haihao <haihao.xiang at intel.com>
- *
- */
-
-#include <pthread.h>
-#include <sys/ioctl.h>
-
-#include "I915XvMC.h"
-#include "i915_structs.h"
-#include "i915_program.h"
-
-#define SAREAPTR(ctx) ((drmI830Sarea *)                     \
-                       (((CARD8 *)(ctx)->sarea_address) +   \
-                        (ctx)->sarea_priv_offset))
-
-#define YOFFSET(surface)        (surface->srf.offset)
-#define UOFFSET(surface)        (surface->srf.offset + \
-                                 SIZE_Y420(surface->width, surface->height) + \
-                                 SIZE_UV420(surface->width, surface->height))
-#define VOFFSET(surface)        (surface->srf.offset + \
-                                 SIZE_Y420(surface->width, surface->height))
-
-/* Lookup tables to speed common calculations */
-static unsigned int mb_bytes[] = {
-    000, 128, 128, 256, 128, 256, 256, 384,  // 0
-    128, 256, 256, 384, 256, 384, 384, 512,  // 1
-    128, 256, 256, 384, 256, 384, 384, 512,  // 10
-    256, 384, 384, 512, 384, 512, 512, 640,  // 11
-    128, 256, 256, 384, 256, 384, 384, 512,  // 100
-    256, 384, 384, 512, 384, 512, 512, 640,  // 101    
-    256, 384, 384, 512, 384, 512, 512, 640,  // 110
-    384, 512, 512, 640, 512, 640, 640, 768   // 111
-};
-
-typedef union {
-    short s[4];
-    uint  u[2];
-} su_t;
-
-static char I915KernelDriverName[] = "i915";
-static int error_base;
-static int event_base;
-
-static Status i915_xvmc_mc_create_context(Display* display, XvMCContext *context, int priv_count, CARD32* priv_data);
-static Status i915_xvmc_mc_destroy_context(Display* display, XvMCContext *context);
-static Status i915_xvmc_mc_create_surface(Display* display, XvMCContext *context, XvMCSurface *surface);
-static Status i915_xvmc_mc_destroy_surface(Display* display, XvMCSurface *surface);
-static Status i915_xvmc_mc_render_surface(Display *display, XvMCContext *context,
-                         unsigned int picture_structure,
-                         XvMCSurface *target_surface,
-                         XvMCSurface *past_surface,
-                         XvMCSurface *future_surface,
-                         unsigned int flags,
-                         unsigned int num_macroblocks,
-                         unsigned int first_macroblock,
-                         XvMCMacroBlockArray *macroblock_array,
-                         XvMCBlockArray *blocks);
-static Status i915_xvmc_mc_put_surface(Display *display,XvMCSurface *surface,
-                      Drawable draw, short srcx, short srcy,
-                      unsigned short srcw, unsigned short srch,
-                      short destx, short desty,
-                      unsigned short destw, unsigned short desth,
-                      int flags);
-static Status i915_xvmc_mc_get_surface_status(Display *display, XvMCSurface *surface, int *stat);
-//XXX
-static int i915_xvmc_mc_init()
-{return 0;}
-static void i915_xvmc_mc_fini()
-{}
-
-struct _intel_xvmc_driver i915_xvmc_mc_driver = {
-    .type = XVMC_I915_MPEG2_MC,
-    .init = i915_xvmc_mc_init,
-    .fini = i915_xvmc_mc_fini,
-    .create_context = i915_xvmc_mc_create_context,
-    .destroy_context = i915_xvmc_mc_destroy_context,
-    .create_surface = i915_xvmc_mc_create_surface,
-    .destroy_surface = i915_xvmc_mc_destroy_surface,
-    .render_surface = i915_xvmc_mc_render_surface,
-    .put_surface = i915_xvmc_mc_put_surface,
-    .get_surface_status = i915_xvmc_mc_get_surface_status,
-};
-
-static int findOverlap(unsigned int width, unsigned int height,
-                       short *dstX, short *dstY,
-                       short *srcX, short *srcY, 
-                       unsigned short *areaW, unsigned short *areaH)
-{
-    int w, h;
-    unsigned int mWidth, mHeight;
-
-    w = *areaW;
-    h = *areaH;
-
-    if ((*dstX >= width) || (*dstY >= height))
-        return 1;
-
-    if (*dstX < 0) {
-        w += *dstX;
-        *srcX -= *dstX;
-        *dstX = 0;
-    }
-
-    if (*dstY < 0) {
-        h += *dstY;
-        *srcY -= *dstY;
-        *dstY = 0;
-    }
-
-    if ((w <= 0) || ((h <= 0)))
-        return 1;
-
-    mWidth = width - *dstX;
-    mHeight = height - *dstY;
-    *areaW = (w <= mWidth) ? w : mWidth;
-    *areaH = (h <= mHeight) ? h : mHeight;
-    return 0;
-}
-
-static __inline__ void renderError(void) 
-{
-    XVMC_ERR("Invalid Macroblock Parameters found.");
-}
-
-static void i915_flush(int map, int render)
-{
-    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;
-
-    intelBatchbufferData(&mi_flush, sizeof(mi_flush), 0);
-}
-
-/* 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)
-{
-    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, h = surface->height;
-
-    /* 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;
-
-    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;
-    } 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;
-    }
-
-    /* 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;
-        else
-            dest_buffer_variables_mpeg->dw1.tff = 1;
-    } else if (picture_structure & XVMC_BOTTOM_FIELD) {
-        if (flags & XVMC_SECOND_FIELD)
-            dest_buffer_variables_mpeg->dw1.tff = 1;
-        else
-            dest_buffer_variables_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 */
-}
-
-static void i915_mc_map_state_buffer(XvMCContext *context, 
-                                       i915XvMCSurface *privTarget,
-                                       i915XvMCSurface *privPast,
-                                       i915XvMCSurface *privFuture)
-{
-    struct i915_3dstate_map_state *map_state;
-    struct texture_map *tm;
-    i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
-    unsigned int w = context->width, h = context->height;
- 
-    /* 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;
-
-    /* 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 */
-
-    /* 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: 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;
-
-    /* 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 */
-
-    /* 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;     
-
-    /* 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;
-
-    /* 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 */
-
-    /* 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;
-}
-
-static void i915_mc_load_sis_msb_buffers(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;
-    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;
-    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;
-
-    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;
-
-    /* SIS */
-    sis = (sis_state *)(++load_indirect);
-    sis->dw0.valid = 1;
-    sis->dw0.force = 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 */
-    msb = (msb_state *)(++sis);
-    msb->dw0.valid = 1;
-    msb->dw0.force = 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_mpeg_set_origin(XvMCContext *context, XvMCMacroBlock *mb)
-{
-    struct i915_3dmpeg_set_origin set_origin;
-
-    /* 3DMPEG_SET_ORIGIN */
-    memset(&set_origin, 0, sizeof(set_origin));
-    set_origin.dw0.type = CMD_3D;
-    set_origin.dw0.opcode = OPC_3DMPEG_SET_ORIGIN;
-    set_origin.dw0.length = 0;
-    set_origin.dw1.h_origin = mb->x;
-    set_origin.dw1.v_origin = mb->y;
-
-    intelBatchbufferData(&set_origin, sizeof(set_origin), 0);
-}
-
-static void i915_mc_mpeg_macroblock_ipicture(XvMCContext *context, XvMCMacroBlock *mb)
-{
-    struct i915_3dmpeg_macroblock_ipicture macroblock_ipicture;
-
-    /* 3DMPEG_MACROBLOCK_IPICTURE */
-    memset(&macroblock_ipicture, 0, sizeof(macroblock_ipicture));
-    macroblock_ipicture.dw0.type = CMD_3D;
-    macroblock_ipicture.dw0.opcode = OPC_3DMPEG_MACROBLOCK_IPICTURE;
-    macroblock_ipicture.dw0.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD);
-
-    intelBatchbufferData(&macroblock_ipicture, sizeof(macroblock_ipicture), 0);
-}
-
-
-static void i915_mc_mpeg_macroblock_0mv(XvMCContext *context, XvMCMacroBlock *mb)
-{
-    struct i915_3dmpeg_macroblock_0mv macroblock_0mv;
-
-    /* 3DMPEG_MACROBLOCK(0mv) */
-    memset(&macroblock_0mv, 0, sizeof(macroblock_0mv));
-    macroblock_0mv.header.dw0.type = CMD_3D;
-    macroblock_0mv.header.dw0.opcode = OPC_3DMPEG_MACROBLOCK;
-    macroblock_0mv.header.dw0.length = 0;
-    macroblock_0mv.header.dw1.mb_intra = 1;     /* should be 1 */ 
-    macroblock_0mv.header.dw1.forward = 0;      /* should be 0 */
-    macroblock_0mv.header.dw1.backward = 0;     /* should be 0 */
-    macroblock_0mv.header.dw1.h263_4mv = 0;     /* should be 0 */
-    macroblock_0mv.header.dw1.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD);
-    
-/*
-    if (!mb->coded_block_pattern)
-        macroblock_0mv.header.dw1.dct_type = XVMC_DCT_TYPE_FRAME;
-*/
-
-    macroblock_0mv.header.dw1.motion_type = 0; // (mb->motion_type & 0x3);
-    macroblock_0mv.header.dw1.vertical_field_select = 0; // mb->motion_vertical_field_select & 0xf;
-    macroblock_0mv.header.dw1.coded_block_pattern = mb->coded_block_pattern;
-    macroblock_0mv.header.dw1.skipped_macroblocks = 0;
-
-    intelBatchbufferData(&macroblock_0mv, sizeof(macroblock_0mv), 0);
-}
-
-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;
-
-    /* 3DMPEG_MACROBLOCK(1fbmv) */
-    memset(&macroblock_1fbmv, 0, sizeof(macroblock_1fbmv));
-    macroblock_1fbmv.header.dw0.type = CMD_3D;
-    macroblock_1fbmv.header.dw0.opcode = OPC_3DMPEG_MACROBLOCK;
-    macroblock_1fbmv.header.dw0.length = 2;
-    macroblock_1fbmv.header.dw1.mb_intra = 0;   /* should be 0 */ 
-    macroblock_1fbmv.header.dw1.forward = ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_FORWARD) ? 1 : 0);
-    macroblock_1fbmv.header.dw1.backward = ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_BACKWARD) ? 1 : 0);
-    macroblock_1fbmv.header.dw1.h263_4mv = 0;   /* should be 0 */
-    macroblock_1fbmv.header.dw1.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD);
-    
-    if (!(mb->coded_block_pattern & 0x3f))
-        macroblock_1fbmv.header.dw1.dct_type = XVMC_DCT_TYPE_FRAME;
-
-    macroblock_1fbmv.header.dw1.motion_type = (mb->motion_type & 0x03);
-    macroblock_1fbmv.header.dw1.vertical_field_select = (mb->motion_vertical_field_select & 0x0f);
-    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];
-
-    macroblock_1fbmv.dw2 = fmv.u[0];
-    macroblock_1fbmv.dw3 = bmv.u[0];
-    
-    intelBatchbufferData(&macroblock_1fbmv, sizeof(macroblock_1fbmv), 0);
-}
-
-static void i915_mc_mpeg_macroblock_2fbmv(XvMCContext *context, XvMCMacroBlock *mb, unsigned int ps)
-{
-    struct i915_3dmpeg_macroblock_2fbmv macroblock_2fbmv;
-    i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
-    
-    /* Motion Vectors */
-    su_t fmv;
-    su_t bmv;
-
-    /* 3DMPEG_MACROBLOCK(2fbmv) */
-    memset(&macroblock_2fbmv, 0, sizeof(macroblock_2fbmv));
-    macroblock_2fbmv.header.dw0.type = CMD_3D;
-    macroblock_2fbmv.header.dw0.opcode = OPC_3DMPEG_MACROBLOCK;
-    macroblock_2fbmv.header.dw0.length = 4;
-    macroblock_2fbmv.header.dw1.mb_intra = 0;   /* should be 0 */
-    macroblock_2fbmv.header.dw1.forward = ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_FORWARD) ? 1 : 0);
-    macroblock_2fbmv.header.dw1.backward = ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_BACKWARD) ? 1 : 0);
-    macroblock_2fbmv.header.dw1.h263_4mv = 0;   /* should be 0 */
-    macroblock_2fbmv.header.dw1.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD);
-    
-    if (!(mb->coded_block_pattern & 0x3f))
-        macroblock_2fbmv.header.dw1.dct_type = XVMC_DCT_TYPE_FRAME;
-
-    macroblock_2fbmv.header.dw1.motion_type = (mb->motion_type & 0x03);
-    macroblock_2fbmv.header.dw1.vertical_field_select = (mb->motion_vertical_field_select & 0x0f);
-    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];
-
-    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;
-        } 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;
-        }
-    }
-
-    macroblock_2fbmv.dw2 = fmv.u[0];
-    macroblock_2fbmv.dw3 = bmv.u[0];
-    macroblock_2fbmv.dw4 = fmv.u[1];
-    macroblock_2fbmv.dw5 = bmv.u[1];
-
-    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);
-}
-
-static void i915_mc_invalidate_subcontext_buffers(XvMCContext *context, unsigned int mask)
-{
-    struct i915_3dstate_load_indirect *load_indirect = NULL;
-    sis_state *sis = NULL;
-    dis_state *dis = NULL;
-    ssb_state *ssb = NULL;
-    msb_state *msb = NULL;
-    psp_state *psp = NULL;
-    psc_state *psc = NULL;
-    i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
-    unsigned int size;
-    void *base = NULL, *ptr = NULL;
-
-    size = sizeof(*load_indirect);
-    if (mask & BLOCK_SIS)
-        size += sizeof(*sis);
-    if (mask & BLOCK_DIS)
-        size += sizeof(*dis);
-    if (mask & BLOCK_SSB)
-        size += sizeof(*ssb);
-    if (mask & BLOCK_MSB)
-        size += sizeof(*msb);
-    if (mask & BLOCK_PSP)
-        size += sizeof(*psp);
-    if (mask & BLOCK_PSC)
-        size += sizeof(*psc);
-
-    if (size == sizeof(*load_indirect)) {
-        XVMC_ERR("There must be at least one bit set\n");
-        return;
-    }
-
-    /* 3DSTATE_LOAD_INDIRECT */
-    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;
-
-    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)
-        load_indirect->dw0.mem_select = 0;
-    else
-        load_indirect->dw0.mem_select = 1;
-
-    load_indirect->dw0.block_mask = mask;
-    load_indirect->dw0.length = (size >> 2) - 2;
-    ptr = ++load_indirect;
-
-    /* SIS */
-    if (mask & BLOCK_SIS) {
-        sis = (sis_state *)ptr;
-        sis->dw0.valid = 0;
-        sis->dw0.buffer_address = 0;
-        sis->dw1.length = 0;
-        ptr = ++sis;
-    }
-
-    /* DIS */
-    if (mask & BLOCK_DIS) {
-        dis = (dis_state *)ptr;
-        dis->dw0.valid = 0;
-        dis->dw0.reset = 0;
-        dis->dw0.buffer_address = 0;
-        ptr = ++dis;
-    }
-
-    /* SSB */
-    if (mask & BLOCK_SSB) {
-        ssb = (ssb_state *)ptr;
-        ssb->dw0.valid = 0;
-        ssb->dw0.buffer_address = 0;
-        ssb->dw1.length = 0;
-        ptr = ++ssb;
-    }
-
-    /* MSB */
-    if (mask & BLOCK_MSB) {
-        msb = (msb_state *)ptr;
-        msb->dw0.valid = 0;
-        msb->dw0.buffer_address = 0;
-        msb->dw1.length = 0;
-        ptr = ++msb;
-    }
-
-    /* PSP */
-    if (mask & BLOCK_PSP) {
-        psp = (psp_state *)ptr;
-        psp->dw0.valid = 0;
-        psp->dw0.buffer_address = 0;
-        psp->dw1.length = 0;
-        ptr = ++psp;
-    }
-
-    /* PSC */
-    if (mask & BLOCK_PSC) {
-        psc = (psc_state *)ptr;
-        psc->dw0.valid = 0;
-        psc->dw0.buffer_address = 0;
-        psc->dw1.length = 0;
-        ptr = ++psc;
-    }
-
-    intelBatchbufferData(base, size, 0);
-    free(base);
-}
-
-static int i915_xvmc_map_buffers(i915XvMCContext *pI915XvMC)
-{
-    if (drmMap(xvmc_driver->fd,
-               pI915XvMC->sis.handle,
-               pI915XvMC->sis.size,
-               (drmAddress *)&pI915XvMC->sis.map) != 0) {
-        return -1;
-    }
-
-    if (drmMap(xvmc_driver->fd,
-               pI915XvMC->ssb.handle,
-               pI915XvMC->ssb.size,
-               (drmAddress *)&pI915XvMC->ssb.map) != 0) {
-        return -1;
-    }
-
-    if (drmMap(xvmc_driver->fd,
-               pI915XvMC->msb.handle,
-               pI915XvMC->msb.size,
-               (drmAddress *)&pI915XvMC->msb.map) != 0) {
-        return -1;
-    }
-
-    if (drmMap(xvmc_driver->fd,
-               pI915XvMC->psp.handle,
-               pI915XvMC->psp.size,
-               (drmAddress *)&pI915XvMC->psp.map) != 0) {
-        return -1;
-    }
-
-    if (drmMap(xvmc_driver->fd,
-               pI915XvMC->psc.handle,
-               pI915XvMC->psc.size,
-               (drmAddress *)&pI915XvMC->psc.map) != 0) {
-        return -1;
-    }
-
-    if (drmMap(xvmc_driver->fd,
-               pI915XvMC->corrdata.handle,
-               pI915XvMC->corrdata.size,
-               (drmAddress *)&pI915XvMC->corrdata.map) != 0) {
-        return -1;
-    }
-
-    return 0;
-}
-
-static void i915_xvmc_unmap_buffers(i915XvMCContext *pI915XvMC)
-{
-    if (pI915XvMC->sis.map) {
-        drmUnmap(pI915XvMC->sis.map, pI915XvMC->sis.size);
-        pI915XvMC->sis.map = NULL;
-    }
-
-    if (pI915XvMC->ssb.map) {
-        drmUnmap(pI915XvMC->ssb.map, pI915XvMC->ssb.size);
-        pI915XvMC->ssb.map = NULL;
-    }
-
-    if (pI915XvMC->msb.map) {
-        drmUnmap(pI915XvMC->msb.map, pI915XvMC->msb.size);
-        pI915XvMC->msb.map = NULL;
-    }
-
-    if (pI915XvMC->psp.map) {
-        drmUnmap(pI915XvMC->psp.map, pI915XvMC->psp.size);
-        pI915XvMC->psp.map = NULL;
-    }
-
-    if (pI915XvMC->psc.map) {
-        drmUnmap(pI915XvMC->psc.map, pI915XvMC->psc.size);
-        pI915XvMC->psc.map = NULL;
-    }
-
-    if (pI915XvMC->corrdata.map) {
-        drmUnmap(pI915XvMC->corrdata.map, pI915XvMC->corrdata.size);
-        pI915XvMC->corrdata.map = NULL;
-    }
-}
-
-/*
- * Video post processing 
- */
-static void i915_yuv2rgb_map_state_buffer(XvMCSurface *target_surface)
-{
-    struct i915_3dstate_map_state *map_state;
-    struct texture_map *tm;
-    i915XvMCSurface *privTarget = NULL;
-    i915XvMCContext *pI915XvMC = NULL;
-    unsigned int w = target_surface->width, h = target_surface->height;
-
-    privTarget = (i915XvMCSurface *)target_surface->privData;
-    pI915XvMC = (i915XvMCContext *)privTarget->privContext;
-    /* 3DSATE_MAP_STATE */
-    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 = 0;
-    map_state->dw0.length = 9;
-    map_state->dw1.map_mask = MAP_MAP0 | MAP_MAP1 | MAP_MAP2;
-
-    /* texture map 0: V Plane */
-    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(privTarget);
-    tm->tm1.tile_walk = TILEWALK_XMAJOR;
-    tm->tm1.tiled_surface = 0;
-    tm->tm1.utilize_fence_regs = 1;
-    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 = (privTarget->uvStride >> 2) - 1;    /* in DWords - 1 */
-
-    /* texture map 1: Y Plane */
-    ++tm;
-    memset(tm, 0, sizeof(*tm));
-    tm->tm0.v_ls_offset = 0;
-    tm->tm0.v_ls = 0;
-    tm->tm0.base_address = YOFFSET(privTarget);
-    tm->tm1.tile_walk = TILEWALK_XMAJOR;
-    tm->tm1.tiled_surface = 0;
-    tm->tm1.utilize_fence_regs = 1;
-    tm->tm1.texel_fmt = 0;
-    tm->tm1.surface_fmt = 1;
-    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 = (privTarget->yStride >> 2) - 1;     /* in DWords - 1 */
-
-    /* texture map 2: U Plane */
-    ++tm;
-    memset(tm, 0, sizeof(*tm));
-    tm->tm0.v_ls_offset = 0;
-    tm->tm0.v_ls = 0;
-    tm->tm0.base_address = UOFFSET(privTarget);
-    tm->tm1.tile_walk = TILEWALK_XMAJOR;
-    tm->tm1.tiled_surface = 0;
-    tm->tm1.utilize_fence_regs = 1;
-    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 = (privTarget->uvStride >> 2) - 1;    /* in DWords - 1 */
-}
-
-static void i915_yuv2rgb_sampler_state_buffer(XvMCSurface *surface)
-{
-    struct i915_3dstate_sampler_state *sampler_state;
-    struct texture_sampler *ts;
-    i915XvMCSurface *privSurface = (i915XvMCSurface *)surface->privData;
-    i915XvMCContext *pI915XvMC = (i915XvMCContext *)privSurface->privContext;
-    
-    /* 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 = 9;
-    sampler_state->dw1.sampler_masker = SAMPLER_SAMPLER0 | SAMPLER_SAMPLER1 | SAMPLER_SAMPLER2;
-
-    /* Sampler 0 */
-    ts = (struct texture_sampler *)(++sampler_state);
-    memset(ts, 0, sizeof(*ts));
-    ts->ts0.reverse_gamma = 0;
-    ts->ts0.planar2packet = 1;
-    ts->ts0.color_conversion = 1;
-    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;
-    ts->ts0.shadow_enable = 0;
-    ts->ts0.max_anisotropy = ANISORATIO_2;
-    ts->ts0.shadow_function = PREFILTEROP_ALWAYS;
-    ts->ts1.min_lod = 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 = 1;
-    ts->ts0.color_conversion = 1;
-    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;
-    ts->ts0.shadow_enable = 0;
-    ts->ts0.max_anisotropy = ANISORATIO_2;
-    ts->ts0.shadow_function = PREFILTEROP_ALWAYS;
-    ts->ts1.min_lod = 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;
-
-    /* Sampler 2 */
-    ++ts;
-    memset(ts, 0, sizeof(*ts));
-    ts->ts0.reverse_gamma = 0;
-    ts->ts0.planar2packet = 1;
-    ts->ts0.color_conversion = 1;
-    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;
-    ts->ts0.shadow_enable = 0;
-    ts->ts0.max_anisotropy = ANISORATIO_2;
-    ts->ts0.shadow_function = PREFILTEROP_ALWAYS;
-    ts->ts1.min_lod = 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 = 2;
-    ts->ts1.east_deinterlacer = 0;
-    ts->ts2.default_color = 0;
-}
-
-static void i915_yuv2rgb_static_indirect_state_buffer(XvMCSurface *surface,
-                                                      unsigned int dstaddr, 
-                                                      int dstpitch)
-{
-    struct i915_3dstate_buffer_info *buffer_info;
-    struct i915_3dstate_dest_buffer_variables *dest_buffer_variables;
-    i915XvMCSurface *privSurface = (i915XvMCSurface *)surface->privData;
-    i915XvMCContext *pI915XvMC = (i915XvMCContext *)privSurface->privContext;
-
-    /* 3DSTATE_BUFFER_INFO */
-    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 = 1;   
-    buffer_info->dw1.tiled_surface = 0;   /* linear */
-    buffer_info->dw1.walk = TILEWALK_XMAJOR;
-    buffer_info->dw1.pitch = dstpitch;
-    buffer_info->dw2.base_address = dstaddr;
-
-    /* 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; /* FIXME 0x1000 .5 ??? */
-    dest_buffer_variables->dw1.dest_h_bias = 8;
-    dest_buffer_variables->dw1.color_fmt = COLORBUFFER_A8R8G8B8;  /* FIXME */
-}
-
-static void i915_yuv2rgb_pixel_shader_program_buffer(XvMCSurface *surface)
-{
-    struct i915_3dstate_pixel_shader_program *pixel_shader_program;
-    i915XvMCSurface *privSurface = (i915XvMCSurface *)surface->privData;
-    i915XvMCContext *pI915XvMC = (i915XvMCContext *)privSurface->privContext;
-    unsigned int *inst;
-    unsigned int dest, src0, src1;
-
-    /* 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 = 0;
-    pixel_shader_program->dw0.length = 23;
-    /* 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);
-    /* dcl_2D   s1 */
-    inst += 3;
-    i915_inst_decl(inst, REG_TYPE_S, 1, D0_SAMPLE_TYPE_2D);
-    /* dcl_2D   s2 */
-    inst += 3;
-    i915_inst_decl(inst, REG_TYPE_S, 2, D0_SAMPLE_TYPE_2D);
-    /* texld    r0 t1 s0 */
-    inst += 3;
-    dest = UREG(REG_TYPE_R, 0); 
-    src0 = UREG(REG_TYPE_T, 1); /* COORD */
-    src1 = UREG(REG_TYPE_S, 0); /* SAMPLER */
-    i915_inst_texld(inst, T0_TEXLD, dest, src0, src1);
-    /* texld    r0 t0 s1 */
-    inst += 3;
-    dest = UREG(REG_TYPE_R, 0); 
-    src0 = UREG(REG_TYPE_T, 0); /* COORD */
-    src1 = UREG(REG_TYPE_S, 1); /* SAMPLER */
-    i915_inst_texld(inst, T0_TEXLD, dest, src0, src1);
-    /* texld    oC t1 s2 */
-    inst += 3;
-    dest = UREG(REG_TYPE_OC, 0);
-    src0 = UREG(REG_TYPE_T, 1); /* COORD */
-    src1 = UREG(REG_TYPE_S, 2); /* SAMPLER */
-    i915_inst_texld(inst, T0_TEXLD, dest, src0, src1);
-}
-
-static void i915_yuv2rgb_proc(XvMCSurface *surface)
-{
-    i915XvMCSurface *privSurface = (i915XvMCSurface *)surface->privData;
-    i915XvMCContext *pI915XvMC = (i915XvMCContext *)privSurface->privContext;
-    struct i915_3dstate_load_state_immediate_1 *load_state_immediate_1 = NULL;
-    struct s2_dword *s2 = NULL;
-    struct s3_dword *s3 = NULL;
-    struct s4_dword *s4 = NULL;
-    struct s5_dword *s5 = NULL;
-    struct s6_dword *s6 = NULL;
-    struct s7_dword *s7 = NULL;
-    struct i915_3dstate_scissor_rectangle scissor_rectangle;
-    struct i915_3dstate_load_indirect *load_indirect = NULL;
-    sis_state *sis = NULL;
-    ssb_state *ssb = NULL;
-    msb_state *msb = NULL;
-    psp_state *psp = NULL;
-    struct i915_3dprimitive *_3dprimitive = NULL;
-    struct vertex_data *vd = NULL;
-    unsigned int size;
-    void *base = NULL;
-
-    /* 3DSTATE_LOAD_STATE_IMMEDIATE_1 */
-    size = sizeof(*load_state_immediate_1) + sizeof(*s2) + sizeof(*s3) +
-        sizeof(*s4) + sizeof(*s5) + sizeof(*s6) + sizeof(*s7);
-    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_s2 = 1;
-    load_state_immediate_1->dw0.load_s3 = 1;
-    load_state_immediate_1->dw0.load_s4 = 1;
-    load_state_immediate_1->dw0.load_s5 = 1;
-    load_state_immediate_1->dw0.load_s6 = 1;
-    load_state_immediate_1->dw0.load_s7 = 1;
-    load_state_immediate_1->dw0.length = 5;
-
-    s2 = (struct s2_dword *)(++load_state_immediate_1);
-    s2->set0_texcoord_fmt = TEXCOORDFMT_2FP;
-    s2->set1_texcoord_fmt = TEXCOORDFMT_2FP;
-    s2->set2_texcoord_fmt = TEXCOORDFMT_NOT_PRESENT;
-    s2->set3_texcoord_fmt = TEXCOORDFMT_NOT_PRESENT;
-    s2->set4_texcoord_fmt = TEXCOORDFMT_NOT_PRESENT;
-    s2->set5_texcoord_fmt = TEXCOORDFMT_NOT_PRESENT;
-    s2->set6_texcoord_fmt = TEXCOORDFMT_NOT_PRESENT;
-    s2->set7_texcoord_fmt = TEXCOORDFMT_NOT_PRESENT;
-
-    s3 = (struct s3_dword *)(++s2);
-    s4 = (struct s4_dword *)(++s3);
-    s4->position_mask = VERTEXHAS_XY;
-    s4->cull_mode = CULLMODE_NONE;
-    s4->color_shade_mode = SHADEMODE_FLAT;
-    s4->specular_shade_mode = SHADEMODE_FLAT;
-    s4->fog_shade_mode = SHADEMODE_FLAT;
-    s4->alpha_shade_mode = SHADEMODE_FLAT;
-    s4->line_width = 0x2;     /* FIXME: 1.0??? */
-    s4->point_width = 0x1; 
-
-    s5 = (struct s5_dword *)(++s4);
-    s6 = (struct s6_dword *)(++s5);
-    s6->src_blend_factor = 1;
-    s6->dest_blend_factor = 1;
-    s6->color_buffer_write = 1;
-
-    s7 = (struct s7_dword *)(++s6);
-    intelBatchbufferData(base, size, 0);
-    free(base);
-
-    /* 3DSTATE_3DSTATE_SCISSOR_RECTANGLE */
-    scissor_rectangle.dw0.type = CMD_3D;
-    scissor_rectangle.dw0.opcode = OPC_3DSTATE_SCISSOR_RECTANGLE;
-    scissor_rectangle.dw0.length = 1;
-    scissor_rectangle.dw1.min_x = 0;
-    scissor_rectangle.dw1.min_y = 0;
-    scissor_rectangle.dw2.max_x = 2047;
-    scissor_rectangle.dw2.max_y = 2047;
-    intelBatchbufferData(&scissor_rectangle, sizeof(scissor_rectangle), 0);
-
-    /* 3DSTATE_LOAD_INDIRECT */
-    size = sizeof(*load_indirect) + sizeof(*sis) + sizeof(*ssb) + sizeof(*msb) + sizeof(*psp);
-    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.mem_select = 1;  /* Bearlake only */
-    load_indirect->dw0.block_mask = BLOCK_SIS | BLOCK_SSB | BLOCK_MSB | BLOCK_PSP;
-    load_indirect->dw0.length = 7;
-
-    /* SIS */
-    sis = (sis_state *)(++load_indirect);
-    sis->dw0.valid = 1;
-    sis->dw0.buffer_address = pI915XvMC->sis.offset;
-    sis->dw1.length = ((sizeof(struct i915_3dstate_buffer_info) +
-                        sizeof(struct i915_3dstate_dest_buffer_variables)) >> 2) - 1;
-
-    /* SSB */
-    ssb = (ssb_state *)(++sis);
-    ssb->dw0.valid = 1;
-    ssb->dw0.buffer_address = pI915XvMC->ssb.offset;
-    ssb->dw1.length = ((sizeof(struct i915_3dstate_sampler_state) + 
-                        sizeof(struct texture_sampler) * 3) >> 2) - 1;
-
-    /* MSB */
-    msb = (msb_state *)(++ssb);
-    msb->dw0.valid = 1;
-    msb->dw0.buffer_address = pI915XvMC->msb.offset;
-    msb->dw1.length = ((sizeof(struct i915_3dstate_map_state) + 
-                        sizeof(struct texture_map) * 3) >> 2) - 1;
-
-    /* PSP */
-    psp = (psp_state *)(++msb);
-    psp->dw0.valid = 1;
-    psp->dw0.buffer_address = pI915XvMC->psp.offset;
-    psp->dw1.length = ((sizeof(struct i915_3dstate_pixel_shader_program) +
-                        sizeof(union shader_inst)) >> 2) - 1;
-
-    intelBatchbufferData(base, size, 0);
-    free(base);
-
-    /* 3DPRIMITIVE */
-    size = sizeof(*_3dprimitive) + sizeof(*vd) * 3;
-    base = calloc(1, size);
-    _3dprimitive = (struct i915_3dprimitive *)base;
-    _3dprimitive->dw0.inline_prim.type = CMD_3D;
-    _3dprimitive->dw0.inline_prim.opcode = OPC_3DPRIMITIVE;
-    _3dprimitive->dw0.inline_prim.vertex_location = VERTEX_INLINE;
-    _3dprimitive->dw0.inline_prim.prim = PRIM_RECTLIST;
-    _3dprimitive->dw0.inline_prim.length = size - 2;
-
-    vd = (struct vertex_data *)(++_3dprimitive);
-    vd->x = 0;          /* FIXME!!! */
-    vd->x = 0;          /* FIXME */
-    vd->tc0.tcx = 0;
-    vd->tc0.tcy = 0;
-    vd->tc1.tcx = 0;
-    vd->tc1.tcy = 0;
-
-    ++vd;
-    vd->x = 0;          /* FIXME!!! */
-    vd->x = 0;          /* FIXME */
-    vd->tc0.tcx = 0;
-    vd->tc0.tcy = 0;
-    vd->tc1.tcx = 0;
-    vd->tc1.tcy = 0;
-
-    ++vd;
-    vd->x = 0;          /* FIXME!!! */
-    vd->x = 0;          /* FIXME */
-    vd->tc0.tcx = 0;
-    vd->tc0.tcy = 0;
-    vd->tc1.tcx = 0;
-    vd->tc1.tcy = 0;
-
-    intelBatchbufferData(base, size, 0);
-    free(base);
-}
-
-/***************************************************************************
-// Function: i915_release_resource
-// Description:
-***************************************************************************/
-//XXX
-static void i915_release_resource(Display *display, XvMCContext *context)
-{
-    i915XvMCContext *pI915XvMC;
-    int screen = DefaultScreen(display);
-
-    if (!(pI915XvMC = context->privData))
-        return;
-
-    pI915XvMC->ref--;
-    i915_xvmc_unmap_buffers(pI915XvMC);
-
-    driDestroyHashContents(pI915XvMC->drawHash);
-    drmHashDestroy(pI915XvMC->drawHash);
-
-    pthread_mutex_destroy(&xvmc_driver->ctxmutex);
-
-    XLockDisplay(display);
-    uniDRIDestroyContext(display, screen, pI915XvMC->id);
-    XUnlockDisplay(display);
-
-    intelDestroyBatchBuffer();
-
-    drmUnmap(xvmc_driver->sarea_address, xvmc_driver->sarea_size);
-
-    if (xvmc_driver->fd >= 0)
-        drmClose(xvmc_driver->fd);
-    xvmc_driver->fd = -1;
-
-    XLockDisplay(display);
-    uniDRICloseConnection(display, screen);
-    _xvmc_destroy_context(display, context);
-    XUnlockDisplay(display);
-
-    free(pI915XvMC);
-    context->privData = NULL;
-}
-
-static Status i915_xvmc_mc_create_context(Display *display, XvMCContext *context,
-	int priv_count, CARD32 *priv_data)
-{
-    i915XvMCContext *pI915XvMC = NULL;
-    I915XvMCCreateContextRec *tmpComm = NULL;
-    Status ret;
-    drm_sarea_t *pSAREA;
-    char *curBusID;
-    uint magic;
-    int major, minor;
-    int isCapable;
-    int screen = DefaultScreen(display);
-
-    if (priv_count != (sizeof(I915XvMCCreateContextRec) >> 2)) {
-        XVMC_ERR("_xvmc_create_context() returned incorrect data size!");
-        XVMC_INFO("\tExpected %d, got %d",
-               (int)(sizeof(I915XvMCCreateContextRec) >> 2),priv_count);
-        _xvmc_destroy_context(display, context);
-        free(priv_data);
-        context->privData = NULL;
-        return BadValue;
-    }
-
-    context->privData = (void *)calloc(1, sizeof(i915XvMCContext));
-    if (!context->privData) {
-        XVMC_ERR("Unable to allocate resources for XvMC context.");
-        return BadAlloc;
-    }
-    pI915XvMC = (i915XvMCContext *)context->privData;
-
-    tmpComm = (I915XvMCCreateContextRec *)priv_data;
-    pI915XvMC->ctxno = tmpComm->ctxno;
-    pI915XvMC->deviceID = tmpComm->deviceID;
-    pI915XvMC->sis.handle = tmpComm->sis.handle;
-    pI915XvMC->sis.offset = tmpComm->sis.offset;
-    pI915XvMC->sis.size = tmpComm->sis.size;
-    pI915XvMC->ssb.handle = tmpComm->ssb.handle;
-    pI915XvMC->ssb.offset = tmpComm->ssb.offset;
-    pI915XvMC->ssb.size = tmpComm->ssb.size;
-    pI915XvMC->msb.handle = tmpComm->msb.handle;
-    pI915XvMC->msb.offset = tmpComm->msb.offset;
-    pI915XvMC->msb.size = tmpComm->msb.size;
-    pI915XvMC->psp.handle = tmpComm->psp.handle;
-    pI915XvMC->psp.offset = tmpComm->psp.offset;
-    pI915XvMC->psp.size = tmpComm->psp.size;
-    pI915XvMC->psc.handle = tmpComm->psc.handle;
-    pI915XvMC->psc.offset = tmpComm->psc.offset;
-    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->sis.bus_addr = tmpComm->sis.bus_addr;
-        pI915XvMC->ssb.bus_addr = tmpComm->ssb.bus_addr;
-        pI915XvMC->msb.bus_addr = tmpComm->msb.bus_addr;
-        pI915XvMC->psp.bus_addr = tmpComm->psp.bus_addr;
-        pI915XvMC->psc.bus_addr = tmpComm->psc.bus_addr;
-    }
-
-    pI915XvMC->corrdata.handle = tmpComm->corrdata.handle;
-    pI915XvMC->corrdata.offset = tmpComm->corrdata.offset;
-    pI915XvMC->corrdata.size = tmpComm->corrdata.size;
-    pI915XvMC->sarea_priv_offset = tmpComm->sarea_priv_offset;
-    pI915XvMC->depth = tmpComm->depth;
-
-    /* Must free the private data we were passed from X */
-    free(priv_data);
-    priv_data = NULL;
-
-    pSAREA = (drm_sarea_t *)xvmc_driver->sarea_address;
-    pI915XvMC->sarea = (drmI830Sarea*)((char*)pSAREA + pI915XvMC->sarea_priv_offset);
-    ret = XMatchVisualInfo(display, screen,
-                           (pI915XvMC->depth == 32) ? 24 : pI915XvMC->depth, TrueColor,
-                           &pI915XvMC->visualInfo);
-
-    if (!ret) {
-	XVMC_ERR("Could not find a matching TrueColor visual.");
-        free(pI915XvMC);
-        context->privData = NULL;
-        drmUnmap(xvmc_driver->sarea_address, xvmc_driver->sarea_size);
-        return BadAlloc;
-    }
-
-    if (!uniDRICreateContext(display, screen,
-                             pI915XvMC->visualInfo.visual, &pI915XvMC->id,
-                             &pI915XvMC->hHWContext)) {
-        XVMC_ERR("Could not create DRI context.");
-        free(pI915XvMC);
-        context->privData = NULL;
-        drmUnmap(xvmc_driver->sarea_address, xvmc_driver->sarea_size);
-        return BadAlloc;
-    }
-
-    if (NULL == (pI915XvMC->drawHash = drmHashCreate())) {
-	XVMC_ERR("Could not allocate drawable hash table.");
-        free(pI915XvMC);
-        context->privData = NULL;
-        return BadAlloc;
-    }
-
-    if (i915_xvmc_map_buffers(pI915XvMC)) {
-        i915_xvmc_unmap_buffers(pI915XvMC);
-        free(pI915XvMC);
-        context->privData = NULL;
-        return BadAlloc;
-    }
-
-    /* Initialize private context values */
-    pI915XvMC->yStride = STRIDE(context->width);
-    pI915XvMC->uvStride = STRIDE(context->width >> 1);
-    pI915XvMC->haveXv = 0;
-    pI915XvMC->dual_prime = 0;
-    pI915XvMC->last_flip = 0;
-    pI915XvMC->port = context->port;
-    pI915XvMC->ref = 1;
-    return Success;
-}
-
-/***************************************************************************
-// Function: XvMCDestroyContext
-// Description: Destorys the specified context.
-//
-// Arguments:
-//   display - Specifies the connection to the server.
-//   context - The context to be destroyed.
-//
-// Returns: Status
-***************************************************************************/
-static int i915_xvmc_mc_destroy_context(Display *display, XvMCContext *context)
-{
-    i915XvMCContext *pI915XvMC;
-
-    if (!(pI915XvMC = context->privData))
-        return XvMCBadContext;
-
-    /* Pass Control to the X server to destroy the drm_context_t */
-    i915_release_resource(display,context);
-    return Success;
-}
-
-/***************************************************************************
-// Function: XvMCCreateSurface
-***************************************************************************/
-static Status i915_xvmc_mc_create_surface(Display *display, XvMCContext *context, XvMCSurface *surface) 
-{
-    Status ret;
-    i915XvMCContext *pI915XvMC;
-    i915XvMCSurface *pI915Surface;
-    I915XvMCCreateSurfaceRec *tmpComm = NULL;
-    int priv_count;
-    uint *priv_data;
-
-    if (!display || !context || !display)
-        return BadValue;
-
-    if (!(pI915XvMC = context->privData))
-        return (error_base + XvMCBadContext);
-
-    PPTHREAD_MUTEX_LOCK();
-    surface->privData = (i915XvMCSurface *)malloc(sizeof(i915XvMCSurface));
-
-    if (!(pI915Surface = surface->privData)) {
-        PPTHREAD_MUTEX_UNLOCK();
-        return BadAlloc;
-    }
-
-    /* Initialize private values */
-    pI915Surface->last_render = 0;
-    pI915Surface->last_flip = 0;
-    pI915Surface->yStride = pI915XvMC->yStride;
-    pI915Surface->uvStride = pI915XvMC->uvStride;
-    pI915Surface->width = context->width;
-    pI915Surface->height = context->height;
-    pI915Surface->privContext = pI915XvMC;
-    pI915Surface->privSubPic = NULL;
-    pI915Surface->srf.map = NULL;
-    XLockDisplay(display);
-
-    if ((ret = _xvmc_create_surface(display, context, surface,
-                                    &priv_count, &priv_data))) {
-        XUnlockDisplay(display);
-        XVMC_ERR("Unable to create XvMCSurface.");
-        free(pI915Surface);
-        surface->privData = NULL;
-        PPTHREAD_MUTEX_UNLOCK();
-        return ret;
-    }
-
-    XUnlockDisplay(display);
-
-    if (priv_count != (sizeof(I915XvMCCreateSurfaceRec) >> 2)) {
-        XVMC_ERR("_xvmc_create_surface() returned incorrect data size!");
-        XVMC_INFO("\tExpected %d, got %d",
-               (int)(sizeof(I915XvMCCreateSurfaceRec) >> 2), priv_count);
-        _xvmc_destroy_surface(display, surface);
-        free(priv_data);
-        free(pI915Surface);
-        surface->privData = NULL;
-        PPTHREAD_MUTEX_UNLOCK();
-        return BadAlloc;
-    }
-
-    tmpComm = (I915XvMCCreateSurfaceRec *)priv_data;
-
-    pI915Surface->srfNo = tmpComm->srfno;
-    pI915Surface->srf.handle = tmpComm->srf.handle;
-    pI915Surface->srf.offset = tmpComm->srf.offset;
-    pI915Surface->srf.size = tmpComm->srf.size;
-    free(priv_data);
-
-    if (drmMap(xvmc_driver->fd,
-               pI915Surface->srf.handle,
-               pI915Surface->srf.size,
-               (drmAddress *)&pI915Surface->srf.map) != 0) {
-        _xvmc_destroy_surface(display, surface);
-        free(pI915Surface);
-        surface->privData = NULL;
-        PPTHREAD_MUTEX_UNLOCK();
-        return BadAlloc;
-    }
-
-    pI915XvMC->ref++;
-    PPTHREAD_MUTEX_UNLOCK();
-    return 0;
-}
-
-
-/***************************************************************************
-// Function: XvMCDestroySurface
-***************************************************************************/
-static int i915_xvmc_mc_destroy_surface(Display *display, XvMCSurface *surface) 
-{
-    i915XvMCSurface *pI915Surface;
-    i915XvMCContext *pI915XvMC;
-
-    if (!display || !surface)
-        return BadValue;
-
-    if (!(pI915Surface = surface->privData))
-        return (error_base + XvMCBadSurface);
-
-    if (!(pI915XvMC = pI915Surface->privContext))
-        return (error_base + XvMCBadSurface);
-
-    if (pI915Surface->last_flip)
-        XvMCSyncSurface(display,surface);
-
-    if (pI915Surface->srf.map)
-        drmUnmap(pI915Surface->srf.map, pI915Surface->srf.size);
-
-    XLockDisplay(display);
-    _xvmc_destroy_surface(display, surface);
-    XUnlockDisplay(display);
-
-    free(pI915Surface);
-    surface->privData = NULL;
-    pI915XvMC->ref--;
-
-    return Success;
-}
-
-
-/***************************************************************************
-// Function: XvMCRenderSurface
-// Description: This function does the actual HWMC. Given a list of
-//  macroblock structures it dispatched the hardware commands to execute
-//  them. 
-***************************************************************************/
-static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context,
-                         unsigned int picture_structure,
-                         XvMCSurface *target_surface,
-                         XvMCSurface *past_surface,
-                         XvMCSurface *future_surface,
-                         unsigned int flags,
-                         unsigned int num_macroblocks,
-                         unsigned int first_macroblock,
-                         XvMCMacroBlockArray *macroblock_array,
-                         XvMCBlockArray *blocks)
-{
-    int i;
-    int picture_coding_type = MPEG_I_PICTURE;
-    /* correction data buffer */
-    char *corrdata_ptr;
-    int corrdata_size = 0;
-
-    /* Block Pointer */
-    short *block_ptr;
-    /* Current Macroblock Pointer */
-    XvMCMacroBlock *mb;
-
-    i915XvMCSurface *privTarget = NULL;
-    i915XvMCSurface *privFuture = NULL;
-    i915XvMCSurface *privPast = NULL;
-    i915XvMCContext *pI915XvMC = NULL;
-
-    /* Check Parameters for validity */
-    if (!display || !context || !target_surface) {
-        XVMC_ERR("Invalid Display, Context or Target!");
-        return BadValue;
-    }
-
-    if (!num_macroblocks)
-        return Success;
-
-    if (!macroblock_array || !blocks) {
-        XVMC_ERR("Invalid block data!");
-        return BadValue;
-    }
-
-    if (macroblock_array->num_blocks < (num_macroblocks + first_macroblock)) {
-        XVMC_ERR("Too many macroblocks requested for MB array size.");
-        return BadValue;
-    }
-
-    if (!(pI915XvMC = context->privData))
-        return (error_base + XvMCBadContext);
-
-    if (!(privTarget = target_surface->privData))
-        return (error_base + XvMCBadSurface);
-
-    /* Test For YV12 Surface */
-    if (context->surface_type_id != FOURCC_YV12) {
-        XVMC_ERR("HWMC only possible on YV12 Surfaces.");
-        return BadValue;
-    }
-
-    /* P Frame Test */
-    if (!past_surface) {
-        /* Just to avoid some ifs later. */
-        privPast = privTarget;
-    } else {
-        if (!(privPast = past_surface->privData)) {
-            XVMC_ERR("Invalid Past Surface!");
-            return (error_base + XvMCBadSurface);
-        }
-        
-        picture_coding_type = MPEG_P_PICTURE;
-    }
-
-    /* B Frame Test */
-    if (!future_surface) {
-        privFuture = privPast; // privTarget;
-    } else {
-        if (!past_surface) {
-            XVMC_ERR("No Past Surface!");
-            return BadValue;
-        }
-
-        if (!(privFuture = future_surface->privData)) {
-            XVMC_ERR("Invalid Future Surface!");
-            return (error_base + XvMCBadSurface);
-        }
-
-        picture_coding_type = MPEG_B_PICTURE;
-    }
-
-    LOCK_HARDWARE(pI915XvMC->hHWContext);
-    corrdata_ptr = pI915XvMC->corrdata.map;
-    corrdata_size = 0;
-
-    for (i = first_macroblock; i < (num_macroblocks + first_macroblock); i++) {
-        int bspm = 0;
-        mb = &macroblock_array->macro_blocks[i];
-        block_ptr = &(blocks->blocks[mb->index << 6]);
-
-        /* Lockup can happen if the coordinates are too far out of range */
-        if (mb->x > (target_surface->width >> 4)) {
-            mb->x = 0;
-            XVMC_INFO("reset x");
-        }
-
-        if (mb->y > (target_surface->height >> 4)) {
-            mb->y = 0;
-            XVMC_INFO("reset y");
-        }
-
-        /* Catch no pattern case */
-        if (!(mb->macroblock_type & XVMC_MB_TYPE_PATTERN) &&
-            !(mb->macroblock_type & XVMC_MB_TYPE_INTRA) &&
-            mb->coded_block_pattern) {
-            mb->coded_block_pattern = 0;
-            XVMC_INFO("no coded blocks present!");
-        }
-        
-        bspm = mb_bytes[mb->coded_block_pattern];
-
-        if (!bspm)
-            continue;
-
-        corrdata_size += bspm;
-
-        if (corrdata_size > pI915XvMC->corrdata.size) {
-            XVMC_ERR("correction data buffer overflow.");
-            break;
-        }
-        memcpy(corrdata_ptr, block_ptr, bspm);
-        corrdata_ptr += bspm;
-    } 
-
-    i915_flush(1, 0);
-    // 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_static_indirect_state_buffer(context, target_surface, 
-                                         picture_structure, flags,
-                                         picture_coding_type);
-    i915_mc_map_state_buffer(context, privTarget, privPast, privFuture);
-    i915_mc_load_sis_msb_buffers(context);
-    i915_mc_mpeg_set_origin(context, &macroblock_array->macro_blocks[first_macroblock]);
-
-    for (i = first_macroblock; i < (num_macroblocks + first_macroblock); i++) {
-        mb = &macroblock_array->macro_blocks[i];
-
-        /* Intra Blocks */
-        if (mb->macroblock_type & XVMC_MB_TYPE_INTRA) {
-            i915_mc_mpeg_macroblock_ipicture(context, mb);
-        } else if ((picture_structure & XVMC_FRAME_PICTURE) == XVMC_FRAME_PICTURE) { /* Frame Picture */
-            switch (mb->motion_type & 3) {
-            case XVMC_PREDICTION_FIELD: /* Field Based */
-                i915_mc_mpeg_macroblock_2fbmv(context, mb, picture_structure);
-                break;
-
-            case XVMC_PREDICTION_FRAME: /* Frame Based */
-                i915_mc_mpeg_macroblock_1fbmv(context, mb);
-                break;
-
-            case XVMC_PREDICTION_DUAL_PRIME:    /* Dual Prime */
-                i915_mc_mpeg_macroblock_2fbmv(context, mb, picture_structure);
-                break;
-
-            default:    /* No Motion Type */
-                renderError();
-                break;
-            }   
-        } else {        /* Frame Picture */
-            switch (mb->motion_type & 3) {
-            case XVMC_PREDICTION_FIELD: /* Field Based */
-                i915_mc_mpeg_macroblock_1fbmv(context, mb);
-                break;
-
-            case XVMC_PREDICTION_16x8:  /* 16x8 MC */
-                i915_mc_mpeg_macroblock_2fbmv(context, mb, picture_structure);
-                break;
-                
-            case XVMC_PREDICTION_DUAL_PRIME:    /* Dual Prime */
-                i915_mc_mpeg_macroblock_1fbmv(context, mb);
-                break;
-
-            default:    /* No Motion Type */
-                renderError();
-                break;
-            }
-        }       /* Field Picture */
-    }
-
-    intelFlushBatch(TRUE);
-    xvmc_driver->last_render = xvmc_driver->alloc.irq_emitted;
-    privTarget->last_render = xvmc_driver->last_render;
-
-    UNLOCK_HARDWARE(pI915XvMC->hHWContext);
-    return 0;
-}
-
-/***************************************************************************
-// Function: XvMCPutSurface
-// Description:
-// Arguments:
-//  display: Connection to X server
-//  surface: Surface to be displayed
-//  draw: X Drawable on which to display the surface
-//  srcx: X coordinate of the top left corner of the region to be
-//          displayed within the surface.
-//  srcy: Y coordinate of the top left corner of the region to be
-//          displayed within the surface.
-//  srcw: Width of the region to be displayed.
-//  srch: Height of the region to be displayed.
-//  destx: X cordinate of the top left corner of the destination region
-//         in the drawable coordinates.
-//  desty: Y cordinate of the top left corner of the destination region
-//         in the drawable coordinates.
-//  destw: Width of the destination region.
-//  desth: Height of the destination region.
-//  flags: One or more of the following.
-//     XVMC_TOP_FIELD - Display only the Top field of the surface.
-//     XVMC_BOTTOM_FIELD - Display only the Bottom Field of the surface.
-//     XVMC_FRAME_PICTURE - Display both fields or frame.
-//
-// Info: Portions of this function derived from i915_video.c (XFree86)
-//
-//   This function is organized so that we wait as long as possible before
-//   touching the overlay registers. Since we don't know that the last
-//   flip has happened yet we want to give the overlay as long as
-//   possible to catch up before we have to check on its progress. This
-//   makes it unlikely that we have to wait on the last flip.
-***************************************************************************/
-static int i915_xvmc_mc_put_surface(Display *display,XvMCSurface *surface,
-                      Drawable draw, short srcx, short srcy,
-                      unsigned short srcw, unsigned short srch,
-                      short destx, short desty,
-                      unsigned short destw, unsigned short desth,
-                      int flags) 
-{
-    i915XvMCContext *pI915XvMC;
-    i915XvMCSurface *pI915Surface;
-    i915XvMCSubpicture *pI915SubPic;
-    I915XvMCCommandBuffer buf;
-
-    // drawableInfo *drawInfo;
-    Status ret;
-
-    if (!display || !surface)
-        return BadValue;
-
-    if (!(pI915Surface = surface->privData))
-        return (error_base + XvMCBadSurface);
-
-    if (!(pI915XvMC = pI915Surface->privContext))
-        return (error_base + XvMCBadSurface);
-
-    PPTHREAD_MUTEX_LOCK();
-    /*
-    if (getDRIDrawableInfoLocked(pI915XvMC->drawHash, display,
-                                 pI915XvMC->screen, draw, 0, pI915XvMC->fd, pI915XvMC->hHWContext,
-                                 pI915XvMC->sarea_address, FALSE, &drawInfo, sizeof(*drawInfo))) {
-        PPTHREAD_MUTEX_UNLOCK();
-        return BadAccess;
-    }
-    */
-    if (!pI915XvMC->haveXv) {
-        pI915XvMC->xvImage =
-            XvCreateImage(display, pI915XvMC->port, FOURCC_XVMC,
-                          (char *)&buf, pI915Surface->width, pI915Surface->height);
-        pI915XvMC->gc = XCreateGC(display, draw, 0, 0);
-        pI915XvMC->haveXv = 1;
-    }
-
-    pI915XvMC->draw = draw;
-    pI915XvMC->xvImage->data = (char *)&buf;
-
-    buf.command = INTEL_XVMC_COMMAND_DISPLAY;
-    buf.ctxNo = pI915XvMC->ctxno;
-    buf.srfNo = pI915Surface->srfNo;
-    pI915SubPic = pI915Surface->privSubPic;
-    buf.subPicNo = (!pI915SubPic ? 0 : pI915SubPic->srfNo);
-    buf.real_id = FOURCC_YV12;
-
-    XLockDisplay(display);
-
-    if ((ret = XvPutImage(display, pI915XvMC->port, draw, pI915XvMC->gc,
-                          pI915XvMC->xvImage, srcx, srcy, srcw, srch,
-                          destx, desty, destw, desth))) {
-        XUnlockDisplay(display);
-        PPTHREAD_MUTEX_UNLOCK();
-
-        return ret;
-    }
-
-    XSync(display, 0);
-    XUnlockDisplay(display);
-    PPTHREAD_MUTEX_UNLOCK();
-
-    return 0;
-}
-
-/***************************************************************************
-// Function: XvMCSyncSurface
-// Arguments:
-//   display - Connection to the X server
-//   surface - The surface to synchronize
-// Info:
-// Returns: Status
-***************************************************************************/
-#if 0
-Status XvMCSyncSurface(Display *display, XvMCSurface *surface) 
-{
-    Status ret;
-    int stat = 0;
-
-    do {
-        ret = XvMCGetSurfaceStatus(display, surface, &stat);
-    } while (!ret && (stat & XVMC_RENDERING));
-
-    return ret;
-}
-
-/***************************************************************************
-// Function: XvMCFlushSurface
-// Description:
-//   This function commits pending rendering requests to ensure that they
-//   wll be completed in a finite amount of time.
-// Arguments:
-//   display - Connection to X server
-//   surface - Surface to flush
-// Returns: Status
-***************************************************************************/
-Status XvMCFlushSurface(Display * display, XvMCSurface *surface) 
-{
-    return Success;
-}
-#endif
-
-/***************************************************************************
-// Function: XvMCGetSurfaceStatus
-// Description:
-// Arguments:
-//  display: connection to X server
-//  surface: The surface to query
-//  stat: One of the Following
-//    XVMC_RENDERING - The last XvMCRenderSurface command has not
-//                     completed.
-//    XVMC_DISPLAYING - The surface is currently being displayed or a
-//                     display is pending.
-***************************************************************************/
-static int i915_xvmc_mc_get_surface_status(Display *display, XvMCSurface *surface, int *stat) 
-{
-    i915XvMCSurface *pI915Surface;
-    i915XvMCContext *pI915XvMC;
-
-    if (!display || !surface || !stat)
-        return BadValue;
-    
-    *stat = 0;
-
-    if (!(pI915Surface = surface->privData))
-        return (error_base + XvMCBadSurface);
-
-    if (!(pI915XvMC = pI915Surface->privContext))
-        return (error_base + XvMCBadSurface);
-
-    // LOCK_HARDWARE(pI915XvMC->hHWContext);
-    PPTHREAD_MUTEX_LOCK();
-    if (pI915Surface->last_flip) {
-        /* This can not happen */
-        if (pI915XvMC->last_flip < pI915Surface->last_flip) {
-            XVMC_ERR("Context last flip is less than surface last flip.");
-            PPTHREAD_MUTEX_UNLOCK();
-            return BadValue;
-        }
-
-        /*
-          If the context has 2 or more flips after this surface it
-          cannot be displaying. Don't bother to check.
-        */
-        if (!(pI915XvMC->last_flip > (pI915Surface->last_flip + 1))) {
-            /*
-              If this surface was the last flipped it is either displaying
-              or about to be so don't bother checking.
-            */
-            if (pI915XvMC->last_flip == pI915Surface->last_flip) {
-                *stat |= XVMC_DISPLAYING;
-            }
-        }
-    }
-
-    if (pI915Surface->last_render &&
-        (pI915Surface->last_render > pI915XvMC->sarea->last_dispatch)) {
-        *stat |= XVMC_RENDERING;
-    }
-
-    // UNLOCK_HARDWARE(pI915XvMC->hHWContext);
-    PPTHREAD_MUTEX_UNLOCK();
-    return 0;
-}
-
-/***************************************************************************
-// 
-//  Surface manipulation functions
-//
-***************************************************************************/
-
-/***************************************************************************
-// Function: XvMCHideSurface
-// Description: Stops the display of a surface.
-// Arguments:
-//   display - Connection to the X server.
-//   surface - surface to be hidden.
-//
-// Returns: Status
-***************************************************************************/
-#if 0
-Status XvMCHideSurface(Display *display, XvMCSurface *surface) 
-{
-    i915XvMCSurface *pI915Surface;
-    i915XvMCContext *pI915XvMC;
-    int stat = 0, ret;
-
-    if (!display || !surface)
-        return BadValue;
-
-    if (!(pI915Surface = surface->privData))
-        return (error_base + XvMCBadSurface);
-
-    /* Get the associated context pointer */
-    if (!(pI915XvMC = pI915Surface->privContext))
-        return (error_base + XvMCBadSurface);
-
-    XvMCSyncSurface(display, surface);
-
-    /*
-      Get the status of the surface, if it is not currently displayed
-      we don't need to worry about it.
-    */
-    if ((ret = XvMCGetSurfaceStatus(display, surface, &stat)) != Success)
-        return ret;
-
-    if (!(stat & XVMC_DISPLAYING))
-        return Success;
-
-    /* FIXME: */
-    return Success;
-}
-
-/***************************************************************************
-//
-// Functions that deal with subpictures
-//
-***************************************************************************/
-
-
-
-/***************************************************************************
-// Function: XvMCCreateSubpicture
-// Description: This creates a subpicture by filling out the XvMCSubpicture
-//              structure passed to it and returning Success.
-// Arguments:
-//   display - Connection to the X server.
-//   context - The context to create the subpicture for.
-//   subpicture - Pre-allocated XvMCSubpicture structure to be filled in.
-//   width - of subpicture
-//   height - of subpicture
-//   xvimage_id - The id describing the XvImage format.
-//
-// Returns: Status
-***************************************************************************/
-Status XvMCCreateSubpicture(Display *display, XvMCContext *context,
-                            XvMCSubpicture *subpicture,
-                            unsigned short width, unsigned short height,
-                            int xvimage_id) 
-{
-    Status ret;
-    i915XvMCContext *pI915XvMC;
-    i915XvMCSubpicture *pI915Subpicture;
-    I915XvMCCreateSurfaceRec *tmpComm = NULL;
-    int priv_count;
-    uint *priv_data;
-
-    if (!subpicture || !context || !display)
-        return BadValue;
-  
-    pI915XvMC = (i915XvMCContext *)context->privData;
-
-    if (!pI915XvMC)
-        return (error_base + XvMCBadContext);
-
-    subpicture->privData =
-        (i915XvMCSubpicture *)malloc(sizeof(i915XvMCSubpicture));
-
-    if (!subpicture->privData)
-        return BadAlloc;
-
-    PPTHREAD_MUTEX_LOCK();
-    subpicture->context_id = context->context_id;
-    subpicture->xvimage_id = xvimage_id;
-    subpicture->width = width;
-    subpicture->height = height;
-    pI915Subpicture = (i915XvMCSubpicture *)subpicture->privData;
-
-    XLockDisplay(display);
-    if ((ret = _xvmc_create_subpicture(display, context, subpicture,
-                                       &priv_count, &priv_data))) {
-        XUnlockDisplay(display);
-        XVMC_ERR("Unable to create XvMCSubpicture.");
-        free(pI915Subpicture);
-        subpicture->privData = NULL;
-        PPTHREAD_MUTEX_UNLOCK();
-        return ret;
-    }
-    XUnlockDisplay(display);
-
-    if (priv_count != (sizeof(I915XvMCCreateSurfaceRec) >> 2)) {
-        XVMC_ERR("_xvmc_create_subpicture() returned incorrect data size!");
-        XVMC_INFO("\tExpected %d, got %d", 
-               (int)(sizeof(I915XvMCCreateSurfaceRec) >> 2), priv_count);
-        XLockDisplay(display);
-        _xvmc_destroy_subpicture(display, subpicture);
-        XUnlockDisplay(display);
-        free(priv_data);
-        free(pI915Subpicture);
-        subpicture->privData = NULL;
-        PPTHREAD_MUTEX_UNLOCK();
-        return BadAlloc;
-    }
-
-    tmpComm = (I915XvMCCreateSurfaceRec *)priv_data;
-    pI915Subpicture->srfNo = tmpComm->srfno;
-    pI915Subpicture->srf.handle = tmpComm->srf.handle;
-    pI915Subpicture->srf.offset = tmpComm->srf.offset;
-    pI915Subpicture->srf.size = tmpComm->srf.size;
-    free(priv_data);
-
-    if (drmMap(pI915XvMC->fd,
-               pI915Subpicture->srf.handle,
-               pI915Subpicture->srf.size,
-               (drmAddress *)&pI915Subpicture->srf.map) != 0) {
-        XLockDisplay(display);
-        _xvmc_destroy_subpicture(display, subpicture);
-        XUnlockDisplay(display);
-        free(pI915Subpicture);
-        subpicture->privData = NULL;
-        PPTHREAD_MUTEX_UNLOCK();
-        return BadAlloc;
-    }
-
-    /* subpicture */
-    subpicture->num_palette_entries = I915_SUBPIC_PALETTE_SIZE;
-    subpicture->entry_bytes = 3;
-    strncpy(subpicture->component_order, "YUV", 4);
-
-    /* Initialize private values */
-    pI915Subpicture->privContext = pI915XvMC;
-    pI915Subpicture->last_render= 0;
-    pI915Subpicture->last_flip = 0;
-    pI915Subpicture->pitch = ((subpicture->width + 3) & ~3);
-
-    switch(subpicture->xvimage_id) {
-    case FOURCC_IA44:
-    case FOURCC_AI44:
-        break;
-
-    default:
-        drmUnmap(pI915Subpicture->srf.map, pI915Subpicture->srf.size);
-        XLockDisplay(display);
-        _xvmc_destroy_subpicture(display, subpicture);
-        XUnlockDisplay(display);
-        free(pI915Subpicture);
-        subpicture->privData = NULL;
-        PPTHREAD_MUTEX_UNLOCK();
-        return BadMatch;
-    }
-
-    pI915XvMC->ref++;
-    PPTHREAD_MUTEX_UNLOCK();
-    return Success;
-}
-
-/***************************************************************************
-// Function: XvMCClearSubpicture
-// Description: Clear the area of the given subpicture to "color".
-//              structure passed to it and returning Success.
-// Arguments:
-//   display - Connection to the X server.
-//   subpicture - Subpicture to clear.
-//   x, y, width, height - rectangle in the subpicture to clear.
-//   color - The data to file the rectangle with.
-//
-// Returns: Status
-***************************************************************************/
-Status XvMCClearSubpicture(Display *display, XvMCSubpicture *subpicture,
-                           short x, short y,
-                           unsigned short width, unsigned short height,
-                           unsigned int color) 
-{
-    i915XvMCContext *pI915XvMC;
-    i915XvMCSubpicture *pI915Subpicture;
-
-    if (!display || !subpicture)
-        return BadValue;
-
-    if (!(pI915Subpicture = subpicture->privData))
-        return (error_base + XvMCBadSubpicture);
-
-    if (!(pI915XvMC = pI915Subpicture->privContext))
-        return (error_base + XvMCBadSubpicture);
-
-    if ((x < 0) || (x + width) > subpicture->width)
-        return BadValue;
-
-    if ((y < 0) || (y + height) > subpicture->height)
-        return BadValue;
-
-    /* FIXME: clear the area */
-
-    return Success;
-}
-
-/***************************************************************************
-// Function: XvMCCompositeSubpicture
-// Description: Composite the XvImae on the subpicture. This composit uses
-//              non-premultiplied alpha. Destination alpha is utilized
-//              except for with indexed subpictures. Indexed subpictures
-//              use a simple "replace".
-// Arguments:
-//   display - Connection to the X server.
-//   subpicture - Subpicture to clear.
-//   image - the XvImage to be used as the source of the composite.
-//   srcx, srcy, width, height - The rectangle from the image to be used.
-//   dstx, dsty - location in the subpicture to composite the source.
-//
-// Returns: Status
-***************************************************************************/
-Status XvMCCompositeSubpicture(Display *display, XvMCSubpicture *subpicture,
-                               XvImage *image,
-                               short srcx, short srcy,
-                               unsigned short width, unsigned short height,
-                               short dstx, short dsty) 
-{
-    i915XvMCContext *pI915XvMC;
-    i915XvMCSubpicture *pI915Subpicture;
-
-    if (!display || !subpicture)
-        return BadValue;
-
-    if (!(pI915Subpicture = subpicture->privData))
-        return (error_base + XvMCBadSubpicture);
-
-    if (!(pI915XvMC = pI915Subpicture->privContext))
-        return (error_base + XvMCBadSubpicture);
-
-    if ((srcx < 0) || (srcx + width) > subpicture->width)
-        return BadValue;
-
-    if ((srcy < 0) || (srcy + height) > subpicture->height)
-        return BadValue;
-
-    if ((dstx < 0) || (dstx + width) > subpicture->width)
-        return BadValue;
-
-    if ((dsty < 0) || (dsty + width) > subpicture->height)
-        return BadValue;
-
-    if (image->id != subpicture->xvimage_id)
-        return BadMatch;
-
-    /* FIXME */
-    return Success;
-}
-
-
-/***************************************************************************
-// Function: XvMCDestroySubpicture
-// Description: Destroys the specified subpicture.
-// Arguments:
-//   display - Connection to the X server.
-//   subpicture - Subpicture to be destroyed.
-//
-// Returns: Status
-***************************************************************************/
-Status XvMCDestroySubpicture(Display *display, XvMCSubpicture *subpicture) 
-{
-    i915XvMCSubpicture *pI915Subpicture;
-    i915XvMCContext *pI915XvMC;
-
-    if (!display || !subpicture)
-        return BadValue;
-
-    if (!(pI915Subpicture = subpicture->privData))
-        return (error_base + XvMCBadSubpicture);
-
-    if (!(pI915XvMC = pI915Subpicture->privContext))
-        return (error_base + XvMCBadSubpicture);
-
-    if (pI915Subpicture->last_render)
-        XvMCSyncSubpicture(display, subpicture);
-
-    if (pI915Subpicture->srf.map)
-        drmUnmap(pI915Subpicture->srf.map, pI915Subpicture->srf.size);
-
-    PPTHREAD_MUTEX_LOCK();
-    XLockDisplay(display);
-    _xvmc_destroy_subpicture(display,subpicture);
-    XUnlockDisplay(display);
-
-    free(pI915Subpicture);
-    subpicture->privData = NULL;
-    pI915XvMC->ref--;
-    PPTHREAD_MUTEX_UNLOCK();
-
-    return Success;
-}
-
-
-/***************************************************************************
-// Function: XvMCSetSubpicturePalette
-// Description: Set the subpictures palette
-// Arguments:
-//   display - Connection to the X server.
-//   subpicture - Subpiture to set palette for.
-//   palette - A pointer to an array holding the palette data. The array
-//     is num_palette_entries * entry_bytes in size.
-// Returns: Status
-***************************************************************************/
-
-Status XvMCSetSubpicturePalette(Display *display, XvMCSubpicture *subpicture,
-                                unsigned char *palette) 
-{
-    i915XvMCSubpicture *pI915Subpicture;
-    int i, j;
-
-    if (!display || !subpicture)
-        return BadValue;
-
-    if (!(pI915Subpicture = subpicture->privData))
-        return (error_base + XvMCBadSubpicture);
-
-    j = 0;
-    for (i = 0; i < 16; i++) {
-        pI915Subpicture->palette[0][i] = palette[j++];
-        pI915Subpicture->palette[1][i] = palette[j++];
-        pI915Subpicture->palette[2][i] = palette[j++];
-    }
-
-    /* FIXME: Update the subpicture with the new palette */
-    return Success;
-}
-
-/***************************************************************************
-// Function: XvMCBlendSubpicture
-// Description: 
-//    The behavior of this function is different depending on whether
-//    or not the XVMC_BACKEND_SUBPICTURE flag is set in the XvMCSurfaceInfo.
-//    i915 only support frontend behavior.
-//  
-//    XVMC_BACKEND_SUBPICTURE not set ("frontend" behavior):
-//   
-//    XvMCBlendSubpicture is a no-op in this case.
-//   
-// Arguments:
-//   display - Connection to the X server.
-//   subpicture - The subpicture to be blended into the video.
-//   target_surface - The surface to be displayed with the blended subpic.
-//   source_surface - Source surface prior to blending.
-//   subx, suby, subw, subh - The rectangle from the subpicture to use.
-//   surfx, surfy, surfw, surfh - The rectangle in the surface to blend
-//      blend the subpicture rectangle into. Scaling can ocure if 
-//      XVMC_SUBPICTURE_INDEPENDENT_SCALING is set.
-//
-// Returns: Status
-***************************************************************************/
-Status XvMCBlendSubpicture(Display *display, XvMCSurface *target_surface,
-                           XvMCSubpicture *subpicture,
-                           short subx, short suby,
-                           unsigned short subw, unsigned short subh,
-                           short surfx, short surfy,
-                           unsigned short surfw, unsigned short surfh) 
-{
-    i915XvMCSubpicture *pI915Subpicture;
-    i915XvMCSurface *privTargetSurface;
-
-    if (!display || !target_surface)
-        return BadValue;
-
-    if (!(privTargetSurface = target_surface->privData))
-        return (error_base + XvMCBadSurface);
-
-    if (subpicture) {
-        if (!(pI915Subpicture = subpicture->privData))
-            return (error_base + XvMCBadSubpicture);
-
-        if ((FOURCC_AI44 != subpicture->xvimage_id) &&
-            (FOURCC_IA44 != subpicture->xvimage_id))
-            return (error_base + XvMCBadSubpicture);
-
-        privTargetSurface->privSubPic = pI915Subpicture;
-    } else {
-        privTargetSurface->privSubPic = NULL;
-    }
-
-    return Success;
-}
-
-/***************************************************************************
-// Function: XvMCBlendSubpicture2
-// Description: 
-//    The behavior of this function is different depending on whether
-//    or not the XVMC_BACKEND_SUBPICTURE flag is set in the XvMCSurfaceInfo.
-//    i915 only supports frontend blending.
-//  
-//    XVMC_BACKEND_SUBPICTURE not set ("frontend" behavior):
-//   
-//    XvMCBlendSubpicture2 blends the source_surface and subpicture and
-//    puts it in the target_surface.  This does not effect the status of
-//    the source surface but will cause the target_surface to query
-//    XVMC_RENDERING until the blend is completed.
-//   
-// Arguments:
-//   display - Connection to the X server.
-//   subpicture - The subpicture to be blended into the video.
-//   target_surface - The surface to be displayed with the blended subpic.
-//   source_surface - Source surface prior to blending.
-//   subx, suby, subw, subh - The rectangle from the subpicture to use.
-//   surfx, surfy, surfw, surfh - The rectangle in the surface to blend
-//      blend the subpicture rectangle into. Scaling can ocure if 
-//      XVMC_SUBPICTURE_INDEPENDENT_SCALING is set.
-//
-// Returns: Status
-***************************************************************************/
-Status XvMCBlendSubpicture2(Display *display, 
-                            XvMCSurface *source_surface,
-                            XvMCSurface *target_surface,
-                            XvMCSubpicture *subpicture,
-                            short subx, short suby,
-                            unsigned short subw, unsigned short subh,
-                            short surfx, short surfy,
-                            unsigned short surfw, unsigned short surfh)
-{
-    i915XvMCContext *pI915XvMC;
-    i915XvMCSubpicture *pI915Subpicture;
-    i915XvMCSurface *privSourceSurface;
-    i915XvMCSurface *privTargetSurface;
-
-    if (!display || !source_surface || !target_surface)
-        return BadValue;
-
-    if (!(privSourceSurface = source_surface->privData))
-        return (error_base + XvMCBadSurface);
-
-    if (!(privTargetSurface = target_surface->privData))
-        return (error_base + XvMCBadSurface);
-
-    if (!(pI915XvMC = privTargetSurface->privContext))
-        return (error_base + XvMCBadSurface);
-
-    if (((surfx + surfw) > privTargetSurface->width) ||
-        ((surfy + surfh) > privTargetSurface->height))
-        return BadValue;
-
-    if ((privSourceSurface->width != privTargetSurface->width) ||
-        (privTargetSurface->height != privTargetSurface->height))
-        return BadValue;
-
-    if (XvMCSyncSurface(display, source_surface))
-        return BadValue;
-
-    /* FIXME: update Target Surface */
-
-    if (subpicture) {
-        if (((subx + subw) > subpicture->width) ||
-            ((suby + subh) > subpicture->height))
-            return BadValue;
-
-        if (!(pI915Subpicture = subpicture->privData))
-            return (error_base + XvMCBadSubpicture);
-
-        if ((FOURCC_AI44 != subpicture->xvimage_id) &&
-            (FOURCC_IA44 != subpicture->xvimage_id))
-            return (error_base + XvMCBadSubpicture);
-
-        privTargetSurface->privSubPic = pI915Subpicture;
-    } else {
-        privTargetSurface->privSubPic = NULL;
-    }
-
-    return Success;
-}
-
-/***************************************************************************
-// Function: XvMCSyncSubpicture
-// Description: This function blocks until all composite/clear requests on
-//              the subpicture have been complete.
-// Arguments:
-//   display - Connection to the X server.
-//   subpicture - The subpicture to synchronize
-//
-// Returns: Status
-***************************************************************************/
-Status XvMCSyncSubpicture(Display *display, XvMCSubpicture *subpicture) 
-{
-    Status ret;
-    int stat = 0;
-
-    if (!display || !subpicture)
-        return BadValue;
-
-    do {
-        ret = XvMCGetSubpictureStatus(display, subpicture, &stat);
-    } while(!ret && (stat & XVMC_RENDERING));
-
-    return ret;
-}
-
-/***************************************************************************
-// Function: XvMCFlushSubpicture
-// Description: This function commits pending composite/clear requests to
-//              ensure that they will be completed in a finite amount of
-//              time.
-// Arguments:
-//   display - Connection to the X server.
-//   subpicture - The subpicture whos compsiting should be flushed
-//
-// Returns: Status
-***************************************************************************/
-Status XvMCFlushSubpicture(Display *display, XvMCSubpicture *subpicture) 
-{
-    i915XvMCSubpicture *pI915Subpicture;
-
-    if (!display || !subpicture)
-        return BadValue;
-
-    if (!(pI915Subpicture = subpicture->privData))
-        return (error_base + XvMCBadSubpicture);
-
-    return Success;
-}
-
-/***************************************************************************
-// Function: XvMCGetSubpictureStatus
-// Description: This function gets the current status of a subpicture
-//
-// Arguments:
-//   display - Connection to the X server.
-//   subpicture - The subpicture whos status is being queried
-//   stat - The status of the subpicture. It can be any of the following
-//          OR'd together:
-//          XVMC_RENDERING  - Last composite or clear request not completed
-//          XVMC_DISPLAYING - Suppicture currently being displayed.
-//
-// Returns: Status
-***************************************************************************/
-Status XvMCGetSubpictureStatus(Display *display, XvMCSubpicture *subpicture,
-                               int *stat) 
-{
-    i915XvMCSubpicture *pI915Subpicture;
-    i915XvMCContext *pI915XvMC;
-
-    if (!display || !subpicture || stat)
-        return BadValue;
-
-    *stat = 0;
-
-    if (!(pI915Subpicture = subpicture->privData))
-        return (error_base + XvMCBadSubpicture);
-
-    if (!(pI915XvMC = pI915Subpicture->privContext))
-        return (error_base + XvMCBadSubpicture);
-
-    // LOCK_HARDWARE(pI915XvMC->hHWContext);
-    PPTHREAD_MUTEX_LOCK();
-    /* FIXME: */
-    if (pI915Subpicture->last_render &&
-        (pI915Subpicture->last_render > pI915XvMC->sarea->last_dispatch)) {
-        *stat |= XVMC_RENDERING;
-    }
-
-    // UNLOCK_HARDWARE(pI915XvMC->hHWContext);
-    PPTHREAD_MUTEX_UNLOCK();
-    return Success;
-}
-
-#endif
diff --git a/src/xvmc/I915XvMC.h b/src/xvmc/I915XvMC.h
deleted file mode 100644
index a470558..0000000
--- a/src/xvmc/I915XvMC.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright © 2006 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Authors:
- *    Xiang Haihao <haihao.xiang at intel.com>
- *
- */
-
-#ifndef _I915XVMC_H
-#define _I915XVMC_H
-
-/* #define XVMC_DEBUG(x) do {x; }while(0); */
-#define XVMC_DEBUG(x)
-
-#include "intel_xvmc.h"
-#include "i915_hwmc.h"
-
-#define I915_SUBPIC_PALETTE_SIZE        16
-#define MAX_SUBCONTEXT_LEN              1024
-
-#define PCI_CHIP_I915_G                 0x2582
-#define PCI_CHIP_I915_GM                0x2592
-#define PCI_CHIP_I945_G                 0x2772
-#define PCI_CHIP_I945_GM                0x27A2
-#define PCI_CHIP_I945_GME               0x27AE
-#define PCI_CHIP_G33_G                  0x29C2
-#define PCI_CHIP_Q35_G                  0x29B2
-#define PCI_CHIP_Q33_G                  0x29D2
-
-/***************************************************************************
-// i915XvMCDrmMap: Holds the data about the DRM maps
-***************************************************************************/
-typedef struct _i915XvMCDrmMap {
-    drm_handle_t handle;
-    unsigned long offset;
-    unsigned long size;
-    unsigned long bus_addr;
-    drmAddress map;
-} i915XvMCDrmMap, *i915XvMCDrmMapPtr;
-
-/***************************************************************************
-// i915XvMCContext: Private Context data referenced via the privData
-//  pointer in the XvMCContext structure.
-***************************************************************************/
-typedef struct _i915XvMCContext {
-    unsigned int ctxno;
-    unsigned int last_flip;
-    unsigned int dual_prime; /* Flag to identify when dual prime is in use. */
-    unsigned int yStride;
-    unsigned int uvStride;
-    unsigned short ref;
-    volatile drmI830Sarea *sarea;
-    drm_context_t hHWContext; /* drmcontext; */
-    unsigned int sarea_priv_offset;	        /* Offset in sarea to private part */
-    unsigned int depth;
-    XvPortID port;		       /* Xv Port ID when displaying */
-    int haveXv;                        /* Have I initialized the Xv
-                                        * connection for this surface? */
-    XvImage *xvImage;                  /* Fake Xv Image used for command
-                                        * buffer transport to the X server */
-    GC  gc;                            /* X GC needed for displaying */
-    Drawable draw;                     /* Drawable to undisplay from */
-    XID id;
-    XVisualInfo visualInfo;
-    void *drawHash;
-    int deviceID;
-
-    i915XvMCDrmMap sis;
-    i915XvMCDrmMap msb;
-    i915XvMCDrmMap ssb;
-    i915XvMCDrmMap psp;
-    i915XvMCDrmMap psc;
-    i915XvMCDrmMap corrdata;
-} i915XvMCContext;
-
-/***************************************************************************
-// i915XvMCSubpicture: Private data structure for each XvMCSubpicture. This
-//  structure is referenced by the privData pointer in the XvMCSubpicture
-//  structure.
-***************************************************************************/
-typedef struct _i915XvMCSubpicture {
-    unsigned int srfNo;
-    unsigned int last_render;
-    unsigned int last_flip;
-    unsigned int pitch;
-    unsigned char palette[3][16];
-    i915XvMCDrmMap srf;
-    i915XvMCContext *privContext;
-} i915XvMCSubpicture;
-
-/***************************************************************************
-// i915XvMCSurface: Private data structure for each XvMCSurface. This
-//  structure is referenced by the privData pointer in the XvMCSurface
-//  structure.
-***************************************************************************/
-#define I830_MAX_BUFS 2                   /*Number of YUV buffers per surface */
-typedef struct _i915XvMCSurface {
-    unsigned int srfNo;                    /* XvMC private surface numbers */
-    unsigned int last_render;
-    unsigned int last_flip;
-    unsigned int yStride;                  /* Stride of YUV420 Y component. */
-    unsigned int uvStride;
-    unsigned int width;                    /* Dimensions */
-    unsigned int height;
-    i915XvMCDrmMap srf;
-    i915XvMCContext *privContext;
-    i915XvMCSubpicture *privSubPic;     /* Subpicture to be blended when
-                                         * displaying. NULL if none. */
-} i915XvMCSurface;
-
-#endif /* _I915XVMC_H */
diff --git a/src/xvmc/Makefile.am b/src/xvmc/Makefile.am
index 09c8c4d..17867db 100644
--- a/src/xvmc/Makefile.am
+++ b/src/xvmc/Makefile.am
@@ -11,8 +11,8 @@ libI810XvMC_la_LIBADD = @DRI_LIBS@
 
 libIntelXvMC_la_SOURCES = intel_xvmc.c \
 			 intel_xvmc.h \
-			 I915XvMC.c \
-                         I915XvMC.h \
+			 i915_xvmc.c \
+                         i915_xvmc.h \
                          intel_batchbuffer.c \
                          intel_batchbuffer.h \
                          xf86dri.c \
diff --git a/src/xvmc/i915_xvmc.c b/src/xvmc/i915_xvmc.c
new file mode 100644
index 0000000..911b80e
--- /dev/null
+++ b/src/xvmc/i915_xvmc.c
@@ -0,0 +1,2934 @@
+/*
+ * Copyright © 2006 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *    Xiang Haihao <haihao.xiang at intel.com>
+ *
+ */
+
+#include <pthread.h>
+#include <sys/ioctl.h>
+
+#include "i915_xvmc.h"
+#include "i915_structs.h"
+#include "i915_program.h"
+
+#define SAREAPTR(ctx) ((drmI830Sarea *)                     \
+                       (((CARD8 *)(ctx)->sarea_address) +   \
+                        (ctx)->sarea_priv_offset))
+
+#define YOFFSET(surface)        (surface->srf.offset)
+#define UOFFSET(surface)        (surface->srf.offset + \
+                                 SIZE_Y420(surface->width, surface->height) + \
+                                 SIZE_UV420(surface->width, surface->height))
+#define VOFFSET(surface)        (surface->srf.offset + \
+                                 SIZE_Y420(surface->width, surface->height))
+
+/* Lookup tables to speed common calculations */
+static unsigned int mb_bytes[] = {
+    000, 128, 128, 256, 128, 256, 256, 384,  // 0
+    128, 256, 256, 384, 256, 384, 384, 512,  // 1
+    128, 256, 256, 384, 256, 384, 384, 512,  // 10
+    256, 384, 384, 512, 384, 512, 512, 640,  // 11
+    128, 256, 256, 384, 256, 384, 384, 512,  // 100
+    256, 384, 384, 512, 384, 512, 512, 640,  // 101    
+    256, 384, 384, 512, 384, 512, 512, 640,  // 110
+    384, 512, 512, 640, 512, 640, 640, 768   // 111
+};
+
+typedef union {
+    short s[4];
+    uint  u[2];
+} su_t;
+
+static char I915KernelDriverName[] = "i915";
+static int error_base;
+static int event_base;
+
+static Status i915_xvmc_mc_create_context(Display* display, XvMCContext *context, int priv_count, CARD32* priv_data);
+static Status i915_xvmc_mc_destroy_context(Display* display, XvMCContext *context);
+static Status i915_xvmc_mc_create_surface(Display* display, XvMCContext *context, XvMCSurface *surface);
+static Status i915_xvmc_mc_destroy_surface(Display* display, XvMCSurface *surface);
+static Status i915_xvmc_mc_render_surface(Display *display, XvMCContext *context,
+                         unsigned int picture_structure,
+                         XvMCSurface *target_surface,
+                         XvMCSurface *past_surface,
+                         XvMCSurface *future_surface,
+                         unsigned int flags,
+                         unsigned int num_macroblocks,
+                         unsigned int first_macroblock,
+                         XvMCMacroBlockArray *macroblock_array,
+                         XvMCBlockArray *blocks);
+static Status i915_xvmc_mc_put_surface(Display *display,XvMCSurface *surface,
+                      Drawable draw, short srcx, short srcy,
+                      unsigned short srcw, unsigned short srch,
+                      short destx, short desty,
+                      unsigned short destw, unsigned short desth,
+                      int flags);
+static Status i915_xvmc_mc_get_surface_status(Display *display, XvMCSurface *surface, int *stat);
+//XXX
+static int i915_xvmc_mc_init()
+{return 0;}
+static void i915_xvmc_mc_fini()
+{}
+
+struct _intel_xvmc_driver i915_xvmc_mc_driver = {
+    .type = XVMC_I915_MPEG2_MC,
+    .init = i915_xvmc_mc_init,
+    .fini = i915_xvmc_mc_fini,
+    .create_context = i915_xvmc_mc_create_context,
+    .destroy_context = i915_xvmc_mc_destroy_context,
+    .create_surface = i915_xvmc_mc_create_surface,
+    .destroy_surface = i915_xvmc_mc_destroy_surface,
+    .render_surface = i915_xvmc_mc_render_surface,
+    .put_surface = i915_xvmc_mc_put_surface,
+    .get_surface_status = i915_xvmc_mc_get_surface_status,
+};
+
+static int findOverlap(unsigned int width, unsigned int height,
+                       short *dstX, short *dstY,
+                       short *srcX, short *srcY, 
+                       unsigned short *areaW, unsigned short *areaH)
+{
+    int w, h;
+    unsigned int mWidth, mHeight;
+
+    w = *areaW;
+    h = *areaH;
+
+    if ((*dstX >= width) || (*dstY >= height))
+        return 1;
+
+    if (*dstX < 0) {
+        w += *dstX;
+        *srcX -= *dstX;
+        *dstX = 0;
+    }
+
+    if (*dstY < 0) {
+        h += *dstY;
+        *srcY -= *dstY;
+        *dstY = 0;
+    }
+
+    if ((w <= 0) || ((h <= 0)))
+        return 1;
+
+    mWidth = width - *dstX;
+    mHeight = height - *dstY;
+    *areaW = (w <= mWidth) ? w : mWidth;
+    *areaH = (h <= mHeight) ? h : mHeight;
+    return 0;
+}
+
+static __inline__ void renderError(void) 
+{
+    XVMC_ERR("Invalid Macroblock Parameters found.");
+}
+
+static void i915_flush(int map, int render)
+{
+    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;
+
+    intelBatchbufferData(&mi_flush, sizeof(mi_flush), 0);
+}
+
+/* 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)
+{
+    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, h = surface->height;
+
+    /* 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;
+
+    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;
+    } 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;
+    }
+
+    /* 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;
+        else
+            dest_buffer_variables_mpeg->dw1.tff = 1;
+    } else if (picture_structure & XVMC_BOTTOM_FIELD) {
+        if (flags & XVMC_SECOND_FIELD)
+            dest_buffer_variables_mpeg->dw1.tff = 1;
+        else
+            dest_buffer_variables_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 */
+}
+
+static void i915_mc_map_state_buffer(XvMCContext *context, 
+                                       i915XvMCSurface *privTarget,
+                                       i915XvMCSurface *privPast,
+                                       i915XvMCSurface *privFuture)
+{
+    struct i915_3dstate_map_state *map_state;
+    struct texture_map *tm;
+    i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
+    unsigned int w = context->width, h = context->height;
+ 
+    /* 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;
+
+    /* 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 */
+
+    /* 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: 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;
+
+    /* 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 */
+
+    /* 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;     
+
+    /* 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;
+
+    /* 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 */
+
+    /* 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;
+}
+
+static void i915_mc_load_sis_msb_buffers(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;
+    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;
+    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;
+
+    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;
+
+    /* SIS */
+    sis = (sis_state *)(++load_indirect);
+    sis->dw0.valid = 1;
+    sis->dw0.force = 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 */
+    msb = (msb_state *)(++sis);
+    msb->dw0.valid = 1;
+    msb->dw0.force = 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_mpeg_set_origin(XvMCContext *context, XvMCMacroBlock *mb)
+{
+    struct i915_3dmpeg_set_origin set_origin;
+
+    /* 3DMPEG_SET_ORIGIN */
+    memset(&set_origin, 0, sizeof(set_origin));
+    set_origin.dw0.type = CMD_3D;
+    set_origin.dw0.opcode = OPC_3DMPEG_SET_ORIGIN;
+    set_origin.dw0.length = 0;
+    set_origin.dw1.h_origin = mb->x;
+    set_origin.dw1.v_origin = mb->y;
+
+    intelBatchbufferData(&set_origin, sizeof(set_origin), 0);
+}
+
+static void i915_mc_mpeg_macroblock_ipicture(XvMCContext *context, XvMCMacroBlock *mb)
+{
+    struct i915_3dmpeg_macroblock_ipicture macroblock_ipicture;
+
+    /* 3DMPEG_MACROBLOCK_IPICTURE */
+    memset(&macroblock_ipicture, 0, sizeof(macroblock_ipicture));
+    macroblock_ipicture.dw0.type = CMD_3D;
+    macroblock_ipicture.dw0.opcode = OPC_3DMPEG_MACROBLOCK_IPICTURE;
+    macroblock_ipicture.dw0.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD);
+
+    intelBatchbufferData(&macroblock_ipicture, sizeof(macroblock_ipicture), 0);
+}
+
+
+static void i915_mc_mpeg_macroblock_0mv(XvMCContext *context, XvMCMacroBlock *mb)
+{
+    struct i915_3dmpeg_macroblock_0mv macroblock_0mv;
+
+    /* 3DMPEG_MACROBLOCK(0mv) */
+    memset(&macroblock_0mv, 0, sizeof(macroblock_0mv));
+    macroblock_0mv.header.dw0.type = CMD_3D;
+    macroblock_0mv.header.dw0.opcode = OPC_3DMPEG_MACROBLOCK;
+    macroblock_0mv.header.dw0.length = 0;
+    macroblock_0mv.header.dw1.mb_intra = 1;     /* should be 1 */ 
+    macroblock_0mv.header.dw1.forward = 0;      /* should be 0 */
+    macroblock_0mv.header.dw1.backward = 0;     /* should be 0 */
+    macroblock_0mv.header.dw1.h263_4mv = 0;     /* should be 0 */
+    macroblock_0mv.header.dw1.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD);
+    
+/*
+    if (!mb->coded_block_pattern)
+        macroblock_0mv.header.dw1.dct_type = XVMC_DCT_TYPE_FRAME;
+*/
+
+    macroblock_0mv.header.dw1.motion_type = 0; // (mb->motion_type & 0x3);
+    macroblock_0mv.header.dw1.vertical_field_select = 0; // mb->motion_vertical_field_select & 0xf;
+    macroblock_0mv.header.dw1.coded_block_pattern = mb->coded_block_pattern;
+    macroblock_0mv.header.dw1.skipped_macroblocks = 0;
+
+    intelBatchbufferData(&macroblock_0mv, sizeof(macroblock_0mv), 0);
+}
+
+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;
+
+    /* 3DMPEG_MACROBLOCK(1fbmv) */
+    memset(&macroblock_1fbmv, 0, sizeof(macroblock_1fbmv));
+    macroblock_1fbmv.header.dw0.type = CMD_3D;
+    macroblock_1fbmv.header.dw0.opcode = OPC_3DMPEG_MACROBLOCK;
+    macroblock_1fbmv.header.dw0.length = 2;
+    macroblock_1fbmv.header.dw1.mb_intra = 0;   /* should be 0 */ 
+    macroblock_1fbmv.header.dw1.forward = ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_FORWARD) ? 1 : 0);
+    macroblock_1fbmv.header.dw1.backward = ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_BACKWARD) ? 1 : 0);
+    macroblock_1fbmv.header.dw1.h263_4mv = 0;   /* should be 0 */
+    macroblock_1fbmv.header.dw1.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD);
+    
+    if (!(mb->coded_block_pattern & 0x3f))
+        macroblock_1fbmv.header.dw1.dct_type = XVMC_DCT_TYPE_FRAME;
+
+    macroblock_1fbmv.header.dw1.motion_type = (mb->motion_type & 0x03);
+    macroblock_1fbmv.header.dw1.vertical_field_select = (mb->motion_vertical_field_select & 0x0f);
+    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];
+
+    macroblock_1fbmv.dw2 = fmv.u[0];
+    macroblock_1fbmv.dw3 = bmv.u[0];
+    
+    intelBatchbufferData(&macroblock_1fbmv, sizeof(macroblock_1fbmv), 0);
+}
+
+static void i915_mc_mpeg_macroblock_2fbmv(XvMCContext *context, XvMCMacroBlock *mb, unsigned int ps)
+{
+    struct i915_3dmpeg_macroblock_2fbmv macroblock_2fbmv;
+    i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
+    
+    /* Motion Vectors */
+    su_t fmv;
+    su_t bmv;
+
+    /* 3DMPEG_MACROBLOCK(2fbmv) */
+    memset(&macroblock_2fbmv, 0, sizeof(macroblock_2fbmv));
+    macroblock_2fbmv.header.dw0.type = CMD_3D;
+    macroblock_2fbmv.header.dw0.opcode = OPC_3DMPEG_MACROBLOCK;
+    macroblock_2fbmv.header.dw0.length = 4;
+    macroblock_2fbmv.header.dw1.mb_intra = 0;   /* should be 0 */
+    macroblock_2fbmv.header.dw1.forward = ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_FORWARD) ? 1 : 0);
+    macroblock_2fbmv.header.dw1.backward = ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_BACKWARD) ? 1 : 0);
+    macroblock_2fbmv.header.dw1.h263_4mv = 0;   /* should be 0 */
+    macroblock_2fbmv.header.dw1.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD);
+    
+    if (!(mb->coded_block_pattern & 0x3f))
+        macroblock_2fbmv.header.dw1.dct_type = XVMC_DCT_TYPE_FRAME;
+
+    macroblock_2fbmv.header.dw1.motion_type = (mb->motion_type & 0x03);
+    macroblock_2fbmv.header.dw1.vertical_field_select = (mb->motion_vertical_field_select & 0x0f);
+    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];
+
+    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;
+        } 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;
+        }
+    }
+
+    macroblock_2fbmv.dw2 = fmv.u[0];
+    macroblock_2fbmv.dw3 = bmv.u[0];
+    macroblock_2fbmv.dw4 = fmv.u[1];
+    macroblock_2fbmv.dw5 = bmv.u[1];
+
+    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);
+}
+
+static void i915_mc_invalidate_subcontext_buffers(XvMCContext *context, unsigned int mask)
+{
+    struct i915_3dstate_load_indirect *load_indirect = NULL;
+    sis_state *sis = NULL;
+    dis_state *dis = NULL;
+    ssb_state *ssb = NULL;
+    msb_state *msb = NULL;
+    psp_state *psp = NULL;
+    psc_state *psc = NULL;
+    i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
+    unsigned int size;
+    void *base = NULL, *ptr = NULL;
+
+    size = sizeof(*load_indirect);
+    if (mask & BLOCK_SIS)
+        size += sizeof(*sis);
+    if (mask & BLOCK_DIS)
+        size += sizeof(*dis);
+    if (mask & BLOCK_SSB)
+        size += sizeof(*ssb);
+    if (mask & BLOCK_MSB)
+        size += sizeof(*msb);
+    if (mask & BLOCK_PSP)
+        size += sizeof(*psp);
+    if (mask & BLOCK_PSC)
+        size += sizeof(*psc);
+
+    if (size == sizeof(*load_indirect)) {
+        XVMC_ERR("There must be at least one bit set\n");
+        return;
+    }
+
+    /* 3DSTATE_LOAD_INDIRECT */
+    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;
+
+    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)
+        load_indirect->dw0.mem_select = 0;
+    else
+        load_indirect->dw0.mem_select = 1;
+
+    load_indirect->dw0.block_mask = mask;
+    load_indirect->dw0.length = (size >> 2) - 2;
+    ptr = ++load_indirect;
+
+    /* SIS */
+    if (mask & BLOCK_SIS) {
+        sis = (sis_state *)ptr;
+        sis->dw0.valid = 0;
+        sis->dw0.buffer_address = 0;
+        sis->dw1.length = 0;
+        ptr = ++sis;
+    }
+
+    /* DIS */
+    if (mask & BLOCK_DIS) {
+        dis = (dis_state *)ptr;
+        dis->dw0.valid = 0;
+        dis->dw0.reset = 0;
+        dis->dw0.buffer_address = 0;
+        ptr = ++dis;
+    }
+
+    /* SSB */
+    if (mask & BLOCK_SSB) {
+        ssb = (ssb_state *)ptr;
+        ssb->dw0.valid = 0;
+        ssb->dw0.buffer_address = 0;
+        ssb->dw1.length = 0;
+        ptr = ++ssb;
+    }
+
+    /* MSB */
+    if (mask & BLOCK_MSB) {
+        msb = (msb_state *)ptr;
+        msb->dw0.valid = 0;
+        msb->dw0.buffer_address = 0;
+        msb->dw1.length = 0;
+        ptr = ++msb;
+    }
+
+    /* PSP */
+    if (mask & BLOCK_PSP) {
+        psp = (psp_state *)ptr;
+        psp->dw0.valid = 0;
+        psp->dw0.buffer_address = 0;
+        psp->dw1.length = 0;
+        ptr = ++psp;
+    }
+
+    /* PSC */
+    if (mask & BLOCK_PSC) {
+        psc = (psc_state *)ptr;
+        psc->dw0.valid = 0;
+        psc->dw0.buffer_address = 0;
+        psc->dw1.length = 0;
+        ptr = ++psc;
+    }
+
+    intelBatchbufferData(base, size, 0);
+    free(base);
+}
+
+static int i915_xvmc_map_buffers(i915XvMCContext *pI915XvMC)
+{
+    if (drmMap(xvmc_driver->fd,
+               pI915XvMC->sis.handle,
+               pI915XvMC->sis.size,
+               (drmAddress *)&pI915XvMC->sis.map) != 0) {
+        return -1;
+    }
+
+    if (drmMap(xvmc_driver->fd,
+               pI915XvMC->ssb.handle,
+               pI915XvMC->ssb.size,
+               (drmAddress *)&pI915XvMC->ssb.map) != 0) {
+        return -1;
+    }
+
+    if (drmMap(xvmc_driver->fd,
+               pI915XvMC->msb.handle,
+               pI915XvMC->msb.size,
+               (drmAddress *)&pI915XvMC->msb.map) != 0) {
+        return -1;
+    }
+
+    if (drmMap(xvmc_driver->fd,
+               pI915XvMC->psp.handle,
+               pI915XvMC->psp.size,
+               (drmAddress *)&pI915XvMC->psp.map) != 0) {
+        return -1;
+    }
+
+    if (drmMap(xvmc_driver->fd,
+               pI915XvMC->psc.handle,
+               pI915XvMC->psc.size,
+               (drmAddress *)&pI915XvMC->psc.map) != 0) {
+        return -1;
+    }
+
+    if (drmMap(xvmc_driver->fd,
+               pI915XvMC->corrdata.handle,
+               pI915XvMC->corrdata.size,
+               (drmAddress *)&pI915XvMC->corrdata.map) != 0) {
+        return -1;
+    }
+
+    return 0;
+}
+
+static void i915_xvmc_unmap_buffers(i915XvMCContext *pI915XvMC)
+{
+    if (pI915XvMC->sis.map) {
+        drmUnmap(pI915XvMC->sis.map, pI915XvMC->sis.size);
+        pI915XvMC->sis.map = NULL;
+    }
+
+    if (pI915XvMC->ssb.map) {
+        drmUnmap(pI915XvMC->ssb.map, pI915XvMC->ssb.size);
+        pI915XvMC->ssb.map = NULL;
+    }
+
+    if (pI915XvMC->msb.map) {
+        drmUnmap(pI915XvMC->msb.map, pI915XvMC->msb.size);
+        pI915XvMC->msb.map = NULL;
+    }
+
+    if (pI915XvMC->psp.map) {
+        drmUnmap(pI915XvMC->psp.map, pI915XvMC->psp.size);
+        pI915XvMC->psp.map = NULL;
+    }
+
+    if (pI915XvMC->psc.map) {
+        drmUnmap(pI915XvMC->psc.map, pI915XvMC->psc.size);
+        pI915XvMC->psc.map = NULL;
+    }
+
+    if (pI915XvMC->corrdata.map) {
+        drmUnmap(pI915XvMC->corrdata.map, pI915XvMC->corrdata.size);
+        pI915XvMC->corrdata.map = NULL;
+    }
+}
+
+/*
+ * Video post processing 
+ */
+static void i915_yuv2rgb_map_state_buffer(XvMCSurface *target_surface)
+{
+    struct i915_3dstate_map_state *map_state;
+    struct texture_map *tm;
+    i915XvMCSurface *privTarget = NULL;
+    i915XvMCContext *pI915XvMC = NULL;
+    unsigned int w = target_surface->width, h = target_surface->height;
+
+    privTarget = (i915XvMCSurface *)target_surface->privData;
+    pI915XvMC = (i915XvMCContext *)privTarget->privContext;
+    /* 3DSATE_MAP_STATE */
+    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 = 0;
+    map_state->dw0.length = 9;
+    map_state->dw1.map_mask = MAP_MAP0 | MAP_MAP1 | MAP_MAP2;
+
+    /* texture map 0: V Plane */
+    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(privTarget);
+    tm->tm1.tile_walk = TILEWALK_XMAJOR;
+    tm->tm1.tiled_surface = 0;
+    tm->tm1.utilize_fence_regs = 1;
+    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 = (privTarget->uvStride >> 2) - 1;    /* in DWords - 1 */
+
+    /* texture map 1: Y Plane */
+    ++tm;
+    memset(tm, 0, sizeof(*tm));
+    tm->tm0.v_ls_offset = 0;
+    tm->tm0.v_ls = 0;
+    tm->tm0.base_address = YOFFSET(privTarget);
+    tm->tm1.tile_walk = TILEWALK_XMAJOR;
+    tm->tm1.tiled_surface = 0;
+    tm->tm1.utilize_fence_regs = 1;
+    tm->tm1.texel_fmt = 0;
+    tm->tm1.surface_fmt = 1;
+    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 = (privTarget->yStride >> 2) - 1;     /* in DWords - 1 */
+
+    /* texture map 2: U Plane */
+    ++tm;
+    memset(tm, 0, sizeof(*tm));
+    tm->tm0.v_ls_offset = 0;
+    tm->tm0.v_ls = 0;
+    tm->tm0.base_address = UOFFSET(privTarget);
+    tm->tm1.tile_walk = TILEWALK_XMAJOR;
+    tm->tm1.tiled_surface = 0;
+    tm->tm1.utilize_fence_regs = 1;
+    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 = (privTarget->uvStride >> 2) - 1;    /* in DWords - 1 */
+}
+
+static void i915_yuv2rgb_sampler_state_buffer(XvMCSurface *surface)
+{
+    struct i915_3dstate_sampler_state *sampler_state;
+    struct texture_sampler *ts;
+    i915XvMCSurface *privSurface = (i915XvMCSurface *)surface->privData;
+    i915XvMCContext *pI915XvMC = (i915XvMCContext *)privSurface->privContext;
+    
+    /* 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 = 9;
+    sampler_state->dw1.sampler_masker = SAMPLER_SAMPLER0 | SAMPLER_SAMPLER1 | SAMPLER_SAMPLER2;
+
+    /* Sampler 0 */
+    ts = (struct texture_sampler *)(++sampler_state);
+    memset(ts, 0, sizeof(*ts));
+    ts->ts0.reverse_gamma = 0;
+    ts->ts0.planar2packet = 1;
+    ts->ts0.color_conversion = 1;
+    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;
+    ts->ts0.shadow_enable = 0;
+    ts->ts0.max_anisotropy = ANISORATIO_2;
+    ts->ts0.shadow_function = PREFILTEROP_ALWAYS;
+    ts->ts1.min_lod = 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 = 1;
+    ts->ts0.color_conversion = 1;
+    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;
+    ts->ts0.shadow_enable = 0;
+    ts->ts0.max_anisotropy = ANISORATIO_2;
+    ts->ts0.shadow_function = PREFILTEROP_ALWAYS;
+    ts->ts1.min_lod = 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;
+
+    /* Sampler 2 */
+    ++ts;
+    memset(ts, 0, sizeof(*ts));
+    ts->ts0.reverse_gamma = 0;
+    ts->ts0.planar2packet = 1;
+    ts->ts0.color_conversion = 1;
+    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;
+    ts->ts0.shadow_enable = 0;
+    ts->ts0.max_anisotropy = ANISORATIO_2;
+    ts->ts0.shadow_function = PREFILTEROP_ALWAYS;
+    ts->ts1.min_lod = 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 = 2;
+    ts->ts1.east_deinterlacer = 0;
+    ts->ts2.default_color = 0;
+}
+
+static void i915_yuv2rgb_static_indirect_state_buffer(XvMCSurface *surface,
+                                                      unsigned int dstaddr, 
+                                                      int dstpitch)
+{
+    struct i915_3dstate_buffer_info *buffer_info;
+    struct i915_3dstate_dest_buffer_variables *dest_buffer_variables;
+    i915XvMCSurface *privSurface = (i915XvMCSurface *)surface->privData;
+    i915XvMCContext *pI915XvMC = (i915XvMCContext *)privSurface->privContext;
+
+    /* 3DSTATE_BUFFER_INFO */
+    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 = 1;   
+    buffer_info->dw1.tiled_surface = 0;   /* linear */
+    buffer_info->dw1.walk = TILEWALK_XMAJOR;
+    buffer_info->dw1.pitch = dstpitch;
+    buffer_info->dw2.base_address = dstaddr;
+
+    /* 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; /* FIXME 0x1000 .5 ??? */
+    dest_buffer_variables->dw1.dest_h_bias = 8;
+    dest_buffer_variables->dw1.color_fmt = COLORBUFFER_A8R8G8B8;  /* FIXME */
+}
+
+static void i915_yuv2rgb_pixel_shader_program_buffer(XvMCSurface *surface)
+{
+    struct i915_3dstate_pixel_shader_program *pixel_shader_program;
+    i915XvMCSurface *privSurface = (i915XvMCSurface *)surface->privData;
+    i915XvMCContext *pI915XvMC = (i915XvMCContext *)privSurface->privContext;
+    unsigned int *inst;
+    unsigned int dest, src0, src1;
+
+    /* 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 = 0;
+    pixel_shader_program->dw0.length = 23;
+    /* 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);
+    /* dcl_2D   s1 */
+    inst += 3;
+    i915_inst_decl(inst, REG_TYPE_S, 1, D0_SAMPLE_TYPE_2D);
+    /* dcl_2D   s2 */
+    inst += 3;
+    i915_inst_decl(inst, REG_TYPE_S, 2, D0_SAMPLE_TYPE_2D);
+    /* texld    r0 t1 s0 */
+    inst += 3;
+    dest = UREG(REG_TYPE_R, 0); 
+    src0 = UREG(REG_TYPE_T, 1); /* COORD */
+    src1 = UREG(REG_TYPE_S, 0); /* SAMPLER */
+    i915_inst_texld(inst, T0_TEXLD, dest, src0, src1);
+    /* texld    r0 t0 s1 */
+    inst += 3;
+    dest = UREG(REG_TYPE_R, 0); 
+    src0 = UREG(REG_TYPE_T, 0); /* COORD */
+    src1 = UREG(REG_TYPE_S, 1); /* SAMPLER */
+    i915_inst_texld(inst, T0_TEXLD, dest, src0, src1);
+    /* texld    oC t1 s2 */
+    inst += 3;
+    dest = UREG(REG_TYPE_OC, 0);
+    src0 = UREG(REG_TYPE_T, 1); /* COORD */
+    src1 = UREG(REG_TYPE_S, 2); /* SAMPLER */
+    i915_inst_texld(inst, T0_TEXLD, dest, src0, src1);
+}
+
+static void i915_yuv2rgb_proc(XvMCSurface *surface)
+{
+    i915XvMCSurface *privSurface = (i915XvMCSurface *)surface->privData;
+    i915XvMCContext *pI915XvMC = (i915XvMCContext *)privSurface->privContext;
+    struct i915_3dstate_load_state_immediate_1 *load_state_immediate_1 = NULL;
+    struct s2_dword *s2 = NULL;
+    struct s3_dword *s3 = NULL;
+    struct s4_dword *s4 = NULL;
+    struct s5_dword *s5 = NULL;
+    struct s6_dword *s6 = NULL;
+    struct s7_dword *s7 = NULL;
+    struct i915_3dstate_scissor_rectangle scissor_rectangle;
+    struct i915_3dstate_load_indirect *load_indirect = NULL;
+    sis_state *sis = NULL;
+    ssb_state *ssb = NULL;
+    msb_state *msb = NULL;
+    psp_state *psp = NULL;
+    struct i915_3dprimitive *_3dprimitive = NULL;
+    struct vertex_data *vd = NULL;
+    unsigned int size;
+    void *base = NULL;
+
+    /* 3DSTATE_LOAD_STATE_IMMEDIATE_1 */
+    size = sizeof(*load_state_immediate_1) + sizeof(*s2) + sizeof(*s3) +
+        sizeof(*s4) + sizeof(*s5) + sizeof(*s6) + sizeof(*s7);
+    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_s2 = 1;
+    load_state_immediate_1->dw0.load_s3 = 1;
+    load_state_immediate_1->dw0.load_s4 = 1;
+    load_state_immediate_1->dw0.load_s5 = 1;
+    load_state_immediate_1->dw0.load_s6 = 1;
+    load_state_immediate_1->dw0.load_s7 = 1;
+    load_state_immediate_1->dw0.length = 5;
+
+    s2 = (struct s2_dword *)(++load_state_immediate_1);
+    s2->set0_texcoord_fmt = TEXCOORDFMT_2FP;
+    s2->set1_texcoord_fmt = TEXCOORDFMT_2FP;
+    s2->set2_texcoord_fmt = TEXCOORDFMT_NOT_PRESENT;
+    s2->set3_texcoord_fmt = TEXCOORDFMT_NOT_PRESENT;
+    s2->set4_texcoord_fmt = TEXCOORDFMT_NOT_PRESENT;
+    s2->set5_texcoord_fmt = TEXCOORDFMT_NOT_PRESENT;
+    s2->set6_texcoord_fmt = TEXCOORDFMT_NOT_PRESENT;
+    s2->set7_texcoord_fmt = TEXCOORDFMT_NOT_PRESENT;
+
+    s3 = (struct s3_dword *)(++s2);
+    s4 = (struct s4_dword *)(++s3);
+    s4->position_mask = VERTEXHAS_XY;
+    s4->cull_mode = CULLMODE_NONE;
+    s4->color_shade_mode = SHADEMODE_FLAT;
+    s4->specular_shade_mode = SHADEMODE_FLAT;
+    s4->fog_shade_mode = SHADEMODE_FLAT;
+    s4->alpha_shade_mode = SHADEMODE_FLAT;
+    s4->line_width = 0x2;     /* FIXME: 1.0??? */
+    s4->point_width = 0x1; 
+
+    s5 = (struct s5_dword *)(++s4);
+    s6 = (struct s6_dword *)(++s5);
+    s6->src_blend_factor = 1;
+    s6->dest_blend_factor = 1;
+    s6->color_buffer_write = 1;
+
+    s7 = (struct s7_dword *)(++s6);
+    intelBatchbufferData(base, size, 0);
+    free(base);
+
+    /* 3DSTATE_3DSTATE_SCISSOR_RECTANGLE */
+    scissor_rectangle.dw0.type = CMD_3D;
+    scissor_rectangle.dw0.opcode = OPC_3DSTATE_SCISSOR_RECTANGLE;
+    scissor_rectangle.dw0.length = 1;
+    scissor_rectangle.dw1.min_x = 0;
+    scissor_rectangle.dw1.min_y = 0;
+    scissor_rectangle.dw2.max_x = 2047;
+    scissor_rectangle.dw2.max_y = 2047;
+    intelBatchbufferData(&scissor_rectangle, sizeof(scissor_rectangle), 0);
+
+    /* 3DSTATE_LOAD_INDIRECT */
+    size = sizeof(*load_indirect) + sizeof(*sis) + sizeof(*ssb) + sizeof(*msb) + sizeof(*psp);
+    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.mem_select = 1;  /* Bearlake only */
+    load_indirect->dw0.block_mask = BLOCK_SIS | BLOCK_SSB | BLOCK_MSB | BLOCK_PSP;
+    load_indirect->dw0.length = 7;
+
+    /* SIS */
+    sis = (sis_state *)(++load_indirect);
+    sis->dw0.valid = 1;
+    sis->dw0.buffer_address = pI915XvMC->sis.offset;
+    sis->dw1.length = ((sizeof(struct i915_3dstate_buffer_info) +
+                        sizeof(struct i915_3dstate_dest_buffer_variables)) >> 2) - 1;
+
+    /* SSB */
+    ssb = (ssb_state *)(++sis);
+    ssb->dw0.valid = 1;
+    ssb->dw0.buffer_address = pI915XvMC->ssb.offset;
+    ssb->dw1.length = ((sizeof(struct i915_3dstate_sampler_state) + 
+                        sizeof(struct texture_sampler) * 3) >> 2) - 1;
+
+    /* MSB */
+    msb = (msb_state *)(++ssb);
+    msb->dw0.valid = 1;
+    msb->dw0.buffer_address = pI915XvMC->msb.offset;
+    msb->dw1.length = ((sizeof(struct i915_3dstate_map_state) + 
+                        sizeof(struct texture_map) * 3) >> 2) - 1;
+
+    /* PSP */
+    psp = (psp_state *)(++msb);
+    psp->dw0.valid = 1;
+    psp->dw0.buffer_address = pI915XvMC->psp.offset;
+    psp->dw1.length = ((sizeof(struct i915_3dstate_pixel_shader_program) +
+                        sizeof(union shader_inst)) >> 2) - 1;
+
+    intelBatchbufferData(base, size, 0);
+    free(base);
+
+    /* 3DPRIMITIVE */
+    size = sizeof(*_3dprimitive) + sizeof(*vd) * 3;
+    base = calloc(1, size);
+    _3dprimitive = (struct i915_3dprimitive *)base;
+    _3dprimitive->dw0.inline_prim.type = CMD_3D;
+    _3dprimitive->dw0.inline_prim.opcode = OPC_3DPRIMITIVE;
+    _3dprimitive->dw0.inline_prim.vertex_location = VERTEX_INLINE;
+    _3dprimitive->dw0.inline_prim.prim = PRIM_RECTLIST;
+    _3dprimitive->dw0.inline_prim.length = size - 2;
+
+    vd = (struct vertex_data *)(++_3dprimitive);
+    vd->x = 0;          /* FIXME!!! */
+    vd->x = 0;          /* FIXME */
+    vd->tc0.tcx = 0;
+    vd->tc0.tcy = 0;
+    vd->tc1.tcx = 0;
+    vd->tc1.tcy = 0;
+
+    ++vd;
+    vd->x = 0;          /* FIXME!!! */
+    vd->x = 0;          /* FIXME */
+    vd->tc0.tcx = 0;
+    vd->tc0.tcy = 0;
+    vd->tc1.tcx = 0;
+    vd->tc1.tcy = 0;
+
+    ++vd;
+    vd->x = 0;          /* FIXME!!! */
+    vd->x = 0;          /* FIXME */
+    vd->tc0.tcx = 0;
+    vd->tc0.tcy = 0;
+    vd->tc1.tcx = 0;
+    vd->tc1.tcy = 0;
+
+    intelBatchbufferData(base, size, 0);
+    free(base);
+}
+
+/***************************************************************************
+// Function: i915_release_resource
+// Description:
+***************************************************************************/
+//XXX
+static void i915_release_resource(Display *display, XvMCContext *context)
+{
+    i915XvMCContext *pI915XvMC;
+    int screen = DefaultScreen(display);
+
+    if (!(pI915XvMC = context->privData))
+        return;
+
+    pI915XvMC->ref--;
+    i915_xvmc_unmap_buffers(pI915XvMC);
+
+    driDestroyHashContents(pI915XvMC->drawHash);
+    drmHashDestroy(pI915XvMC->drawHash);
+
+    pthread_mutex_destroy(&xvmc_driver->ctxmutex);
+
+    XLockDisplay(display);
+    uniDRIDestroyContext(display, screen, pI915XvMC->id);
+    XUnlockDisplay(display);
+
+    intelDestroyBatchBuffer();
+
+    drmUnmap(xvmc_driver->sarea_address, xvmc_driver->sarea_size);
+
+    if (xvmc_driver->fd >= 0)
+        drmClose(xvmc_driver->fd);
+    xvmc_driver->fd = -1;
+
+    XLockDisplay(display);
+    uniDRICloseConnection(display, screen);
+    _xvmc_destroy_context(display, context);
+    XUnlockDisplay(display);
+
+    free(pI915XvMC);
+    context->privData = NULL;
+}
+
+static Status i915_xvmc_mc_create_context(Display *display, XvMCContext *context,
+	int priv_count, CARD32 *priv_data)
+{
+    i915XvMCContext *pI915XvMC = NULL;
+    I915XvMCCreateContextRec *tmpComm = NULL;
+    Status ret;
+    drm_sarea_t *pSAREA;
+    char *curBusID;
+    uint magic;
+    int major, minor;
+    int isCapable;
+    int screen = DefaultScreen(display);
+
+    if (priv_count != (sizeof(I915XvMCCreateContextRec) >> 2)) {
+        XVMC_ERR("_xvmc_create_context() returned incorrect data size!");
+        XVMC_INFO("\tExpected %d, got %d",
+               (int)(sizeof(I915XvMCCreateContextRec) >> 2),priv_count);
+        _xvmc_destroy_context(display, context);
+        free(priv_data);
+        context->privData = NULL;
+        return BadValue;
+    }
+
+    context->privData = (void *)calloc(1, sizeof(i915XvMCContext));
+    if (!context->privData) {
+        XVMC_ERR("Unable to allocate resources for XvMC context.");
+        return BadAlloc;
+    }
+    pI915XvMC = (i915XvMCContext *)context->privData;
+
+    tmpComm = (I915XvMCCreateContextRec *)priv_data;
+    pI915XvMC->ctxno = tmpComm->ctxno;
+    pI915XvMC->deviceID = tmpComm->deviceID;
+    pI915XvMC->sis.handle = tmpComm->sis.handle;
+    pI915XvMC->sis.offset = tmpComm->sis.offset;
+    pI915XvMC->sis.size = tmpComm->sis.size;
+    pI915XvMC->ssb.handle = tmpComm->ssb.handle;
+    pI915XvMC->ssb.offset = tmpComm->ssb.offset;
+    pI915XvMC->ssb.size = tmpComm->ssb.size;
+    pI915XvMC->msb.handle = tmpComm->msb.handle;
+    pI915XvMC->msb.offset = tmpComm->msb.offset;
+    pI915XvMC->msb.size = tmpComm->msb.size;
+    pI915XvMC->psp.handle = tmpComm->psp.handle;
+    pI915XvMC->psp.offset = tmpComm->psp.offset;
+    pI915XvMC->psp.size = tmpComm->psp.size;
+    pI915XvMC->psc.handle = tmpComm->psc.handle;
+    pI915XvMC->psc.offset = tmpComm->psc.offset;
+    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->sis.bus_addr = tmpComm->sis.bus_addr;
+        pI915XvMC->ssb.bus_addr = tmpComm->ssb.bus_addr;
+        pI915XvMC->msb.bus_addr = tmpComm->msb.bus_addr;
+        pI915XvMC->psp.bus_addr = tmpComm->psp.bus_addr;
+        pI915XvMC->psc.bus_addr = tmpComm->psc.bus_addr;
+    }
+
+    pI915XvMC->corrdata.handle = tmpComm->corrdata.handle;
+    pI915XvMC->corrdata.offset = tmpComm->corrdata.offset;
+    pI915XvMC->corrdata.size = tmpComm->corrdata.size;
+    pI915XvMC->sarea_priv_offset = tmpComm->sarea_priv_offset;
+    pI915XvMC->depth = tmpComm->depth;
+
+    /* Must free the private data we were passed from X */
+    free(priv_data);
+    priv_data = NULL;
+
+    pSAREA = (drm_sarea_t *)xvmc_driver->sarea_address;
+    pI915XvMC->sarea = (drmI830Sarea*)((char*)pSAREA + pI915XvMC->sarea_priv_offset);
+    ret = XMatchVisualInfo(display, screen,
+                           (pI915XvMC->depth == 32) ? 24 : pI915XvMC->depth, TrueColor,
+                           &pI915XvMC->visualInfo);
+
+    if (!ret) {
+	XVMC_ERR("Could not find a matching TrueColor visual.");
+        free(pI915XvMC);
+        context->privData = NULL;
+        drmUnmap(xvmc_driver->sarea_address, xvmc_driver->sarea_size);
+        return BadAlloc;
+    }
+
+    if (!uniDRICreateContext(display, screen,
+                             pI915XvMC->visualInfo.visual, &pI915XvMC->id,
+                             &pI915XvMC->hHWContext)) {
+        XVMC_ERR("Could not create DRI context.");
+        free(pI915XvMC);
+        context->privData = NULL;
+        drmUnmap(xvmc_driver->sarea_address, xvmc_driver->sarea_size);
+        return BadAlloc;
+    }
+
+    if (NULL == (pI915XvMC->drawHash = drmHashCreate())) {
+	XVMC_ERR("Could not allocate drawable hash table.");
+        free(pI915XvMC);
+        context->privData = NULL;
+        return BadAlloc;
+    }
+
+    if (i915_xvmc_map_buffers(pI915XvMC)) {
+        i915_xvmc_unmap_buffers(pI915XvMC);
+        free(pI915XvMC);
+        context->privData = NULL;
+        return BadAlloc;
+    }
+
+    /* Initialize private context values */
+    pI915XvMC->yStride = STRIDE(context->width);
+    pI915XvMC->uvStride = STRIDE(context->width >> 1);
+    pI915XvMC->haveXv = 0;
+    pI915XvMC->dual_prime = 0;
+    pI915XvMC->last_flip = 0;
+    pI915XvMC->port = context->port;
+    pI915XvMC->ref = 1;
+    return Success;
+}
+
+/***************************************************************************
+// Function: XvMCDestroyContext
+// Description: Destorys the specified context.
+//
+// Arguments:
+//   display - Specifies the connection to the server.
+//   context - The context to be destroyed.
+//
+// Returns: Status
+***************************************************************************/
+static int i915_xvmc_mc_destroy_context(Display *display, XvMCContext *context)
+{
+    i915XvMCContext *pI915XvMC;
+
+    if (!(pI915XvMC = context->privData))
+        return XvMCBadContext;
+
+    /* Pass Control to the X server to destroy the drm_context_t */
+    i915_release_resource(display,context);
+    return Success;
+}
+
+/***************************************************************************
+// Function: XvMCCreateSurface
+***************************************************************************/
+static Status i915_xvmc_mc_create_surface(Display *display, XvMCContext *context, XvMCSurface *surface) 
+{
+    Status ret;
+    i915XvMCContext *pI915XvMC;
+    i915XvMCSurface *pI915Surface;
+    I915XvMCCreateSurfaceRec *tmpComm = NULL;
+    int priv_count;
+    uint *priv_data;
+
+    if (!display || !context || !display)
+        return BadValue;
+
+    if (!(pI915XvMC = context->privData))
+        return (error_base + XvMCBadContext);
+
+    PPTHREAD_MUTEX_LOCK();
+    surface->privData = (i915XvMCSurface *)malloc(sizeof(i915XvMCSurface));
+
+    if (!(pI915Surface = surface->privData)) {
+        PPTHREAD_MUTEX_UNLOCK();
+        return BadAlloc;
+    }
+
+    /* Initialize private values */
+    pI915Surface->last_render = 0;
+    pI915Surface->last_flip = 0;
+    pI915Surface->yStride = pI915XvMC->yStride;
+    pI915Surface->uvStride = pI915XvMC->uvStride;
+    pI915Surface->width = context->width;
+    pI915Surface->height = context->height;
+    pI915Surface->privContext = pI915XvMC;
+    pI915Surface->privSubPic = NULL;
+    pI915Surface->srf.map = NULL;
+    XLockDisplay(display);
+
+    if ((ret = _xvmc_create_surface(display, context, surface,
+                                    &priv_count, &priv_data))) {
+        XUnlockDisplay(display);
+        XVMC_ERR("Unable to create XvMCSurface.");
+        free(pI915Surface);
+        surface->privData = NULL;
+        PPTHREAD_MUTEX_UNLOCK();
+        return ret;
+    }
+
+    XUnlockDisplay(display);
+
+    if (priv_count != (sizeof(I915XvMCCreateSurfaceRec) >> 2)) {
+        XVMC_ERR("_xvmc_create_surface() returned incorrect data size!");
+        XVMC_INFO("\tExpected %d, got %d",
+               (int)(sizeof(I915XvMCCreateSurfaceRec) >> 2), priv_count);
+        _xvmc_destroy_surface(display, surface);
+        free(priv_data);
+        free(pI915Surface);
+        surface->privData = NULL;
+        PPTHREAD_MUTEX_UNLOCK();
+        return BadAlloc;
+    }
+
+    tmpComm = (I915XvMCCreateSurfaceRec *)priv_data;
+
+    pI915Surface->srfNo = tmpComm->srfno;
+    pI915Surface->srf.handle = tmpComm->srf.handle;
+    pI915Surface->srf.offset = tmpComm->srf.offset;
+    pI915Surface->srf.size = tmpComm->srf.size;
+    free(priv_data);
+
+    if (drmMap(xvmc_driver->fd,
+               pI915Surface->srf.handle,
+               pI915Surface->srf.size,
+               (drmAddress *)&pI915Surface->srf.map) != 0) {
+        _xvmc_destroy_surface(display, surface);
+        free(pI915Surface);
+        surface->privData = NULL;
+        PPTHREAD_MUTEX_UNLOCK();
+        return BadAlloc;
+    }
+
+    pI915XvMC->ref++;
+    PPTHREAD_MUTEX_UNLOCK();
+    return 0;
+}
+
+
+/***************************************************************************
+// Function: XvMCDestroySurface
+***************************************************************************/
+static int i915_xvmc_mc_destroy_surface(Display *display, XvMCSurface *surface) 
+{
+    i915XvMCSurface *pI915Surface;
+    i915XvMCContext *pI915XvMC;
+
+    if (!display || !surface)
+        return BadValue;
+
+    if (!(pI915Surface = surface->privData))
+        return (error_base + XvMCBadSurface);
+
+    if (!(pI915XvMC = pI915Surface->privContext))
+        return (error_base + XvMCBadSurface);
+
+    if (pI915Surface->last_flip)
+        XvMCSyncSurface(display,surface);
+
+    if (pI915Surface->srf.map)
+        drmUnmap(pI915Surface->srf.map, pI915Surface->srf.size);
+
+    XLockDisplay(display);
+    _xvmc_destroy_surface(display, surface);
+    XUnlockDisplay(display);
+
+    free(pI915Surface);
+    surface->privData = NULL;
+    pI915XvMC->ref--;
+
+    return Success;
+}
+
+
+/***************************************************************************
+// Function: XvMCRenderSurface
+// Description: This function does the actual HWMC. Given a list of
+//  macroblock structures it dispatched the hardware commands to execute
+//  them. 
+***************************************************************************/
+static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context,
+                         unsigned int picture_structure,
+                         XvMCSurface *target_surface,
+                         XvMCSurface *past_surface,
+                         XvMCSurface *future_surface,
+                         unsigned int flags,
+                         unsigned int num_macroblocks,
+                         unsigned int first_macroblock,
+                         XvMCMacroBlockArray *macroblock_array,
+                         XvMCBlockArray *blocks)
+{
+    int i;
+    int picture_coding_type = MPEG_I_PICTURE;
+    /* correction data buffer */
+    char *corrdata_ptr;
+    int corrdata_size = 0;
+
+    /* Block Pointer */
+    short *block_ptr;
+    /* Current Macroblock Pointer */
+    XvMCMacroBlock *mb;
+
+    i915XvMCSurface *privTarget = NULL;
+    i915XvMCSurface *privFuture = NULL;
+    i915XvMCSurface *privPast = NULL;
+    i915XvMCContext *pI915XvMC = NULL;
+
+    /* Check Parameters for validity */
+    if (!display || !context || !target_surface) {
+        XVMC_ERR("Invalid Display, Context or Target!");
+        return BadValue;
+    }
+
+    if (!num_macroblocks)
+        return Success;
+
+    if (!macroblock_array || !blocks) {
+        XVMC_ERR("Invalid block data!");
+        return BadValue;
+    }
+
+    if (macroblock_array->num_blocks < (num_macroblocks + first_macroblock)) {
+        XVMC_ERR("Too many macroblocks requested for MB array size.");
+        return BadValue;
+    }
+
+    if (!(pI915XvMC = context->privData))
+        return (error_base + XvMCBadContext);
+
+    if (!(privTarget = target_surface->privData))
+        return (error_base + XvMCBadSurface);
+
+    /* Test For YV12 Surface */
+    if (context->surface_type_id != FOURCC_YV12) {
+        XVMC_ERR("HWMC only possible on YV12 Surfaces.");
+        return BadValue;
+    }
+
+    /* P Frame Test */
+    if (!past_surface) {
+        /* Just to avoid some ifs later. */
+        privPast = privTarget;
+    } else {
+        if (!(privPast = past_surface->privData)) {
+            XVMC_ERR("Invalid Past Surface!");
+            return (error_base + XvMCBadSurface);
+        }
+        
+        picture_coding_type = MPEG_P_PICTURE;
+    }
+
+    /* B Frame Test */
+    if (!future_surface) {
+        privFuture = privPast; // privTarget;
+    } else {
+        if (!past_surface) {
+            XVMC_ERR("No Past Surface!");
+            return BadValue;
+        }
+
+        if (!(privFuture = future_surface->privData)) {
+            XVMC_ERR("Invalid Future Surface!");
+            return (error_base + XvMCBadSurface);
+        }
+
+        picture_coding_type = MPEG_B_PICTURE;
+    }
+
+    LOCK_HARDWARE(pI915XvMC->hHWContext);
+    corrdata_ptr = pI915XvMC->corrdata.map;
+    corrdata_size = 0;
+
+    for (i = first_macroblock; i < (num_macroblocks + first_macroblock); i++) {
+        int bspm = 0;
+        mb = &macroblock_array->macro_blocks[i];
+        block_ptr = &(blocks->blocks[mb->index << 6]);
+
+        /* Lockup can happen if the coordinates are too far out of range */
+        if (mb->x > (target_surface->width >> 4)) {
+            mb->x = 0;
+            XVMC_INFO("reset x");
+        }
+
+        if (mb->y > (target_surface->height >> 4)) {
+            mb->y = 0;
+            XVMC_INFO("reset y");
+        }
+
+        /* Catch no pattern case */
+        if (!(mb->macroblock_type & XVMC_MB_TYPE_PATTERN) &&
+            !(mb->macroblock_type & XVMC_MB_TYPE_INTRA) &&
+            mb->coded_block_pattern) {
+            mb->coded_block_pattern = 0;
+            XVMC_INFO("no coded blocks present!");
+        }
+        
+        bspm = mb_bytes[mb->coded_block_pattern];
+
+        if (!bspm)
+            continue;
+
+        corrdata_size += bspm;
+
+        if (corrdata_size > pI915XvMC->corrdata.size) {
+            XVMC_ERR("correction data buffer overflow.");
+            break;
+        }
+        memcpy(corrdata_ptr, block_ptr, bspm);
+        corrdata_ptr += bspm;
+    } 
+
+    i915_flush(1, 0);
+    // 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_static_indirect_state_buffer(context, target_surface, 
+                                         picture_structure, flags,
+                                         picture_coding_type);
+    i915_mc_map_state_buffer(context, privTarget, privPast, privFuture);
+    i915_mc_load_sis_msb_buffers(context);
+    i915_mc_mpeg_set_origin(context, &macroblock_array->macro_blocks[first_macroblock]);
+
+    for (i = first_macroblock; i < (num_macroblocks + first_macroblock); i++) {
+        mb = &macroblock_array->macro_blocks[i];
+
+        /* Intra Blocks */
+        if (mb->macroblock_type & XVMC_MB_TYPE_INTRA) {
+            i915_mc_mpeg_macroblock_ipicture(context, mb);
+        } else if ((picture_structure & XVMC_FRAME_PICTURE) == XVMC_FRAME_PICTURE) { /* Frame Picture */
+            switch (mb->motion_type & 3) {
+            case XVMC_PREDICTION_FIELD: /* Field Based */
+                i915_mc_mpeg_macroblock_2fbmv(context, mb, picture_structure);
+                break;
+
+            case XVMC_PREDICTION_FRAME: /* Frame Based */
+                i915_mc_mpeg_macroblock_1fbmv(context, mb);
+                break;
+
+            case XVMC_PREDICTION_DUAL_PRIME:    /* Dual Prime */
+                i915_mc_mpeg_macroblock_2fbmv(context, mb, picture_structure);
+                break;
+
+            default:    /* No Motion Type */
+                renderError();
+                break;
+            }   
+        } else {        /* Frame Picture */
+            switch (mb->motion_type & 3) {
+            case XVMC_PREDICTION_FIELD: /* Field Based */
+                i915_mc_mpeg_macroblock_1fbmv(context, mb);
+                break;
+
+            case XVMC_PREDICTION_16x8:  /* 16x8 MC */
+                i915_mc_mpeg_macroblock_2fbmv(context, mb, picture_structure);
+                break;
+                
+            case XVMC_PREDICTION_DUAL_PRIME:    /* Dual Prime */
+                i915_mc_mpeg_macroblock_1fbmv(context, mb);
+                break;
+
+            default:    /* No Motion Type */
+                renderError();
+                break;
+            }
+        }       /* Field Picture */
+    }
+
+    intelFlushBatch(TRUE);
+    xvmc_driver->last_render = xvmc_driver->alloc.irq_emitted;
+    privTarget->last_render = xvmc_driver->last_render;
+
+    UNLOCK_HARDWARE(pI915XvMC->hHWContext);
+    return 0;
+}
+
+/***************************************************************************
+// Function: XvMCPutSurface
+// Description:
+// Arguments:
+//  display: Connection to X server
+//  surface: Surface to be displayed
+//  draw: X Drawable on which to display the surface
+//  srcx: X coordinate of the top left corner of the region to be
+//          displayed within the surface.
+//  srcy: Y coordinate of the top left corner of the region to be
+//          displayed within the surface.
+//  srcw: Width of the region to be displayed.
+//  srch: Height of the region to be displayed.
+//  destx: X cordinate of the top left corner of the destination region
+//         in the drawable coordinates.
+//  desty: Y cordinate of the top left corner of the destination region
+//         in the drawable coordinates.
+//  destw: Width of the destination region.
+//  desth: Height of the destination region.
+//  flags: One or more of the following.
+//     XVMC_TOP_FIELD - Display only the Top field of the surface.
+//     XVMC_BOTTOM_FIELD - Display only the Bottom Field of the surface.
+//     XVMC_FRAME_PICTURE - Display both fields or frame.
+//
+// Info: Portions of this function derived from i915_video.c (XFree86)
+//
+//   This function is organized so that we wait as long as possible before
+//   touching the overlay registers. Since we don't know that the last
+//   flip has happened yet we want to give the overlay as long as
+//   possible to catch up before we have to check on its progress. This
+//   makes it unlikely that we have to wait on the last flip.
+***************************************************************************/
+static int i915_xvmc_mc_put_surface(Display *display,XvMCSurface *surface,
+                      Drawable draw, short srcx, short srcy,
+                      unsigned short srcw, unsigned short srch,
+                      short destx, short desty,
+                      unsigned short destw, unsigned short desth,
+                      int flags) 
+{
+    i915XvMCContext *pI915XvMC;
+    i915XvMCSurface *pI915Surface;
+    i915XvMCSubpicture *pI915SubPic;
+    I915XvMCCommandBuffer buf;
+
+    // drawableInfo *drawInfo;
+    Status ret;
+
+    if (!display || !surface)
+        return BadValue;
+
+    if (!(pI915Surface = surface->privData))
+        return (error_base + XvMCBadSurface);
+
+    if (!(pI915XvMC = pI915Surface->privContext))
+        return (error_base + XvMCBadSurface);
+
+    PPTHREAD_MUTEX_LOCK();
+    /*
+    if (getDRIDrawableInfoLocked(pI915XvMC->drawHash, display,
+                                 pI915XvMC->screen, draw, 0, pI915XvMC->fd, pI915XvMC->hHWContext,
+                                 pI915XvMC->sarea_address, FALSE, &drawInfo, sizeof(*drawInfo))) {
+        PPTHREAD_MUTEX_UNLOCK();
+        return BadAccess;
+    }
+    */
+    if (!pI915XvMC->haveXv) {
+        pI915XvMC->xvImage =
+            XvCreateImage(display, pI915XvMC->port, FOURCC_XVMC,
+                          (char *)&buf, pI915Surface->width, pI915Surface->height);
+        pI915XvMC->gc = XCreateGC(display, draw, 0, 0);
+        pI915XvMC->haveXv = 1;
+    }
+
+    pI915XvMC->draw = draw;
+    pI915XvMC->xvImage->data = (char *)&buf;
+
+    buf.command = INTEL_XVMC_COMMAND_DISPLAY;
+    buf.ctxNo = pI915XvMC->ctxno;
+    buf.srfNo = pI915Surface->srfNo;
+    pI915SubPic = pI915Surface->privSubPic;
+    buf.subPicNo = (!pI915SubPic ? 0 : pI915SubPic->srfNo);
+    buf.real_id = FOURCC_YV12;
+
+    XLockDisplay(display);
+
+    if ((ret = XvPutImage(display, pI915XvMC->port, draw, pI915XvMC->gc,
+                          pI915XvMC->xvImage, srcx, srcy, srcw, srch,
+                          destx, desty, destw, desth))) {
+        XUnlockDisplay(display);
+        PPTHREAD_MUTEX_UNLOCK();
+
+        return ret;
+    }
+
+    XSync(display, 0);
+    XUnlockDisplay(display);
+    PPTHREAD_MUTEX_UNLOCK();
+
+    return 0;
+}
+
+/***************************************************************************
+// Function: XvMCSyncSurface
+// Arguments:
+//   display - Connection to the X server
+//   surface - The surface to synchronize
+// Info:
+// Returns: Status
+***************************************************************************/
+#if 0
+Status XvMCSyncSurface(Display *display, XvMCSurface *surface) 
+{
+    Status ret;
+    int stat = 0;
+
+    do {
+        ret = XvMCGetSurfaceStatus(display, surface, &stat);
+    } while (!ret && (stat & XVMC_RENDERING));
+
+    return ret;
+}
+
+/***************************************************************************
+// Function: XvMCFlushSurface
+// Description:
+//   This function commits pending rendering requests to ensure that they
+//   wll be completed in a finite amount of time.
+// Arguments:
+//   display - Connection to X server
+//   surface - Surface to flush
+// Returns: Status
+***************************************************************************/
+Status XvMCFlushSurface(Display * display, XvMCSurface *surface) 
+{
+    return Success;
+}
+#endif
+
+/***************************************************************************
+// Function: XvMCGetSurfaceStatus
+// Description:
+// Arguments:
+//  display: connection to X server
+//  surface: The surface to query
+//  stat: One of the Following
+//    XVMC_RENDERING - The last XvMCRenderSurface command has not
+//                     completed.
+//    XVMC_DISPLAYING - The surface is currently being displayed or a
+//                     display is pending.
+***************************************************************************/
+static int i915_xvmc_mc_get_surface_status(Display *display, XvMCSurface *surface, int *stat) 
+{
+    i915XvMCSurface *pI915Surface;
+    i915XvMCContext *pI915XvMC;
+
+    if (!display || !surface || !stat)
+        return BadValue;
+    
+    *stat = 0;
+
+    if (!(pI915Surface = surface->privData))
+        return (error_base + XvMCBadSurface);
+
+    if (!(pI915XvMC = pI915Surface->privContext))
+        return (error_base + XvMCBadSurface);
+
+    // LOCK_HARDWARE(pI915XvMC->hHWContext);
+    PPTHREAD_MUTEX_LOCK();
+    if (pI915Surface->last_flip) {
+        /* This can not happen */
+        if (pI915XvMC->last_flip < pI915Surface->last_flip) {
+            XVMC_ERR("Context last flip is less than surface last flip.");
+            PPTHREAD_MUTEX_UNLOCK();
+            return BadValue;
+        }
+
+        /*
+          If the context has 2 or more flips after this surface it
+          cannot be displaying. Don't bother to check.
+        */
+        if (!(pI915XvMC->last_flip > (pI915Surface->last_flip + 1))) {
+            /*
+              If this surface was the last flipped it is either displaying
+              or about to be so don't bother checking.
+            */
+            if (pI915XvMC->last_flip == pI915Surface->last_flip) {
+                *stat |= XVMC_DISPLAYING;
+            }
+        }
+    }
+
+    if (pI915Surface->last_render &&
+        (pI915Surface->last_render > pI915XvMC->sarea->last_dispatch)) {
+        *stat |= XVMC_RENDERING;
+    }
+
+    // UNLOCK_HARDWARE(pI915XvMC->hHWContext);
+    PPTHREAD_MUTEX_UNLOCK();
+    return 0;
+}
+
+/***************************************************************************
+// 
+//  Surface manipulation functions
+//
+***************************************************************************/
+
+/***************************************************************************
+// Function: XvMCHideSurface
+// Description: Stops the display of a surface.
+// Arguments:
+//   display - Connection to the X server.
+//   surface - surface to be hidden.
+//
+// Returns: Status
+***************************************************************************/
+#if 0
+Status XvMCHideSurface(Display *display, XvMCSurface *surface) 
+{
+    i915XvMCSurface *pI915Surface;
+    i915XvMCContext *pI915XvMC;
+    int stat = 0, ret;
+
+    if (!display || !surface)
+        return BadValue;
+
+    if (!(pI915Surface = surface->privData))
+        return (error_base + XvMCBadSurface);
+
+    /* Get the associated context pointer */
+    if (!(pI915XvMC = pI915Surface->privContext))
+        return (error_base + XvMCBadSurface);
+
+    XvMCSyncSurface(display, surface);
+
+    /*
+      Get the status of the surface, if it is not currently displayed
+      we don't need to worry about it.
+    */
+    if ((ret = XvMCGetSurfaceStatus(display, surface, &stat)) != Success)
+        return ret;
+
+    if (!(stat & XVMC_DISPLAYING))
+        return Success;
+
+    /* FIXME: */
+    return Success;
+}
+
+/***************************************************************************
+//
+// Functions that deal with subpictures
+//
+***************************************************************************/
+
+
+
+/***************************************************************************
+// Function: XvMCCreateSubpicture
+// Description: This creates a subpicture by filling out the XvMCSubpicture
+//              structure passed to it and returning Success.
+// Arguments:
+//   display - Connection to the X server.
+//   context - The context to create the subpicture for.
+//   subpicture - Pre-allocated XvMCSubpicture structure to be filled in.
+//   width - of subpicture
+//   height - of subpicture
+//   xvimage_id - The id describing the XvImage format.
+//
+// Returns: Status
+***************************************************************************/
+Status XvMCCreateSubpicture(Display *display, XvMCContext *context,
+                            XvMCSubpicture *subpicture,
+                            unsigned short width, unsigned short height,
+                            int xvimage_id) 
+{
+    Status ret;
+    i915XvMCContext *pI915XvMC;
+    i915XvMCSubpicture *pI915Subpicture;
+    I915XvMCCreateSurfaceRec *tmpComm = NULL;
+    int priv_count;
+    uint *priv_data;
+
+    if (!subpicture || !context || !display)
+        return BadValue;
+  
+    pI915XvMC = (i915XvMCContext *)context->privData;
+
+    if (!pI915XvMC)
+        return (error_base + XvMCBadContext);
+
+    subpicture->privData =
+        (i915XvMCSubpicture *)malloc(sizeof(i915XvMCSubpicture));
+
+    if (!subpicture->privData)
+        return BadAlloc;
+
+    PPTHREAD_MUTEX_LOCK();
+    subpicture->context_id = context->context_id;
+    subpicture->xvimage_id = xvimage_id;
+    subpicture->width = width;
+    subpicture->height = height;
+    pI915Subpicture = (i915XvMCSubpicture *)subpicture->privData;
+
+    XLockDisplay(display);
+    if ((ret = _xvmc_create_subpicture(display, context, subpicture,
+                                       &priv_count, &priv_data))) {
+        XUnlockDisplay(display);
+        XVMC_ERR("Unable to create XvMCSubpicture.");
+        free(pI915Subpicture);
+        subpicture->privData = NULL;
+        PPTHREAD_MUTEX_UNLOCK();
+        return ret;
+    }
+    XUnlockDisplay(display);
+
+    if (priv_count != (sizeof(I915XvMCCreateSurfaceRec) >> 2)) {
+        XVMC_ERR("_xvmc_create_subpicture() returned incorrect data size!");
+        XVMC_INFO("\tExpected %d, got %d", 
+               (int)(sizeof(I915XvMCCreateSurfaceRec) >> 2), priv_count);
+        XLockDisplay(display);
+        _xvmc_destroy_subpicture(display, subpicture);
+        XUnlockDisplay(display);
+        free(priv_data);
+        free(pI915Subpicture);
+        subpicture->privData = NULL;
+        PPTHREAD_MUTEX_UNLOCK();
+        return BadAlloc;
+    }
+
+    tmpComm = (I915XvMCCreateSurfaceRec *)priv_data;
+    pI915Subpicture->srfNo = tmpComm->srfno;
+    pI915Subpicture->srf.handle = tmpComm->srf.handle;
+    pI915Subpicture->srf.offset = tmpComm->srf.offset;
+    pI915Subpicture->srf.size = tmpComm->srf.size;
+    free(priv_data);
+
+    if (drmMap(pI915XvMC->fd,
+               pI915Subpicture->srf.handle,
+               pI915Subpicture->srf.size,
+               (drmAddress *)&pI915Subpicture->srf.map) != 0) {
+        XLockDisplay(display);
+        _xvmc_destroy_subpicture(display, subpicture);
+        XUnlockDisplay(display);
+        free(pI915Subpicture);
+        subpicture->privData = NULL;
+        PPTHREAD_MUTEX_UNLOCK();
+        return BadAlloc;
+    }
+
+    /* subpicture */
+    subpicture->num_palette_entries = I915_SUBPIC_PALETTE_SIZE;
+    subpicture->entry_bytes = 3;
+    strncpy(subpicture->component_order, "YUV", 4);
+
+    /* Initialize private values */
+    pI915Subpicture->privContext = pI915XvMC;
+    pI915Subpicture->last_render= 0;
+    pI915Subpicture->last_flip = 0;
+    pI915Subpicture->pitch = ((subpicture->width + 3) & ~3);
+
+    switch(subpicture->xvimage_id) {
+    case FOURCC_IA44:
+    case FOURCC_AI44:
+        break;
+
+    default:
+        drmUnmap(pI915Subpicture->srf.map, pI915Subpicture->srf.size);
+        XLockDisplay(display);
+        _xvmc_destroy_subpicture(display, subpicture);
+        XUnlockDisplay(display);
+        free(pI915Subpicture);
+        subpicture->privData = NULL;
+        PPTHREAD_MUTEX_UNLOCK();
+        return BadMatch;
+    }
+
+    pI915XvMC->ref++;
+    PPTHREAD_MUTEX_UNLOCK();
+    return Success;
+}
+
+/***************************************************************************
+// Function: XvMCClearSubpicture
+// Description: Clear the area of the given subpicture to "color".
+//              structure passed to it and returning Success.
+// Arguments:
+//   display - Connection to the X server.
+//   subpicture - Subpicture to clear.
+//   x, y, width, height - rectangle in the subpicture to clear.
+//   color - The data to file the rectangle with.
+//
+// Returns: Status
+***************************************************************************/
+Status XvMCClearSubpicture(Display *display, XvMCSubpicture *subpicture,
+                           short x, short y,
+                           unsigned short width, unsigned short height,
+                           unsigned int color) 
+{
+    i915XvMCContext *pI915XvMC;
+    i915XvMCSubpicture *pI915Subpicture;
+
+    if (!display || !subpicture)
+        return BadValue;
+
+    if (!(pI915Subpicture = subpicture->privData))
+        return (error_base + XvMCBadSubpicture);
+
+    if (!(pI915XvMC = pI915Subpicture->privContext))
+        return (error_base + XvMCBadSubpicture);
+
+    if ((x < 0) || (x + width) > subpicture->width)
+        return BadValue;
+
+    if ((y < 0) || (y + height) > subpicture->height)
+        return BadValue;
+
+    /* FIXME: clear the area */
+
+    return Success;
+}
+
+/***************************************************************************
+// Function: XvMCCompositeSubpicture
+// Description: Composite the XvImae on the subpicture. This composit uses
+//              non-premultiplied alpha. Destination alpha is utilized
+//              except for with indexed subpictures. Indexed subpictures
+//              use a simple "replace".
+// Arguments:
+//   display - Connection to the X server.
+//   subpicture - Subpicture to clear.
+//   image - the XvImage to be used as the source of the composite.
+//   srcx, srcy, width, height - The rectangle from the image to be used.
+//   dstx, dsty - location in the subpicture to composite the source.
+//
+// Returns: Status
+***************************************************************************/
+Status XvMCCompositeSubpicture(Display *display, XvMCSubpicture *subpicture,
+                               XvImage *image,
+                               short srcx, short srcy,
+                               unsigned short width, unsigned short height,
+                               short dstx, short dsty) 
+{
+    i915XvMCContext *pI915XvMC;
+    i915XvMCSubpicture *pI915Subpicture;
+
+    if (!display || !subpicture)
+        return BadValue;
+
+    if (!(pI915Subpicture = subpicture->privData))
+        return (error_base + XvMCBadSubpicture);
+
+    if (!(pI915XvMC = pI915Subpicture->privContext))
+        return (error_base + XvMCBadSubpicture);
+
+    if ((srcx < 0) || (srcx + width) > subpicture->width)
+        return BadValue;
+
+    if ((srcy < 0) || (srcy + height) > subpicture->height)
+        return BadValue;
+
+    if ((dstx < 0) || (dstx + width) > subpicture->width)
+        return BadValue;
+
+    if ((dsty < 0) || (dsty + width) > subpicture->height)
+        return BadValue;
+
+    if (image->id != subpicture->xvimage_id)
+        return BadMatch;
+
+    /* FIXME */
+    return Success;
+}
+
+
+/***************************************************************************
+// Function: XvMCDestroySubpicture
+// Description: Destroys the specified subpicture.
+// Arguments:
+//   display - Connection to the X server.
+//   subpicture - Subpicture to be destroyed.
+//
+// Returns: Status
+***************************************************************************/
+Status XvMCDestroySubpicture(Display *display, XvMCSubpicture *subpicture) 
+{
+    i915XvMCSubpicture *pI915Subpicture;
+    i915XvMCContext *pI915XvMC;
+
+    if (!display || !subpicture)
+        return BadValue;
+
+    if (!(pI915Subpicture = subpicture->privData))
+        return (error_base + XvMCBadSubpicture);
+
+    if (!(pI915XvMC = pI915Subpicture->privContext))
+        return (error_base + XvMCBadSubpicture);
+
+    if (pI915Subpicture->last_render)
+        XvMCSyncSubpicture(display, subpicture);
+
+    if (pI915Subpicture->srf.map)
+        drmUnmap(pI915Subpicture->srf.map, pI915Subpicture->srf.size);
+
+    PPTHREAD_MUTEX_LOCK();
+    XLockDisplay(display);
+    _xvmc_destroy_subpicture(display,subpicture);
+    XUnlockDisplay(display);
+
+    free(pI915Subpicture);
+    subpicture->privData = NULL;
+    pI915XvMC->ref--;
+    PPTHREAD_MUTEX_UNLOCK();
+
+    return Success;
+}
+
+
+/***************************************************************************
+// Function: XvMCSetSubpicturePalette
+// Description: Set the subpictures palette
+// Arguments:
+//   display - Connection to the X server.
+//   subpicture - Subpiture to set palette for.
+//   palette - A pointer to an array holding the palette data. The array
+//     is num_palette_entries * entry_bytes in size.
+// Returns: Status
+***************************************************************************/
+
+Status XvMCSetSubpicturePalette(Display *display, XvMCSubpicture *subpicture,
+                                unsigned char *palette) 
+{
+    i915XvMCSubpicture *pI915Subpicture;
+    int i, j;
+
+    if (!display || !subpicture)
+        return BadValue;
+
+    if (!(pI915Subpicture = subpicture->privData))
+        return (error_base + XvMCBadSubpicture);
+
+    j = 0;
+    for (i = 0; i < 16; i++) {
+        pI915Subpicture->palette[0][i] = palette[j++];
+        pI915Subpicture->palette[1][i] = palette[j++];
+        pI915Subpicture->palette[2][i] = palette[j++];
+    }
+
+    /* FIXME: Update the subpicture with the new palette */
+    return Success;
+}
+
+/***************************************************************************
+// Function: XvMCBlendSubpicture
+// Description: 
+//    The behavior of this function is different depending on whether
+//    or not the XVMC_BACKEND_SUBPICTURE flag is set in the XvMCSurfaceInfo.
+//    i915 only support frontend behavior.
+//  
+//    XVMC_BACKEND_SUBPICTURE not set ("frontend" behavior):
+//   
+//    XvMCBlendSubpicture is a no-op in this case.
+//   
+// Arguments:
+//   display - Connection to the X server.
+//   subpicture - The subpicture to be blended into the video.
+//   target_surface - The surface to be displayed with the blended subpic.
+//   source_surface - Source surface prior to blending.
+//   subx, suby, subw, subh - The rectangle from the subpicture to use.
+//   surfx, surfy, surfw, surfh - The rectangle in the surface to blend
+//      blend the subpicture rectangle into. Scaling can ocure if 
+//      XVMC_SUBPICTURE_INDEPENDENT_SCALING is set.
+//
+// Returns: Status
+***************************************************************************/
+Status XvMCBlendSubpicture(Display *display, XvMCSurface *target_surface,
+                           XvMCSubpicture *subpicture,
+                           short subx, short suby,
+                           unsigned short subw, unsigned short subh,
+                           short surfx, short surfy,
+                           unsigned short surfw, unsigned short surfh) 
+{
+    i915XvMCSubpicture *pI915Subpicture;
+    i915XvMCSurface *privTargetSurface;
+
+    if (!display || !target_surface)
+        return BadValue;
+
+    if (!(privTargetSurface = target_surface->privData))
+        return (error_base + XvMCBadSurface);
+
+    if (subpicture) {
+        if (!(pI915Subpicture = subpicture->privData))
+            return (error_base + XvMCBadSubpicture);
+
+        if ((FOURCC_AI44 != subpicture->xvimage_id) &&
+            (FOURCC_IA44 != subpicture->xvimage_id))
+            return (error_base + XvMCBadSubpicture);
+
+        privTargetSurface->privSubPic = pI915Subpicture;
+    } else {
+        privTargetSurface->privSubPic = NULL;
+    }
+
+    return Success;
+}
+
+/***************************************************************************
+// Function: XvMCBlendSubpicture2
+// Description: 
+//    The behavior of this function is different depending on whether
+//    or not the XVMC_BACKEND_SUBPICTURE flag is set in the XvMCSurfaceInfo.
+//    i915 only supports frontend blending.
+//  
+//    XVMC_BACKEND_SUBPICTURE not set ("frontend" behavior):
+//   
+//    XvMCBlendSubpicture2 blends the source_surface and subpicture and
+//    puts it in the target_surface.  This does not effect the status of
+//    the source surface but will cause the target_surface to query
+//    XVMC_RENDERING until the blend is completed.
+//   
+// Arguments:
+//   display - Connection to the X server.
+//   subpicture - The subpicture to be blended into the video.
+//   target_surface - The surface to be displayed with the blended subpic.
+//   source_surface - Source surface prior to blending.
+//   subx, suby, subw, subh - The rectangle from the subpicture to use.
+//   surfx, surfy, surfw, surfh - The rectangle in the surface to blend
+//      blend the subpicture rectangle into. Scaling can ocure if 
+//      XVMC_SUBPICTURE_INDEPENDENT_SCALING is set.
+//
+// Returns: Status
+***************************************************************************/
+Status XvMCBlendSubpicture2(Display *display, 
+                            XvMCSurface *source_surface,
+                            XvMCSurface *target_surface,
+                            XvMCSubpicture *subpicture,
+                            short subx, short suby,
+                            unsigned short subw, unsigned short subh,
+                            short surfx, short surfy,
+                            unsigned short surfw, unsigned short surfh)
+{
+    i915XvMCContext *pI915XvMC;
+    i915XvMCSubpicture *pI915Subpicture;
+    i915XvMCSurface *privSourceSurface;
+    i915XvMCSurface *privTargetSurface;
+
+    if (!display || !source_surface || !target_surface)
+        return BadValue;
+
+    if (!(privSourceSurface = source_surface->privData))
+        return (error_base + XvMCBadSurface);
+
+    if (!(privTargetSurface = target_surface->privData))
+        return (error_base + XvMCBadSurface);
+
+    if (!(pI915XvMC = privTargetSurface->privContext))
+        return (error_base + XvMCBadSurface);
+
+    if (((surfx + surfw) > privTargetSurface->width) ||
+        ((surfy + surfh) > privTargetSurface->height))
+        return BadValue;
+
+    if ((privSourceSurface->width != privTargetSurface->width) ||
+        (privTargetSurface->height != privTargetSurface->height))
+        return BadValue;
+
+    if (XvMCSyncSurface(display, source_surface))
+        return BadValue;
+
+    /* FIXME: update Target Surface */
+
+    if (subpicture) {
+        if (((subx + subw) > subpicture->width) ||
+            ((suby + subh) > subpicture->height))
+            return BadValue;
+
+        if (!(pI915Subpicture = subpicture->privData))
+            return (error_base + XvMCBadSubpicture);
+
+        if ((FOURCC_AI44 != subpicture->xvimage_id) &&
+            (FOURCC_IA44 != subpicture->xvimage_id))
+            return (error_base + XvMCBadSubpicture);
+
+        privTargetSurface->privSubPic = pI915Subpicture;
+    } else {
+        privTargetSurface->privSubPic = NULL;
+    }
+
+    return Success;
+}
+
+/***************************************************************************
+// Function: XvMCSyncSubpicture
+// Description: This function blocks until all composite/clear requests on
+//              the subpicture have been complete.
+// Arguments:
+//   display - Connection to the X server.
+//   subpicture - The subpicture to synchronize
+//
+// Returns: Status
+***************************************************************************/
+Status XvMCSyncSubpicture(Display *display, XvMCSubpicture *subpicture) 
+{
+    Status ret;
+    int stat = 0;
+
+    if (!display || !subpicture)
+        return BadValue;
+
+    do {
+        ret = XvMCGetSubpictureStatus(display, subpicture, &stat);
+    } while(!ret && (stat & XVMC_RENDERING));
+
+    return ret;
+}
+
+/***************************************************************************
+// Function: XvMCFlushSubpicture
+// Description: This function commits pending composite/clear requests to
+//              ensure that they will be completed in a finite amount of
+//              time.
+// Arguments:
+//   display - Connection to the X server.
+//   subpicture - The subpicture whos compsiting should be flushed
+//
+// Returns: Status
+***************************************************************************/
+Status XvMCFlushSubpicture(Display *display, XvMCSubpicture *subpicture) 
+{
+    i915XvMCSubpicture *pI915Subpicture;
+
+    if (!display || !subpicture)
+        return BadValue;
+
+    if (!(pI915Subpicture = subpicture->privData))
+        return (error_base + XvMCBadSubpicture);
+
+    return Success;
+}
+
+/***************************************************************************
+// Function: XvMCGetSubpictureStatus
+// Description: This function gets the current status of a subpicture
+//
+// Arguments:
+//   display - Connection to the X server.
+//   subpicture - The subpicture whos status is being queried
+//   stat - The status of the subpicture. It can be any of the following
+//          OR'd together:
+//          XVMC_RENDERING  - Last composite or clear request not completed
+//          XVMC_DISPLAYING - Suppicture currently being displayed.
+//
+// Returns: Status
+***************************************************************************/
+Status XvMCGetSubpictureStatus(Display *display, XvMCSubpicture *subpicture,
+                               int *stat) 
+{
+    i915XvMCSubpicture *pI915Subpicture;
+    i915XvMCContext *pI915XvMC;
+
+    if (!display || !subpicture || stat)
+        return BadValue;
+
+    *stat = 0;
+
+    if (!(pI915Subpicture = subpicture->privData))
+        return (error_base + XvMCBadSubpicture);
+
+    if (!(pI915XvMC = pI915Subpicture->privContext))
+        return (error_base + XvMCBadSubpicture);
+
+    // LOCK_HARDWARE(pI915XvMC->hHWContext);
+    PPTHREAD_MUTEX_LOCK();
+    /* FIXME: */
+    if (pI915Subpicture->last_render &&
+        (pI915Subpicture->last_render > pI915XvMC->sarea->last_dispatch)) {
+        *stat |= XVMC_RENDERING;
+    }
+
+    // UNLOCK_HARDWARE(pI915XvMC->hHWContext);
+    PPTHREAD_MUTEX_UNLOCK();
+    return Success;
+}
+
+#endif
diff --git a/src/xvmc/i915_xvmc.h b/src/xvmc/i915_xvmc.h
new file mode 100644
index 0000000..a470558
--- /dev/null
+++ b/src/xvmc/i915_xvmc.h
@@ -0,0 +1,130 @@
+/*
+ * Copyright © 2006 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *    Xiang Haihao <haihao.xiang at intel.com>
+ *
+ */
+
+#ifndef _I915XVMC_H
+#define _I915XVMC_H
+
+/* #define XVMC_DEBUG(x) do {x; }while(0); */
+#define XVMC_DEBUG(x)
+
+#include "intel_xvmc.h"
+#include "i915_hwmc.h"
+
+#define I915_SUBPIC_PALETTE_SIZE        16
+#define MAX_SUBCONTEXT_LEN              1024
+
+#define PCI_CHIP_I915_G                 0x2582
+#define PCI_CHIP_I915_GM                0x2592
+#define PCI_CHIP_I945_G                 0x2772
+#define PCI_CHIP_I945_GM                0x27A2
+#define PCI_CHIP_I945_GME               0x27AE
+#define PCI_CHIP_G33_G                  0x29C2
+#define PCI_CHIP_Q35_G                  0x29B2
+#define PCI_CHIP_Q33_G                  0x29D2
+
+/***************************************************************************
+// i915XvMCDrmMap: Holds the data about the DRM maps
+***************************************************************************/
+typedef struct _i915XvMCDrmMap {
+    drm_handle_t handle;
+    unsigned long offset;
+    unsigned long size;
+    unsigned long bus_addr;
+    drmAddress map;
+} i915XvMCDrmMap, *i915XvMCDrmMapPtr;
+
+/***************************************************************************
+// i915XvMCContext: Private Context data referenced via the privData
+//  pointer in the XvMCContext structure.
+***************************************************************************/
+typedef struct _i915XvMCContext {
+    unsigned int ctxno;
+    unsigned int last_flip;
+    unsigned int dual_prime; /* Flag to identify when dual prime is in use. */
+    unsigned int yStride;
+    unsigned int uvStride;
+    unsigned short ref;
+    volatile drmI830Sarea *sarea;
+    drm_context_t hHWContext; /* drmcontext; */
+    unsigned int sarea_priv_offset;	        /* Offset in sarea to private part */
+    unsigned int depth;
+    XvPortID port;		       /* Xv Port ID when displaying */
+    int haveXv;                        /* Have I initialized the Xv
+                                        * connection for this surface? */
+    XvImage *xvImage;                  /* Fake Xv Image used for command
+                                        * buffer transport to the X server */
+    GC  gc;                            /* X GC needed for displaying */
+    Drawable draw;                     /* Drawable to undisplay from */
+    XID id;
+    XVisualInfo visualInfo;
+    void *drawHash;
+    int deviceID;
+
+    i915XvMCDrmMap sis;
+    i915XvMCDrmMap msb;
+    i915XvMCDrmMap ssb;
+    i915XvMCDrmMap psp;
+    i915XvMCDrmMap psc;
+    i915XvMCDrmMap corrdata;
+} i915XvMCContext;
+
+/***************************************************************************
+// i915XvMCSubpicture: Private data structure for each XvMCSubpicture. This
+//  structure is referenced by the privData pointer in the XvMCSubpicture
+//  structure.
+***************************************************************************/
+typedef struct _i915XvMCSubpicture {
+    unsigned int srfNo;
+    unsigned int last_render;
+    unsigned int last_flip;
+    unsigned int pitch;
+    unsigned char palette[3][16];
+    i915XvMCDrmMap srf;
+    i915XvMCContext *privContext;
+} i915XvMCSubpicture;
+
+/***************************************************************************
+// i915XvMCSurface: Private data structure for each XvMCSurface. This
+//  structure is referenced by the privData pointer in the XvMCSurface
+//  structure.
+***************************************************************************/
+#define I830_MAX_BUFS 2                   /*Number of YUV buffers per surface */
+typedef struct _i915XvMCSurface {
+    unsigned int srfNo;                    /* XvMC private surface numbers */
+    unsigned int last_render;
+    unsigned int last_flip;
+    unsigned int yStride;                  /* Stride of YUV420 Y component. */
+    unsigned int uvStride;
+    unsigned int width;                    /* Dimensions */
+    unsigned int height;
+    i915XvMCDrmMap srf;
+    i915XvMCContext *privContext;
+    i915XvMCSubpicture *privSubPic;     /* Subpicture to be blended when
+                                         * displaying. NULL if none. */
+} i915XvMCSurface;
+
+#endif /* _I915XVMC_H */
commit 06c0579df8d45f7f04b96956353d5f86cf59148f
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Thu Nov 15 15:01:56 2007 +0800

    xvmc: some code clean up

diff --git a/src/i830_hwmc.c b/src/i830_hwmc.c
index 432733c..aed8631 100644
--- a/src/i830_hwmc.c
+++ b/src/i830_hwmc.c
@@ -112,7 +112,7 @@ Bool intel_xvmc_screen_init(ScreenPtr pScreen)
     return TRUE;
 }
 
-int intel_xvmc_putimage_size(ScrnInfoPtr pScrn)
+int intel_xvmc_put_image_size(ScrnInfoPtr pScrn)
 {
-    return (*xvmc_driver->putimage_size)(pScrn);
+    return (*xvmc_driver->put_image_size)(pScrn);
 }
diff --git a/src/i830_hwmc.h b/src/i830_hwmc.h
index b874d21..c5b3c17 100644
--- a/src/i830_hwmc.h
+++ b/src/i830_hwmc.h
@@ -70,7 +70,7 @@ struct intel_xvmc_driver {
     /* more items for xvmv surface manage? */
     Bool (*init)(ScrnInfoPtr, XF86VideoAdaptorPtr);
     void (*fini)(ScrnInfoPtr);
-    int (*putimage_size)(ScrnInfoPtr);
+    int (*put_image_size)(ScrnInfoPtr);
     void* devPrivate;
 };
 
@@ -83,7 +83,7 @@ extern Bool intel_xvmc_probe(ScrnInfoPtr);
 extern Bool intel_xvmc_driver_init(ScreenPtr, XF86VideoAdaptorPtr);
 extern Bool intel_xvmc_screen_init(ScreenPtr);
 extern void intel_xvmc_finish(ScrnInfoPtr);
-extern int intel_xvmc_putimage_size(ScrnInfoPtr);
+extern int  intel_xvmc_put_image_size(ScrnInfoPtr);
 #endif
 
 #endif
diff --git a/src/i830_video.c b/src/i830_video.c
index 5cc291d..d62c566 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2550,7 +2550,7 @@ I830QueryImageAttributes(ScrnInfoPtr pScrn,
 	break;
     case FOURCC_XVMC:
         *h = (*h + 1) & ~1;
-        size = intel_xvmc_putimage_size(pScrn);
+        size = intel_xvmc_put_image_size(pScrn);
         if (pitches)
             pitches[0] = size;
         break;
diff --git a/src/i915_hwmc.c b/src/i915_hwmc.c
index 8a0abf3..9e28d16 100644
--- a/src/i915_hwmc.c
+++ b/src/i915_hwmc.c
@@ -85,7 +85,7 @@ typedef struct _I915XvMCContextPriv
     drm_handle_t corrdata_handle;
 } I915XvMCContextPriv;
 
-typedef struct _I915XvMC 
+typedef struct _I915XvMC
 {
     XID contexts[I915_XVMC_MAX_CONTEXTS];
     XID surfaces[I915_XVMC_MAX_SURFACES];
@@ -96,19 +96,8 @@ typedef struct _I915XvMC
 } I915XvMC, *I915XvMCPtr;
 
 #define ARRARY_SIZE(a) (sizeof(a) / sizeof(a[0]))
-static int I915XvMCCreateContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext,
-                                  int *num_priv, long **priv );
-static void I915XvMCDestroyContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext);
 
-static int I915XvMCCreateSurface (ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf,
-                                  int *num_priv, long **priv );
-static void I915XvMCDestroySurface (ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf);
-
-static int I915XvMCCreateSubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSurf,
-                                     int *num_priv, long **priv );
-static void I915XvMCDestroySubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSurf);
-
-static int yv12_subpicture_index_list[2] = 
+static int yv12_subpicture_index_list[2] =
 {
     FOURCC_IA44,
     FOURCC_AI44
@@ -119,10 +108,10 @@ static XF86MCImageIDList yv12_subpicture_list =
     ARRARY_SIZE(yv12_subpicture_index_list),
     yv12_subpicture_index_list
 };
- 
+
 static XF86MCSurfaceInfoRec i915_YV12_mpg2_surface =
 {
-    FOURCC_YV12,  
+    FOURCC_YV12,
     XVMC_CHROMA_FORMAT_420,
     0,
     720,
@@ -138,7 +127,7 @@ static XF86MCSurfaceInfoRec i915_YV12_mpg2_surface =
 
 static XF86MCSurfaceInfoRec i915_YV12_mpg1_surface =
 {
-    FOURCC_YV12,  
+    FOURCC_YV12,
     XVMC_CHROMA_FORMAT_420,
     0,
     720,
@@ -152,7 +141,7 @@ static XF86MCSurfaceInfoRec i915_YV12_mpg1_surface =
     NULL,
 };
 
-static XF86MCSurfaceInfoPtr ppSI[2] = 
+static XF86MCSurfaceInfoPtr ppSI[2] =
 {
     (XF86MCSurfaceInfoPtr)&i915_YV12_mpg2_surface,
     (XF86MCSurfaceInfoPtr)&i915_YV12_mpg1_surface
@@ -168,31 +157,6 @@ static XF86ImagePtr i915_subpicture_list[2] =
     (XF86ImagePtr)&ai44_subpicture
 };
 
-/* Fill in the device dependent adaptor record. 
- * This is named "Intel(R) Textured Video" because this code falls under the
- * XV extenstion, the name must match or it won't be used.
- *
- * Surface and Subpicture - see above
- * Function pointers to functions below
- */
-static XF86MCAdaptorRec pAdapt = 
-{
-    "Intel(R) Textured Video",		                        /* name */
-    ARRARY_SIZE(ppSI),                                          /* num_surfaces */
-    ppSI,				                        /* surfaces */
-    0,
-    NULL,
-#if 0
-    ARRARY_SIZE(i915_subpicture_list),                          /* num_subpictures */
-    i915_subpicture_list,		                        /* subpictures */
-#endif
-    (xf86XvMCCreateContextProcPtr)I915XvMCCreateContext,
-    (xf86XvMCDestroyContextProcPtr)I915XvMCDestroyContext,
-    (xf86XvMCCreateSurfaceProcPtr)I915XvMCCreateSurface,
-    (xf86XvMCDestroySurfaceProcPtr)I915XvMCDestroySurface,
-    (xf86XvMCCreateSubpictureProcPtr)I915XvMCCreateSubpicture,
-    (xf86XvMCDestroySubpictureProcPtr)I915XvMCDestroySubpicture
-};
 
 /*
  * Init and clean up the screen private parts of XvMC.
@@ -417,9 +381,8 @@ static void i915_free_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *ctxpr
 
 }
 
-/**************************************************************************
- *
- *  I915XvMCCreateContext
+/*
+ *  i915_xvmc_create_context
  *
  *  Some info about the private data:
  *
@@ -431,7 +394,7 @@ static void i915_free_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *ctxpr
  *
  **************************************************************************/
 
-static int I915XvMCCreateContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext,
+static int i915_xvmc_create_context (ScrnInfoPtr pScrn, XvMCContextPtr pContext,
                                   int *num_priv, long **priv )
 {
     I830Ptr pI830 = I830PTR(pScrn);
@@ -447,7 +410,7 @@ static int I915XvMCCreateContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext,
 
     if (!pI830->XvMCEnabled) {
         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-                   "[XvMC] I915XvMCCreateContext: Cannot use XvMC!\n");
+                   "[XvMC] i915: XvMC disabled!\n");
         return BadAlloc;
     }
 
@@ -456,10 +419,10 @@ static int I915XvMCCreateContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext,
             break;
     }
 
-    if (i == I915_XVMC_MAX_CONTEXTS || 
+    if (i == I915_XVMC_MAX_CONTEXTS ||
 	    pXvMC->ncontexts >= I915_XVMC_MAX_CONTEXTS) {
         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-                   "[XvMC] I915XvMCCreateContext: Out of contexts.\n");
+                   "[XvMC] i915: Out of contexts.\n");
         return BadAlloc;
     }
 
@@ -477,7 +440,7 @@ static int I915XvMCCreateContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext,
 
     if (!ctxpriv) {
         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-                   "[XvMC] I915XvMCCreateContext: Unable to allocate memory!\n");
+                   "[XvMC] i915: Unable to allocate memory!\n");
         xfree(*priv);
         *priv = NULL;
         *num_priv = 0;
@@ -548,7 +511,7 @@ static int I915XvMCCreateContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext,
     return Success;
 }
 
-static int I915XvMCCreateSurface(ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf,
+static int i915_xvmc_create_surface (ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf,
                                  int *num_priv, long **priv )
 {
     I830Ptr pI830 = I830PTR(pScrn);
@@ -561,7 +524,7 @@ static int I915XvMCCreateSurface(ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf,
 
     if (!pI830->XvMCEnabled) {
         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-                   "[XvMC] I915XvMCCreateContext: Cannot use XvMC!\n");
+                   "[XvMC] i915: XvMC disabled!\n");
         return BadAlloc;
     }
 
@@ -576,16 +539,16 @@ static int I915XvMCCreateSurface(ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf,
     if (srfno == I915_XVMC_MAX_SURFACES ||
 	    pXvMC->nsurfaces >= I915_XVMC_MAX_SURFACES) {
         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-                   "[XvMC] I915XvMCCreateSurface: Too many surfaces !\n");
+                   "[XvMC] i915: Too many surfaces !\n");
         return BadAlloc;
     }
 
     *priv = xcalloc(1, sizeof(I915XvMCCreateSurfaceRec));
-    surfaceRec = (I915XvMCCreateSurfaceRec *)*priv;     
+    surfaceRec = (I915XvMCCreateSurfaceRec *)*priv;
 
     if (!*priv) {
         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-                   "[XvMC] I915XvMCCreateSurface: Unable to allocate memory!\n");
+                   "[XvMC] i915:Unable to allocate surface priv ret memory!\n");
         return BadAlloc;
     }
 
@@ -594,7 +557,7 @@ static int I915XvMCCreateSurface(ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf,
 
     if (!sfpriv) {
         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-                   "[XvMC] I915XvMCCreateSurface: Unable to allocate memory!\n");
+                   "[XvMC] i915: Unable to allocate surface priv memory!\n");
         xfree(*priv);
         *priv = NULL;
         *num_priv = 0;
@@ -604,12 +567,11 @@ static int I915XvMCCreateSurface(ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf,
     ctx = pSurf->context;
     bufsize = SIZE_YUV420(ctx->width, ctx->height);
 
-    /* FIXME xvmc ttm */
-    if (!i830_allocate_xvmc_buffer(pScrn, "XvMC surface", 
+    if (!i830_allocate_xvmc_buffer(pScrn, "XvMC surface",
                                    &(sfpriv->surface), bufsize,
                                    ALIGN_BOTH_ENDS)) {
         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-                   "[XvMC] I915XvMCCreateSurface: Failed to allocate XvMC surface space!\n");
+                   "[XvMC] i915 : Failed to allocate XvMC surface space!\n");
         xfree(sfpriv);
         xfree(*priv);
         *priv = NULL;
@@ -643,7 +605,7 @@ static int I915XvMCCreateSurface(ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf,
     return Success;
 }
 
-static int I915XvMCCreateSubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSubp,
+static int i915_xvmc_create_subpict(ScrnInfoPtr pScrn, XvMCSubpicturePtr pSubp,
                                      int *num_priv, long **priv )
 {
     I830Ptr pI830 = I830PTR(pScrn);
@@ -665,7 +627,7 @@ static int I915XvMCCreateSubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSubp,
     if (srfno == I915_XVMC_MAX_SURFACES ||
 	    pXvMC->nsurfaces >= I915_XVMC_MAX_SURFACES) {
         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-                   "[XvMC] I915XvMCCreateSubpicture: Too many surfaces !\n");
+                   "[XvMC] i915: Too many surfaces !\n");
         return BadAlloc;
     }
 
@@ -674,7 +636,7 @@ static int I915XvMCCreateSubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSubp,
 
     if (!*priv) {
         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-                   "[XvMC] I915XvMCCreateSubpicture: Unable to allocate memory!\n");
+                   "[XvMC] i915: Unable to allocate memory!\n");
         return BadAlloc;
     }
 
@@ -683,7 +645,7 @@ static int I915XvMCCreateSubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSubp,
 
     if (!sfpriv) {
         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-                   "[XvMC] I915XvMCCreateSubpicture: Unable to allocate memory!\n");
+                   "[XvMC] i915: Unable to allocate memory!\n");
         xfree(*priv);
         *priv = NULL;
         *num_priv = 0;
@@ -731,7 +693,8 @@ static int I915XvMCCreateSubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSubp,
     return Success;
 }
 
-static void I915XvMCDestroyContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext)
+static void i915_xvmc_destroy_context (ScrnInfoPtr pScrn,
+					XvMCContextPtr pContext)
 {
     I915XvMCPtr pXvMC = (I915XvMCPtr)xvmc_driver->devPrivate;
     int i;
@@ -751,7 +714,7 @@ static void I915XvMCDestroyContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext)
     return;
 }
 
-static void I915XvMCDestroySurface (ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf)
+static void i915_xvmc_destroy_surface (ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf)
 {
     I830Ptr pI830 = I830PTR(pScrn);
     I915XvMCPtr pXvMC = (I915XvMCPtr)xvmc_driver->devPrivate;
@@ -760,7 +723,7 @@ static void I915XvMCDestroySurface (ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf)
     for (i = 0; i < I915_XVMC_MAX_SURFACES; i++) {
         if (pXvMC->surfaces[i] == pSurf->surface_id) {
             drmRmMap(pI830->drmSubFD, pXvMC->sfprivs[i]->surface_handle);
-            i830_free_memory(pScrn, pXvMC->sfprivs[i]->surface);            
+            i830_free_memory(pScrn, pXvMC->sfprivs[i]->surface);
             xfree(pXvMC->sfprivs[i]);
             pXvMC->nsurfaces--;
             pXvMC->sfprivs[i] = 0;
@@ -772,7 +735,8 @@ static void I915XvMCDestroySurface (ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf)
     return;
 }
 
-static void I915XvMCDestroySubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSubp)
+static void i915_xvmc_destroy_subpict (ScrnInfoPtr pScrn,
+					XvMCSubpicturePtr pSubp)
 {
     I830Ptr pI830 = I830PTR(pScrn);
     I915XvMCPtr pXvMC = (I915XvMCPtr)xvmc_driver->devPrivate;
@@ -781,7 +745,7 @@ static void I915XvMCDestroySubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSub
     for (i = 0; i < I915_XVMC_MAX_SURFACES; i++) {
         if (pXvMC->surfaces[i] == pSubp->subpicture_id) {
             drmRmMap(pI830->drmSubFD, pXvMC->sfprivs[i]->surface_handle);
-            i830_free_memory(pScrn, pXvMC->sfprivs[i]->surface);            
+            i830_free_memory(pScrn, pXvMC->sfprivs[i]->surface);
             xfree(pXvMC->sfprivs[i]);
             pXvMC->nsurfaces--;
             pXvMC->sfprivs[i] = 0;
@@ -793,12 +757,13 @@ static void I915XvMCDestroySubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSub
     return;
 }
 
-static int I915XvMCPutImage(ScrnInfoPtr pScrn, short src_x, short src_y,
-                                     short drw_x, short drw_y, short src_w,
-                                     short src_h, short drw_w, short drw_h,
-                                     int id, unsigned char *buf, short width,
-                                     short height, Bool sync, RegionPtr clipBoxes, pointer data,
-                                     DrawablePtr pDraw)
+static int i915_xvmc_put_image(ScrnInfoPtr pScrn,
+	short src_x, short src_y,
+	short drw_x, short drw_y, short src_w,
+	short src_h, short drw_w, short drw_h,
+	int id, unsigned char *buf, short width,
+	short height, Bool sync, RegionPtr clipBoxes, pointer data,
+	DrawablePtr pDraw)
 {
     I830Ptr pI830 = I830PTR(pScrn);
     I915XvMCPtr pXvMC = (I915XvMCPtr)xvmc_driver->devPrivate;
@@ -813,11 +778,12 @@ static int I915XvMCPutImage(ScrnInfoPtr pScrn, short src_x, short src_y,
 			!pXvMC->surfaces[i915XvMCData->srfNo] ||
 			!pXvMC->sfprivs[i915XvMCData->srfNo]) {
 		    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-			    "[XvMC] I915XvMCPutImage: Invalid parameters !\n");
+			    "[XvMC] i915 put image: Invalid parameters!\n");
 		    return 1;
 		}
 
-		buf = pI830->FbBase + pXvMC->sfprivs[i915XvMCData->srfNo]->surface->offset;
+		buf = pI830->FbBase +
+		    pXvMC->sfprivs[i915XvMCData->srfNo]->surface->offset;
 		id = i915XvMCData->real_id;
 		pI830->IsXvMCSurface = 1;
 		break;
@@ -828,12 +794,13 @@ static int I915XvMCPutImage(ScrnInfoPtr pScrn, short src_x, short src_y,
     }
 
     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);
+                        drw_w, drw_h, id, buf, width, height, sync, clipBoxes,
+			data, pDraw);
     pI830->IsXvMCSurface = 0;
     return ret;
 }
 
-static int i915_xvmc_putimage_size(ScrnInfoPtr pScrn)
+static int i915_xvmc_put_image_size(ScrnInfoPtr pScrn)
 {
     return sizeof(I915XvMCCommandBuffer);
 }
@@ -893,7 +860,7 @@ static Bool i915_xvmc_init(ScrnInfoPtr pScrn, XF86VideoAdaptorPtr XvAdapt)
 
     /* set up wrappers */
     pXvMC->savePutImage = XvAdapt->PutImage;
-    XvAdapt->PutImage = I915XvMCPutImage;
+    XvAdapt->PutImage = i915_xvmc_put_image;
     return TRUE;
 }
 
@@ -906,12 +873,38 @@ static void i915_xvmc_fini(ScrnInfoPtr pScrn)
     xfree(xvmc_driver->devPrivate);
 }
 
+/* Fill in the device dependent adaptor record.
+ * This is named "Intel(R) Textured Video" because this code falls under the
+ * XV extenstion, the name must match or it won't be used.
+ *
+ * Surface and Subpicture - see above
+ * Function pointers to functions below
+ */
+static XF86MCAdaptorRec pAdapt =
+{
+    .name		= "Intel(R) Textured Video",
+    .num_surfaces	= ARRARY_SIZE(ppSI),
+    .surfaces		= ppSI,
+#if 0
+    .num_subpictures	= ARRARY_SIZE(i915_subpicture_list),
+    .subpictures	= i915_subpicture_list,
+#endif
+    .num_subpictures	= 0,
+    .subpictures	= NULL,
+    .CreateContext	= (xf86XvMCCreateContextProcPtr) i915_xvmc_create_context,
+    .DestroyContext	= (xf86XvMCDestroyContextProcPtr) i915_xvmc_destroy_context,
+    .CreateSurface	= (xf86XvMCCreateSurfaceProcPtr) i915_xvmc_create_surface,
+    .DestroySurface	= (xf86XvMCDestroySurfaceProcPtr) i915_xvmc_destroy_surface,
+    .CreateSubpicture	= (xf86XvMCCreateSubpictureProcPtr) i915_xvmc_create_subpict,
+    .DestroySubpicture	= (xf86XvMCDestroySubpictureProcPtr) i915_xvmc_destroy_subpict,
+};
+
 /* new xvmc driver interface */
 struct intel_xvmc_driver i915_xvmc_driver = {
-    .name	= "i915_xvmc",
-    .adaptor	= &pAdapt,
-    .flag	= XVMC_I915_MPEG2_MC,
-    .init	= i915_xvmc_init,
-    .fini	= i915_xvmc_fini,
-    .putimage_size = i915_xvmc_putimage_size,
+    .name		= "i915_xvmc",
+    .adaptor		= &pAdapt,
+    .flag		= XVMC_I915_MPEG2_MC,
+    .init		= i915_xvmc_init,
+    .fini		= i915_xvmc_fini,
+    .put_image_size	= i915_xvmc_put_image_size,
 };
commit 4983e3401390654098dbf99dcfb45bab060b068c
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Thu Nov 15 13:56:24 2007 +0800

    xvmc: move locking code into generic place

diff --git a/src/xvmc/I915XvMC.c b/src/xvmc/I915XvMC.c
index 1ff3629..d34808f 100644
--- a/src/xvmc/I915XvMC.c
+++ b/src/xvmc/I915XvMC.c
@@ -145,64 +145,6 @@ static __inline__ void renderError(void)
     XVMC_ERR("Invalid Macroblock Parameters found.");
 }
 
-static void I915XvMCContendedLock(i915XvMCContext *pI915XvMC, drmLockFlags flags)
-{
-    drmGetLock(xvmc_driver->fd, pI915XvMC->hHWContext, flags);
-}
-
-#define SET_BLOCKED_SIGSET(pI915XvMC)   do {    \
-        sigset_t bl_mask;                       \
-        sigfillset(&bl_mask);           \
-        sigdelset(&bl_mask, SIGFPE);    \
-        sigdelset(&bl_mask, SIGILL);    \
-        sigdelset(&bl_mask, SIGSEGV);   \
-        sigdelset(&bl_mask, SIGBUS);    \
-        sigdelset(&bl_mask, SIGKILL);   \
-        pthread_sigmask(SIG_SETMASK, &bl_mask, &pI915XvMC->sa_mask); \
-    } while (0)
-
-#define RESTORE_BLOCKED_SIGSET(pI915XvMC) do {    \
-        pthread_sigmask(SIG_SETMASK, &pI915XvMC->sa_mask, NULL); \
-    } while (0)
-
-#define PPTHREAD_MUTEX_LOCK(pI915XvMC) do {             \
-        SET_BLOCKED_SIGSET(pI915XvMC);                  \
-        pthread_mutex_lock(&pI915XvMC->ctxmutex);       \
-    } while (0)
-
-#define PPTHREAD_MUTEX_UNLOCK(pI915XvMC) do {           \
-        pthread_mutex_unlock(&pI915XvMC->ctxmutex);     \
-        RESTORE_BLOCKED_SIGSET(pI915XvMC);              \
-    } while (0)
-
-/* Lock the hardware and validate our state.
- */
-static void LOCK_HARDWARE(i915XvMCContext  *pI915XvMC)
-{
-    char __ret = 0;
-
-    PPTHREAD_MUTEX_LOCK(pI915XvMC);
-    assert(!pI915XvMC->locked);
-
-    DRM_CAS(pI915XvMC->driHwLock, pI915XvMC->hHWContext,
-            (DRM_LOCK_HELD|pI915XvMC->hHWContext), __ret);
-
-    if (__ret)
-        I915XvMCContendedLock(pI915XvMC, 0);
-
-    pI915XvMC->locked = 1;
-}
-
-/* Unlock the hardware using the global current context
- */
-static void UNLOCK_HARDWARE(i915XvMCContext *pI915XvMC)
-{
-    pI915XvMC->locked = 0;
-    DRM_UNLOCK(xvmc_driver->fd, pI915XvMC->driHwLock, 
-               pI915XvMC->hHWContext);
-    PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
-}
-
 static void i915_flush(int map, int render)
 {
     struct i915_mi_flush mi_flush;
@@ -1712,7 +1654,7 @@ static void i915_release_resource(Display *display, XvMCContext *context)
     driDestroyHashContents(pI915XvMC->drawHash);
     drmHashDestroy(pI915XvMC->drawHash);
 
-    pthread_mutex_destroy(&pI915XvMC->ctxmutex);
+    pthread_mutex_destroy(&xvmc_driver->ctxmutex);
 
     XLockDisplay(display);
     uniDRIDestroyContext(display, screen, pI915XvMC->id);
@@ -1806,7 +1748,6 @@ static Status i915_xvmc_mc_create_context(Display *display, XvMCContext *context
     priv_data = NULL;
 
     pSAREA = (drm_sarea_t *)xvmc_driver->sarea_address;
-    pI915XvMC->driHwLock = (drmLock *)&pSAREA->lock;
     pI915XvMC->sarea = (drmI830Sarea*)((char*)pSAREA + pI915XvMC->sarea_priv_offset);
     ret = XMatchVisualInfo(display, screen,
                            (pI915XvMC->depth == 32) ? 24 : pI915XvMC->depth, TrueColor,
@@ -1850,10 +1791,7 @@ static Status i915_xvmc_mc_create_context(Display *display, XvMCContext *context
     pI915XvMC->haveXv = 0;
     pI915XvMC->dual_prime = 0;
     pI915XvMC->last_flip = 0;
-    pI915XvMC->locked = 0;
     pI915XvMC->port = context->port;
-    /* XXX */
-    pthread_mutex_init(&pI915XvMC->ctxmutex, NULL);
     pI915XvMC->ref = 1;
     return Success;
 }
@@ -1898,11 +1836,11 @@ static Status i915_xvmc_mc_create_surface(Display *display, XvMCContext *context
     if (!(pI915XvMC = context->privData))
         return (error_base + XvMCBadContext);
 
-    PPTHREAD_MUTEX_LOCK(pI915XvMC);
+    PPTHREAD_MUTEX_LOCK();
     surface->privData = (i915XvMCSurface *)malloc(sizeof(i915XvMCSurface));
 
     if (!(pI915Surface = surface->privData)) {
-        PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
+        PPTHREAD_MUTEX_UNLOCK();
         return BadAlloc;
     }
 
@@ -1924,7 +1862,7 @@ static Status i915_xvmc_mc_create_surface(Display *display, XvMCContext *context
         XVMC_ERR("Unable to create XvMCSurface.");
         free(pI915Surface);
         surface->privData = NULL;
-        PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
+        PPTHREAD_MUTEX_UNLOCK();
         return ret;
     }
 
@@ -1938,7 +1876,7 @@ static Status i915_xvmc_mc_create_surface(Display *display, XvMCContext *context
         free(priv_data);
         free(pI915Surface);
         surface->privData = NULL;
-        PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
+        PPTHREAD_MUTEX_UNLOCK();
         return BadAlloc;
     }
 
@@ -1957,12 +1895,12 @@ static Status i915_xvmc_mc_create_surface(Display *display, XvMCContext *context
         _xvmc_destroy_surface(display, surface);
         free(pI915Surface);
         surface->privData = NULL;
-        PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
+        PPTHREAD_MUTEX_UNLOCK();
         return BadAlloc;
     }
 
     pI915XvMC->ref++;
-    PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
+    PPTHREAD_MUTEX_UNLOCK();
     return 0;
 }
 
@@ -2096,7 +2034,7 @@ static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context,
         picture_coding_type = MPEG_B_PICTURE;
     }
 
-    LOCK_HARDWARE(pI915XvMC);
+    LOCK_HARDWARE(pI915XvMC->hHWContext);
     corrdata_ptr = pI915XvMC->corrdata.map;
     corrdata_size = 0;
 
@@ -2204,7 +2142,7 @@ static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context,
     xvmc_driver->last_render = xvmc_driver->alloc.irq_emitted;
     privTarget->last_render = xvmc_driver->last_render;
 
-    UNLOCK_HARDWARE(pI915XvMC);
+    UNLOCK_HARDWARE(pI915XvMC->hHWContext);
     return 0;
 }
 
@@ -2264,12 +2202,12 @@ static int i915_xvmc_mc_put_surface(Display *display,XvMCSurface *surface,
     if (!(pI915XvMC = pI915Surface->privContext))
         return (error_base + XvMCBadSurface);
 
-    PPTHREAD_MUTEX_LOCK(pI915XvMC);
+    PPTHREAD_MUTEX_LOCK();
     /*
     if (getDRIDrawableInfoLocked(pI915XvMC->drawHash, display,
                                  pI915XvMC->screen, draw, 0, pI915XvMC->fd, pI915XvMC->hHWContext,
                                  pI915XvMC->sarea_address, FALSE, &drawInfo, sizeof(*drawInfo))) {
-        PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
+        PPTHREAD_MUTEX_UNLOCK();
         return BadAccess;
     }
     */
@@ -2297,14 +2235,14 @@ static int i915_xvmc_mc_put_surface(Display *display,XvMCSurface *surface,
                           pI915XvMC->xvImage, srcx, srcy, srcw, srch,
                           destx, desty, destw, desth))) {
         XUnlockDisplay(display);
-        PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
+        PPTHREAD_MUTEX_UNLOCK();
 
         return ret;
     }
 
     XSync(display, 0);
     XUnlockDisplay(display);
-    PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
+    PPTHREAD_MUTEX_UNLOCK();
 
     return 0;
 }
@@ -2374,13 +2312,13 @@ static int i915_xvmc_mc_get_surface_status(Display *display, XvMCSurface *surfac
     if (!(pI915XvMC = pI915Surface->privContext))
         return (error_base + XvMCBadSurface);
 
-    // LOCK_HARDWARE(pI915XvMC);
-    PPTHREAD_MUTEX_LOCK(pI915XvMC);
+    // LOCK_HARDWARE(pI915XvMC->hHWContext);
+    PPTHREAD_MUTEX_LOCK();
     if (pI915Surface->last_flip) {
         /* This can not happen */
         if (pI915XvMC->last_flip < pI915Surface->last_flip) {
             XVMC_ERR("Context last flip is less than surface last flip.");
-            PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
+            PPTHREAD_MUTEX_UNLOCK();
             return BadValue;
         }
 
@@ -2404,8 +2342,8 @@ static int i915_xvmc_mc_get_surface_status(Display *display, XvMCSurface *surfac
         *stat |= XVMC_RENDERING;
     }
 
-    // UNLOCK_HARDWARE(pI915XvMC);
-    PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
+    // UNLOCK_HARDWARE(pI915XvMC->hHWContext);
+    PPTHREAD_MUTEX_UNLOCK();
     return 0;
 }
 
@@ -2505,7 +2443,7 @@ Status XvMCCreateSubpicture(Display *display, XvMCContext *context,
     if (!subpicture->privData)
         return BadAlloc;
 
-    PPTHREAD_MUTEX_LOCK(pI915XvMC);
+    PPTHREAD_MUTEX_LOCK();
     subpicture->context_id = context->context_id;
     subpicture->xvimage_id = xvimage_id;
     subpicture->width = width;
@@ -2519,7 +2457,7 @@ Status XvMCCreateSubpicture(Display *display, XvMCContext *context,
         XVMC_ERR("Unable to create XvMCSubpicture.");
         free(pI915Subpicture);
         subpicture->privData = NULL;
-        PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
+        PPTHREAD_MUTEX_UNLOCK();
         return ret;
     }
     XUnlockDisplay(display);
@@ -2534,7 +2472,7 @@ Status XvMCCreateSubpicture(Display *display, XvMCContext *context,
         free(priv_data);
         free(pI915Subpicture);
         subpicture->privData = NULL;
-        PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
+        PPTHREAD_MUTEX_UNLOCK();
         return BadAlloc;
     }
 
@@ -2554,7 +2492,7 @@ Status XvMCCreateSubpicture(Display *display, XvMCContext *context,
         XUnlockDisplay(display);
         free(pI915Subpicture);
         subpicture->privData = NULL;
-        PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
+        PPTHREAD_MUTEX_UNLOCK();
         return BadAlloc;
     }
 
@@ -2581,12 +2519,12 @@ Status XvMCCreateSubpicture(Display *display, XvMCContext *context,
         XUnlockDisplay(display);
         free(pI915Subpicture);
         subpicture->privData = NULL;
-        PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
+        PPTHREAD_MUTEX_UNLOCK();
         return BadMatch;
     }
 
     pI915XvMC->ref++;
-    PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
+    PPTHREAD_MUTEX_UNLOCK();
     return Success;
 }
 
@@ -2712,7 +2650,7 @@ Status XvMCDestroySubpicture(Display *display, XvMCSubpicture *subpicture)
     if (pI915Subpicture->srf.map)
         drmUnmap(pI915Subpicture->srf.map, pI915Subpicture->srf.size);
 
-    PPTHREAD_MUTEX_LOCK(pI915XvMC);
+    PPTHREAD_MUTEX_LOCK();
     XLockDisplay(display);
     _xvmc_destroy_subpicture(display,subpicture);
     XUnlockDisplay(display);
@@ -2720,7 +2658,7 @@ Status XvMCDestroySubpicture(Display *display, XvMCSubpicture *subpicture)
     free(pI915Subpicture);
     subpicture->privData = NULL;
     pI915XvMC->ref--;
-    PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
+    PPTHREAD_MUTEX_UNLOCK();
 
     return Success;
 }
@@ -2980,16 +2918,16 @@ Status XvMCGetSubpictureStatus(Display *display, XvMCSubpicture *subpicture,
     if (!(pI915XvMC = pI915Subpicture->privContext))
         return (error_base + XvMCBadSubpicture);
 
-    // LOCK_HARDWARE(pI915XvMC);
-    PPTHREAD_MUTEX_LOCK(pI915XvMC);
+    // LOCK_HARDWARE(pI915XvMC->hHWContext);
+    PPTHREAD_MUTEX_LOCK();
     /* FIXME: */
     if (pI915Subpicture->last_render &&
         (pI915Subpicture->last_render > pI915XvMC->sarea->last_dispatch)) {
         *stat |= XVMC_RENDERING;
     }
 
-    // UNLOCK_HARDWARE(pI915XvMC);
-    PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
+    // UNLOCK_HARDWARE(pI915XvMC->hHWContext);
+    PPTHREAD_MUTEX_UNLOCK();
     return Success;
 }
 
diff --git a/src/xvmc/I915XvMC.h b/src/xvmc/I915XvMC.h
index b97dc48..a470558 100644
--- a/src/xvmc/I915XvMC.h
+++ b/src/xvmc/I915XvMC.h
@@ -68,12 +68,7 @@ typedef struct _i915XvMCContext {
     unsigned int yStride;
     unsigned int uvStride;
     unsigned short ref;
-    pthread_mutex_t ctxmutex;
-    int lock;   /* Lightweight lock to avoid locking twice */
-    int locked;
     volatile drmI830Sarea *sarea;
-    
-    drmLock *driHwLock;
     drm_context_t hHWContext; /* drmcontext; */
     unsigned int sarea_priv_offset;	        /* Offset in sarea to private part */
     unsigned int depth;
@@ -94,11 +89,7 @@ typedef struct _i915XvMCContext {
     i915XvMCDrmMap ssb;
     i915XvMCDrmMap psp;
     i915XvMCDrmMap psc;
-
     i915XvMCDrmMap corrdata;
-
-    sigset_t sa_mask;
-
 } i915XvMCContext;
 
 /***************************************************************************
diff --git a/src/xvmc/intel_xvmc.c b/src/xvmc/intel_xvmc.c
index 6c9a950..21eb607 100644
--- a/src/xvmc/intel_xvmc.c
+++ b/src/xvmc/intel_xvmc.c
@@ -30,6 +30,35 @@ struct _intel_xvmc_driver *xvmc_driver = NULL;
 static int error_base;
 static int event_base;
 
+/* locking */
+static void intel_xvmc_try_heavy_lock(drm_context_t ctx)
+{
+    drmGetLock(xvmc_driver->fd, ctx, 0);
+}
+
+void LOCK_HARDWARE(drm_context_t ctx)
+{
+    char __ret = 0;
+
+    PPTHREAD_MUTEX_LOCK();
+    assert(!xvmc_driver->locked);
+
+    DRM_CAS(xvmc_driver->driHwLock, ctx,
+            (DRM_LOCK_HELD | ctx), __ret);
+
+    if (__ret)
+	intel_xvmc_try_heavy_lock(ctx);
+
+    xvmc_driver->locked = 1;
+}
+
+void UNLOCK_HARDWARE(drm_context_t ctx)
+{
+    xvmc_driver->locked = 0;
+    DRM_UNLOCK(xvmc_driver->fd, xvmc_driver->driHwLock, ctx);
+    PPTHREAD_MUTEX_UNLOCK();
+}
+
 /*
 * Function: XvMCCreateContext
 * Description: Create a XvMC context for the given surface parameters.
@@ -196,6 +225,9 @@ Status XvMCCreateContext(Display *display, XvPortID port,
 	free(priv_data);
         return BadAlloc;
     }
+    pSAREA = (drm_sarea_t *)xvmc_driver->sarea_address;
+    xvmc_driver->driHwLock = (drmLock *)&pSAREA->lock;
+    pthread_mutex_init(&xvmc_driver->ctxmutex, NULL);
 
     /* call driver hook.
      * driver hook should free priv_data after return if success.*/
diff --git a/src/xvmc/intel_xvmc.h b/src/xvmc/intel_xvmc.h
index b5fadb1..28390af 100644
--- a/src/xvmc/intel_xvmc.h
+++ b/src/xvmc/intel_xvmc.h
@@ -136,6 +136,12 @@ typedef struct _intel_xvmc_driver {
     intel_xvmc_drm_map_t batchbuffer;
     unsigned int last_render;
 
+    sigset_t sa_mask;
+    pthread_mutex_t ctxmutex;
+    int lock;   /* Lightweight lock to avoid locking twice */
+    int locked;
+    drmLock *driHwLock;
+
     void *private;
 
     /* XXX: remove? */
@@ -180,4 +186,31 @@ typedef struct _intel_xvmc_driver {
 extern struct _intel_xvmc_driver i915_xvmc_mc_driver;
 extern struct _intel_xvmc_driver *xvmc_driver;
 
+#define SET_BLOCKED_SIGSET()   do {    \
+        sigset_t bl_mask;                       \
+        sigfillset(&bl_mask);           \
+        sigdelset(&bl_mask, SIGFPE);    \
+        sigdelset(&bl_mask, SIGILL);    \
+        sigdelset(&bl_mask, SIGSEGV);   \
+        sigdelset(&bl_mask, SIGBUS);    \
+        sigdelset(&bl_mask, SIGKILL);   \
+        pthread_sigmask(SIG_SETMASK, &bl_mask, &xvmc_driver->sa_mask); \
+    } while (0)
+
+#define RESTORE_BLOCKED_SIGSET() do {    \
+        pthread_sigmask(SIG_SETMASK, &xvmc_driver->sa_mask, NULL); \
+    } while (0)
+
+#define PPTHREAD_MUTEX_LOCK() do {             \
+        SET_BLOCKED_SIGSET();                  \
+        pthread_mutex_lock(&xvmc_driver->ctxmutex);       \
+    } while (0)
+
+#define PPTHREAD_MUTEX_UNLOCK() do {           \
+        pthread_mutex_unlock(&xvmc_driver->ctxmutex);     \
+        RESTORE_BLOCKED_SIGSET();              \
+    } while (0)
+
+extern void LOCK_HARDWARE(drm_context_t);
+extern void UNLOCK_HARDWARE(drm_context_t);
 #endif
commit bcd656c8dfe7309a5cf02ce1da8bc747ccd6e21c
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Thu Nov 15 11:18:38 2007 +0800

    xvmc: oops, should first map batch buffer before init

diff --git a/src/xvmc/intel_batchbuffer.c b/src/xvmc/intel_batchbuffer.c
index c96bd45..82a7bf2 100644
--- a/src/xvmc/intel_batchbuffer.c
+++ b/src/xvmc/intel_batchbuffer.c
@@ -98,6 +98,14 @@ void intelDestroyBatchBuffer(void)
 
 Bool intelInitBatchBuffer(void)
 {
+    if (drmMap(xvmc_driver->fd,
+		xvmc_driver->batchbuffer.handle,
+		xvmc_driver->batchbuffer.size,
+		(drmAddress *)&xvmc_driver->batchbuffer.map) != 0) {
+	XVMC_ERR("fail to map batch buffer\n");
+	return False;
+    }
+
     if (xvmc_driver->batchbuffer.map) {
 	xvmc_driver->alloc.size = xvmc_driver->batchbuffer.size;
 	xvmc_driver->alloc.offset = xvmc_driver->batchbuffer.offset;
@@ -110,14 +118,6 @@ Bool intelInitBatchBuffer(void)
 
     xvmc_driver->alloc.active_buf = 0;
     assert(xvmc_driver->alloc.ptr);
-
-    if (drmMap(xvmc_driver->fd,
-		xvmc_driver->batchbuffer.handle,
-		xvmc_driver->batchbuffer.size,
-		(drmAddress *)&xvmc_driver->batchbuffer.map) != 0) {
-	XVMC_ERR("fail to map batch buffer\n");
-	return False;
-    }
 }
 
 void intelFiniBatchBuffer(void)
commit 0464af581b0fcfc4d1c7fec8160d812262086177
Merge: 2256519... e56c166...
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Thu Nov 15 11:05:44 2007 +0800

    Merge branch 'master' into xvmc

commit 22565198b360826ba10e7ca05d272c419054dc08
Merge: 619044b... e64f492...
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Thu Nov 15 18:53:22 2007 +0800

    Merge branch 'master' into xvmc

commit 619044b242d4abf605b42cfff538b63f445fe709
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Thu Nov 15 02:23:07 2007 +0800

    xvmc: move batch buffer init/fini to intel_batchbuffer.c

diff --git a/src/xvmc/I915XvMC.c b/src/xvmc/I915XvMC.c
index cc05167..1ff3629 100644
--- a/src/xvmc/I915XvMC.c
+++ b/src/xvmc/I915XvMC.c
@@ -1241,14 +1241,6 @@ static int i915_xvmc_map_buffers(i915XvMCContext *pI915XvMC)
                (drmAddress *)&pI915XvMC->corrdata.map) != 0) {
         return -1;
     }
-    
-    /* XXX */
-    if (drmMap(xvmc_driver->fd,
-               xvmc_driver->batchbuffer.handle,
-               xvmc_driver->batchbuffer.size,
-               (drmAddress *)&xvmc_driver->batchbuffer.map) != 0) {
-        return -1;
-    }
 
     return 0;
 }
@@ -1284,11 +1276,6 @@ static void i915_xvmc_unmap_buffers(i915XvMCContext *pI915XvMC)
         drmUnmap(pI915XvMC->corrdata.map, pI915XvMC->corrdata.size);
         pI915XvMC->corrdata.map = NULL;
     }
-
-    if (xvmc_driver->batchbuffer.map) {
-        drmUnmap(xvmc_driver->batchbuffer.map, xvmc_driver->batchbuffer.size);
-        xvmc_driver->batchbuffer.map = NULL;
-    }
 }
 
 /*
diff --git a/src/xvmc/intel_batchbuffer.c b/src/xvmc/intel_batchbuffer.c
index 7768218..c96bd45 100644
--- a/src/xvmc/intel_batchbuffer.c
+++ b/src/xvmc/intel_batchbuffer.c
@@ -96,20 +96,38 @@ void intelDestroyBatchBuffer(void)
 }
 
 
-void intelInitBatchBuffer(void)
+Bool intelInitBatchBuffer(void)
 {
     if (xvmc_driver->batchbuffer.map) {
-        xvmc_driver->alloc.size = xvmc_driver->batchbuffer.size;
-        xvmc_driver->alloc.offset = xvmc_driver->batchbuffer.offset;
-        xvmc_driver->alloc.ptr = xvmc_driver->batchbuffer.map;
+	xvmc_driver->alloc.size = xvmc_driver->batchbuffer.size;
+	xvmc_driver->alloc.offset = xvmc_driver->batchbuffer.offset;
+	xvmc_driver->alloc.ptr = xvmc_driver->batchbuffer.map;
     } else {
-        xvmc_driver->alloc.size = 8 * 1024;
-        xvmc_driver->alloc.offset = 0;
-        xvmc_driver->alloc.ptr = malloc(xvmc_driver->alloc.size);
+	xvmc_driver->alloc.size = 8 * 1024;
+	xvmc_driver->alloc.offset = 0;
+	xvmc_driver->alloc.ptr = malloc(xvmc_driver->alloc.size);
     }
 
-   xvmc_driver->alloc.active_buf = 0;
-   assert(xvmc_driver->alloc.ptr);
+    xvmc_driver->alloc.active_buf = 0;
+    assert(xvmc_driver->alloc.ptr);
+
+    if (drmMap(xvmc_driver->fd,
+		xvmc_driver->batchbuffer.handle,
+		xvmc_driver->batchbuffer.size,
+		(drmAddress *)&xvmc_driver->batchbuffer.map) != 0) {
+	XVMC_ERR("fail to map batch buffer\n");
+	return False;
+    }
+}
+
+void intelFiniBatchBuffer(void)
+{
+    intelFlushBatch(TRUE);
+
+    if (xvmc_driver->batchbuffer.map) {
+        drmUnmap(xvmc_driver->batchbuffer.map, xvmc_driver->batchbuffer.size);
+        xvmc_driver->batchbuffer.map = NULL;
+    }
 }
 
 void intelBatchbufferRequireSpace(unsigned int sz)
diff --git a/src/xvmc/intel_batchbuffer.h b/src/xvmc/intel_batchbuffer.h
index c44a0ad..20e7406 100644
--- a/src/xvmc/intel_batchbuffer.h
+++ b/src/xvmc/intel_batchbuffer.h
@@ -36,7 +36,8 @@ extern int VERBOSE;
 
 extern void intelFlushBatch(Bool);
 extern void intelBatchbufferData(const void *, unsigned, unsigned);
-extern void intelInitBatchBuffer(void);
+extern Bool intelInitBatchBuffer(void);
+extern Bool intelFnitBatchBuffer(void);
 extern void intelDestroyBatchBuffer(void);
 extern void intelCmdIoctl(char *, unsigned);
 #endif /* _INTEL_BATCHBUFFER_H */
diff --git a/src/xvmc/intel_xvmc.c b/src/xvmc/intel_xvmc.c
index 6a99d6d..6c9a950 100644
--- a/src/xvmc/intel_xvmc.c
+++ b/src/xvmc/intel_xvmc.c
@@ -238,6 +238,7 @@ Status XvMCDestroyContext(Display *display, XvMCContext *context)
     /* Pass Control to the X server to destroy the drm_context_t */
     //XXX move generic destroy method here
     //i915_release_resource(display,context);
+    intelFiniBatchBuffer();
     return Success;
 }
 
commit ae805ac379ccfdae9ee272896665e73f5bc7d2cf
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Thu Nov 15 02:13:07 2007 +0800

    xvmc: take out batch buffer handling code

diff --git a/src/i830_memory.c b/src/i830_memory.c
index 907a58a..a08312d 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -2010,5 +2010,8 @@ Bool i830_allocate_xvmc_buffer(ScrnInfoPtr pScrn, const char *name,
         return FALSE;
     }
 
+    if (!i830_bind_memory(pScrn, *buffer))
+	return FALSE;
+
     return TRUE;
 }
diff --git a/src/i915_hwmc.c b/src/i915_hwmc.c
index ef242ba..8a0abf3 100644
--- a/src/i915_hwmc.c
+++ b/src/i915_hwmc.c
@@ -293,14 +293,6 @@ static Bool i915_map_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *ctxpri
         return FALSE;
     }
 
-    if (drmAddMap(pI830->drmSubFD,
-                  (drm_handle_t)(xvmc_driver->batch->offset + pI830->LinearAddr),
-                  xvmc_driver->batch->size, DRM_AGP, 0,
-                  &xvmc_driver->batch_handle) < 0) {
-        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-                   "[drm] drmAddMap(batchbuffer_handle) failed!\n");
-        return FALSE;
-    }
         
     return TRUE;
 }
@@ -339,10 +331,6 @@ static void i915_unmap_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *ctxp
         ctxpriv->corrdata_handle = 0;
     }
 
-    if (xvmc_driver->batch_handle) {
-        drmRmMap(pI830->drmSubFD, xvmc_driver->batch_handle);
-        xvmc_driver->batch_handle = 0;
-    }
 }
 
 static Bool i915_allocate_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *ctxpriv)
@@ -390,11 +378,6 @@ static Bool i915_allocate_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *c
         return FALSE;
     }
 
-    if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC]batch buffer",
-                                   &(xvmc_driver->batch), 8 * 1024,
-                                   ALIGN_BOTH_ENDS)) {
-        return FALSE;
-    }
 
     i830_describe_allocations(pScrn, 1, "");
     return TRUE;
@@ -432,10 +415,6 @@ static void i915_free_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *ctxpr
         ctxpriv->mcCorrdata = NULL;
     }
 
-    if (xvmc_driver->batch) {
-        i830_free_memory(pScrn, xvmc_driver->batch);
-        xvmc_driver->batch = NULL;
-    }
 }
 
 /**************************************************************************
@@ -859,6 +838,40 @@ static int i915_xvmc_putimage_size(ScrnInfoPtr pScrn)
     return sizeof(I915XvMCCommandBuffer);
 }
 
+static Bool i915_xvmc_init_batch(ScrnInfoPtr pScrn)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+
+    if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC] batch buffer",
+                                   &(xvmc_driver->batch), 8 * 1024,
+                                   ALIGN_BOTH_ENDS))
+        return FALSE;
+
+    if (drmAddMap(pI830->drmSubFD,
+                  (drm_handle_t)(xvmc_driver->batch->offset+pI830->LinearAddr),
+                  xvmc_driver->batch->size, DRM_AGP, 0,
+                  &xvmc_driver->batch_handle) < 0) {
+        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                   "[drm] drmAddMap(batchbuffer_handle) failed!\n");
+        return FALSE;
+    }
+    return TRUE;
+}
+
+static void i915_xvmc_fini_batch(ScrnInfoPtr pScrn)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+
+    if (xvmc_driver->batch_handle) {
+        drmRmMap(pI830->drmSubFD, xvmc_driver->batch_handle);
+        xvmc_driver->batch_handle = 0;
+    }
+    if (xvmc_driver->batch) {
+        i830_free_memory(pScrn, xvmc_driver->batch);
+        xvmc_driver->batch = NULL;
+    }
+}
+
 static Bool i915_xvmc_init(ScrnInfoPtr pScrn, XF86VideoAdaptorPtr XvAdapt)
 {
     I915XvMCPtr pXvMC;
@@ -870,6 +883,12 @@ static Bool i915_xvmc_init(ScrnInfoPtr pScrn, XF86VideoAdaptorPtr XvAdapt)
         return FALSE;
     }
     xvmc_driver->devPrivate = (void*)pXvMC;
+    if (!i915_xvmc_init_batch(pScrn)) {
+        xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+		"[XvMC] fail to init batch buffer\n");
+	xfree(pXvMC);
+	return FALSE;
+    }
     initI915XvMC(pXvMC);
 
     /* set up wrappers */
@@ -883,6 +902,7 @@ static void i915_xvmc_fini(ScrnInfoPtr pScrn)
     I915XvMCPtr pXvMC = (I915XvMCPtr)xvmc_driver->devPrivate;
 
     cleanupI915XvMC(pXvMC);
+    i915_xvmc_fini_batch(pScrn);
     xfree(xvmc_driver->devPrivate);
 }
 
commit e8db8584ae4860aa991c916126335b287a972d5b
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Wed Nov 14 00:11:20 2007 +0800

    xvmc: attempt to move batch buffer code out of i915 private

diff --git a/src/i830_hwmc.h b/src/i830_hwmc.h
index 97fe4fd..b874d21 100644
--- a/src/i830_hwmc.h
+++ b/src/i830_hwmc.h
@@ -43,9 +43,18 @@
 #define XVMC_I965_MPEG2_VLD	0x08
 
 /* common header for context private */
+struct hwmc_buffer
+{
+    drm_handle_t handle;
+    unsigned long offset;
+    unsigned long size;
+    unsigned long bus_addr;
+};
+
 struct _intel_xvmc_common {
     unsigned int type;
     unsigned int sarea_size;
+    struct hwmc_buffer batchbuffer;
 };
 
 #ifdef _INTEL_XVMC_SERVER_
@@ -55,6 +64,9 @@ struct intel_xvmc_driver {
     char *name;
     XF86MCAdaptorPtr adaptor;
     unsigned int flag;
+    i830_memory *batch;
+    drm_handle_t batch_handle;
+
     /* more items for xvmv surface manage? */
     Bool (*init)(ScrnInfoPtr, XF86VideoAdaptorPtr);
     void (*fini)(ScrnInfoPtr);
diff --git a/src/i915_hwmc.c b/src/i915_hwmc.c
index 6ab00e2..ef242ba 100644
--- a/src/i915_hwmc.c
+++ b/src/i915_hwmc.c
@@ -83,8 +83,6 @@ typedef struct _I915XvMCContextPriv
     drm_handle_t psc_handle;
     i830_memory *mcCorrdata;
     drm_handle_t corrdata_handle;
-    i830_memory *mcBatchBuffer;
-    drm_handle_t batchbuffer_handle;
 } I915XvMCContextPriv;
 
 typedef struct _I915XvMC 
@@ -296,9 +294,9 @@ static Bool i915_map_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *ctxpri
     }
 
     if (drmAddMap(pI830->drmSubFD,
-                  (drm_handle_t)(ctxpriv->mcBatchBuffer->offset + pI830->LinearAddr),
-                  ctxpriv->mcBatchBuffer->size, DRM_AGP, 0,
-                  (drmAddress)&ctxpriv->batchbuffer_handle) < 0) {
+                  (drm_handle_t)(xvmc_driver->batch->offset + pI830->LinearAddr),
+                  xvmc_driver->batch->size, DRM_AGP, 0,
+                  &xvmc_driver->batch_handle) < 0) {
         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
                    "[drm] drmAddMap(batchbuffer_handle) failed!\n");
         return FALSE;
@@ -341,9 +339,9 @@ static void i915_unmap_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *ctxp
         ctxpriv->corrdata_handle = 0;
     }
 
-    if (ctxpriv->batchbuffer_handle) {
-        drmRmMap(pI830->drmSubFD, ctxpriv->batchbuffer_handle);
-        ctxpriv->batchbuffer_handle = 0;
+    if (xvmc_driver->batch_handle) {
+        drmRmMap(pI830->drmSubFD, xvmc_driver->batch_handle);
+        xvmc_driver->batch_handle = 0;
     }
 }
 
@@ -393,7 +391,7 @@ static Bool i915_allocate_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *c
     }
 
     if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC]batch buffer",
-                                   &(ctxpriv->mcBatchBuffer), 8 * 1024,
+                                   &(xvmc_driver->batch), 8 * 1024,
                                    ALIGN_BOTH_ENDS)) {
         return FALSE;
     }
@@ -434,9 +432,9 @@ static void i915_free_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *ctxpr
         ctxpriv->mcCorrdata = NULL;
     }
 
-    if (ctxpriv->mcBatchBuffer) {
-        i830_free_memory(pScrn, ctxpriv->mcBatchBuffer);
-        ctxpriv->mcBatchBuffer = NULL;
+    if (xvmc_driver->batch) {
+        i830_free_memory(pScrn, xvmc_driver->batch);
+        xvmc_driver->batch = NULL;
     }
 }
 
@@ -528,8 +526,14 @@ static int I915XvMCCreateContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext,
         return BadAlloc;
     }
 
+    /* common context items */
     contextRec->comm.type = xvmc_driver->flag;
     contextRec->comm.sarea_size = pDRIInfo->SAREASize;
+    contextRec->comm.batchbuffer.offset = xvmc_driver->batch->offset;
+    contextRec->comm.batchbuffer.size = xvmc_driver->batch->size;
+    contextRec->comm.batchbuffer.handle = xvmc_driver->batch_handle;
+
+    /* i915 private context */
     contextRec->ctxno = i;
     contextRec->sis.handle = ctxpriv->sis_handle;
     contextRec->sis.offset = ctxpriv->mcStaticIndirectState->offset;
@@ -554,9 +558,6 @@ static int I915XvMCCreateContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext,
     contextRec->corrdata.handle = ctxpriv->corrdata_handle;
     contextRec->corrdata.offset = ctxpriv->mcCorrdata->offset;
     contextRec->corrdata.size = ctxpriv->mcCorrdata->size;
-    contextRec->batchbuffer.handle = ctxpriv->batchbuffer_handle;
-    contextRec->batchbuffer.offset = ctxpriv->mcBatchBuffer->offset;
-    contextRec->batchbuffer.size = ctxpriv->mcBatchBuffer->size;
     contextRec->sarea_priv_offset = sizeof(XF86DRISAREARec);
     contextRec->depth = pScrn->bitsPerPixel;
     contextRec->deviceID = pI830DRI->deviceID;
diff --git a/src/i915_hwmc.h b/src/i915_hwmc.h
index d110661..684ed94 100644
--- a/src/i915_hwmc.h
+++ b/src/i915_hwmc.h
@@ -47,15 +47,8 @@ typedef struct
     int real_id;
 } I915XvMCCommandBuffer;
 
-struct hwmc_buffer
-{
-    drm_handle_t handle;
-    unsigned long offset;
-    unsigned long size;
-    unsigned long bus_addr;
-};
 
-typedef struct 
+typedef struct
 {
     struct _intel_xvmc_common comm;
     unsigned int ctxno; /* XvMC private context reference number */
@@ -65,7 +58,6 @@ typedef struct
     struct hwmc_buffer psp;
     struct hwmc_buffer psc;
     struct hwmc_buffer corrdata;/* Correction Data Buffer */
-    struct hwmc_buffer batchbuffer;
     unsigned int sarea_priv_offset;
     unsigned int depth;
     int deviceID;
diff --git a/src/xvmc/I915XvMC.c b/src/xvmc/I915XvMC.c
index aab186d..cc05167 100644
--- a/src/xvmc/I915XvMC.c
+++ b/src/xvmc/I915XvMC.c
@@ -31,7 +31,6 @@
 #include "I915XvMC.h"
 #include "i915_structs.h"
 #include "i915_program.h"
-#include "intel_batchbuffer.h"
 
 #define SAREAPTR(ctx) ((drmI830Sarea *)                     \
                        (((CARD8 *)(ctx)->sarea_address) +   \
@@ -204,7 +203,7 @@ static void UNLOCK_HARDWARE(i915XvMCContext *pI915XvMC)
     PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
 }
 
-static void i915_flush(i915XvMCContext *pI915XvMC, int map, int render)
+static void i915_flush(int map, int render)
 {
     struct i915_mi_flush mi_flush;
 
@@ -214,7 +213,7 @@ static void i915_flush(i915XvMCContext *pI915XvMC, int map, int render)
     mi_flush.dw0.map_cache_invalidate = map;
     mi_flush.dw0.render_cache_flush_inhibit = render;
 
-    intelBatchbufferData(pI915XvMC, &mi_flush, sizeof(mi_flush), 0);
+    intelBatchbufferData(&mi_flush, sizeof(mi_flush), 0);
 }
 
 /* for MC picture rendering */
@@ -539,14 +538,13 @@ static void i915_mc_load_sis_msb_buffers(XvMCContext *context)
     else
         msb->dw0.buffer_address = (pI915XvMC->msb.bus_addr >> 2);
 
-    intelBatchbufferData(pI915XvMC, base, size, 0);
+    intelBatchbufferData(base, size, 0);
     free(base);
 }
 
 static void i915_mc_mpeg_set_origin(XvMCContext *context, XvMCMacroBlock *mb)
 {
     struct i915_3dmpeg_set_origin set_origin;
-    i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
 
     /* 3DMPEG_SET_ORIGIN */
     memset(&set_origin, 0, sizeof(set_origin));
@@ -556,13 +554,12 @@ static void i915_mc_mpeg_set_origin(XvMCContext *context, XvMCMacroBlock *mb)
     set_origin.dw1.h_origin = mb->x;
     set_origin.dw1.v_origin = mb->y;
 
-    intelBatchbufferData(pI915XvMC, &set_origin, sizeof(set_origin), 0);
+    intelBatchbufferData(&set_origin, sizeof(set_origin), 0);
 }
 
 static void i915_mc_mpeg_macroblock_ipicture(XvMCContext *context, XvMCMacroBlock *mb)
 {
     struct i915_3dmpeg_macroblock_ipicture macroblock_ipicture;
-    i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
 
     /* 3DMPEG_MACROBLOCK_IPICTURE */
     memset(&macroblock_ipicture, 0, sizeof(macroblock_ipicture));
@@ -570,14 +567,13 @@ static void i915_mc_mpeg_macroblock_ipicture(XvMCContext *context, XvMCMacroBloc
     macroblock_ipicture.dw0.opcode = OPC_3DMPEG_MACROBLOCK_IPICTURE;
     macroblock_ipicture.dw0.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD);
 
-    intelBatchbufferData(pI915XvMC, &macroblock_ipicture, sizeof(macroblock_ipicture), 0);
+    intelBatchbufferData(&macroblock_ipicture, sizeof(macroblock_ipicture), 0);
 }
 
 
 static void i915_mc_mpeg_macroblock_0mv(XvMCContext *context, XvMCMacroBlock *mb)
 {
     struct i915_3dmpeg_macroblock_0mv macroblock_0mv;
-    i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
 
     /* 3DMPEG_MACROBLOCK(0mv) */
     memset(&macroblock_0mv, 0, sizeof(macroblock_0mv));
@@ -600,13 +596,12 @@ static void i915_mc_mpeg_macroblock_0mv(XvMCContext *context, XvMCMacroBlock *mb
     macroblock_0mv.header.dw1.coded_block_pattern = mb->coded_block_pattern;
     macroblock_0mv.header.dw1.skipped_macroblocks = 0;
 
-    intelBatchbufferData(pI915XvMC, &macroblock_0mv, sizeof(macroblock_0mv), 0);
+    intelBatchbufferData(&macroblock_0mv, sizeof(macroblock_0mv), 0);
 }
 
 static void i915_mc_mpeg_macroblock_1fbmv(XvMCContext *context, XvMCMacroBlock *mb)
 {
     struct i915_3dmpeg_macroblock_1fbmv macroblock_1fbmv;
-    i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
     
     /* Motion Vectors */
     su_t fmv;
@@ -639,7 +634,7 @@ static void i915_mc_mpeg_macroblock_1fbmv(XvMCContext *context, XvMCMacroBlock *
     macroblock_1fbmv.dw2 = fmv.u[0];
     macroblock_1fbmv.dw3 = bmv.u[0];
     
-    intelBatchbufferData(pI915XvMC, &macroblock_1fbmv, sizeof(macroblock_1fbmv), 0);
+    intelBatchbufferData(&macroblock_1fbmv, sizeof(macroblock_1fbmv), 0);
 }
 
 static void i915_mc_mpeg_macroblock_2fbmv(XvMCContext *context, XvMCMacroBlock *mb, unsigned int ps)
@@ -706,7 +701,7 @@ static void i915_mc_mpeg_macroblock_2fbmv(XvMCContext *context, XvMCMacroBlock *
     macroblock_2fbmv.dw4 = fmv.u[1];
     macroblock_2fbmv.dw5 = bmv.u[1];
 
-    intelBatchbufferData(pI915XvMC, &macroblock_2fbmv, sizeof(macroblock_2fbmv), 0);
+    intelBatchbufferData(&macroblock_2fbmv, sizeof(macroblock_2fbmv), 0);
 }
 
 /* for MC context initialization */
@@ -1032,7 +1027,7 @@ static void i915_mc_one_time_state_initialization(XvMCContext *context)
     s6->color_buffer_write = 1;
     s6->triangle_pv = 0;
 
-    intelBatchbufferData(pI915XvMC, base, size, 0);
+    intelBatchbufferData(base, size, 0);
     free(base);
 
     /* 3DSTATE_LOAD_INDIRECT */
@@ -1091,7 +1086,7 @@ static void i915_mc_one_time_state_initialization(XvMCContext *context)
     else
         psc->dw0.buffer_address = (pI915XvMC->psc.bus_addr >> 2);
 
-    intelBatchbufferData(pI915XvMC, base, size, 0);
+    intelBatchbufferData(base, size, 0);
     free(base);
 }
 
@@ -1199,7 +1194,7 @@ static void i915_mc_invalidate_subcontext_buffers(XvMCContext *context, unsigned
         ptr = ++psc;
     }
 
-    intelBatchbufferData(pI915XvMC, base, size, 0);
+    intelBatchbufferData(base, size, 0);
     free(base);
 }
 
@@ -1247,10 +1242,11 @@ static int i915_xvmc_map_buffers(i915XvMCContext *pI915XvMC)
         return -1;
     }
     
+    /* XXX */
     if (drmMap(xvmc_driver->fd,
-               pI915XvMC->batchbuffer.handle,
-               pI915XvMC->batchbuffer.size,
-               (drmAddress *)&pI915XvMC->batchbuffer.map) != 0) {
+               xvmc_driver->batchbuffer.handle,
+               xvmc_driver->batchbuffer.size,
+               (drmAddress *)&xvmc_driver->batchbuffer.map) != 0) {
         return -1;
     }
 
@@ -1289,9 +1285,9 @@ static void i915_xvmc_unmap_buffers(i915XvMCContext *pI915XvMC)
         pI915XvMC->corrdata.map = NULL;
     }
 
-    if (pI915XvMC->batchbuffer.map) {
-        drmUnmap(pI915XvMC->batchbuffer.map, pI915XvMC->batchbuffer.size);
-        pI915XvMC->batchbuffer.map = NULL;
+    if (xvmc_driver->batchbuffer.map) {
+        drmUnmap(xvmc_driver->batchbuffer.map, xvmc_driver->batchbuffer.size);
+        xvmc_driver->batchbuffer.map = NULL;
     }
 }
 
@@ -1618,7 +1614,7 @@ static void i915_yuv2rgb_proc(XvMCSurface *surface)
     s6->color_buffer_write = 1;
 
     s7 = (struct s7_dword *)(++s6);
-    intelBatchbufferData(pI915XvMC, base, size, 0);
+    intelBatchbufferData(base, size, 0);
     free(base);
 
     /* 3DSTATE_3DSTATE_SCISSOR_RECTANGLE */
@@ -1629,7 +1625,7 @@ static void i915_yuv2rgb_proc(XvMCSurface *surface)
     scissor_rectangle.dw1.min_y = 0;
     scissor_rectangle.dw2.max_x = 2047;
     scissor_rectangle.dw2.max_y = 2047;
-    intelBatchbufferData(pI915XvMC, &scissor_rectangle, sizeof(scissor_rectangle), 0);
+    intelBatchbufferData(&scissor_rectangle, sizeof(scissor_rectangle), 0);
 
     /* 3DSTATE_LOAD_INDIRECT */
     size = sizeof(*load_indirect) + sizeof(*sis) + sizeof(*ssb) + sizeof(*msb) + sizeof(*psp);
@@ -1669,7 +1665,7 @@ static void i915_yuv2rgb_proc(XvMCSurface *surface)
     psp->dw1.length = ((sizeof(struct i915_3dstate_pixel_shader_program) +
                         sizeof(union shader_inst)) >> 2) - 1;
 
-    intelBatchbufferData(pI915XvMC, base, size, 0);
+    intelBatchbufferData(base, size, 0);
     free(base);
 
     /* 3DPRIMITIVE */
@@ -1706,7 +1702,7 @@ static void i915_yuv2rgb_proc(XvMCSurface *surface)
     vd->tc1.tcx = 0;
     vd->tc1.tcy = 0;
 
-    intelBatchbufferData(pI915XvMC, base, size, 0);
+    intelBatchbufferData(base, size, 0);
     free(base);
 }
 
@@ -1735,7 +1731,7 @@ static void i915_release_resource(Display *display, XvMCContext *context)
     uniDRIDestroyContext(display, screen, pI915XvMC->id);
     XUnlockDisplay(display);
 
-    intelDestroyBatchBuffer(pI915XvMC);
+    intelDestroyBatchBuffer();
 
     drmUnmap(xvmc_driver->sarea_address, xvmc_driver->sarea_size);
 
@@ -1815,9 +1811,6 @@ static Status i915_xvmc_mc_create_context(Display *display, XvMCContext *context
     pI915XvMC->corrdata.handle = tmpComm->corrdata.handle;
     pI915XvMC->corrdata.offset = tmpComm->corrdata.offset;
     pI915XvMC->corrdata.size = tmpComm->corrdata.size;
-    pI915XvMC->batchbuffer.handle = tmpComm->batchbuffer.handle;
-    pI915XvMC->batchbuffer.offset = tmpComm->batchbuffer.offset;
-    pI915XvMC->batchbuffer.size = tmpComm->batchbuffer.size;
     pI915XvMC->sarea_priv_offset = tmpComm->sarea_priv_offset;
     pI915XvMC->depth = tmpComm->depth;
 
@@ -1872,9 +1865,8 @@ static Status i915_xvmc_mc_create_context(Display *display, XvMCContext *context
     pI915XvMC->last_flip = 0;
     pI915XvMC->locked = 0;
     pI915XvMC->port = context->port;
-    pthread_mutex_init(&pI915XvMC->ctxmutex, NULL);
     /* XXX */
-    intelInitBatchBuffer(pI915XvMC);
+    pthread_mutex_init(&pI915XvMC->ctxmutex, NULL);
     pI915XvMC->ref = 1;
     return Success;
 }
@@ -2160,7 +2152,7 @@ static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context,
         corrdata_ptr += bspm;
     } 
 
-    i915_flush(pI915XvMC, 1, 0);
+    i915_flush(1, 0);
     // i915_mc_invalidate_subcontext_buffers(context, BLOCK_SIS | BLOCK_DIS | BLOCK_SSB 
     // | BLOCK_MSB | BLOCK_PSP | BLOCK_PSC);
 
@@ -2221,9 +2213,9 @@ static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context,
         }       /* Field Picture */
     }
 
-    intelFlushBatch(pI915XvMC, TRUE);
-    pI915XvMC->last_render = pI915XvMC->alloc.irq_emitted;
-    privTarget->last_render = pI915XvMC->last_render;
+    intelFlushBatch(TRUE);
+    xvmc_driver->last_render = xvmc_driver->alloc.irq_emitted;
+    privTarget->last_render = xvmc_driver->last_render;
 
     UNLOCK_HARDWARE(pI915XvMC);
     return 0;
diff --git a/src/xvmc/I915XvMC.h b/src/xvmc/I915XvMC.h
index b1d3117..b97dc48 100644
--- a/src/xvmc/I915XvMC.h
+++ b/src/xvmc/I915XvMC.h
@@ -63,7 +63,6 @@ typedef struct _i915XvMCDrmMap {
 ***************************************************************************/
 typedef struct _i915XvMCContext {
     unsigned int ctxno;
-    unsigned int last_render;
     unsigned int last_flip;
     unsigned int dual_prime; /* Flag to identify when dual prime is in use. */
     unsigned int yStride;
@@ -97,25 +96,9 @@ typedef struct _i915XvMCContext {
     i915XvMCDrmMap psc;
 
     i915XvMCDrmMap corrdata;
-    i915XvMCDrmMap batchbuffer;
 
     sigset_t sa_mask;
 
-    struct {
-	unsigned int start_offset;
-	unsigned int size;
-	unsigned int space;
-	unsigned char *ptr;
-    } batch;
-
-    struct
-    {
-        void *ptr;
-        unsigned int size;
-        unsigned int offset;
-        unsigned int active_buf;
-        unsigned int irq_emitted;
-    } alloc;
 } i915XvMCContext;
 
 /***************************************************************************
diff --git a/src/xvmc/intel_batchbuffer.c b/src/xvmc/intel_batchbuffer.c
index 8b6ff11..7768218 100644
--- a/src/xvmc/intel_batchbuffer.c
+++ b/src/xvmc/intel_batchbuffer.c
@@ -43,12 +43,12 @@
 #include <X11/extensions/XvMC.h>
 #include <X11/extensions/XvMClib.h>
 
-#include "I915XvMC.h"
+#include "intel_xvmc.h"
 #include "intel_batchbuffer.h"
 
 #define MI_BATCH_BUFFER_END     (0xA << 23)
 
-int intelEmitIrqLocked(i915XvMCContext *pI915XvMC)
+int intelEmitIrqLocked(void)
 {
    drmI830IrqEmit ie;
    int ret, seq;
@@ -65,7 +65,7 @@ int intelEmitIrqLocked(i915XvMCContext *pI915XvMC)
    return seq;
 }
 
-void intelWaitIrq(i915XvMCContext *pI915XvMC, int seq)
+void intelWaitIrq(int seq)
 {
    int ret;
    drmI830IrqWait iw;
@@ -82,137 +82,136 @@ void intelWaitIrq(i915XvMCContext *pI915XvMC, int seq)
    }
 }
 
-void intelDestroyBatchBuffer(i915XvMCContext *pI915XvMC)
+void intelDestroyBatchBuffer(void)
 {
-   if (pI915XvMC->alloc.offset) {
-       pI915XvMC->alloc.ptr = NULL;
-       pI915XvMC->alloc.offset = 0;
-   } else if (pI915XvMC->alloc.ptr) {
-      free(pI915XvMC->alloc.ptr);
-      pI915XvMC->alloc.ptr = NULL;
+   if (xvmc_driver->alloc.offset) {
+       xvmc_driver->alloc.ptr = NULL;
+       xvmc_driver->alloc.offset = 0;
+   } else if (xvmc_driver->alloc.ptr) {
+      free(xvmc_driver->alloc.ptr);
+      xvmc_driver->alloc.ptr = NULL;
    }
 
-   memset(&pI915XvMC->batch, 0, sizeof(pI915XvMC->batch));
+   memset(&xvmc_driver->batch, 0, sizeof(xvmc_driver->batch));
 }
 
 
-void intelInitBatchBuffer(i915XvMCContext  *pI915XvMC)
+void intelInitBatchBuffer(void)
 {
-    if (pI915XvMC->batchbuffer.map) {
-        pI915XvMC->alloc.size = pI915XvMC->batchbuffer.size;
-        pI915XvMC->alloc.offset = pI915XvMC->batchbuffer.offset;
-        pI915XvMC->alloc.ptr = pI915XvMC->batchbuffer.map;
+    if (xvmc_driver->batchbuffer.map) {
+        xvmc_driver->alloc.size = xvmc_driver->batchbuffer.size;
+        xvmc_driver->alloc.offset = xvmc_driver->batchbuffer.offset;
+        xvmc_driver->alloc.ptr = xvmc_driver->batchbuffer.map;
     } else {
-        pI915XvMC->alloc.size = 8 * 1024;
-        pI915XvMC->alloc.offset = 0;
-        pI915XvMC->alloc.ptr = malloc(pI915XvMC->alloc.size);
+        xvmc_driver->alloc.size = 8 * 1024;
+        xvmc_driver->alloc.offset = 0;
+        xvmc_driver->alloc.ptr = malloc(xvmc_driver->alloc.size);
     }
 
-   pI915XvMC->alloc.active_buf = 0;
-   assert(pI915XvMC->alloc.ptr);
+   xvmc_driver->alloc.active_buf = 0;
+   assert(xvmc_driver->alloc.ptr);
 }
 
-void intelBatchbufferRequireSpace(i915XvMCContext *pI915XvMC, unsigned sz)
+void intelBatchbufferRequireSpace(unsigned int sz)
 {
-   if (pI915XvMC->batch.space < sz)
-      intelFlushBatch(pI915XvMC, TRUE);
+   if (xvmc_driver->batch.space < sz)
+      intelFlushBatch(TRUE);
 }
 
-void intelBatchbufferData(i915XvMCContext *pI915XvMC, const void *data, 
-                          unsigned bytes, unsigned flags)
+void intelBatchbufferData(const void *data, unsigned bytes, unsigned flags)
 {
    assert((bytes & 0x3) == 0);
 
-   intelBatchbufferRequireSpace(pI915XvMC, bytes);
-   memcpy(pI915XvMC->batch.ptr, data, bytes);
-   pI915XvMC->batch.ptr += bytes;
-   pI915XvMC->batch.space -= bytes;
+   intelBatchbufferRequireSpace(bytes);
+   memcpy(xvmc_driver->batch.ptr, data, bytes);
+   xvmc_driver->batch.ptr += bytes;
+   xvmc_driver->batch.space -= bytes;
 
-   assert(pI915XvMC->batch.space >= 0);
+   assert(xvmc_driver->batch.space >= 0);
 }
 
 #define MI_FLUSH                ((0 << 29) | (4 << 23))
 #define FLUSH_MAP_CACHE         (1 << 0)
 #define FLUSH_RENDER_CACHE      (0 << 2)
 #define FLUSH_WRITE_DIRTY_STATE (1 << 4)
-void intelRefillBatchLocked(i915XvMCContext *pI915XvMC, Bool allow_unlock )
+
+void intelRefillBatchLocked(Bool allow_unlock )
 {
-   unsigned half = pI915XvMC->alloc.size >> 1;
-   unsigned buf = (pI915XvMC->alloc.active_buf ^= 1);
+   unsigned half = xvmc_driver->alloc.size >> 1;
+   unsigned buf = (xvmc_driver->alloc.active_buf ^= 1);
    unsigned dword[2];
 
    dword[0] = MI_FLUSH | FLUSH_WRITE_DIRTY_STATE | FLUSH_RENDER_CACHE | FLUSH_MAP_CACHE;
    dword[1] = 0;
-   intelCmdIoctl(pI915XvMC, (char *)&dword[0], sizeof(dword));
-   pI915XvMC->alloc.irq_emitted = intelEmitIrqLocked(pI915XvMC);
+   intelCmdIoctl((char *)&dword[0], sizeof(dword));
+   xvmc_driver->alloc.irq_emitted = intelEmitIrqLocked();
 
-   if (pI915XvMC->alloc.irq_emitted) {
-       intelWaitIrq(pI915XvMC, pI915XvMC->alloc.irq_emitted);
+   if (xvmc_driver->alloc.irq_emitted) {
+       intelWaitIrq(xvmc_driver->alloc.irq_emitted);
    }
 
-   pI915XvMC->batch.start_offset = pI915XvMC->alloc.offset + buf * half;
-   pI915XvMC->batch.ptr = (unsigned char *)pI915XvMC->alloc.ptr + buf * half;
-   pI915XvMC->batch.size = half - 8;
-   pI915XvMC->batch.space = half - 8;
-   assert(pI915XvMC->batch.space >= 0);
+   xvmc_driver->batch.start_offset = xvmc_driver->alloc.offset + buf * half;
+   xvmc_driver->batch.ptr = (unsigned char *)xvmc_driver->alloc.ptr + buf * half;
+   xvmc_driver->batch.size = half - 8;
+   xvmc_driver->batch.space = half - 8;
+   assert(xvmc_driver->batch.space >= 0);
 }
 
 
-void intelFlushBatchLocked(i915XvMCContext *pI915XvMC,
-                           Bool ignore_cliprects,
+void intelFlushBatchLocked(Bool ignore_cliprects,
                            Bool refill,
                            Bool allow_unlock)
 {
    drmI830BatchBuffer batch;
 
-   if (pI915XvMC->batch.space != pI915XvMC->batch.size) {
+   if (xvmc_driver->batch.space != xvmc_driver->batch.size) {
 
-      batch.start = pI915XvMC->batch.start_offset;
-      batch.used = pI915XvMC->batch.size - pI915XvMC->batch.space;
+      batch.start = xvmc_driver->batch.start_offset;
+      batch.used = xvmc_driver->batch.size - xvmc_driver->batch.space;
       batch.cliprects = 0;
       batch.num_cliprects = 0;
       batch.DR1 = 0;
       batch.DR4 = 0;
 
-      if (pI915XvMC->alloc.offset) {
+      if (xvmc_driver->alloc.offset) {
           if ((batch.used & 0x4) == 0) {
-              ((int *)pI915XvMC->batch.ptr)[0] = 0;
-              ((int *)pI915XvMC->batch.ptr)[1] = MI_BATCH_BUFFER_END;
+              ((int *)xvmc_driver->batch.ptr)[0] = 0;
+              ((int *)xvmc_driver->batch.ptr)[1] = MI_BATCH_BUFFER_END;
               batch.used += 0x8;
-              pI915XvMC->batch.ptr += 0x8;
+              xvmc_driver->batch.ptr += 0x8;
           } else {
-              ((int *)pI915XvMC->batch.ptr)[0] = MI_BATCH_BUFFER_END;
+              ((int *)xvmc_driver->batch.ptr)[0] = MI_BATCH_BUFFER_END;
               batch.used += 0x4;
-              pI915XvMC->batch.ptr += 0x4;
+              xvmc_driver->batch.ptr += 0x4;
           }
       }
 
-      pI915XvMC->batch.start_offset += batch.used;
-      pI915XvMC->batch.size -= batch.used;
+      xvmc_driver->batch.start_offset += batch.used;
+      xvmc_driver->batch.size -= batch.used;
 
-      if (pI915XvMC->batch.size < 8) {
+      if (xvmc_driver->batch.size < 8) {
          refill = TRUE;
-         pI915XvMC->batch.space = pI915XvMC->batch.size = 0;
+         xvmc_driver->batch.space = xvmc_driver->batch.size = 0;
       }
       else {
-         pI915XvMC->batch.size -= 8;
-         pI915XvMC->batch.space = pI915XvMC->batch.size;
+         xvmc_driver->batch.size -= 8;
+         xvmc_driver->batch.space = xvmc_driver->batch.size;
       }
 
-      assert(pI915XvMC->batch.space >= 0);
-      assert(batch.start >= pI915XvMC->alloc.offset);
-      assert(batch.start < pI915XvMC->alloc.offset + pI915XvMC->alloc.size);
-      assert(batch.start + batch.used > pI915XvMC->alloc.offset);
-      assert(batch.start + batch.used <= pI915XvMC->alloc.offset + pI915XvMC->alloc.size);
+      assert(xvmc_driver->batch.space >= 0);
+      assert(batch.start >= xvmc_driver->alloc.offset);
+      assert(batch.start < xvmc_driver->alloc.offset + xvmc_driver->alloc.size);
+      assert(batch.start + batch.used > xvmc_driver->alloc.offset);
+      assert(batch.start + batch.used <= xvmc_driver->alloc.offset + xvmc_driver->alloc.size);
 
-      if (pI915XvMC->alloc.offset) {
+      if (xvmc_driver->alloc.offset) {
           if (drmCommandWrite(xvmc_driver->fd, DRM_I830_BATCHBUFFER, &batch, sizeof(batch))) {
               fprintf(stderr, "DRM_I830_BATCHBUFFER: %d\n",  -errno);
               exit(1);
           }
       } else {
          drmI830CmdBuffer cmd;
-         cmd.buf = (char *)pI915XvMC->alloc.ptr + batch.start;
+         cmd.buf = (char *)xvmc_driver->alloc.ptr + batch.start;
          cmd.sz = batch.used;
          cmd.DR1 = batch.DR1;
          cmd.DR4 = batch.DR4;
@@ -228,15 +227,15 @@ void intelFlushBatchLocked(i915XvMCContext *pI915XvMC,
    }
 
    if (refill)
-      intelRefillBatchLocked(pI915XvMC, allow_unlock);
+      intelRefillBatchLocked(allow_unlock);
 }
 
-void intelFlushBatch(i915XvMCContext *pI915XvMC, Bool refill )
+void intelFlushBatch(Bool refill )
 {
-   intelFlushBatchLocked(pI915XvMC, FALSE, refill, TRUE);
+   intelFlushBatchLocked(FALSE, refill, TRUE);
 }
 
-void intelCmdIoctl(i915XvMCContext *pI915XvMC, char *buf, unsigned used)
+void intelCmdIoctl(char *buf, unsigned used)
 {
    drmI830CmdBuffer cmd;
 
diff --git a/src/xvmc/intel_batchbuffer.h b/src/xvmc/intel_batchbuffer.h
index 5b3e8e1..c44a0ad 100644
--- a/src/xvmc/intel_batchbuffer.h
+++ b/src/xvmc/intel_batchbuffer.h
@@ -13,10 +13,10 @@ extern int VERBOSE;
         if (VERBOSE) fprintf(stderr,                                    \
                              "BEGIN_BATCH(%ld) in %s, %d dwords free\n", \
                              ((unsigned long)n), __FUNCTION__,          \
-                             pI915XvMC->batch.space/4);                     \
-        if (pI915XvMC->batch.space < (n)*4)                                 \
-            intelFlushBatch(pI915XvMC, TRUE);                            \
-        batch_ptr = pI915XvMC->batch.ptr;                                   \
+                             xvmc_driver->batch.space/4);                     \
+        if (xvmc_driver->batch.space < (n)*4)                                 \
+            intelFlushBatch(TRUE);                            \
+        batch_ptr = xvmc_driver->batch.ptr;                                   \
     } while (0)
 
 #define OUT_BATCH(n)                                                    \
@@ -29,14 +29,14 @@ extern int VERBOSE;
 #define ADVANCE_BATCH()                                        \
     do {                                                       \
         if (VERBOSE) fprintf(stderr, "ADVANCE_BATCH()\n");     \
-        pI915XvMC->batch.space -= (batch_ptr - pI915XvMC->batch.ptr);  \
-        pI915XvMC->batch.ptr = batch_ptr;                          \
-        assert(pI915XvMC->batch.space >= 0);                       \
+        xvmc_driver->batch.space -= (batch_ptr - xvmc_driver->batch.ptr);  \
+        xvmc_driver->batch.ptr = batch_ptr;                          \
+        assert(xvmc_driver->batch.space >= 0);                       \
     } while(0)
 
-extern void intelFlushBatch(i915XvMCContext *, Bool);
-extern void intelBatchbufferData(i915XvMCContext *, const void *, unsigned, unsigned);
-extern void intelInitBatchBuffer(i915XvMCContext *);
-extern void intelDestroyBatchBuffer(i915XvMCContext *);
-extern void intelCmdIoctl(i915XvMCContext *, char *, unsigned);
+extern void intelFlushBatch(Bool);
+extern void intelBatchbufferData(const void *, unsigned, unsigned);
+extern void intelInitBatchBuffer(void);
+extern void intelDestroyBatchBuffer(void);
+extern void intelCmdIoctl(char *, unsigned);
 #endif /* _INTEL_BATCHBUFFER_H */
diff --git a/src/xvmc/intel_xvmc.c b/src/xvmc/intel_xvmc.c
index 804ce49..6a99d6d 100644
--- a/src/xvmc/intel_xvmc.c
+++ b/src/xvmc/intel_xvmc.c
@@ -141,6 +141,9 @@ Status XvMCCreateContext(Display *display, XvPortID port,
 	return BadValue;
     }
     xvmc_driver->sarea_size = comm->sarea_size;
+    xvmc_driver->batchbuffer.handle = comm->batchbuffer.handle;
+    xvmc_driver->batchbuffer.offset = comm->batchbuffer.offset;
+    xvmc_driver->batchbuffer.size = comm->batchbuffer.size;
 
     ret = uniDRIQueryDirectRenderingCapable(display, screen,
                                             &isCapable);
@@ -204,8 +207,7 @@ Status XvMCCreateContext(Display *display, XvPortID port,
 	return ret;
     }
 
-    /* FIXME batch buffer */
-    //intelInitBatchBuffer(xvmc_driver);
+    intelInitBatchBuffer();
 
     return Success;
 }
@@ -675,7 +677,7 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context,
         }       /* Field Picture */
     }
 
-    intelFlushBatch(pI915XvMC, TRUE);
+    intelFlushBatch(TRUE);
     pI915XvMC->last_render = pI915XvMC->alloc.irq_emitted;
     privTarget->last_render = pI915XvMC->last_render;
 
diff --git a/src/xvmc/intel_xvmc.h b/src/xvmc/intel_xvmc.h
index 56e44e1..b5fadb1 100644
--- a/src/xvmc/intel_xvmc.h
+++ b/src/xvmc/intel_xvmc.h
@@ -54,6 +54,8 @@
 #include "xf86dri.h"
 #include "driDrawable.h"
 
+#include "intel_batchbuffer.h"
+
 #define DEBUG 0
 
 #define XVMC_ERR(s, arg...)					\
@@ -97,8 +99,15 @@ extern Status  _xvmc_create_subpicture(Display *dpy, XvMCContext *context,
 extern Status   _xvmc_destroy_subpicture(Display *dpy,
 					 XvMCSubpicture *subpicture);
 
+typedef struct _intel_xvmc_drm_map {
+    drm_handle_t handle;
+    unsigned long offset;
+    unsigned long size;
+    unsigned long bus_addr;
+    drmAddress map;
+} intel_xvmc_drm_map_t, *intel_xvmc_drm_map_ptr;
 
-struct _intel_xvmc_driver {
+typedef struct _intel_xvmc_driver {
     int type;			/* hw xvmc type - i830_hwmc.h */
     int screen;			/* current screen num*/
 
@@ -109,6 +118,24 @@ struct _intel_xvmc_driver {
     unsigned int sarea_size;
     drmAddress sarea_address;
 
+    struct {
+	unsigned int start_offset;
+	unsigned int size;
+	unsigned int space;
+	unsigned char *ptr;
+    } batch;
+
+    struct
+    {
+        void *ptr;
+        unsigned int size;
+        unsigned int offset;
+        unsigned int active_buf;
+        unsigned int irq_emitted;
+    } alloc;
+    intel_xvmc_drm_map_t batchbuffer;
+    unsigned int last_render;
+
     void *private;
 
     /* XXX: remove? */
@@ -148,7 +175,7 @@ struct _intel_xvmc_driver {
     Status (*get_surface_status)(Display *display, XvMCSurface *surface, int *stat);
 
     /* XXX more for vld */
-};
+} intel_xvmc_driver_t, *intel_xvmc_driver_ptr;
 
 extern struct _intel_xvmc_driver i915_xvmc_mc_driver;
 extern struct _intel_xvmc_driver *xvmc_driver;
commit 11c0e0dbef42f1ae77a77d534870d3e9821fb017
Merge: c838f72... 43fbc54...
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Tue Nov 13 22:44:06 2007 +0800

    Merge branch 'master' into xvmc

commit c838f7297f675ea9d82678ed37715955cb0a8a78
Merge: a9449ff... 6f53568...
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Fri Nov 9 19:37:07 2007 +0800

    Merge branch 'xvmc' of git+ssh://zhen@people.freedesktop.org/~zhen/xf86-video-intel into xvmc

commit a9449fff4be8e6b3cc82914376420e3a66b960f5
Merge: a470f6b... 177924e...
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Fri Nov 9 19:36:25 2007 +0800

    Merge branch 'master' into xvmc

commit a470f6b2ca291e305979dd9223885a50dc0b334b
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Fri Oct 26 22:40:47 2007 +0800

    try to move some fields to xvmc driver structure
    
    Still a lot of things to move include batch buffer, lock, context,
    surface resource handling, etc.

diff --git a/src/i830_hwmc.h b/src/i830_hwmc.h
index 70ec00d..97fe4fd 100644
--- a/src/i830_hwmc.h
+++ b/src/i830_hwmc.h
@@ -45,6 +45,7 @@
 /* common header for context private */
 struct _intel_xvmc_common {
     unsigned int type;
+    unsigned int sarea_size;
 };
 
 #ifdef _INTEL_XVMC_SERVER_
diff --git a/src/i915_hwmc.c b/src/i915_hwmc.c
index f65a0cf..6ab00e2 100644
--- a/src/i915_hwmc.c
+++ b/src/i915_hwmc.c
@@ -386,7 +386,6 @@ static Bool i915_allocate_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *c
         return FALSE;
     }
 
-    /* XXX xvmc ttm */
     if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC]Correction Data Buffer", 
                                    &(ctxpriv->mcCorrdata), 512 * 1024,
                                    ALIGN_BOTH_ENDS)) {
@@ -530,6 +529,7 @@ static int I915XvMCCreateContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext,
     }
 
     contextRec->comm.type = xvmc_driver->flag;
+    contextRec->comm.sarea_size = pDRIInfo->SAREASize;
     contextRec->ctxno = i;
     contextRec->sis.handle = ctxpriv->sis_handle;
     contextRec->sis.offset = ctxpriv->mcStaticIndirectState->offset;
@@ -557,9 +557,7 @@ static int I915XvMCCreateContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext,
     contextRec->batchbuffer.handle = ctxpriv->batchbuffer_handle;
     contextRec->batchbuffer.offset = ctxpriv->mcBatchBuffer->offset;
     contextRec->batchbuffer.size = ctxpriv->mcBatchBuffer->size;
-    contextRec->sarea_size = pDRIInfo->SAREASize;
     contextRec->sarea_priv_offset = sizeof(XF86DRISAREARec);
-    contextRec->screen = pScrn->pScreen->myNum;
     contextRec->depth = pScrn->bitsPerPixel;
     contextRec->deviceID = pI830DRI->deviceID;
 
diff --git a/src/i915_hwmc.h b/src/i915_hwmc.h
index cf74d33..d110661 100644
--- a/src/i915_hwmc.h
+++ b/src/i915_hwmc.h
@@ -66,9 +66,7 @@ typedef struct
     struct hwmc_buffer psc;
     struct hwmc_buffer corrdata;/* Correction Data Buffer */
     struct hwmc_buffer batchbuffer;
-    unsigned int sarea_size;
     unsigned int sarea_priv_offset;
-    unsigned int screen;
     unsigned int depth;
     int deviceID;
 } I915XvMCCreateContextRec;
diff --git a/src/xvmc/I915XvMC.c b/src/xvmc/I915XvMC.c
index a5e596a..687d54f 100644
--- a/src/xvmc/I915XvMC.c
+++ b/src/xvmc/I915XvMC.c
@@ -148,7 +148,7 @@ static __inline__ void renderError(void)
 
 static void I915XvMCContendedLock(i915XvMCContext *pI915XvMC, drmLockFlags flags)
 {
-    drmGetLock(pI915XvMC->fd, pI915XvMC->hHWContext, flags);
+    drmGetLock(xvmc_driver->fd, pI915XvMC->hHWContext, flags);
 }
 
 #define SET_BLOCKED_SIGSET(pI915XvMC)   do {    \
@@ -199,7 +199,7 @@ static void LOCK_HARDWARE(i915XvMCContext  *pI915XvMC)
 static void UNLOCK_HARDWARE(i915XvMCContext *pI915XvMC)
 {
     pI915XvMC->locked = 0;
-    DRM_UNLOCK(pI915XvMC->fd, pI915XvMC->driHwLock, 
+    DRM_UNLOCK(xvmc_driver->fd, pI915XvMC->driHwLock, 
                pI915XvMC->hHWContext);
     PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
 }
@@ -1205,49 +1205,49 @@ static void i915_mc_invalidate_subcontext_buffers(XvMCContext *context, unsigned
 
 static int i915_xvmc_map_buffers(i915XvMCContext *pI915XvMC)
 {
-    if (drmMap(pI915XvMC->fd,
+    if (drmMap(xvmc_driver->fd,
                pI915XvMC->sis.handle,
                pI915XvMC->sis.size,
                (drmAddress *)&pI915XvMC->sis.map) != 0) {
         return -1;
     }
 
-    if (drmMap(pI915XvMC->fd,
+    if (drmMap(xvmc_driver->fd,
                pI915XvMC->ssb.handle,
                pI915XvMC->ssb.size,
                (drmAddress *)&pI915XvMC->ssb.map) != 0) {
         return -1;
     }
 
-    if (drmMap(pI915XvMC->fd,
+    if (drmMap(xvmc_driver->fd,
                pI915XvMC->msb.handle,
                pI915XvMC->msb.size,
                (drmAddress *)&pI915XvMC->msb.map) != 0) {
         return -1;
     }
 
-    if (drmMap(pI915XvMC->fd,
+    if (drmMap(xvmc_driver->fd,
                pI915XvMC->psp.handle,
                pI915XvMC->psp.size,
                (drmAddress *)&pI915XvMC->psp.map) != 0) {
         return -1;
     }
 
-    if (drmMap(pI915XvMC->fd,
+    if (drmMap(xvmc_driver->fd,
                pI915XvMC->psc.handle,
                pI915XvMC->psc.size,
                (drmAddress *)&pI915XvMC->psc.map) != 0) {
         return -1;
     }
 
-    if (drmMap(pI915XvMC->fd,
+    if (drmMap(xvmc_driver->fd,
                pI915XvMC->corrdata.handle,
                pI915XvMC->corrdata.size,
                (drmAddress *)&pI915XvMC->corrdata.map) != 0) {
         return -1;
     }
     
-    if (drmMap(pI915XvMC->fd,
+    if (drmMap(xvmc_driver->fd,
                pI915XvMC->batchbuffer.handle,
                pI915XvMC->batchbuffer.size,
                (drmAddress *)&pI915XvMC->batchbuffer.map) != 0) {
@@ -1718,6 +1718,7 @@ static void i915_yuv2rgb_proc(XvMCSurface *surface)
 static void i915_release_resource(Display *display, XvMCContext *context)
 {
     i915XvMCContext *pI915XvMC;
+    int screen = DefaultScreen(display);
 
     if (!(pI915XvMC = context->privData))
         return;
@@ -1731,18 +1732,19 @@ static void i915_release_resource(Display *display, XvMCContext *context)
     pthread_mutex_destroy(&pI915XvMC->ctxmutex);
 
     XLockDisplay(display);
-    uniDRIDestroyContext(display, pI915XvMC->screen, pI915XvMC->id);
+    uniDRIDestroyContext(display, screen, pI915XvMC->id);
     XUnlockDisplay(display);
 
     intelDestroyBatchBuffer(pI915XvMC);
-    drmUnmap(pI915XvMC->sarea_address, pI915XvMC->sarea_size);
 
-    if (pI915XvMC->fd >= 0)
-        drmClose(pI915XvMC->fd);
-    pI915XvMC->fd = -1;
+    drmUnmap(xvmc_driver->sarea_address, xvmc_driver->sarea_size);
+
+    if (xvmc_driver->fd >= 0)
+        drmClose(xvmc_driver->fd);
+    xvmc_driver->fd = -1;
 
     XLockDisplay(display);
-    uniDRICloseConnection(display, pI915XvMC->screen);
+    uniDRICloseConnection(display, screen);
     _xvmc_destroy_context(display, context);
     XUnlockDisplay(display);
 
@@ -1768,9 +1770,8 @@ static Status i915_xvmc_mc_create_context(Display *display, XvMCContext *context
                (int)(sizeof(I915XvMCCreateContextRec) >> 2),priv_count);
         _xvmc_destroy_context(display, context);
         free(priv_data);
-        free(pI915XvMC);
         context->privData = NULL;
-        return BadAccess;
+        return BadValue;
     }
 
     context->privData = (void *)calloc(1, sizeof(i915XvMCContext));
@@ -1816,73 +1817,22 @@ static Status i915_xvmc_mc_create_context(Display *display, XvMCContext *context
     pI915XvMC->batchbuffer.handle = tmpComm->batchbuffer.handle;
     pI915XvMC->batchbuffer.offset = tmpComm->batchbuffer.offset;
     pI915XvMC->batchbuffer.size = tmpComm->batchbuffer.size;
-    pI915XvMC->sarea_size = tmpComm->sarea_size;
     pI915XvMC->sarea_priv_offset = tmpComm->sarea_priv_offset;
-    //XXX
-//    xvmc_driver->screen = 
-    pI915XvMC->screen = tmpComm->screen;
     pI915XvMC->depth = tmpComm->depth;
 
     /* Must free the private data we were passed from X */
     free(priv_data);
     priv_data = NULL;
 
-    /* XXX just keep current i915 setup code for now */
-
-    ret = uniDRIQueryDirectRenderingCapable(display, pI915XvMC->screen,
-                                            &isCapable);
-    if (!ret || !isCapable) {
-	XVMC_ERR("Direct Rendering is not available on this system!");
-        return BadAlloc;
-    }
-
-    if (!uniDRIOpenConnection(display, pI915XvMC->screen,
-                              &pI915XvMC->hsarea, &curBusID)) {
-        XVMC_ERR("Could not open DRI connection to X server!");
-        return BadAlloc;
-    }
-
-    strncpy(pI915XvMC->busIdString, curBusID, 20);
-    pI915XvMC->busIdString[20] = '\0';
-    free(curBusID);
-
-    /* Open DRI Device */
-    if((pI915XvMC->fd = drmOpen("i915", NULL)) < 0) {
-        XVMC_ERR("DRM Device could not be opened.");
-	//(xvmc_driver->fini)();
-	//xvmc_driver = NULL;
-        return BadAccess;
-    }
-
-    /* Get magic number */
-    drmGetMagic(pI915XvMC->fd, &magic);
-    // context->flags = (unsigned long)magic;
-
-    if (!uniDRIAuthConnection(display, pI915XvMC->screen, magic)) {
-	XVMC_ERR("[XvMC]: X server did not allow DRI. Check permissions.");
-	//(xvmc_driver->fini)();
-	//xvmc_driver = NULL;
-        return BadAlloc;
-    }
-
-    /*
-     * Map DRI Sarea. we always want it right?
-     */
-    if (drmMap(pI915XvMC->fd, pI915XvMC->hsarea,
-               pI915XvMC->sarea_size, &pI915XvMC->sarea_address) < 0) {
-        XVMC_ERR("Unable to map DRI SAREA.\n");
-	//(xvmc_driver->fini)();
-	//xvmc_driver = NULL;
-        return BadAlloc;
-    }
-    pSAREA = (drm_sarea_t *)pI915XvMC->sarea_address;
+    pSAREA = (drm_sarea_t *)xvmc_driver->sarea_address;
     pI915XvMC->driHwLock = (drmLock *)&pSAREA->lock;
-    pI915XvMC->sarea = SAREAPTR(pI915XvMC);
-    XLockDisplay(display);
-    ret = XMatchVisualInfo(display, pI915XvMC->screen,
+    pI915XvMC->sarea = (drmI830Sarea*)((char*)pSAREA + pI915XvMC->sarea_priv_offset);
+    /*
+     *  XXX we don't need to bother X for DRI context, as we're not DRI. */
+#if 0
+    ret = XMatchVisualInfo(display, xvmc_driver->screen,
                            (pI915XvMC->depth == 32) ? 24 : pI915XvMC->depth, TrueColor,
                            &pI915XvMC->visualInfo);
-    XUnlockDisplay(display);
 
     if (!ret) {
 	XVMC_ERR("Could not find a matching TrueColor visual.");
@@ -1901,12 +1851,12 @@ static Status i915_xvmc_mc_create_context(Display *display, XvMCContext *context
         drmUnmap(pI915XvMC->sarea_address, pI915XvMC->sarea_size);
         return BadAlloc;
     }
+#endif
 
     if (NULL == (pI915XvMC->drawHash = drmHashCreate())) {
 	XVMC_ERR("Could not allocate drawable hash table.");
         free(pI915XvMC);
         context->privData = NULL;
-        drmUnmap(pI915XvMC->sarea_address, pI915XvMC->sarea_size);
         return BadAlloc;
     }
 
@@ -1914,7 +1864,6 @@ static Status i915_xvmc_mc_create_context(Display *display, XvMCContext *context
         i915_xvmc_unmap_buffers(pI915XvMC);
         free(pI915XvMC);
         context->privData = NULL;
-        drmUnmap(pI915XvMC->sarea_address, pI915XvMC->sarea_size);
         return BadAlloc;
     }
 
@@ -1927,6 +1876,7 @@ static Status i915_xvmc_mc_create_context(Display *display, XvMCContext *context
     pI915XvMC->locked = 0;
     pI915XvMC->port = context->port;
     pthread_mutex_init(&pI915XvMC->ctxmutex, NULL);
+    /* XXX */
     intelInitBatchBuffer(pI915XvMC);
     pI915XvMC->ref = 1;
     return Success;
@@ -2024,7 +1974,7 @@ static Status i915_xvmc_mc_create_surface(Display *display, XvMCContext *context
     pI915Surface->srf.size = tmpComm->srf.size;
     free(priv_data);
 
-    if (drmMap(pI915XvMC->fd,
+    if (drmMap(xvmc_driver->fd,
                pI915Surface->srf.handle,
                pI915Surface->srf.size,
                (drmAddress *)&pI915Surface->srf.map) != 0) {
diff --git a/src/xvmc/I915XvMC.h b/src/xvmc/I915XvMC.h
index d122bcc..b1d3117 100644
--- a/src/xvmc/I915XvMC.h
+++ b/src/xvmc/I915XvMC.h
@@ -63,7 +63,6 @@ typedef struct _i915XvMCDrmMap {
 ***************************************************************************/
 typedef struct _i915XvMCContext {
     unsigned int ctxno;
-    int fd;   /* File descriptor for /dev/dri */
     unsigned int last_render;
     unsigned int last_flip;
     unsigned int dual_prime; /* Flag to identify when dual prime is in use. */
@@ -71,18 +70,13 @@ typedef struct _i915XvMCContext {
     unsigned int uvStride;
     unsigned short ref;
     pthread_mutex_t ctxmutex;
-    char busIdString[21]; /* PCI:0:1:0 or PCI:0:2:0 */
     int lock;   /* Lightweight lock to avoid locking twice */
     int locked;
     volatile drmI830Sarea *sarea;
     
     drmLock *driHwLock;
     drm_context_t hHWContext; /* drmcontext; */
-    drm_handle_t hsarea;                /* Handle to drm shared memory area */
-    drmAddress sarea_address;	        /* Virtual address of shared memory area */
-    unsigned int sarea_size;                /* Size of drm shared memory area */
     unsigned int sarea_priv_offset;	        /* Offset in sarea to private part */
-    unsigned int screen;
     unsigned int depth;
     XvPortID port;		       /* Xv Port ID when displaying */
     int haveXv;                        /* Have I initialized the Xv
@@ -108,13 +102,13 @@ typedef struct _i915XvMCContext {
     sigset_t sa_mask;
 
     struct {
-        unsigned int start_offset;
-        unsigned int size;
-        unsigned int space;
-        unsigned char *ptr;
+	unsigned int start_offset;
+	unsigned int size;
+	unsigned int space;
+	unsigned char *ptr;
     } batch;
 
-    struct 
+    struct
     {
         void *ptr;
         unsigned int size;
diff --git a/src/xvmc/intel_batchbuffer.c b/src/xvmc/intel_batchbuffer.c
index ecd57b5..8b6ff11 100644
--- a/src/xvmc/intel_batchbuffer.c
+++ b/src/xvmc/intel_batchbuffer.c
@@ -54,7 +54,7 @@ int intelEmitIrqLocked(i915XvMCContext *pI915XvMC)
    int ret, seq;
 
    ie.irq_seq = &seq;
-   ret = drmCommandWriteRead(pI915XvMC->fd, DRM_I830_IRQ_EMIT,
+   ret = drmCommandWriteRead(xvmc_driver->fd, DRM_I830_IRQ_EMIT,
                              &ie, sizeof(ie));
 
    if ( ret ) {
@@ -73,7 +73,7 @@ void intelWaitIrq(i915XvMCContext *pI915XvMC, int seq)
    iw.irq_seq = seq;
 
    do {
-      ret = drmCommandWrite(pI915XvMC->fd, DRM_I830_IRQ_WAIT, &iw, sizeof(iw) );
+      ret = drmCommandWrite(xvmc_driver->fd, DRM_I830_IRQ_WAIT, &iw, sizeof(iw) );
    } while (ret == -EAGAIN || ret == -EINTR);
 
    if (ret) {
@@ -206,7 +206,7 @@ void intelFlushBatchLocked(i915XvMCContext *pI915XvMC,
       assert(batch.start + batch.used <= pI915XvMC->alloc.offset + pI915XvMC->alloc.size);
 
       if (pI915XvMC->alloc.offset) {
-          if (drmCommandWrite(pI915XvMC->fd, DRM_I830_BATCHBUFFER, &batch, sizeof(batch))) {
+          if (drmCommandWrite(xvmc_driver->fd, DRM_I830_BATCHBUFFER, &batch, sizeof(batch))) {
               fprintf(stderr, "DRM_I830_BATCHBUFFER: %d\n",  -errno);
               exit(1);
           }
@@ -219,7 +219,7 @@ void intelFlushBatchLocked(i915XvMCContext *pI915XvMC,
          cmd.num_cliprects = batch.num_cliprects;
          cmd.cliprects = batch.cliprects;
 
-         if (drmCommandWrite(pI915XvMC->fd, DRM_I830_CMDBUFFER, 
+         if (drmCommandWrite(xvmc_driver->fd, DRM_I830_CMDBUFFER, 
                              &cmd, sizeof(cmd))) {
             fprintf(stderr, "DRM_I915_CMDBUFFER: %d\n",  -errno);
             exit(1);
@@ -247,7 +247,7 @@ void intelCmdIoctl(i915XvMCContext *pI915XvMC, char *buf, unsigned used)
    cmd.DR1 = 0;
    cmd.DR4 = 0;
 
-   if (drmCommandWrite(pI915XvMC->fd, DRM_I830_CMDBUFFER, 
+   if (drmCommandWrite(xvmc_driver->fd, DRM_I830_CMDBUFFER, 
                        &cmd, sizeof(cmd))) {
       fprintf(stderr, "DRM_I830_CMDBUFFER: %d\n",  -errno);
       exit(1);
diff --git a/src/xvmc/intel_xvmc.c b/src/xvmc/intel_xvmc.c
index 9962d8a..804ce49 100644
--- a/src/xvmc/intel_xvmc.c
+++ b/src/xvmc/intel_xvmc.c
@@ -26,26 +26,26 @@
  */
 #include "intel_xvmc.h"
 
-static struct _intel_xvmc_driver* xvmc_driver = NULL;
+struct _intel_xvmc_driver *xvmc_driver = NULL;
 static int error_base;
 static int event_base;
 
-/***************************************************************************
-// Function: XvMCCreateContext
-// Description: Create a XvMC context for the given surface parameters.
-// Arguments:
-//   display - Connection to the X server.
-//   port - XvPortID to use as avertised by the X connection.
-//   surface_type_id - Unique identifier for the Surface type.
-//   width - Width of the surfaces.
-//   height - Height of the surfaces.
-//   flags - one or more of the following
-//      XVMC_DIRECT - A direct rendered context is requested.
-//
-// Notes: surface_type_id and width/height parameters must match those
-//        returned by XvMCListSurfaceTypes.
-// Returns: Status
-***************************************************************************/
+/*
+* Function: XvMCCreateContext
+* Description: Create a XvMC context for the given surface parameters.
+* Arguments:
+*   display - Connection to the X server.
+*   port - XvPortID to use as avertised by the X connection.
+*   surface_type_id - Unique identifier for the Surface type.
+*   width - Width of the surfaces.
+*   height - Height of the surfaces.
+*   flags - one or more of the following
+*      XVMC_DIRECT - A direct rendered context is requested.
+
+* Notes: surface_type_id and width/height parameters must match those
+*        returned by XvMCListSurfaceTypes.
+* Returns: Status
+*/
 Status XvMCCreateContext(Display *display, XvPortID port,
                          int surface_type_id, int width, int height,
                          int flags, XvMCContext *context)
@@ -55,17 +55,17 @@ Status XvMCCreateContext(Display *display, XvPortID port,
     char *curBusID;
     CARD32 *priv_data = NULL;
     struct _intel_xvmc_common *comm;
-    uint magic;
+    drm_magic_t magic;
     int major, minor;
     int priv_count;
     int isCapable;
+    int screen = DefaultScreen(display);
 
     /* Verify Obvious things first */
     if (!display || !context)
         return BadValue;
 
     if (!(flags & XVMC_DIRECT)) {
-        /* Indirect */
         XVMC_ERR("Indirect Rendering not supported! Using Direct.");
         return BadValue;
     }
@@ -91,7 +91,7 @@ Status XvMCCreateContext(Display *display, XvPortID port,
 
     if (!XvMCQueryExtension(display, &event_base, &error_base)) {
         XVMC_ERR("XvMCExtension is not available!");
-        return BadAccess;
+        return BadValue;
     }
     ret = XvMCQueryVersion(display, &major, &minor);
     if (ret) {
@@ -136,32 +136,25 @@ Status XvMCCreateContext(Display *display, XvPortID port,
 	return BadValue;
     }
 
-    if (xvmc_driver == NULL) {
+    if (xvmc_driver == NULL || xvmc_driver->type != comm->type) {
 	XVMC_ERR("fail to load xvmc driver for type %d\n", comm->type);
 	return BadValue;
     }
+    xvmc_driver->sarea_size = comm->sarea_size;
 
-    /* driver hook should free priv_data after return if success.
-     * and set xvmc_driver->screen num */
-    ret = (xvmc_driver->create_context)(display, context, priv_count, priv_data);
-    if (ret) {
-	XVMC_ERR("driver create context failed\n");
-	free(priv_data);
-	return ret;
-    }
-
-#if 0
-    ret = uniDRIQueryDirectRenderingCapable(display, xvmc_driver->screen,
+    ret = uniDRIQueryDirectRenderingCapable(display, screen,
                                             &isCapable);
     if (!ret || !isCapable) {
 	XVMC_ERR("Direct Rendering is not available on this system!");
-        return BadAlloc;
+	free(priv_data);
+        return BadValue;
     }
 
-    if (!uniDRIOpenConnection(display, xvmc_driver->screen,
+    if (!uniDRIOpenConnection(display, screen,
                               &xvmc_driver->hsarea, &curBusID)) {
         XVMC_ERR("Could not open DRI connection to X server!");
-        return BadAlloc;
+	free(priv_data);
+        return BadValue;
     }
 
     strncpy(xvmc_driver->busID, curBusID, 20);
@@ -171,19 +164,21 @@ Status XvMCCreateContext(Display *display, XvPortID port,
     /* Open DRI Device */
     if((xvmc_driver->fd = drmOpen("i915", NULL)) < 0) {
         XVMC_ERR("DRM Device could not be opened.");
-	(xvmc_driver->fini)();
+	//(xvmc_driver->fini)();
 	xvmc_driver = NULL;
-        return BadAccess;
+	free(priv_data);
+        return BadValue;
     }
 
     /* Get magic number */
     drmGetMagic(xvmc_driver->fd, &magic);
     // context->flags = (unsigned long)magic;
 
-    if (!uniDRIAuthConnection(display, xvmc_driver->screen, magic)) {
+    if (!uniDRIAuthConnection(display, screen, magic)) {
 	XVMC_ERR("[XvMC]: X server did not allow DRI. Check permissions.");
-	(xvmc_driver->fini)();
+	//(xvmc_driver->fini)();
 	xvmc_driver = NULL;
+	free(priv_data);
         return BadAlloc;
     }
 
@@ -193,66 +188,24 @@ Status XvMCCreateContext(Display *display, XvPortID port,
     if (drmMap(xvmc_driver->fd, xvmc_driver->hsarea,
                xvmc_driver->sarea_size, &xvmc_driver->sarea_address) < 0) {
         XVMC_ERR("Unable to map DRI SAREA.\n");
-	(xvmc_driver->fini)();
+	//(xvmc_driver->fini)();
 	xvmc_driver = NULL;
+	free(priv_data);
         return BadAlloc;
     }
 
-    pSAREA = (drm_sarea_t *)xvmc_driver->sarea_address;
-    pI915XvMC->driHwLock = (drmLock *)&pSAREA->lock;
-    pI915XvMC->sarea = SAREAPTR(pI915XvMC);
-    XLockDisplay(display);
-    ret = XMatchVisualInfo(display, pI915XvMC->screen,
-                           (pI915XvMC->depth == 32) ? 24 : pI915XvMC->depth, TrueColor,
-                           &pI915XvMC->visualInfo);
-    XUnlockDisplay(display);
-
-    if (!ret) {
-	XVMC_ERR("Could not find a matching TrueColor visual.");
-        free(pI915XvMC);
-        context->privData = NULL;
-        drmUnmap(pI915XvMC->sarea_address, pI915XvMC->sarea_size);
-        return BadAlloc;
-    }
-
-    if (!uniDRICreateContext(display, pI915XvMC->screen,
-                             pI915XvMC->visualInfo.visual, &pI915XvMC->id,
-                             &pI915XvMC->hHWContext)) {
-        XVMC_ERR("Could not create DRI context.");
-        free(pI915XvMC);
-        context->privData = NULL;
-        drmUnmap(pI915XvMC->sarea_address, pI915XvMC->sarea_size);
-        return BadAlloc;
-    }
-
-    if (NULL == (pI915XvMC->drawHash = drmHashCreate())) {
-	XVMC_ERR("Could not allocate drawable hash table.");
-        free(pI915XvMC);
-        context->privData = NULL;
-        drmUnmap(pI915XvMC->sarea_address, pI915XvMC->sarea_size);
-        return BadAlloc;
-    }
-
-    if (i915_xvmc_map_buffers(pI915XvMC)) {
-        i915_xvmc_unmap_buffers(pI915XvMC);
-        free(pI915XvMC);
-        context->privData = NULL;
-        drmUnmap(pI915XvMC->sarea_address, pI915XvMC->sarea_size);
-        return BadAlloc;
+    /* call driver hook.
+     * driver hook should free priv_data after return if success.*/
+    ret = (xvmc_driver->create_context)(display, context, priv_count, priv_data);
+    if (ret) {
+	XVMC_ERR("driver create context failed\n");
+	free(priv_data);
+	drmUnmap(xvmc_driver->sarea_address, xvmc_driver->sarea_size);
+	return ret;
     }
 
-    /* Initialize private context values */
-    pI915XvMC->yStride = STRIDE(width);
-    pI915XvMC->uvStride = STRIDE(width >> 1);
-    pI915XvMC->haveXv = 0;
-    pI915XvMC->dual_prime = 0;
-    pI915XvMC->last_flip = 0;
-    pI915XvMC->locked = 0;
-    pI915XvMC->port = context->port;
-    pthread_mutex_init(&pI915XvMC->ctxmutex, NULL);
-    intelInitBatchBuffer(pI915XvMC);
-    pI915XvMC->ref = 1;
-#endif
+    /* FIXME batch buffer */
+    //intelInitBatchBuffer(xvmc_driver);
 
     return Success;
 }
diff --git a/src/xvmc/intel_xvmc.h b/src/xvmc/intel_xvmc.h
index bc37500..56e44e1 100644
--- a/src/xvmc/intel_xvmc.h
+++ b/src/xvmc/intel_xvmc.h
@@ -101,14 +101,16 @@ extern Status   _xvmc_destroy_subpicture(Display *dpy,
 struct _intel_xvmc_driver {
     int type;			/* hw xvmc type - i830_hwmc.h */
     int screen;			/* current screen num*/
-#if 0
+
+    int fd;			/* drm file handler */
     drm_handle_t hsarea;	/* DRI open connect */
+    char busID[32];
+
     unsigned int sarea_size;
     drmAddress sarea_address;
-#endif
-    char busID[32];
-    int fd;			/* drm file handler */
+
     void *private;
+
     /* XXX: remove? */
     int (*init)(void);
     void (*fini)(void);
@@ -149,5 +151,6 @@ struct _intel_xvmc_driver {
 };
 
 extern struct _intel_xvmc_driver i915_xvmc_mc_driver;
+extern struct _intel_xvmc_driver *xvmc_driver;
 
 #endif
commit 6f53568cd2aeeec6bd8c1f1d9f9c5ecadc5c62f9
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Fri Oct 26 14:58:43 2007 +0800

    Fix DRI context creation for XvMC

diff --git a/src/xvmc/I915XvMC.c b/src/xvmc/I915XvMC.c
index 687d54f..aab186d 100644
--- a/src/xvmc/I915XvMC.c
+++ b/src/xvmc/I915XvMC.c
@@ -1763,6 +1763,7 @@ static Status i915_xvmc_mc_create_context(Display *display, XvMCContext *context
     uint magic;
     int major, minor;
     int isCapable;
+    int screen = DefaultScreen(display);
 
     if (priv_count != (sizeof(I915XvMCCreateContextRec) >> 2)) {
         XVMC_ERR("_xvmc_create_context() returned incorrect data size!");
@@ -1827,10 +1828,7 @@ static Status i915_xvmc_mc_create_context(Display *display, XvMCContext *context
     pSAREA = (drm_sarea_t *)xvmc_driver->sarea_address;
     pI915XvMC->driHwLock = (drmLock *)&pSAREA->lock;
     pI915XvMC->sarea = (drmI830Sarea*)((char*)pSAREA + pI915XvMC->sarea_priv_offset);
-    /*
-     *  XXX we don't need to bother X for DRI context, as we're not DRI. */
-#if 0
-    ret = XMatchVisualInfo(display, xvmc_driver->screen,
+    ret = XMatchVisualInfo(display, screen,
                            (pI915XvMC->depth == 32) ? 24 : pI915XvMC->depth, TrueColor,
                            &pI915XvMC->visualInfo);
 
@@ -1838,20 +1836,19 @@ static Status i915_xvmc_mc_create_context(Display *display, XvMCContext *context
 	XVMC_ERR("Could not find a matching TrueColor visual.");
         free(pI915XvMC);
         context->privData = NULL;
-        drmUnmap(pI915XvMC->sarea_address, pI915XvMC->sarea_size);
+        drmUnmap(xvmc_driver->sarea_address, xvmc_driver->sarea_size);
         return BadAlloc;
     }
 
-    if (!uniDRICreateContext(display, pI915XvMC->screen,
+    if (!uniDRICreateContext(display, screen,
                              pI915XvMC->visualInfo.visual, &pI915XvMC->id,
                              &pI915XvMC->hHWContext)) {
         XVMC_ERR("Could not create DRI context.");
         free(pI915XvMC);
         context->privData = NULL;
-        drmUnmap(pI915XvMC->sarea_address, pI915XvMC->sarea_size);
+        drmUnmap(xvmc_driver->sarea_address, xvmc_driver->sarea_size);
         return BadAlloc;
     }
-#endif
 
     if (NULL == (pI915XvMC->drawHash = drmHashCreate())) {
 	XVMC_ERR("Could not allocate drawable hash table.");
commit ce9802edd25255f6c9c11e512b2ef905384b914d
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Wed Oct 24 00:31:53 2007 +0800

    fix xvmc return values
    
    Use values defined by xvmc lib spec

diff --git a/src/xvmc/I915XvMC.c b/src/xvmc/I915XvMC.c
index 2c3dec6..a5e596a 100644
--- a/src/xvmc/I915XvMC.c
+++ b/src/xvmc/I915XvMC.c
@@ -65,11 +65,11 @@ static char I915KernelDriverName[] = "i915";
 static int error_base;
 static int event_base;
 
-static int i915_xvmc_mc_create_context(Display* display, XvMCContext *context, int priv_count, CARD32* priv_data);
-static int i915_xvmc_mc_destroy_context(Display* display, XvMCContext *context);
-static int i915_xvmc_mc_create_surface(Display* display, XvMCContext *context, XvMCSurface *surface);
-static int i915_xvmc_mc_destroy_surface(Display* display, XvMCSurface *surface);
-static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context,
+static Status i915_xvmc_mc_create_context(Display* display, XvMCContext *context, int priv_count, CARD32* priv_data);
+static Status i915_xvmc_mc_destroy_context(Display* display, XvMCContext *context);
+static Status i915_xvmc_mc_create_surface(Display* display, XvMCContext *context, XvMCSurface *surface);
+static Status i915_xvmc_mc_destroy_surface(Display* display, XvMCSurface *surface);
+static Status i915_xvmc_mc_render_surface(Display *display, XvMCContext *context,
                          unsigned int picture_structure,
                          XvMCSurface *target_surface,
                          XvMCSurface *past_surface,
@@ -79,13 +79,13 @@ static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context,
                          unsigned int first_macroblock,
                          XvMCMacroBlockArray *macroblock_array,
                          XvMCBlockArray *blocks);
-static int i915_xvmc_mc_put_surface(Display *display,XvMCSurface *surface,
+static Status i915_xvmc_mc_put_surface(Display *display,XvMCSurface *surface,
                       Drawable draw, short srcx, short srcy,
                       unsigned short srcw, unsigned short srch,
                       short destx, short desty,
                       unsigned short destw, unsigned short desth,
                       int flags);
-static int i915_xvmc_mc_get_surface_status(Display *display, XvMCSurface *surface, int *stat);
+static Status i915_xvmc_mc_get_surface_status(Display *display, XvMCSurface *surface, int *stat);
 //XXX
 static int i915_xvmc_mc_init()
 {return 0;}
@@ -1750,7 +1750,7 @@ static void i915_release_resource(Display *display, XvMCContext *context)
     context->privData = NULL;
 }
 
-static int i915_xvmc_mc_create_context(Display *display, XvMCContext *context,
+static Status i915_xvmc_mc_create_context(Display *display, XvMCContext *context,
 	int priv_count, CARD32 *priv_data)
 {
     i915XvMCContext *pI915XvMC = NULL;
@@ -1929,7 +1929,7 @@ static int i915_xvmc_mc_create_context(Display *display, XvMCContext *context,
     pthread_mutex_init(&pI915XvMC->ctxmutex, NULL);
     intelInitBatchBuffer(pI915XvMC);
     pI915XvMC->ref = 1;
-    return 0;
+    return Success;
 }
 
 /***************************************************************************
@@ -1947,7 +1947,7 @@ static int i915_xvmc_mc_destroy_context(Display *display, XvMCContext *context)
     i915XvMCContext *pI915XvMC;
 
     if (!(pI915XvMC = context->privData))
-        return (error_base + XvMCBadContext);
+        return XvMCBadContext;
 
     /* Pass Control to the X server to destroy the drm_context_t */
     i915_release_resource(display,context);
@@ -1957,7 +1957,7 @@ static int i915_xvmc_mc_destroy_context(Display *display, XvMCContext *context)
 /***************************************************************************
 // Function: XvMCCreateSurface
 ***************************************************************************/
-static int i915_xvmc_mc_create_surface(Display *display, XvMCContext *context, XvMCSurface *surface) 
+static Status i915_xvmc_mc_create_surface(Display *display, XvMCContext *context, XvMCSurface *surface) 
 {
     Status ret;
     i915XvMCContext *pI915XvMC;
diff --git a/src/xvmc/intel_xvmc.c b/src/xvmc/intel_xvmc.c
index 30df1ef..9962d8a 100644
--- a/src/xvmc/intel_xvmc.c
+++ b/src/xvmc/intel_xvmc.c
@@ -67,7 +67,7 @@ Status XvMCCreateContext(Display *display, XvPortID port,
     if (!(flags & XVMC_DIRECT)) {
         /* Indirect */
         XVMC_ERR("Indirect Rendering not supported! Using Direct.");
-        return BadAccess;
+        return BadValue;
     }
 
     /* Limit use to root for now */
@@ -96,7 +96,7 @@ Status XvMCCreateContext(Display *display, XvPortID port,
     ret = XvMCQueryVersion(display, &major, &minor);
     if (ret) {
         XVMC_ERR("XvMCQueryVersion Failed, unable to determine protocol version.");
-	return BadAccess;
+	return ret;
     }
 
     /* XXX: major and minor could be checked in future for XvMC
@@ -127,18 +127,18 @@ Status XvMCCreateContext(Display *display, XvPortID port,
 		XVMC_ERR("unimplemented xvmc type %d", comm->type);
 		free(priv_data);
 		priv_data = NULL;
-		return BadAccess;
+		return BadValue;
 	}
     } else {
 	XVMC_ERR("wrong hw xvmc type returned\n");
 	free(priv_data);
 	priv_data = NULL;
-	return BadAccess;
+	return BadValue;
     }
 
     if (xvmc_driver == NULL) {
 	XVMC_ERR("fail to load xvmc driver for type %d\n", comm->type);
-	return BadAccess;
+	return BadValue;
     }
 
     /* driver hook should free priv_data after return if success.
@@ -147,7 +147,7 @@ Status XvMCCreateContext(Display *display, XvPortID port,
     if (ret) {
 	XVMC_ERR("driver create context failed\n");
 	free(priv_data);
-	return BadAccess;
+	return ret;
     }
 
 #if 0
@@ -269,14 +269,15 @@ Status XvMCCreateContext(Display *display, XvPortID port,
 ***************************************************************************/
 Status XvMCDestroyContext(Display *display, XvMCContext *context)
 {
-    int ret = -1;
+    Status ret;
+
     if (!display || !context)
-        return BadValue;
+        return XvMCBadContext;
 
     ret = (xvmc_driver->destroy_context)(display, context);
     if (ret) {
 	XVMC_ERR("destroy context fail\n");
-	return BadAccess;
+	return ret;
     }
 
     /* Pass Control to the X server to destroy the drm_context_t */
@@ -290,20 +291,23 @@ Status XvMCDestroyContext(Display *display, XvMCContext *context)
 ***************************************************************************/
 Status XvMCCreateSurface(Display *display, XvMCContext *context, XvMCSurface *surface) 
 {
-    int ret;
+    Status ret;
 //    i915XvMCContext *pI915XvMC;
 //    i915XvMCSurface *pI915Surface;
 //    I915XvMCCreateSurfaceRec *tmpComm = NULL;
 //    int priv_count;
 //    uint *priv_data;
 
-    if (!display || !context || !surface)
-        return BadValue;
+    if (!display || !context)
+        return XvMCBadContext;
+
+    if (!surface)
+	return XvMCBadSurface;
 
     ret = (xvmc_driver->create_surface)(display, context, surface);
     if (ret) {
 	XVMC_ERR("create surface failed\n");
-	return BadAccess;
+	return ret;
     }
 
 #if 0
@@ -390,7 +394,7 @@ Status XvMCDestroySurface(Display *display, XvMCSurface *surface)
 //    i915XvMCContext *pI915XvMC;
 
     if (!display || !surface)
-        return BadValue;
+        return XvMCBadSurface;
 
     (xvmc_driver->destroy_surface)(display, surface);
 
@@ -518,12 +522,14 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context,
                          XvMCMacroBlockArray *macroblock_array,
                          XvMCBlockArray *blocks)
 {
-    int ret;
+    Status ret;
 
-    if (!display || !context || !target_surface) {
+    if (!display || !context) {
         XVMC_ERR("Invalid Display, Context or Target!");
-        return BadValue;
+        return XvMCBadContext;
     }
+    if (!target_surface)
+	return XvMCBadSurface;
 
     ret = (xvmc_driver->render_surface)(display, context, picture_structure,
 	    target_surface, past_surface, future_surface, flags,
@@ -532,7 +538,7 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context,
 
     if (ret) {
 	XVMC_ERR("render surface fail\n");
-	return BadAccess;
+	return ret;
     }
 #if 0
     int i;
@@ -764,16 +770,16 @@ Status XvMCPutSurface(Display *display,XvMCSurface *surface,
                       unsigned short destw, unsigned short desth,
                       int flags)
 {
-    int ret = -1;
+    Status ret;
 
     if (!display || !surface)
-        return BadValue;
+        return XvMCBadSurface;
 
     ret = (xvmc_driver->put_surface)(display, surface, draw, srcx, srcy,
 	    srcw, srch, destx, desty, destw, desth, flags);
     if (ret) {
 	XVMC_ERR("put surface fail\n");
-	return BadAccess;
+	return ret;
     }
 
 #if 0
@@ -853,6 +859,9 @@ Status XvMCSyncSurface(Display *display, XvMCSurface *surface)
     Status ret;
     int stat = 0;
 
+    if (!display || !surface)
+	return XvMCBadSurface;
+
     do {
         ret = XvMCGetSurfaceStatus(display, surface, &stat);
     } while (!ret && (stat & XVMC_RENDERING));
@@ -872,6 +881,8 @@ Status XvMCSyncSurface(Display *display, XvMCSurface *surface)
 ***************************************************************************/
 Status XvMCFlushSurface(Display * display, XvMCSurface *surface) 
 {
+    if (!display || !surface)
+	return XvMCBadSurface;
     return Success;
 }
 
@@ -889,15 +900,15 @@ Status XvMCFlushSurface(Display * display, XvMCSurface *surface)
 ***************************************************************************/
 Status XvMCGetSurfaceStatus(Display *display, XvMCSurface *surface, int *stat) 
 {
-    int ret = -1;
+    Status ret;
 
     if (!display || !surface || !stat)
-        return BadValue;
+        return XvMCBadSurface;
 
     ret = (xvmc_driver->get_surface_status)(display, surface, stat);
     if (ret) {
 	XVMC_ERR("get surface status fail\n");
-	return BadAccess;
+	return ret;
     }
 
 #if 0
@@ -972,10 +983,11 @@ Status XvMCHideSurface(Display *display, XvMCSurface *surface)
 {
 //    i915XvMCSurface *pI915Surface;
 //    i915XvMCContext *pI915XvMC;
-    int stat = 0, ret;
+    int stat = 0;
+    Status ret;
 
     if (!display || !surface)
-        return BadValue;
+        return XvMCBadSurface;
 
 #if 0
     if (!(pI915Surface = surface->privData))
diff --git a/src/xvmc/intel_xvmc.h b/src/xvmc/intel_xvmc.h
index fd1326e..bc37500 100644
--- a/src/xvmc/intel_xvmc.h
+++ b/src/xvmc/intel_xvmc.h
@@ -114,17 +114,17 @@ struct _intel_xvmc_driver {
     void (*fini)(void);
 
     /* driver specific xvmc callbacks */
-    int (*create_context)(Display* display, XvMCContext *context,
+    Status (*create_context)(Display* display, XvMCContext *context,
 	    int priv_count, CARD32 *priv_data);
 
-    int (*destroy_context)(Display* display, XvMCContext *context);
+    Status (*destroy_context)(Display* display, XvMCContext *context);
 
-    int (*create_surface)(Display* display, XvMCContext *context,
+    Status (*create_surface)(Display* display, XvMCContext *context,
 	    XvMCSurface *surface);
 
-    int (*destroy_surface)(Display* display, XvMCSurface *surface);
+    Status (*destroy_surface)(Display* display, XvMCSurface *surface);
 
-    int (*render_surface)(Display *display, XvMCContext *context,
+    Status (*render_surface)(Display *display, XvMCContext *context,
 	    unsigned int picture_structure,
 	    XvMCSurface *target_surface,
 	    XvMCSurface *past_surface,
@@ -136,14 +136,14 @@ struct _intel_xvmc_driver {
 	    XvMCBlockArray *blocks);
 
     /* XXX this should be same for all drivers */
-    int (*put_surface)(Display *display, XvMCSurface *surface,
+    Status (*put_surface)(Display *display, XvMCSurface *surface,
 	    Drawable draw, short srcx, short srcy,
 	    unsigned short srcw, unsigned short srch,
 	    short destx, short desty,
 	    unsigned short destw, unsigned short desth,
 	    int flags);
 
-    int (*get_surface_status)(Display *display, XvMCSurface *surface, int *stat);
+    Status (*get_surface_status)(Display *display, XvMCSurface *surface, int *stat);
 
     /* XXX more for vld */
 };
commit 9c84543eb0fde4643eb7529eb6b08eacf57c12d0
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Tue Oct 23 22:16:55 2007 +0800

    add missing license header for new files

diff --git a/src/xvmc/intel_xvmc.c b/src/xvmc/intel_xvmc.c
index 8c770ce..30df1ef 100644
--- a/src/xvmc/intel_xvmc.c
+++ b/src/xvmc/intel_xvmc.c
@@ -1,19 +1,30 @@
-
-/* public interface file */
-
-#include <X11/X.h>
-#include <X11/Xlibint.h>
-#include <fourcc.h>
-#include <X11/extensions/Xv.h>
-#include <X11/extensions/Xvlib.h>
-#include <X11/extensions/XvMC.h>
-#include <X11/extensions/XvMClib.h>
-#include <xf86drm.h>
-#include <drm_sarea.h>
-
+/*
+ * Copyright © 2007 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *    Zhenyu Wang <zhenyu.z.wang at intel.com>
+ *
+ */
 #include "intel_xvmc.h"
-#include "xf86dri.h"
-#include "driDrawable.h"
 
 static struct _intel_xvmc_driver* xvmc_driver = NULL;
 static int error_base;
diff --git a/src/xvmc/intel_xvmc.h b/src/xvmc/intel_xvmc.h
index 1d6ff71..fd1326e 100644
--- a/src/xvmc/intel_xvmc.h
+++ b/src/xvmc/intel_xvmc.h
@@ -1,4 +1,29 @@
-
+/*
+ * Copyright © 2007 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *    Zhenyu Wang <zhenyu.z.wang at intel.com>
+ *
+ */
 #ifndef INTEL_XVMC_H
 #define INTEL_XVMC_H
 
@@ -16,6 +41,7 @@
 #include <xf86drm.h>
 #include "i830_common.h"
 #include "i830_hwmc.h"
+#include <X11/X.h>
 #include <X11/Xlibint.h>
 #include <X11/Xutil.h>
 #include <fourcc.h>
@@ -83,13 +109,21 @@ struct _intel_xvmc_driver {
     char busID[32];
     int fd;			/* drm file handler */
     void *private;
-    /* XXX: api hooks */
-    int (*init)(/*XXX*/);
-    void (*fini)(/*XXX*/);
-    int (*create_context)(Display* display, XvMCContext *context, int priv_count, CARD32 *priv_data);
+    /* XXX: remove? */
+    int (*init)(void);
+    void (*fini)(void);
+
+    /* driver specific xvmc callbacks */
+    int (*create_context)(Display* display, XvMCContext *context,
+	    int priv_count, CARD32 *priv_data);
+
     int (*destroy_context)(Display* display, XvMCContext *context);
-    int (*create_surface)(Display* display, XvMCContext *context, XvMCSurface *surface);
+
+    int (*create_surface)(Display* display, XvMCContext *context,
+	    XvMCSurface *surface);
+
     int (*destroy_surface)(Display* display, XvMCSurface *surface);
+
     int (*render_surface)(Display *display, XvMCContext *context,
 	    unsigned int picture_structure,
 	    XvMCSurface *target_surface,
@@ -100,13 +134,18 @@ struct _intel_xvmc_driver {
 	    unsigned int first_macroblock,
 	    XvMCMacroBlockArray *macroblock_array,
 	    XvMCBlockArray *blocks);
-    int (*put_surface)(Display *display,XvMCSurface *surface,
+
+    /* XXX this should be same for all drivers */
+    int (*put_surface)(Display *display, XvMCSurface *surface,
 	    Drawable draw, short srcx, short srcy,
 	    unsigned short srcw, unsigned short srch,
 	    short destx, short desty,
 	    unsigned short destw, unsigned short desth,
 	    int flags);
+
     int (*get_surface_status)(Display *display, XvMCSurface *surface, int *stat);
+
+    /* XXX more for vld */
 };
 
 extern struct _intel_xvmc_driver i915_xvmc_mc_driver;
commit 90e4eafdf59edd966ed626107c3909b24737da8d
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Mon Oct 22 17:09:15 2007 +0800

    revert xvmc memory allocation hacks

diff --git a/src/i915_hwmc.c b/src/i915_hwmc.c
index e2c9130..f65a0cf 100644
--- a/src/i915_hwmc.c
+++ b/src/i915_hwmc.c
@@ -350,8 +350,7 @@ static void i915_unmap_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *ctxp
 static Bool i915_allocate_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *ctxpriv)
 {
     I830Ptr pI830 = I830PTR(pScrn);
-    /* FIXME xvmc ttm */
-    int flags = ALIGN_BOTH_ENDS | NEED_LIFETIME_FIXED;
+    int flags = ALIGN_BOTH_ENDS;
 
     if (IS_I915G(pI830) || IS_I915GM(pI830) ||
 	    IS_I945G(pI830) || IS_I945GM(pI830))
@@ -390,13 +389,13 @@ static Bool i915_allocate_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *c
     /* XXX xvmc ttm */
     if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC]Correction Data Buffer", 
                                    &(ctxpriv->mcCorrdata), 512 * 1024,
-                                   ALIGN_BOTH_ENDS | NEED_LIFETIME_FIXED)) {
+                                   ALIGN_BOTH_ENDS)) {
         return FALSE;
     }
 
     if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC]batch buffer",
                                    &(ctxpriv->mcBatchBuffer), 8 * 1024,
-                                   ALIGN_BOTH_ENDS | NEED_LIFETIME_FIXED)) {
+                                   ALIGN_BOTH_ENDS)) {
         return FALSE;
     }
 
@@ -630,7 +629,7 @@ static int I915XvMCCreateSurface(ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf,
     /* FIXME xvmc ttm */
     if (!i830_allocate_xvmc_buffer(pScrn, "XvMC surface", 
                                    &(sfpriv->surface), bufsize,
-                                   ALIGN_BOTH_ENDS | NEED_LIFETIME_FIXED)) {
+                                   ALIGN_BOTH_ENDS)) {
         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
                    "[XvMC] I915XvMCCreateSurface: Failed to allocate XvMC surface space!\n");
         xfree(sfpriv);
commit 167c56bcf82f0a6d72151b202e6d56f6e0d627f6
Merge: fc9368c... 78e251d...
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Tue Oct 23 00:12:22 2007 +0800

    Merge branch 'master' into xvmc

diff --cc src/i830_driver.c
index 4d57dce,4407241..e64b167
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@@ -196,12 -197,8 +197,13 @@@ USE OR OTHER DEALINGS IN THE SOFTWARE
  #include "i830_display.h"
  #include "i830_debug.h"
  #include "i830_bios.h"
+ #include "i830_video.h"
  
 +#ifdef XvMCExtension
 +#define _INTEL_XVMC_SERVER_
 +#include "i830_hwmc.h"
 +#endif
 +
  #ifdef XF86DRI
  #include "dri.h"
  #include <sys/ioctl.h>
commit fc9368ce7dacd52ef222559d20188ddcf2a85df5
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Tue Oct 23 00:09:06 2007 +0800

    split xvmc user lib chipset drivers

diff --git a/src/i830_hwmc.h b/src/i830_hwmc.h
index 60a4978..70ec00d 100644
--- a/src/i830_hwmc.h
+++ b/src/i830_hwmc.h
@@ -36,14 +36,20 @@
 #define INTEL_XVMC_COMMAND_DISPLAY      0x00
 #define INTEL_XVMC_COMMAND_UNDISPLAY    0x01
 
+/* hw xvmc support type */
+#define XVMC_I915_MPEG2_MC	0x01
+#define XVMC_I965_MPEG2_MC	0x02
+#define XVMC_I945_MPEG2_VLD	0x04
+#define XVMC_I965_MPEG2_VLD	0x08
+
+/* common header for context private */
+struct _intel_xvmc_common {
+    unsigned int type;
+};
+
 #ifdef _INTEL_XVMC_SERVER_
 #include <xf86xvmc.h>
 
-#define XVMC_DRIVER_MPEG2_MC    0x0001
-#define XVMC_DRIVER_MPEG2_VLD   0x0002
-#define XVMC_DRIVER_H264_MC     0x0004
-#define XVMC_DRIVER_H264_VLD    0x0008
-
 struct intel_xvmc_driver {
     char *name;
     XF86MCAdaptorPtr adaptor;
diff --git a/src/i915_hwmc.c b/src/i915_hwmc.c
index ed5e7bc..e2c9130 100644
--- a/src/i915_hwmc.c
+++ b/src/i915_hwmc.c
@@ -56,7 +56,6 @@
 #endif
 
 #define _INTEL_XVMC_SERVER_
-#include "i830_hwmc.h"
 #include "i915_hwmc.h"
 
 #define I915_XVMC_MAX_BUFFERS 2
@@ -531,6 +530,7 @@ static int I915XvMCCreateContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext,
         return BadAlloc;
     }
 
+    contextRec->comm.type = xvmc_driver->flag;
     contextRec->ctxno = i;
     contextRec->sis.handle = ctxpriv->sis_handle;
     contextRec->sis.offset = ctxpriv->mcStaticIndirectState->offset;
@@ -892,7 +892,7 @@ static void i915_xvmc_fini(ScrnInfoPtr pScrn)
 struct intel_xvmc_driver i915_xvmc_driver = {
     .name	= "i915_xvmc",
     .adaptor	= &pAdapt,
-    .flag	= XVMC_DRIVER_MPEG2_MC,
+    .flag	= XVMC_I915_MPEG2_MC,
     .init	= i915_xvmc_init,
     .fini	= i915_xvmc_fini,
     .putimage_size = i915_xvmc_putimage_size,
diff --git a/src/i915_hwmc.h b/src/i915_hwmc.h
index 21964cb..cf74d33 100644
--- a/src/i915_hwmc.h
+++ b/src/i915_hwmc.h
@@ -27,6 +27,8 @@
 #ifndef _I915_HWMC_H
 #define _I915_HWMC_H
 
+#include "i830_hwmc.h"
+
 #define STRIDE(w)               (((w) + 0x3ff) & ~0x3ff)
 #define SIZE_Y420(w, h)         (h * STRIDE(w))
 #define SIZE_UV420(w, h)        ((h >> 1) * STRIDE(w >> 1))
@@ -55,6 +57,7 @@ struct hwmc_buffer
 
 typedef struct 
 {
+    struct _intel_xvmc_common comm;
     unsigned int ctxno; /* XvMC private context reference number */
     struct hwmc_buffer sis;
     struct hwmc_buffer ssb;
diff --git a/src/xvmc/I915XvMC.c b/src/xvmc/I915XvMC.c
index 59d5730..2c3dec6 100644
--- a/src/xvmc/I915XvMC.c
+++ b/src/xvmc/I915XvMC.c
@@ -24,35 +24,14 @@
  *    Xiang Haihao <haihao.xiang at intel.com>
  *
  */
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <errno.h>
-#include <signal.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <string.h>
-#include <assert.h>
 
 #include <pthread.h>
 #include <sys/ioctl.h>
-#include <X11/Xlibint.h>
-#include <fourcc.h>
-#include <X11/extensions/Xv.h>
-#include <X11/extensions/Xvlib.h>
-#include <X11/extensions/XvMC.h>
-#include <X11/extensions/XvMClib.h>
-#include <xf86drm.h>
-#include <drm_sarea.h>
 
 #include "I915XvMC.h"
 #include "i915_structs.h"
 #include "i915_program.h"
 #include "intel_batchbuffer.h"
-#include "xf86dri.h"
-#include "driDrawable.h"
-
-#define _STATIC_ static
 
 #define SAREAPTR(ctx) ((drmI830Sarea *)                     \
                        (((CARD8 *)(ctx)->sarea_address) +   \
@@ -66,7 +45,7 @@
                                  SIZE_Y420(surface->width, surface->height))
 
 /* Lookup tables to speed common calculations */
-_STATIC_ unsigned int mb_bytes[] = {
+static unsigned int mb_bytes[] = {
     000, 128, 128, 256, 128, 256, 256, 384,  // 0
     128, 256, 256, 384, 256, 384, 384, 512,  // 1
     128, 256, 256, 384, 256, 384, 384, 512,  // 10
@@ -82,11 +61,51 @@ typedef union {
     uint  u[2];
 } su_t;
 
-_STATIC_ char I915KernelDriverName[] = "i915";
-_STATIC_ int error_base;
-_STATIC_ int event_base;
+static char I915KernelDriverName[] = "i915";
+static int error_base;
+static int event_base;
+
+static int i915_xvmc_mc_create_context(Display* display, XvMCContext *context, int priv_count, CARD32* priv_data);
+static int i915_xvmc_mc_destroy_context(Display* display, XvMCContext *context);
+static int i915_xvmc_mc_create_surface(Display* display, XvMCContext *context, XvMCSurface *surface);
+static int i915_xvmc_mc_destroy_surface(Display* display, XvMCSurface *surface);
+static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context,
+                         unsigned int picture_structure,
+                         XvMCSurface *target_surface,
+                         XvMCSurface *past_surface,
+                         XvMCSurface *future_surface,
+                         unsigned int flags,
+                         unsigned int num_macroblocks,
+                         unsigned int first_macroblock,
+                         XvMCMacroBlockArray *macroblock_array,
+                         XvMCBlockArray *blocks);
+static int i915_xvmc_mc_put_surface(Display *display,XvMCSurface *surface,
+                      Drawable draw, short srcx, short srcy,
+                      unsigned short srcw, unsigned short srch,
+                      short destx, short desty,
+                      unsigned short destw, unsigned short desth,
+                      int flags);
+static int i915_xvmc_mc_get_surface_status(Display *display, XvMCSurface *surface, int *stat);
+//XXX
+static int i915_xvmc_mc_init()
+{return 0;}
+static void i915_xvmc_mc_fini()
+{}
+
+struct _intel_xvmc_driver i915_xvmc_mc_driver = {
+    .type = XVMC_I915_MPEG2_MC,
+    .init = i915_xvmc_mc_init,
+    .fini = i915_xvmc_mc_fini,
+    .create_context = i915_xvmc_mc_create_context,
+    .destroy_context = i915_xvmc_mc_destroy_context,
+    .create_surface = i915_xvmc_mc_create_surface,
+    .destroy_surface = i915_xvmc_mc_destroy_surface,
+    .render_surface = i915_xvmc_mc_render_surface,
+    .put_surface = i915_xvmc_mc_put_surface,
+    .get_surface_status = i915_xvmc_mc_get_surface_status,
+};
 
-_STATIC_ int findOverlap(unsigned int width, unsigned int height,
+static int findOverlap(unsigned int width, unsigned int height,
                        short *dstX, short *dstY,
                        short *srcX, short *srcY, 
                        unsigned short *areaW, unsigned short *areaH)
@@ -122,12 +141,12 @@ _STATIC_ int findOverlap(unsigned int width, unsigned int height,
     return 0;
 }
 
-_STATIC_ __inline__ void renderError(void) 
+static __inline__ void renderError(void) 
 {
     XVMC_ERR("Invalid Macroblock Parameters found.");
 }
 
-_STATIC_ void I915XvMCContendedLock(i915XvMCContext *pI915XvMC, drmLockFlags flags)
+static void I915XvMCContendedLock(i915XvMCContext *pI915XvMC, drmLockFlags flags)
 {
     drmGetLock(pI915XvMC->fd, pI915XvMC->hHWContext, flags);
 }
@@ -159,7 +178,7 @@ _STATIC_ void I915XvMCContendedLock(i915XvMCContext *pI915XvMC, drmLockFlags fla
 
 /* Lock the hardware and validate our state.
  */
-_STATIC_ void LOCK_HARDWARE(i915XvMCContext  *pI915XvMC)
+static void LOCK_HARDWARE(i915XvMCContext  *pI915XvMC)
 {
     char __ret = 0;
 
@@ -177,7 +196,7 @@ _STATIC_ void LOCK_HARDWARE(i915XvMCContext  *pI915XvMC)
 
 /* Unlock the hardware using the global current context
  */
-_STATIC_ void UNLOCK_HARDWARE(i915XvMCContext *pI915XvMC)
+static void UNLOCK_HARDWARE(i915XvMCContext *pI915XvMC)
 {
     pI915XvMC->locked = 0;
     DRM_UNLOCK(pI915XvMC->fd, pI915XvMC->driHwLock, 
@@ -185,7 +204,7 @@ _STATIC_ void UNLOCK_HARDWARE(i915XvMCContext *pI915XvMC)
     PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
 }
 
-_STATIC_ void i915_flush(i915XvMCContext *pI915XvMC, int map, int render)
+static void i915_flush(i915XvMCContext *pI915XvMC, int map, int render)
 {
     struct i915_mi_flush mi_flush;
 
@@ -199,7 +218,7 @@ _STATIC_ void i915_flush(i915XvMCContext *pI915XvMC, int map, int render)
 }
 
 /* for MC picture rendering */
-_STATIC_ void i915_mc_static_indirect_state_buffer(XvMCContext *context, 
+static void i915_mc_static_indirect_state_buffer(XvMCContext *context, 
                                                    XvMCSurface *surface,
                                                    unsigned int picture_structure,
                                                    unsigned int flags,
@@ -325,7 +344,7 @@ _STATIC_ void i915_mc_static_indirect_state_buffer(XvMCContext *context,
     buffer_info->dw2.base_address = (pI915XvMC->corrdata.offset >> 2);  /* starting DWORD address */
 }
 
-_STATIC_ void i915_mc_map_state_buffer(XvMCContext *context, 
+static void i915_mc_map_state_buffer(XvMCContext *context, 
                                        i915XvMCSurface *privTarget,
                                        i915XvMCSurface *privPast,
                                        i915XvMCSurface *privFuture)
@@ -471,7 +490,7 @@ _STATIC_ void i915_mc_map_state_buffer(XvMCContext *context,
     tm->tm2.pitch = (privFuture->uvStride >> 2) - 1;
 }
 
-_STATIC_ void i915_mc_load_sis_msb_buffers(XvMCContext *context)
+static void i915_mc_load_sis_msb_buffers(XvMCContext *context)
 {
     struct i915_3dstate_load_indirect *load_indirect;
     sis_state *sis = NULL;
@@ -524,7 +543,7 @@ _STATIC_ void i915_mc_load_sis_msb_buffers(XvMCContext *context)
     free(base);
 }
 
-_STATIC_ void i915_mc_mpeg_set_origin(XvMCContext *context, XvMCMacroBlock *mb)
+static void i915_mc_mpeg_set_origin(XvMCContext *context, XvMCMacroBlock *mb)
 {
     struct i915_3dmpeg_set_origin set_origin;
     i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
@@ -540,7 +559,7 @@ _STATIC_ void i915_mc_mpeg_set_origin(XvMCContext *context, XvMCMacroBlock *mb)
     intelBatchbufferData(pI915XvMC, &set_origin, sizeof(set_origin), 0);
 }
 
-_STATIC_ void i915_mc_mpeg_macroblock_ipicture(XvMCContext *context, XvMCMacroBlock *mb)
+static void i915_mc_mpeg_macroblock_ipicture(XvMCContext *context, XvMCMacroBlock *mb)
 {
     struct i915_3dmpeg_macroblock_ipicture macroblock_ipicture;
     i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
@@ -555,7 +574,7 @@ _STATIC_ void i915_mc_mpeg_macroblock_ipicture(XvMCContext *context, XvMCMacroBl
 }
 
 
-_STATIC_ void i915_mc_mpeg_macroblock_0mv(XvMCContext *context, XvMCMacroBlock *mb)
+static void i915_mc_mpeg_macroblock_0mv(XvMCContext *context, XvMCMacroBlock *mb)
 {
     struct i915_3dmpeg_macroblock_0mv macroblock_0mv;
     i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
@@ -584,7 +603,7 @@ _STATIC_ void i915_mc_mpeg_macroblock_0mv(XvMCContext *context, XvMCMacroBlock *
     intelBatchbufferData(pI915XvMC, &macroblock_0mv, sizeof(macroblock_0mv), 0);
 }
 
-_STATIC_ void i915_mc_mpeg_macroblock_1fbmv(XvMCContext *context, XvMCMacroBlock *mb)
+static void i915_mc_mpeg_macroblock_1fbmv(XvMCContext *context, XvMCMacroBlock *mb)
 {
     struct i915_3dmpeg_macroblock_1fbmv macroblock_1fbmv;
     i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
@@ -623,7 +642,7 @@ _STATIC_ void i915_mc_mpeg_macroblock_1fbmv(XvMCContext *context, XvMCMacroBlock
     intelBatchbufferData(pI915XvMC, &macroblock_1fbmv, sizeof(macroblock_1fbmv), 0);
 }
 
-_STATIC_ void i915_mc_mpeg_macroblock_2fbmv(XvMCContext *context, XvMCMacroBlock *mb, unsigned int ps)
+static void i915_mc_mpeg_macroblock_2fbmv(XvMCContext *context, XvMCMacroBlock *mb, unsigned int ps)
 {
     struct i915_3dmpeg_macroblock_2fbmv macroblock_2fbmv;
     i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
@@ -691,7 +710,7 @@ _STATIC_ void i915_mc_mpeg_macroblock_2fbmv(XvMCContext *context, XvMCMacroBlock
 }
 
 /* for MC context initialization */
-_STATIC_ void i915_mc_sampler_state_buffer(XvMCContext *context)
+static void i915_mc_sampler_state_buffer(XvMCContext *context)
 {
     struct i915_3dstate_sampler_state *sampler_state;
     struct texture_sampler *ts;
@@ -760,7 +779,7 @@ _STATIC_ void i915_mc_sampler_state_buffer(XvMCContext *context)
     ts->ts2.default_color = 0;
 }
 
-_STATIC_ void i915_inst_arith(unsigned int *inst,
+static void i915_inst_arith(unsigned int *inst,
                             unsigned int op,
                             unsigned int dest,
                             unsigned int mask,
@@ -775,7 +794,7 @@ _STATIC_ void i915_inst_arith(unsigned int *inst,
     *inst = (A2_SRC1(src1) | A2_SRC2(src2));
 }
 
-_STATIC_ void i915_inst_decl(unsigned int *inst, 
+static void i915_inst_decl(unsigned int *inst, 
                            unsigned int type,
                            unsigned int nr,
                            unsigned int d0_flags)
@@ -789,7 +808,7 @@ _STATIC_ void i915_inst_decl(unsigned int *inst,
     *inst = D2_MBZ;
 }
 
-_STATIC_ void i915_inst_texld(unsigned int *inst,
+static void i915_inst_texld(unsigned int *inst,
                               unsigned int op,
                               unsigned int dest,
                               unsigned int coord,
@@ -803,7 +822,7 @@ _STATIC_ void i915_inst_texld(unsigned int *inst,
    *inst = T2_MBZ;
 }
 
-_STATIC_ void i915_mc_pixel_shader_program_buffer(XvMCContext *context)
+static void i915_mc_pixel_shader_program_buffer(XvMCContext *context)
 {
     struct i915_3dstate_pixel_shader_program *pixel_shader_program;
     i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
@@ -945,7 +964,7 @@ _STATIC_ void i915_mc_pixel_shader_program_buffer(XvMCContext *context)
     inst += 3;
 }
 
-_STATIC_ void i915_mc_pixel_shader_constants_buffer(XvMCContext *context)
+static void i915_mc_pixel_shader_constants_buffer(XvMCContext *context)
 {
     struct i915_3dstate_pixel_shader_constants *pixel_shader_constants;
     i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
@@ -964,7 +983,7 @@ _STATIC_ void i915_mc_pixel_shader_constants_buffer(XvMCContext *context)
     *(value++) = 0.5;
 }
 
-_STATIC_ void i915_mc_one_time_state_initialization(XvMCContext *context)
+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;
@@ -1076,7 +1095,7 @@ _STATIC_ void i915_mc_one_time_state_initialization(XvMCContext *context)
     free(base);
 }
 
-_STATIC_ void i915_mc_invalidate_subcontext_buffers(XvMCContext *context, unsigned int mask)
+static void i915_mc_invalidate_subcontext_buffers(XvMCContext *context, unsigned int mask)
 {
     struct i915_3dstate_load_indirect *load_indirect = NULL;
     sis_state *sis = NULL;
@@ -1184,7 +1203,7 @@ _STATIC_ void i915_mc_invalidate_subcontext_buffers(XvMCContext *context, unsign
     free(base);
 }
 
-_STATIC_ int i915_xvmc_map_buffers(i915XvMCContext *pI915XvMC)
+static int i915_xvmc_map_buffers(i915XvMCContext *pI915XvMC)
 {
     if (drmMap(pI915XvMC->fd,
                pI915XvMC->sis.handle,
@@ -1238,7 +1257,7 @@ _STATIC_ int i915_xvmc_map_buffers(i915XvMCContext *pI915XvMC)
     return 0;
 }
 
-_STATIC_ void i915_xvmc_unmap_buffers(i915XvMCContext *pI915XvMC)
+static void i915_xvmc_unmap_buffers(i915XvMCContext *pI915XvMC)
 {
     if (pI915XvMC->sis.map) {
         drmUnmap(pI915XvMC->sis.map, pI915XvMC->sis.size);
@@ -1279,7 +1298,7 @@ _STATIC_ void i915_xvmc_unmap_buffers(i915XvMCContext *pI915XvMC)
 /*
  * Video post processing 
  */
-_STATIC_ void i915_yuv2rgb_map_state_buffer(XvMCSurface *target_surface)
+static void i915_yuv2rgb_map_state_buffer(XvMCSurface *target_surface)
 {
     struct i915_3dstate_map_state *map_state;
     struct texture_map *tm;
@@ -1353,7 +1372,7 @@ _STATIC_ void i915_yuv2rgb_map_state_buffer(XvMCSurface *target_surface)
     tm->tm2.pitch = (privTarget->uvStride >> 2) - 1;    /* in DWords - 1 */
 }
 
-_STATIC_ void i915_yuv2rgb_sampler_state_buffer(XvMCSurface *surface)
+static void i915_yuv2rgb_sampler_state_buffer(XvMCSurface *surface)
 {
     struct i915_3dstate_sampler_state *sampler_state;
     struct texture_sampler *ts;
@@ -1450,7 +1469,7 @@ _STATIC_ void i915_yuv2rgb_sampler_state_buffer(XvMCSurface *surface)
     ts->ts2.default_color = 0;
 }
 
-_STATIC_ void i915_yuv2rgb_static_indirect_state_buffer(XvMCSurface *surface,
+static void i915_yuv2rgb_static_indirect_state_buffer(XvMCSurface *surface,
                                                       unsigned int dstaddr, 
                                                       int dstpitch)
 {
@@ -1484,7 +1503,7 @@ _STATIC_ void i915_yuv2rgb_static_indirect_state_buffer(XvMCSurface *surface,
     dest_buffer_variables->dw1.color_fmt = COLORBUFFER_A8R8G8B8;  /* FIXME */
 }
 
-_STATIC_ void i915_yuv2rgb_pixel_shader_program_buffer(XvMCSurface *surface)
+static void i915_yuv2rgb_pixel_shader_program_buffer(XvMCSurface *surface)
 {
     struct i915_3dstate_pixel_shader_program *pixel_shader_program;
     i915XvMCSurface *privSurface = (i915XvMCSurface *)surface->privData;
@@ -1534,7 +1553,7 @@ _STATIC_ void i915_yuv2rgb_pixel_shader_program_buffer(XvMCSurface *surface)
     i915_inst_texld(inst, T0_TEXLD, dest, src0, src1);
 }
 
-_STATIC_ void i915_yuv2rgb_proc(XvMCSurface *surface)
+static void i915_yuv2rgb_proc(XvMCSurface *surface)
 {
     i915XvMCSurface *privSurface = (i915XvMCSurface *)surface->privData;
     i915XvMCContext *pI915XvMC = (i915XvMCContext *)privSurface->privContext;
@@ -1695,13 +1714,11 @@ _STATIC_ void i915_yuv2rgb_proc(XvMCSurface *surface)
 // Function: i915_release_resource
 // Description:
 ***************************************************************************/
-_STATIC_ void i915_release_resource(Display *display, XvMCContext *context)
+//XXX
+static void i915_release_resource(Display *display, XvMCContext *context)
 {
     i915XvMCContext *pI915XvMC;
 
-    if (!display || !context)
-        return;
-
     if (!(pI915XvMC = context->privData))
         return;
 
@@ -1733,115 +1750,18 @@ _STATIC_ void i915_release_resource(Display *display, XvMCContext *context)
     context->privData = NULL;
 }
 
-/***************************************************************************
-// Function: XvMCCreateContext
-// Description: Create a XvMC context for the given surface parameters.
-// Arguments:
-//   display - Connection to the X server.
-//   port - XvPortID to use as avertised by the X connection.
-//   surface_type_id - Unique identifier for the Surface type.
-//   width - Width of the surfaces.
-//   height - Height of the surfaces.
-//   flags - one or more of the following
-//      XVMC_DIRECT - A direct rendered context is requested.
-//
-// Notes: surface_type_id and width/height parameters must match those
-//        returned by XvMCListSurfaceTypes.
-// Returns: Status
-***************************************************************************/
-Status XvMCCreateContext(Display *display, XvPortID port,
-                         int surface_type_id, int width, int height, 
-                         int flags, XvMCContext *context) 
-{  
+static int i915_xvmc_mc_create_context(Display *display, XvMCContext *context,
+	int priv_count, CARD32 *priv_data)
+{
     i915XvMCContext *pI915XvMC = NULL;
     I915XvMCCreateContextRec *tmpComm = NULL;
     Status ret;
     drm_sarea_t *pSAREA;
     char *curBusID;
-    uint *priv_data = NULL;
     uint magic;
     int major, minor;
-    int priv_count;
     int isCapable;
 
-    /* Verify Obvious things first */
-    if (!display || !context)
-        return BadValue;
-
-    if (!(flags & XVMC_DIRECT)) {
-        /* Indirect */
-        XVMC_ERR("Indirect Rendering not supported! Using Direct.");
-        return BadAccess;
-    }
-
-    /* Limit use to root for now */
-    /* FIXME: remove it ??? */
-/*
-    if (geteuid()) {
-        printf("Use of XvMC on i915 is currently limited to root\n");
-        return BadAccess;
-    }
-*/
-    /*
-     *FIXME: Check $DISPLAY for legal values here
-     */
-    context->surface_type_id = surface_type_id;
-    context->width = (unsigned short)((width + 15) & ~15);
-    context->height = (unsigned short)((height + 15) & ~15);
-    context->flags = flags;
-    context->port = port;
-
-    /* 
-       Width, Height, and flags are checked against surface_type_id
-       and port for validity inside the X server, no need to check
-       here.
-    */
-
-    /* Verify the XvMC extension exists */
-    XLockDisplay(display);
-    if (!XvMCQueryExtension(display, &event_base, &error_base)) {
-        XUnlockDisplay(display);
-        XVMC_ERR("XvMCExtension is not available!");
-        return BadAlloc;
-    }
-    /* Verify XvMC version */
-    ret = XvMCQueryVersion(display, &major, &minor);
-    if (ret) {
-        XVMC_ERR("XvMCQueryVersion Failed, unable to determine protocol version.");
-    }
-    XUnlockDisplay(display);
-    /* FIXME: Check Major and Minor here */
-
-    /* Allocate private Context data */
-    context->privData = (void *)calloc(1, sizeof(i915XvMCContext));
-    if (!context->privData) {
-        XVMC_ERR("Unable to allocate resources for XvMC context.");
-        return BadAlloc;
-    }
-    pI915XvMC = (i915XvMCContext *)context->privData;
-
-    /* Check for drm */
-    if (!drmAvailable()) {
-        XVMC_ERR("Direct Rendering is not avilable on this system!");
-        free(pI915XvMC);
-        context->privData = NULL;
-        return BadAccess;
-    }
-
-    /*
-      Pass control to the X server to create a drm_context_t for us and
-      validate the with/height and flags.
-    */
-    XLockDisplay(display);
-    if ((ret = _xvmc_create_context(display, context, &priv_count, &priv_data))) {
-        XUnlockDisplay(display);
-        XVMC_ERR("Unable to create XvMC Context.");
-        free(pI915XvMC);
-        context->privData = NULL;
-        return ret;
-    }
-    XUnlockDisplay(display);
-
     if (priv_count != (sizeof(I915XvMCCreateContextRec) >> 2)) {
         XVMC_ERR("_xvmc_create_context() returned incorrect data size!");
         XVMC_INFO("\tExpected %d, got %d",
@@ -1850,8 +1770,15 @@ Status XvMCCreateContext(Display *display, XvPortID port,
         free(priv_data);
         free(pI915XvMC);
         context->privData = NULL;
+        return BadAccess;
+    }
+
+    context->privData = (void *)calloc(1, sizeof(i915XvMCContext));
+    if (!context->privData) {
+        XVMC_ERR("Unable to allocate resources for XvMC context.");
         return BadAlloc;
     }
+    pI915XvMC = (i915XvMCContext *)context->privData;
 
     tmpComm = (I915XvMCCreateContextRec *)priv_data;
     pI915XvMC->ctxno = tmpComm->ctxno;
@@ -1891,6 +1818,8 @@ Status XvMCCreateContext(Display *display, XvPortID port,
     pI915XvMC->batchbuffer.size = tmpComm->batchbuffer.size;
     pI915XvMC->sarea_size = tmpComm->sarea_size;
     pI915XvMC->sarea_priv_offset = tmpComm->sarea_priv_offset;
+    //XXX
+//    xvmc_driver->screen = 
     pI915XvMC->screen = tmpComm->screen;
     pI915XvMC->depth = tmpComm->depth;
 
@@ -1898,64 +1827,54 @@ Status XvMCCreateContext(Display *display, XvPortID port,
     free(priv_data);
     priv_data = NULL;
 
-    XLockDisplay(display);
+    /* XXX just keep current i915 setup code for now */
+
     ret = uniDRIQueryDirectRenderingCapable(display, pI915XvMC->screen,
                                             &isCapable);
     if (!ret || !isCapable) {
-        XUnlockDisplay(display);
 	XVMC_ERR("Direct Rendering is not available on this system!");
-        free(pI915XvMC);
-        context->privData = NULL;
         return BadAlloc;
     }
 
     if (!uniDRIOpenConnection(display, pI915XvMC->screen,
                               &pI915XvMC->hsarea, &curBusID)) {
-        XUnlockDisplay(display);
         XVMC_ERR("Could not open DRI connection to X server!");
-        free(pI915XvMC);
-        context->privData = NULL;
         return BadAlloc;
     }
-    XUnlockDisplay(display);
 
     strncpy(pI915XvMC->busIdString, curBusID, 20);
     pI915XvMC->busIdString[20] = '\0';
     free(curBusID);
 
     /* Open DRI Device */
-    if((pI915XvMC->fd = drmOpen(I915KernelDriverName, NULL)) < 0) {
-        XVMC_ERR("DRM Device for %s could not be opened.", I915KernelDriverName);
-        free(pI915XvMC);
-        context->privData = NULL;
+    if((pI915XvMC->fd = drmOpen("i915", NULL)) < 0) {
+        XVMC_ERR("DRM Device could not be opened.");
+	//(xvmc_driver->fini)();
+	//xvmc_driver = NULL;
         return BadAccess;
-    } /* !pI915XvMC->fd */
+    }
 
     /* Get magic number */
     drmGetMagic(pI915XvMC->fd, &magic);
     // context->flags = (unsigned long)magic;
 
-    XLockDisplay(display);
     if (!uniDRIAuthConnection(display, pI915XvMC->screen, magic)) {
-        XUnlockDisplay(display);
 	XVMC_ERR("[XvMC]: X server did not allow DRI. Check permissions.");
-        free(pI915XvMC);
-        context->privData = NULL;
+	//(xvmc_driver->fini)();
+	//xvmc_driver = NULL;
         return BadAlloc;
     }
-    XUnlockDisplay(display);
 
     /*
-     * Map DRI Sarea.
+     * Map DRI Sarea. we always want it right?
      */
     if (drmMap(pI915XvMC->fd, pI915XvMC->hsarea,
                pI915XvMC->sarea_size, &pI915XvMC->sarea_address) < 0) {
         XVMC_ERR("Unable to map DRI SAREA.\n");
-        free(pI915XvMC);
-        context->privData = NULL;
+	//(xvmc_driver->fini)();
+	//xvmc_driver = NULL;
         return BadAlloc;
     }
-
     pSAREA = (drm_sarea_t *)pI915XvMC->sarea_address;
     pI915XvMC->driHwLock = (drmLock *)&pSAREA->lock;
     pI915XvMC->sarea = SAREAPTR(pI915XvMC);
@@ -2000,8 +1919,8 @@ Status XvMCCreateContext(Display *display, XvPortID port,
     }
 
     /* Initialize private context values */
-    pI915XvMC->yStride = STRIDE(width);
-    pI915XvMC->uvStride = STRIDE(width >> 1);
+    pI915XvMC->yStride = STRIDE(context->width);
+    pI915XvMC->uvStride = STRIDE(context->width >> 1);
     pI915XvMC->haveXv = 0;
     pI915XvMC->dual_prime = 0;
     pI915XvMC->last_flip = 0;
@@ -2010,7 +1929,7 @@ Status XvMCCreateContext(Display *display, XvPortID port,
     pthread_mutex_init(&pI915XvMC->ctxmutex, NULL);
     intelInitBatchBuffer(pI915XvMC);
     pI915XvMC->ref = 1;
-    return Success;
+    return 0;
 }
 
 /***************************************************************************
@@ -2023,13 +1942,10 @@ Status XvMCCreateContext(Display *display, XvPortID port,
 //
 // Returns: Status
 ***************************************************************************/
-Status XvMCDestroyContext(Display *display, XvMCContext *context)
+static int i915_xvmc_mc_destroy_context(Display *display, XvMCContext *context)
 {
     i915XvMCContext *pI915XvMC;
 
-    if (!display || !context)
-        return BadValue;
-
     if (!(pI915XvMC = context->privData))
         return (error_base + XvMCBadContext);
 
@@ -2041,7 +1957,7 @@ Status XvMCDestroyContext(Display *display, XvMCContext *context)
 /***************************************************************************
 // Function: XvMCCreateSurface
 ***************************************************************************/
-Status XvMCCreateSurface(Display *display, XvMCContext *context, XvMCSurface *surface) 
+static int i915_xvmc_mc_create_surface(Display *display, XvMCContext *context, XvMCSurface *surface) 
 {
     Status ret;
     i915XvMCContext *pI915XvMC;
@@ -2121,14 +2037,14 @@ Status XvMCCreateSurface(Display *display, XvMCContext *context, XvMCSurface *su
 
     pI915XvMC->ref++;
     PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
-    return Success;
+    return 0;
 }
 
 
 /***************************************************************************
 // Function: XvMCDestroySurface
 ***************************************************************************/
-Status XvMCDestroySurface(Display *display, XvMCSurface *surface) 
+static int i915_xvmc_mc_destroy_surface(Display *display, XvMCSurface *surface) 
 {
     i915XvMCSurface *pI915Surface;
     i915XvMCContext *pI915XvMC;
@@ -2159,87 +2075,6 @@ Status XvMCDestroySurface(Display *display, XvMCSurface *surface)
     return Success;
 }
 
-/***************************************************************************
-// Function: XvMCCreateBlocks
-***************************************************************************/
-Status XvMCCreateBlocks(Display *display, XvMCContext *context,
-                        unsigned int num_blocks, 
-                        XvMCBlockArray *block) 
-{
-    if (!display || !context || !num_blocks || !block)
-        return BadValue;
-
-    memset(block, 0, sizeof(XvMCBlockArray));
-
-    if (!(block->blocks = (short *)malloc(num_blocks << 6 * sizeof(short))))
-        return BadAlloc;
-
-    block->num_blocks = num_blocks;
-    block->context_id = context->context_id;
-    block->privData = NULL;
-
-    return Success;
-}
-
-/***************************************************************************
-// Function: XvMCDestroyBlocks
-***************************************************************************/
-Status XvMCDestroyBlocks(Display *display, XvMCBlockArray *block) 
-{
-    if (!display || block)
-        return BadValue;
-
-    if (block->blocks)
-        free(block->blocks);
-
-    block->context_id = 0;
-    block->num_blocks = 0;
-    block->blocks = NULL;
-    block->privData = NULL;
-
-    return Success;
-}
-
-/***************************************************************************
-// Function: XvMCCreateMacroBlocks
-***************************************************************************/
-Status XvMCCreateMacroBlocks(Display *display, XvMCContext *context,
-                             unsigned int num_blocks,
-                             XvMCMacroBlockArray *blocks) 
-{
-    if (!display || !context || !blocks || !num_blocks)
-        return BadValue;
-
-    memset(blocks, 0, sizeof(XvMCMacroBlockArray));
-    blocks->macro_blocks = (XvMCMacroBlock *)malloc(num_blocks * sizeof(XvMCMacroBlock));
-
-    if (!blocks->macro_blocks)
-        return BadAlloc;
-
-    blocks->num_blocks = num_blocks;
-    blocks->context_id = context->context_id;
-    blocks->privData = NULL;
-
-    return Success;
-}
-
-/***************************************************************************
-// Function: XvMCDestroyMacroBlocks
-***************************************************************************/
-Status XvMCDestroyMacroBlocks(Display *display, XvMCMacroBlockArray *block) 
-{
-    if (!display || !block)
-        return BadValue;
-    if (block->macro_blocks)
-        free(block->macro_blocks);
-
-    block->context_id = 0;
-    block->num_blocks = 0;
-    block->macro_blocks = NULL;
-    block->privData = NULL;
-
-    return Success;
-}
 
 /***************************************************************************
 // Function: XvMCRenderSurface
@@ -2247,7 +2082,7 @@ Status XvMCDestroyMacroBlocks(Display *display, XvMCMacroBlockArray *block)
 //  macroblock structures it dispatched the hardware commands to execute
 //  them. 
 ***************************************************************************/
-Status XvMCRenderSurface(Display *display, XvMCContext *context,
+static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context,
                          unsigned int picture_structure,
                          XvMCSurface *target_surface,
                          XvMCSurface *past_surface,
@@ -2256,7 +2091,7 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context,
                          unsigned int num_macroblocks,
                          unsigned int first_macroblock,
                          XvMCMacroBlockArray *macroblock_array,
-                         XvMCBlockArray *blocks) 
+                         XvMCBlockArray *blocks)
 {
     int i;
     int picture_coding_type = MPEG_I_PICTURE;
@@ -2444,7 +2279,7 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context,
     privTarget->last_render = pI915XvMC->last_render;
 
     UNLOCK_HARDWARE(pI915XvMC);
-    return Success;
+    return 0;
 }
 
 /***************************************************************************
@@ -2479,7 +2314,7 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context,
 //   possible to catch up before we have to check on its progress. This
 //   makes it unlikely that we have to wait on the last flip.
 ***************************************************************************/
-Status XvMCPutSurface(Display *display,XvMCSurface *surface,
+static int i915_xvmc_mc_put_surface(Display *display,XvMCSurface *surface,
                       Drawable draw, short srcx, short srcy,
                       unsigned short srcw, unsigned short srch,
                       short destx, short desty,
@@ -2545,7 +2380,7 @@ Status XvMCPutSurface(Display *display,XvMCSurface *surface,
     XUnlockDisplay(display);
     PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
 
-    return Success;
+    return 0;
 }
 
 /***************************************************************************
@@ -2556,6 +2391,7 @@ Status XvMCPutSurface(Display *display,XvMCSurface *surface,
 // Info:
 // Returns: Status
 ***************************************************************************/
+#if 0
 Status XvMCSyncSurface(Display *display, XvMCSurface *surface) 
 {
     Status ret;
@@ -2582,6 +2418,7 @@ Status XvMCFlushSurface(Display * display, XvMCSurface *surface)
 {
     return Success;
 }
+#endif
 
 /***************************************************************************
 // Function: XvMCGetSurfaceStatus
@@ -2595,7 +2432,7 @@ Status XvMCFlushSurface(Display * display, XvMCSurface *surface)
 //    XVMC_DISPLAYING - The surface is currently being displayed or a
 //                     display is pending.
 ***************************************************************************/
-Status XvMCGetSurfaceStatus(Display *display, XvMCSurface *surface, int *stat) 
+static int i915_xvmc_mc_get_surface_status(Display *display, XvMCSurface *surface, int *stat) 
 {
     i915XvMCSurface *pI915Surface;
     i915XvMCContext *pI915XvMC;
@@ -2643,7 +2480,7 @@ Status XvMCGetSurfaceStatus(Display *display, XvMCSurface *surface, int *stat)
 
     // UNLOCK_HARDWARE(pI915XvMC);
     PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
-    return Success;
+    return 0;
 }
 
 /***************************************************************************
@@ -2661,6 +2498,7 @@ Status XvMCGetSurfaceStatus(Display *display, XvMCSurface *surface, int *stat)
 //
 // Returns: Status
 ***************************************************************************/
+#if 0
 Status XvMCHideSurface(Display *display, XvMCSurface *surface) 
 {
     i915XvMCSurface *pI915Surface;
@@ -3229,64 +3067,4 @@ Status XvMCGetSubpictureStatus(Display *display, XvMCSubpicture *subpicture,
     return Success;
 }
 
-/***************************************************************************
-// Function: XvMCQueryAttributes
-// Description: An array of XvAttributes of size "number" is returned by
-//   this function. If there are no attributes, NULL is returned and number
-//   is set to 0. The array may be freed with xfree().
-//
-// Arguments:
-//   display - Connection to the X server.
-//   context - The context whos attributes we are querying.
-//   number - The returned number of recognized atoms
-//
-// Returns:
-//  An array of XvAttributes.
-***************************************************************************/
-XvAttribute *XvMCQueryAttributes(Display *display, XvMCContext *context,
-                                 int *number) 
-{
-    /* now XvMC has no extra attribs than Xv */
-    *number = 0;
-    return NULL;
-}
-
-/***************************************************************************
-// Function: XvMCSetAttribute
-// Description: This function sets a context-specific attribute.
-//
-// Arguments:
-//   display - Connection to the X server.
-//   context - The context whos attributes we are querying.
-//   attribute - The X atom of the attribute to be changed.
-//   value - The new value for the attribute.
-//
-// Returns:
-//  Status
-***************************************************************************/
-Status XvMCSetAttribute(Display *display, XvMCContext *context,
-                        Atom attribute, int value)
-{
-    return Success;
-}
-
-/***************************************************************************
-// Function: XvMCGetAttribute
-// Description: This function queries a context-specific attribute and
-//   returns the value.
-//
-// Arguments:
-//   display - Connection to the X server.
-//   context - The context whos attributes we are querying.
-//   attribute - The X atom of the attribute to be queried
-//   value - The returned attribute value
-//
-// Returns:
-//  Status
-// Notes:
-***************************************************************************/
-Status XvMCGetAttribute(Display *display, XvMCContext *context,
-                        Atom attribute, int *value) 
-{
-    return Success;
-}
+#endif
diff --git a/src/xvmc/Makefile.am b/src/xvmc/Makefile.am
index 0a805fb..09c8c4d 100644
--- a/src/xvmc/Makefile.am
+++ b/src/xvmc/Makefile.am
@@ -1,5 +1,5 @@
 if DRI
-lib_LTLIBRARIES=libI810XvMC.la libI915XvMC.la
+lib_LTLIBRARIES=libI810XvMC.la libIntelXvMC.la
 
 libI810XvMC_la_SOURCES = I810XvMC.c \
 			 I810XvMC.h
@@ -9,9 +9,10 @@ libI810XvMC_la_CFLAGS = @WARN_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@ \
 libI810XvMC_la_LDFLAGS = -version-number 1:0:0
 libI810XvMC_la_LIBADD = @DRI_LIBS@ 
 
-libI915XvMC_la_SOURCES = I915XvMC.c \
-                         I915XvMC.h \
+libIntelXvMC_la_SOURCES = intel_xvmc.c \
 			 intel_xvmc.h \
+			 I915XvMC.c \
+                         I915XvMC.h \
                          intel_batchbuffer.c \
                          intel_batchbuffer.h \
                          xf86dri.c \
@@ -19,7 +20,7 @@ libI915XvMC_la_SOURCES = I915XvMC.c \
                          xf86dristr.h \
                          driDrawable.c \
                          driDrawable.h
-libI915XvMC_la_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@ -I$(top_srcdir)/src -DTRUE=1 -DFALSE=0
-libI915XvMC_la_LDFLAGS = -version-number 1:0:0
-libI915XvMC_la_LIBADD = @DRI_LIBS@
+libIntelXvMC_la_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@ -I$(top_srcdir)/src -DTRUE=1 -DFALSE=0
+libIntelXvMC_la_LDFLAGS = -version-number 1:0:0
+libIntelXvMC_la_LIBADD = @DRI_LIBS@
 endif
diff --git a/src/xvmc/intel_xvmc.c b/src/xvmc/intel_xvmc.c
new file mode 100644
index 0000000..8c770ce
--- /dev/null
+++ b/src/xvmc/intel_xvmc.c
@@ -0,0 +1,1333 @@
+
+/* public interface file */
+
+#include <X11/X.h>
+#include <X11/Xlibint.h>
+#include <fourcc.h>
+#include <X11/extensions/Xv.h>
+#include <X11/extensions/Xvlib.h>
+#include <X11/extensions/XvMC.h>
+#include <X11/extensions/XvMClib.h>
+#include <xf86drm.h>
+#include <drm_sarea.h>
+
+#include "intel_xvmc.h"
+#include "xf86dri.h"
+#include "driDrawable.h"
+
+static struct _intel_xvmc_driver* xvmc_driver = NULL;
+static int error_base;
+static int event_base;
+
+/***************************************************************************
+// Function: XvMCCreateContext
+// Description: Create a XvMC context for the given surface parameters.
+// Arguments:
+//   display - Connection to the X server.
+//   port - XvPortID to use as avertised by the X connection.
+//   surface_type_id - Unique identifier for the Surface type.
+//   width - Width of the surfaces.
+//   height - Height of the surfaces.
+//   flags - one or more of the following
+//      XVMC_DIRECT - A direct rendered context is requested.
+//
+// Notes: surface_type_id and width/height parameters must match those
+//        returned by XvMCListSurfaceTypes.
+// Returns: Status
+***************************************************************************/
+Status XvMCCreateContext(Display *display, XvPortID port,
+                         int surface_type_id, int width, int height,
+                         int flags, XvMCContext *context)
+{
+    Status ret;
+    drm_sarea_t *pSAREA;
+    char *curBusID;
+    CARD32 *priv_data = NULL;
+    struct _intel_xvmc_common *comm;
+    uint magic;
+    int major, minor;
+    int priv_count;
+    int isCapable;
+
+    /* Verify Obvious things first */
+    if (!display || !context)
+        return BadValue;
+
+    if (!(flags & XVMC_DIRECT)) {
+        /* Indirect */
+        XVMC_ERR("Indirect Rendering not supported! Using Direct.");
+        return BadAccess;
+    }
+
+    /* Limit use to root for now */
+    /* FIXME: remove it ??? */
+/*
+    if (geteuid()) {
+        printf("Use of XvMC on i915 is currently limited to root\n");
+        return BadAccess;
+    }
+*/
+    /*
+       Width, Height, and flags are checked against surface_type_id
+       and port for validity inside the X server, no need to check
+       here.
+    */
+    context->surface_type_id = surface_type_id;
+    context->width = (unsigned short)((width + 15) & ~15);
+    context->height = (unsigned short)((height + 15) & ~15);
+    context->flags = flags;
+    context->port = port;
+
+    if (!XvMCQueryExtension(display, &event_base, &error_base)) {
+        XVMC_ERR("XvMCExtension is not available!");
+        return BadAccess;
+    }
+    ret = XvMCQueryVersion(display, &major, &minor);
+    if (ret) {
+        XVMC_ERR("XvMCQueryVersion Failed, unable to determine protocol version.");
+	return BadAccess;
+    }
+
+    /* XXX: major and minor could be checked in future for XvMC
+     * protocol capability (i.e H.264/AVC decode available)
+     */
+
+    /*
+      Pass control to the X server to create a drm_context_t for us and
+      validate the with/height and flags.
+    */
+    if ((ret = _xvmc_create_context(display, context, &priv_count, &priv_data))) {
+        XVMC_ERR("Unable to create XvMC Context.");
+        return ret;
+    }
+
+    comm = (struct _intel_xvmc_common *)priv_data;
+    XVMC_INFO("hw xvmc type %d", comm->type);
+    //XXX: how to handle different driver types
+    if (xvmc_driver == NULL || xvmc_driver->type != comm->type) {
+	switch (comm->type) {
+	    case XVMC_I915_MPEG2_MC:
+		xvmc_driver = &i915_xvmc_mc_driver;
+		break;
+	    case XVMC_I965_MPEG2_MC:
+	    case XVMC_I945_MPEG2_VLD:
+	    case XVMC_I965_MPEG2_VLD:
+	    default:
+		XVMC_ERR("unimplemented xvmc type %d", comm->type);
+		free(priv_data);
+		priv_data = NULL;
+		return BadAccess;
+	}
+    } else {
+	XVMC_ERR("wrong hw xvmc type returned\n");
+	free(priv_data);
+	priv_data = NULL;
+	return BadAccess;
+    }
+
+    if (xvmc_driver == NULL) {
+	XVMC_ERR("fail to load xvmc driver for type %d\n", comm->type);
+	return BadAccess;
+    }
+
+    /* driver hook should free priv_data after return if success.
+     * and set xvmc_driver->screen num */
+    ret = (xvmc_driver->create_context)(display, context, priv_count, priv_data);
+    if (ret) {
+	XVMC_ERR("driver create context failed\n");
+	free(priv_data);
+	return BadAccess;
+    }
+
+#if 0
+    ret = uniDRIQueryDirectRenderingCapable(display, xvmc_driver->screen,
+                                            &isCapable);
+    if (!ret || !isCapable) {
+	XVMC_ERR("Direct Rendering is not available on this system!");
+        return BadAlloc;
+    }
+
+    if (!uniDRIOpenConnection(display, xvmc_driver->screen,
+                              &xvmc_driver->hsarea, &curBusID)) {
+        XVMC_ERR("Could not open DRI connection to X server!");
+        return BadAlloc;
+    }
+
+    strncpy(xvmc_driver->busID, curBusID, 20);
+    xvmc_driver->busID[20] = '\0';
+    free(curBusID);
+
+    /* Open DRI Device */
+    if((xvmc_driver->fd = drmOpen("i915", NULL)) < 0) {
+        XVMC_ERR("DRM Device could not be opened.");
+	(xvmc_driver->fini)();
+	xvmc_driver = NULL;
+        return BadAccess;
+    }
+
+    /* Get magic number */
+    drmGetMagic(xvmc_driver->fd, &magic);
+    // context->flags = (unsigned long)magic;
+
+    if (!uniDRIAuthConnection(display, xvmc_driver->screen, magic)) {
+	XVMC_ERR("[XvMC]: X server did not allow DRI. Check permissions.");
+	(xvmc_driver->fini)();
+	xvmc_driver = NULL;
+        return BadAlloc;
+    }
+
+    /*
+     * Map DRI Sarea. we always want it right?
+     */
+    if (drmMap(xvmc_driver->fd, xvmc_driver->hsarea,
+               xvmc_driver->sarea_size, &xvmc_driver->sarea_address) < 0) {
+        XVMC_ERR("Unable to map DRI SAREA.\n");
+	(xvmc_driver->fini)();
+	xvmc_driver = NULL;
+        return BadAlloc;
+    }
+
+    pSAREA = (drm_sarea_t *)xvmc_driver->sarea_address;
+    pI915XvMC->driHwLock = (drmLock *)&pSAREA->lock;
+    pI915XvMC->sarea = SAREAPTR(pI915XvMC);
+    XLockDisplay(display);
+    ret = XMatchVisualInfo(display, pI915XvMC->screen,
+                           (pI915XvMC->depth == 32) ? 24 : pI915XvMC->depth, TrueColor,
+                           &pI915XvMC->visualInfo);
+    XUnlockDisplay(display);
+
+    if (!ret) {
+	XVMC_ERR("Could not find a matching TrueColor visual.");
+        free(pI915XvMC);
+        context->privData = NULL;
+        drmUnmap(pI915XvMC->sarea_address, pI915XvMC->sarea_size);
+        return BadAlloc;
+    }
+
+    if (!uniDRICreateContext(display, pI915XvMC->screen,
+                             pI915XvMC->visualInfo.visual, &pI915XvMC->id,
+                             &pI915XvMC->hHWContext)) {
+        XVMC_ERR("Could not create DRI context.");
+        free(pI915XvMC);
+        context->privData = NULL;
+        drmUnmap(pI915XvMC->sarea_address, pI915XvMC->sarea_size);
+        return BadAlloc;
+    }
+
+    if (NULL == (pI915XvMC->drawHash = drmHashCreate())) {
+	XVMC_ERR("Could not allocate drawable hash table.");
+        free(pI915XvMC);
+        context->privData = NULL;
+        drmUnmap(pI915XvMC->sarea_address, pI915XvMC->sarea_size);
+        return BadAlloc;
+    }
+
+    if (i915_xvmc_map_buffers(pI915XvMC)) {
+        i915_xvmc_unmap_buffers(pI915XvMC);
+        free(pI915XvMC);
+        context->privData = NULL;
+        drmUnmap(pI915XvMC->sarea_address, pI915XvMC->sarea_size);
+        return BadAlloc;
+    }
+
+    /* Initialize private context values */
+    pI915XvMC->yStride = STRIDE(width);
+    pI915XvMC->uvStride = STRIDE(width >> 1);
+    pI915XvMC->haveXv = 0;
+    pI915XvMC->dual_prime = 0;
+    pI915XvMC->last_flip = 0;
+    pI915XvMC->locked = 0;
+    pI915XvMC->port = context->port;
+    pthread_mutex_init(&pI915XvMC->ctxmutex, NULL);
+    intelInitBatchBuffer(pI915XvMC);
+    pI915XvMC->ref = 1;
+#endif
+
+    return Success;
+}
+
+/***************************************************************************
+// Function: XvMCDestroyContext
+// Description: Destorys the specified context.
+//
+// Arguments:
+//   display - Specifies the connection to the server.
+//   context - The context to be destroyed.
+//
+// Returns: Status
+***************************************************************************/
+Status XvMCDestroyContext(Display *display, XvMCContext *context)
+{
+    int ret = -1;
+    if (!display || !context)
+        return BadValue;
+
+    ret = (xvmc_driver->destroy_context)(display, context);
+    if (ret) {
+	XVMC_ERR("destroy context fail\n");
+	return BadAccess;
+    }
+
+    /* Pass Control to the X server to destroy the drm_context_t */
+    //XXX move generic destroy method here
+    //i915_release_resource(display,context);
+    return Success;
+}
+
+/***************************************************************************
+// Function: XvMCCreateSurface
+***************************************************************************/
+Status XvMCCreateSurface(Display *display, XvMCContext *context, XvMCSurface *surface) 
+{
+    int ret;
+//    i915XvMCContext *pI915XvMC;
+//    i915XvMCSurface *pI915Surface;
+//    I915XvMCCreateSurfaceRec *tmpComm = NULL;
+//    int priv_count;
+//    uint *priv_data;
+
+    if (!display || !context || !surface)
+        return BadValue;
+
+    ret = (xvmc_driver->create_surface)(display, context, surface);
+    if (ret) {
+	XVMC_ERR("create surface failed\n");
+	return BadAccess;
+    }
+
+#if 0
+    if (!(pI915XvMC = context->privData))
+        return (error_base + XvMCBadContext);
+
+    PPTHREAD_MUTEX_LOCK(pI915XvMC);
+    surface->privData = (i915XvMCSurface *)malloc(sizeof(i915XvMCSurface));
+
+    if (!(pI915Surface = surface->privData)) {
+        PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
+        return BadAlloc;
+    }
+
+    /* Initialize private values */
+    pI915Surface->last_render = 0;
+    pI915Surface->last_flip = 0;
+    pI915Surface->yStride = pI915XvMC->yStride;
+    pI915Surface->uvStride = pI915XvMC->uvStride;
+    pI915Surface->width = context->width;
+    pI915Surface->height = context->height;
+    pI915Surface->privContext = pI915XvMC;
+    pI915Surface->privSubPic = NULL;
+    pI915Surface->srf.map = NULL;
+    XLockDisplay(display);
+
+    if ((ret = _xvmc_create_surface(display, context, surface,
+                                    &priv_count, &priv_data))) {
+        XUnlockDisplay(display);
+        XVMC_ERR("Unable to create XvMCSurface.");
+        free(pI915Surface);
+        surface->privData = NULL;
+        PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
+        return ret;
+    }
+
+    XUnlockDisplay(display);
+
+    if (priv_count != (sizeof(I915XvMCCreateSurfaceRec) >> 2)) {
+        XVMC_ERR("_xvmc_create_surface() returned incorrect data size!");
+        XVMC_INFO("\tExpected %d, got %d",
+               (int)(sizeof(I915XvMCCreateSurfaceRec) >> 2), priv_count);
+        _xvmc_destroy_surface(display, surface);
+        free(priv_data);
+        free(pI915Surface);
+        surface->privData = NULL;
+        PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
+        return BadAlloc;
+    }
+
+    tmpComm = (I915XvMCCreateSurfaceRec *)priv_data;
+
+    pI915Surface->srfNo = tmpComm->srfno;
+    pI915Surface->srf.handle = tmpComm->srf.handle;
+    pI915Surface->srf.offset = tmpComm->srf.offset;
+    pI915Surface->srf.size = tmpComm->srf.size;
+    free(priv_data);
+
+    if (drmMap(pI915XvMC->fd,
+               pI915Surface->srf.handle,
+               pI915Surface->srf.size,
+               (drmAddress *)&pI915Surface->srf.map) != 0) {
+        _xvmc_destroy_surface(display, surface);
+        free(pI915Surface);
+        surface->privData = NULL;
+        PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
+        return BadAlloc;
+    }
+
+    pI915XvMC->ref++;
+    PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
+#endif
+
+    return Success;
+}
+
+
+/***************************************************************************
+// Function: XvMCDestroySurface
+***************************************************************************/
+Status XvMCDestroySurface(Display *display, XvMCSurface *surface) 
+{
+//    i915XvMCSurface *pI915Surface;
+//    i915XvMCContext *pI915XvMC;
+
+    if (!display || !surface)
+        return BadValue;
+
+    (xvmc_driver->destroy_surface)(display, surface);
+
+#if 0
+    if (!(pI915Surface = surface->privData))
+        return (error_base + XvMCBadSurface);
+
+    if (!(pI915XvMC = pI915Surface->privContext))
+        return (error_base + XvMCBadSurface);
+
+    if (pI915Surface->last_flip)
+        XvMCSyncSurface(display,surface);
+
+    if (pI915Surface->srf.map)
+        drmUnmap(pI915Surface->srf.map, pI915Surface->srf.size);
+
+    XLockDisplay(display);
+    _xvmc_destroy_surface(display, surface);
+    XUnlockDisplay(display);
+
+    free(pI915Surface);
+    surface->privData = NULL;
+    pI915XvMC->ref--;
+#endif
+
+    return Success;
+}
+
+/***************************************************************************
+// Function: XvMCCreateBlocks
+***************************************************************************/
+Status XvMCCreateBlocks(Display *display, XvMCContext *context,
+                        unsigned int num_blocks, 
+                        XvMCBlockArray *block) 
+{
+    if (!display || !context || !num_blocks || !block)
+        return BadValue;
+
+    memset(block, 0, sizeof(XvMCBlockArray));
+
+    if (!(block->blocks = (short *)malloc(num_blocks << 6 * sizeof(short))))
+        return BadAlloc;
+
+    block->num_blocks = num_blocks;
+    block->context_id = context->context_id;
+    block->privData = NULL;
+
+    return Success;
+}
+
+/***************************************************************************
+// Function: XvMCDestroyBlocks
+***************************************************************************/
+Status XvMCDestroyBlocks(Display *display, XvMCBlockArray *block) 
+{
+    if (!display || block)
+        return BadValue;
+
+    if (block->blocks)
+        free(block->blocks);
+
+    block->context_id = 0;
+    block->num_blocks = 0;
+    block->blocks = NULL;
+    block->privData = NULL;
+
+    return Success;
+}
+
+/***************************************************************************
+// Function: XvMCCreateMacroBlocks
+***************************************************************************/
+Status XvMCCreateMacroBlocks(Display *display, XvMCContext *context,
+                             unsigned int num_blocks,
+                             XvMCMacroBlockArray *blocks) 
+{
+    if (!display || !context || !blocks || !num_blocks)
+        return BadValue;
+
+    memset(blocks, 0, sizeof(XvMCMacroBlockArray));
+    blocks->macro_blocks = (XvMCMacroBlock *)malloc(num_blocks * sizeof(XvMCMacroBlock));
+
+    if (!blocks->macro_blocks)
+        return BadAlloc;
+
+    blocks->num_blocks = num_blocks;
+    blocks->context_id = context->context_id;
+    blocks->privData = NULL;
+
+    return Success;
+}
+
+/***************************************************************************
+// Function: XvMCDestroyMacroBlocks
+***************************************************************************/
+Status XvMCDestroyMacroBlocks(Display *display, XvMCMacroBlockArray *block) 
+{
+    if (!display || !block)
+        return BadValue;
+    if (block->macro_blocks)
+        free(block->macro_blocks);
+
+    block->context_id = 0;
+    block->num_blocks = 0;
+    block->macro_blocks = NULL;
+    block->privData = NULL;
+
+    return Success;
+}
+
+/***************************************************************************
+// Function: XvMCRenderSurface
+// Description: This function does the actual HWMC. Given a list of
+//  macroblock structures it dispatched the hardware commands to execute
+//  them. 
+***************************************************************************/
+Status XvMCRenderSurface(Display *display, XvMCContext *context,
+                         unsigned int picture_structure,
+                         XvMCSurface *target_surface,
+                         XvMCSurface *past_surface,
+                         XvMCSurface *future_surface,
+                         unsigned int flags,
+                         unsigned int num_macroblocks,
+                         unsigned int first_macroblock,
+                         XvMCMacroBlockArray *macroblock_array,
+                         XvMCBlockArray *blocks)
+{
+    int ret;
+
+    if (!display || !context || !target_surface) {
+        XVMC_ERR("Invalid Display, Context or Target!");
+        return BadValue;
+    }
+
+    ret = (xvmc_driver->render_surface)(display, context, picture_structure,
+	    target_surface, past_surface, future_surface, flags,
+	    num_macroblocks, first_macroblock, macroblock_array,
+	    blocks);
+
+    if (ret) {
+	XVMC_ERR("render surface fail\n");
+	return BadAccess;
+    }
+#if 0
+    int i;
+    int picture_coding_type = MPEG_I_PICTURE;
+    /* correction data buffer */
+    char *corrdata_ptr;
+    int corrdata_size = 0;
+
+    /* Block Pointer */
+    short *block_ptr;
+    /* Current Macroblock Pointer */
+    XvMCMacroBlock *mb;
+
+    i915XvMCSurface *privTarget = NULL;
+    i915XvMCSurface *privFuture = NULL;
+    i915XvMCSurface *privPast = NULL;
+    i915XvMCContext *pI915XvMC = NULL;
+
+    /* Check Parameters for validity */
+    if (!display || !context || !target_surface) {
+        XVMC_ERR("Invalid Display, Context or Target!");
+        return BadValue;
+    }
+
+    if (!num_macroblocks)
+        return Success;
+
+    if (!macroblock_array || !blocks) {
+        XVMC_ERR("Invalid block data!");
+        return BadValue;
+    }
+
+    if (macroblock_array->num_blocks < (num_macroblocks + first_macroblock)) {
+        XVMC_ERR("Too many macroblocks requested for MB array size.");
+        return BadValue;
+    }
+
+    if (!(pI915XvMC = context->privData))
+        return (error_base + XvMCBadContext);
+
+    if (!(privTarget = target_surface->privData))
+        return (error_base + XvMCBadSurface);
+
+    /* Test For YV12 Surface */
+    if (context->surface_type_id != FOURCC_YV12) {
+        XVMC_ERR("HWMC only possible on YV12 Surfaces.");
+        return BadValue;
+    }
+
+    /* P Frame Test */
+    if (!past_surface) {
+        /* Just to avoid some ifs later. */
+        privPast = privTarget;
+    } else {
+        if (!(privPast = past_surface->privData)) {
+            XVMC_ERR("Invalid Past Surface!");
+            return (error_base + XvMCBadSurface);
+        }
+        
+        picture_coding_type = MPEG_P_PICTURE;
+    }
+
+    /* B Frame Test */
+    if (!future_surface) {
+        privFuture = privPast; // privTarget;
+    } else {
+        if (!past_surface) {
+            XVMC_ERR("No Past Surface!");
+            return BadValue;
+        }
+
+        if (!(privFuture = future_surface->privData)) {
+            XVMC_ERR("Invalid Future Surface!");
+            return (error_base + XvMCBadSurface);
+        }
+
+        picture_coding_type = MPEG_B_PICTURE;
+    }
+
+    LOCK_HARDWARE(pI915XvMC);
+    corrdata_ptr = pI915XvMC->corrdata.map;
+    corrdata_size = 0;
+
+    for (i = first_macroblock; i < (num_macroblocks + first_macroblock); i++) {
+        int bspm = 0;
+        mb = &macroblock_array->macro_blocks[i];
+        block_ptr = &(blocks->blocks[mb->index << 6]);
+
+        /* Lockup can happen if the coordinates are too far out of range */
+        if (mb->x > (target_surface->width >> 4)) {
+            mb->x = 0;
+            XVMC_INFO("reset x");
+        }
+
+        if (mb->y > (target_surface->height >> 4)) {
+            mb->y = 0;
+            XVMC_INFO("reset y");
+        }
+
+        /* Catch no pattern case */
+        if (!(mb->macroblock_type & XVMC_MB_TYPE_PATTERN) &&
+            !(mb->macroblock_type & XVMC_MB_TYPE_INTRA) &&
+            mb->coded_block_pattern) {
+            mb->coded_block_pattern = 0;
+            XVMC_INFO("no coded blocks present!");
+        }
+        
+        bspm = mb_bytes[mb->coded_block_pattern];
+
+        if (!bspm)
+            continue;
+
+        corrdata_size += bspm;
+
+        if (corrdata_size > pI915XvMC->corrdata.size) {
+            XVMC_ERR("correction data buffer overflow.");
+            break;
+        }
+        memcpy(corrdata_ptr, block_ptr, bspm);
+        corrdata_ptr += bspm;
+    } 
+
+    i915_flush(pI915XvMC, 1, 0);
+    // 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_static_indirect_state_buffer(context, target_surface, 
+                                         picture_structure, flags,
+                                         picture_coding_type);
+    i915_mc_map_state_buffer(context, privTarget, privPast, privFuture);
+    i915_mc_load_sis_msb_buffers(context);
+    i915_mc_mpeg_set_origin(context, &macroblock_array->macro_blocks[first_macroblock]);
+
+    for (i = first_macroblock; i < (num_macroblocks + first_macroblock); i++) {
+        mb = &macroblock_array->macro_blocks[i];
+
+        /* Intra Blocks */
+        if (mb->macroblock_type & XVMC_MB_TYPE_INTRA) {
+            i915_mc_mpeg_macroblock_ipicture(context, mb);
+        } else if ((picture_structure & XVMC_FRAME_PICTURE) == XVMC_FRAME_PICTURE) { /* Frame Picture */
+            switch (mb->motion_type & 3) {
+            case XVMC_PREDICTION_FIELD: /* Field Based */
+                i915_mc_mpeg_macroblock_2fbmv(context, mb, picture_structure);
+                break;
+
+            case XVMC_PREDICTION_FRAME: /* Frame Based */
+                i915_mc_mpeg_macroblock_1fbmv(context, mb);
+                break;
+
+            case XVMC_PREDICTION_DUAL_PRIME:    /* Dual Prime */
+                i915_mc_mpeg_macroblock_2fbmv(context, mb, picture_structure);
+                break;
+
+            default:    /* No Motion Type */
+                renderError();
+                break;
+            }   
+        } else {        /* Frame Picture */
+            switch (mb->motion_type & 3) {
+            case XVMC_PREDICTION_FIELD: /* Field Based */
+                i915_mc_mpeg_macroblock_1fbmv(context, mb);
+                break;
+
+            case XVMC_PREDICTION_16x8:  /* 16x8 MC */
+                i915_mc_mpeg_macroblock_2fbmv(context, mb, picture_structure);
+                break;
+                
+            case XVMC_PREDICTION_DUAL_PRIME:    /* Dual Prime */
+                i915_mc_mpeg_macroblock_1fbmv(context, mb);
+                break;
+
+            default:    /* No Motion Type */
+                renderError();
+                break;
+            }
+        }       /* Field Picture */
+    }
+
+    intelFlushBatch(pI915XvMC, TRUE);
+    pI915XvMC->last_render = pI915XvMC->alloc.irq_emitted;
+    privTarget->last_render = pI915XvMC->last_render;
+
+    UNLOCK_HARDWARE(pI915XvMC);
+#endif
+    return Success;
+}
+
+/***************************************************************************
+// Function: XvMCPutSurface
+// Description:
+// Arguments:
+//  display: Connection to X server
+//  surface: Surface to be displayed
+//  draw: X Drawable on which to display the surface
+//  srcx: X coordinate of the top left corner of the region to be
+//          displayed within the surface.
+//  srcy: Y coordinate of the top left corner of the region to be
+//          displayed within the surface.
+//  srcw: Width of the region to be displayed.
+//  srch: Height of the region to be displayed.
+//  destx: X cordinate of the top left corner of the destination region
+//         in the drawable coordinates.
+//  desty: Y cordinate of the top left corner of the destination region
+//         in the drawable coordinates.
+//  destw: Width of the destination region.
+//  desth: Height of the destination region.
+//  flags: One or more of the following.
+//     XVMC_TOP_FIELD - Display only the Top field of the surface.
+//     XVMC_BOTTOM_FIELD - Display only the Bottom Field of the surface.
+//     XVMC_FRAME_PICTURE - Display both fields or frame.
+//
+// Info: Portions of this function derived from i915_video.c (XFree86)
+//
+//   This function is organized so that we wait as long as possible before
+//   touching the overlay registers. Since we don't know that the last
+//   flip has happened yet we want to give the overlay as long as
+//   possible to catch up before we have to check on its progress. This
+//   makes it unlikely that we have to wait on the last flip.
+***************************************************************************/
+Status XvMCPutSurface(Display *display,XvMCSurface *surface,
+                      Drawable draw, short srcx, short srcy,
+                      unsigned short srcw, unsigned short srch,
+                      short destx, short desty,
+                      unsigned short destw, unsigned short desth,
+                      int flags)
+{
+    int ret = -1;
+
+    if (!display || !surface)
+        return BadValue;
+
+    ret = (xvmc_driver->put_surface)(display, surface, draw, srcx, srcy,
+	    srcw, srch, destx, desty, destw, desth, flags);
+    if (ret) {
+	XVMC_ERR("put surface fail\n");
+	return BadAccess;
+    }
+
+#if 0
+    i915XvMCContext *pI915XvMC;
+    i915XvMCSurface *pI915Surface;
+    i915XvMCSubpicture *pI915SubPic;
+    I915XvMCCommandBuffer buf;
+
+    // drawableInfo *drawInfo;
+    Status ret;
+
+    if (!display || !surface)
+        return BadValue;
+
+    if (!(pI915Surface = surface->privData))
+        return (error_base + XvMCBadSurface);
+
+    if (!(pI915XvMC = pI915Surface->privContext))
+        return (error_base + XvMCBadSurface);
+
+    PPTHREAD_MUTEX_LOCK(pI915XvMC);
+    /*
+    if (getDRIDrawableInfoLocked(pI915XvMC->drawHash, display,
+                                 pI915XvMC->screen, draw, 0, pI915XvMC->fd, pI915XvMC->hHWContext,
+                                 pI915XvMC->sarea_address, FALSE, &drawInfo, sizeof(*drawInfo))) {
+        PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
+        return BadAccess;
+    }
+    */
+    if (!pI915XvMC->haveXv) {
+        pI915XvMC->xvImage =
+            XvCreateImage(display, pI915XvMC->port, FOURCC_XVMC,
+                          (char *)&buf, pI915Surface->width, pI915Surface->height);
+        pI915XvMC->gc = XCreateGC(display, draw, 0, 0);
+        pI915XvMC->haveXv = 1;
+    }
+
+    pI915XvMC->draw = draw;
+    pI915XvMC->xvImage->data = (char *)&buf;
+
+    buf.command = INTEL_XVMC_COMMAND_DISPLAY;
+    buf.ctxNo = pI915XvMC->ctxno;
+    buf.srfNo = pI915Surface->srfNo;
+    pI915SubPic = pI915Surface->privSubPic;
+    buf.subPicNo = (!pI915SubPic ? 0 : pI915SubPic->srfNo);
+    buf.real_id = FOURCC_YV12;
+
+    XLockDisplay(display);
+
+    if ((ret = XvPutImage(display, pI915XvMC->port, draw, pI915XvMC->gc,
+                          pI915XvMC->xvImage, srcx, srcy, srcw, srch,
+                          destx, desty, destw, desth))) {
+        XUnlockDisplay(display);
+        PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
+
+        return ret;
+    }
+
+    XSync(display, 0);
+    XUnlockDisplay(display);
+    PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
+#endif
+
+    return Success;
+}
+
+/***************************************************************************
+// Function: XvMCSyncSurface
+// Arguments:
+//   display - Connection to the X server
+//   surface - The surface to synchronize
+// Info:
+// Returns: Status
+***************************************************************************/
+Status XvMCSyncSurface(Display *display, XvMCSurface *surface) 
+{
+    Status ret;
+    int stat = 0;
+
+    do {
+        ret = XvMCGetSurfaceStatus(display, surface, &stat);
+    } while (!ret && (stat & XVMC_RENDERING));
+
+    return ret;
+}
+
+/***************************************************************************
+// Function: XvMCFlushSurface
+// Description:
+//   This function commits pending rendering requests to ensure that they
+//   wll be completed in a finite amount of time.
+// Arguments:
+//   display - Connection to X server
+//   surface - Surface to flush
+// Returns: Status
+***************************************************************************/
+Status XvMCFlushSurface(Display * display, XvMCSurface *surface) 
+{
+    return Success;
+}
+
+/***************************************************************************
+// Function: XvMCGetSurfaceStatus
+// Description:
+// Arguments:
+//  display: connection to X server
+//  surface: The surface to query
+//  stat: One of the Following
+//    XVMC_RENDERING - The last XvMCRenderSurface command has not
+//                     completed.
+//    XVMC_DISPLAYING - The surface is currently being displayed or a
+//                     display is pending.
+***************************************************************************/
+Status XvMCGetSurfaceStatus(Display *display, XvMCSurface *surface, int *stat) 
+{
+    int ret = -1;
+
+    if (!display || !surface || !stat)
+        return BadValue;
+
+    ret = (xvmc_driver->get_surface_status)(display, surface, stat);
+    if (ret) {
+	XVMC_ERR("get surface status fail\n");
+	return BadAccess;
+    }
+
+#if 0
+    i915XvMCSurface *pI915Surface;
+    i915XvMCContext *pI915XvMC;
+
+    if (!display || !surface || !stat)
+        return BadValue;
+    
+    *stat = 0;
+
+    if (!(pI915Surface = surface->privData))
+        return (error_base + XvMCBadSurface);
+
+    if (!(pI915XvMC = pI915Surface->privContext))
+        return (error_base + XvMCBadSurface);
+
+    // LOCK_HARDWARE(pI915XvMC);
+    PPTHREAD_MUTEX_LOCK(pI915XvMC);
+    if (pI915Surface->last_flip) {
+        /* This can not happen */
+        if (pI915XvMC->last_flip < pI915Surface->last_flip) {
+            XVMC_ERR("Context last flip is less than surface last flip.");
+            PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
+            return BadValue;
+        }
+
+        /*
+          If the context has 2 or more flips after this surface it
+          cannot be displaying. Don't bother to check.
+        */
+        if (!(pI915XvMC->last_flip > (pI915Surface->last_flip + 1))) {
+            /*
+              If this surface was the last flipped it is either displaying
+              or about to be so don't bother checking.
+            */
+            if (pI915XvMC->last_flip == pI915Surface->last_flip) {
+                *stat |= XVMC_DISPLAYING;
+            }
+        }
+    }
+
+    if (pI915Surface->last_render &&
+        (pI915Surface->last_render > pI915XvMC->sarea->last_dispatch)) {
+        *stat |= XVMC_RENDERING;
+    }
+
+    // UNLOCK_HARDWARE(pI915XvMC);
+    PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
+#endif
+
+    return Success;
+}
+
+/***************************************************************************
+// 
+//  Surface manipulation functions
+//
+***************************************************************************/
+
+/***************************************************************************
+// Function: XvMCHideSurface
+// Description: Stops the display of a surface.
+// Arguments:
+//   display - Connection to the X server.
+//   surface - surface to be hidden.
+//
+// Returns: Status
+***************************************************************************/
+//XXX this seems broken now
+Status XvMCHideSurface(Display *display, XvMCSurface *surface) 
+{
+//    i915XvMCSurface *pI915Surface;
+//    i915XvMCContext *pI915XvMC;
+    int stat = 0, ret;
+
+    if (!display || !surface)
+        return BadValue;
+
+#if 0
+    if (!(pI915Surface = surface->privData))
+        return (error_base + XvMCBadSurface);
+
+    /* Get the associated context pointer */
+    if (!(pI915XvMC = pI915Surface->privContext))
+        return (error_base + XvMCBadSurface);
+#endif
+
+    XvMCSyncSurface(display, surface);
+
+    /*
+      Get the status of the surface, if it is not currently displayed
+      we don't need to worry about it.
+    */
+    if ((ret = XvMCGetSurfaceStatus(display, surface, &stat)) != Success)
+        return ret;
+
+    if (!(stat & XVMC_DISPLAYING))
+        return Success;
+
+    /* FIXME: */
+    return Success;
+}
+
+/***************************************************************************
+//
+// Functions that deal with subpictures
+//
+***************************************************************************/
+
+
+
+/***************************************************************************
+// Function: XvMCCreateSubpicture
+// Description: This creates a subpicture by filling out the XvMCSubpicture
+//              structure passed to it and returning Success.
+// Arguments:
+//   display - Connection to the X server.
+//   context - The context to create the subpicture for.
+//   subpicture - Pre-allocated XvMCSubpicture structure to be filled in.
+//   width - of subpicture
+//   height - of subpicture
+//   xvimage_id - The id describing the XvImage format.
+//
+// Returns: Status
+***************************************************************************/
+Status XvMCCreateSubpicture(Display *display, XvMCContext *context,
+                            XvMCSubpicture *subpicture,
+                            unsigned short width, unsigned short height,
+                            int xvimage_id) 
+{
+    return BadValue;
+}
+
+/***************************************************************************
+// Function: XvMCClearSubpicture
+// Description: Clear the area of the given subpicture to "color".
+//              structure passed to it and returning Success.
+// Arguments:
+//   display - Connection to the X server.
+//   subpicture - Subpicture to clear.
+//   x, y, width, height - rectangle in the subpicture to clear.
+//   color - The data to file the rectangle with.
+//
+// Returns: Status
+***************************************************************************/
+Status XvMCClearSubpicture(Display *display, XvMCSubpicture *subpicture,
+                           short x, short y,
+                           unsigned short width, unsigned short height,
+                           unsigned int color) 
+{
+    return BadValue;
+}
+
+/***************************************************************************
+// Function: XvMCCompositeSubpicture
+// Description: Composite the XvImae on the subpicture. This composit uses
+//              non-premultiplied alpha. Destination alpha is utilized
+//              except for with indexed subpictures. Indexed subpictures
+//              use a simple "replace".
+// Arguments:
+//   display - Connection to the X server.
+//   subpicture - Subpicture to clear.
+//   image - the XvImage to be used as the source of the composite.
+//   srcx, srcy, width, height - The rectangle from the image to be used.
+//   dstx, dsty - location in the subpicture to composite the source.
+//
+// Returns: Status
+***************************************************************************/
+Status XvMCCompositeSubpicture(Display *display, XvMCSubpicture *subpicture,
+                               XvImage *image,
+                               short srcx, short srcy,
+                               unsigned short width, unsigned short height,
+                               short dstx, short dsty) 
+{
+    return BadValue;
+}
+
+
+/***************************************************************************
+// Function: XvMCDestroySubpicture
+// Description: Destroys the specified subpicture.
+// Arguments:
+//   display - Connection to the X server.
+//   subpicture - Subpicture to be destroyed.
+//
+// Returns: Status
+***************************************************************************/
+Status XvMCDestroySubpicture(Display *display, XvMCSubpicture *subpicture) 
+{
+    return BadValue;
+}
+
+
+/***************************************************************************
+// Function: XvMCSetSubpicturePalette
+// Description: Set the subpictures palette
+// Arguments:
+//   display - Connection to the X server.
+//   subpicture - Subpiture to set palette for.
+//   palette - A pointer to an array holding the palette data. The array
+//     is num_palette_entries * entry_bytes in size.
+// Returns: Status
+***************************************************************************/
+
+Status XvMCSetSubpicturePalette(Display *display, XvMCSubpicture *subpicture,
+                                unsigned char *palette) 
+{
+    return BadValue;
+}
+
+/***************************************************************************
+// Function: XvMCBlendSubpicture
+// Description: 
+//    The behavior of this function is different depending on whether
+//    or not the XVMC_BACKEND_SUBPICTURE flag is set in the XvMCSurfaceInfo.
+//    i915 only support frontend behavior.
+//  
+//    XVMC_BACKEND_SUBPICTURE not set ("frontend" behavior):
+//   
+//    XvMCBlendSubpicture is a no-op in this case.
+//   
+// Arguments:
+//   display - Connection to the X server.
+//   subpicture - The subpicture to be blended into the video.
+//   target_surface - The surface to be displayed with the blended subpic.
+//   source_surface - Source surface prior to blending.
+//   subx, suby, subw, subh - The rectangle from the subpicture to use.
+//   surfx, surfy, surfw, surfh - The rectangle in the surface to blend
+//      blend the subpicture rectangle into. Scaling can ocure if 
+//      XVMC_SUBPICTURE_INDEPENDENT_SCALING is set.
+//
+// Returns: Status
+***************************************************************************/
+Status XvMCBlendSubpicture(Display *display, XvMCSurface *target_surface,
+                           XvMCSubpicture *subpicture,
+                           short subx, short suby,
+                           unsigned short subw, unsigned short subh,
+                           short surfx, short surfy,
+                           unsigned short surfw, unsigned short surfh) 
+{
+    return BadValue;
+}
+
+/***************************************************************************
+// Function: XvMCBlendSubpicture2
+// Description: 
+//    The behavior of this function is different depending on whether
+//    or not the XVMC_BACKEND_SUBPICTURE flag is set in the XvMCSurfaceInfo.
+//    i915 only supports frontend blending.
+//  
+//    XVMC_BACKEND_SUBPICTURE not set ("frontend" behavior):
+//   
+//    XvMCBlendSubpicture2 blends the source_surface and subpicture and
+//    puts it in the target_surface.  This does not effect the status of
+//    the source surface but will cause the target_surface to query
+//    XVMC_RENDERING until the blend is completed.
+//   
+// Arguments:
+//   display - Connection to the X server.
+//   subpicture - The subpicture to be blended into the video.
+//   target_surface - The surface to be displayed with the blended subpic.
+//   source_surface - Source surface prior to blending.
+//   subx, suby, subw, subh - The rectangle from the subpicture to use.
+//   surfx, surfy, surfw, surfh - The rectangle in the surface to blend
+//      blend the subpicture rectangle into. Scaling can ocure if 
+//      XVMC_SUBPICTURE_INDEPENDENT_SCALING is set.
+//
+// Returns: Status
+***************************************************************************/
+Status XvMCBlendSubpicture2(Display *display, 
+                            XvMCSurface *source_surface,
+                            XvMCSurface *target_surface,
+                            XvMCSubpicture *subpicture,
+                            short subx, short suby,
+                            unsigned short subw, unsigned short subh,
+                            short surfx, short surfy,
+                            unsigned short surfw, unsigned short surfh)
+{
+    return BadValue;
+}
+
+/***************************************************************************
+// Function: XvMCSyncSubpicture
+// Description: This function blocks until all composite/clear requests on
+//              the subpicture have been complete.
+// Arguments:
+//   display - Connection to the X server.
+//   subpicture - The subpicture to synchronize
+//
+// Returns: Status
+***************************************************************************/
+Status XvMCSyncSubpicture(Display *display, XvMCSubpicture *subpicture) 
+{
+    return BadValue;
+#if 0
+    Status ret;
+    int stat = 0;
+
+    if (!display || !subpicture)
+
+    do {
+        ret = XvMCGetSubpictureStatus(display, subpicture, &stat);
+    } while(!ret && (stat & XVMC_RENDERING));
+
+    return ret;
+#endif
+}
+
+/***************************************************************************
+// Function: XvMCFlushSubpicture
+// Description: This function commits pending composite/clear requests to
+//              ensure that they will be completed in a finite amount of
+//              time.
+// Arguments:
+//   display - Connection to the X server.
+//   subpicture - The subpicture whos compsiting should be flushed
+//
+// Returns: Status
+***************************************************************************/
+Status XvMCFlushSubpicture(Display *display, XvMCSubpicture *subpicture) 
+{
+    return BadValue;
+#if 0
+    i915XvMCSubpicture *pI915Subpicture;
+
+    if (!display || !subpicture)
+        return BadValue;
+
+    if (!(pI915Subpicture = subpicture->privData))
+        return (error_base + XvMCBadSubpicture);
+
+    return Success;
+#endif
+}
+
+/***************************************************************************
+// Function: XvMCGetSubpictureStatus
+// Description: This function gets the current status of a subpicture
+//
+// Arguments:
+//   display - Connection to the X server.
+//   subpicture - The subpicture whos status is being queried
+//   stat - The status of the subpicture. It can be any of the following
+//          OR'd together:
+//          XVMC_RENDERING  - Last composite or clear request not completed
+//          XVMC_DISPLAYING - Suppicture currently being displayed.
+//
+// Returns: Status
+***************************************************************************/
+Status XvMCGetSubpictureStatus(Display *display, XvMCSubpicture *subpicture,
+                               int *stat) 
+{
+    return BadValue;
+#if 0
+    i915XvMCSubpicture *pI915Subpicture;
+    i915XvMCContext *pI915XvMC;
+
+    if (!display || !subpicture || stat)
+        return BadValue;
+
+    *stat = 0;
+
+    if (!(pI915Subpicture = subpicture->privData))
+        return (error_base + XvMCBadSubpicture);
+
+    if (!(pI915XvMC = pI915Subpicture->privContext))
+        return (error_base + XvMCBadSubpicture);
+
+    // LOCK_HARDWARE(pI915XvMC);
+    PPTHREAD_MUTEX_LOCK(pI915XvMC);
+    /* FIXME: */
+    if (pI915Subpicture->last_render &&
+        (pI915Subpicture->last_render > pI915XvMC->sarea->last_dispatch)) {
+        *stat |= XVMC_RENDERING;
+    }
+
+    // UNLOCK_HARDWARE(pI915XvMC);
+    PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
+    return Success;
+#endif
+}
+
+/***************************************************************************
+// Function: XvMCQueryAttributes
+// Description: An array of XvAttributes of size "number" is returned by
+//   this function. If there are no attributes, NULL is returned and number
+//   is set to 0. The array may be freed with xfree().
+//
+// Arguments:
+//   display - Connection to the X server.
+//   context - The context whos attributes we are querying.
+//   number - The returned number of recognized atoms
+//
+// Returns:
+//  An array of XvAttributes.
+***************************************************************************/
+XvAttribute *XvMCQueryAttributes(Display *display, XvMCContext *context,
+                                 int *number) 
+{
+    /* now XvMC has no extra attribs than Xv */
+    *number = 0;
+    return NULL;
+}
+
+/***************************************************************************
+// Function: XvMCSetAttribute
+// Description: This function sets a context-specific attribute.
+//
+// Arguments:
+//   display - Connection to the X server.
+//   context - The context whos attributes we are querying.
+//   attribute - The X atom of the attribute to be changed.
+//   value - The new value for the attribute.
+//
+// Returns:
+//  Status
+***************************************************************************/
+Status XvMCSetAttribute(Display *display, XvMCContext *context,
+                        Atom attribute, int value)
+{
+    return Success;
+}
+
+/***************************************************************************
+// Function: XvMCGetAttribute
+// Description: This function queries a context-specific attribute and
+//   returns the value.
+//
+// Arguments:
+//   display - Connection to the X server.
+//   context - The context whos attributes we are querying.
+//   attribute - The X atom of the attribute to be queried
+//   value - The returned attribute value
+//
+// Returns:
+//  Status
+// Notes:
+***************************************************************************/
+Status XvMCGetAttribute(Display *display, XvMCContext *context,
+                        Atom attribute, int *value) 
+{
+    return Success;
+}
diff --git a/src/xvmc/intel_xvmc.h b/src/xvmc/intel_xvmc.h
index 0726be4..1d6ff71 100644
--- a/src/xvmc/intel_xvmc.h
+++ b/src/xvmc/intel_xvmc.h
@@ -2,12 +2,31 @@
 #ifndef INTEL_XVMC_H
 #define INTEL_XVMC_H
 
-#include "xf86drm.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <string.h>
+#include <assert.h>
+#include <signal.h>
+
+#include <xf86drm.h>
 #include "i830_common.h"
 #include "i830_hwmc.h"
 #include <X11/Xlibint.h>
 #include <X11/Xutil.h>
-#include <signal.h>
+#include <fourcc.h>
+#include <X11/extensions/Xv.h>
+#include <X11/extensions/Xvlib.h>
+#include <X11/extensions/XvMC.h>
+#include <X11/extensions/XvMClib.h>
+#include <drm_sarea.h>
+
+#include "xf86dri.h"
+#include "driDrawable.h"
 
 #define DEBUG 0
 
@@ -35,7 +54,7 @@
   when a HW independent libXvMC is created.
 */
 extern Status _xvmc_create_context(Display *dpy, XvMCContext *context,
-				   int *priv_count, uint **priv_data);
+				   int *priv_count, CARD32 **priv_data);
 
 extern Status _xvmc_destroy_context(Display *dpy, XvMCContext *context);
 
@@ -52,4 +71,44 @@ extern Status  _xvmc_create_subpicture(Display *dpy, XvMCContext *context,
 extern Status   _xvmc_destroy_subpicture(Display *dpy,
 					 XvMCSubpicture *subpicture);
 
+
+struct _intel_xvmc_driver {
+    int type;			/* hw xvmc type - i830_hwmc.h */
+    int screen;			/* current screen num*/
+#if 0
+    drm_handle_t hsarea;	/* DRI open connect */
+    unsigned int sarea_size;
+    drmAddress sarea_address;
+#endif
+    char busID[32];
+    int fd;			/* drm file handler */
+    void *private;
+    /* XXX: api hooks */
+    int (*init)(/*XXX*/);
+    void (*fini)(/*XXX*/);
+    int (*create_context)(Display* display, XvMCContext *context, int priv_count, CARD32 *priv_data);
+    int (*destroy_context)(Display* display, XvMCContext *context);
+    int (*create_surface)(Display* display, XvMCContext *context, XvMCSurface *surface);
+    int (*destroy_surface)(Display* display, XvMCSurface *surface);
+    int (*render_surface)(Display *display, XvMCContext *context,
+	    unsigned int picture_structure,
+	    XvMCSurface *target_surface,
+	    XvMCSurface *past_surface,
+	    XvMCSurface *future_surface,
+	    unsigned int flags,
+	    unsigned int num_macroblocks,
+	    unsigned int first_macroblock,
+	    XvMCMacroBlockArray *macroblock_array,
+	    XvMCBlockArray *blocks);
+    int (*put_surface)(Display *display,XvMCSurface *surface,
+	    Drawable draw, short srcx, short srcy,
+	    unsigned short srcw, unsigned short srch,
+	    short destx, short desty,
+	    unsigned short destw, unsigned short desth,
+	    int flags);
+    int (*get_surface_status)(Display *display, XvMCSurface *surface, int *stat);
+};
+
+extern struct _intel_xvmc_driver i915_xvmc_mc_driver;
+
 #endif
commit cc892d1ba1d87d08bdd04f857efc6b8f64620018
Merge: b52ce0b... fd97edb...
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Mon Oct 15 22:09:14 2007 +0800

    Merge branch 'xvmc' of git+ssh://zhen@people.freedesktop.org/~zhen/xf86-video-intel into xvmc

commit b52ce0bd178c268d20334e2be8fad46037e47499
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Mon Oct 8 22:56:44 2007 +0800

    use field name to initialize i915 xvmc driver

diff --git a/src/i915_hwmc.c b/src/i915_hwmc.c
index 2869aaa..7a62076 100644
--- a/src/i915_hwmc.c
+++ b/src/i915_hwmc.c
@@ -883,11 +883,10 @@ static void i915_xvmc_fini(ScrnInfoPtr pScrn)
 
 /* new xvmc driver interface */
 struct intel_xvmc_driver i915_xvmc_driver = {
-    "i915_xvmc",
-    &pAdapt,
-    XVMC_DRIVER_MPEG2_MC,
-    i915_xvmc_init,
-    i915_xvmc_fini,
-    i915_xvmc_putimage_size,
-    NULL
+    .name	= "i915_xvmc",
+    .adaptor	= &pAdapt,
+    .flag	= XVMC_DRIVER_MPEG2_MC,
+    .init	= i915_xvmc_init,
+    .fini	= i915_xvmc_fini,
+    .putimage_size = i915_xvmc_putimage_size,
 };
commit e0fb228401b10ea4281eee48497bf1d584999705
Merge: 84d7b2b... 9e770bf...
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Mon Oct 8 22:45:11 2007 +0800

    Merge branch 'master' into xvmc
    
    Conflicts:
    
    	src/i830_driver.c

commit fd97edb62463e50a1860290d54684a68d5490bdc
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Mon Oct 8 16:13:26 2007 +0800

    move some definition out of i915 specific header

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 60cfe24..4d57dce 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -198,6 +198,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "i830_bios.h"
 
 #ifdef XvMCExtension
+#define _INTEL_XVMC_SERVER_
 #include "i830_hwmc.h"
 #endif
 
diff --git a/src/i830_hwmc.c b/src/i830_hwmc.c
index 575bdbc..432733c 100644
--- a/src/i830_hwmc.c
+++ b/src/i830_hwmc.c
@@ -28,6 +28,7 @@
 #include "config.h"
 #endif
 
+#define _INTEL_XVMC_SERVER_
 #include "i830.h"
 #include "i830_hwmc.h"
 
diff --git a/src/i830_hwmc.h b/src/i830_hwmc.h
index 199a92a..60a4978 100644
--- a/src/i830_hwmc.h
+++ b/src/i830_hwmc.h
@@ -27,6 +27,16 @@
 #ifndef I830_HWMC_H
 #define I830_HWMC_H
 
+#define FOURCC_XVMC     (('C' << 24) + ('M' << 16) + ('V' << 8) + 'X')
+
+/*
+ * Commands that client submits through XvPutImage:
+ */
+
+#define INTEL_XVMC_COMMAND_DISPLAY      0x00
+#define INTEL_XVMC_COMMAND_UNDISPLAY    0x01
+
+#ifdef _INTEL_XVMC_SERVER_
 #include <xf86xvmc.h>
 
 #define XVMC_DRIVER_MPEG2_MC    0x0001
@@ -55,5 +65,6 @@ extern Bool intel_xvmc_driver_init(ScreenPtr, XF86VideoAdaptorPtr);
 extern Bool intel_xvmc_screen_init(ScreenPtr);
 extern void intel_xvmc_finish(ScrnInfoPtr);
 extern int intel_xvmc_putimage_size(ScrnInfoPtr);
+#endif
 
 #endif
diff --git a/src/i830_video.c b/src/i830_video.c
index 09ba806..63e8618 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -75,6 +75,7 @@
 #include "fourcc.h"
 
 #ifdef XvMCExtension
+#define _INTEL_XVMC_SERVER_
 #include "i830_hwmc.h"
 #include "i915_hwmc.h"
 #endif
diff --git a/src/i915_hwmc.c b/src/i915_hwmc.c
index 1e204ba..e0446ba 100644
--- a/src/i915_hwmc.c
+++ b/src/i915_hwmc.c
@@ -55,6 +55,7 @@
 #include "xf86xvpriv.h"
 #endif
 
+#define _INTEL_XVMC_SERVER_
 #include "i830_hwmc.h"
 #include "i915_hwmc.h"
 
@@ -830,7 +831,7 @@ static int I915XvMCPutImage(ScrnInfoPtr pScrn, short src_x, short src_y,
     if (pI830->XvMCEnabled) {
         if (FOURCC_XVMC == id) {
             switch (i915XvMCData->command) {
-            case I915_XVMC_COMMAND_DISPLAY:
+            case INTEL_XVMC_COMMAND_DISPLAY:
 		if ((i915XvMCData->srfNo >= I915_XVMC_MAX_SURFACES) ||
 			!pXvMC->surfaces[i915XvMCData->srfNo] ||
 			!pXvMC->sfprivs[i915XvMCData->srfNo]) {
diff --git a/src/i915_hwmc.h b/src/i915_hwmc.h
index 597d30c..21964cb 100644
--- a/src/i915_hwmc.h
+++ b/src/i915_hwmc.h
@@ -33,18 +33,9 @@
 #define SIZE_YUV420(w, h)       (h * (STRIDE(w) + STRIDE(w >> 1)))
 #define SIZE_XX44(w, h)         (h * STRIDE(w))
 
-#define FOURCC_XVMC     (('C' << 24) + ('M' << 16) + ('V' << 8) + 'X')
-
 #define I915_NUM_XVMC_ATTRIBUTES       0x02
 #define I915_XVMC_VALID 0x80000000
 
-/*
- * Commands that client submits through XvPutImage:
- */
-
-#define I915_XVMC_COMMAND_DISPLAY      0x00
-#define I915_XVMC_COMMAND_UNDISPLAY    0x01
-
 typedef struct
 {
     unsigned int command;
diff --git a/src/xvmc/I915XvMC.c b/src/xvmc/I915XvMC.c
index 94b5026..59d5730 100644
--- a/src/xvmc/I915XvMC.c
+++ b/src/xvmc/I915XvMC.c
@@ -45,7 +45,6 @@
 #include <xf86drm.h>
 #include <drm_sarea.h>
 
-#include "intel_xvmc.h"
 #include "I915XvMC.h"
 #include "i915_structs.h"
 #include "i915_program.h"
@@ -2524,7 +2523,7 @@ Status XvMCPutSurface(Display *display,XvMCSurface *surface,
     pI915XvMC->draw = draw;
     pI915XvMC->xvImage->data = (char *)&buf;
 
-    buf.command = I915_XVMC_COMMAND_DISPLAY;
+    buf.command = INTEL_XVMC_COMMAND_DISPLAY;
     buf.ctxNo = pI915XvMC->ctxno;
     buf.srfNo = pI915Surface->srfNo;
     pI915SubPic = pI915Surface->privSubPic;
diff --git a/src/xvmc/I915XvMC.h b/src/xvmc/I915XvMC.h
index 78aea7d..d122bcc 100644
--- a/src/xvmc/I915XvMC.h
+++ b/src/xvmc/I915XvMC.h
@@ -31,12 +31,8 @@
 /* #define XVMC_DEBUG(x) do {x; }while(0); */
 #define XVMC_DEBUG(x)
 
-#include "xf86drm.h"
-#include "i830_common.h"
+#include "intel_xvmc.h"
 #include "i915_hwmc.h"
-#include <X11/Xlibint.h>
-#include <X11/Xutil.h>
-#include <signal.h>
 
 #define I915_SUBPIC_PALETTE_SIZE        16
 #define MAX_SUBCONTEXT_LEN              1024
@@ -163,29 +159,4 @@ typedef struct _i915XvMCSurface {
                                          * displaying. NULL if none. */
 } i915XvMCSurface;
 
-/* Subpicture fourcc */
-#define FOURCC_IA44 0x34344149
-
-/*
-  Definitions for temporary wire protocol hooks to be replaced
-  when a HW independent libXvMC is created.
-*/
-extern Status _xvmc_create_context(Display *dpy, XvMCContext *context,
-				   int *priv_count, uint **priv_data);
-
-extern Status _xvmc_destroy_context(Display *dpy, XvMCContext *context);
-
-extern Status _xvmc_create_surface(Display *dpy, XvMCContext *context,
-				   XvMCSurface *surface, int *priv_count,
-				   uint **priv_data);
-
-extern Status _xvmc_destroy_surface(Display *dpy, XvMCSurface *surface);
-
-extern Status  _xvmc_create_subpicture(Display *dpy, XvMCContext *context,
-				       XvMCSubpicture *subpicture,
-				       int *priv_count, uint **priv_data);
-
-extern Status   _xvmc_destroy_subpicture(Display *dpy,
-					 XvMCSubpicture *subpicture);
-
 #endif /* _I915XVMC_H */
diff --git a/src/xvmc/intel_xvmc.h b/src/xvmc/intel_xvmc.h
index 072a0f4..0726be4 100644
--- a/src/xvmc/intel_xvmc.h
+++ b/src/xvmc/intel_xvmc.h
@@ -2,6 +2,13 @@
 #ifndef INTEL_XVMC_H
 #define INTEL_XVMC_H
 
+#include "xf86drm.h"
+#include "i830_common.h"
+#include "i830_hwmc.h"
+#include <X11/Xlibint.h>
+#include <X11/Xutil.h>
+#include <signal.h>
+
 #define DEBUG 0
 
 #define XVMC_ERR(s, arg...)					\
@@ -20,4 +27,29 @@
 	    fprintf(stderr, "intel_xvmc debug: " s "\n", ##arg);	\
     } while (0)
 
+/* Subpicture fourcc */
+#define FOURCC_IA44 0x34344149
+
+/*
+  Definitions for temporary wire protocol hooks to be replaced
+  when a HW independent libXvMC is created.
+*/
+extern Status _xvmc_create_context(Display *dpy, XvMCContext *context,
+				   int *priv_count, uint **priv_data);
+
+extern Status _xvmc_destroy_context(Display *dpy, XvMCContext *context);
+
+extern Status _xvmc_create_surface(Display *dpy, XvMCContext *context,
+				   XvMCSurface *surface, int *priv_count,
+				   uint **priv_data);
+
+extern Status _xvmc_destroy_surface(Display *dpy, XvMCSurface *surface);
+
+extern Status  _xvmc_create_subpicture(Display *dpy, XvMCContext *context,
+				       XvMCSubpicture *subpicture,
+				       int *priv_count, uint **priv_data);
+
+extern Status   _xvmc_destroy_subpicture(Display *dpy,
+					 XvMCSubpicture *subpicture);
+
 #endif
commit 3a2b5222341b37322b788e329c2b9006dc14ecfd
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Mon Oct 8 15:46:11 2007 +0800

    Temp work around ttm allocation for xvmc, which should be fixed later.

diff --git a/src/i915_hwmc.c b/src/i915_hwmc.c
index 2869aaa..1e204ba 100644
--- a/src/i915_hwmc.c
+++ b/src/i915_hwmc.c
@@ -350,9 +350,13 @@ static void i915_unmap_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *ctxp
 static Bool i915_allocate_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *ctxpriv)
 {
     I830Ptr pI830 = I830PTR(pScrn);
-    int flags = (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830) || IS_I945GM(pI830)) ? 
-        (ALIGN_BOTH_ENDS | NEED_PHYSICAL_ADDR) : ALIGN_BOTH_ENDS;
-    
+    /* FIXME xvmc ttm */
+    int flags = ALIGN_BOTH_ENDS | NEED_LIFETIME_FIXED;
+
+    if (IS_I915G(pI830) || IS_I915GM(pI830) ||
+	    IS_I945G(pI830) || IS_I945GM(pI830))
+        flags |= NEED_PHYSICAL_ADDR;
+
     if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC]Static Indirect State",
                                   &(ctxpriv->mcStaticIndirectState), 4 * 1024,
                                   flags)) {
@@ -383,15 +387,16 @@ static Bool i915_allocate_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *c
         return FALSE;
     }
 
+    /* XXX xvmc ttm */
     if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC]Correction Data Buffer", 
                                    &(ctxpriv->mcCorrdata), 512 * 1024,
-                                   ALIGN_BOTH_ENDS)) {
+                                   ALIGN_BOTH_ENDS | NEED_LIFETIME_FIXED)) {
         return FALSE;
     }
 
     if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC]batch buffer",
                                    &(ctxpriv->mcBatchBuffer), 8 * 1024,
-                                   ALIGN_BOTH_ENDS)) {
+                                   ALIGN_BOTH_ENDS | NEED_LIFETIME_FIXED)) {
         return FALSE;
     }
 
@@ -621,9 +626,10 @@ static int I915XvMCCreateSurface(ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf,
     ctx = pSurf->context;
     bufsize = SIZE_YUV420(ctx->width, ctx->height);
 
+    /* FIXME xvmc ttm */
     if (!i830_allocate_xvmc_buffer(pScrn, "XvMC surface", 
                                    &(sfpriv->surface), bufsize,
-                                   ALIGN_BOTH_ENDS)) {
+                                   ALIGN_BOTH_ENDS | NEED_LIFETIME_FIXED)) {
         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
                    "[XvMC] I915XvMCCreateSurface: Failed to allocate XvMC surface space!\n");
         xfree(sfpriv);
commit 84d7b2b955107264b67526a04028a8b79d8804e3
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Sat Sep 29 19:41:15 2007 +0800

    rename xvmc init function names

diff --git a/src/i830_hwmc.c b/src/i830_hwmc.c
index 5cc37be..575bdbc 100644
--- a/src/i830_hwmc.c
+++ b/src/i830_hwmc.c
@@ -72,7 +72,7 @@ void intel_xvmc_finish(ScrnInfoPtr pScrn)
     (*xvmc_driver->fini)(pScrn);
 }
 
-Bool intel_xvmc_xv_init(ScreenPtr pScreen, XF86VideoAdaptorPtr xv_adaptor)
+Bool intel_xvmc_driver_init(ScreenPtr pScreen, XF86VideoAdaptorPtr xv_adaptor)
 {
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
 
@@ -88,7 +88,7 @@ Bool intel_xvmc_xv_init(ScreenPtr pScreen, XF86VideoAdaptorPtr xv_adaptor)
     return TRUE;
 }
 
-Bool intel_xvmc_init(ScreenPtr pScreen)
+Bool intel_xvmc_screen_init(ScreenPtr pScreen)
 {
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
     I830Ptr pI830 = I830PTR(pScrn);
diff --git a/src/i830_hwmc.h b/src/i830_hwmc.h
index e295da6..199a92a 100644
--- a/src/i830_hwmc.h
+++ b/src/i830_hwmc.h
@@ -51,8 +51,8 @@ extern struct intel_xvmc_driver i915_xvmc_driver;
 
 extern Bool intel_xvmc_set_driver(struct intel_xvmc_driver *);
 extern Bool intel_xvmc_probe(ScrnInfoPtr);
-extern Bool intel_xvmc_xv_init(ScreenPtr, XF86VideoAdaptorPtr);
-extern Bool intel_xvmc_init(ScreenPtr);
+extern Bool intel_xvmc_driver_init(ScreenPtr, XF86VideoAdaptorPtr);
+extern Bool intel_xvmc_screen_init(ScreenPtr);
 extern void intel_xvmc_finish(ScrnInfoPtr);
 extern int intel_xvmc_putimage_size(ScrnInfoPtr);
 
diff --git a/src/i830_video.c b/src/i830_video.c
index 65cd2d5..09ba806 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -626,7 +626,7 @@ I830InitVideo(ScreenPtr pScreen)
 #ifdef XvMCExtension
     if (intel_xvmc_probe(pScrn)) {
 	if (texturedAdaptor)
-	    ret = intel_xvmc_xv_init(pScreen, texturedAdaptor);
+	    ret = intel_xvmc_driver_init(pScreen, texturedAdaptor);
     }
 #endif
 
@@ -635,7 +635,7 @@ I830InitVideo(ScreenPtr pScreen)
 
 #ifdef XvMCExtension
     if (ret)
-	intel_xvmc_init(pScreen);
+	intel_xvmc_screen_init(pScreen);
 #endif
     xfree(adaptors);
 }
commit 64188246bb25e95a916ebb8a50a09298e56d91d9
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Wed Sep 26 15:48:19 2007 +0800

    clean up old i915 xvmc function declare

diff --git a/src/i830.h b/src/i830.h
index b45be22..90dc186 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -669,8 +669,11 @@ extern long I830CheckAvailableMemory(ScrnInfoPtr pScrn);
 Bool i830_allocate_2d_memory(ScrnInfoPtr pScrn);
 Bool i830_allocate_texture_memory(ScrnInfoPtr pScrn);
 Bool i830_allocate_3d_memory(ScrnInfoPtr pScrn);
+#ifdef XvMCExtension
 Bool i830_allocate_xvmc_buffer(ScrnInfoPtr pScrn, const char *name,
                                i830_memory **buffer, unsigned long size, int flags);
+#endif
+
 extern Bool I830IsPrimary(ScrnInfoPtr pScrn);
 
 extern Bool I830I2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, int i2c_reg,
@@ -767,9 +770,4 @@ extern const int I830CopyROP[16];
 #define QUIRK_IGNORE_MACMINI_LVDS 	0x00000004
 extern void i830_fixup_devices(ScrnInfoPtr);
 
-/* i915 XvMC */
-Bool I915XvMCInit(ScreenPtr, XF86VideoAdaptorPtr);
-Bool I915XvMCScreenInit(ScreenPtr);
-unsigned long I915XvMCPutImageSize(ScrnInfoPtr);
-
 #endif /* _I830_H_ */
commit 320b7f08f457455f1d16b4c36d149bdc3f6ceead
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Wed Sep 26 15:02:33 2007 +0800

    Revert to origin xvmc setup steps
    
    We have to grab xvadaptor's PutImage earlier than
    xv init, otherwise no chance to do that..

diff --git a/src/i830_hwmc.c b/src/i830_hwmc.c
index b651072..5cc37be 100644
--- a/src/i830_hwmc.c
+++ b/src/i830_hwmc.c
@@ -58,8 +58,6 @@ Bool intel_xvmc_probe(ScrnInfoPtr pScrn)
 	else
 	    ret = intel_xvmc_set_driver(&i965_xvmc_driver);
 	 */
-	if (ret)
-	    pI830->XvMCEnabled = TRUE;
     } else {
 	ErrorF("Your chipset doesn't support XvMC.\n");
 	return FALSE;
@@ -74,10 +72,9 @@ void intel_xvmc_finish(ScrnInfoPtr pScrn)
     (*xvmc_driver->fini)(pScrn);
 }
 
-Bool intel_xvmc_init(ScreenPtr pScreen, XF86VideoAdaptorPtr xv_adaptor)
+Bool intel_xvmc_xv_init(ScreenPtr pScreen, XF86VideoAdaptorPtr xv_adaptor)
 {
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-    I830Ptr pI830 = I830PTR(pScrn);
 
     if (!xvmc_driver) {
 	ErrorF("Failed to probe XvMC driver.\n");
@@ -88,11 +85,22 @@ Bool intel_xvmc_init(ScreenPtr pScreen, XF86VideoAdaptorPtr xv_adaptor)
 	ErrorF("XvMC driver initialize failed.\n");
 	return FALSE;
     }
+    return TRUE;
+}
+
+Bool intel_xvmc_init(ScreenPtr pScreen)
+{
+    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+    I830Ptr pI830 = I830PTR(pScrn);
+
+    if (!xvmc_driver)
+	return FALSE;
 
     if (xf86XvMCScreenInit(pScreen, 1, &xvmc_driver->adaptor)) {
 	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 		"[XvMC] %s driver initialized.\n",
 		xvmc_driver->name);
+	pI830->XvMCEnabled = TRUE;
     } else {
 	intel_xvmc_finish(pScrn);
 	pI830->XvMCEnabled = FALSE;
diff --git a/src/i830_hwmc.h b/src/i830_hwmc.h
index 539621b..e295da6 100644
--- a/src/i830_hwmc.h
+++ b/src/i830_hwmc.h
@@ -51,7 +51,8 @@ extern struct intel_xvmc_driver i915_xvmc_driver;
 
 extern Bool intel_xvmc_set_driver(struct intel_xvmc_driver *);
 extern Bool intel_xvmc_probe(ScrnInfoPtr);
-extern Bool intel_xvmc_init(ScreenPtr, XF86VideoAdaptorPtr);
+extern Bool intel_xvmc_xv_init(ScreenPtr, XF86VideoAdaptorPtr);
+extern Bool intel_xvmc_init(ScreenPtr);
 extern void intel_xvmc_finish(ScrnInfoPtr);
 extern int intel_xvmc_putimage_size(ScrnInfoPtr);
 
diff --git a/src/i830_video.c b/src/i830_video.c
index 050f808..65cd2d5 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -560,6 +560,7 @@ I830InitVideo(ScreenPtr pScreen)
     XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL;
     XF86VideoAdaptorPtr overlayAdaptor = NULL, texturedAdaptor = NULL;
     int num_adaptors;
+    Bool ret = FALSE;
 
 #if 0
     {
@@ -622,15 +623,19 @@ I830InitVideo(ScreenPtr pScreen)
 	}
 	I830InitOffscreenImages(pScreen);
     }
+#ifdef XvMCExtension
+    if (intel_xvmc_probe(pScrn)) {
+	if (texturedAdaptor)
+	    ret = intel_xvmc_xv_init(pScreen, texturedAdaptor);
+    }
+#endif
 
     if (num_adaptors)
 	xf86XVScreenInit(pScreen, adaptors, num_adaptors);
 
 #ifdef XvMCExtension
-    if (intel_xvmc_probe(pScrn)) {
-	if (texturedAdaptor)
-	    intel_xvmc_init(pScreen, texturedAdaptor);
-    }
+    if (ret)
+	intel_xvmc_init(pScreen);
 #endif
     xfree(adaptors);
 }
commit 1e0ff38f44e3b5a8b4a5d509c7faa266270d522c
Author: Hong Liu <hong.liu at intel.com>
Date:   Thu Sep 20 11:28:52 2007 +0800

    Fix pixmap offset
    
    Use consistent interface for counting pixmap offset.

diff --git a/src/i830_exa.c b/src/i830_exa.c
index 273c626..8850382 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -112,9 +112,7 @@ i830_pixmap_tiled(PixmapPtr pPixmap)
     I830Ptr pI830 = I830PTR(pScrn);
     unsigned long offset;
 
-    /* Don't use exaGetPixmapOffset becuase we might be called from XAA code. */
-    offset = (long)pPixmap->devPrivate.ptr -
-	(long)pI830->FbBase;
+    offset = intel_get_pixmap_offset(pPixmap);
     if (offset == pI830->front_buffer->offset &&
 	pI830->front_buffer->tiling != TILE_NONE)
     {
diff --git a/src/i830_video.c b/src/i830_video.c
index b0d42f0..050f808 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2444,9 +2444,10 @@ I830PutImage(ScrnInfoPtr pScrn,
     }
 #endif
 
-    if (((char *)pPixmap->devPrivate.ptr < (char *)pI830->FbBase) ||
-	((char *)pPixmap->devPrivate.ptr >= (char *)pI830->FbBase +
-	 pI830->FbMapSize)) {
+    if (!pI830->useEXA &&
+	    (((char *)pPixmap->devPrivate.ptr < (char *)pI830->FbBase) ||
+	     ((char *)pPixmap->devPrivate.ptr >= (char *)pI830->FbBase +
+	      pI830->FbMapSize))) {
 	/* If the pixmap wasn't in framebuffer, then we have no way in XAA to
 	 * force it there.  So, we simply refuse to draw and fail.
 	 */
diff --git a/src/i915_video.c b/src/i915_video.c
index a6447b1..00494a7 100644
--- a/src/i915_video.c
+++ b/src/i915_video.c
@@ -127,8 +127,8 @@ I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
    /* front buffer, pitch, offset */
    OUT_RING(_3DSTATE_BUF_INFO_CMD);
    OUT_RING(BUF_3D_ID_COLOR_BACK | BUF_3D_USE_FENCE |
-	    BUF_3D_PITCH(pPixmap->devKind));
-   OUT_RING(BUF_3D_ADDR((long)pPixmap->devPrivate.ptr - (long)pI830->FbBase));
+	    BUF_3D_PITCH(intel_get_pixmap_pitch(pPixmap)));
+   OUT_RING(BUF_3D_ADDR(intel_get_pixmap_offset(pPixmap)));
    ADVANCE_LP_RING();
 
    if (!planar) {
diff --git a/src/i965_video.c b/src/i965_video.c
index 6ed7f01..0357270 100644
--- a/src/i965_video.c
+++ b/src/i965_video.c
@@ -371,13 +371,12 @@ I965DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
     dest_surf_state->ss0.mipmap_layout_mode = 0;
     dest_surf_state->ss0.render_cache_read_mode = 0;
 
-    dest_surf_state->ss1.base_addr = (long)pPixmap->devPrivate.ptr -
-	(long)pI830->FbBase;
+    dest_surf_state->ss1.base_addr = intel_get_pixmap_offset(pPixmap);
     dest_surf_state->ss2.height = pScrn->virtualY - 1;
     dest_surf_state->ss2.width = pScrn->virtualX - 1;
     dest_surf_state->ss2.mip_count = 0;
     dest_surf_state->ss2.render_target_rotation = 0;
-    dest_surf_state->ss3.pitch = pPixmap->devKind - 1;
+    dest_surf_state->ss3.pitch = intel_get_pixmap_pitch(pPixmap) - 1;
     dest_surf_state->ss3.tiled_surface = i830_pixmap_tiled(pPixmap);
     dest_surf_state->ss3.tile_walk = 0; /* TileX */
 
commit 85e4bd109464a4d90856e17bc960872eeaebc2ad
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Wed Sep 26 14:32:46 2007 +0800

    Log xvmc driver name

diff --git a/src/i830_hwmc.c b/src/i830_hwmc.c
index 903acb8..b651072 100644
--- a/src/i830_hwmc.c
+++ b/src/i830_hwmc.c
@@ -91,7 +91,8 @@ Bool intel_xvmc_init(ScreenPtr pScreen, XF86VideoAdaptorPtr xv_adaptor)
 
     if (xf86XvMCScreenInit(pScreen, 1, &xvmc_driver->adaptor)) {
 	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-		"[XvMC] Initialized XvMC.\n");
+		"[XvMC] %s driver initialized.\n",
+		xvmc_driver->name);
     } else {
 	intel_xvmc_finish(pScrn);
 	pI830->XvMCEnabled = FALSE;
commit e58b76a24a29e0a502650807de81e650e5dc184d
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Wed Sep 26 14:40:04 2007 +0800

    clean up err report
    
    Still need to clean up return value for XvMC API

diff --git a/src/xvmc/I915XvMC.c b/src/xvmc/I915XvMC.c
index 22718de..94b5026 100644
--- a/src/xvmc/I915XvMC.c
+++ b/src/xvmc/I915XvMC.c
@@ -45,6 +45,7 @@
 #include <xf86drm.h>
 #include <drm_sarea.h>
 
+#include "intel_xvmc.h"
 #include "I915XvMC.h"
 #include "i915_structs.h"
 #include "i915_program.h"
@@ -124,8 +125,7 @@ _STATIC_ int findOverlap(unsigned int width, unsigned int height,
 
 _STATIC_ __inline__ void renderError(void) 
 {
-    printf("Invalid Macroblock Parameters found.\n");
-    return;
+    XVMC_ERR("Invalid Macroblock Parameters found.");
 }
 
 _STATIC_ void I915XvMCContendedLock(i915XvMCContext *pI915XvMC, drmLockFlags flags)
@@ -1105,7 +1105,7 @@ _STATIC_ void i915_mc_invalidate_subcontext_buffers(XvMCContext *context, unsign
         size += sizeof(*psc);
 
     if (size == sizeof(*load_indirect)) {
-        printf("There must be at least one bit set\n");
+        XVMC_ERR("There must be at least one bit set\n");
         return;
     }
 
@@ -1771,7 +1771,7 @@ Status XvMCCreateContext(Display *display, XvPortID port,
 
     if (!(flags & XVMC_DIRECT)) {
         /* Indirect */
-        printf("Indirect Rendering not supported! Using Direct.\n");
+        XVMC_ERR("Indirect Rendering not supported! Using Direct.");
         return BadAccess;
     }
 
@@ -1802,13 +1802,13 @@ Status XvMCCreateContext(Display *display, XvPortID port,
     XLockDisplay(display);
     if (!XvMCQueryExtension(display, &event_base, &error_base)) {
         XUnlockDisplay(display);
-        printf("XvMCExtension is not available!\n");
+        XVMC_ERR("XvMCExtension is not available!");
         return BadAlloc;
     }
     /* Verify XvMC version */
     ret = XvMCQueryVersion(display, &major, &minor);
     if (ret) {
-        printf("XvMCQueryVersion Failed, unable to determine protocol version\n");
+        XVMC_ERR("XvMCQueryVersion Failed, unable to determine protocol version.");
     }
     XUnlockDisplay(display);
     /* FIXME: Check Major and Minor here */
@@ -1816,14 +1816,14 @@ Status XvMCCreateContext(Display *display, XvPortID port,
     /* Allocate private Context data */
     context->privData = (void *)calloc(1, sizeof(i915XvMCContext));
     if (!context->privData) {
-        printf("Unable to allocate resources for XvMC context.\n");
+        XVMC_ERR("Unable to allocate resources for XvMC context.");
         return BadAlloc;
     }
     pI915XvMC = (i915XvMCContext *)context->privData;
 
     /* Check for drm */
     if (!drmAvailable()) {
-        printf("Direct Rendering is not avilable on this system!\n");
+        XVMC_ERR("Direct Rendering is not avilable on this system!");
         free(pI915XvMC);
         context->privData = NULL;
         return BadAccess;
@@ -1836,7 +1836,7 @@ Status XvMCCreateContext(Display *display, XvPortID port,
     XLockDisplay(display);
     if ((ret = _xvmc_create_context(display, context, &priv_count, &priv_data))) {
         XUnlockDisplay(display);
-        printf("Unable to create XvMC Context.\n");
+        XVMC_ERR("Unable to create XvMC Context.");
         free(pI915XvMC);
         context->privData = NULL;
         return ret;
@@ -1844,8 +1844,8 @@ Status XvMCCreateContext(Display *display, XvPortID port,
     XUnlockDisplay(display);
 
     if (priv_count != (sizeof(I915XvMCCreateContextRec) >> 2)) {
-        printf("_xvmc_create_context() returned incorrect data size!\n");
-        printf("\tExpected %d, got %d\n", 
+        XVMC_ERR("_xvmc_create_context() returned incorrect data size!");
+        XVMC_INFO("\tExpected %d, got %d",
                (int)(sizeof(I915XvMCCreateContextRec) >> 2),priv_count);
         _xvmc_destroy_context(display, context);
         free(priv_data);
@@ -1904,8 +1904,7 @@ Status XvMCCreateContext(Display *display, XvPortID port,
                                             &isCapable);
     if (!ret || !isCapable) {
         XUnlockDisplay(display);
-        fprintf(stderr,
-                "Direct Rendering is not available on this system!\n");
+	XVMC_ERR("Direct Rendering is not available on this system!");
         free(pI915XvMC);
         context->privData = NULL;
         return BadAlloc;
@@ -1914,7 +1913,7 @@ Status XvMCCreateContext(Display *display, XvPortID port,
     if (!uniDRIOpenConnection(display, pI915XvMC->screen,
                               &pI915XvMC->hsarea, &curBusID)) {
         XUnlockDisplay(display);
-        fprintf(stderr, "Could not open DRI connection to X server!\n");
+        XVMC_ERR("Could not open DRI connection to X server!");
         free(pI915XvMC);
         context->privData = NULL;
         return BadAlloc;
@@ -1927,7 +1926,7 @@ Status XvMCCreateContext(Display *display, XvPortID port,
 
     /* Open DRI Device */
     if((pI915XvMC->fd = drmOpen(I915KernelDriverName, NULL)) < 0) {
-        printf("DRM Device for %s could not be opened.\n", I915KernelDriverName);
+        XVMC_ERR("DRM Device for %s could not be opened.", I915KernelDriverName);
         free(pI915XvMC);
         context->privData = NULL;
         return BadAccess;
@@ -1940,8 +1939,7 @@ Status XvMCCreateContext(Display *display, XvPortID port,
     XLockDisplay(display);
     if (!uniDRIAuthConnection(display, pI915XvMC->screen, magic)) {
         XUnlockDisplay(display);
-        fprintf(stderr,
-                "[XvMC]: X server did not allow DRI. Check permissions.\n");
+	XVMC_ERR("[XvMC]: X server did not allow DRI. Check permissions.");
         free(pI915XvMC);
         context->privData = NULL;
         return BadAlloc;
@@ -1953,7 +1951,7 @@ Status XvMCCreateContext(Display *display, XvPortID port,
      */
     if (drmMap(pI915XvMC->fd, pI915XvMC->hsarea,
                pI915XvMC->sarea_size, &pI915XvMC->sarea_address) < 0) {
-        fprintf(stderr, "Unable to map DRI SAREA.\n");
+        XVMC_ERR("Unable to map DRI SAREA.\n");
         free(pI915XvMC);
         context->privData = NULL;
         return BadAlloc;
@@ -1969,8 +1967,7 @@ Status XvMCCreateContext(Display *display, XvPortID port,
     XUnlockDisplay(display);
 
     if (!ret) {
-        fprintf(stderr,
-                "[XvMC]: Could not find a matching TrueColor visual.\n");
+	XVMC_ERR("Could not find a matching TrueColor visual.");
         free(pI915XvMC);
         context->privData = NULL;
         drmUnmap(pI915XvMC->sarea_address, pI915XvMC->sarea_size);
@@ -1980,8 +1977,7 @@ Status XvMCCreateContext(Display *display, XvPortID port,
     if (!uniDRICreateContext(display, pI915XvMC->screen,
                              pI915XvMC->visualInfo.visual, &pI915XvMC->id,
                              &pI915XvMC->hHWContext)) {
-
-        fprintf(stderr, "[XvMC]: Could not create DRI context.\n");
+        XVMC_ERR("Could not create DRI context.");
         free(pI915XvMC);
         context->privData = NULL;
         drmUnmap(pI915XvMC->sarea_address, pI915XvMC->sarea_size);
@@ -1989,8 +1985,7 @@ Status XvMCCreateContext(Display *display, XvPortID port,
     }
 
     if (NULL == (pI915XvMC->drawHash = drmHashCreate())) {
-        fprintf(stderr, 
-                "[XvMC]: Could not allocate drawable hash table.\n");
+	XVMC_ERR("Could not allocate drawable hash table.");
         free(pI915XvMC);
         context->privData = NULL;
         drmUnmap(pI915XvMC->sarea_address, pI915XvMC->sarea_size);
@@ -2085,7 +2080,7 @@ Status XvMCCreateSurface(Display *display, XvMCContext *context, XvMCSurface *su
     if ((ret = _xvmc_create_surface(display, context, surface,
                                     &priv_count, &priv_data))) {
         XUnlockDisplay(display);
-        printf("Unable to create XvMCSurface.\n");
+        XVMC_ERR("Unable to create XvMCSurface.");
         free(pI915Surface);
         surface->privData = NULL;
         PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
@@ -2095,8 +2090,8 @@ Status XvMCCreateSurface(Display *display, XvMCContext *context, XvMCSurface *su
     XUnlockDisplay(display);
 
     if (priv_count != (sizeof(I915XvMCCreateSurfaceRec) >> 2)) {
-        printf("_xvmc_create_surface() returned incorrect data size!\n");
-        printf("\tExpected %d, got %d\n", 
+        XVMC_ERR("_xvmc_create_surface() returned incorrect data size!");
+        XVMC_INFO("\tExpected %d, got %d",
                (int)(sizeof(I915XvMCCreateSurfaceRec) >> 2), priv_count);
         _xvmc_destroy_surface(display, surface);
         free(priv_data);
@@ -2281,13 +2276,8 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context,
     i915XvMCContext *pI915XvMC = NULL;
 
     /* Check Parameters for validity */
-    if (!display) {
-        printf("Error, Invalid display!\n");
-        return BadValue;
-    }
-
     if (!display || !context || !target_surface) {
-        printf("Error, Invalid Display, Context or Target!\n");
+        XVMC_ERR("Invalid Display, Context or Target!");
         return BadValue;
     }
 
@@ -2295,12 +2285,12 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context,
         return Success;
 
     if (!macroblock_array || !blocks) {
-        printf("Error, Invalid block data!\n");
+        XVMC_ERR("Invalid block data!");
         return BadValue;
     }
 
     if (macroblock_array->num_blocks < (num_macroblocks + first_macroblock)) {
-        printf("Error, Too many macroblocks requested for MB array size.\n");
+        XVMC_ERR("Too many macroblocks requested for MB array size.");
         return BadValue;
     }
 
@@ -2312,7 +2302,7 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context,
 
     /* Test For YV12 Surface */
     if (context->surface_type_id != FOURCC_YV12) {
-        printf("Error, HWMC only possible on YV12 Surfaces\n");
+        XVMC_ERR("HWMC only possible on YV12 Surfaces.");
         return BadValue;
     }
 
@@ -2322,7 +2312,7 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context,
         privPast = privTarget;
     } else {
         if (!(privPast = past_surface->privData)) {
-            printf("Error, Invalid Past Surface!\n");
+            XVMC_ERR("Invalid Past Surface!");
             return (error_base + XvMCBadSurface);
         }
         
@@ -2334,12 +2324,12 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context,
         privFuture = privPast; // privTarget;
     } else {
         if (!past_surface) {
-            printf("Error, No Past Surface!\n");
+            XVMC_ERR("No Past Surface!");
             return BadValue;
         }
 
         if (!(privFuture = future_surface->privData)) {
-            printf("Error, Invalid Future Surface!\n");
+            XVMC_ERR("Invalid Future Surface!");
             return (error_base + XvMCBadSurface);
         }
 
@@ -2358,12 +2348,12 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context,
         /* Lockup can happen if the coordinates are too far out of range */
         if (mb->x > (target_surface->width >> 4)) {
             mb->x = 0;
-            printf("reset x\n");
+            XVMC_INFO("reset x");
         }
 
         if (mb->y > (target_surface->height >> 4)) {
             mb->y = 0;
-            printf("reset y\n");
+            XVMC_INFO("reset y");
         }
 
         /* Catch no pattern case */
@@ -2371,7 +2361,7 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context,
             !(mb->macroblock_type & XVMC_MB_TYPE_INTRA) &&
             mb->coded_block_pattern) {
             mb->coded_block_pattern = 0;
-            printf("no coded blocks present!\n");
+            XVMC_INFO("no coded blocks present!");
         }
         
         bspm = mb_bytes[mb->coded_block_pattern];
@@ -2382,7 +2372,7 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context,
         corrdata_size += bspm;
 
         if (corrdata_size > pI915XvMC->corrdata.size) {
-            printf("Error, correction data buffer overflow\n");
+            XVMC_ERR("correction data buffer overflow.");
             break;
         }
         memcpy(corrdata_ptr, block_ptr, bspm);
@@ -2627,7 +2617,7 @@ Status XvMCGetSurfaceStatus(Display *display, XvMCSurface *surface, int *stat)
     if (pI915Surface->last_flip) {
         /* This can not happen */
         if (pI915XvMC->last_flip < pI915Surface->last_flip) {
-            printf("Error: Context last flip is less than surface last flip.\n");
+            XVMC_ERR("Context last flip is less than surface last flip.");
             PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
             return BadValue;
         }
@@ -2763,7 +2753,7 @@ Status XvMCCreateSubpicture(Display *display, XvMCContext *context,
     if ((ret = _xvmc_create_subpicture(display, context, subpicture,
                                        &priv_count, &priv_data))) {
         XUnlockDisplay(display);
-        printf("Unable to create XvMCSubpicture.\n");
+        XVMC_ERR("Unable to create XvMCSubpicture.");
         free(pI915Subpicture);
         subpicture->privData = NULL;
         PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
@@ -2772,8 +2762,8 @@ Status XvMCCreateSubpicture(Display *display, XvMCContext *context,
     XUnlockDisplay(display);
 
     if (priv_count != (sizeof(I915XvMCCreateSurfaceRec) >> 2)) {
-        printf("_xvmc_create_subpicture() returned incorrect data size!\n");
-        printf("\tExpected %d, got %d\n", 
+        XVMC_ERR("_xvmc_create_subpicture() returned incorrect data size!");
+        XVMC_INFO("\tExpected %d, got %d", 
                (int)(sizeof(I915XvMCCreateSurfaceRec) >> 2), priv_count);
         XLockDisplay(display);
         _xvmc_destroy_subpicture(display, subpicture);
diff --git a/src/xvmc/Makefile.am b/src/xvmc/Makefile.am
index 6733809..0a805fb 100644
--- a/src/xvmc/Makefile.am
+++ b/src/xvmc/Makefile.am
@@ -11,6 +11,7 @@ libI810XvMC_la_LIBADD = @DRI_LIBS@
 
 libI915XvMC_la_SOURCES = I915XvMC.c \
                          I915XvMC.h \
+			 intel_xvmc.h \
                          intel_batchbuffer.c \
                          intel_batchbuffer.h \
                          xf86dri.c \
diff --git a/src/xvmc/intel_xvmc.h b/src/xvmc/intel_xvmc.h
new file mode 100644
index 0000000..072a0f4
--- /dev/null
+++ b/src/xvmc/intel_xvmc.h
@@ -0,0 +1,23 @@
+
+#ifndef INTEL_XVMC_H
+#define INTEL_XVMC_H
+
+#define DEBUG 0
+
+#define XVMC_ERR(s, arg...)					\
+    do {							\
+	fprintf(stderr, "intel_xvmc err: " s "\n", ##arg);	\
+    } while (0)
+
+#define XVMC_INFO(s, arg...)					\
+    do {							\
+	fprintf(stderr, "intel_xvmc info: " s "\n", ##arg);	\
+    } while (0)
+
+#define XVMC_DBG(s, arg...)						\
+    do {								\
+	if (DEBUG)							\
+	    fprintf(stderr, "intel_xvmc debug: " s "\n", ##arg);	\
+    } while (0)
+
+#endif
commit b10a9668dc50d10489b2ae531d89c8ab7c408170
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Wed Sep 26 14:01:57 2007 +0800

    fix i915 xvmc devPrivate reference

diff --git a/src/i830.h b/src/i830.h
index d5ad7a1..b45be22 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -319,12 +319,12 @@ typedef struct _I830Rec {
    /* For Xvideo */
    i830_memory *overlay_regs;
 #endif
-   
+#ifdef XvMCExtension
    /* For XvMC */
-   void *xvmc;
    Bool XvMCEnabled;
    Bool IsXvMCSurface;
- 
+#endif
+
    XF86ModReqInfo shadowReq; /* to test for later libshadow */
    Rotation rotation;
    void (*PointerMoved)(int, int, int);
diff --git a/src/i915_hwmc.c b/src/i915_hwmc.c
index 32a0879..2869aaa 100644
--- a/src/i915_hwmc.c
+++ b/src/i915_hwmc.c
@@ -458,7 +458,7 @@ static int I915XvMCCreateContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext,
     DRIInfoPtr pDRIInfo = pI830->pDRIInfo;
     I830DRIPtr pI830DRI = pDRIInfo->devPrivate;
     I915XvMCCreateContextRec *contextRec = NULL;
-    I915XvMCPtr pXvMC = pI830->xvmc;
+    I915XvMCPtr pXvMC = (I915XvMCPtr)xvmc_driver->devPrivate;
     I915XvMCContextPriv *ctxpriv = NULL;
     int i;
 
@@ -569,7 +569,7 @@ static int I915XvMCCreateSurface(ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf,
                                  int *num_priv, long **priv )
 {
     I830Ptr pI830 = I830PTR(pScrn);
-    I915XvMCPtr pXvMC = pI830->xvmc;
+    I915XvMCPtr pXvMC = (I915XvMCPtr)xvmc_driver->devPrivate;
     I915XvMCSurfacePriv *sfpriv = NULL;
     I915XvMCCreateSurfaceRec *surfaceRec = NULL;
     XvMCContextPtr ctx = NULL;
@@ -663,7 +663,7 @@ static int I915XvMCCreateSubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSubp,
                                      int *num_priv, long **priv )
 {
     I830Ptr pI830 = I830PTR(pScrn);
-    I915XvMCPtr pXvMC = pI830->xvmc;
+    I915XvMCPtr pXvMC = (I915XvMCPtr)xvmc_driver->devPrivate;
     I915XvMCSurfacePriv *sfpriv = NULL;
     I915XvMCCreateSurfaceRec *surfaceRec = NULL;
     XvMCContextPtr ctx = NULL;
@@ -749,8 +749,7 @@ static int I915XvMCCreateSubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSubp,
 
 static void I915XvMCDestroyContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext)
 {
-    I830Ptr pI830 = I830PTR(pScrn);
-    I915XvMCPtr pXvMC = pI830->xvmc;
+    I915XvMCPtr pXvMC = (I915XvMCPtr)xvmc_driver->devPrivate;
     int i;
 
     for (i = 0; i < I915_XVMC_MAX_CONTEXTS; i++) {
@@ -771,7 +770,7 @@ static void I915XvMCDestroyContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext)
 static void I915XvMCDestroySurface (ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf)
 {
     I830Ptr pI830 = I830PTR(pScrn);
-    I915XvMCPtr pXvMC = pI830->xvmc;
+    I915XvMCPtr pXvMC = (I915XvMCPtr)xvmc_driver->devPrivate;
     int i;
 
     for (i = 0; i < I915_XVMC_MAX_SURFACES; i++) {
@@ -792,7 +791,7 @@ static void I915XvMCDestroySurface (ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf)
 static void I915XvMCDestroySubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSubp)
 {
     I830Ptr pI830 = I830PTR(pScrn);
-    I915XvMCPtr pXvMC = pI830->xvmc;
+    I915XvMCPtr pXvMC = (I915XvMCPtr)xvmc_driver->devPrivate;
     int i;
 
     for (i = 0; i < I915_XVMC_MAX_SURFACES; i++) {
@@ -818,7 +817,7 @@ static int I915XvMCPutImage(ScrnInfoPtr pScrn, short src_x, short src_y,
                                      DrawablePtr pDraw)
 {
     I830Ptr pI830 = I830PTR(pScrn);
-    I915XvMCPtr pXvMC = pI830->xvmc;
+    I915XvMCPtr pXvMC = (I915XvMCPtr)xvmc_driver->devPrivate;
     I915XvMCCommandBuffer *i915XvMCData = (I915XvMCCommandBuffer *)buf;
     int ret;
 
commit f12eaaf385e7a0b85524588a5d865d1cc3f1a0cf
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Wed Sep 26 13:49:55 2007 +0800

    comment out i965_xvmc_driver for now

diff --git a/src/i830_hwmc.c b/src/i830_hwmc.c
index e51445b..903acb8 100644
--- a/src/i830_hwmc.c
+++ b/src/i830_hwmc.c
@@ -54,8 +54,10 @@ Bool intel_xvmc_probe(ScrnInfoPtr pScrn)
     if (IS_I9XX(pI830)) {
 	if (!IS_I965G(pI830))
 	    ret = intel_xvmc_set_driver(&i915_xvmc_driver);
+	/*
 	else
 	    ret = intel_xvmc_set_driver(&i965_xvmc_driver);
+	 */
 	if (ret)
 	    pI830->XvMCEnabled = TRUE;
     } else {
diff --git a/src/i830_hwmc.h b/src/i830_hwmc.h
index a316af2..539621b 100644
--- a/src/i830_hwmc.h
+++ b/src/i830_hwmc.h
@@ -47,7 +47,7 @@ struct intel_xvmc_driver {
 
 extern struct intel_xvmc_driver *xvmc_driver;
 extern struct intel_xvmc_driver i915_xvmc_driver;
-extern struct intel_xvmc_driver i965_xvmc_driver;
+/* extern struct intel_xvmc_driver i965_xvmc_driver; */
 
 extern Bool intel_xvmc_set_driver(struct intel_xvmc_driver *);
 extern Bool intel_xvmc_probe(ScrnInfoPtr);
commit 513e8a2f8abde1b11b8058e94a650796fd51779b
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Wed Sep 26 13:45:42 2007 +0800

    Create xvmc driver interface
    
    convert i915 to new xvmc driver interface

diff --git a/src/Makefile.am b/src/Makefile.am
index 1c29a1e..c62b825 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -59,6 +59,8 @@ INTEL_DRI_SRCS = \
          i810_dri.h \
          i830_dri.c \
          i810_hwmc.c \
+	 i830_hwmc.h \
+	 i830_hwmc.c \
          i915_hwmc.c \
          i915_hwmc.h \
          i830_dri.h
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 5a242b4..7f8921a 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -197,6 +197,10 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "i830_debug.h"
 #include "i830_bios.h"
 
+#ifdef XvMCExtension
+#include "i830_hwmc.h"
+#endif
+
 #ifdef XF86DRI
 #include "dri.h"
 #include <sys/ioctl.h>
@@ -2970,6 +2974,12 @@ i830AdjustFrame(int scrnIndex, int x, int y, int flags)
 static void
 I830FreeScreen(int scrnIndex, int flags)
 {
+#ifdef XvMCExtension
+    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+    I830Ptr pI830 = I830PTR(pScrn);
+    if (pI830->XvMCEnabled)
+	intel_xvmc_finish(xf86Screens[scrnIndex]);
+#endif
    I830FreeRec(xf86Screens[scrnIndex]);
    if (xf86LoaderCheckSymbol("vgaHWFreeHWRec"))
       vgaHWFreeHWRec(xf86Screens[scrnIndex]);
diff --git a/src/i830_hwmc.c b/src/i830_hwmc.c
new file mode 100644
index 0000000..e51445b
--- /dev/null
+++ b/src/i830_hwmc.c
@@ -0,0 +1,106 @@
+/*
+ * Copyright © 2007 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *    Zhenyu Wang <zhenyu.z.wang at intel.com>
+ *
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "i830.h"
+#include "i830_hwmc.h"
+
+struct intel_xvmc_driver *xvmc_driver;
+
+/* set global current driver for xvmc */
+Bool intel_xvmc_set_driver(struct intel_xvmc_driver *d)
+{
+    if (xvmc_driver) {
+	ErrorF("XvMC driver already set!\n");
+	return FALSE;
+    } else
+	xvmc_driver = d;
+    return TRUE;
+}
+
+/* check chip type and load xvmc driver */
+/* This must be first called! */
+Bool intel_xvmc_probe(ScrnInfoPtr pScrn)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+    Bool ret = FALSE;
+
+    if (IS_I9XX(pI830)) {
+	if (!IS_I965G(pI830))
+	    ret = intel_xvmc_set_driver(&i915_xvmc_driver);
+	else
+	    ret = intel_xvmc_set_driver(&i965_xvmc_driver);
+	if (ret)
+	    pI830->XvMCEnabled = TRUE;
+    } else {
+	ErrorF("Your chipset doesn't support XvMC.\n");
+	return FALSE;
+    }
+    return TRUE;
+}
+
+void intel_xvmc_finish(ScrnInfoPtr pScrn)
+{
+    if (!xvmc_driver)
+	return;
+    (*xvmc_driver->fini)(pScrn);
+}
+
+Bool intel_xvmc_init(ScreenPtr pScreen, XF86VideoAdaptorPtr xv_adaptor)
+{
+    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+    I830Ptr pI830 = I830PTR(pScrn);
+
+    if (!xvmc_driver) {
+	ErrorF("Failed to probe XvMC driver.\n");
+	return FALSE;
+    }
+
+    if (!(*xvmc_driver->init)(pScrn, xv_adaptor)) {
+	ErrorF("XvMC driver initialize failed.\n");
+	return FALSE;
+    }
+
+    if (xf86XvMCScreenInit(pScreen, 1, &xvmc_driver->adaptor)) {
+	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+		"[XvMC] Initialized XvMC.\n");
+    } else {
+	intel_xvmc_finish(pScrn);
+	pI830->XvMCEnabled = FALSE;
+	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+		"[XvMC] Failed to initialize XvMC.\n");
+	return FALSE;
+    }
+    return TRUE;
+}
+
+int intel_xvmc_putimage_size(ScrnInfoPtr pScrn)
+{
+    return (*xvmc_driver->putimage_size)(pScrn);
+}
diff --git a/src/i830_hwmc.h b/src/i830_hwmc.h
new file mode 100644
index 0000000..a316af2
--- /dev/null
+++ b/src/i830_hwmc.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright © 2007 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *    Zhenyu Wang <zhenyu.z.wang at intel.com>
+ *
+ */
+#ifndef I830_HWMC_H
+#define I830_HWMC_H
+
+#include <xf86xvmc.h>
+
+#define XVMC_DRIVER_MPEG2_MC    0x0001
+#define XVMC_DRIVER_MPEG2_VLD   0x0002
+#define XVMC_DRIVER_H264_MC     0x0004
+#define XVMC_DRIVER_H264_VLD    0x0008
+
+struct intel_xvmc_driver {
+    char *name;
+    XF86MCAdaptorPtr adaptor;
+    unsigned int flag;
+    /* more items for xvmv surface manage? */
+    Bool (*init)(ScrnInfoPtr, XF86VideoAdaptorPtr);
+    void (*fini)(ScrnInfoPtr);
+    int (*putimage_size)(ScrnInfoPtr);
+    void* devPrivate;
+};
+
+extern struct intel_xvmc_driver *xvmc_driver;
+extern struct intel_xvmc_driver i915_xvmc_driver;
+extern struct intel_xvmc_driver i965_xvmc_driver;
+
+extern Bool intel_xvmc_set_driver(struct intel_xvmc_driver *);
+extern Bool intel_xvmc_probe(ScrnInfoPtr);
+extern Bool intel_xvmc_init(ScreenPtr, XF86VideoAdaptorPtr);
+extern void intel_xvmc_finish(ScrnInfoPtr);
+extern int intel_xvmc_putimage_size(ScrnInfoPtr);
+
+#endif
diff --git a/src/i830_video.c b/src/i830_video.c
index ff12fa8..b0d42f0 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -74,7 +74,10 @@
 #include "dixstruct.h"
 #include "fourcc.h"
 
+#ifdef XvMCExtension
+#include "i830_hwmc.h"
 #include "i915_hwmc.h"
+#endif
 
 #ifndef USE_USLEEP_FOR_VIDEO
 #define USE_USLEEP_FOR_VIDEO 0
@@ -557,7 +560,6 @@ I830InitVideo(ScreenPtr pScreen)
     XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL;
     XF86VideoAdaptorPtr overlayAdaptor = NULL, texturedAdaptor = NULL;
     int num_adaptors;
-    Bool xvmc_init = FALSE;
 
 #if 0
     {
@@ -621,18 +623,16 @@ I830InitVideo(ScreenPtr pScreen)
 	I830InitOffscreenImages(pScreen);
     }
 
-#ifdef XvMCExtension
-    if (texturedAdaptor)
-	xvmc_init = I915XvMCInit(pScreen, texturedAdaptor);
-#endif
     if (num_adaptors)
 	xf86XVScreenInit(pScreen, adaptors, num_adaptors);
 
-    xfree(adaptors);
 #ifdef XvMCExtension
-    if (xvmc_init)
-	I915XvMCScreenInit(pScreen);
+    if (intel_xvmc_probe(pScrn)) {
+	if (texturedAdaptor)
+	    intel_xvmc_init(pScreen, texturedAdaptor);
+    }
 #endif
+    xfree(adaptors);
 }
 
 static void
@@ -2283,6 +2283,7 @@ I830PutImage(ScrnInfoPtr pScrn,
     switch (id) {
     case FOURCC_YV12:
     case FOURCC_I420:
+	//XXX
         if (pI830->IsXvMCSurface) {
             srcPitch = (width + 0x3ff) & ~0x3ff;
             srcPitch2 = ((width >> 1) + 0x3ff) & ~0x3ff;
@@ -2546,7 +2547,7 @@ I830QueryImageAttributes(ScrnInfoPtr pScrn,
 	break;
     case FOURCC_XVMC:
         *h = (*h + 1) & ~1;
-        size = I915XvMCPutImageSize(pScrn);
+        size = intel_xvmc_putimage_size(pScrn);
         if (pitches)
             pitches[0] = size;
         break;
diff --git a/src/i915_hwmc.c b/src/i915_hwmc.c
index 7a8a073..32a0879 100644
--- a/src/i915_hwmc.c
+++ b/src/i915_hwmc.c
@@ -55,6 +55,7 @@
 #include "xf86xvpriv.h"
 #endif
 
+#include "i830_hwmc.h"
 #include "i915_hwmc.h"
 
 #define I915_XVMC_MAX_BUFFERS 2
@@ -195,11 +196,6 @@ static XF86MCAdaptorRec pAdapt =
     (xf86XvMCDestroySubpictureProcPtr)I915XvMCDestroySubpicture
 };
 
-static XF86MCAdaptorPtr ppAdapt[1] = 
-{
-    (XF86MCAdaptorPtr)&pAdapt
-};
-
 /*
  * Init and clean up the screen private parts of XvMC.
  */
@@ -220,14 +216,12 @@ static void initI915XvMC(I915XvMCPtr xvmc)
     xvmc->nsurfaces = 0;
 }
 
-//XXX
-static void cleanupI915XvMC(I915XvMCPtr xvmc, XF86VideoAdaptorPtr * XvAdaptors, int XvAdaptorCount)
+static void cleanupI915XvMC(I915XvMCPtr xvmc)
 {
-    unsigned int i;
+    int i;
 
     for (i = 0; i < I915_XVMC_MAX_CONTEXTS; i++) {
         xvmc->contexts[i] = 0;
-
         if (xvmc->ctxprivs[i]) {
             xfree(xvmc->ctxprivs[i]);
             xvmc->ctxprivs[i] = NULL;
@@ -236,7 +230,6 @@ static void cleanupI915XvMC(I915XvMCPtr xvmc, XF86VideoAdaptorPtr * XvAdaptors,
 
     for (i = 0; i < I915_XVMC_MAX_SURFACES; i++) {
         xvmc->surfaces[i] = 0;
-        
         if (xvmc->sfprivs[i]) {
             xfree(xvmc->sfprivs[i]);
             xvmc->sfprivs[i] = NULL;
@@ -857,36 +850,22 @@ static int I915XvMCPutImage(ScrnInfoPtr pScrn, short src_x, short src_y,
     return ret;
 }
 
-/*********************************** Public Function **************************************/
-
-/**************************************************************************
- *
- *  I915InitMC
- *
- *  Inputs:
- *    Screen pointer
- *
- *  Outputs:
- *    None
- *  
- **************************************************************************/
+static int i915_xvmc_putimage_size(ScrnInfoPtr pScrn)
+{
+    return sizeof(I915XvMCCommandBuffer);
+}
 
-Bool I915XvMCInit(ScreenPtr pScreen, XF86VideoAdaptorPtr XvAdapt)
+static Bool i915_xvmc_init(ScrnInfoPtr pScrn, XF86VideoAdaptorPtr XvAdapt)
 {
-    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-    I830Ptr pI830 = I830PTR(pScrn);
     I915XvMCPtr pXvMC;
 
-    if (!IS_I9XX(pI830) || IS_I965G(pI830))
-	return FALSE;
-
     pXvMC = (I915XvMCPtr)xcalloc(1, sizeof(I915XvMC));
     if (!pXvMC) {
         xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
                    "[XvMC] alloc driver private failed!\n");
         return FALSE;
     }
-    pI830->xvmc = pXvMC;
+    xvmc_driver->devPrivate = (void*)pXvMC;
     initI915XvMC(pXvMC);
 
     /* set up wrappers */
@@ -895,32 +874,21 @@ Bool I915XvMCInit(ScreenPtr pScreen, XF86VideoAdaptorPtr XvAdapt)
     return TRUE;
 }
 
-Bool I915XvMCScreenInit(ScreenPtr pScreen)
+static void i915_xvmc_fini(ScrnInfoPtr pScrn)
 {
-    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-    I830Ptr pI830 = I830PTR(pScrn);
+    I915XvMCPtr pXvMC = (I915XvMCPtr)xvmc_driver->devPrivate;
 
-    if (xf86XvMCScreenInit(pScreen, 1, ppAdapt)) {
-	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-		"[XvMC] Initialized XvMC.\n");
-	pI830->XvMCEnabled = TRUE;
-    } else {
-        xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-		"[XvMC] xf86 XvMC initial failed\n");
-	pI830->XvMCEnabled = FALSE;
-	xfree(pI830->xvmc);
-	pI830->xvmc = NULL;
-	return FALSE;
-    }
-    return TRUE;
+    cleanupI915XvMC(pXvMC);
+    xfree(xvmc_driver->devPrivate);
 }
 
-unsigned long I915XvMCPutImageSize(ScrnInfoPtr pScrn)
-{
-    I830Ptr pI830 = I830PTR(pScrn);
-
-    if (pI830->XvMCEnabled)
-        return sizeof(I915XvMCCommandBuffer);
-
-    return 0;
-}
+/* new xvmc driver interface */
+struct intel_xvmc_driver i915_xvmc_driver = {
+    "i915_xvmc",
+    &pAdapt,
+    XVMC_DRIVER_MPEG2_MC,
+    i915_xvmc_init,
+    i915_xvmc_fini,
+    i915_xvmc_putimage_size,
+    NULL
+};
commit 798448e4641acf241b7cbae0d6c243ae383da9f4
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Wed Sep 19 13:29:31 2007 +0800

    Add media state definition on i965
    
    This adds VFE state and interface descriptor struct define.

diff --git a/src/brw_defines.h b/src/brw_defines.h
index 93aed54..13cb439 100644
--- a/src/brw_defines.h
+++ b/src/brw_defines.h
@@ -842,6 +842,30 @@
 #define R02_PRIM_END    0x1
 #define R02_PRIM_START  0x2
 
-
+/* media pipeline */
+
+#define BRW_VFE_MODE_GENERIC		0x0
+#define BRW_VFE_MODE_VLD_MPEG2		0x1
+#define BRW_VFE_MODE_IS			0x2
+#define BRW_VFE_MODE_AVC_MC		0x4
+#define BRW_VFE_MODE_AVC_IT		0x7
+#define BRW_VFE_MODE_VC1_IT		0xB
+
+#define BRW_VFE_DEBUG_COUNTER_FREE	0
+#define BRW_VFE_DEBUG_COUNTER_FROZEN	1
+#define BRW_VFE_DEBUG_COUNTER_ONCE	2
+#define BRW_VFE_DEBUG_COUNTER_ALWAYS	3
+
+/* VLD_STATE */
+#define BRW_MPEG_TOP_FIELD		1
+#define BRW_MPEG_BOTTOM_FIELD		2
+#define BRW_MPEG_FRAME			3
+#define BRW_MPEG_QSCALE_LINEAR		0
+#define BRW_MPEG_QSCALE_NONLINEAR	1
+#define BRW_MPEG_ZIGZAG_SCAN		0
+#define BRW_MPEG_ALTER_VERTICAL_SCAN	1
+#define BRW_MPEG_I_PICTURE		1
+#define BRW_MPEG_P_PICTURE		2
+#define BRW_MPEG_B_PICTURE		3
 
 #endif
diff --git a/src/brw_structs.h b/src/brw_structs.h
index 28d8e12..7a18b91 100644
--- a/src/brw_structs.h
+++ b/src/brw_structs.h
@@ -1336,5 +1336,112 @@ struct brw_instruction
    } bits3;
 };
 
+/* media pipeline */
+
+struct brw_vfe_state {
+    struct {
+	unsigned int per_thread_scratch_space:4;
+	unsigned int pad3:3;
+	unsigned int extend_vfe_state_present:1;
+	unsigned int pad2:2;
+	unsigned int scratch_base:22;
+    } vfe0;
+
+    struct {
+	unsigned int debug_counter_control:2;
+	unsigned int children_present:1;
+	unsigned int vfe_mode:4;
+	unsigned int pad2:2;
+	unsigned int num_urb_entries:7;
+	unsigned int urb_entry_alloc_size:9;
+	unsigned int max_threads:7;
+    } vfe1;
+
+    struct {
+	unsigned int pad4:4;
+	unsigned int interface_descriptor_base:28;
+    } vfe2;
+};
+
+struct brw_vld_state {
+    struct {
+	unsigned int pad6:6;
+	unsigned int scan_order:1;
+	unsigned int intra_vlc_format:1;
+	unsigned int quantizer_scale_type:1;
+	unsigned int concealment_motion_vector:1;
+	unsigned int frame_predict_frame_dct:1;
+	unsigned int top_field_first:1;
+	unsigned int picture_structure:2;
+	unsigned int intra_dc_precision:2;
+	unsigned int f_code_0_0:4;
+	unsigned int f_code_0_1:4;
+	unsigned int f_code_1_0:4;
+	unsigned int f_code_1_1:4;
+    } vld0;
+
+    struct {
+	unsigned int pad2:9;
+	unsigned int picture_coding_type:2;
+	unsigned int pad:21;
+    } vld1;
+
+    struct {
+	unsigned int index_0:4;
+	unsigned int index_1:4;
+	unsigned int index_2:4;
+	unsigned int index_3:4;
+	unsigned int index_4:4;
+	unsigned int index_5:4;
+	unsigned int index_6:4;
+	unsigned int index_7:4;
+    } desc_remap_table0;
+
+    struct {
+	unsigned int index_8:4;
+	unsigned int index_9:4;
+	unsigned int index_10:4;
+	unsigned int index_11:4;
+	unsigned int index_12:4;
+	unsigned int index_13:4;
+	unsigned int index_14:4;
+	unsigned int index_15:4;
+    } desc_remap_table1;
+};
+
+struct brw_interface_descriptor {
+    struct {
+	unsigned int grf_reg_blocks:4;
+	unsigned int pad:2;
+	unsigned int kernel_start_pointer:26;
+    } desc0;
+
+    struct {
+	unsigned int pad:7;
+	unsigned int software_exception:1;
+	unsigned int pad2:3;
+	unsigned int maskstack_exception:1;
+	unsigned int pad3:1;
+	unsigned int illegal_opcode_exception:1;
+	unsigned int pad4:2;
+	unsigned int floating_point_mode:1;
+	unsigned int thread_priority:1;
+	unsigned int single_program_flow:1;
+	unsigned int pad5:1;
+	unsigned int const_urb_entry_read_offset:6;
+	unsigned int const_urb_entry_read_len:6;
+    } desc1;
+
+    struct {
+	unsigned int pad:2;
+	unsigned int sampler_count:3;
+	unsigned int sampler_state_pointer:27;
+    } desc2;
+
+    struct {
+	unsigned int binding_table_entry_count:5;
+	unsigned int binding_table_pointer:27;
+    } desc3;
+};
 
 #endif
commit 36b81ba20d20e7b235cb701c5135cbf3f3eedb12
Merge: 02ad9ce... bda3c69...
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Wed Sep 19 11:44:41 2007 +0800

    Merge branch 'master' into xvmc-i915
    
    Conflicts:
    
    	src/i830.h
    	src/i830_memory.c

diff --cc src/i830.h
index d6e8fec,71c46b4..d5ad7a1
--- a/src/i830.h
+++ b/src/i830.h
@@@ -769,4 -760,4 +767,9 @@@ extern const int I830CopyROP[16]
  #define QUIRK_IGNORE_MACMINI_LVDS 	0x00000004
  extern void i830_fixup_devices(ScrnInfoPtr);
  
++/* i915 XvMC */
++Bool I915XvMCInit(ScreenPtr, XF86VideoAdaptorPtr);
++Bool I915XvMCScreenInit(ScreenPtr);
++unsigned long I915XvMCPutImageSize(ScrnInfoPtr);
++
  #endif /* _I830_H_ */
diff --cc src/i830_memory.c
index c094d5d,3da489d..9579a53
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@@ -1716,61 -1682,3 +1682,22 @@@ I830CheckAvailableMemory(ScrnInfoPtr pS
  
      return maxPages * 4;
  }
 +
- #ifdef I830_USE_XAA
- /**
-  * Allocates memory from the XF86 linear allocator, but also purges
-  * memory if possible to cause the allocation to succeed.
-  */
- FBLinearPtr
- i830_xf86AllocateOffscreenLinear(ScreenPtr pScreen, int length,
- 				 int granularity,
- 				 MoveLinearCallbackProcPtr moveCB,
- 				 RemoveLinearCallbackProcPtr removeCB,
- 				 pointer privData)
- {
-     FBLinearPtr linear;
-     int max_size;
- 
-     linear = xf86AllocateOffscreenLinear(pScreen, length, granularity, moveCB,
- 					 removeCB, privData);
-     if (linear != NULL)
- 	return linear;
- 
-     /* The above allocation didn't succeed, so purge unlocked stuff and try
-      * again.
-      */
-     xf86QueryLargestOffscreenLinear(pScreen, &max_size, granularity,
- 				    PRIORITY_EXTREME);
- 
-     if (max_size < length)
- 	return NULL;
- 
-     xf86PurgeUnlockedOffscreenAreas(pScreen);
- 
-     linear = xf86AllocateOffscreenLinear(pScreen, length, granularity, moveCB,
- 					 removeCB, privData);
- 
-     return linear;
- }
- 
- #endif
- 
 +/*
 + * Allocate memory for MC compensation
 + */
 +Bool i830_allocate_xvmc_buffer(ScrnInfoPtr pScrn, const char *name,
 +                               i830_memory **buffer, unsigned long size,
 +                               int flags)
 +{
 +    *buffer = i830_allocate_memory(pScrn, name, size,
 +                                   GTT_PAGE_SIZE, flags);
 +
 +    if (!*buffer) {
 +        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 +                   "Failed to allocate memory for %s.\n", name);
 +        return FALSE;
 +    }
 +
 +    return TRUE;
 +}
commit 02ad9cee330fb5fb0008ad6f74e74e8d8a1fc36e
Merge: 105f8a1... 7b143e5...
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Fri Aug 10 16:45:56 2007 +0800

    Merge branch 'master' into xvmc-i915

commit 105f8a183eb64623d9a9e2833dbe27156a551f69
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Fri Aug 10 16:44:46 2007 +0800

    disable subpicture initial
    
    until we really implement it, OSD can't work for now.

diff --git a/src/i915_hwmc.c b/src/i915_hwmc.c
index b6865c6..7a8a073 100644
--- a/src/i915_hwmc.c
+++ b/src/i915_hwmc.c
@@ -131,8 +131,10 @@ static XF86MCSurfaceInfoRec i915_YV12_mpg2_surface =
     720,
     576,
     XVMC_MPEG_2,
-    XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING,
-    &yv12_subpicture_list
+    /* XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING,*/
+    0,
+    /* &yv12_subpicture_list*/
+    NULL,
 };
 
 static XF86MCSurfaceInfoRec i915_YV12_mpg1_surface =
@@ -145,8 +147,10 @@ static XF86MCSurfaceInfoRec i915_YV12_mpg1_surface =
     720,
     576,
     XVMC_MPEG_1,
-    XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING,
-    &yv12_subpicture_list
+    /* XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING,*/
+    0,
+    /* &yv12_subpicture_list*/
+    NULL,
 };
 
 static XF86MCSurfaceInfoPtr ppSI[2] = 
@@ -177,8 +181,12 @@ static XF86MCAdaptorRec pAdapt =
     "Intel(R) Textured Video",		                        /* name */
     ARRARY_SIZE(ppSI),                                          /* num_surfaces */
     ppSI,				                        /* surfaces */
+    0,
+    NULL,
+#if 0
     ARRARY_SIZE(i915_subpicture_list),                          /* num_subpictures */
     i915_subpicture_list,		                        /* subpictures */
+#endif
     (xf86XvMCCreateContextProcPtr)I915XvMCCreateContext,
     (xf86XvMCDestroyContextProcPtr)I915XvMCDestroyContext,
     (xf86XvMCCreateSurfaceProcPtr)I915XvMCCreateSurface,
commit 87cc72ef509b85635bf0e84c47dfed6b7242170b
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Wed Aug 8 09:39:55 2007 +0800

    check early if we have slot left for new context or surface

diff --git a/src/i915_hwmc.c b/src/i915_hwmc.c
index 9475977..b6865c6 100644
--- a/src/i915_hwmc.c
+++ b/src/i915_hwmc.c
@@ -208,6 +208,8 @@ static void initI915XvMC(I915XvMCPtr xvmc)
         xvmc->surfaces[i] = 0;
         xvmc->sfprivs[i] = NULL;
     }
+    xvmc->ncontexts = 0;
+    xvmc->nsurfaces = 0;
 }
 
 //XXX
@@ -468,7 +470,13 @@ static int I915XvMCCreateContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext,
         return BadAlloc;
     }
 
-    if (pXvMC->ncontexts >= I915_XVMC_MAX_CONTEXTS) {
+    for (i = 0; i < I915_XVMC_MAX_CONTEXTS; i++) {
+        if (!pXvMC->contexts[i])
+            break;
+    }
+
+    if (i == I915_XVMC_MAX_CONTEXTS || 
+	    pXvMC->ncontexts >= I915_XVMC_MAX_CONTEXTS) {
         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
                    "[XvMC] I915XvMCCreateContext: Out of contexts.\n");
         return BadAlloc;
@@ -484,11 +492,6 @@ static int I915XvMCCreateContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext,
 
     *num_priv = sizeof(I915XvMCCreateContextRec) >> 2;
 
-    for (i = 0; i < I915_XVMC_MAX_CONTEXTS; i++) {
-        if (!pXvMC->contexts[i])
-            break;
-    }
-
     ctxpriv = (I915XvMCContextPriv *)xcalloc(1, sizeof(I915XvMCContextPriv));
 
     if (!ctxpriv) {
@@ -572,10 +575,22 @@ static int I915XvMCCreateSurface(ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf,
     unsigned int srfno;
     unsigned long bufsize;
 
+    if (!pI830->XvMCEnabled) {
+        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                   "[XvMC] I915XvMCCreateContext: Cannot use XvMC!\n");
+        return BadAlloc;
+    }
+
     *priv = NULL;
     *num_priv = 0;
 
-    if (pXvMC->nsurfaces >= I915_XVMC_MAX_SURFACES) {
+    for (srfno = 0; srfno < I915_XVMC_MAX_SURFACES; ++srfno) {
+        if (!pXvMC->surfaces[srfno])
+            break;
+    }
+
+    if (srfno == I915_XVMC_MAX_SURFACES ||
+	    pXvMC->nsurfaces >= I915_XVMC_MAX_SURFACES) {
         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
                    "[XvMC] I915XvMCCreateSurface: Too many surfaces !\n");
         return BadAlloc;
@@ -631,10 +646,6 @@ static int I915XvMCCreateSurface(ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf,
         return BadAlloc;
     }
 
-    for (srfno = 0; srfno < I915_XVMC_MAX_SURFACES; ++srfno) {
-        if (!pXvMC->surfaces[srfno])
-            break;
-    }
     surfaceRec->srfno = srfno;
     surfaceRec->srf.handle = sfpriv->surface_handle;
     surfaceRec->srf.offset = sfpriv->surface->offset;
@@ -661,7 +672,13 @@ static int I915XvMCCreateSubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSubp,
     *priv = NULL;
     *num_priv = 0;
 
-    if (pXvMC->nsurfaces >= I915_XVMC_MAX_SURFACES) {
+    for (srfno = 0; srfno < I915_XVMC_MAX_SURFACES; ++srfno) {
+        if (!pXvMC->surfaces[srfno])
+            break;
+    }
+
+    if (srfno == I915_XVMC_MAX_SURFACES ||
+	    pXvMC->nsurfaces >= I915_XVMC_MAX_SURFACES) {
         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
                    "[XvMC] I915XvMCCreateSubpicture: Too many surfaces !\n");
         return BadAlloc;
@@ -717,11 +734,6 @@ static int I915XvMCCreateSubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSubp,
         return BadAlloc;
     }
 
-    for (srfno = 0; srfno < I915_XVMC_MAX_SURFACES; ++srfno) {
-        if (!pXvMC->surfaces[srfno])
-            break;
-    }
-
     surfaceRec->srfno = srfno;
     surfaceRec->srf.handle = sfpriv->surface_handle;
     surfaceRec->srf.offset = sfpriv->surface->offset;
@@ -820,7 +832,7 @@ static int I915XvMCPutImage(ScrnInfoPtr pScrn, short src_x, short src_y,
 			    "[XvMC] I915XvMCPutImage: Invalid parameters !\n");
 		    return 1;
 		}
-                   
+
 		buf = pI830->FbBase + pXvMC->sfprivs[i915XvMCData->srfNo]->surface->offset;
 		id = i915XvMCData->real_id;
 		pI830->IsXvMCSurface = 1;
commit fec6744b763f2b85b4e592c51326b9ee979bef5d
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Wed Aug 8 09:26:10 2007 +0800

    I missed to remove port attributes wrapper

diff --git a/src/i915_hwmc.c b/src/i915_hwmc.c
index 8ff1864..9475977 100644
--- a/src/i915_hwmc.c
+++ b/src/i915_hwmc.c
@@ -93,8 +93,6 @@ typedef struct _I915XvMC
     I915XvMCSurfacePriv *sfprivs[I915_XVMC_MAX_SURFACES];
     I915XvMCContextPriv *ctxprivs[I915_XVMC_MAX_CONTEXTS];
     int ncontexts,nsurfaces;
-    SetPortAttributeFuncPtr saveSetPortAttribute;
-    GetPortAttributeFuncPtr saveGetPortAttribute;
     PutImageFuncPtr savePutImage;
 } I915XvMC, *I915XvMCPtr;
 
commit 76c084d41999f13497b80d4ac6799cb974adaa03
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Wed Aug 8 09:22:42 2007 +0800

    explicit say "unsigned int"

diff --git a/src/i915_hwmc.c b/src/i915_hwmc.c
index 79fe284..8ff1864 100644
--- a/src/i915_hwmc.c
+++ b/src/i915_hwmc.c
@@ -657,8 +657,8 @@ static int I915XvMCCreateSubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSubp,
     I915XvMCSurfacePriv *sfpriv = NULL;
     I915XvMCCreateSurfaceRec *surfaceRec = NULL;
     XvMCContextPtr ctx = NULL;
-    unsigned srfno;
-    unsigned bufsize;
+    unsigned int srfno;
+    unsigned int bufsize;
 
     *priv = NULL;
     *num_priv = 0;
diff --git a/src/i915_hwmc.h b/src/i915_hwmc.h
index 61c7c4b..597d30c 100644
--- a/src/i915_hwmc.h
+++ b/src/i915_hwmc.h
@@ -47,12 +47,11 @@
 
 typedef struct
 {
-    unsigned command;
-    unsigned ctxNo;
-    unsigned srfNo;
-    unsigned subPicNo;
+    unsigned int command;
+    unsigned int ctxNo;
+    unsigned int srfNo;
+    unsigned int subPicNo;
     int real_id;
-    unsigned pad;
 } I915XvMCCommandBuffer;
 
 struct hwmc_buffer
@@ -65,7 +64,7 @@ struct hwmc_buffer
 
 typedef struct 
 {
-    unsigned ctxno; /* XvMC private context reference number */
+    unsigned int ctxno; /* XvMC private context reference number */
     struct hwmc_buffer sis;
     struct hwmc_buffer ssb;
     struct hwmc_buffer msb;
@@ -73,16 +72,16 @@ typedef struct
     struct hwmc_buffer psc;
     struct hwmc_buffer corrdata;/* Correction Data Buffer */
     struct hwmc_buffer batchbuffer;
-    unsigned sarea_size;
-    unsigned sarea_priv_offset;
-    unsigned screen;
-    unsigned depth;
+    unsigned int sarea_size;
+    unsigned int sarea_priv_offset;
+    unsigned int screen;
+    unsigned int depth;
     int deviceID;
 } I915XvMCCreateContextRec;
 
 typedef struct 
 {
-    unsigned srfno;
+    unsigned int srfno;
     struct hwmc_buffer srf;
 } I915XvMCCreateSurfaceRec;
 
diff --git a/src/xvmc/I915XvMC.c b/src/xvmc/I915XvMC.c
index 7040f6a..22718de 100644
--- a/src/xvmc/I915XvMC.c
+++ b/src/xvmc/I915XvMC.c
@@ -66,7 +66,7 @@
                                  SIZE_Y420(surface->width, surface->height))
 
 /* Lookup tables to speed common calculations */
-_STATIC_ unsigned mb_bytes[] = {
+_STATIC_ unsigned int mb_bytes[] = {
     000, 128, 128, 256, 128, 256, 256, 384,  // 0
     128, 256, 256, 384, 256, 384, 384, 512,  // 1
     128, 256, 256, 384, 256, 384, 384, 512,  // 10
@@ -86,13 +86,13 @@ _STATIC_ char I915KernelDriverName[] = "i915";
 _STATIC_ int error_base;
 _STATIC_ int event_base;
 
-_STATIC_ int findOverlap(unsigned width, unsigned height,
+_STATIC_ int findOverlap(unsigned int width, unsigned int height,
                        short *dstX, short *dstY,
                        short *srcX, short *srcY, 
                        unsigned short *areaW, unsigned short *areaH)
 {
     int w, h;
-    unsigned mWidth, mHeight;
+    unsigned int mWidth, mHeight;
 
     w = *areaW;
     h = *areaH;
@@ -128,7 +128,7 @@ _STATIC_ __inline__ void renderError(void)
     return;
 }
 
-_STATIC_ void I915XvMCContendedLock(i915XvMCContext *pI915XvMC, unsigned flags)
+_STATIC_ void I915XvMCContendedLock(i915XvMCContext *pI915XvMC, drmLockFlags flags)
 {
     drmGetLock(pI915XvMC->fd, pI915XvMC->hHWContext, flags);
 }
@@ -202,16 +202,16 @@ _STATIC_ void i915_flush(i915XvMCContext *pI915XvMC, int map, int render)
 /* for MC picture rendering */
 _STATIC_ void i915_mc_static_indirect_state_buffer(XvMCContext *context, 
                                                    XvMCSurface *surface,
-                                                   unsigned picture_structure,
-                                                   unsigned flags,
-                                                   unsigned picture_coding_type)
+                                                   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 w = surface->width, h = surface->height;
+    unsigned int w = surface->width, h = surface->height;
 
     /* 3DSTATE_BUFFER_INFO */
     /* DEST Y */
@@ -334,7 +334,7 @@ _STATIC_ void i915_mc_map_state_buffer(XvMCContext *context,
     struct i915_3dstate_map_state *map_state;
     struct texture_map *tm;
     i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
-    unsigned w = context->width, h = context->height;
+    unsigned int w = context->width, h = context->height;
  
     /* 3DSATE_MAP_STATE: Y */
     map_state = (struct i915_3dstate_map_state *)pI915XvMC->msb.map;
@@ -479,7 +479,7 @@ _STATIC_ void i915_mc_load_sis_msb_buffers(XvMCContext *context)
     msb_state *msb = NULL;
     i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
     void *base = NULL;
-    unsigned size;
+    unsigned int size;
     int mem_select = 1;
 
     /* 3DSTATE_LOAD_INDIRECT */
@@ -624,7 +624,7 @@ _STATIC_ void i915_mc_mpeg_macroblock_1fbmv(XvMCContext *context, XvMCMacroBlock
     intelBatchbufferData(pI915XvMC, &macroblock_1fbmv, sizeof(macroblock_1fbmv), 0);
 }
 
-_STATIC_ void i915_mc_mpeg_macroblock_2fbmv(XvMCContext *context, XvMCMacroBlock *mb, unsigned ps)
+_STATIC_ void i915_mc_mpeg_macroblock_2fbmv(XvMCContext *context, XvMCMacroBlock *mb, unsigned int ps)
 {
     struct i915_3dmpeg_macroblock_2fbmv macroblock_2fbmv;
     i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
@@ -761,12 +761,12 @@ _STATIC_ void i915_mc_sampler_state_buffer(XvMCContext *context)
     ts->ts2.default_color = 0;
 }
 
-_STATIC_ void i915_inst_arith(unsigned *inst,
-                            unsigned op,
-                            unsigned dest,
-                            unsigned mask,
-                            unsigned saturate,
-                            unsigned src0, unsigned src1, unsigned src2)
+_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));
@@ -776,12 +776,12 @@ _STATIC_ void i915_inst_arith(unsigned *inst,
     *inst = (A2_SRC1(src1) | A2_SRC2(src2));
 }
 
-_STATIC_ void i915_inst_decl(unsigned *inst, 
-                           unsigned type,
-                           unsigned nr,
-                           unsigned d0_flags)
+_STATIC_ void i915_inst_decl(unsigned int *inst, 
+                           unsigned int type,
+                           unsigned int nr,
+                           unsigned int d0_flags)
 {
-    unsigned reg = UREG(type, nr);
+    unsigned int reg = UREG(type, nr);
     
     *inst = (D0_DCL | D0_DEST(reg) | d0_flags);
     inst++;
@@ -790,11 +790,11 @@ _STATIC_ void i915_inst_decl(unsigned *inst,
     *inst = D2_MBZ;
 }
 
-_STATIC_ void i915_inst_texld(unsigned *inst,
-                              unsigned op,
-                              unsigned dest,
-                              unsigned coord,
-                              unsigned sampler)
+_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));
@@ -808,8 +808,8 @@ _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 *inst;
-    unsigned dest, src0, src1, src2;
+    unsigned int *inst;
+    unsigned int dest, src0, src1, src2;
 
     /* Shader 0 */
     pixel_shader_program = (struct i915_3dstate_pixel_shader_program *)pI915XvMC->psp.map;
@@ -819,7 +819,7 @@ _STATIC_ void i915_mc_pixel_shader_program_buffer(XvMCContext *context)
     pixel_shader_program->dw0.retain = 1;
     pixel_shader_program->dw0.length = 2;
     /* mov oC, c0.0000 */
-    inst = (unsigned *)(++pixel_shader_program);
+    inst = (unsigned int*)(++pixel_shader_program);
     dest = UREG(REG_TYPE_OC, 0);
     src0 = UREG(REG_TYPE_CONST, 0);
     src1 = 0;
@@ -836,7 +836,7 @@ _STATIC_ void i915_mc_pixel_shader_program_buffer(XvMCContext *context)
     pixel_shader_program->dw0.retain = 1;
     pixel_shader_program->dw0.length = 14;
     /* dcl t0.xy */
-    inst = (unsigned *)(++pixel_shader_program);
+    inst = (unsigned int*)(++pixel_shader_program);
     i915_inst_decl(inst, REG_TYPE_T, T_TEX0, D0_CHANNEL_XY);
     /* dcl t1.xy */
     inst += 3;
@@ -867,7 +867,7 @@ _STATIC_ void i915_mc_pixel_shader_program_buffer(XvMCContext *context)
     pixel_shader_program->dw0.retain = 1;
     pixel_shader_program->dw0.length = 14;
     /* dcl t2.xy */
-    inst = (unsigned *)(++pixel_shader_program);
+    inst = (unsigned int*)(++pixel_shader_program);
     i915_inst_decl(inst, REG_TYPE_T, T_TEX2, D0_CHANNEL_XY);
     /* dcl t3.xy */
     inst += 3;
@@ -898,7 +898,7 @@ _STATIC_ void i915_mc_pixel_shader_program_buffer(XvMCContext *context)
     pixel_shader_program->dw0.retain = 1;
     pixel_shader_program->dw0.length = 29;
     /* dcl t0.xy */
-    inst = (unsigned *)(++pixel_shader_program);
+    inst = (unsigned int*)(++pixel_shader_program);
     i915_inst_decl(inst, REG_TYPE_T, T_TEX0, D0_CHANNEL_XY);
     /* dcl t1.xy */
     inst += 3;
@@ -976,7 +976,7 @@ _STATIC_ void i915_mc_one_time_state_initialization(XvMCContext *context)
     psp_state *psp = NULL;
     psc_state *psc = NULL;
     i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
-    unsigned size;
+    unsigned int size;
     void *base = NULL;
     int mem_select = 1;
 
@@ -1077,7 +1077,7 @@ _STATIC_ void i915_mc_one_time_state_initialization(XvMCContext *context)
     free(base);
 }
 
-_STATIC_ void i915_mc_invalidate_subcontext_buffers(XvMCContext *context, unsigned mask)
+_STATIC_ void i915_mc_invalidate_subcontext_buffers(XvMCContext *context, unsigned int mask)
 {
     struct i915_3dstate_load_indirect *load_indirect = NULL;
     sis_state *sis = NULL;
@@ -1087,7 +1087,7 @@ _STATIC_ void i915_mc_invalidate_subcontext_buffers(XvMCContext *context, unsign
     psp_state *psp = NULL;
     psc_state *psc = NULL;
     i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
-    unsigned size;
+    unsigned int size;
     void *base = NULL, *ptr = NULL;
 
     size = sizeof(*load_indirect);
@@ -1286,7 +1286,7 @@ _STATIC_ void i915_yuv2rgb_map_state_buffer(XvMCSurface *target_surface)
     struct texture_map *tm;
     i915XvMCSurface *privTarget = NULL;
     i915XvMCContext *pI915XvMC = NULL;
-    unsigned w = target_surface->width, h = target_surface->height;
+    unsigned int w = target_surface->width, h = target_surface->height;
 
     privTarget = (i915XvMCSurface *)target_surface->privData;
     pI915XvMC = (i915XvMCContext *)privTarget->privContext;
@@ -1452,7 +1452,7 @@ _STATIC_ void i915_yuv2rgb_sampler_state_buffer(XvMCSurface *surface)
 }
 
 _STATIC_ void i915_yuv2rgb_static_indirect_state_buffer(XvMCSurface *surface,
-                                                      unsigned dstaddr, 
+                                                      unsigned int dstaddr, 
                                                       int dstpitch)
 {
     struct i915_3dstate_buffer_info *buffer_info;
@@ -1490,8 +1490,8 @@ _STATIC_ void i915_yuv2rgb_pixel_shader_program_buffer(XvMCSurface *surface)
     struct i915_3dstate_pixel_shader_program *pixel_shader_program;
     i915XvMCSurface *privSurface = (i915XvMCSurface *)surface->privData;
     i915XvMCContext *pI915XvMC = (i915XvMCContext *)privSurface->privContext;
-    unsigned *inst;
-    unsigned dest, src0, src1;
+    unsigned int *inst;
+    unsigned int dest, src0, src1;
 
     /* Shader 0 */
     pixel_shader_program = (struct i915_3dstate_pixel_shader_program *)pI915XvMC->psp.map;
@@ -1501,7 +1501,7 @@ _STATIC_ void i915_yuv2rgb_pixel_shader_program_buffer(XvMCSurface *surface)
     pixel_shader_program->dw0.retain = 0;
     pixel_shader_program->dw0.length = 23;
     /* dcl      t0.xy */
-    inst = (unsigned *)(++pixel_shader_program);
+    inst = (unsigned int*)(++pixel_shader_program);
     i915_inst_decl(inst, REG_TYPE_T, T_TEX0, D0_CHANNEL_XY);
     /* dcl         t1.xy */
     inst += 3;
@@ -1554,7 +1554,7 @@ _STATIC_ void i915_yuv2rgb_proc(XvMCSurface *surface)
     psp_state *psp = NULL;
     struct i915_3dprimitive *_3dprimitive = NULL;
     struct vertex_data *vd = NULL;
-    unsigned size;
+    unsigned int size;
     void *base = NULL;
 
     /* 3DSTATE_LOAD_STATE_IMMEDIATE_1 */
diff --git a/src/xvmc/I915XvMC.h b/src/xvmc/I915XvMC.h
index 3a83edc..78aea7d 100644
--- a/src/xvmc/I915XvMC.h
+++ b/src/xvmc/I915XvMC.h
@@ -66,13 +66,13 @@ typedef struct _i915XvMCDrmMap {
 //  pointer in the XvMCContext structure.
 ***************************************************************************/
 typedef struct _i915XvMCContext {
-    unsigned ctxno;
+    unsigned int ctxno;
     int fd;   /* File descriptor for /dev/dri */
-    unsigned last_render;
-    unsigned last_flip;
-    unsigned dual_prime; /* Flag to identify when dual prime is in use. */
-    unsigned yStride;
-    unsigned uvStride;
+    unsigned int last_render;
+    unsigned int last_flip;
+    unsigned int dual_prime; /* Flag to identify when dual prime is in use. */
+    unsigned int yStride;
+    unsigned int uvStride;
     unsigned short ref;
     pthread_mutex_t ctxmutex;
     char busIdString[21]; /* PCI:0:1:0 or PCI:0:2:0 */
@@ -84,10 +84,10 @@ typedef struct _i915XvMCContext {
     drm_context_t hHWContext; /* drmcontext; */
     drm_handle_t hsarea;                /* Handle to drm shared memory area */
     drmAddress sarea_address;	        /* Virtual address of shared memory area */
-    unsigned sarea_size;                /* Size of drm shared memory area */
-    unsigned sarea_priv_offset;	        /* Offset in sarea to private part */
-    unsigned screen;
-    unsigned depth;
+    unsigned int sarea_size;                /* Size of drm shared memory area */
+    unsigned int sarea_priv_offset;	        /* Offset in sarea to private part */
+    unsigned int screen;
+    unsigned int depth;
     XvPortID port;		       /* Xv Port ID when displaying */
     int haveXv;                        /* Have I initialized the Xv
                                         * connection for this surface? */
@@ -112,19 +112,19 @@ typedef struct _i915XvMCContext {
     sigset_t sa_mask;
 
     struct {
-        unsigned start_offset;
-        unsigned size;
-        unsigned space;
+        unsigned int start_offset;
+        unsigned int size;
+        unsigned int space;
         unsigned char *ptr;
     } batch;
 
     struct 
     {
         void *ptr;
-        unsigned size;
-        unsigned offset;
-        unsigned active_buf;
-        unsigned irq_emitted;
+        unsigned int size;
+        unsigned int offset;
+        unsigned int active_buf;
+        unsigned int irq_emitted;
     } alloc;
 } i915XvMCContext;
 
@@ -134,10 +134,10 @@ typedef struct _i915XvMCContext {
 //  structure.
 ***************************************************************************/
 typedef struct _i915XvMCSubpicture {
-    unsigned srfNo;
-    unsigned last_render;
-    unsigned last_flip;
-    unsigned pitch;
+    unsigned int srfNo;
+    unsigned int last_render;
+    unsigned int last_flip;
+    unsigned int pitch;
     unsigned char palette[3][16];
     i915XvMCDrmMap srf;
     i915XvMCContext *privContext;
@@ -150,13 +150,13 @@ typedef struct _i915XvMCSubpicture {
 ***************************************************************************/
 #define I830_MAX_BUFS 2                   /*Number of YUV buffers per surface */
 typedef struct _i915XvMCSurface {
-    unsigned srfNo;                    /* XvMC private surface numbers */
-    unsigned last_render;
-    unsigned last_flip;
-    unsigned yStride;                  /* Stride of YUV420 Y component. */
-    unsigned uvStride;
-    unsigned width;                    /* Dimensions */
-    unsigned height;
+    unsigned int srfNo;                    /* XvMC private surface numbers */
+    unsigned int last_render;
+    unsigned int last_flip;
+    unsigned int yStride;                  /* Stride of YUV420 Y component. */
+    unsigned int uvStride;
+    unsigned int width;                    /* Dimensions */
+    unsigned int height;
     i915XvMCDrmMap srf;
     i915XvMCContext *privContext;
     i915XvMCSubpicture *privSubPic;     /* Subpicture to be blended when
commit cfc614b1f9143ed1407733aaa81c4a980c613a63
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Wed Aug 8 09:06:47 2007 +0800

    remove xvmc attributes
    
    We don't have extra attributes than Xv port.

diff --git a/src/i830_video.h b/src/i830_video.h
index 67022f6..7e2d149 100644
--- a/src/i830_video.h
+++ b/src/i830_video.h
@@ -77,7 +77,6 @@ typedef struct {
    int oneLineMode;
    int scaleRatio;
    Bool textured;
-   void *xvmc_priv;
 } I830PortPrivRec, *I830PortPrivPtr;
 
 #define GET_PORT_PRIVATE(pScrn) \
diff --git a/src/i915_hwmc.c b/src/i915_hwmc.c
index 19e2b34..79fe284 100644
--- a/src/i915_hwmc.c
+++ b/src/i915_hwmc.c
@@ -57,31 +57,6 @@
 
 #include "i915_hwmc.h"
 
-#define MAKE_ATOM(a) MakeAtom(a, strlen(a), TRUE)
-
-/*
- * List Attributes for the XvMC extension to handle:
- * As long as the attribute is supported by the Xv adaptor, it needs only to
- * be added here to be supported also by XvMC.
- */
-static char *attrXvMC[I915_NUM_XVMC_ATTRIBUTES] = { 
-    "XV_BRIGHTNESS",
-    "XV_CONTRAST",
-};
-static Atom attrAtoms[I915_NUM_XVMC_ATTRIBUTES];
-
-typedef struct
-{
-    unsigned ctxDisplaying;
-    int xvmc_port;
-    I915XvMCAttrHolder xvAttr;
-    int newAttribute;
-
-    SetPortAttributeFuncPtr SetPortAttribute;
-    GetPortAttributeFuncPtr GetPortAttribute;
-    PutImageFuncPtr PutImage;
-} I915XvMCXVPriv;
-
 #define I915_XVMC_MAX_BUFFERS 2
 #define I915_XVMC_MAX_CONTEXTS 4
 #define I915_XVMC_MAX_SURFACES 20
@@ -484,9 +459,6 @@ static int I915XvMCCreateContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext,
     I915XvMCCreateContextRec *contextRec = NULL;
     I915XvMCPtr pXvMC = pI830->xvmc;
     I915XvMCContextPriv *ctxpriv = NULL;
-    XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)pContext->port_priv;
-    I830PortPrivPtr pPriv = (I830PortPrivPtr)portPriv->DevPriv.ptr;
-    I915XvMCXVPriv *vx = (I915XvMCXVPriv *)pPriv->xvmc_priv;
     int i;
 
     *priv = NULL;
@@ -583,7 +555,6 @@ static int I915XvMCCreateContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext,
     contextRec->screen = pScrn->pScreen->myNum;
     contextRec->depth = pScrn->bitsPerPixel;
     contextRec->deviceID = pI830DRI->deviceID;
-    contextRec->initAttrs = vx->xvAttr;
 
     pXvMC->ncontexts++;
     pXvMC->contexts[i] = pContext->context_id;
@@ -828,70 +799,7 @@ static void I915XvMCDestroySubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSub
     return;
 }
 
-/*
- *
- */
-static int I915XvMCInterceptXvGetAttribute(ScrnInfoPtr pScrn, Atom attribute,
-                                           INT32 * value, pointer data)
-{
-    unsigned i;
-    I830PortPrivPtr pPriv = (I830PortPrivPtr)data;
-    I915XvMCXVPriv *vx = (I915XvMCXVPriv *)pPriv->xvmc_priv;
-    I830Ptr pI830 = I830PTR(pScrn);
-    I915XvMCPtr pXvMC = pI830->xvmc;
-
-    if (I830PTR(pScrn)->XvMCEnabled) {
-        for (i = 0; i < vx->xvAttr.numAttr; ++i) {
-            if (vx->xvAttr.attributes[i].attribute == attribute) {
-                *value = vx->xvAttr.attributes[i].value;
-                return Success;
-            }
-        }
-    }
-
-    return pXvMC->saveGetPortAttribute(pScrn, attribute, value, data);
-}
-
-static int I915XvMCInterceptXvAttribute(ScrnInfoPtr pScrn, Atom attribute,
-                                        INT32 value, pointer data)
-{
-    unsigned i;
-    I830PortPrivPtr pPriv = (I830PortPrivPtr)data;
-    I915XvMCXVPriv *vx = (I915XvMCXVPriv *)pPriv->xvmc_priv;
-    I830Ptr pI830 = I830PTR(pScrn);
-    I915XvMCPtr pXvMC = pI830->xvmc;
-
-    if (pI830->XvMCEnabled) {
-        for (i = 0; i < vx->xvAttr.numAttr; ++i) {
-            if (vx->xvAttr.attributes[i].attribute == attribute) {
-                vx->xvAttr.attributes[i].value = value;
-                return Success;
-            }
-        }
-    }
-
-    return pXvMC->saveSetPortAttribute(pScrn, attribute, value, data);
-}
-
-static int I915XvMCDisplayAttributes(ScrnInfoPtr pScrn,
-                                     const I915XvMCAttrHolder * ah, I830PortPrivPtr pPriv)
-{
-    I830Ptr pI830 = I830PTR(pScrn);
-    I915XvMCPtr pXvMC = pI830->xvmc;
-    unsigned i;
-    int ret;
-
-    for (i = 0; i < ah->numAttr; ++i) {
-        ret = pXvMC->saveSetPortAttribute(pScrn, ah->attributes[i].attribute,
-                                   ah->attributes[i].value, pPriv);
-        if (ret)
-            return ret;
-    }
-
-    return Success;
-}
-
-static int I915XvMCInterceptPutImage(ScrnInfoPtr pScrn, short src_x, short src_y,
+static int I915XvMCPutImage(ScrnInfoPtr pScrn, short src_x, short src_y,
                                      short drw_x, short drw_y, short src_w,
                                      short src_h, short drw_w, short drw_h,
                                      int id, unsigned char *buf, short width,
@@ -899,8 +807,6 @@ static int I915XvMCInterceptPutImage(ScrnInfoPtr pScrn, short src_x, short src_y
                                      DrawablePtr pDraw)
 {
     I830Ptr pI830 = I830PTR(pScrn);
-    I830PortPrivPtr pPriv = (I830PortPrivPtr)data;
-    I915XvMCXVPriv *vx = (I915XvMCXVPriv *)pPriv->xvmc_priv;
     I915XvMCPtr pXvMC = pI830->xvmc;
     I915XvMCCommandBuffer *i915XvMCData = (I915XvMCCommandBuffer *)buf;
     int ret;
@@ -908,19 +814,12 @@ static int I915XvMCInterceptPutImage(ScrnInfoPtr pScrn, short src_x, short src_y
     if (pI830->XvMCEnabled) {
         if (FOURCC_XVMC == id) {
             switch (i915XvMCData->command) {
-            case I915_XVMC_COMMAND_ATTRIBUTES:
-                if ((i915XvMCData->ctxNo | I915_XVMC_VALID) != vx->ctxDisplaying)
-                    return 1;
-
-                I915XvMCDisplayAttributes(pScrn, &i915XvMCData->attrib, pPriv);
-                return 0;
-
             case I915_XVMC_COMMAND_DISPLAY:
 		if ((i915XvMCData->srfNo >= I915_XVMC_MAX_SURFACES) ||
 			!pXvMC->surfaces[i915XvMCData->srfNo] ||
 			!pXvMC->sfprivs[i915XvMCData->srfNo]) {
 		    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-			    "[XvMC] I915XvMCInterceptPutImage: Invalid parameters !\n");
+			    "[XvMC] I915XvMCPutImage: Invalid parameters !\n");
 		    return 1;
 		}
                    
@@ -958,10 +857,7 @@ Bool I915XvMCInit(ScreenPtr pScreen, XF86VideoAdaptorPtr XvAdapt)
 {
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
     I830Ptr pI830 = I830PTR(pScrn);
-    I830PortPrivPtr pPriv;
-    I915XvMCXVPriv *vx;
     I915XvMCPtr pXvMC;
-    int i, j;
 
     if (!IS_I9XX(pI830) || IS_I965G(pI830))
 	return FALSE;
@@ -975,38 +871,9 @@ Bool I915XvMCInit(ScreenPtr pScreen, XF86VideoAdaptorPtr XvAdapt)
     pI830->xvmc = pXvMC;
     initI915XvMC(pXvMC);
 
-    for (j = 0; j < XvAdapt->nPorts; ++j) {
-        pPriv = (I830PortPrivPtr) XvAdapt->pPortPrivates[j].ptr;
-
-        if (NULL == (pPriv->xvmc_priv = xcalloc(1, sizeof(I915XvMCXVPriv)))) {
-	    xfree(pI830->xvmc);
-            return BadAlloc;
-	}
-
-        for (i = 0; i < I915_NUM_XVMC_ATTRIBUTES; ++i)
-            attrAtoms[i] = MAKE_ATOM(attrXvMC[i]);
-
-        vx = (I915XvMCXVPriv *) pPriv->xvmc_priv;
-
-        vx->ctxDisplaying = 0;
-        vx->xvAttr.numAttr = I915_NUM_XVMC_ATTRIBUTES;
-        vx->xvmc_port = -1;
-        vx->newAttribute = 1;
-
-        for (i = 0; i < I915_NUM_XVMC_ATTRIBUTES; ++i) {
-            vx->xvAttr.attributes[i].attribute = attrAtoms[i];
-            XvAdapt->GetPortAttribute(pScrn, attrAtoms[i],
-                                 &(vx->xvAttr.attributes[i].value), pPriv);
-        }
-    }
     /* set up wrappers */
-    pXvMC->saveGetPortAttribute = XvAdapt->GetPortAttribute;
-    pXvMC->saveSetPortAttribute = XvAdapt->SetPortAttribute;
     pXvMC->savePutImage = XvAdapt->PutImage;
-
-    XvAdapt->GetPortAttribute = I915XvMCInterceptXvGetAttribute;
-    XvAdapt->SetPortAttribute = I915XvMCInterceptXvAttribute;
-    XvAdapt->PutImage = I915XvMCInterceptPutImage;
+    XvAdapt->PutImage = I915XvMCPutImage;
     return TRUE;
 }
 
diff --git a/src/i915_hwmc.h b/src/i915_hwmc.h
index 529636e..61c7c4b 100644
--- a/src/i915_hwmc.h
+++ b/src/i915_hwmc.h
@@ -44,19 +44,6 @@
 
 #define I915_XVMC_COMMAND_DISPLAY      0x00
 #define I915_XVMC_COMMAND_UNDISPLAY    0x01
-#define I915_XVMC_COMMAND_ATTRIBUTES   0x02
-
-typedef struct
-{
-    INT32 attribute;
-    INT32 value;
-} I915AttrPair;
-
-typedef struct
-{
-    unsigned numAttr;
-    I915AttrPair attributes[I915_NUM_XVMC_ATTRIBUTES];
-} I915XvMCAttrHolder;
 
 typedef struct
 {
@@ -64,7 +51,6 @@ typedef struct
     unsigned ctxNo;
     unsigned srfNo;
     unsigned subPicNo;
-    I915XvMCAttrHolder attrib;
     int real_id;
     unsigned pad;
 } I915XvMCCommandBuffer;
@@ -92,7 +78,6 @@ typedef struct
     unsigned screen;
     unsigned depth;
     int deviceID;
-    I915XvMCAttrHolder initAttrs;
 } I915XvMCCreateContextRec;
 
 typedef struct 
diff --git a/src/xvmc/I915XvMC.c b/src/xvmc/I915XvMC.c
index 3eb0bc3..7040f6a 100644
--- a/src/xvmc/I915XvMC.c
+++ b/src/xvmc/I915XvMC.c
@@ -122,45 +122,6 @@ _STATIC_ int findOverlap(unsigned width, unsigned height,
     return 0;
 }
 
-_STATIC_ void setupAttribDesc(Display * display, XvPortID port,
-                            const I915XvMCAttrHolder * attrib, XvAttribute attribDesc[])
-{  
-    XvAttribute *XvAttribs, *curAD;
-    int num;
-    unsigned i, j;
-
-    XLockDisplay(display);
-    XvAttribs = XvQueryPortAttributes(display, port, &num);
-    for (i = 0; i < attrib->numAttr; ++i) {
-        curAD = attribDesc + i;
-        curAD->flags = 0;
-        curAD->min_value = 0;
-        curAD->max_value = 0;
-        curAD->name = NULL;
-        for (j = 0; j < num; ++j) {
-            if (attrib->attributes[i].attribute ==
-                XInternAtom(display, XvAttribs[j].name, TRUE)) {
-                *curAD = XvAttribs[j];
-                curAD->name = strdup(XvAttribs[j].name);
-                break;
-            }
-        }
-    }
-    if (XvAttribs)
-        XFree(XvAttribs);
-    XUnlockDisplay(display);
-}
-
-_STATIC_ void releaseAttribDesc(int numAttr, XvAttribute attribDesc[])
-{
-    int i;
-
-    for (i = 0; i < numAttr; ++i) {
-        if (attribDesc[i].name)
-            free(attribDesc[i].name);
-    }
-}
-
 _STATIC_ __inline__ void renderError(void) 
 {
     printf("Invalid Macroblock Parameters found.\n");
@@ -1747,7 +1708,6 @@ _STATIC_ void i915_release_resource(Display *display, XvMCContext *context)
 
     pI915XvMC->ref--;
     i915_xvmc_unmap_buffers(pI915XvMC);
-    releaseAttribDesc(pI915XvMC->attrib.numAttr, pI915XvMC->attribDesc);
 
     driDestroyHashContents(pI915XvMC->drawHash);
     drmHashDestroy(pI915XvMC->drawHash);
@@ -1934,7 +1894,6 @@ Status XvMCCreateContext(Display *display, XvPortID port,
     pI915XvMC->sarea_priv_offset = tmpComm->sarea_priv_offset;
     pI915XvMC->screen = tmpComm->screen;
     pI915XvMC->depth = tmpComm->depth;
-    pI915XvMC->attrib = tmpComm->initAttrs;
 
     /* Must free the private data we were passed from X */
     free(priv_data);
@@ -2047,11 +2006,9 @@ Status XvMCCreateContext(Display *display, XvPortID port,
     }
 
     /* Initialize private context values */
-    setupAttribDesc(display, port, &pI915XvMC->attrib, pI915XvMC->attribDesc);
     pI915XvMC->yStride = STRIDE(width);
     pI915XvMC->uvStride = STRIDE(width >> 1);
     pI915XvMC->haveXv = 0;
-    pI915XvMC->attribChanged = 1;
     pI915XvMC->dual_prime = 0;
     pI915XvMC->last_flip = 0;
     pI915XvMC->locked = 0;
@@ -2582,7 +2539,6 @@ Status XvMCPutSurface(Display *display,XvMCSurface *surface,
     buf.srfNo = pI915Surface->srfNo;
     pI915SubPic = pI915Surface->privSubPic;
     buf.subPicNo = (!pI915SubPic ? 0 : pI915SubPic->srfNo);
-    buf.attrib = pI915XvMC->attrib;
     buf.real_id = FOURCC_YV12;
 
     XLockDisplay(display);
@@ -2598,7 +2554,6 @@ Status XvMCPutSurface(Display *display,XvMCSurface *surface,
 
     XSync(display, 0);
     XUnlockDisplay(display);
-    pI915XvMC->attribChanged = 0;
     PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
 
     return Success;
@@ -3302,29 +3257,9 @@ Status XvMCGetSubpictureStatus(Display *display, XvMCSubpicture *subpicture,
 XvAttribute *XvMCQueryAttributes(Display *display, XvMCContext *context,
                                  int *number) 
 {
-    i915XvMCContext *pI915XvMC;
-    XvAttribute *attributes;
-
-    if (!number)
-        return NULL;
-
+    /* now XvMC has no extra attribs than Xv */
     *number = 0;
-
-    if (!display || !context)
-        return NULL;
-
-    if (!(pI915XvMC = context->privData))
-        return NULL;
-
-    PPTHREAD_MUTEX_LOCK(pI915XvMC);
-    if (NULL != (attributes = (XvAttribute *)
-                 malloc(I915_NUM_XVMC_ATTRIBUTES * sizeof(XvAttribute)))) {
-        memcpy(attributes, pI915XvMC->attribDesc, I915_NUM_XVMC_ATTRIBUTES);
-        *number = I915_NUM_XVMC_ATTRIBUTES;
-    }
-    PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
-
-    return attributes;
+    return NULL;
 }
 
 /***************************************************************************
@@ -3343,52 +3278,6 @@ XvAttribute *XvMCQueryAttributes(Display *display, XvMCContext *context,
 Status XvMCSetAttribute(Display *display, XvMCContext *context,
                         Atom attribute, int value)
 {
-    i915XvMCContext *pI915XvMC;
-    I915XvMCCommandBuffer buf;
-    int found = 0;
-    unsigned i;
-
-    if (!display)
-        return BadValue;
-
-    if (!context || !(pI915XvMC = context->privData))
-        return (error_base + XvMCBadContext);
-
-    PPTHREAD_MUTEX_LOCK(pI915XvMC);
-    for (i = 0; i < pI915XvMC->attrib.numAttr; ++i) {
-        if (attribute == pI915XvMC->attrib.attributes[i].attribute) {
-            if ((!(pI915XvMC->attribDesc[i].flags & XvSettable)) ||
-                value < pI915XvMC->attribDesc[i].min_value ||
-                value > pI915XvMC->attribDesc[i].max_value) {
-                PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
-                return BadValue;
-            }
-
-            pI915XvMC->attrib.attributes[i].value = value;
-            found = 1;
-            pI915XvMC->attribChanged = 1;
-            break;
-        }
-    }
-
-    if (!found) {
-        PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
-        return BadMatch;
-    }
-
-    if (pI915XvMC->haveXv) {
-        buf.command = I915_XVMC_COMMAND_ATTRIBUTES;
-        pI915XvMC->xvImage->data = (char *)&buf;
-        buf.ctxNo = pI915XvMC->ctxno | I915_XVMC_VALID;
-        buf.attrib = pI915XvMC->attrib;
-        XLockDisplay(display);
-        pI915XvMC->attribChanged =
-            XvPutImage(display, pI915XvMC->port, pI915XvMC->draw,
-                       pI915XvMC->gc, pI915XvMC->xvImage, 0, 0, 1, 1, 0, 0, 1, 1);
-        XUnlockDisplay(display);
-    }
-
-    PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
     return Success;
 }
 
@@ -3410,30 +3299,5 @@ Status XvMCSetAttribute(Display *display, XvMCContext *context,
 Status XvMCGetAttribute(Display *display, XvMCContext *context,
                         Atom attribute, int *value) 
 {
-    i915XvMCContext *pI915XvMC;
-    int found = 0;
-    unsigned i;
-
-    if (!display || !value)
-        return BadValue;
-
-    if (!context || !(pI915XvMC = context->privData))
-        return (error_base + XvMCBadContext);
-
-    PPTHREAD_MUTEX_LOCK(pI915XvMC);
-    for (i = 0; i < pI915XvMC->attrib.numAttr; ++i) {
-        if (attribute == pI915XvMC->attrib.attributes[i].attribute) {
-            if (pI915XvMC->attribDesc[i].flags & XvGettable) {
-                *value = pI915XvMC->attrib.attributes[i].value;
-                found = 1;
-                break;
-            }
-        }
-    }
-    PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
-
-    if (!found)
-        return BadMatch;
-    
     return Success;
 }
diff --git a/src/xvmc/I915XvMC.h b/src/xvmc/I915XvMC.h
index 4fc9fc5..3a83edc 100644
--- a/src/xvmc/I915XvMC.h
+++ b/src/xvmc/I915XvMC.h
@@ -89,15 +89,10 @@ typedef struct _i915XvMCContext {
     unsigned screen;
     unsigned depth;
     XvPortID port;		       /* Xv Port ID when displaying */
-    I915XvMCAttrHolder attrib;          /* This contexts attributes and their values */
-    XvAttribute attribDesc[I915_NUM_XVMC_ATTRIBUTES];    /* Attribute decriptions */
     int haveXv;                        /* Have I initialized the Xv
                                         * connection for this surface? */
     XvImage *xvImage;                  /* Fake Xv Image used for command
                                         * buffer transport to the X server */
-    int attribChanged;                 /* Attributes have changed and need to
-                                        * be uploaded to Xv at next frame
-                                        * display */
     GC  gc;                            /* X GC needed for displaying */
     Drawable draw;                     /* Drawable to undisplay from */
     XID id;
commit b29a932bec2a3cc5a38e9c09c012cfdc1b6209c1
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Tue Aug 7 16:47:13 2007 +0800

    code cleanups
    
    and put wrap function in driver xvmc priv instead of per xv port priv

diff --git a/src/i830.h b/src/i830.h
index de37749..a792f38 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -746,8 +746,8 @@ static inline int i830_fb_compression_supported(I830Ptr pI830)
 }
 
 /* i915 XvMC */
-int I915XvMCInitXv(ScrnInfoPtr, XF86VideoAdaptorPtr);
-void I915InitMC(ScreenPtr);
+Bool I915XvMCInit(ScreenPtr, XF86VideoAdaptorPtr);
+Bool I915XvMCScreenInit(ScreenPtr);
 unsigned long I915XvMCPutImageSize(ScrnInfoPtr);
 
 extern const int I830PatternROP[16];
diff --git a/src/i830_driver.c b/src/i830_driver.c
index b617bd4..7957e26 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -2721,14 +2721,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
       pI830->directRenderingEnabled = I830DRIFinishScreenInit(pScreen);
    }
 
-#ifdef XvMCExtension
-   if (pI830->XvEnabled && (pI830->directRenderingEnabled) && 
-       (IS_I915G(pI830) || IS_I915GM(pI830) || 
-        IS_I945G(pI830) || IS_I945GM(pI830) ||
-        IS_G33CLASS(pI830))) {
-       I915InitMC(pScreen);
-   }
-#endif
 #endif
 
    /* Setup 3D engine, needed for rotation too */
diff --git a/src/i830_video.c b/src/i830_video.c
index 4ee9f76..ed68104 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -560,6 +560,7 @@ I830InitVideo(ScreenPtr pScreen)
     XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL;
     XF86VideoAdaptorPtr overlayAdaptor = NULL, texturedAdaptor = NULL;
     int num_adaptors;
+    Bool xvmc_init = FALSE;
 
 #if 0
     {
@@ -602,16 +603,6 @@ I830InitVideo(ScreenPtr pScreen)
 	if (texturedAdaptor != NULL) {
 	    adaptors[num_adaptors++] = texturedAdaptor;
 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Set up textured video\n");
-
-#ifdef XF86DRI
-#ifdef XvMCExtension
-        if (IS_I915G(pI830) || IS_I915GM(pI830) || 
-            IS_I945G(pI830) || IS_I945GM(pI830) ||
-            IS_G33CLASS(pI830)) {
-               I915XvMCInitXv(pScrn, texturedAdaptor);
-        }
-#endif
-#endif
 	} else {
 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 		       "Failed to set up textured video\n");
@@ -633,10 +624,18 @@ I830InitVideo(ScreenPtr pScreen)
 	I830InitOffscreenImages(pScreen);
     }
 
+#ifdef XvMCExtension
+    if (texturedAdaptor)
+	xvmc_init = I915XvMCInit(pScreen, texturedAdaptor);
+#endif
     if (num_adaptors)
 	xf86XVScreenInit(pScreen, adaptors, num_adaptors);
 
     xfree(adaptors);
+#ifdef XvMCExtension
+    if (xvmc_init)
+	I915XvMCScreenInit(pScreen);
+#endif
 }
 
 static void
@@ -2631,11 +2630,7 @@ I830QueryImageAttributes(ScrnInfoPtr pScrn,
 	break;
     case FOURCC_XVMC:
         *h = (*h + 1) & ~1;
-#ifdef XF86DRI
         size = I915XvMCPutImageSize(pScrn);
-#else
-        size = 0;
-#endif
         if (pitches)
             pitches[0] = size;
         break;
diff --git a/src/i915_hwmc.c b/src/i915_hwmc.c
index 158b7b8..19e2b34 100644
--- a/src/i915_hwmc.c
+++ b/src/i915_hwmc.c
@@ -118,6 +118,9 @@ typedef struct _I915XvMC
     I915XvMCSurfacePriv *sfprivs[I915_XVMC_MAX_SURFACES];
     I915XvMCContextPriv *ctxprivs[I915_XVMC_MAX_CONTEXTS];
     int ncontexts,nsurfaces;
+    SetPortAttributeFuncPtr saveSetPortAttribute;
+    GetPortAttributeFuncPtr saveGetPortAttribute;
+    PutImageFuncPtr savePutImage;
 } I915XvMC, *I915XvMCPtr;
 
 #define ARRARY_SIZE(a) (sizeof(a) / sizeof(a[0]))
@@ -234,6 +237,7 @@ static void initI915XvMC(I915XvMCPtr xvmc)
     }
 }
 
+//XXX
 static void cleanupI915XvMC(I915XvMCPtr xvmc, XF86VideoAdaptorPtr * XvAdaptors, int XvAdaptorCount)
 {
     unsigned int i;
@@ -483,15 +487,14 @@ static int I915XvMCCreateContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext,
     XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)pContext->port_priv;
     I830PortPrivPtr pPriv = (I830PortPrivPtr)portPriv->DevPriv.ptr;
     I915XvMCXVPriv *vx = (I915XvMCXVPriv *)pPriv->xvmc_priv;
-
     int i;
 
     *priv = NULL;
     *num_priv = 0;
 
-    if (!pI830->directRenderingEnabled) {
+    if (!pI830->XvMCEnabled) {
         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-                   "[XvMC] I915XvMCCreateContext: Cannot use XvMC without DRI!\n");
+                   "[XvMC] I915XvMCCreateContext: Cannot use XvMC!\n");
         return BadAlloc;
     }
 
@@ -834,6 +837,8 @@ static int I915XvMCInterceptXvGetAttribute(ScrnInfoPtr pScrn, Atom attribute,
     unsigned i;
     I830PortPrivPtr pPriv = (I830PortPrivPtr)data;
     I915XvMCXVPriv *vx = (I915XvMCXVPriv *)pPriv->xvmc_priv;
+    I830Ptr pI830 = I830PTR(pScrn);
+    I915XvMCPtr pXvMC = pI830->xvmc;
 
     if (I830PTR(pScrn)->XvMCEnabled) {
         for (i = 0; i < vx->xvAttr.numAttr; ++i) {
@@ -844,7 +849,7 @@ static int I915XvMCInterceptXvGetAttribute(ScrnInfoPtr pScrn, Atom attribute,
         }
     }
 
-    return vx->GetPortAttribute(pScrn, attribute, value, data);
+    return pXvMC->saveGetPortAttribute(pScrn, attribute, value, data);
 }
 
 static int I915XvMCInterceptXvAttribute(ScrnInfoPtr pScrn, Atom attribute,
@@ -853,8 +858,10 @@ static int I915XvMCInterceptXvAttribute(ScrnInfoPtr pScrn, Atom attribute,
     unsigned i;
     I830PortPrivPtr pPriv = (I830PortPrivPtr)data;
     I915XvMCXVPriv *vx = (I915XvMCXVPriv *)pPriv->xvmc_priv;
+    I830Ptr pI830 = I830PTR(pScrn);
+    I915XvMCPtr pXvMC = pI830->xvmc;
 
-    if (I830PTR(pScrn)->XvMCEnabled) {
+    if (pI830->XvMCEnabled) {
         for (i = 0; i < vx->xvAttr.numAttr; ++i) {
             if (vx->xvAttr.attributes[i].attribute == attribute) {
                 vx->xvAttr.attributes[i].value = value;
@@ -863,18 +870,19 @@ static int I915XvMCInterceptXvAttribute(ScrnInfoPtr pScrn, Atom attribute,
         }
     }
 
-    return vx->SetPortAttribute(pScrn, attribute, value, data);
+    return pXvMC->saveSetPortAttribute(pScrn, attribute, value, data);
 }
 
 static int I915XvMCDisplayAttributes(ScrnInfoPtr pScrn,
                                      const I915XvMCAttrHolder * ah, I830PortPrivPtr pPriv)
 {
-    I915XvMCXVPriv *vx = (I915XvMCXVPriv *) pPriv->xvmc_priv;
+    I830Ptr pI830 = I830PTR(pScrn);
+    I915XvMCPtr pXvMC = pI830->xvmc;
     unsigned i;
     int ret;
 
     for (i = 0; i < ah->numAttr; ++i) {
-        ret = vx->SetPortAttribute(pScrn, ah->attributes[i].attribute,
+        ret = pXvMC->saveSetPortAttribute(pScrn, ah->attributes[i].attribute,
                                    ah->attributes[i].value, pPriv);
         if (ret)
             return ret;
@@ -893,14 +901,12 @@ static int I915XvMCInterceptPutImage(ScrnInfoPtr pScrn, short src_x, short src_y
     I830Ptr pI830 = I830PTR(pScrn);
     I830PortPrivPtr pPriv = (I830PortPrivPtr)data;
     I915XvMCXVPriv *vx = (I915XvMCXVPriv *)pPriv->xvmc_priv;
+    I915XvMCPtr pXvMC = pI830->xvmc;
+    I915XvMCCommandBuffer *i915XvMCData = (I915XvMCCommandBuffer *)buf;
     int ret;
 
-    if (I830PTR(pScrn)->XvMCEnabled) {
+    if (pI830->XvMCEnabled) {
         if (FOURCC_XVMC == id) {
-            I915XvMCPtr pXvMC = pI830->xvmc;
-            I915XvMCCommandBuffer *i915XvMCData = (I915XvMCCommandBuffer *)buf;
-            int i;
-
             switch (i915XvMCData->command) {
             case I915_XVMC_COMMAND_ATTRIBUTES:
                 if ((i915XvMCData->ctxNo | I915_XVMC_VALID) != vx->ctxDisplaying)
@@ -910,33 +916,25 @@ static int I915XvMCInterceptPutImage(ScrnInfoPtr pScrn, short src_x, short src_y
                 return 0;
 
             case I915_XVMC_COMMAND_DISPLAY:
-                for (i = 0; i < I915_XVMC_MAX_SURFACES; i++) {
-                   i830_memory *mem = NULL;
-
-                   if ((i915XvMCData->srfNo >= I915_XVMC_MAX_SURFACES) ||
-                       !pXvMC->surfaces[i915XvMCData->srfNo] ||
-                       !pXvMC->sfprivs[i915XvMCData->srfNo]) {
-                      xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-                                 "[XvMC] I915XvMCInterceptPutImage: Invalid parameters !\n");
-                      return 1;
-                   }
+		if ((i915XvMCData->srfNo >= I915_XVMC_MAX_SURFACES) ||
+			!pXvMC->surfaces[i915XvMCData->srfNo] ||
+			!pXvMC->sfprivs[i915XvMCData->srfNo]) {
+		    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+			    "[XvMC] I915XvMCInterceptPutImage: Invalid parameters !\n");
+		    return 1;
+		}
                    
-                   mem = pXvMC->sfprivs[i915XvMCData->srfNo]->surface;
-                   buf = pI830->FbBase + mem->offset;
-                   id = i915XvMCData->real_id;
-                   pI830->IsXvMCSurface = 1;
-                   break;
-                }
-
-                break;
-
+		buf = pI830->FbBase + pXvMC->sfprivs[i915XvMCData->srfNo]->surface->offset;
+		id = i915XvMCData->real_id;
+		pI830->IsXvMCSurface = 1;
+		break;
             default:
                 return 0;
             }
         }
     }
 
-    ret = vx->PutImage(pScrn, src_x, src_y, drw_x, drw_y, src_w, src_h,
+    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;
@@ -955,57 +953,38 @@ static int I915XvMCInterceptPutImage(ScrnInfoPtr pScrn, short src_x, short src_y
  *    None
  *  
  **************************************************************************/
-void I915InitMC(ScreenPtr pScreen)
+
+Bool I915XvMCInit(ScreenPtr pScreen, XF86VideoAdaptorPtr XvAdapt)
 {
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
     I830Ptr pI830 = I830PTR(pScrn);
-    I915XvMCPtr pXvMC = NULL; 
+    I830PortPrivPtr pPriv;
+    I915XvMCXVPriv *vx;
+    I915XvMCPtr pXvMC;
+    int i, j;
 
-    pI830->XvMCEnabled = FALSE;
-    if (!pI830->directRenderingEnabled) {
-        xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-                   "[XvMC] Cannot use XvMC without DRI!\n");
-        return;
-    }
+    if (!IS_I9XX(pI830) || IS_I965G(pI830))
+	return FALSE;
 
-    pXvMC = (I915XvMCPtr)calloc(1, sizeof(I915XvMC));
+    pXvMC = (I915XvMCPtr)xcalloc(1, sizeof(I915XvMC));
     if (!pXvMC) {
         xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-                   "[XvMC] Failure!\n");
-        return;
+                   "[XvMC] alloc driver private failed!\n");
+        return FALSE;
     }
-
     pI830->xvmc = pXvMC;
     initI915XvMC(pXvMC);
-    xf86XvMCScreenInit(pScreen, 1, ppAdapt);
-    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-               "[XvMC] Initialized XvMC extension.\n");
-    pI830->XvMCEnabled = TRUE;
-}
-
-int I915XvMCInitXv(ScrnInfoPtr pScrn, XF86VideoAdaptorPtr XvAdapt)
-{
-    I830PortPrivPtr pPriv;
-    I915XvMCXVPriv *vx;
-    unsigned i, j;
-    SetPortAttributeFuncPtr setportattribute = XvAdapt->SetPortAttribute;
-    GetPortAttributeFuncPtr getportattribute = XvAdapt->GetPortAttribute;
-    PutImageFuncPtr putimage = XvAdapt->PutImage;
-
-    XvAdapt->GetPortAttribute = I915XvMCInterceptXvGetAttribute;
-    XvAdapt->SetPortAttribute = I915XvMCInterceptXvAttribute;
-    XvAdapt->PutImage = I915XvMCInterceptPutImage;
 
     for (j = 0; j < XvAdapt->nPorts; ++j) {
         pPriv = (I830PortPrivPtr) XvAdapt->pPortPrivates[j].ptr;
 
         if (NULL == (pPriv->xvmc_priv = xcalloc(1, sizeof(I915XvMCXVPriv)))) {
+	    xfree(pI830->xvmc);
             return BadAlloc;
-        }
+	}
 
-        for (i = 0; i < I915_NUM_XVMC_ATTRIBUTES; ++i) {
+        for (i = 0; i < I915_NUM_XVMC_ATTRIBUTES; ++i)
             attrAtoms[i] = MAKE_ATOM(attrXvMC[i]);
-        }
 
         vx = (I915XvMCXVPriv *) pPriv->xvmc_priv;
 
@@ -1014,24 +993,48 @@ int I915XvMCInitXv(ScrnInfoPtr pScrn, XF86VideoAdaptorPtr XvAdapt)
         vx->xvmc_port = -1;
         vx->newAttribute = 1;
 
-        /* set up wrappers */
-        vx->GetPortAttribute = getportattribute;
-        vx->SetPortAttribute = setportattribute;
-        vx->PutImage = putimage;
-
         for (i = 0; i < I915_NUM_XVMC_ATTRIBUTES; ++i) {
             vx->xvAttr.attributes[i].attribute = attrAtoms[i];
-            vx->xvAttr.attributes[i].value = 0;
-            vx->GetPortAttribute(pScrn, attrAtoms[i],
+            XvAdapt->GetPortAttribute(pScrn, attrAtoms[i],
                                  &(vx->xvAttr.attributes[i].value), pPriv);
         }
     }
-    return Success;
+    /* set up wrappers */
+    pXvMC->saveGetPortAttribute = XvAdapt->GetPortAttribute;
+    pXvMC->saveSetPortAttribute = XvAdapt->SetPortAttribute;
+    pXvMC->savePutImage = XvAdapt->PutImage;
+
+    XvAdapt->GetPortAttribute = I915XvMCInterceptXvGetAttribute;
+    XvAdapt->SetPortAttribute = I915XvMCInterceptXvAttribute;
+    XvAdapt->PutImage = I915XvMCInterceptPutImage;
+    return TRUE;
+}
+
+Bool I915XvMCScreenInit(ScreenPtr pScreen)
+{
+    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+    I830Ptr pI830 = I830PTR(pScrn);
+
+    if (xf86XvMCScreenInit(pScreen, 1, ppAdapt)) {
+	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+		"[XvMC] Initialized XvMC.\n");
+	pI830->XvMCEnabled = TRUE;
+    } else {
+        xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+		"[XvMC] xf86 XvMC initial failed\n");
+	pI830->XvMCEnabled = FALSE;
+	xfree(pI830->xvmc);
+	pI830->xvmc = NULL;
+	return FALSE;
+    }
+    return TRUE;
 }
 
 unsigned long I915XvMCPutImageSize(ScrnInfoPtr pScrn)
 {
-    if (I830PTR(pScrn)->XvMCEnabled)
+    I830Ptr pI830 = I830PTR(pScrn);
+
+    if (pI830->XvMCEnabled)
         return sizeof(I915XvMCCommandBuffer);
 
     return 0;
commit c4deefa80a6349db968e25bd6778cdf7a514ca7f
Author: Xiang, Haihao <haihao.xiang at intel.com>
Date:   Mon Jul 23 10:35:32 2007 +0800

    only enable xvmc for 915/945/G33

diff --git a/src/i830_driver.c b/src/i830_driver.c
index f24d1ad..b617bd4 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -2722,7 +2722,10 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
    }
 
 #ifdef XvMCExtension
-   if (pI830->XvEnabled && (pI830->directRenderingEnabled) && IS_I9XX(pI830)) {
+   if (pI830->XvEnabled && (pI830->directRenderingEnabled) && 
+       (IS_I915G(pI830) || IS_I915GM(pI830) || 
+        IS_I945G(pI830) || IS_I945GM(pI830) ||
+        IS_G33CLASS(pI830))) {
        I915InitMC(pScreen);
    }
 #endif
diff --git a/src/i830_video.c b/src/i830_video.c
index a74634f..4ee9f76 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -605,8 +605,11 @@ I830InitVideo(ScreenPtr pScreen)
 
 #ifdef XF86DRI
 #ifdef XvMCExtension
-            if (IS_I9XX(pI830))
+        if (IS_I915G(pI830) || IS_I915GM(pI830) || 
+            IS_I945G(pI830) || IS_I945GM(pI830) ||
+            IS_G33CLASS(pI830)) {
                I915XvMCInitXv(pScrn, texturedAdaptor);
+        }
 #endif
 #endif
 	} else {
commit a52c53b8603495ab05e07e3da5092fe122fcb6f2
Author: Xiang, Haihao <haihao.xiang at intel.com>
Date:   Fri Jul 20 17:10:27 2007 +0800

    don't initialize XvMC if xv is disabled.

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 9cae291..f24d1ad 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -2722,7 +2722,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
    }
 
 #ifdef XvMCExtension
-   if ((pI830->directRenderingEnabled) && IS_I9XX(pI830)) {
+   if (pI830->XvEnabled && (pI830->directRenderingEnabled) && IS_I9XX(pI830)) {
        I915InitMC(pScreen);
    }
 #endif
diff --git a/src/i830_video.c b/src/i830_video.c
index 1c1fbab..a74634f 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -604,9 +604,11 @@ I830InitVideo(ScreenPtr pScreen)
 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Set up textured video\n");
 
 #ifdef XF86DRI
-            if (/* pI830->XvMCEnabled && */IS_I9XX(pI830))
+#ifdef XvMCExtension
+            if (IS_I9XX(pI830))
                I915XvMCInitXv(pScrn, texturedAdaptor);
 #endif
+#endif
 	} else {
 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 		       "Failed to set up textured video\n");
commit 6b4d43dbf4bbb86d479d8fca480c8bec39e2714b
Author: Xiang, Haihao <haihao.xiang at intel.com>
Date:   Fri Jul 20 09:59:40 2007 +0800

    lock display when creating context

diff --git a/src/xvmc/I915XvMC.c b/src/xvmc/I915XvMC.c
index 5efd762..3eb0bc3 100644
--- a/src/xvmc/I915XvMC.c
+++ b/src/xvmc/I915XvMC.c
@@ -1841,8 +1841,8 @@ Status XvMCCreateContext(Display *display, XvPortID port,
     /* Verify the XvMC extension exists */
     XLockDisplay(display);
     if (!XvMCQueryExtension(display, &event_base, &error_base)) {
-        printf("XvMCExtension is not available!\n");
         XUnlockDisplay(display);
+        printf("XvMCExtension is not available!\n");
         return BadAlloc;
     }
     /* Verify XvMC version */
@@ -1873,12 +1873,15 @@ Status XvMCCreateContext(Display *display, XvPortID port,
       Pass control to the X server to create a drm_context_t for us and
       validate the with/height and flags.
     */
+    XLockDisplay(display);
     if ((ret = _xvmc_create_context(display, context, &priv_count, &priv_data))) {
+        XUnlockDisplay(display);
         printf("Unable to create XvMC Context.\n");
         free(pI915XvMC);
         context->privData = NULL;
         return ret;
     }
+    XUnlockDisplay(display);
 
     if (priv_count != (sizeof(I915XvMCCreateContextRec) >> 2)) {
         printf("_xvmc_create_context() returned incorrect data size!\n");
commit 42e91c7092f9cf7f5c0b98e9ae3d92a5b30821bf
Author: Xiang, Haihao <haihao.xiang at intel.com>
Date:   Thu Jul 19 17:30:54 2007 +0800

    move i830_allocate_xvmc_buffer out of  #if/#endif

diff --git a/src/i830_memory.c b/src/i830_memory.c
index fcf0ebf..b2c5149 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -1759,6 +1759,8 @@ i830_xf86AllocateOffscreenLinear(ScreenPtr pScreen, int length,
     return linear;
 }
 
+#endif
+
 /*
  * Allocate memory for MC compensation
  */
@@ -1777,4 +1779,3 @@ Bool i830_allocate_xvmc_buffer(ScrnInfoPtr pScrn, const char *name,
 
     return TRUE;
 }
-#endif
commit 36ea26f2779d951fa173da785aca100564e5ecf8
Author: Xiang, Haihao <haihao.xiang at intel.com>
Date:   Thu Jul 19 17:21:05 2007 +0800

    add copyright

diff --git a/src/i915_hwmc.c b/src/i915_hwmc.c
index c82001a..158b7b8 100644
--- a/src/i915_hwmc.c
+++ b/src/i915_hwmc.c
@@ -1,3 +1,29 @@
+/*
+ * Copyright © 2006 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *    Xiang Haihao <haihao.xiang at intel.com>
+ *
+ */
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
diff --git a/src/i915_hwmc.h b/src/i915_hwmc.h
index eac82e3..529636e 100644
--- a/src/i915_hwmc.h
+++ b/src/i915_hwmc.h
@@ -1,3 +1,29 @@
+/*
+ * Copyright © 2006 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *    Xiang Haihao <haihao.xiang at intel.com>
+ *
+ */
 #ifndef _I915_HWMC_H
 #define _I915_HWMC_H
 
diff --git a/src/xvmc/I915XvMC.c b/src/xvmc/I915XvMC.c
index c2a1c00..5efd762 100644
--- a/src/xvmc/I915XvMC.c
+++ b/src/xvmc/I915XvMC.c
@@ -1,3 +1,29 @@
+/*
+ * Copyright © 2006 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *    Xiang Haihao <haihao.xiang at intel.com>
+ *
+ */
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
@@ -1078,6 +1104,7 @@ _STATIC_ void i915_mc_one_time_state_initialization(XvMCContext *context)
     /* PSC */
     psc = (psc_state *)(++psp);
     psc->dw0.valid = 1;
+    psc->dw0.force = 1;
     psc->dw1.length = 5; /* 6 - 1 */
 
     if (mem_select)
@@ -2403,8 +2430,8 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context,
     } 
 
     i915_flush(pI915XvMC, 1, 0);
-    i915_mc_invalidate_subcontext_buffers(context, BLOCK_SIS | BLOCK_DIS | BLOCK_SSB 
-                                          | BLOCK_MSB | BLOCK_PSP | BLOCK_PSC);
+    // 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);
diff --git a/src/xvmc/I915XvMC.h b/src/xvmc/I915XvMC.h
index 5b88d49..4fc9fc5 100644
--- a/src/xvmc/I915XvMC.h
+++ b/src/xvmc/I915XvMC.h
@@ -1,28 +1,29 @@
-/***************************************************************************
-
-Copyright 2001 Intel Corporation.  All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sub license, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice (including the
-next paragraph) shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
-IN NO EVENT SHALL INTEL, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
-DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
-THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
+/*
+ * Copyright © 2006 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *    Xiang Haihao <haihao.xiang at intel.com>
+ *
+ */
 
 #ifndef _I915XVMC_H
 #define _I915XVMC_H
diff --git a/src/xvmc/i915_structs.h b/src/xvmc/i915_structs.h
index 042a4ad..a25d734 100644
--- a/src/xvmc/i915_structs.h
+++ b/src/xvmc/i915_structs.h
@@ -1,3 +1,30 @@
+/*
+ * Copyright © 2006 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *    Xiang Haihao <haihao.xiang at intel.com>
+ *
+ */
+
 #ifndef _I915_STRUCTS_H
 #define _I915_STRUCTS_H
 
diff --git a/src/xvmc/intel_batchbuffer.c b/src/xvmc/intel_batchbuffer.c
index dd54330..ecd57b5 100644
--- a/src/xvmc/intel_batchbuffer.c
+++ b/src/xvmc/intel_batchbuffer.c
@@ -1,3 +1,30 @@
+/**************************************************************************
+ *
+ * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
commit 9d03873423c0968b2d6700b7d8d44c7e23b8d7f3
Author: Xiang, Haihao <haihao.xiang at intel.com>
Date:   Thu Jul 19 10:03:19 2007 +0800

    block some signals within critical section to avoid
    
    dead lock.

diff --git a/src/i830_video.c b/src/i830_video.c
index 015b426..1c1fbab 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2383,8 +2383,8 @@ I830PutImage(ScrnInfoPtr pScrn,
     case FOURCC_YV12:
     case FOURCC_I420:
         if (pI830->IsXvMCSurface) {
-            srcPitch = (width + 0x400) & ~0x3ff;
-            srcPitch2 = ((width >> 1) + 0x400) & ~0x3ff;
+            srcPitch = (width + 0x3ff) & ~0x3ff;
+            srcPitch2 = ((width >> 1) + 0x3ff) & ~0x3ff;
         } else {
             srcPitch = (width + 0x3) & ~0x3;
             srcPitch2 = ((width >> 1) + 0x3) & ~0x3;
diff --git a/src/i915_hwmc.c b/src/i915_hwmc.c
index b5bd13e..c82001a 100644
--- a/src/i915_hwmc.c
+++ b/src/i915_hwmc.c
@@ -37,7 +37,6 @@
  * List Attributes for the XvMC extension to handle:
  * As long as the attribute is supported by the Xv adaptor, it needs only to
  * be added here to be supported also by XvMC.
- * Currently, only colorkey seems to be supported by Xv for Putimage.
  */
 static char *attrXvMC[I915_NUM_XVMC_ATTRIBUTES] = { 
     "XV_BRIGHTNESS",
diff --git a/src/i915_hwmc.h b/src/i915_hwmc.h
index f2570ce..eac82e3 100644
--- a/src/i915_hwmc.h
+++ b/src/i915_hwmc.h
@@ -54,7 +54,6 @@ struct hwmc_buffer
 typedef struct 
 {
     unsigned ctxno; /* XvMC private context reference number */
-    drm_context_t drmcontext;
     struct hwmc_buffer sis;
     struct hwmc_buffer ssb;
     struct hwmc_buffer msb;
diff --git a/src/xvmc/I915XvMC.c b/src/xvmc/I915XvMC.c
index 3b086c2..c2a1c00 100644
--- a/src/xvmc/I915XvMC.c
+++ b/src/xvmc/I915XvMC.c
@@ -26,7 +26,7 @@
 #include "xf86dri.h"
 #include "driDrawable.h"
 
-#define _STATIC_
+#define _STATIC_ static
 
 #define SAREAPTR(ctx) ((drmI830Sarea *)                     \
                        (((CARD8 *)(ctx)->sarea_address) +   \
@@ -146,12 +146,38 @@ _STATIC_ void I915XvMCContendedLock(i915XvMCContext *pI915XvMC, unsigned flags)
     drmGetLock(pI915XvMC->fd, pI915XvMC->hHWContext, flags);
 }
 
+#define SET_BLOCKED_SIGSET(pI915XvMC)   do {    \
+        sigset_t bl_mask;                       \
+        sigfillset(&bl_mask);           \
+        sigdelset(&bl_mask, SIGFPE);    \
+        sigdelset(&bl_mask, SIGILL);    \
+        sigdelset(&bl_mask, SIGSEGV);   \
+        sigdelset(&bl_mask, SIGBUS);    \
+        sigdelset(&bl_mask, SIGKILL);   \
+        pthread_sigmask(SIG_SETMASK, &bl_mask, &pI915XvMC->sa_mask); \
+    } while (0)
+
+#define RESTORE_BLOCKED_SIGSET(pI915XvMC) do {    \
+        pthread_sigmask(SIG_SETMASK, &pI915XvMC->sa_mask, NULL); \
+    } while (0)
+
+#define PPTHREAD_MUTEX_LOCK(pI915XvMC) do {             \
+        SET_BLOCKED_SIGSET(pI915XvMC);                  \
+        pthread_mutex_lock(&pI915XvMC->ctxmutex);       \
+    } while (0)
+
+#define PPTHREAD_MUTEX_UNLOCK(pI915XvMC) do {           \
+        pthread_mutex_unlock(&pI915XvMC->ctxmutex);     \
+        RESTORE_BLOCKED_SIGSET(pI915XvMC);              \
+    } while (0)
+
 /* Lock the hardware and validate our state.
  */
 _STATIC_ void LOCK_HARDWARE(i915XvMCContext  *pI915XvMC)
 {
     char __ret = 0;
-    pthread_mutex_lock(&pI915XvMC->ctxmutex);
+
+    PPTHREAD_MUTEX_LOCK(pI915XvMC);
     assert(!pI915XvMC->locked);
 
     DRM_CAS(pI915XvMC->driHwLock, pI915XvMC->hHWContext,
@@ -170,7 +196,7 @@ _STATIC_ void UNLOCK_HARDWARE(i915XvMCContext *pI915XvMC)
     pI915XvMC->locked = 0;
     DRM_UNLOCK(pI915XvMC->fd, pI915XvMC->driHwLock, 
                pI915XvMC->hHWContext);
-    pthread_mutex_unlock(&pI915XvMC->ctxmutex);
+    PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
 }
 
 _STATIC_ void i915_flush(i915XvMCContext *pI915XvMC, int map, int render)
@@ -2049,11 +2075,11 @@ Status XvMCCreateSurface(Display *display, XvMCContext *context, XvMCSurface *su
     if (!(pI915XvMC = context->privData))
         return (error_base + XvMCBadContext);
 
-    pthread_mutex_lock(&pI915XvMC->ctxmutex);
+    PPTHREAD_MUTEX_LOCK(pI915XvMC);
     surface->privData = (i915XvMCSurface *)malloc(sizeof(i915XvMCSurface));
 
     if (!(pI915Surface = surface->privData)) {
-        pthread_mutex_unlock(&pI915XvMC->ctxmutex);
+        PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
         return BadAlloc;
     }
 
@@ -2075,7 +2101,7 @@ Status XvMCCreateSurface(Display *display, XvMCContext *context, XvMCSurface *su
         printf("Unable to create XvMCSurface.\n");
         free(pI915Surface);
         surface->privData = NULL;
-        pthread_mutex_unlock(&pI915XvMC->ctxmutex);
+        PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
         return ret;
     }
 
@@ -2089,7 +2115,7 @@ Status XvMCCreateSurface(Display *display, XvMCContext *context, XvMCSurface *su
         free(priv_data);
         free(pI915Surface);
         surface->privData = NULL;
-        pthread_mutex_unlock(&pI915XvMC->ctxmutex);
+        PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
         return BadAlloc;
     }
 
@@ -2108,12 +2134,12 @@ Status XvMCCreateSurface(Display *display, XvMCContext *context, XvMCSurface *su
         _xvmc_destroy_surface(display, surface);
         free(pI915Surface);
         surface->privData = NULL;
-        pthread_mutex_unlock(&pI915XvMC->ctxmutex);
+        PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
         return BadAlloc;
     }
 
     pI915XvMC->ref++;
-    pthread_mutex_unlock(&pI915XvMC->ctxmutex);
+    PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
     return Success;
 }
 
@@ -2501,12 +2527,12 @@ Status XvMCPutSurface(Display *display,XvMCSurface *surface,
     if (!(pI915XvMC = pI915Surface->privContext))
         return (error_base + XvMCBadSurface);
 
-    pthread_mutex_lock(&pI915XvMC->ctxmutex);
+    PPTHREAD_MUTEX_LOCK(pI915XvMC);
     /*
     if (getDRIDrawableInfoLocked(pI915XvMC->drawHash, display,
                                  pI915XvMC->screen, draw, 0, pI915XvMC->fd, pI915XvMC->hHWContext,
                                  pI915XvMC->sarea_address, FALSE, &drawInfo, sizeof(*drawInfo))) {
-        pthread_mutex_unlock(&pI915XvMC->ctxmutex);
+        PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
         return BadAccess;
     }
     */
@@ -2535,7 +2561,7 @@ Status XvMCPutSurface(Display *display,XvMCSurface *surface,
                           pI915XvMC->xvImage, srcx, srcy, srcw, srch,
                           destx, desty, destw, desth))) {
         XUnlockDisplay(display);
-        pthread_mutex_unlock(&pI915XvMC->ctxmutex);
+        PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
 
         return ret;
     }
@@ -2543,7 +2569,7 @@ Status XvMCPutSurface(Display *display,XvMCSurface *surface,
     XSync(display, 0);
     XUnlockDisplay(display);
     pI915XvMC->attribChanged = 0;
-    pthread_mutex_unlock(&pI915XvMC->ctxmutex);
+    PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
 
     return Success;
 }
@@ -2611,12 +2637,13 @@ Status XvMCGetSurfaceStatus(Display *display, XvMCSurface *surface, int *stat)
     if (!(pI915XvMC = pI915Surface->privContext))
         return (error_base + XvMCBadSurface);
 
-    LOCK_HARDWARE(pI915XvMC);
-
+    // LOCK_HARDWARE(pI915XvMC);
+    PPTHREAD_MUTEX_LOCK(pI915XvMC);
     if (pI915Surface->last_flip) {
         /* This can not happen */
         if (pI915XvMC->last_flip < pI915Surface->last_flip) {
             printf("Error: Context last flip is less than surface last flip.\n");
+            PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
             return BadValue;
         }
 
@@ -2640,7 +2667,8 @@ Status XvMCGetSurfaceStatus(Display *display, XvMCSurface *surface, int *stat)
         *stat |= XVMC_RENDERING;
     }
 
-    UNLOCK_HARDWARE(pI915XvMC);
+    // UNLOCK_HARDWARE(pI915XvMC);
+    PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
     return Success;
 }
 
@@ -2739,28 +2767,36 @@ Status XvMCCreateSubpicture(Display *display, XvMCContext *context,
     if (!subpicture->privData)
         return BadAlloc;
 
+    PPTHREAD_MUTEX_LOCK(pI915XvMC);
     subpicture->context_id = context->context_id;
     subpicture->xvimage_id = xvimage_id;
     subpicture->width = width;
     subpicture->height = height;
     pI915Subpicture = (i915XvMCSubpicture *)subpicture->privData;
 
+    XLockDisplay(display);
     if ((ret = _xvmc_create_subpicture(display, context, subpicture,
                                        &priv_count, &priv_data))) {
+        XUnlockDisplay(display);
         printf("Unable to create XvMCSubpicture.\n");
         free(pI915Subpicture);
         subpicture->privData = NULL;
+        PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
         return ret;
     }
+    XUnlockDisplay(display);
 
     if (priv_count != (sizeof(I915XvMCCreateSurfaceRec) >> 2)) {
         printf("_xvmc_create_subpicture() returned incorrect data size!\n");
         printf("\tExpected %d, got %d\n", 
                (int)(sizeof(I915XvMCCreateSurfaceRec) >> 2), priv_count);
+        XLockDisplay(display);
         _xvmc_destroy_subpicture(display, subpicture);
+        XUnlockDisplay(display);
         free(priv_data);
         free(pI915Subpicture);
         subpicture->privData = NULL;
+        PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
         return BadAlloc;
     }
 
@@ -2775,9 +2811,12 @@ Status XvMCCreateSubpicture(Display *display, XvMCContext *context,
                pI915Subpicture->srf.handle,
                pI915Subpicture->srf.size,
                (drmAddress *)&pI915Subpicture->srf.map) != 0) {
+        XLockDisplay(display);
         _xvmc_destroy_subpicture(display, subpicture);
+        XUnlockDisplay(display);
         free(pI915Subpicture);
         subpicture->privData = NULL;
+        PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
         return BadAlloc;
     }
 
@@ -2799,13 +2838,17 @@ Status XvMCCreateSubpicture(Display *display, XvMCContext *context,
 
     default:
         drmUnmap(pI915Subpicture->srf.map, pI915Subpicture->srf.size);
+        XLockDisplay(display);
         _xvmc_destroy_subpicture(display, subpicture);
+        XUnlockDisplay(display);
         free(pI915Subpicture);
         subpicture->privData = NULL;
+        PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
         return BadMatch;
     }
 
     pI915XvMC->ref++;
+    PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
     return Success;
 }
 
@@ -2931,6 +2974,7 @@ Status XvMCDestroySubpicture(Display *display, XvMCSubpicture *subpicture)
     if (pI915Subpicture->srf.map)
         drmUnmap(pI915Subpicture->srf.map, pI915Subpicture->srf.size);
 
+    PPTHREAD_MUTEX_LOCK(pI915XvMC);
     XLockDisplay(display);
     _xvmc_destroy_subpicture(display,subpicture);
     XUnlockDisplay(display);
@@ -2938,6 +2982,7 @@ Status XvMCDestroySubpicture(Display *display, XvMCSubpicture *subpicture)
     free(pI915Subpicture);
     subpicture->privData = NULL;
     pI915XvMC->ref--;
+    PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
 
     return Success;
 }
@@ -3197,14 +3242,16 @@ Status XvMCGetSubpictureStatus(Display *display, XvMCSubpicture *subpicture,
     if (!(pI915XvMC = pI915Subpicture->privContext))
         return (error_base + XvMCBadSubpicture);
 
-    LOCK_HARDWARE(pI915XvMC);
+    // LOCK_HARDWARE(pI915XvMC);
+    PPTHREAD_MUTEX_LOCK(pI915XvMC);
     /* FIXME: */
     if (pI915Subpicture->last_render &&
         (pI915Subpicture->last_render > pI915XvMC->sarea->last_dispatch)) {
         *stat |= XVMC_RENDERING;
     }
 
-    UNLOCK_HARDWARE(pI915XvMC);
+    // UNLOCK_HARDWARE(pI915XvMC);
+    PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
     return Success;
 }
 
@@ -3239,13 +3286,13 @@ XvAttribute *XvMCQueryAttributes(Display *display, XvMCContext *context,
     if (!(pI915XvMC = context->privData))
         return NULL;
 
-    pthread_mutex_lock(&pI915XvMC->ctxmutex);
+    PPTHREAD_MUTEX_LOCK(pI915XvMC);
     if (NULL != (attributes = (XvAttribute *)
                  malloc(I915_NUM_XVMC_ATTRIBUTES * sizeof(XvAttribute)))) {
         memcpy(attributes, pI915XvMC->attribDesc, I915_NUM_XVMC_ATTRIBUTES);
         *number = I915_NUM_XVMC_ATTRIBUTES;
     }
-    pthread_mutex_unlock(&pI915XvMC->ctxmutex);
+    PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
 
     return attributes;
 }
@@ -3277,13 +3324,15 @@ Status XvMCSetAttribute(Display *display, XvMCContext *context,
     if (!context || !(pI915XvMC = context->privData))
         return (error_base + XvMCBadContext);
 
-    pthread_mutex_lock(&pI915XvMC->ctxmutex);
+    PPTHREAD_MUTEX_LOCK(pI915XvMC);
     for (i = 0; i < pI915XvMC->attrib.numAttr; ++i) {
         if (attribute == pI915XvMC->attrib.attributes[i].attribute) {
             if ((!(pI915XvMC->attribDesc[i].flags & XvSettable)) ||
                 value < pI915XvMC->attribDesc[i].min_value ||
-                value > pI915XvMC->attribDesc[i].max_value)
+                value > pI915XvMC->attribDesc[i].max_value) {
+                PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
                 return BadValue;
+            }
 
             pI915XvMC->attrib.attributes[i].value = value;
             found = 1;
@@ -3293,7 +3342,7 @@ Status XvMCSetAttribute(Display *display, XvMCContext *context,
     }
 
     if (!found) {
-        pthread_mutex_unlock(&pI915XvMC->ctxmutex);
+        PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
         return BadMatch;
     }
 
@@ -3309,7 +3358,7 @@ Status XvMCSetAttribute(Display *display, XvMCContext *context,
         XUnlockDisplay(display);
     }
 
-    pthread_mutex_unlock(&pI915XvMC->ctxmutex);
+    PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
     return Success;
 }
 
@@ -3341,7 +3390,7 @@ Status XvMCGetAttribute(Display *display, XvMCContext *context,
     if (!context || !(pI915XvMC = context->privData))
         return (error_base + XvMCBadContext);
 
-    pthread_mutex_lock(&pI915XvMC->ctxmutex);
+    PPTHREAD_MUTEX_LOCK(pI915XvMC);
     for (i = 0; i < pI915XvMC->attrib.numAttr; ++i) {
         if (attribute == pI915XvMC->attrib.attributes[i].attribute) {
             if (pI915XvMC->attribDesc[i].flags & XvGettable) {
@@ -3351,7 +3400,7 @@ Status XvMCGetAttribute(Display *display, XvMCContext *context,
             }
         }
     }
-    pthread_mutex_unlock(&pI915XvMC->ctxmutex);
+    PPTHREAD_MUTEX_UNLOCK(pI915XvMC);
 
     if (!found)
         return BadMatch;
diff --git a/src/xvmc/I915XvMC.h b/src/xvmc/I915XvMC.h
index 7f47f43..5b88d49 100644
--- a/src/xvmc/I915XvMC.h
+++ b/src/xvmc/I915XvMC.h
@@ -35,6 +35,7 @@ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "i915_hwmc.h"
 #include <X11/Xlibint.h>
 #include <X11/Xutil.h>
+#include <signal.h>
 
 #define I915_SUBPIC_PALETTE_SIZE        16
 #define MAX_SUBCONTEXT_LEN              1024
@@ -112,6 +113,8 @@ typedef struct _i915XvMCContext {
     i915XvMCDrmMap corrdata;
     i915XvMCDrmMap batchbuffer;
 
+    sigset_t sa_mask;
+
     struct {
         unsigned start_offset;
         unsigned size;
commit 25658f838bd1bcd7559d7a032d127c626833fb7c
Author: Xiang, Haihao <haihao.xiang at intel.com>
Date:   Mon Jul 16 13:03:58 2007 +0800

    1. The pitches for y/u/v surfaces are 1024bytes aligned.
    
    2. clean code

diff --git a/src/i830.h b/src/i830.h
index cde15ad..de37749 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -313,7 +313,8 @@ typedef struct _I830Rec {
    /* For XvMC */
    void *xvmc;
    Bool XvMCEnabled;
-
+   Bool IsXvMCSurface;
+ 
    XF86ModReqInfo shadowReq; /* to test for later libshadow */
    Rotation rotation;
    void (*PointerMoved)(int, int, int);
diff --git a/src/i830_video.c b/src/i830_video.c
index f7f2f74..015b426 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2382,8 +2382,14 @@ I830PutImage(ScrnInfoPtr pScrn,
     switch (id) {
     case FOURCC_YV12:
     case FOURCC_I420:
-	srcPitch = (width + 3) & ~3;
-	srcPitch2 = ((width >> 1) + 3) & ~3;
+        if (pI830->IsXvMCSurface) {
+            srcPitch = (width + 0x400) & ~0x3ff;
+            srcPitch2 = ((width >> 1) + 0x400) & ~0x3ff;
+        } else {
+            srcPitch = (width + 0x3) & ~0x3;
+            srcPitch2 = ((width >> 1) + 0x3) & ~0x3;
+        }
+
 	if (pPriv->textured && IS_I965G(pI830))
 	    destId = FOURCC_YUY2;
 	break;
diff --git a/src/i915_hwmc.c b/src/i915_hwmc.c
index 0f57a5f..b5bd13e 100644
--- a/src/i915_hwmc.c
+++ b/src/i915_hwmc.c
@@ -191,41 +191,6 @@ static XF86MCAdaptorPtr ppAdapt[1] =
     (XF86MCAdaptorPtr)&pAdapt
 };
 
-static unsigned int stride(int w)
-{
-    return (w + 3) & ~3;
-}
-
-static unsigned long size_y420(int w, int h)
-{
-   unsigned cpp = 1;
-   unsigned yPitch = stride(w) * cpp;
-   
-   return h * yPitch;
-}
-
-static unsigned long size_uv420(int w, int h)
-{
-   unsigned cpp = 1;
-   unsigned uvPitch = stride(w >> 1) * cpp;
-
-   return h / 2 * uvPitch;
-}
-
-static unsigned long size_yuv420(int w, int h)
-{
-    unsigned cpp = 1;
-    unsigned yPitch = stride(w) * cpp;
-    unsigned uvPitch = stride(w >> 1) * cpp;
-
-    return h * (yPitch + uvPitch);
-}
-
-static unsigned long size_xx44(int w, int h)
-{
-    return h * stride(w);
-}
-
 /*
  * Init and clean up the screen private parts of XvMC.
  */
@@ -641,7 +606,7 @@ static int I915XvMCCreateSurface(ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf,
     }
 
     ctx = pSurf->context;
-    bufsize = size_yuv420(ctx->width, ctx->height);
+    bufsize = SIZE_YUV420(ctx->width, ctx->height);
 
     if (!i830_allocate_xvmc_buffer(pScrn, "XvMC surface", 
                                    &(sfpriv->surface), bufsize,
@@ -727,7 +692,7 @@ static int I915XvMCCreateSubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSubp,
     }
 
     ctx = pSubp->context;
-    bufsize = size_xx44(ctx->width, ctx->height);
+    bufsize = SIZE_XX44(ctx->width, ctx->height);
 
     if (!i830_allocate_xvmc_buffer(pScrn, "XvMC surface", 
                                    &(sfpriv->surface), bufsize,
@@ -900,12 +865,13 @@ static int I915XvMCInterceptPutImage(ScrnInfoPtr pScrn, short src_x, short src_y
                                      short height, Bool sync, RegionPtr clipBoxes, pointer data,
                                      DrawablePtr pDraw)
 {
+    I830Ptr pI830 = I830PTR(pScrn);
     I830PortPrivPtr pPriv = (I830PortPrivPtr)data;
     I915XvMCXVPriv *vx = (I915XvMCXVPriv *)pPriv->xvmc_priv;
+    int ret;
 
     if (I830PTR(pScrn)->XvMCEnabled) {
         if (FOURCC_XVMC == id) {
-            I830Ptr pI830 = I830PTR(pScrn);
             I915XvMCPtr pXvMC = pI830->xvmc;
             I915XvMCCommandBuffer *i915XvMCData = (I915XvMCCommandBuffer *)buf;
             int i;
@@ -933,6 +899,7 @@ static int I915XvMCInterceptPutImage(ScrnInfoPtr pScrn, short src_x, short src_y
                    mem = pXvMC->sfprivs[i915XvMCData->srfNo]->surface;
                    buf = pI830->FbBase + mem->offset;
                    id = i915XvMCData->real_id;
+                   pI830->IsXvMCSurface = 1;
                    break;
                 }
 
@@ -944,8 +911,10 @@ static int I915XvMCInterceptPutImage(ScrnInfoPtr pScrn, short src_x, short src_y
         }
     }
 
-    return vx->PutImage(pScrn, src_x, src_y, drw_x, drw_y, src_w, src_h,
+    ret = vx->PutImage(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;
 }
 
 /*********************************** Public Function **************************************/
diff --git a/src/i915_hwmc.h b/src/i915_hwmc.h
index a4b4220..f2570ce 100644
--- a/src/i915_hwmc.h
+++ b/src/i915_hwmc.h
@@ -1,6 +1,12 @@
 #ifndef _I915_HWMC_H
 #define _I915_HWMC_H
 
+#define STRIDE(w)               (((w) + 0x3ff) & ~0x3ff)
+#define SIZE_Y420(w, h)         (h * STRIDE(w))
+#define SIZE_UV420(w, h)        ((h >> 1) * STRIDE(w >> 1))
+#define SIZE_YUV420(w, h)       (h * (STRIDE(w) + STRIDE(w >> 1)))
+#define SIZE_XX44(w, h)         (h * STRIDE(w))
+
 #define FOURCC_XVMC     (('C' << 24) + ('M' << 16) + ('V' << 8) + 'X')
 
 #define I915_NUM_XVMC_ATTRIBUTES       0x02
diff --git a/src/xvmc/I915XvMC.c b/src/xvmc/I915XvMC.c
index b4d1f57..3b086c2 100644
--- a/src/xvmc/I915XvMC.c
+++ b/src/xvmc/I915XvMC.c
@@ -34,10 +34,10 @@
 
 #define YOFFSET(surface)        (surface->srf.offset)
 #define UOFFSET(surface)        (surface->srf.offset + \
-                                 size_y(surface->width, surface->height) + \
-                                 size_uv(surface->width, surface->height))
+                                 SIZE_Y420(surface->width, surface->height) + \
+                                 SIZE_UV420(surface->width, surface->height))
 #define VOFFSET(surface)        (surface->srf.offset + \
-                                 size_y(surface->width, surface->height))
+                                 SIZE_Y420(surface->width, surface->height))
 
 /* Lookup tables to speed common calculations */
 _STATIC_ unsigned mb_bytes[] = {
@@ -173,67 +173,6 @@ _STATIC_ void UNLOCK_HARDWARE(i915XvMCContext *pI915XvMC)
     pthread_mutex_unlock(&pI915XvMC->ctxmutex);
 }
 
-_STATIC_ unsigned stride(int w)
-{
-    return (w + 3) & ~3;
-}
-
-_STATIC_ unsigned long size_y(int w, int h)
-{
-    unsigned cpp = 1;
-    unsigned yPitch = stride(w) * cpp;
-
-    return h * yPitch;
-}
-
-_STATIC_ unsigned long size_uv(int w, int h)
-{
-    unsigned cpp = 1;
-    unsigned uvPitch = stride(w >> 1) * cpp;
-    
-    return h / 2 * uvPitch;
-}
-
-_STATIC_ unsigned long size_yuv420(int w, int h)
-{
-    unsigned cpp = 1;
-    unsigned yPitch = stride(w) * cpp;
-    unsigned uvPitch = stride(w >> 1) * cpp;
-
-    return h * (yPitch + uvPitch);
-}
-
-_STATIC_ void i915_clear_surface(i915XvMCContext *pI915XvMC, i915XvMCSurface *surface)
-{
-    struct i915_color_blt color_blt;
-
-    if (surface->processing)
-        return;
-
-    memset(&color_blt, 0, sizeof(color_blt));
-    color_blt.dw0.type = CMD_2D;
-    color_blt.dw0.opcode = OPC_COLOR_BLT;
-    color_blt.dw0.bpp_mask = 0x1;
-    color_blt.dw0.length = 3;
-    color_blt.dw1.color_depth = 0;      /* 8bit */
-    color_blt.dw1.rop = 0xf0;
-    color_blt.dw1.pitch = surface->yStride;
-    color_blt.dw2.height = surface->height;
-    color_blt.dw2.width = surface->width;
-    color_blt.dw3.address = YOFFSET(surface);
-    color_blt.dw4.pattern = 0x7f;
-    intelBatchbufferData(pI915XvMC, &color_blt, sizeof(color_blt), 0);
-
-    color_blt.dw1.pitch = surface->uvStride;
-    color_blt.dw2.height = (surface->height >> 1);
-    color_blt.dw2.width = (surface->width >> 1);
-    color_blt.dw3.address = VOFFSET(surface);
-    intelBatchbufferData(pI915XvMC, &color_blt, sizeof(color_blt), 0);
-
-    color_blt.dw3.address = UOFFSET(surface);
-    intelBatchbufferData(pI915XvMC, &color_blt, sizeof(color_blt), 0);
-}
-
 _STATIC_ void i915_flush(i915XvMCContext *pI915XvMC, int map, int render)
 {
     struct i915_mi_flush mi_flush;
@@ -247,11 +186,6 @@ _STATIC_ void i915_flush(i915XvMCContext *pI915XvMC, int map, int render)
     intelBatchbufferData(pI915XvMC, &mi_flush, sizeof(mi_flush), 0);
 }
 
-_STATIC_ void i915_flush_with_flush_bit_clear(i915XvMCContext *pI915XvMC)
-{
-    i915_flush(pI915XvMC, 1, 0);
-}
-
 /* for MC picture rendering */
 _STATIC_ void i915_mc_static_indirect_state_buffer(XvMCContext *context, 
                                                    XvMCSurface *surface,
@@ -535,8 +469,6 @@ _STATIC_ void i915_mc_load_sis_msb_buffers(XvMCContext *context)
     unsigned size;
     int mem_select = 1;
 
-    i915_flush_with_flush_bit_clear(pI915XvMC);
-
     /* 3DSTATE_LOAD_INDIRECT */
     size = sizeof(*load_indirect) + sizeof(*sis) + sizeof(*msb);
     base = calloc(1, size);
@@ -668,10 +600,10 @@ _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][1];
-    fmv.s[1] = mb->PMV[0][0][0];
-    bmv.s[0] = mb->PMV[0][1][1];
-    bmv.s[1] = mb->PMV[0][1][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];
 
     macroblock_1fbmv.dw2 = fmv.u[0];
     macroblock_1fbmv.dw3 = bmv.u[0];
@@ -707,34 +639,34 @@ _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][1];
-    fmv.s[1] = mb->PMV[0][0][0];
-    fmv.s[2] = mb->PMV[1][0][1];
-    fmv.s[3] = mb->PMV[1][0][0];
-    bmv.s[0] = mb->PMV[0][1][1];
-    bmv.s[1] = mb->PMV[0][1][0];
-    bmv.s[2] = mb->PMV[1][1][1];
-    bmv.s[3] = mb->PMV[1][1][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];
 
     if ((ps & XVMC_FRAME_PICTURE) == XVMC_FRAME_PICTURE) {
         if ((mb->motion_type & 3) == XVMC_PREDICTION_FIELD) {
-            fmv.s[0] = mb->PMV[0][0][1] >> 1;
-            fmv.s[1] = mb->PMV[0][0][0];
-            fmv.s[2] = mb->PMV[1][0][1] >> 1;
-            fmv.s[3] = mb->PMV[1][0][0];
-            bmv.s[0] = mb->PMV[0][1][1] >> 1;
-            bmv.s[1] = mb->PMV[0][1][0];
-            bmv.s[2] = mb->PMV[1][1][1] >> 1;
-            bmv.s[3] = mb->PMV[1][1][0];
+            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;
         } else if ((mb->motion_type & 3) == XVMC_PREDICTION_DUAL_PRIME) {
-            fmv.s[0] = mb->PMV[0][0][1] >> 1;
-            fmv.s[1] = mb->PMV[0][0][0];
-            fmv.s[2] = mb->PMV[0][0][1] >> 1;  // MPEG2 MV[0][1] isn't used
-            fmv.s[3] = mb->PMV[0][0][0];
-            bmv.s[0] = mb->PMV[1][0][1] >> 1;
-            bmv.s[1] = mb->PMV[1][0][0];
-            bmv.s[2] = mb->PMV[1][1][1] >> 1;
-            bmv.s[3] = mb->PMV[1][1][0];
+            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;
         }
     }
 
@@ -1072,9 +1004,6 @@ _STATIC_ void i915_mc_one_time_state_initialization(XvMCContext *context)
     intelBatchbufferData(pI915XvMC, base, size, 0);
     free(base);
 
-    /* flush */
-    i915_flush_with_flush_bit_clear(pI915XvMC);
-
     /* 3DSTATE_LOAD_INDIRECT */
     size = sizeof(*load_indirect) + sizeof(*dis) + sizeof(*ssb) + sizeof(*psp) + sizeof(*psc);
     base = calloc(1, size);
@@ -1147,9 +1076,6 @@ _STATIC_ void i915_mc_invalidate_subcontext_buffers(XvMCContext *context, unsign
     unsigned size;
     void *base = NULL, *ptr = NULL;
 
-    /* flush */
-    i915_flush_with_flush_bit_clear(pI915XvMC);
-
     size = sizeof(*load_indirect);
     if (mask & BLOCK_SIS)
         size += sizeof(*sis);
@@ -1364,8 +1290,7 @@ _STATIC_ void i915_yuv2rgb_map_state_buffer(XvMCSurface *target_surface)
     memset(tm, 0, sizeof(*tm));
     tm->tm0.v_ls_offset = 0;
     tm->tm0.v_ls = 0;
-    tm->tm0.base_address = privTarget->srf.offset +
-        size_y(w, h);
+    tm->tm0.base_address = VOFFSET(privTarget);
     tm->tm1.tile_walk = TILEWALK_XMAJOR;
     tm->tm1.tiled_surface = 0;
     tm->tm1.utilize_fence_regs = 1;
@@ -1383,7 +1308,7 @@ _STATIC_ void i915_yuv2rgb_map_state_buffer(XvMCSurface *target_surface)
     memset(tm, 0, sizeof(*tm));
     tm->tm0.v_ls_offset = 0;
     tm->tm0.v_ls = 0;
-    tm->tm0.base_address = privTarget->srf.offset;
+    tm->tm0.base_address = YOFFSET(privTarget);
     tm->tm1.tile_walk = TILEWALK_XMAJOR;
     tm->tm1.tiled_surface = 0;
     tm->tm1.utilize_fence_regs = 1;
@@ -1401,8 +1326,7 @@ _STATIC_ void i915_yuv2rgb_map_state_buffer(XvMCSurface *target_surface)
     memset(tm, 0, sizeof(*tm));
     tm->tm0.v_ls_offset = 0;
     tm->tm0.v_ls = 0;
-    tm->tm0.base_address = privTarget->srf.offset +
-        size_y(w, h) + size_uv(w, h);
+    tm->tm0.base_address = UOFFSET(privTarget);
     tm->tm1.tile_walk = TILEWALK_XMAJOR;
     tm->tm1.tiled_surface = 0;
     tm->tm1.utilize_fence_regs = 1;
@@ -1675,9 +1599,6 @@ _STATIC_ void i915_yuv2rgb_proc(XvMCSurface *surface)
     scissor_rectangle.dw2.max_y = 2047;
     intelBatchbufferData(pI915XvMC, &scissor_rectangle, sizeof(scissor_rectangle), 0);
 
-    /* flush */
-    i915_flush_with_flush_bit_clear(pI915XvMC);
-
     /* 3DSTATE_LOAD_INDIRECT */
     size = sizeof(*load_indirect) + sizeof(*sis) + sizeof(*ssb) + sizeof(*msb) + sizeof(*psp);
     base = calloc(1, size);
@@ -2071,8 +1992,8 @@ Status XvMCCreateContext(Display *display, XvPortID port,
 
     /* Initialize private context values */
     setupAttribDesc(display, port, &pI915XvMC->attrib, pI915XvMC->attribDesc);
-    pI915XvMC->yStride = stride(width) * 1;     /* cpp = 1 */
-    pI915XvMC->uvStride = stride(width >> 1) * 1;
+    pI915XvMC->yStride = STRIDE(width);
+    pI915XvMC->uvStride = STRIDE(width >> 1);
     pI915XvMC->haveXv = 0;
     pI915XvMC->attribChanged = 1;
     pI915XvMC->dual_prime = 0;
@@ -2082,7 +2003,6 @@ Status XvMCCreateContext(Display *display, XvPortID port,
     pthread_mutex_init(&pI915XvMC->ctxmutex, NULL);
     intelInitBatchBuffer(pI915XvMC);
     pI915XvMC->ref = 1;
-    pI915XvMC->inited_mc = 0;
     return Success;
 }
 
@@ -2144,7 +2064,6 @@ Status XvMCCreateSurface(Display *display, XvMCContext *context, XvMCSurface *su
     pI915Surface->uvStride = pI915XvMC->uvStride;
     pI915Surface->width = context->width;
     pI915Surface->height = context->height;
-    pI915Surface->processing = 0;
     pI915Surface->privContext = pI915XvMC;
     pI915Surface->privSubPic = NULL;
     pI915Surface->srf.map = NULL;
@@ -2415,27 +2334,9 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context,
     }
 
     LOCK_HARDWARE(pI915XvMC);
-    // if (!pI915XvMC->inited_mc) {
-    i915_clear_surface(pI915XvMC, privTarget);
-    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);
-    pI915XvMC->inited_mc = 1;
-    //}
-    intelFlushBatch(pI915XvMC, TRUE);
-    UNLOCK_HARDWARE(pI915XvMC);
-
     corrdata_ptr = pI915XvMC->corrdata.map;
     corrdata_size = 0;
 
-    if (macroblock_array->macro_blocks[first_macroblock].y == (target_surface->height >> 4) - 1)
-        privTarget->processing = 0;
-    else
-        privTarget->processing = 1;
-
     for (i = first_macroblock; i < (num_macroblocks + first_macroblock); i++) {
         int bspm = 0;
         mb = &macroblock_array->macro_blocks[i];
@@ -2461,19 +2362,29 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context,
         }
         
         bspm = mb_bytes[mb->coded_block_pattern];
+
+        if (!bspm)
+            continue;
+
         corrdata_size += bspm;
 
         if (corrdata_size > pI915XvMC->corrdata.size) {
             printf("Error, correction data buffer overflow\n");
             break;
         }
-
         memcpy(corrdata_ptr, block_ptr, bspm);
         corrdata_ptr += bspm;
     } 
 
-    /* Lock */
-    LOCK_HARDWARE(pI915XvMC);
+    i915_flush(pI915XvMC, 1, 0);
+    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_static_indirect_state_buffer(context, target_surface, 
                                          picture_structure, flags,
                                          picture_coding_type);
@@ -2524,7 +2435,6 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context,
                 break;
             }
         }       /* Field Picture */
-        i915_flush(pI915XvMC, 0, 1);
     }
 
     intelFlushBatch(pI915XvMC, TRUE);
diff --git a/src/xvmc/I915XvMC.h b/src/xvmc/I915XvMC.h
index 9dd73e7..7f47f43 100644
--- a/src/xvmc/I915XvMC.h
+++ b/src/xvmc/I915XvMC.h
@@ -77,7 +77,6 @@ typedef struct _i915XvMCContext {
     int lock;   /* Lightweight lock to avoid locking twice */
     int locked;
     volatile drmI830Sarea *sarea;
-    int inited_mc;
     
     drmLock *driHwLock;
     drm_context_t hHWContext; /* drmcontext; */
@@ -159,7 +158,6 @@ typedef struct _i915XvMCSurface {
     unsigned uvStride;
     unsigned width;                    /* Dimensions */
     unsigned height;
-    unsigned processing;
     i915XvMCDrmMap srf;
     i915XvMCContext *privContext;
     i915XvMCSubpicture *privSubPic;     /* Subpicture to be blended when
commit 8f316a4584d0676e5dae051698bde0831f018cc4
Author: root <root at xhh-bl32.(none)>
Date:   Thu Jul 12 16:24:03 2007 +0800

    1. clean code
    
    2. fix an error in map_state

diff --git a/src/i830_video.c b/src/i830_video.c
index 94fe309..f7f2f74 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -275,7 +275,7 @@ static XF86ImageRec Images[NUM_IMAGES] = {
         FOURCC_XVMC,
         XvYUV,
         LSBFirst,
-        {'V', 'I', 'A', 0x00,
+        {'X', 'V', 'M', 'C',
          0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0xAA, 0x00,
          0x38, 0x9B, 0x71},
         12,
diff --git a/src/xvmc/I915XvMC.c b/src/xvmc/I915XvMC.c
index bc25a4c..b4d1f57 100644
--- a/src/xvmc/I915XvMC.c
+++ b/src/xvmc/I915XvMC.c
@@ -32,6 +32,13 @@
                        (((CARD8 *)(ctx)->sarea_address) +   \
                         (ctx)->sarea_priv_offset))
 
+#define YOFFSET(surface)        (surface->srf.offset)
+#define UOFFSET(surface)        (surface->srf.offset + \
+                                 size_y(surface->width, surface->height) + \
+                                 size_uv(surface->width, surface->height))
+#define VOFFSET(surface)        (surface->srf.offset + \
+                                 size_y(surface->width, surface->height))
+
 /* Lookup tables to speed common calculations */
 _STATIC_ unsigned mb_bytes[] = {
     000, 128, 128, 256, 128, 256, 256, 384,  // 0
@@ -196,6 +203,37 @@ _STATIC_ unsigned long size_yuv420(int w, int h)
     return h * (yPitch + uvPitch);
 }
 
+_STATIC_ void i915_clear_surface(i915XvMCContext *pI915XvMC, i915XvMCSurface *surface)
+{
+    struct i915_color_blt color_blt;
+
+    if (surface->processing)
+        return;
+
+    memset(&color_blt, 0, sizeof(color_blt));
+    color_blt.dw0.type = CMD_2D;
+    color_blt.dw0.opcode = OPC_COLOR_BLT;
+    color_blt.dw0.bpp_mask = 0x1;
+    color_blt.dw0.length = 3;
+    color_blt.dw1.color_depth = 0;      /* 8bit */
+    color_blt.dw1.rop = 0xf0;
+    color_blt.dw1.pitch = surface->yStride;
+    color_blt.dw2.height = surface->height;
+    color_blt.dw2.width = surface->width;
+    color_blt.dw3.address = YOFFSET(surface);
+    color_blt.dw4.pattern = 0x7f;
+    intelBatchbufferData(pI915XvMC, &color_blt, sizeof(color_blt), 0);
+
+    color_blt.dw1.pitch = surface->uvStride;
+    color_blt.dw2.height = (surface->height >> 1);
+    color_blt.dw2.width = (surface->width >> 1);
+    color_blt.dw3.address = VOFFSET(surface);
+    intelBatchbufferData(pI915XvMC, &color_blt, sizeof(color_blt), 0);
+
+    color_blt.dw3.address = UOFFSET(surface);
+    intelBatchbufferData(pI915XvMC, &color_blt, sizeof(color_blt), 0);
+}
+
 _STATIC_ void i915_flush(i915XvMCContext *pI915XvMC, int map, int render)
 {
     struct i915_mi_flush mi_flush;
@@ -214,46 +252,6 @@ _STATIC_ void i915_flush_with_flush_bit_clear(i915XvMCContext *pI915XvMC)
     i915_flush(pI915XvMC, 1, 0);
 }
 
-_STATIC_ void i915_3d_initialization(XvMCContext *context)
-{
-    i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
-    struct i915_3dstate_coord_set_bindings coord_set_bindings;
-    struct i915_3dstate_drawing_rectangle drawing_rectangle;
-    struct i915_3dstate_modes_5 modes_5;
-    i915_flush_with_flush_bit_clear(pI915XvMC);
-
-    memset(&coord_set_bindings, 0, sizeof(coord_set_bindings));
-    coord_set_bindings.dw0.type = CMD_3D;
-    coord_set_bindings.dw0.opcode = OPC_3DSTATE_COORD_SET_BINDINGS;
-    coord_set_bindings.dw0.itcs7_src = 7;
-    coord_set_bindings.dw0.itcs6_src = 6;
-    coord_set_bindings.dw0.itcs5_src = 5;
-    coord_set_bindings.dw0.itcs4_src = 4;
-    coord_set_bindings.dw0.itcs3_src = 3;
-    coord_set_bindings.dw0.itcs2_src = 2;
-    coord_set_bindings.dw0.itcs1_src = 1;
-    coord_set_bindings.dw0.itcs0_src = 0;
-    intelBatchbufferData(pI915XvMC, &coord_set_bindings, sizeof(coord_set_bindings), 0);
-
-    memset(&drawing_rectangle, 0, sizeof(drawing_rectangle));
-    drawing_rectangle.dw0.type = CMD_3D;
-    drawing_rectangle.dw0.opcode = OPC_3DSTATE_DRAWING_RECTANGLE;
-    drawing_rectangle.dw0.length = 3;
-    drawing_rectangle.dw2.x_min = 0;
-    drawing_rectangle.dw2.y_min = 0;
-    drawing_rectangle.dw3.x_max = 2047;
-    drawing_rectangle.dw3.y_max = 2047;
-    intelBatchbufferData(pI915XvMC, &drawing_rectangle, sizeof(drawing_rectangle), 0);
-
-    memset(&modes_5, 0, sizeof(modes_5));
-    modes_5.dw0.type = CMD_3D;
-    modes_5.dw0.opcode = OPC_3DSTATE_MODES_5;
-    modes_5.dw0.prc_op = 1;
-    modes_5.dw0.ptc_op = 1;
-    intelBatchbufferData(pI915XvMC, &modes_5, sizeof(modes_5), 0);
-}
-
-
 /* for MC picture rendering */
 _STATIC_ void i915_mc_static_indirect_state_buffer(XvMCContext *context, 
                                                    XvMCSurface *surface,
@@ -281,7 +279,7 @@ _STATIC_ void i915_mc_static_indirect_state_buffer(XvMCContext *context,
     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 = (pI915Surface->srf.offset >> 2);    /* starting DWORD address */
+    buffer_info->dw2.base_address = (YOFFSET(pI915Surface) >> 2);    /* starting DWORD address */
 
     /* DEST U */
     ++buffer_info;
@@ -295,8 +293,7 @@ _STATIC_ void i915_mc_static_indirect_state_buffer(XvMCContext *context,
     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 = ((pI915Surface->srf.offset +
-                                      size_y(w, h) + size_uv(w, h)) >> 2);      /* starting DWORD address */
+    buffer_info->dw2.base_address = (UOFFSET(pI915Surface) >> 2);      /* starting DWORD address */
 
     /* DEST V */
     ++buffer_info;
@@ -310,8 +307,7 @@ _STATIC_ void i915_mc_static_indirect_state_buffer(XvMCContext *context,
     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 = ((pI915Surface->srf.offset +
-                                      size_y(w, h)) >> 2);      /* starting DWORD address */
+    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);
@@ -321,6 +317,7 @@ _STATIC_ void i915_mc_static_indirect_state_buffer(XvMCContext *context,
     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;
 
@@ -342,6 +339,7 @@ _STATIC_ void i915_mc_static_indirect_state_buffer(XvMCContext *context,
     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;            
 
@@ -405,7 +403,7 @@ _STATIC_ void i915_mc_map_state_buffer(XvMCContext *context,
     memset(tm, 0, sizeof(*tm));
     tm->tm0.v_ls_offset = 0;
     tm->tm0.v_ls = 0;
-    tm->tm0.base_address = (privPast->srf.offset >> 2);
+    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;
@@ -423,7 +421,7 @@ _STATIC_ void i915_mc_map_state_buffer(XvMCContext *context,
     memset(tm, 0, sizeof(*tm));
     tm->tm0.v_ls_offset = 0;
     tm->tm0.v_ls = 0;
-    tm->tm0.base_address = (privFuture->srf.offset >> 2);
+    tm->tm0.base_address = (YOFFSET(privFuture) >> 2);
     tm->tm1.tile_walk = TILEWALK_XMAJOR;
     tm->tm1.tiled_surface = 0;
     tm->tm1.utilize_fence_regs = 0;
@@ -450,8 +448,7 @@ _STATIC_ void i915_mc_map_state_buffer(XvMCContext *context,
     memset(tm, 0, sizeof(*tm));
     tm->tm0.v_ls_offset = 0;
     tm->tm0.v_ls = 0;
-    tm->tm0.base_address = ((privPast->srf.offset +
-                             size_y(w, h) + size_uv(w, h)) >> 2);
+    tm->tm0.base_address = (UOFFSET(privPast) >> 2);
     tm->tm1.tile_walk = TILEWALK_XMAJOR;
     tm->tm1.tiled_surface = 0;
     tm->tm1.utilize_fence_regs = 0;
@@ -469,8 +466,7 @@ _STATIC_ void i915_mc_map_state_buffer(XvMCContext *context,
     memset(tm, 0, sizeof(*tm));
     tm->tm0.v_ls_offset = 0;
     tm->tm0.v_ls = 0;
-    tm->tm0.base_address = ((privFuture->srf.offset +
-                             size_y(w, h) + size_uv(w, h)) >> 2);
+    tm->tm0.base_address = (UOFFSET(privFuture) >> 2);
     tm->tm1.tile_walk = TILEWALK_XMAJOR;
     tm->tm1.tiled_surface = 0;
     tm->tm1.utilize_fence_regs = 0;
@@ -497,8 +493,7 @@ _STATIC_ void i915_mc_map_state_buffer(XvMCContext *context,
     memset(tm, 0, sizeof(*tm));
     tm->tm0.v_ls_offset = 0;
     tm->tm0.v_ls = 0;
-    tm->tm0.base_address = ((privPast->srf.offset +
-                            size_y(w, h)) >> 2);
+    tm->tm0.base_address = (VOFFSET(privPast) >> 2);
     tm->tm1.tile_walk = TILEWALK_XMAJOR;
     tm->tm1.tiled_surface = 0;
     tm->tm1.utilize_fence_regs = 0;
@@ -516,8 +511,7 @@ _STATIC_ void i915_mc_map_state_buffer(XvMCContext *context,
     memset(tm, 0, sizeof(*tm));
     tm->tm0.v_ls_offset = 0;
     tm->tm0.v_ls = 0;
-    tm->tm0.base_address = ((privFuture->srf.offset +
-                             size_y(w, h)) >> 2);
+    tm->tm0.base_address = (VOFFSET(privFuture) >> 2);
     tm->tm1.tile_walk = TILEWALK_XMAJOR;
     tm->tm1.tiled_surface = 0;
     tm->tm1.utilize_fence_regs = 0;
@@ -674,10 +668,10 @@ _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];
+    fmv.s[0] = mb->PMV[0][0][1];
+    fmv.s[1] = mb->PMV[0][0][0];
+    bmv.s[0] = mb->PMV[0][1][1];
+    bmv.s[1] = mb->PMV[0][1][0];
 
     macroblock_1fbmv.dw2 = fmv.u[0];
     macroblock_1fbmv.dw3 = bmv.u[0];
@@ -685,7 +679,7 @@ _STATIC_ void i915_mc_mpeg_macroblock_1fbmv(XvMCContext *context, XvMCMacroBlock
     intelBatchbufferData(pI915XvMC, &macroblock_1fbmv, sizeof(macroblock_1fbmv), 0);
 }
 
-_STATIC_ void i915_mc_mpeg_macroblock_2fbmv(XvMCContext *context, XvMCMacroBlock *mb)
+_STATIC_ void i915_mc_mpeg_macroblock_2fbmv(XvMCContext *context, XvMCMacroBlock *mb, unsigned ps)
 {
     struct i915_3dmpeg_macroblock_2fbmv macroblock_2fbmv;
     i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
@@ -713,14 +707,36 @@ _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];
+    fmv.s[0] = mb->PMV[0][0][1];
+    fmv.s[1] = mb->PMV[0][0][0];
+    fmv.s[2] = mb->PMV[1][0][1];
+    fmv.s[3] = mb->PMV[1][0][0];
+    bmv.s[0] = mb->PMV[0][1][1];
+    bmv.s[1] = mb->PMV[0][1][0];
+    bmv.s[2] = mb->PMV[1][1][1];
+    bmv.s[3] = mb->PMV[1][1][0];
+
+    if ((ps & XVMC_FRAME_PICTURE) == XVMC_FRAME_PICTURE) {
+        if ((mb->motion_type & 3) == XVMC_PREDICTION_FIELD) {
+            fmv.s[0] = mb->PMV[0][0][1] >> 1;
+            fmv.s[1] = mb->PMV[0][0][0];
+            fmv.s[2] = mb->PMV[1][0][1] >> 1;
+            fmv.s[3] = mb->PMV[1][0][0];
+            bmv.s[0] = mb->PMV[0][1][1] >> 1;
+            bmv.s[1] = mb->PMV[0][1][0];
+            bmv.s[2] = mb->PMV[1][1][1] >> 1;
+            bmv.s[3] = mb->PMV[1][1][0];
+        } else if ((mb->motion_type & 3) == XVMC_PREDICTION_DUAL_PRIME) {
+            fmv.s[0] = mb->PMV[0][0][1] >> 1;
+            fmv.s[1] = mb->PMV[0][0][0];
+            fmv.s[2] = mb->PMV[0][0][1] >> 1;  // MPEG2 MV[0][1] isn't used
+            fmv.s[3] = mb->PMV[0][0][0];
+            bmv.s[0] = mb->PMV[1][0][1] >> 1;
+            bmv.s[1] = mb->PMV[1][0][0];
+            bmv.s[2] = mb->PMV[1][1][1] >> 1;
+            bmv.s[3] = mb->PMV[1][1][0];
+        }
+    }
 
     macroblock_2fbmv.dw2 = fmv.u[0];
     macroblock_2fbmv.dw3 = bmv.u[0];
@@ -1043,12 +1059,12 @@ _STATIC_ void i915_mc_one_time_state_initialization(XvMCContext *context)
     s6->alpha_test_enable = 0;
     s6->alpha_test_function = 0;
     s6->alpha_reference_value = 0;
-    s6->depth_test_enable = 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 = 0;
-    s6->dest_blend_factor = 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;
@@ -1085,6 +1101,7 @@ _STATIC_ void i915_mc_one_time_state_initialization(XvMCContext *context)
     /* SSB */
     ssb = (ssb_state *)(++dis);
     ssb->dw0.valid = 1;
+    ssb->dw0.force = 1;
     ssb->dw1.length = 7; /* 8 - 1 */
 
     if (mem_select)
@@ -1095,6 +1112,7 @@ _STATIC_ void i915_mc_one_time_state_initialization(XvMCContext *context)
     /* 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)
@@ -2126,6 +2144,7 @@ Status XvMCCreateSurface(Display *display, XvMCContext *context, XvMCSurface *su
     pI915Surface->uvStride = pI915XvMC->uvStride;
     pI915Surface->width = context->width;
     pI915Surface->height = context->height;
+    pI915Surface->processing = 0;
     pI915Surface->privContext = pI915XvMC;
     pI915Surface->privSubPic = NULL;
     pI915Surface->srf.map = NULL;
@@ -2397,8 +2416,8 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context,
 
     LOCK_HARDWARE(pI915XvMC);
     // if (!pI915XvMC->inited_mc) {
-    i915_3d_initialization(context);
-    i915_mc_invalidate_subcontext_buffers(context, BLOCK_SIS | BLOCK_SSB 
+    i915_clear_surface(pI915XvMC, privTarget);
+    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);
@@ -2412,6 +2431,11 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context,
     corrdata_ptr = pI915XvMC->corrdata.map;
     corrdata_size = 0;
 
+    if (macroblock_array->macro_blocks[first_macroblock].y == (target_surface->height >> 4) - 1)
+        privTarget->processing = 0;
+    else
+        privTarget->processing = 1;
+
     for (i = first_macroblock; i < (num_macroblocks + first_macroblock); i++) {
         int bspm = 0;
         mb = &macroblock_array->macro_blocks[i];
@@ -2446,7 +2470,7 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context,
 
         memcpy(corrdata_ptr, block_ptr, bspm);
         corrdata_ptr += bspm;
-    }
+    } 
 
     /* Lock */
     LOCK_HARDWARE(pI915XvMC);
@@ -2458,7 +2482,7 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context,
     i915_mc_mpeg_set_origin(context, &macroblock_array->macro_blocks[first_macroblock]);
 
     for (i = first_macroblock; i < (num_macroblocks + first_macroblock); i++) {
-         mb = &macroblock_array->macro_blocks[i];
+        mb = &macroblock_array->macro_blocks[i];
 
         /* Intra Blocks */
         if (mb->macroblock_type & XVMC_MB_TYPE_INTRA) {
@@ -2466,15 +2490,15 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context,
         } else if ((picture_structure & XVMC_FRAME_PICTURE) == XVMC_FRAME_PICTURE) { /* Frame Picture */
             switch (mb->motion_type & 3) {
             case XVMC_PREDICTION_FIELD: /* Field Based */
-                i915_mc_mpeg_macroblock_2fbmv(context, mb);
+                i915_mc_mpeg_macroblock_2fbmv(context, mb, picture_structure);
                 break;
 
             case XVMC_PREDICTION_FRAME: /* Frame Based */
                 i915_mc_mpeg_macroblock_1fbmv(context, mb);
-            break;
+                break;
 
             case XVMC_PREDICTION_DUAL_PRIME:    /* Dual Prime */
-                i915_mc_mpeg_macroblock_2fbmv(context, mb);
+                i915_mc_mpeg_macroblock_2fbmv(context, mb, picture_structure);
                 break;
 
             default:    /* No Motion Type */
@@ -2488,7 +2512,7 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context,
                 break;
 
             case XVMC_PREDICTION_16x8:  /* 16x8 MC */
-                i915_mc_mpeg_macroblock_2fbmv(context, mb);
+                i915_mc_mpeg_macroblock_2fbmv(context, mb, picture_structure);
                 break;
                 
             case XVMC_PREDICTION_DUAL_PRIME:    /* Dual Prime */
diff --git a/src/xvmc/I915XvMC.h b/src/xvmc/I915XvMC.h
index a27ea66..9dd73e7 100644
--- a/src/xvmc/I915XvMC.h
+++ b/src/xvmc/I915XvMC.h
@@ -159,6 +159,7 @@ typedef struct _i915XvMCSurface {
     unsigned uvStride;
     unsigned width;                    /* Dimensions */
     unsigned height;
+    unsigned processing;
     i915XvMCDrmMap srf;
     i915XvMCContext *privContext;
     i915XvMCSubpicture *privSubPic;     /* Subpicture to be blended when
diff --git a/src/xvmc/i915_structs.h b/src/xvmc/i915_structs.h
index 24f215b..042a4ad 100644
--- a/src/xvmc/i915_structs.h
+++ b/src/xvmc/i915_structs.h
@@ -20,6 +20,41 @@ struct i915_mi_flush
     } dw0;
 };
 
+/* BLT */
+#define CMD_2D          0x02
+#define OPC_COLOR_BLT                           (0x40)
+
+struct i915_color_blt
+{
+    struct {
+        unsigned length : 5;
+        unsigned pad0 : 15;
+        unsigned bpp_mask : 2;
+        unsigned opcode : 7;
+        unsigned type : 3;
+    } dw0;
+
+    struct {
+        unsigned pitch : 16;
+        unsigned rop : 8;
+        unsigned color_depth : 2;
+        unsigned pad0 : 6;
+    } dw1;
+
+    struct {
+        unsigned width : 16;
+        unsigned height : 16;
+    } dw2;
+
+    struct {
+        unsigned address;
+    } dw3;
+
+    struct {
+        unsigned pattern;
+    } dw4;
+};
+
 /* 3D_INSTRUCTION */
 #define CMD_3D          0x03
 
@@ -29,6 +64,8 @@ struct i915_mi_flush
 #define OPC_3DMPEG_SLICE                        (0x12 + (0x1e << 5))
 #define OPC_3DMPEG_QM_PALETTE_LOAD              (0x13 + (0x1e << 5))
 
+#define OPC_3DSTATE_SCISSOR_ENABLE              (0x10 + (0x1c << 5))
+
 #define OPC_3DSTATE_MAP_STATE                   (0x00 + (0x1d << 8))
 #define OPC_3DSTATE_SAMPLER_STATE               (0x01 + (0x1d << 8))
 #define OPC_3DSTATE_LOAD_STATE_IMMEDIATE_1      (0x04 + (0x1d << 8))
@@ -178,6 +215,7 @@ struct i915_3dmpeg_qm_palette_load
 #define BUFFERID_COLOR_BACK     3
 #define BUFFERID_COLOR_AUX      4
 #define BUFFERID_MC_INTRA_CORR  5
+#define BUFFERID_DEPTH          7
 
 #define TILEWALK_XMAJOR         0
 #define TILEWALK_YMAJOR         1
@@ -209,6 +247,7 @@ struct i915_3dstate_buffer_info
     } dw2;
 };
 
+#define COLORBUFFER_8BIT         0x00
 #define COLORBUFFER_X1R5G5B5     0x01
 #define COLORBUFFER_R5G6B5       0x02
 #define COLORBUFFER_A8R8G8B8     0x03
@@ -363,8 +402,8 @@ struct i915_3dstate_map_state
     } dw0;
 
     struct {
-        unsigned pad0 : 16;
         unsigned map_mask : 16;
+        unsigned pad0 : 16;
     } dw1;
 //    struct texture_map *tms;
 };
@@ -904,67 +943,4 @@ struct i915_3dprimitive
         } indirect_prim;            
     } dw0;
 };
-
-struct i915_3dstate_coord_set_bindings
-{
-    struct {
-        unsigned itcs0_src : 3;
-        unsigned itcs1_src : 3;
-        unsigned itcs2_src : 3;
-        unsigned itcs3_src : 3;
-        unsigned itcs4_src : 3;
-        unsigned itcs5_src : 3;
-        unsigned itcs6_src : 3;
-        unsigned itcs7_src : 3;
-        unsigned opcode : 5;
-        unsigned type : 3;
-    } dw0;
-};
-
-struct i915_3dstate_drawing_rectangle
-{
-    struct {
-        unsigned length : 16;
-        unsigned opcode : 13;
-        unsigned type : 3;
-    } dw0;
-
-    struct {
-        unsigned pad0 : 24;
-        unsigned y_dither_offset : 2;
-        unsigned x_dither_offset : 2;
-        unsigned pad1 : 2;
-        unsigned dbco_disable : 1;
-        unsigned fsc_disable : 1;
-    } dw1;
-
-    struct {
-        unsigned x_min : 16;
-        unsigned y_min : 16;
-    } dw2;
-
-    struct {
-        unsigned x_max : 16;
-        unsigned y_max : 16;
-    } dw3;
-
-    struct {
-        unsigned x_origin : 16;
-        unsigned y_origin : 16;
-    } dw4;
-};
-
-struct i915_3dstate_modes_5
-{
-    struct {
-        unsigned pad0 : 16;
-        unsigned ptc_op : 1;
-        unsigned tc_disable : 1;
-        unsigned prc_op : 1;
-        unsigned pad1 : 5;
-        unsigned opcode : 5;
-        unsigned type : 3;
-    } dw0;
-};
-
 #endif /*_I915_STRUCTS_H */
commit 4844254431695158287167e3b0fad25d9efb7a6c
Author: root <root at xhh-bl32.(none)>
Date:   Tue Jun 26 16:32:30 2007 +0800

    a fix for 945G/945GM

diff --git a/src/i915_hwmc.c b/src/i915_hwmc.c
index bc5b728..0f57a5f 100644
--- a/src/i915_hwmc.c
+++ b/src/i915_hwmc.c
@@ -380,7 +380,7 @@ static void i915_unmap_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *ctxp
 static Bool i915_allocate_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *ctxpriv)
 {
     I830Ptr pI830 = I830PTR(pScrn);
-    int flags = (IS_I915G(pI830) || IS_I915GM(pI830)) ? 
+    int flags = (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830) || IS_I945GM(pI830)) ? 
         (ALIGN_BOTH_ENDS | NEED_PHYSICAL_ADDR) : ALIGN_BOTH_ENDS;
     
     if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC]Static Indirect State",
diff --git a/src/xvmc/I915XvMC.c b/src/xvmc/I915XvMC.c
index 3df6ebe..bc25a4c 100644
--- a/src/xvmc/I915XvMC.c
+++ b/src/xvmc/I915XvMC.c
@@ -214,6 +214,46 @@ _STATIC_ void i915_flush_with_flush_bit_clear(i915XvMCContext *pI915XvMC)
     i915_flush(pI915XvMC, 1, 0);
 }
 
+_STATIC_ void i915_3d_initialization(XvMCContext *context)
+{
+    i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
+    struct i915_3dstate_coord_set_bindings coord_set_bindings;
+    struct i915_3dstate_drawing_rectangle drawing_rectangle;
+    struct i915_3dstate_modes_5 modes_5;
+    i915_flush_with_flush_bit_clear(pI915XvMC);
+
+    memset(&coord_set_bindings, 0, sizeof(coord_set_bindings));
+    coord_set_bindings.dw0.type = CMD_3D;
+    coord_set_bindings.dw0.opcode = OPC_3DSTATE_COORD_SET_BINDINGS;
+    coord_set_bindings.dw0.itcs7_src = 7;
+    coord_set_bindings.dw0.itcs6_src = 6;
+    coord_set_bindings.dw0.itcs5_src = 5;
+    coord_set_bindings.dw0.itcs4_src = 4;
+    coord_set_bindings.dw0.itcs3_src = 3;
+    coord_set_bindings.dw0.itcs2_src = 2;
+    coord_set_bindings.dw0.itcs1_src = 1;
+    coord_set_bindings.dw0.itcs0_src = 0;
+    intelBatchbufferData(pI915XvMC, &coord_set_bindings, sizeof(coord_set_bindings), 0);
+
+    memset(&drawing_rectangle, 0, sizeof(drawing_rectangle));
+    drawing_rectangle.dw0.type = CMD_3D;
+    drawing_rectangle.dw0.opcode = OPC_3DSTATE_DRAWING_RECTANGLE;
+    drawing_rectangle.dw0.length = 3;
+    drawing_rectangle.dw2.x_min = 0;
+    drawing_rectangle.dw2.y_min = 0;
+    drawing_rectangle.dw3.x_max = 2047;
+    drawing_rectangle.dw3.y_max = 2047;
+    intelBatchbufferData(pI915XvMC, &drawing_rectangle, sizeof(drawing_rectangle), 0);
+
+    memset(&modes_5, 0, sizeof(modes_5));
+    modes_5.dw0.type = CMD_3D;
+    modes_5.dw0.opcode = OPC_3DSTATE_MODES_5;
+    modes_5.dw0.prc_op = 1;
+    modes_5.dw0.ptc_op = 1;
+    intelBatchbufferData(pI915XvMC, &modes_5, sizeof(modes_5), 0);
+}
+
+
 /* for MC picture rendering */
 _STATIC_ void i915_mc_static_indirect_state_buffer(XvMCContext *context, 
                                                    XvMCSurface *surface,
@@ -513,7 +553,9 @@ _STATIC_ void i915_mc_load_sis_msb_buffers(XvMCContext *context)
     load_indirect->dw0.length = (size >> 2) - 2;
 
     if (pI915XvMC->deviceID == PCI_CHIP_I915_G ||
-        pI915XvMC->deviceID == PCI_CHIP_I915_GM)
+        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;
@@ -529,7 +571,6 @@ _STATIC_ void i915_mc_load_sis_msb_buffers(XvMCContext *context)
     else
         sis->dw0.buffer_address = (pI915XvMC->sis.bus_addr >> 2);
 
-
     /* MSB */
     msb = (msb_state *)(++sis);
     msb->dw0.valid = 1;
@@ -633,12 +674,6 @@ _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][1];
-    fmv.s[1] = mb->PMV[0][0][0];
-    bmv.s[0] = mb->PMV[0][1][1];
-    bmv.s[1] = mb->PMV[0][1][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];
@@ -1008,12 +1043,12 @@ _STATIC_ void i915_mc_one_time_state_initialization(XvMCContext *context)
     s6->alpha_test_enable = 0;
     s6->alpha_test_function = 0;
     s6->alpha_reference_value = 0;
-    s6->depth_test_enable = 1;
+    s6->depth_test_enable = 0;
     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->src_blend_factor = 0;
+    s6->dest_blend_factor = 0;
     s6->depth_buffer_write = 0;
     s6->color_buffer_write = 1;
     s6->triangle_pv = 0;
@@ -1034,7 +1069,9 @@ _STATIC_ void i915_mc_one_time_state_initialization(XvMCContext *context)
     load_indirect->dw0.length = (size >> 2) - 2;
 
     if (pI915XvMC->deviceID == PCI_CHIP_I915_G ||
-        pI915XvMC->deviceID == PCI_CHIP_I915_GM)
+        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;
@@ -1121,7 +1158,9 @@ _STATIC_ void i915_mc_invalidate_subcontext_buffers(XvMCContext *context, unsign
     load_indirect->dw0.opcode = OPC_3DSTATE_LOAD_INDIRECT;
 
     if (pI915XvMC->deviceID == PCI_CHIP_I915_G ||
-        pI915XvMC->deviceID == PCI_CHIP_I915_GM)
+        pI915XvMC->deviceID == PCI_CHIP_I915_GM ||
+        pI915XvMC->deviceID == PCI_CHIP_I945_G ||
+        pI915XvMC->deviceID == PCI_CHIP_I945_GM)
         load_indirect->dw0.mem_select = 0;
     else
         load_indirect->dw0.mem_select = 1;
@@ -1880,7 +1919,9 @@ Status XvMCCreateContext(Display *display, XvPortID port,
     pI915XvMC->psc.size = tmpComm->psc.size;
 
     if (pI915XvMC->deviceID == PCI_CHIP_I915_G ||
-        pI915XvMC->deviceID == PCI_CHIP_I915_GM) {
+        pI915XvMC->deviceID == PCI_CHIP_I915_GM ||
+        pI915XvMC->deviceID == PCI_CHIP_I945_G ||
+        pI915XvMC->deviceID == PCI_CHIP_I945_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;
@@ -2356,6 +2397,7 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context,
 
     LOCK_HARDWARE(pI915XvMC);
     // if (!pI915XvMC->inited_mc) {
+    i915_3d_initialization(context);
     i915_mc_invalidate_subcontext_buffers(context, BLOCK_SIS | BLOCK_SSB 
                                           | BLOCK_MSB | BLOCK_PSP | BLOCK_PSC);
     i915_mc_sampler_state_buffer(context);
diff --git a/src/xvmc/i915_structs.h b/src/xvmc/i915_structs.h
index 05a23aa..24f215b 100644
--- a/src/xvmc/i915_structs.h
+++ b/src/xvmc/i915_structs.h
@@ -36,8 +36,11 @@ struct i915_mi_flush
 #define OPC_3DSTATE_PIXEL_SHADER_CONSTANTS      (0x06 + (0x1d << 8))
 #define OPC_3DSTATE_LOAD_INDIRECT               (0x07 + (0x1d << 8))
 
+#define OPC_3DSTATE_MODES_5                     (0x0c)
+#define OPC_3DSTATE_COORD_SET_BINDINGS          (0x16)
 #define OPC_3DPRIMITIVE                         (0x1f)
 
+#define OPC_3DSTATE_DRAWING_RECTANGLE           (0x80 + (0x1d << 8))
 #define OPC_3DSTATE_SCISSOR_RECTANGLE           (0x81 + (0x1d << 8))
 #define OPC_3DSTATE_DEST_BUFFER_VARIABLES       (0x85 + (0x1d << 8))
 #define OPC_3DSTATE_DEST_BUFFER_VARIABLES_MPEG  (0x87 + (0x1d << 8))
@@ -902,4 +905,66 @@ struct i915_3dprimitive
     } dw0;
 };
 
+struct i915_3dstate_coord_set_bindings
+{
+    struct {
+        unsigned itcs0_src : 3;
+        unsigned itcs1_src : 3;
+        unsigned itcs2_src : 3;
+        unsigned itcs3_src : 3;
+        unsigned itcs4_src : 3;
+        unsigned itcs5_src : 3;
+        unsigned itcs6_src : 3;
+        unsigned itcs7_src : 3;
+        unsigned opcode : 5;
+        unsigned type : 3;
+    } dw0;
+};
+
+struct i915_3dstate_drawing_rectangle
+{
+    struct {
+        unsigned length : 16;
+        unsigned opcode : 13;
+        unsigned type : 3;
+    } dw0;
+
+    struct {
+        unsigned pad0 : 24;
+        unsigned y_dither_offset : 2;
+        unsigned x_dither_offset : 2;
+        unsigned pad1 : 2;
+        unsigned dbco_disable : 1;
+        unsigned fsc_disable : 1;
+    } dw1;
+
+    struct {
+        unsigned x_min : 16;
+        unsigned y_min : 16;
+    } dw2;
+
+    struct {
+        unsigned x_max : 16;
+        unsigned y_max : 16;
+    } dw3;
+
+    struct {
+        unsigned x_origin : 16;
+        unsigned y_origin : 16;
+    } dw4;
+};
+
+struct i915_3dstate_modes_5
+{
+    struct {
+        unsigned pad0 : 16;
+        unsigned ptc_op : 1;
+        unsigned tc_disable : 1;
+        unsigned prc_op : 1;
+        unsigned pad1 : 5;
+        unsigned opcode : 5;
+        unsigned type : 3;
+    } dw0;
+};
+
 #endif /*_I915_STRUCTS_H */
commit 8c249765ce788f8adb0325a8e3016a0eae74b13b
Author: root <root at xhh-bl32.(none)>
Date:   Mon Jun 25 14:07:01 2007 +0800

    1. using batch buffer
    
    2. implement macroblock_ipicture instruction
    3. 16bit INTRA block

diff --git a/src/i830.h b/src/i830.h
index 2149782..cde15ad 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -649,10 +649,8 @@ extern long I830CheckAvailableMemory(ScrnInfoPtr pScrn);
 Bool i830_allocate_2d_memory(ScrnInfoPtr pScrn);
 Bool i830_allocate_texture_memory(ScrnInfoPtr pScrn);
 Bool i830_allocate_3d_memory(ScrnInfoPtr pScrn);
-Bool i830_allocate_xvmc_surface(ScrnInfoPtr pScrn, i830_memory **surface,
-                                unsigned long size);
 Bool i830_allocate_xvmc_buffer(ScrnInfoPtr pScrn, const char *name,
-                               i830_memory **buffer, unsigned long size);
+                               i830_memory **buffer, unsigned long size, int flags);
 extern Bool I830IsPrimary(ScrnInfoPtr pScrn);
 
 extern Bool I830I2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, int i2c_reg,
diff --git a/src/i830_memory.c b/src/i830_memory.c
index 7022167..fcf0ebf 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -1760,40 +1760,21 @@ i830_xf86AllocateOffscreenLinear(ScreenPtr pScreen, int length,
 }
 
 /*
- * Allocate memory for XvMC surface
- */
-Bool
-i830_allocate_xvmc_surface(ScrnInfoPtr pScrn, i830_memory **surface, unsigned long size)
-{
-    I830Ptr pI830 = I830PTR(pScrn);
-
-    *surface = i830_allocate_memory(pScrn, "XvMC surface", size,
-                                    GTT_PAGE_SIZE, ALIGN_BOTH_ENDS);
-
-    if (!*surface) {
-        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-                   "Failed to allocate XvMC surface space.\n");
-        return FALSE;
-    }
-
-    return TRUE;
-}
-
-/*
  * Allocate memory for MC compensation
  */
-Bool i830_allocate_xvmc_buffer(ScrnInfoPtr pScrn, const char *name, i830_memory **buffer, unsigned long size)
+Bool i830_allocate_xvmc_buffer(ScrnInfoPtr pScrn, const char *name,
+                               i830_memory **buffer, unsigned long size,
+                               int flags)
 {
-    I830Ptr pI830 = I830PTR(pScrn);
-
     *buffer = i830_allocate_memory(pScrn, name, size,
-                                   GTT_PAGE_SIZE, ALIGN_BOTH_ENDS);
+                                   GTT_PAGE_SIZE, flags);
 
     if (!*buffer) {
         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
                    "Failed to allocate memory for %s.\n", name);
         return FALSE;
     }
+
     return TRUE;
 }
 #endif
diff --git a/src/i915_hwmc.c b/src/i915_hwmc.c
index e5c8bd4..bc5b728 100644
--- a/src/i915_hwmc.c
+++ b/src/i915_hwmc.c
@@ -70,10 +70,20 @@ typedef struct _I915XvMCSurfacePriv
 
 typedef struct _I915XvMCContextPriv
 {
-    i830_memory *mcSubContexts;
-    drm_handle_t subcontexts_handle;
+    i830_memory *mcStaticIndirectState;
+    drm_handle_t sis_handle;
+    i830_memory *mcSamplerState;
+    drm_handle_t ssb_handle;
+    i830_memory *mcMapState;
+    drm_handle_t msb_handle;
+    i830_memory *mcPixelShaderProgram;
+    drm_handle_t psp_handle;
+    i830_memory *mcPixelShaderConstants;
+    drm_handle_t psc_handle;
     i830_memory *mcCorrdata;
     drm_handle_t corrdata_handle;
+    i830_memory *mcBatchBuffer;
+    drm_handle_t batchbuffer_handle;
 } I915XvMCContextPriv;
 
 typedef struct _I915XvMC 
@@ -120,8 +130,7 @@ static XF86MCSurfaceInfoRec i915_YV12_mpg2_surface =
     720,
     576,
     XVMC_MPEG_2,
-    XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING |
-    XVMC_INTRA_UNSIGNED,
+    XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING,
     &yv12_subpicture_list
 };
 
@@ -135,8 +144,7 @@ static XF86MCSurfaceInfoRec i915_YV12_mpg1_surface =
     720,
     576,
     XVMC_MPEG_1,
-    XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING |
-    XVMC_INTRA_UNSIGNED,
+    XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING,
     &yv12_subpicture_list
 };
 
@@ -264,11 +272,47 @@ static Bool i915_map_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *ctxpri
     I830Ptr pI830 = I830PTR(pScrn);
 
     if (drmAddMap(pI830->drmSubFD,
-                  (drm_handle_t)(ctxpriv->mcSubContexts->offset + pI830->LinearAddr),
-                  ctxpriv->mcSubContexts->size, DRM_AGP, 0,
-                  (drmAddress)&ctxpriv->subcontexts_handle) < 0) {
+                  (drm_handle_t)(ctxpriv->mcStaticIndirectState->offset + pI830->LinearAddr),
+                  ctxpriv->mcStaticIndirectState->size, DRM_AGP, 0,
+                  (drmAddress)&ctxpriv->sis_handle) < 0) {
         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-                   "[drm] drmAddMap(corrdata_handle) failed!\n");
+                   "[drm] drmAddMap(sis_handle) failed!\n");
+        return FALSE;
+    }
+
+    if (drmAddMap(pI830->drmSubFD,
+                  (drm_handle_t)(ctxpriv->mcSamplerState->offset + pI830->LinearAddr),
+                  ctxpriv->mcSamplerState->size, DRM_AGP, 0,
+                  (drmAddress)&ctxpriv->ssb_handle) < 0) {
+        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                   "[drm] drmAddMap(ssb_handle) failed!\n");
+        return FALSE;
+    }
+
+    if (drmAddMap(pI830->drmSubFD,
+                  (drm_handle_t)(ctxpriv->mcMapState->offset + pI830->LinearAddr),
+                  ctxpriv->mcMapState->size, DRM_AGP, 0,
+                  (drmAddress)&ctxpriv->msb_handle) < 0) {
+        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                   "[drm] drmAddMap(msb_handle) failed!\n");
+        return FALSE;
+    }
+
+    if (drmAddMap(pI830->drmSubFD,
+                  (drm_handle_t)(ctxpriv->mcPixelShaderProgram->offset + pI830->LinearAddr),
+                  ctxpriv->mcPixelShaderProgram->size, DRM_AGP, 0,
+                  (drmAddress)&ctxpriv->psp_handle) < 0) {
+        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                   "[drm] drmAddMap(psp_handle) failed!\n");
+        return FALSE;
+    }
+
+    if (drmAddMap(pI830->drmSubFD,
+                  (drm_handle_t)(ctxpriv->mcPixelShaderConstants->offset + pI830->LinearAddr),
+                  ctxpriv->mcPixelShaderConstants->size, DRM_AGP, 0,
+                  (drmAddress)&ctxpriv->psc_handle) < 0) {
+        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                   "[drm] drmAddMap(psc_handle) failed!\n");
         return FALSE;
     }
 
@@ -281,6 +325,15 @@ static Bool i915_map_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *ctxpri
         return FALSE;
     }
 
+    if (drmAddMap(pI830->drmSubFD,
+                  (drm_handle_t)(ctxpriv->mcBatchBuffer->offset + pI830->LinearAddr),
+                  ctxpriv->mcBatchBuffer->size, DRM_AGP, 0,
+                  (drmAddress)&ctxpriv->batchbuffer_handle) < 0) {
+        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                   "[drm] drmAddMap(batchbuffer_handle) failed!\n");
+        return FALSE;
+    }
+        
     return TRUE;
 }
 
@@ -288,26 +341,87 @@ static void i915_unmap_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *ctxp
 {
     I830Ptr pI830 = I830PTR(pScrn);
     
-    if (ctxpriv->subcontexts_handle) {
-        drmRmMap(pI830->drmSubFD, ctxpriv->subcontexts_handle);
-        ctxpriv->subcontexts_handle = 0;
+    if (ctxpriv->sis_handle) {
+        drmRmMap(pI830->drmSubFD, ctxpriv->sis_handle);
+        ctxpriv->sis_handle = 0;
+    }
+
+    if (ctxpriv->ssb_handle) {
+        drmRmMap(pI830->drmSubFD, ctxpriv->ssb_handle);
+        ctxpriv->ssb_handle = 0;
+    }
+
+    if (ctxpriv->msb_handle) {
+        drmRmMap(pI830->drmSubFD, ctxpriv->msb_handle);
+        ctxpriv->msb_handle = 0;
+    }
+
+    if (ctxpriv->psp_handle) {
+        drmRmMap(pI830->drmSubFD, ctxpriv->psp_handle);
+        ctxpriv->psp_handle = 0;
+    }
+
+    if (ctxpriv->psc_handle) {
+        drmRmMap(pI830->drmSubFD, ctxpriv->psc_handle);
+        ctxpriv->psc_handle = 0;
     }
 
     if (ctxpriv->corrdata_handle) {
         drmRmMap(pI830->drmSubFD, ctxpriv->corrdata_handle);
         ctxpriv->corrdata_handle = 0;
     }
+
+    if (ctxpriv->batchbuffer_handle) {
+        drmRmMap(pI830->drmSubFD, ctxpriv->batchbuffer_handle);
+        ctxpriv->batchbuffer_handle = 0;
+    }
 }
 
 static Bool i915_allocate_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *ctxpriv)
 {
-    if (!i830_allocate_xvmc_buffer(pScrn, "buffers for context subsets",
-                                   &(ctxpriv->mcSubContexts), 8 * 1024)) {
+    I830Ptr pI830 = I830PTR(pScrn);
+    int flags = (IS_I915G(pI830) || IS_I915GM(pI830)) ? 
+        (ALIGN_BOTH_ENDS | NEED_PHYSICAL_ADDR) : ALIGN_BOTH_ENDS;
+    
+    if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC]Static Indirect State",
+                                  &(ctxpriv->mcStaticIndirectState), 4 * 1024,
+                                  flags)) {
+        return FALSE;
+    }
+
+    if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC]Sampler State",
+                                  &(ctxpriv->mcSamplerState), 4 * 1024,
+                                  flags)) {
+        return FALSE;
+    }
+
+    if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC]Map State",
+                                  &(ctxpriv->mcMapState), 4 * 1024,
+                                  flags)) {
+        return FALSE;
+    }
+
+    if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC]Pixel Shader Program",
+                                  &(ctxpriv->mcPixelShaderProgram), 4 * 1024,
+                                  flags)) {
+        return FALSE;
+    }
+
+    if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC]Pixel Shader Constants",
+                                  &(ctxpriv->mcPixelShaderConstants), 4 * 1024,
+                                  flags)) {
+        return FALSE;
+    }
+
+    if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC]Correction Data Buffer", 
+                                   &(ctxpriv->mcCorrdata), 512 * 1024,
+                                   ALIGN_BOTH_ENDS)) {
         return FALSE;
     }
 
-    if (!i830_allocate_xvmc_buffer(pScrn, "Correction Data Buffer", 
-                                   &(ctxpriv->mcCorrdata), 1 * 1024 * 1024)) {
+    if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC]batch buffer",
+                                   &(ctxpriv->mcBatchBuffer), 8 * 1024,
+                                   ALIGN_BOTH_ENDS)) {
         return FALSE;
     }
 
@@ -317,15 +431,40 @@ static Bool i915_allocate_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *c
 
 static void i915_free_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *ctxpriv)
 {
-    if (ctxpriv->mcSubContexts) {
-        i830_free_memory(pScrn, ctxpriv->mcSubContexts);
-        ctxpriv->mcSubContexts = NULL;
+    if (ctxpriv->mcStaticIndirectState) {
+        i830_free_memory(pScrn, ctxpriv->mcStaticIndirectState);
+        ctxpriv->mcStaticIndirectState = NULL;
+    }
+
+    if (ctxpriv->mcSamplerState) {
+        i830_free_memory(pScrn, ctxpriv->mcSamplerState);
+        ctxpriv->mcSamplerState = NULL;
+    }
+
+    if (ctxpriv->mcMapState) {
+        i830_free_memory(pScrn, ctxpriv->mcMapState);
+        ctxpriv->mcMapState = NULL;
+    }
+
+    if (ctxpriv->mcPixelShaderProgram) {
+        i830_free_memory(pScrn, ctxpriv->mcPixelShaderProgram);
+        ctxpriv->mcPixelShaderProgram = NULL;
+    }
+
+    if (ctxpriv->mcPixelShaderConstants) {
+        i830_free_memory(pScrn, ctxpriv->mcPixelShaderConstants);
+        ctxpriv->mcPixelShaderConstants = NULL;
     }
 
     if (ctxpriv->mcCorrdata) {
         i830_free_memory(pScrn, ctxpriv->mcCorrdata);
         ctxpriv->mcCorrdata = NULL;
     }
+
+    if (ctxpriv->mcBatchBuffer) {
+        i830_free_memory(pScrn, ctxpriv->mcBatchBuffer);
+        ctxpriv->mcBatchBuffer = NULL;
+    }
 }
 
 /**************************************************************************
@@ -347,6 +486,7 @@ static int I915XvMCCreateContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext,
 {
     I830Ptr pI830 = I830PTR(pScrn);
     DRIInfoPtr pDRIInfo = pI830->pDRIInfo;
+    I830DRIPtr pI830DRI = pDRIInfo->devPrivate;
     I915XvMCCreateContextRec *contextRec = NULL;
     I915XvMCPtr pXvMC = pI830->xvmc;
     I915XvMCContextPriv *ctxpriv = NULL;
@@ -419,16 +559,37 @@ static int I915XvMCCreateContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext,
     }
 
     contextRec->ctxno = i;
-    contextRec->subcontexts.handle = ctxpriv->subcontexts_handle;
-    contextRec->subcontexts.offset = ctxpriv->mcSubContexts->offset;
-    contextRec->subcontexts.size = ctxpriv->mcSubContexts->size;
+    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->batchbuffer.handle = ctxpriv->batchbuffer_handle;
+    contextRec->batchbuffer.offset = ctxpriv->mcBatchBuffer->offset;
+    contextRec->batchbuffer.size = ctxpriv->mcBatchBuffer->size;
     contextRec->sarea_size = pDRIInfo->SAREASize;
     contextRec->sarea_priv_offset = sizeof(XF86DRISAREARec);
     contextRec->screen = pScrn->pScreen->myNum;
     contextRec->depth = pScrn->bitsPerPixel;
+    contextRec->deviceID = pI830DRI->deviceID;
     contextRec->initAttrs = vx->xvAttr;
 
     pXvMC->ncontexts++;
@@ -482,7 +643,9 @@ static int I915XvMCCreateSurface(ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf,
     ctx = pSurf->context;
     bufsize = size_yuv420(ctx->width, ctx->height);
 
-    if (!i830_allocate_xvmc_surface(pScrn, &(sfpriv->surface), bufsize)) {
+    if (!i830_allocate_xvmc_buffer(pScrn, "XvMC surface", 
+                                   &(sfpriv->surface), bufsize,
+                                   ALIGN_BOTH_ENDS)) {
         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
                    "[XvMC] I915XvMCCreateSurface: Failed to allocate XvMC surface space!\n");
         xfree(sfpriv);
@@ -510,7 +673,6 @@ static int I915XvMCCreateSurface(ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf,
         if (!pXvMC->surfaces[srfno])
             break;
     }
-
     surfaceRec->srfno = srfno;
     surfaceRec->srf.handle = sfpriv->surface_handle;
     surfaceRec->srf.offset = sfpriv->surface->offset;
@@ -567,7 +729,9 @@ static int I915XvMCCreateSubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSubp,
     ctx = pSubp->context;
     bufsize = size_xx44(ctx->width, ctx->height);
 
-    if (!i830_allocate_xvmc_surface(pScrn, &(sfpriv->surface), bufsize)) {
+    if (!i830_allocate_xvmc_buffer(pScrn, "XvMC surface", 
+                                   &(sfpriv->surface), bufsize,
+                                   ALIGN_BOTH_ENDS)) {
         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
                    "[XvMC] I915XvMCCreateSurface: Failed to allocate XvMC surface space!\n");
         xfree(sfpriv);
diff --git a/src/i915_hwmc.h b/src/i915_hwmc.h
index 42d2b29..a4b4220 100644
--- a/src/i915_hwmc.h
+++ b/src/i915_hwmc.h
@@ -39,21 +39,28 @@ typedef struct
 
 struct hwmc_buffer
 {
-    unsigned handle;
-    unsigned offset;
-    unsigned size;
+    drm_handle_t handle;
+    unsigned long offset;
+    unsigned long size;
+    unsigned long bus_addr;
 };
 
 typedef struct 
 {
     unsigned ctxno; /* XvMC private context reference number */
     drm_context_t drmcontext;
-    struct hwmc_buffer subcontexts;
+    struct hwmc_buffer sis;
+    struct hwmc_buffer ssb;
+    struct hwmc_buffer msb;
+    struct hwmc_buffer psp;
+    struct hwmc_buffer psc;
     struct hwmc_buffer corrdata;/* Correction Data Buffer */
+    struct hwmc_buffer batchbuffer;
     unsigned sarea_size;
     unsigned sarea_priv_offset;
     unsigned screen;
     unsigned depth;
+    int deviceID;
     I915XvMCAttrHolder initAttrs;
 } I915XvMCCreateContextRec;
 
diff --git a/src/xvmc/I915XvMC.c b/src/xvmc/I915XvMC.c
index 0257d53..3df6ebe 100644
--- a/src/xvmc/I915XvMC.c
+++ b/src/xvmc/I915XvMC.c
@@ -196,19 +196,24 @@ _STATIC_ unsigned long size_yuv420(int w, int h)
     return h * (yPitch + uvPitch);
 }
 
-_STATIC_ void i915_flush_with_flush_bit_clear(i915XvMCContext *pI915XvMC)
+_STATIC_ void i915_flush(i915XvMCContext *pI915XvMC, int map, int render)
 {
     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 = 1;
-    mi_flush.dw0.render_cache_flush_inhibit = 0;
+    mi_flush.dw0.map_cache_invalidate = map;
+    mi_flush.dw0.render_cache_flush_inhibit = render;
 
     intelBatchbufferData(pI915XvMC, &mi_flush, sizeof(mi_flush), 0);
 }
 
+_STATIC_ void i915_flush_with_flush_bit_clear(i915XvMCContext *pI915XvMC)
+{
+    i915_flush(pI915XvMC, 1, 0);
+}
+
 /* for MC picture rendering */
 _STATIC_ void i915_mc_static_indirect_state_buffer(XvMCContext *context, 
                                                    XvMCSurface *surface,
@@ -314,6 +319,8 @@ _STATIC_ void i915_mc_static_indirect_state_buffer(XvMCContext *context,
             dest_buffer_variables_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;
 
@@ -389,7 +396,7 @@ _STATIC_ void i915_mc_map_state_buffer(XvMCContext *context,
     tm->tm2.cube_face = 0;
     tm->tm2.pitch = (privFuture->yStride >> 2) - 1;
 
-    /* 3DSATE_MAP_STATE: U*/
+    /* 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;
@@ -484,7 +491,7 @@ _STATIC_ void i915_mc_map_state_buffer(XvMCContext *context,
     tm->tm2.pitch = (privFuture->uvStride >> 2) - 1;
 }
 
-_STATIC_ void i915_mc_load_indirect_buffer(XvMCContext *context)
+_STATIC_ void i915_mc_load_sis_msb_buffers(XvMCContext *context)
 {
     struct i915_3dstate_load_indirect *load_indirect;
     sis_state *sis = NULL;
@@ -492,6 +499,7 @@ _STATIC_ void i915_mc_load_indirect_buffer(XvMCContext *context)
     i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
     void *base = NULL;
     unsigned size;
+    int mem_select = 1;
 
     i915_flush_with_flush_bit_clear(pI915XvMC);
 
@@ -501,22 +509,38 @@ _STATIC_ void i915_mc_load_indirect_buffer(XvMCContext *context)
     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.mem_select = 1;  /* Bearlake only */
     load_indirect->dw0.block_mask = BLOCK_SIS | BLOCK_MSB;
     load_indirect->dw0.length = (size >> 2) - 2;
 
+    if (pI915XvMC->deviceID == PCI_CHIP_I915_G ||
+        pI915XvMC->deviceID == PCI_CHIP_I915_GM)
+        mem_select = 0;
+
+    load_indirect->dw0.mem_select = mem_select;
+
     /* SIS */
     sis = (sis_state *)(++load_indirect);
     sis->dw0.valid = 1;
-    sis->dw0.buffer_address = (pI915XvMC->sis.offset >> 2);
+    sis->dw0.force = 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 */
     msb = (msb_state *)(++sis);
     msb->dw0.valid = 1;
-    msb->dw0.buffer_address = (pI915XvMC->msb.offset >> 2);
+    msb->dw0.force = 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(pI915XvMC, base, size, 0);
     free(base);
 }
@@ -537,6 +561,21 @@ _STATIC_ void i915_mc_mpeg_set_origin(XvMCContext *context, XvMCMacroBlock *mb)
     intelBatchbufferData(pI915XvMC, &set_origin, sizeof(set_origin), 0);
 }
 
+_STATIC_ void i915_mc_mpeg_macroblock_ipicture(XvMCContext *context, XvMCMacroBlock *mb)
+{
+    struct i915_3dmpeg_macroblock_ipicture macroblock_ipicture;
+    i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
+
+    /* 3DMPEG_MACROBLOCK_IPICTURE */
+    memset(&macroblock_ipicture, 0, sizeof(macroblock_ipicture));
+    macroblock_ipicture.dw0.type = CMD_3D;
+    macroblock_ipicture.dw0.opcode = OPC_3DMPEG_MACROBLOCK_IPICTURE;
+    macroblock_ipicture.dw0.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD);
+
+    intelBatchbufferData(pI915XvMC, &macroblock_ipicture, sizeof(macroblock_ipicture), 0);
+}
+
+
 _STATIC_ void i915_mc_mpeg_macroblock_0mv(XvMCContext *context, XvMCMacroBlock *mb)
 {
     struct i915_3dmpeg_macroblock_0mv macroblock_0mv;
@@ -553,14 +592,16 @@ _STATIC_ void i915_mc_mpeg_macroblock_0mv(XvMCContext *context, XvMCMacroBlock *
     macroblock_0mv.header.dw1.h263_4mv = 0;     /* should be 0 */
     macroblock_0mv.header.dw1.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD);
     
+/*
     if (!mb->coded_block_pattern)
         macroblock_0mv.header.dw1.dct_type = XVMC_DCT_TYPE_FRAME;
+*/
 
     macroblock_0mv.header.dw1.motion_type = 0; // (mb->motion_type & 0x3);
     macroblock_0mv.header.dw1.vertical_field_select = 0; // mb->motion_vertical_field_select & 0xf;
     macroblock_0mv.header.dw1.coded_block_pattern = mb->coded_block_pattern;
     macroblock_0mv.header.dw1.skipped_macroblocks = 0;
-    
+
     intelBatchbufferData(pI915XvMC, &macroblock_0mv, sizeof(macroblock_0mv), 0);
 }
 
@@ -584,7 +625,7 @@ _STATIC_ void i915_mc_mpeg_macroblock_1fbmv(XvMCContext *context, XvMCMacroBlock
     macroblock_1fbmv.header.dw1.h263_4mv = 0;   /* should be 0 */
     macroblock_1fbmv.header.dw1.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD);
     
-    if (!mb->coded_block_pattern)
+    if (!(mb->coded_block_pattern & 0x3f))
         macroblock_1fbmv.header.dw1.dct_type = XVMC_DCT_TYPE_FRAME;
 
     macroblock_1fbmv.header.dw1.motion_type = (mb->motion_type & 0x03);
@@ -629,7 +670,7 @@ _STATIC_ void i915_mc_mpeg_macroblock_2fbmv(XvMCContext *context, XvMCMacroBlock
     macroblock_2fbmv.header.dw1.h263_4mv = 0;   /* should be 0 */
     macroblock_2fbmv.header.dw1.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD);
     
-    if (!mb->coded_block_pattern)
+    if (!(mb->coded_block_pattern & 0x3f))
         macroblock_2fbmv.header.dw1.dct_type = XVMC_DCT_TYPE_FRAME;
 
     macroblock_2fbmv.header.dw1.motion_type = (mb->motion_type & 0x03);
@@ -941,6 +982,7 @@ _STATIC_ void i915_mc_one_time_state_initialization(XvMCContext *context)
     i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
     unsigned size;
     void *base = NULL;
+    int mem_select = 1;
 
     /* 3DSTATE_LOAD_STATE_IMMEDIATE_1 */
     size = sizeof(*load_state_immediate_1) + sizeof(*s3) + sizeof(*s6);
@@ -988,10 +1030,15 @@ _STATIC_ void i915_mc_one_time_state_initialization(XvMCContext *context)
     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.mem_select = 1;      /* Bearlake only */
     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)
+        mem_select = 0;
+
+    load_indirect->dw0.mem_select = mem_select;
+
     /* DIS */
     dis = (dis_state *)(++load_indirect);
     dis->dw0.valid = 0;
@@ -1001,26 +1048,38 @@ _STATIC_ void i915_mc_one_time_state_initialization(XvMCContext *context)
     /* SSB */
     ssb = (ssb_state *)(++dis);
     ssb->dw0.valid = 1;
-    ssb->dw0.buffer_address = (pI915XvMC->ssb.offset >> 2);
     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.buffer_address = (pI915XvMC->psp.offset >> 2);
     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.buffer_address = (pI915XvMC->psc.offset >> 2);
     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(pI915XvMC, base, size, 0);
     free(base);
 }
 
-_STATIC_ void i915_mc_start_rendering(XvMCContext *context)
+_STATIC_ void i915_mc_invalidate_subcontext_buffers(XvMCContext *context, unsigned mask)
 {
     struct i915_3dstate_load_indirect *load_indirect = NULL;
     sis_state *sis = NULL;
@@ -1031,58 +1090,99 @@ _STATIC_ void i915_mc_start_rendering(XvMCContext *context)
     psc_state *psc = NULL;
     i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
     unsigned size;
-    void *base = NULL;
+    void *base = NULL, *ptr = NULL;
 
     /* flush */
     i915_flush_with_flush_bit_clear(pI915XvMC);
 
+    size = sizeof(*load_indirect);
+    if (mask & BLOCK_SIS)
+        size += sizeof(*sis);
+    if (mask & BLOCK_DIS)
+        size += sizeof(*dis);
+    if (mask & BLOCK_SSB)
+        size += sizeof(*ssb);
+    if (mask & BLOCK_MSB)
+        size += sizeof(*msb);
+    if (mask & BLOCK_PSP)
+        size += sizeof(*psp);
+    if (mask & BLOCK_PSC)
+        size += sizeof(*psc);
+
+    if (size == sizeof(*load_indirect)) {
+        printf("There must be at least one bit set\n");
+        return;
+    }
+
     /* 3DSTATE_LOAD_INDIRECT */
-    size = sizeof(*load_indirect) + sizeof(*sis) + sizeof(*dis) + 
-        sizeof(*ssb) + sizeof(*msb) + 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.mem_select = 1;      /* Bearlake only */
-    load_indirect->dw0.block_mask = BLOCK_SIS | BLOCK_DIS | 
-        BLOCK_SSB | BLOCK_MSB | BLOCK_PSP | BLOCK_PSC;
+
+    if (pI915XvMC->deviceID == PCI_CHIP_I915_G ||
+        pI915XvMC->deviceID == PCI_CHIP_I915_GM)
+        load_indirect->dw0.mem_select = 0;
+    else
+        load_indirect->dw0.mem_select = 1;
+
+    load_indirect->dw0.block_mask = mask;
     load_indirect->dw0.length = (size >> 2) - 2;
+    ptr = ++load_indirect;
 
     /* SIS */
-    sis = (sis_state *)(++load_indirect);
-    sis->dw0.valid = 0;
-    sis->dw0.buffer_address = 0;
-    sis->dw1.length = 0;
+    if (mask & BLOCK_SIS) {
+        sis = (sis_state *)ptr;
+        sis->dw0.valid = 0;
+        sis->dw0.buffer_address = 0;
+        sis->dw1.length = 0;
+        ptr = ++sis;
+    }
 
     /* DIS */
-    dis = (dis_state *)(++sis);
-    dis->dw0.valid = 0;
-    dis->dw0.reset = 0;
-    dis->dw0.buffer_address = 0;
+    if (mask & BLOCK_DIS) {
+        dis = (dis_state *)ptr;
+        dis->dw0.valid = 0;
+        dis->dw0.reset = 0;
+        dis->dw0.buffer_address = 0;
+        ptr = ++dis;
+    }
 
     /* SSB */
-    ssb = (ssb_state *)(++dis);
-    ssb->dw0.valid = 0;
-    ssb->dw0.buffer_address = 0;
-    ssb->dw1.length = 0;
+    if (mask & BLOCK_SSB) {
+        ssb = (ssb_state *)ptr;
+        ssb->dw0.valid = 0;
+        ssb->dw0.buffer_address = 0;
+        ssb->dw1.length = 0;
+        ptr = ++ssb;
+    }
 
     /* MSB */
-    msb = (msb_state *)(++ssb);
-    msb->dw0.valid = 0;
-    msb->dw0.buffer_address = 0;
-    msb->dw1.length = 0;
+    if (mask & BLOCK_MSB) {
+        msb = (msb_state *)ptr;
+        msb->dw0.valid = 0;
+        msb->dw0.buffer_address = 0;
+        msb->dw1.length = 0;
+        ptr = ++msb;
+    }
 
     /* PSP */
-    psp = (psp_state *)(++msb);
-    psp->dw0.valid = 0;
-    psp->dw0.buffer_address = 0;
-    psp->dw1.length = 0;
-    
+    if (mask & BLOCK_PSP) {
+        psp = (psp_state *)ptr;
+        psp->dw0.valid = 0;
+        psp->dw0.buffer_address = 0;
+        psp->dw1.length = 0;
+        ptr = ++psp;
+    }
+
     /* PSC */
-    psc = (psc_state *)(++psp);
-    psc->dw0.valid = 0;
-    psc->dw0.buffer_address = 0;
-    psc->dw1.length = 0;
+    if (mask & BLOCK_PSC) {
+        psc = (psc_state *)ptr;
+        psc->dw0.valid = 0;
+        psc->dw0.buffer_address = 0;
+        psc->dw1.length = 0;
+        ptr = ++psc;
+    }
 
     intelBatchbufferData(pI915XvMC, base, size, 0);
     free(base);
@@ -1091,9 +1191,37 @@ _STATIC_ void i915_mc_start_rendering(XvMCContext *context)
 _STATIC_ int i915_xvmc_map_buffers(i915XvMCContext *pI915XvMC)
 {
     if (drmMap(pI915XvMC->fd,
-               pI915XvMC->subcontexts.handle,
-               pI915XvMC->subcontexts.size,
-               (drmAddress *)&pI915XvMC->subcontexts.map) != 0) {
+               pI915XvMC->sis.handle,
+               pI915XvMC->sis.size,
+               (drmAddress *)&pI915XvMC->sis.map) != 0) {
+        return -1;
+    }
+
+    if (drmMap(pI915XvMC->fd,
+               pI915XvMC->ssb.handle,
+               pI915XvMC->ssb.size,
+               (drmAddress *)&pI915XvMC->ssb.map) != 0) {
+        return -1;
+    }
+
+    if (drmMap(pI915XvMC->fd,
+               pI915XvMC->msb.handle,
+               pI915XvMC->msb.size,
+               (drmAddress *)&pI915XvMC->msb.map) != 0) {
+        return -1;
+    }
+
+    if (drmMap(pI915XvMC->fd,
+               pI915XvMC->psp.handle,
+               pI915XvMC->psp.size,
+               (drmAddress *)&pI915XvMC->psp.map) != 0) {
+        return -1;
+    }
+
+    if (drmMap(pI915XvMC->fd,
+               pI915XvMC->psc.handle,
+               pI915XvMC->psc.size,
+               (drmAddress *)&pI915XvMC->psc.map) != 0) {
         return -1;
     }
 
@@ -1104,20 +1232,41 @@ _STATIC_ int i915_xvmc_map_buffers(i915XvMCContext *pI915XvMC)
         return -1;
     }
     
-    pI915XvMC->sis.map = pI915XvMC->subcontexts.map;
-    pI915XvMC->msb.map = pI915XvMC->subcontexts.map + 1 * 1024;
-    pI915XvMC->ssb.map = pI915XvMC->subcontexts.map + 2 * 1024;
-    pI915XvMC->psp.map = pI915XvMC->subcontexts.map + 3 * 1024;
-    pI915XvMC->psc.map = pI915XvMC->subcontexts.map + 4 * 1024;
+    if (drmMap(pI915XvMC->fd,
+               pI915XvMC->batchbuffer.handle,
+               pI915XvMC->batchbuffer.size,
+               (drmAddress *)&pI915XvMC->batchbuffer.map) != 0) {
+        return -1;
+    }
 
     return 0;
 }
 
 _STATIC_ void i915_xvmc_unmap_buffers(i915XvMCContext *pI915XvMC)
 {
-    if (pI915XvMC->subcontexts.map) {
-        drmUnmap(pI915XvMC->subcontexts.map, pI915XvMC->subcontexts.size);
-        pI915XvMC->subcontexts.map = NULL;
+    if (pI915XvMC->sis.map) {
+        drmUnmap(pI915XvMC->sis.map, pI915XvMC->sis.size);
+        pI915XvMC->sis.map = NULL;
+    }
+
+    if (pI915XvMC->ssb.map) {
+        drmUnmap(pI915XvMC->ssb.map, pI915XvMC->ssb.size);
+        pI915XvMC->ssb.map = NULL;
+    }
+
+    if (pI915XvMC->msb.map) {
+        drmUnmap(pI915XvMC->msb.map, pI915XvMC->msb.size);
+        pI915XvMC->msb.map = NULL;
+    }
+
+    if (pI915XvMC->psp.map) {
+        drmUnmap(pI915XvMC->psp.map, pI915XvMC->psp.size);
+        pI915XvMC->psp.map = NULL;
+    }
+
+    if (pI915XvMC->psc.map) {
+        drmUnmap(pI915XvMC->psc.map, pI915XvMC->psc.size);
+        pI915XvMC->psc.map = NULL;
     }
 
     if (pI915XvMC->corrdata.map) {
@@ -1125,11 +1274,10 @@ _STATIC_ void i915_xvmc_unmap_buffers(i915XvMCContext *pI915XvMC)
         pI915XvMC->corrdata.map = NULL;
     }
 
-    pI915XvMC->sis.map = NULL;
-    pI915XvMC->msb.map = NULL;
-    pI915XvMC->ssb.map = NULL;
-    pI915XvMC->psp.map = NULL;
-    pI915XvMC->psc.map = NULL;
+    if (pI915XvMC->batchbuffer.map) {
+        drmUnmap(pI915XvMC->batchbuffer.map, pI915XvMC->batchbuffer.size);
+        pI915XvMC->batchbuffer.map = NULL;
+    }
 }
 
 /*
@@ -1714,22 +1862,38 @@ Status XvMCCreateContext(Display *display, XvPortID port,
 
     tmpComm = (I915XvMCCreateContextRec *)priv_data;
     pI915XvMC->ctxno = tmpComm->ctxno;
-    pI915XvMC->subcontexts.handle = tmpComm->subcontexts.handle;
-    pI915XvMC->subcontexts.offset = tmpComm->subcontexts.offset;
-    pI915XvMC->subcontexts.size = tmpComm->subcontexts.size;
-    pI915XvMC->sis.offset = pI915XvMC->subcontexts.offset;
-    pI915XvMC->sis.size = 1024;
-    pI915XvMC->msb.offset = pI915XvMC->subcontexts.offset + 1 * 1024;
-    pI915XvMC->msb.size = 1024;
-    pI915XvMC->ssb.offset = pI915XvMC->subcontexts.offset + 2 * 1024;
-    pI915XvMC->ssb.size = 1024;
-    pI915XvMC->psp.offset = pI915XvMC->subcontexts.offset + 3 * 1024;
-    pI915XvMC->psp.size = 1024;
-    pI915XvMC->psc.offset = pI915XvMC->subcontexts.offset + 4 * 1024;
-    pI915XvMC->psc.size = 1024;
+    pI915XvMC->deviceID = tmpComm->deviceID;
+    pI915XvMC->sis.handle = tmpComm->sis.handle;
+    pI915XvMC->sis.offset = tmpComm->sis.offset;
+    pI915XvMC->sis.size = tmpComm->sis.size;
+    pI915XvMC->ssb.handle = tmpComm->ssb.handle;
+    pI915XvMC->ssb.offset = tmpComm->ssb.offset;
+    pI915XvMC->ssb.size = tmpComm->ssb.size;
+    pI915XvMC->msb.handle = tmpComm->msb.handle;
+    pI915XvMC->msb.offset = tmpComm->msb.offset;
+    pI915XvMC->msb.size = tmpComm->msb.size;
+    pI915XvMC->psp.handle = tmpComm->psp.handle;
+    pI915XvMC->psp.offset = tmpComm->psp.offset;
+    pI915XvMC->psp.size = tmpComm->psp.size;
+    pI915XvMC->psc.handle = tmpComm->psc.handle;
+    pI915XvMC->psc.offset = tmpComm->psc.offset;
+    pI915XvMC->psc.size = tmpComm->psc.size;
+
+    if (pI915XvMC->deviceID == PCI_CHIP_I915_G ||
+        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;
+        pI915XvMC->psp.bus_addr = tmpComm->psp.bus_addr;
+        pI915XvMC->psc.bus_addr = tmpComm->psc.bus_addr;
+    }
+
     pI915XvMC->corrdata.handle = tmpComm->corrdata.handle;
     pI915XvMC->corrdata.offset = tmpComm->corrdata.offset;
     pI915XvMC->corrdata.size = tmpComm->corrdata.size;
+    pI915XvMC->batchbuffer.handle = tmpComm->batchbuffer.handle;
+    pI915XvMC->batchbuffer.offset = tmpComm->batchbuffer.offset;
+    pI915XvMC->batchbuffer.size = tmpComm->batchbuffer.size;
     pI915XvMC->sarea_size = tmpComm->sarea_size;
     pI915XvMC->sarea_priv_offset = tmpComm->sarea_priv_offset;
     pI915XvMC->screen = tmpComm->screen;
@@ -1859,6 +2023,7 @@ Status XvMCCreateContext(Display *display, XvPortID port,
     pthread_mutex_init(&pI915XvMC->ctxmutex, NULL);
     intelInitBatchBuffer(pI915XvMC);
     pI915XvMC->ref = 1;
+    pI915XvMC->inited_mc = 0;
     return Success;
 }
 
@@ -2190,7 +2355,15 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context,
     }
 
     LOCK_HARDWARE(pI915XvMC);
-    i915_mc_start_rendering(context);
+    // if (!pI915XvMC->inited_mc) {
+    i915_mc_invalidate_subcontext_buffers(context, BLOCK_SIS | 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);
+    pI915XvMC->inited_mc = 1;
+    //}
     intelFlushBatch(pI915XvMC, TRUE);
     UNLOCK_HARDWARE(pI915XvMC);
 
@@ -2232,36 +2405,23 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context,
         memcpy(corrdata_ptr, block_ptr, bspm);
         corrdata_ptr += bspm;
     }
-    //memset(privTarget->srf.map, 0x7f, 128);
+
     /* Lock */
     LOCK_HARDWARE(pI915XvMC);
-    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);
-    intelFlushBatch(pI915XvMC, TRUE);
-
     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_load_indirect_buffer(context);
-    intelFlushBatch(pI915XvMC, TRUE);
-    // i915_mc_mpeg_set_origin(context, &macroblock_array->macro_blocks[first_macroblock]);
+    i915_mc_load_sis_msb_buffers(context);
+    i915_mc_mpeg_set_origin(context, &macroblock_array->macro_blocks[first_macroblock]);
+
     for (i = first_macroblock; i < (num_macroblocks + first_macroblock); i++) {
-        mb = &macroblock_array->macro_blocks[i];
-        i915_mc_mpeg_set_origin(context, mb);
-        // &macroblock_array->macro_blocks[first_macroblock]);
+         mb = &macroblock_array->macro_blocks[i];
 
         /* Intra Blocks */
         if (mb->macroblock_type & XVMC_MB_TYPE_INTRA) {
-            i915_mc_mpeg_macroblock_0mv(context, mb);
-            intelFlushBatch(pI915XvMC, TRUE);
-            continue;
-        }
-
-        /* Frame Picture */
-        if ((picture_structure & XVMC_FRAME_PICTURE) == XVMC_FRAME_PICTURE) {
+            i915_mc_mpeg_macroblock_ipicture(context, mb);
+        } else if ((picture_structure & XVMC_FRAME_PICTURE) == XVMC_FRAME_PICTURE) { /* Frame Picture */
             switch (mb->motion_type & 3) {
             case XVMC_PREDICTION_FIELD: /* Field Based */
                 i915_mc_mpeg_macroblock_2fbmv(context, mb);
@@ -2269,7 +2429,7 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context,
 
             case XVMC_PREDICTION_FRAME: /* Frame Based */
                 i915_mc_mpeg_macroblock_1fbmv(context, mb);
-                break;
+            break;
 
             case XVMC_PREDICTION_DUAL_PRIME:    /* Dual Prime */
                 i915_mc_mpeg_macroblock_2fbmv(context, mb);
@@ -2298,7 +2458,7 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context,
                 break;
             }
         }       /* Field Picture */
-        intelFlushBatch(pI915XvMC, TRUE);        
+        i915_flush(pI915XvMC, 0, 1);
     }
 
     intelFlushBatch(pI915XvMC, TRUE);
diff --git a/src/xvmc/I915XvMC.h b/src/xvmc/I915XvMC.h
index e3a83d9..a27ea66 100644
--- a/src/xvmc/I915XvMC.h
+++ b/src/xvmc/I915XvMC.h
@@ -37,14 +37,25 @@ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include <X11/Xutil.h>
 
 #define I915_SUBPIC_PALETTE_SIZE        16
+#define MAX_SUBCONTEXT_LEN              1024
+
+#define PCI_CHIP_I915_G                 0x2582
+#define PCI_CHIP_I915_GM                0x2592
+#define PCI_CHIP_I945_G                 0x2772
+#define PCI_CHIP_I945_GM                0x27A2
+#define PCI_CHIP_I945_GME               0x27AE
+#define PCI_CHIP_G33_G                  0x29C2
+#define PCI_CHIP_Q35_G                  0x29B2
+#define PCI_CHIP_Q33_G                  0x29D2
 
 /***************************************************************************
 // i915XvMCDrmMap: Holds the data about the DRM maps
 ***************************************************************************/
 typedef struct _i915XvMCDrmMap {
     drm_handle_t handle;
-    unsigned offset;
-    unsigned size;
+    unsigned long offset;
+    unsigned long size;
+    unsigned long bus_addr;
     drmAddress map;
 } i915XvMCDrmMap, *i915XvMCDrmMapPtr;
 
@@ -66,7 +77,8 @@ typedef struct _i915XvMCContext {
     int lock;   /* Lightweight lock to avoid locking twice */
     int locked;
     volatile drmI830Sarea *sarea;
-
+    int inited_mc;
+    
     drmLock *driHwLock;
     drm_context_t hHWContext; /* drmcontext; */
     drm_handle_t hsarea;                /* Handle to drm shared memory area */
@@ -90,14 +102,16 @@ typedef struct _i915XvMCContext {
     XID id;
     XVisualInfo visualInfo;
     void *drawHash;
+    int deviceID;
 
     i915XvMCDrmMap sis;
     i915XvMCDrmMap msb;
     i915XvMCDrmMap ssb;
     i915XvMCDrmMap psp;
     i915XvMCDrmMap psc;
-    i915XvMCDrmMap subcontexts;
+
     i915XvMCDrmMap corrdata;
+    i915XvMCDrmMap batchbuffer;
 
     struct {
         unsigned start_offset;
diff --git a/src/xvmc/i915_structs.h b/src/xvmc/i915_structs.h
index cd842a8..05a23aa 100644
--- a/src/xvmc/i915_structs.h
+++ b/src/xvmc/i915_structs.h
@@ -253,6 +253,13 @@ struct i915_3dstate_dest_buffer_variables
 #define MPEG_P_PICTURE          2
 #define MPEG_B_PICTURE          3
 
+#define MC_SUB_1H               0
+#define MC_SUB_2H               1
+#define MC_SUB_4H               2
+
+#define MC_SUB_1V               0
+#define MC_SUB_2V               1
+
 struct i915_3dstate_dest_buffer_variables_mpeg
 {
     struct {
diff --git a/src/xvmc/intel_batchbuffer.c b/src/xvmc/intel_batchbuffer.c
index 080a939..dd54330 100644
--- a/src/xvmc/intel_batchbuffer.c
+++ b/src/xvmc/intel_batchbuffer.c
@@ -19,6 +19,8 @@
 #include "I915XvMC.h"
 #include "intel_batchbuffer.h"
 
+#define MI_BATCH_BUFFER_END     (0xA << 23)
+
 int intelEmitIrqLocked(i915XvMCContext *pI915XvMC)
 {
    drmI830IrqEmit ie;
@@ -56,7 +58,8 @@ void intelWaitIrq(i915XvMCContext *pI915XvMC, int seq)
 void intelDestroyBatchBuffer(i915XvMCContext *pI915XvMC)
 {
    if (pI915XvMC->alloc.offset) {
-      // FIXME: free the memory allocated from AGP
+       pI915XvMC->alloc.ptr = NULL;
+       pI915XvMC->alloc.offset = 0;
    } else if (pI915XvMC->alloc.ptr) {
       free(pI915XvMC->alloc.ptr);
       pI915XvMC->alloc.ptr = NULL;
@@ -68,11 +71,17 @@ void intelDestroyBatchBuffer(i915XvMCContext *pI915XvMC)
 
 void intelInitBatchBuffer(i915XvMCContext  *pI915XvMC)
 {
-   pI915XvMC->alloc.offset = 0;
-   pI915XvMC->alloc.size = 16 * 1024;
-   pI915XvMC->alloc.ptr = malloc(pI915XvMC->alloc.size);
-   pI915XvMC->alloc.active_buf = 0;
+    if (pI915XvMC->batchbuffer.map) {
+        pI915XvMC->alloc.size = pI915XvMC->batchbuffer.size;
+        pI915XvMC->alloc.offset = pI915XvMC->batchbuffer.offset;
+        pI915XvMC->alloc.ptr = pI915XvMC->batchbuffer.map;
+    } else {
+        pI915XvMC->alloc.size = 8 * 1024;
+        pI915XvMC->alloc.offset = 0;
+        pI915XvMC->alloc.ptr = malloc(pI915XvMC->alloc.size);
+    }
 
+   pI915XvMC->alloc.active_buf = 0;
    assert(pI915XvMC->alloc.ptr);
 }
 
@@ -85,37 +94,33 @@ void intelBatchbufferRequireSpace(i915XvMCContext *pI915XvMC, unsigned sz)
 void intelBatchbufferData(i915XvMCContext *pI915XvMC, const void *data, 
                           unsigned bytes, unsigned flags)
 {
-   int extra = 0;
-
    assert((bytes & 0x3) == 0);
 
-   if (bytes & 0x7)
-      extra = 1;
-
-   intelBatchbufferRequireSpace(pI915XvMC, bytes + extra << 2);
+   intelBatchbufferRequireSpace(pI915XvMC, bytes);
    memcpy(pI915XvMC->batch.ptr, data, bytes);
    pI915XvMC->batch.ptr += bytes;
    pI915XvMC->batch.space -= bytes;
 
-   if (extra) {
-      *(int *)(pI915XvMC->batch.ptr) = 0;
-      pI915XvMC->batch.ptr += 4;
-      pI915XvMC->batch.space -= 4;
-   }
-
    assert(pI915XvMC->batch.space >= 0);
 }
 
+#define MI_FLUSH                ((0 << 29) | (4 << 23))
+#define FLUSH_MAP_CACHE         (1 << 0)
+#define FLUSH_RENDER_CACHE      (0 << 2)
+#define FLUSH_WRITE_DIRTY_STATE (1 << 4)
 void intelRefillBatchLocked(i915XvMCContext *pI915XvMC, Bool allow_unlock )
 {
-   unsigned last_irq = pI915XvMC->alloc.irq_emitted;
    unsigned half = pI915XvMC->alloc.size >> 1;
    unsigned buf = (pI915XvMC->alloc.active_buf ^= 1);
+   unsigned dword[2];
 
+   dword[0] = MI_FLUSH | FLUSH_WRITE_DIRTY_STATE | FLUSH_RENDER_CACHE | FLUSH_MAP_CACHE;
+   dword[1] = 0;
+   intelCmdIoctl(pI915XvMC, (char *)&dword[0], sizeof(dword));
    pI915XvMC->alloc.irq_emitted = intelEmitIrqLocked(pI915XvMC);
 
-   if (last_irq) {
-      intelWaitIrq(pI915XvMC, last_irq);
+   if (pI915XvMC->alloc.irq_emitted) {
+       intelWaitIrq(pI915XvMC, pI915XvMC->alloc.irq_emitted);
    }
 
    pI915XvMC->batch.start_offset = pI915XvMC->alloc.offset + buf * half;
@@ -143,7 +148,16 @@ void intelFlushBatchLocked(i915XvMCContext *pI915XvMC,
       batch.DR4 = 0;
 
       if (pI915XvMC->alloc.offset) {
-         // FIXME: MI_BATCH_BUFFER_END
+          if ((batch.used & 0x4) == 0) {
+              ((int *)pI915XvMC->batch.ptr)[0] = 0;
+              ((int *)pI915XvMC->batch.ptr)[1] = MI_BATCH_BUFFER_END;
+              batch.used += 0x8;
+              pI915XvMC->batch.ptr += 0x8;
+          } else {
+              ((int *)pI915XvMC->batch.ptr)[0] = MI_BATCH_BUFFER_END;
+              batch.used += 0x4;
+              pI915XvMC->batch.ptr += 0x4;
+          }
       }
 
       pI915XvMC->batch.start_offset += batch.used;
@@ -165,7 +179,10 @@ void intelFlushBatchLocked(i915XvMCContext *pI915XvMC,
       assert(batch.start + batch.used <= pI915XvMC->alloc.offset + pI915XvMC->alloc.size);
 
       if (pI915XvMC->alloc.offset) {
-         // DRM_I830_BATCHBUFFER
+          if (drmCommandWrite(pI915XvMC->fd, DRM_I830_BATCHBUFFER, &batch, sizeof(batch))) {
+              fprintf(stderr, "DRM_I830_BATCHBUFFER: %d\n",  -errno);
+              exit(1);
+          }
       } else {
          drmI830CmdBuffer cmd;
          cmd.buf = (char *)pI915XvMC->alloc.ptr + batch.start;
commit 2b20b395541f786e4009211e4c56042257b8d114
Author: Xiang, Haihao <haihao.xiang at intel.com>
Date:   Mon Jun 25 10:43:49 2007 +0800

    fix a bug related to display surface

diff --git a/src/i915_hwmc.c b/src/i915_hwmc.c
index 58d26c2..e5c8bd4 100644
--- a/src/i915_hwmc.c
+++ b/src/i915_hwmc.c
@@ -766,15 +766,12 @@ static int I915XvMCInterceptPutImage(ScrnInfoPtr pScrn, short src_x, short src_y
                       return 1;
                    }
                    
-                   mem = pXvMC->sfprivs[i]->surface;
+                   mem = pXvMC->sfprivs[i915XvMCData->srfNo]->surface;
                    buf = pI830->FbBase + mem->offset;
                    id = i915XvMCData->real_id;
                    break;
                 }
 
-                if (i >= I915_XVMC_MAX_SURFACES)
-                    return 1;
-
                 break;
 
             default:
diff --git a/src/xvmc/I915XvMC.c b/src/xvmc/I915XvMC.c
index e73f1a8..0257d53 100644
--- a/src/xvmc/I915XvMC.c
+++ b/src/xvmc/I915XvMC.c
@@ -209,35 +209,6 @@ _STATIC_ void i915_flush_with_flush_bit_clear(i915XvMCContext *pI915XvMC)
     intelBatchbufferData(pI915XvMC, &mi_flush, sizeof(mi_flush), 0);
 }
 
-_STATIC_ void i915_flush(i915XvMCContext *pI915XvMC)
-{
-    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 = 1;
-    mi_flush.dw0.render_cache_flush_inhibit = 1;
-
-    intelBatchbufferData(pI915XvMC, &mi_flush, sizeof(mi_flush), 0);
-}
-
-_STATIC_ void __i915_flush(i915XvMCContext *pI915XvMC)
-{
-    struct i915_mi_flush mi_flush;
-    unsigned cmd[2];
-
-    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 = 1;
-    mi_flush.dw0.render_cache_flush_inhibit = 1;
-
-    cmd[0] = *(unsigned *)((char *)&mi_flush);
-    cmd[1] = 0;
-    intelCmdIoctl(pI915XvMC, (char *)&cmd[0], sizeof(cmd));
-}
-
 /* for MC picture rendering */
 _STATIC_ void i915_mc_static_indirect_state_buffer(XvMCContext *context, 
                                                    XvMCSurface *surface,
@@ -311,9 +282,10 @@ _STATIC_ void i915_mc_static_indirect_state_buffer(XvMCContext *context,
     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_offset = 1;
+        dest_buffer_variables->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;
     }
 
     /* 3DSTATE_DEST_BUFFER_VARIABLES_MPEG */
@@ -387,7 +359,7 @@ _STATIC_ void i915_mc_map_state_buffer(XvMCContext *context,
     tm->tm0.v_ls_offset = 0;
     tm->tm0.v_ls = 0;
     tm->tm0.base_address = (privPast->srf.offset >> 2);
-    tm->tm1.tile_walk = TILEWALK_XMAJOR;
+    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 */
@@ -789,9 +761,9 @@ _STATIC_ void i915_inst_texld(unsigned *inst,
 {
    dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest));
    *inst = (op | T0_DEST(dest) | T0_SAMPLER(sampler));
-    inst++;
+   inst++;
    *inst = T1_ADDRESS_REG(coord);
-    inst++;
+   inst++;
    *inst = T2_MBZ;
 }
 
@@ -925,7 +897,7 @@ _STATIC_ void i915_mc_pixel_shader_program_buffer(XvMCContext *context)
     src1 = UREG(REG_TYPE_R, 1);
     src2 = 0;
     i915_inst_arith(inst, A0_ADD, dest, A0_DEST_CHANNEL_ALL,
-                    A0_DEST_SATURATE, src0, src1, src2);
+                    0 /* A0_DEST_SATURATE */, src0, src1, src2);
     /* mul oC, r0, c0 */
     inst += 3;
     dest = UREG(REG_TYPE_OC, 0);
@@ -1048,7 +1020,7 @@ _STATIC_ void i915_mc_one_time_state_initialization(XvMCContext *context)
     free(base);
 }
 
-_STATIC_ void i915_mc_finish_render(XvMCContext *context)
+_STATIC_ void i915_mc_start_rendering(XvMCContext *context)
 {
     struct i915_3dstate_load_indirect *load_indirect = NULL;
     sis_state *sis = NULL;
@@ -1744,6 +1716,7 @@ Status XvMCCreateContext(Display *display, XvPortID port,
     pI915XvMC->ctxno = tmpComm->ctxno;
     pI915XvMC->subcontexts.handle = tmpComm->subcontexts.handle;
     pI915XvMC->subcontexts.offset = tmpComm->subcontexts.offset;
+    pI915XvMC->subcontexts.size = tmpComm->subcontexts.size;
     pI915XvMC->sis.offset = pI915XvMC->subcontexts.offset;
     pI915XvMC->sis.size = 1024;
     pI915XvMC->msb.offset = pI915XvMC->subcontexts.offset + 1 * 1024;
@@ -1754,7 +1727,6 @@ Status XvMCCreateContext(Display *display, XvPortID port,
     pI915XvMC->psp.size = 1024;
     pI915XvMC->psc.offset = pI915XvMC->subcontexts.offset + 4 * 1024;
     pI915XvMC->psc.size = 1024;
-    pI915XvMC->subcontexts.size = tmpComm->subcontexts.size;
     pI915XvMC->corrdata.handle = tmpComm->corrdata.handle;
     pI915XvMC->corrdata.offset = tmpComm->corrdata.offset;
     pI915XvMC->corrdata.size = tmpComm->corrdata.size;
@@ -2218,6 +2190,7 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context,
     }
 
     LOCK_HARDWARE(pI915XvMC);
+    i915_mc_start_rendering(context);
     intelFlushBatch(pI915XvMC, TRUE);
     UNLOCK_HARDWARE(pI915XvMC);
 
@@ -2242,9 +2215,10 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context,
 
         /* Catch no pattern case */
         if (!(mb->macroblock_type & XVMC_MB_TYPE_PATTERN) &&
-            !(mb->macroblock_type & XVMC_MB_TYPE_INTRA)) {
+            !(mb->macroblock_type & XVMC_MB_TYPE_INTRA) &&
+            mb->coded_block_pattern) {
             mb->coded_block_pattern = 0;
-            printf("no coded blocks present\n");
+            printf("no coded blocks present!\n");
         }
         
         bspm = mb_bytes[mb->coded_block_pattern];
@@ -2327,7 +2301,6 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context,
         intelFlushBatch(pI915XvMC, TRUE);        
     }
 
-    i915_mc_finish_render(context);
     intelFlushBatch(pI915XvMC, TRUE);
     pI915XvMC->last_render = pI915XvMC->alloc.irq_emitted;
     privTarget->last_render = pI915XvMC->last_render;
commit 6e47601ac7427390fa4cb6e228dfb566ff95db09
Author: Xiang, Haihao <haihao.xiang at intel.com>
Date:   Mon Jun 25 10:40:08 2007 +0800

    fix some bugs

diff --git a/src/i915_hwmc.c b/src/i915_hwmc.c
index 52c903c..58d26c2 100644
--- a/src/i915_hwmc.c
+++ b/src/i915_hwmc.c
@@ -70,16 +70,8 @@ typedef struct _I915XvMCSurfacePriv
 
 typedef struct _I915XvMCContextPriv
 {
-    i830_memory *mcStaticIndirectState;
-    drm_handle_t sis_handle;
-    i830_memory *mcMapState;
-    drm_handle_t msb_handle;
-    i830_memory *mcSamplerState;
-    drm_handle_t ssb_handle;
-    i830_memory *mcPixelShaderProgram;
-    drm_handle_t psp_handle;
-    i830_memory *mcPixelShaderConstants;
-    drm_handle_t psc_handle;
+    i830_memory *mcSubContexts;
+    drm_handle_t subcontexts_handle;
     i830_memory *mcCorrdata;
     drm_handle_t corrdata_handle;
 } I915XvMCContextPriv;
@@ -272,47 +264,11 @@ static Bool i915_map_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *ctxpri
     I830Ptr pI830 = I830PTR(pScrn);
 
     if (drmAddMap(pI830->drmSubFD,
-                  (drm_handle_t)(ctxpriv->mcStaticIndirectState->offset + pI830->LinearAddr),
-                  ctxpriv->mcStaticIndirectState->size, DRM_AGP, 0,
-                  (drmAddress)&ctxpriv->sis_handle) < 0) {
+                  (drm_handle_t)(ctxpriv->mcSubContexts->offset + pI830->LinearAddr),
+                  ctxpriv->mcSubContexts->size, DRM_AGP, 0,
+                  (drmAddress)&ctxpriv->subcontexts_handle) < 0) {
         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-                   "[drm] drmAddMap(sis_handle) failed!\n");
-        return FALSE;
-    }
-
-    if (drmAddMap(pI830->drmSubFD,
-                  (drm_handle_t)(ctxpriv->mcMapState->offset + pI830->LinearAddr),
-                  ctxpriv->mcMapState->size, DRM_AGP, 0,
-                  (drmAddress)&ctxpriv->msb_handle) < 0) {
-        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-                   "[drm] drmAddMap(msb_handle) failed!\n");
-        return FALSE;
-    }
-
-    if (drmAddMap(pI830->drmSubFD, 
-                  (drm_handle_t)(ctxpriv->mcSamplerState->offset + pI830->LinearAddr),
-                  ctxpriv->mcSamplerState->size, DRM_AGP, 0,
-                  (drmAddress)&ctxpriv->ssb_handle) < 0) {
-        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-                   "[drm] drmAddress(ssb_handle) failed!\n");
-        return FALSE;
-    }
-
-    if (drmAddMap(pI830->drmSubFD, 
-                  (drm_handle_t)(ctxpriv->mcPixelShaderProgram->offset + pI830->LinearAddr),
-                  ctxpriv->mcPixelShaderProgram->size, DRM_AGP, 0,
-                  (drmAddress)&ctxpriv->psp_handle) < 0) {
-        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-                   "[drm] drmAddress(psp_handle) failed!\n");
-        return FALSE;
-    }
-
-    if (drmAddMap(pI830->drmSubFD, 
-                  (drm_handle_t)(ctxpriv->mcPixelShaderConstants->offset + pI830->LinearAddr),
-                  ctxpriv->mcPixelShaderConstants->size, DRM_AGP, 0,
-                  (drmAddress)&ctxpriv->psc_handle) < 0) {
-        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-                   "[drm] drmAddress(psc_handle) failed!\n");
+                   "[drm] drmAddMap(corrdata_handle) failed!\n");
         return FALSE;
     }
 
@@ -332,29 +288,9 @@ static void i915_unmap_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *ctxp
 {
     I830Ptr pI830 = I830PTR(pScrn);
     
-    if (ctxpriv->sis_handle) {
-        drmRmMap(pI830->drmSubFD, ctxpriv->sis_handle);
-        ctxpriv->sis_handle = 0;
-    }
-
-    if (ctxpriv->msb_handle) {
-        drmRmMap(pI830->drmSubFD, ctxpriv->msb_handle);
-        ctxpriv->msb_handle = 0;
-    }
-
-    if (ctxpriv->ssb_handle) {
-        drmRmMap(pI830->drmSubFD, ctxpriv->ssb_handle);
-        ctxpriv->ssb_handle = 0;
-    }
-
-    if (ctxpriv->psp_handle) {
-        drmRmMap(pI830->drmSubFD, ctxpriv->psp_handle);
-        ctxpriv->psp_handle = 0;
-    }
-
-    if (ctxpriv->psc_handle) {
-        drmRmMap(pI830->drmSubFD, ctxpriv->psc_handle);
-        ctxpriv->psc_handle = 0;
+    if (ctxpriv->subcontexts_handle) {
+        drmRmMap(pI830->drmSubFD, ctxpriv->subcontexts_handle);
+        ctxpriv->subcontexts_handle = 0;
     }
 
     if (ctxpriv->corrdata_handle) {
@@ -365,64 +301,25 @@ static void i915_unmap_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *ctxp
 
 static Bool i915_allocate_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *ctxpriv)
 {
-    if (!i830_allocate_xvmc_buffer(pScrn, "Static Indirect State", 
-                                   &(ctxpriv->mcStaticIndirectState), 512)) {
-        return FALSE;
-    }
-
-    if (!i830_allocate_xvmc_buffer(pScrn, "Map State", 
-                                   &(ctxpriv->mcMapState), 512)) {
-        return FALSE;
-    }
-
-    if (!i830_allocate_xvmc_buffer(pScrn, "Sampler State",
-                                   &(ctxpriv->mcSamplerState), 512)) {
-        return FALSE;
-    }
-
-    if (!i830_allocate_xvmc_buffer(pScrn, "Pixel Shader Program",
-                                   &(ctxpriv->mcPixelShaderProgram), 512)) {
-        return FALSE;
-    }
-
-    if (!i830_allocate_xvmc_buffer(pScrn, "Pixel Shader Constants",
-                                   &(ctxpriv->mcPixelShaderConstants), 128)) {
+    if (!i830_allocate_xvmc_buffer(pScrn, "buffers for context subsets",
+                                   &(ctxpriv->mcSubContexts), 8 * 1024)) {
         return FALSE;
     }
 
     if (!i830_allocate_xvmc_buffer(pScrn, "Correction Data Buffer", 
-                                   &(ctxpriv->mcCorrdata), 2 * 1024 * 1024)) {
+                                   &(ctxpriv->mcCorrdata), 1 * 1024 * 1024)) {
         return FALSE;
     }
 
+    i830_describe_allocations(pScrn, 1, "");
     return TRUE;
 }
 
 static void i915_free_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *ctxpriv)
 {
-    if (ctxpriv->mcStaticIndirectState) {
-        i830_free_memory(pScrn, ctxpriv->mcStaticIndirectState);
-        ctxpriv->mcStaticIndirectState = NULL;
-    }
-
-    if (ctxpriv->mcMapState) {
-        i830_free_memory(pScrn, ctxpriv->mcMapState);
-        ctxpriv->mcMapState = NULL;
-    }
-
-    if (ctxpriv->mcSamplerState) {
-        i830_free_memory(pScrn, ctxpriv->mcSamplerState);
-        ctxpriv->mcSamplerState = NULL;
-    }
-
-    if (ctxpriv->mcPixelShaderProgram) {
-        i830_free_memory(pScrn, ctxpriv->mcPixelShaderProgram);
-        ctxpriv->mcPixelShaderProgram = NULL;
-    }
-
-    if (ctxpriv->mcPixelShaderConstants) {
-        i830_free_memory(pScrn, ctxpriv->mcPixelShaderConstants);
-        ctxpriv->mcPixelShaderConstants = NULL;
+    if (ctxpriv->mcSubContexts) {
+        i830_free_memory(pScrn, ctxpriv->mcSubContexts);
+        ctxpriv->mcSubContexts = NULL;
     }
 
     if (ctxpriv->mcCorrdata) {
@@ -522,21 +419,9 @@ static int I915XvMCCreateContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext,
     }
 
     contextRec->ctxno = i;
-    contextRec->sis.handle = ctxpriv->sis_handle;
-    contextRec->sis.offset = ctxpriv->mcStaticIndirectState->offset;
-    contextRec->sis.size = ctxpriv->mcStaticIndirectState->size;
-    contextRec->msb.handle = ctxpriv->msb_handle;
-    contextRec->msb.offset = ctxpriv->mcMapState->offset;
-    contextRec->msb.size = ctxpriv->mcMapState->size;
-    contextRec->ssb.handle = ctxpriv->ssb_handle;
-    contextRec->ssb.offset = ctxpriv->mcSamplerState->offset;
-    contextRec->ssb.size = ctxpriv->mcSamplerState->size;
-    contextRec->psp.handle = ctxpriv->psp_handle;
-    contextRec->psp.offset = ctxpriv->mcPixelShaderProgram->offset;
-    contextRec->psp.size = ctxpriv->mcPixelShaderProgram->size;
-    contextRec->psc.handle = ctxpriv->psc_handle;
-    contextRec->psc.offset = ctxpriv->mcPixelShaderConstants->offset;
-    contextRec->psc.size = ctxpriv->mcPixelShaderConstants->size;
+    contextRec->subcontexts.handle = ctxpriv->subcontexts_handle;
+    contextRec->subcontexts.offset = ctxpriv->mcSubContexts->offset;
+    contextRec->subcontexts.size = ctxpriv->mcSubContexts->size;
     contextRec->corrdata.handle = ctxpriv->corrdata_handle;
     contextRec->corrdata.offset = ctxpriv->mcCorrdata->offset;
     contextRec->corrdata.size = ctxpriv->mcCorrdata->size;
@@ -606,7 +491,7 @@ static int I915XvMCCreateSurface(ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf,
         *num_priv = 0;
         return BadAlloc;
     }
-
+    i830_describe_allocations(pScrn, 1, "");
     if (drmAddMap(pI830->drmSubFD,
                   (drm_handle_t)(sfpriv->surface->offset + pI830->LinearAddr),
                   sfpriv->surface->size, DRM_AGP, 0,
@@ -621,11 +506,6 @@ static int I915XvMCCreateSurface(ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf,
         return BadAlloc;
     }
 
-    memset(pI830->FbBase + sfpriv->surface->offset, 0x5a, size_y420(ctx->width, ctx->height));
-    memset(pI830->FbBase + sfpriv->surface->offset + size_y420(ctx->width, ctx->height),
-           0x5c, size_uv420(ctx->width, ctx->height));
-    memset(pI830->FbBase + sfpriv->surface->offset + size_y420(ctx->width, ctx->height) + size_uv420(ctx->width, ctx->height),
-           0x5f, size_uv420(ctx->width, ctx->height));
     for (srfno = 0; srfno < I915_XVMC_MAX_SURFACES; ++srfno) {
         if (!pXvMC->surfaces[srfno])
             break;
diff --git a/src/i915_hwmc.h b/src/i915_hwmc.h
index b87ba31..42d2b29 100644
--- a/src/i915_hwmc.h
+++ b/src/i915_hwmc.h
@@ -48,11 +48,7 @@ typedef struct
 {
     unsigned ctxno; /* XvMC private context reference number */
     drm_context_t drmcontext;
-    struct hwmc_buffer sis;     /* Static Indirect State Buffer */
-    struct hwmc_buffer msb;     /* Map State Block */
-    struct hwmc_buffer ssb;     /* Sampler State Block */
-    struct hwmc_buffer psp;     /* Pixel Shader Program Buffer */
-    struct hwmc_buffer psc;     /* Pixel Shader Constants Buffer */
+    struct hwmc_buffer subcontexts;
     struct hwmc_buffer corrdata;/* Correction Data Buffer */
     unsigned sarea_size;
     unsigned sarea_priv_offset;
diff --git a/src/xvmc/I915XvMC.c b/src/xvmc/I915XvMC.c
index 2f75d57..e73f1a8 100644
--- a/src/xvmc/I915XvMC.c
+++ b/src/xvmc/I915XvMC.c
@@ -265,7 +265,7 @@ _STATIC_ void i915_mc_static_indirect_state_buffer(XvMCContext *context,
     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 = pI915Surface->srf.offset;
+    buffer_info->dw2.base_address = (pI915Surface->srf.offset >> 2);    /* starting DWORD address */
 
     /* DEST U */
     ++buffer_info;
@@ -279,8 +279,8 @@ _STATIC_ void i915_mc_static_indirect_state_buffer(XvMCContext *context,
     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 = pI915Surface->srf.offset +
-        size_y(w, h) + size_uv(w, h);
+    buffer_info->dw2.base_address = ((pI915Surface->srf.offset +
+                                      size_y(w, h) + size_uv(w, h)) >> 2);      /* starting DWORD address */
 
     /* DEST V */
     ++buffer_info;
@@ -294,8 +294,8 @@ _STATIC_ void i915_mc_static_indirect_state_buffer(XvMCContext *context,
     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 = pI915Surface->srf.offset +
-        size_y(w, h);
+    buffer_info->dw2.base_address = ((pI915Surface->srf.offset +
+                                      size_y(w, h)) >> 2);      /* starting DWORD address */
 
     /* 3DSTATE_DEST_BUFFER_VARIABLES */
     dest_buffer_variables = (struct i915_3dstate_dest_buffer_variables *)(++buffer_info);
@@ -306,7 +306,15 @@ _STATIC_ void i915_mc_static_indirect_state_buffer(XvMCContext *context,
     dest_buffer_variables->dw1.dest_v_bias = 8; /* 0.5 */
     dest_buffer_variables->dw1.dest_h_bias = 8; /* 0.5 */
     dest_buffer_variables->dw1.v_ls = 0;    
-    dest_buffer_variables->dw1.v_ls_offset = 1;
+    dest_buffer_variables->dw1.v_ls_offset = 0;
+
+    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_offset = 1;
+    } else if ((picture_structure & XVMC_FRAME_PICTURE) == XVMC_BOTTOM_FIELD) {
+        dest_buffer_variables->dw1.v_ls = 1;
+    }
 
     /* 3DSTATE_DEST_BUFFER_VARIABLES_MPEG */
     dest_buffer_variables_mpeg = (struct i915_3dstate_dest_buffer_variables_mpeg *)(++dest_buffer_variables);
@@ -351,7 +359,7 @@ _STATIC_ void i915_mc_static_indirect_state_buffer(XvMCContext *context,
     buffer_info->dw1.tiled_surface = 0; 
     buffer_info->dw1.walk = 0;
     buffer_info->dw1.pitch = 0;
-    buffer_info->dw2.base_address = pI915XvMC->corrdata.offset;
+    buffer_info->dw2.base_address = (pI915XvMC->corrdata.offset >> 2);  /* starting DWORD address */
 }
 
 _STATIC_ void i915_mc_map_state_buffer(XvMCContext *context, 
@@ -378,7 +386,7 @@ _STATIC_ void i915_mc_map_state_buffer(XvMCContext *context,
     memset(tm, 0, sizeof(*tm));
     tm->tm0.v_ls_offset = 0;
     tm->tm0.v_ls = 0;
-    tm->tm0.base_address = privPast->srf.offset;
+    tm->tm0.base_address = (privPast->srf.offset >> 2);
     tm->tm1.tile_walk = TILEWALK_XMAJOR;
     tm->tm1.tiled_surface = 0;
     tm->tm1.utilize_fence_regs = 0;
@@ -396,7 +404,7 @@ _STATIC_ void i915_mc_map_state_buffer(XvMCContext *context,
     memset(tm, 0, sizeof(*tm));
     tm->tm0.v_ls_offset = 0;
     tm->tm0.v_ls = 0;
-    tm->tm0.base_address = privFuture->srf.offset;
+    tm->tm0.base_address = (privFuture->srf.offset >> 2);
     tm->tm1.tile_walk = TILEWALK_XMAJOR;
     tm->tm1.tiled_surface = 0;
     tm->tm1.utilize_fence_regs = 0;
@@ -423,8 +431,8 @@ _STATIC_ void i915_mc_map_state_buffer(XvMCContext *context,
     memset(tm, 0, sizeof(*tm));
     tm->tm0.v_ls_offset = 0;
     tm->tm0.v_ls = 0;
-    tm->tm0.base_address = privPast->srf.offset +
-        size_y(w, h) + size_uv(w, h);
+    tm->tm0.base_address = ((privPast->srf.offset +
+                             size_y(w, h) + size_uv(w, h)) >> 2);
     tm->tm1.tile_walk = TILEWALK_XMAJOR;
     tm->tm1.tiled_surface = 0;
     tm->tm1.utilize_fence_regs = 0;
@@ -442,8 +450,8 @@ _STATIC_ void i915_mc_map_state_buffer(XvMCContext *context,
     memset(tm, 0, sizeof(*tm));
     tm->tm0.v_ls_offset = 0;
     tm->tm0.v_ls = 0;
-    tm->tm0.base_address = privFuture->srf.offset +
-        size_y(w, h) + size_uv(w, h);
+    tm->tm0.base_address = ((privFuture->srf.offset +
+                             size_y(w, h) + size_uv(w, h)) >> 2);
     tm->tm1.tile_walk = TILEWALK_XMAJOR;
     tm->tm1.tiled_surface = 0;
     tm->tm1.utilize_fence_regs = 0;
@@ -470,8 +478,8 @@ _STATIC_ void i915_mc_map_state_buffer(XvMCContext *context,
     memset(tm, 0, sizeof(*tm));
     tm->tm0.v_ls_offset = 0;
     tm->tm0.v_ls = 0;
-    tm->tm0.base_address = privPast->srf.offset +
-        size_y(w, h);
+    tm->tm0.base_address = ((privPast->srf.offset +
+                            size_y(w, h)) >> 2);
     tm->tm1.tile_walk = TILEWALK_XMAJOR;
     tm->tm1.tiled_surface = 0;
     tm->tm1.utilize_fence_regs = 0;
@@ -489,8 +497,8 @@ _STATIC_ void i915_mc_map_state_buffer(XvMCContext *context,
     memset(tm, 0, sizeof(*tm));
     tm->tm0.v_ls_offset = 0;
     tm->tm0.v_ls = 0;
-    tm->tm0.base_address = privFuture->srf.offset +
-        size_y(w, h);
+    tm->tm0.base_address = ((privFuture->srf.offset +
+                             size_y(w, h)) >> 2);
     tm->tm1.tile_walk = TILEWALK_XMAJOR;
     tm->tm1.tiled_surface = 0;
     tm->tm1.utilize_fence_regs = 0;
@@ -528,13 +536,13 @@ _STATIC_ void i915_mc_load_indirect_buffer(XvMCContext *context)
     /* SIS */
     sis = (sis_state *)(++load_indirect);
     sis->dw0.valid = 1;
-    sis->dw0.buffer_address = pI915XvMC->sis.offset;
+    sis->dw0.buffer_address = (pI915XvMC->sis.offset >> 2);
     sis->dw1.length = 16; // 4 * 3 + 2 + 3 - 1
 
     /* MSB */
     msb = (msb_state *)(++sis);
     msb->dw0.valid = 1;
-    msb->dw0.buffer_address = pI915XvMC->msb.offset;
+    msb->dw0.buffer_address = (pI915XvMC->msb.offset >> 2);
     msb->dw1.length = 23; // 3 * 8 - 1
 
     intelBatchbufferData(pI915XvMC, base, size, 0);
@@ -576,7 +584,7 @@ _STATIC_ void i915_mc_mpeg_macroblock_0mv(XvMCContext *context, XvMCMacroBlock *
     if (!mb->coded_block_pattern)
         macroblock_0mv.header.dw1.dct_type = XVMC_DCT_TYPE_FRAME;
 
-    macroblock_0mv.header.dw1.motion_type = 0; // (mb->motion_type & 0x3)
+    macroblock_0mv.header.dw1.motion_type = 0; // (mb->motion_type & 0x3);
     macroblock_0mv.header.dw1.vertical_field_select = 0; // mb->motion_vertical_field_select & 0xf;
     macroblock_0mv.header.dw1.coded_block_pattern = mb->coded_block_pattern;
     macroblock_0mv.header.dw1.skipped_macroblocks = 0;
@@ -1021,59 +1029,99 @@ _STATIC_ void i915_mc_one_time_state_initialization(XvMCContext *context)
     /* SSB */
     ssb = (ssb_state *)(++dis);
     ssb->dw0.valid = 1;
-    ssb->dw0.buffer_address = pI915XvMC->ssb.offset;
+    ssb->dw0.buffer_address = (pI915XvMC->ssb.offset >> 2);
     ssb->dw1.length = 7; /* 8 - 1 */
 
     /* PSP */
     psp = (psp_state *)(++ssb);
     psp->dw0.valid = 1;
-    psp->dw0.buffer_address = pI915XvMC->psp.offset;
+    psp->dw0.buffer_address = (pI915XvMC->psp.offset >> 2);
     psp->dw1.length = 66; /* 4 + 16 + 16 + 31 - 1 */
     
     /* PSC */
     psc = (psc_state *)(++psp);
     psc->dw0.valid = 1;
-    psc->dw0.buffer_address = pI915XvMC->psc.offset;
+    psc->dw0.buffer_address = (pI915XvMC->psc.offset >> 2);
     psc->dw1.length = 5; /* 6 - 1 */
 
     intelBatchbufferData(pI915XvMC, base, size, 0);
     free(base);
 }
 
-_STATIC_ int i915_xvmc_map_buffers(i915XvMCContext *pI915XvMC)
+_STATIC_ void i915_mc_finish_render(XvMCContext *context)
 {
-    if (drmMap(pI915XvMC->fd,
-               pI915XvMC->sis.handle,
-               pI915XvMC->sis.size,
-               (drmAddress *)&pI915XvMC->sis.map) != 0) {
-        return -1;
-    }
+    struct i915_3dstate_load_indirect *load_indirect = NULL;
+    sis_state *sis = NULL;
+    dis_state *dis = NULL;
+    ssb_state *ssb = NULL;
+    msb_state *msb = NULL;
+    psp_state *psp = NULL;
+    psc_state *psc = NULL;
+    i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
+    unsigned size;
+    void *base = NULL;
 
-    if (drmMap(pI915XvMC->fd,
-               pI915XvMC->msb.handle,
-               pI915XvMC->msb.size,
-               (drmAddress *)&pI915XvMC->msb.map) != 0) {
-        return -1;
-    }
+    /* flush */
+    i915_flush_with_flush_bit_clear(pI915XvMC);
 
-    if (drmMap(pI915XvMC->fd,
-               pI915XvMC->ssb.handle,
-               pI915XvMC->ssb.size,
-               (drmAddress *)&pI915XvMC->ssb.map) != 0) {
-        return -1;
-    }
+    /* 3DSTATE_LOAD_INDIRECT */
+    size = sizeof(*load_indirect) + sizeof(*sis) + sizeof(*dis) + 
+        sizeof(*ssb) + sizeof(*msb) + 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.mem_select = 1;      /* Bearlake only */
+    load_indirect->dw0.block_mask = BLOCK_SIS | BLOCK_DIS | 
+        BLOCK_SSB | BLOCK_MSB | BLOCK_PSP | BLOCK_PSC;
+    load_indirect->dw0.length = (size >> 2) - 2;
 
-    if (drmMap(pI915XvMC->fd,
-               pI915XvMC->psp.handle,
-               pI915XvMC->psp.size,
-               (drmAddress *)&pI915XvMC->psp.map) != 0) {
-        return -1;
-    }
+    /* SIS */
+    sis = (sis_state *)(++load_indirect);
+    sis->dw0.valid = 0;
+    sis->dw0.buffer_address = 0;
+    sis->dw1.length = 0;
 
+    /* DIS */
+    dis = (dis_state *)(++sis);
+    dis->dw0.valid = 0;
+    dis->dw0.reset = 0;
+    dis->dw0.buffer_address = 0;
+
+    /* SSB */
+    ssb = (ssb_state *)(++dis);
+    ssb->dw0.valid = 0;
+    ssb->dw0.buffer_address = 0;
+    ssb->dw1.length = 0;
+
+    /* MSB */
+    msb = (msb_state *)(++ssb);
+    msb->dw0.valid = 0;
+    msb->dw0.buffer_address = 0;
+    msb->dw1.length = 0;
+
+    /* PSP */
+    psp = (psp_state *)(++msb);
+    psp->dw0.valid = 0;
+    psp->dw0.buffer_address = 0;
+    psp->dw1.length = 0;
+    
+    /* PSC */
+    psc = (psc_state *)(++psp);
+    psc->dw0.valid = 0;
+    psc->dw0.buffer_address = 0;
+    psc->dw1.length = 0;
+
+    intelBatchbufferData(pI915XvMC, base, size, 0);
+    free(base);
+}
+
+_STATIC_ int i915_xvmc_map_buffers(i915XvMCContext *pI915XvMC)
+{
     if (drmMap(pI915XvMC->fd,
-               pI915XvMC->psc.handle,
-               pI915XvMC->psc.size,
-               (drmAddress *)&pI915XvMC->psc.map) != 0) {
+               pI915XvMC->subcontexts.handle,
+               pI915XvMC->subcontexts.size,
+               (drmAddress *)&pI915XvMC->subcontexts.map) != 0) {
         return -1;
     }
 
@@ -1083,41 +1131,33 @@ _STATIC_ int i915_xvmc_map_buffers(i915XvMCContext *pI915XvMC)
                (drmAddress *)&pI915XvMC->corrdata.map) != 0) {
         return -1;
     }
+    
+    pI915XvMC->sis.map = pI915XvMC->subcontexts.map;
+    pI915XvMC->msb.map = pI915XvMC->subcontexts.map + 1 * 1024;
+    pI915XvMC->ssb.map = pI915XvMC->subcontexts.map + 2 * 1024;
+    pI915XvMC->psp.map = pI915XvMC->subcontexts.map + 3 * 1024;
+    pI915XvMC->psc.map = pI915XvMC->subcontexts.map + 4 * 1024;
 
     return 0;
 }
 
 _STATIC_ void i915_xvmc_unmap_buffers(i915XvMCContext *pI915XvMC)
 {
-    if (pI915XvMC->sis.map) {
-        drmUnmap(pI915XvMC->sis.map, pI915XvMC->sis.size);
-        pI915XvMC->sis.map = NULL;
-    }
-
-    if (pI915XvMC->msb.map) {
-        drmUnmap(pI915XvMC->msb.map, pI915XvMC->msb.size);
-        pI915XvMC->msb.map = NULL;
-    }
-
-    if (pI915XvMC->ssb.map) {
-        drmUnmap(pI915XvMC->ssb.map, pI915XvMC->ssb.size);
-        pI915XvMC->ssb.map = NULL;
-    }
-
-    if (pI915XvMC->psp.map) {
-        drmUnmap(pI915XvMC->psp.map, pI915XvMC->psp.size);
-        pI915XvMC->psp.map = NULL;
-    }
-
-    if (pI915XvMC->psc.map) {
-        drmUnmap(pI915XvMC->psc.map, pI915XvMC->psc.size);
-        pI915XvMC->psc.map = NULL;
+    if (pI915XvMC->subcontexts.map) {
+        drmUnmap(pI915XvMC->subcontexts.map, pI915XvMC->subcontexts.size);
+        pI915XvMC->subcontexts.map = NULL;
     }
 
     if (pI915XvMC->corrdata.map) {
         drmUnmap(pI915XvMC->corrdata.map, pI915XvMC->corrdata.size);
         pI915XvMC->corrdata.map = NULL;
     }
+
+    pI915XvMC->sis.map = NULL;
+    pI915XvMC->msb.map = NULL;
+    pI915XvMC->ssb.map = NULL;
+    pI915XvMC->psp.map = NULL;
+    pI915XvMC->psc.map = NULL;
 }
 
 /*
@@ -1702,21 +1742,19 @@ Status XvMCCreateContext(Display *display, XvPortID port,
 
     tmpComm = (I915XvMCCreateContextRec *)priv_data;
     pI915XvMC->ctxno = tmpComm->ctxno;
-    pI915XvMC->sis.handle = tmpComm->sis.handle;
-    pI915XvMC->sis.offset = tmpComm->sis.offset;
-    pI915XvMC->sis.size = tmpComm->sis.size;
-    pI915XvMC->msb.handle = tmpComm->msb.handle;
-    pI915XvMC->msb.offset = tmpComm->msb.offset;
-    pI915XvMC->msb.size = tmpComm->msb.size;
-    pI915XvMC->ssb.handle = tmpComm->ssb.handle;
-    pI915XvMC->ssb.offset = tmpComm->ssb.offset;
-    pI915XvMC->ssb.size = tmpComm->ssb.size;
-    pI915XvMC->psp.handle = tmpComm->psp.handle;
-    pI915XvMC->psp.offset = tmpComm->psp.offset;
-    pI915XvMC->psp.size = tmpComm->psp.size;
-    pI915XvMC->psc.handle = tmpComm->psc.handle;
-    pI915XvMC->psc.offset = tmpComm->psc.offset;
-    pI915XvMC->psc.size = tmpComm->psc.size;
+    pI915XvMC->subcontexts.handle = tmpComm->subcontexts.handle;
+    pI915XvMC->subcontexts.offset = tmpComm->subcontexts.offset;
+    pI915XvMC->sis.offset = pI915XvMC->subcontexts.offset;
+    pI915XvMC->sis.size = 1024;
+    pI915XvMC->msb.offset = pI915XvMC->subcontexts.offset + 1 * 1024;
+    pI915XvMC->msb.size = 1024;
+    pI915XvMC->ssb.offset = pI915XvMC->subcontexts.offset + 2 * 1024;
+    pI915XvMC->ssb.size = 1024;
+    pI915XvMC->psp.offset = pI915XvMC->subcontexts.offset + 3 * 1024;
+    pI915XvMC->psp.size = 1024;
+    pI915XvMC->psc.offset = pI915XvMC->subcontexts.offset + 4 * 1024;
+    pI915XvMC->psc.size = 1024;
+    pI915XvMC->subcontexts.size = tmpComm->subcontexts.size;
     pI915XvMC->corrdata.handle = tmpComm->corrdata.handle;
     pI915XvMC->corrdata.offset = tmpComm->corrdata.offset;
     pI915XvMC->corrdata.size = tmpComm->corrdata.size;
@@ -2164,7 +2202,7 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context,
 
     /* B Frame Test */
     if (!future_surface) {
-        privFuture = privTarget;
+        privFuture = privPast; // privTarget;
     } else {
         if (!past_surface) {
             printf("Error, No Past Surface!\n");
@@ -2192,16 +2230,22 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context,
         block_ptr = &(blocks->blocks[mb->index << 6]);
 
         /* Lockup can happen if the coordinates are too far out of range */
-        if (mb->x > (target_surface->width >> 4))
+        if (mb->x > (target_surface->width >> 4)) {
             mb->x = 0;
+            printf("reset x\n");
+        }
 
-        if (mb->y > (target_surface->height >> 4))
+        if (mb->y > (target_surface->height >> 4)) {
             mb->y = 0;
+            printf("reset y\n");
+        }
 
         /* Catch no pattern case */
         if (!(mb->macroblock_type & XVMC_MB_TYPE_PATTERN) &&
-            !(mb->macroblock_type & XVMC_MB_TYPE_INTRA)) 
+            !(mb->macroblock_type & XVMC_MB_TYPE_INTRA)) {
             mb->coded_block_pattern = 0;
+            printf("no coded blocks present\n");
+        }
         
         bspm = mb_bytes[mb->coded_block_pattern];
         corrdata_size += bspm;
@@ -2228,11 +2272,12 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context,
                                          picture_coding_type);
     i915_mc_map_state_buffer(context, privTarget, privPast, privFuture);
     i915_mc_load_indirect_buffer(context);
-    i915_mc_mpeg_set_origin(context, 
-                            &macroblock_array->macro_blocks[first_macroblock]);
     intelFlushBatch(pI915XvMC, TRUE);
+    // i915_mc_mpeg_set_origin(context, &macroblock_array->macro_blocks[first_macroblock]);
     for (i = first_macroblock; i < (num_macroblocks + first_macroblock); i++) {
         mb = &macroblock_array->macro_blocks[i];
+        i915_mc_mpeg_set_origin(context, mb);
+        // &macroblock_array->macro_blocks[first_macroblock]);
 
         /* Intra Blocks */
         if (mb->macroblock_type & XVMC_MB_TYPE_INTRA) {
@@ -2282,46 +2327,12 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context,
         intelFlushBatch(pI915XvMC, TRUE);        
     }
 
+    i915_mc_finish_render(context);
     intelFlushBatch(pI915XvMC, TRUE);
     pI915XvMC->last_render = pI915XvMC->alloc.irq_emitted;
     privTarget->last_render = pI915XvMC->last_render;
 
     UNLOCK_HARDWARE(pI915XvMC);
-
-    {
-        int i;
-        corrdata_ptr = pI915XvMC->corrdata.map;
-
-        printf("correct data:\n");
-        for (i = 0; i < 32; i++) {
-            printf("%02x ", *corrdata_ptr++);
-        }
-        printf("\n");
-
-        printf("y data:\n");
-        corrdata_ptr = privTarget->srf.map;
-        for (i = 0; i < 32; i++) {
-            printf("%02x ", *corrdata_ptr++);
-        }
-        printf("\n");
-
-        printf("v data:\n");
-        corrdata_ptr = privTarget->srf.map + size_y(context->width, context->height);
-        for (i = 0; i < 32; i++) {
-            printf("%02x ", *corrdata_ptr++);
-        }
-        printf("\n");
-
-        printf("u data:\n");
-        corrdata_ptr = privTarget->srf.map + size_y(context->width, context->height) + 
-           size_uv(context->width, context->height);
-        for (i = 0; i < 32; i++) {
-            printf("%02x ", *corrdata_ptr++);
-        }
-        printf("\n");
-
-        fflush(NULL);
-    }
     return Success;
 }
 
diff --git a/src/xvmc/I915XvMC.h b/src/xvmc/I915XvMC.h
index 1260084..e3a83d9 100644
--- a/src/xvmc/I915XvMC.h
+++ b/src/xvmc/I915XvMC.h
@@ -96,6 +96,7 @@ typedef struct _i915XvMCContext {
     i915XvMCDrmMap ssb;
     i915XvMCDrmMap psp;
     i915XvMCDrmMap psc;
+    i915XvMCDrmMap subcontexts;
     i915XvMCDrmMap corrdata;
 
     struct {
commit d038ffdfffb846e22f360faac5d469c8e59795ad
Author: Xiang, Haihao <haihao.xiang at intel.com>
Date:   Mon Jun 25 10:37:12 2007 +0800

    Release resource allocated for surface/subpicture

diff --git a/src/i915_hwmc.c b/src/i915_hwmc.c
index f9c36ac..52c903c 100644
--- a/src/i915_hwmc.c
+++ b/src/i915_hwmc.c
@@ -757,6 +757,7 @@ static void I915XvMCDestroySurface (ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf)
 
     for (i = 0; i < I915_XVMC_MAX_SURFACES; i++) {
         if (pXvMC->surfaces[i] == pSurf->surface_id) {
+            drmRmMap(pI830->drmSubFD, pXvMC->sfprivs[i]->surface_handle);
             i830_free_memory(pScrn, pXvMC->sfprivs[i]->surface);            
             xfree(pXvMC->sfprivs[i]);
             pXvMC->nsurfaces--;
@@ -777,6 +778,7 @@ static void I915XvMCDestroySubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSub
 
     for (i = 0; i < I915_XVMC_MAX_SURFACES; i++) {
         if (pXvMC->surfaces[i] == pSubp->subpicture_id) {
+            drmRmMap(pI830->drmSubFD, pXvMC->sfprivs[i]->surface_handle);
             i830_free_memory(pScrn, pXvMC->sfprivs[i]->surface);            
             xfree(pXvMC->sfprivs[i]);
             pXvMC->nsurfaces--;
diff --git a/src/xvmc/I915XvMC.c b/src/xvmc/I915XvMC.c
index 937eee9..2f75d57 100644
--- a/src/xvmc/I915XvMC.c
+++ b/src/xvmc/I915XvMC.c
@@ -1912,7 +1912,7 @@ Status XvMCCreateSurface(Display *display, XvMCContext *context, XvMCSurface *su
     pI915Surface->height = context->height;
     pI915Surface->privContext = pI915XvMC;
     pI915Surface->privSubPic = NULL;
-
+    pI915Surface->srf.map = NULL;
     XLockDisplay(display);
 
     if ((ret = _xvmc_create_surface(display, context, surface,
@@ -1984,8 +1984,11 @@ Status XvMCDestroySurface(Display *display, XvMCSurface *surface)
     if (pI915Surface->last_flip)
         XvMCSyncSurface(display,surface);
 
+    if (pI915Surface->srf.map)
+        drmUnmap(pI915Surface->srf.map, pI915Surface->srf.size);
+
     XLockDisplay(display);
-    _xvmc_destroy_surface(display,surface);
+    _xvmc_destroy_surface(display, surface);
     XUnlockDisplay(display);
 
     free(pI915Surface);
@@ -2626,6 +2629,7 @@ Status XvMCCreateSubpicture(Display *display, XvMCContext *context,
                                        &priv_count, &priv_data))) {
         printf("Unable to create XvMCSubpicture.\n");
         free(pI915Subpicture);
+        subpicture->privData = NULL;
         return ret;
     }
 
@@ -2674,6 +2678,8 @@ Status XvMCCreateSubpicture(Display *display, XvMCContext *context,
         break;
 
     default:
+        drmUnmap(pI915Subpicture->srf.map, pI915Subpicture->srf.size);
+        _xvmc_destroy_subpicture(display, subpicture);
         free(pI915Subpicture);
         subpicture->privData = NULL;
         return BadMatch;
@@ -2802,6 +2808,9 @@ Status XvMCDestroySubpicture(Display *display, XvMCSubpicture *subpicture)
     if (pI915Subpicture->last_render)
         XvMCSyncSubpicture(display, subpicture);
 
+    if (pI915Subpicture->srf.map)
+        drmUnmap(pI915Subpicture->srf.map, pI915Subpicture->srf.size);
+
     XLockDisplay(display);
     _xvmc_destroy_subpicture(display,subpicture);
     XUnlockDisplay(display);
commit a9bf7e28b91692c7c7a4915cdf9603cd2ef025ea
Author: Xiang, Haihao <haihao.xiang at intel.com>
Date:   Mon Jun 25 10:33:35 2007 +0800

    fix some bugs

diff --git a/src/i830_video.c b/src/i830_video.c
index 9d9511e..94fe309 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -259,13 +259,37 @@ static XF86AttributeRec GammaAttributes[GAMMA_ATTRIBUTES] = {
     {XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA5"}
 };
 
-#define NUM_IMAGES 4
+#define NUM_IMAGES 5
 
 static XF86ImageRec Images[NUM_IMAGES] = {
     XVIMAGE_YUY2,
     XVIMAGE_YV12,
     XVIMAGE_I420,
-    XVIMAGE_UYVY
+    XVIMAGE_UYVY,
+    {
+        /*
+         * Below, a dummy picture type that is used in XvPutImage only to do
+         * an overlay update. Introduced for the XvMC client lib.
+         * Defined to have a zero data size.
+         */
+        FOURCC_XVMC,
+        XvYUV,
+        LSBFirst,
+        {'V', 'I', 'A', 0x00,
+         0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0xAA, 0x00,
+         0x38, 0x9B, 0x71},
+        12,
+        XvPlanar,
+        3,
+        0, 0, 0, 0,
+        8, 8, 8,
+        1, 2, 2,
+        1, 2, 2,
+        {'Y', 'V', 'U',
+         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+         0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+        XvTopToBottom
+    },
 };
 
 typedef struct {
diff --git a/src/i915_hwmc.c b/src/i915_hwmc.c
index ed4fe6c..f9c36ac 100644
--- a/src/i915_hwmc.c
+++ b/src/i915_hwmc.c
@@ -65,6 +65,7 @@ typedef struct _I915XvMCSurfacePriv
 {
     i830_memory *surface;
     unsigned long offsets[I915_XVMC_MAX_BUFFERS];
+    drm_handle_t surface_handle;
 } I915XvMCSurfacePriv;
 
 typedef struct _I915XvMCContextPriv
@@ -192,14 +193,30 @@ static XF86MCAdaptorPtr ppAdapt[1] =
 
 static unsigned int stride(int w)
 {
-    return (w + 31) & ~31;
+    return (w + 3) & ~3;
+}
+
+static unsigned long size_y420(int w, int h)
+{
+   unsigned cpp = 1;
+   unsigned yPitch = stride(w) * cpp;
+   
+   return h * yPitch;
+}
+
+static unsigned long size_uv420(int w, int h)
+{
+   unsigned cpp = 1;
+   unsigned uvPitch = stride(w >> 1) * cpp;
+
+   return h / 2 * uvPitch;
 }
 
 static unsigned long size_yuv420(int w, int h)
 {
-    unsigned cpp = 4;
+    unsigned cpp = 1;
     unsigned yPitch = stride(w) * cpp;
-    unsigned uvPitch = stride(w / 2) * cpp;
+    unsigned uvPitch = stride(w >> 1) * cpp;
 
     return h * (yPitch + uvPitch);
 }
@@ -542,8 +559,9 @@ static int I915XvMCCreateSurface(ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf,
     I830Ptr pI830 = I830PTR(pScrn);
     I915XvMCPtr pXvMC = pI830->xvmc;
     I915XvMCSurfacePriv *sfpriv = NULL;
+    I915XvMCCreateSurfaceRec *surfaceRec = NULL;
     XvMCContextPtr ctx = NULL;
-    unsigned int sfno, i, nbuffers;
+    unsigned int srfno;
     unsigned long bufsize;
 
     *priv = NULL;
@@ -555,22 +573,23 @@ static int I915XvMCCreateSurface(ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf,
         return BadAlloc;
     }
 
-    sfpriv = (I915XvMCSurfacePriv *)xcalloc(1, sizeof(I915XvMCSurfacePriv));
+    *priv = xcalloc(1, sizeof(I915XvMCCreateSurfaceRec));
+    surfaceRec = (I915XvMCCreateSurfaceRec *)*priv;     
 
-    if (!sfpriv) {
+    if (!*priv) {
         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
                    "[XvMC] I915XvMCCreateSurface: Unable to allocate memory!\n");
         return BadAlloc;
     }
 
-    nbuffers = 1;
-    *num_priv = nbuffers + 2;
-    *priv = (long *)xcalloc(*num_priv, sizeof(unsigned long));
-    
-    if (!*priv) {
+    *num_priv = sizeof(I915XvMCCreateSurfaceRec) >> 2;
+    sfpriv = (I915XvMCSurfacePriv *)xcalloc(1, sizeof(I915XvMCSurfacePriv));
+
+    if (!sfpriv) {
         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
                    "[XvMC] I915XvMCCreateSurface: Unable to allocate memory!\n");
-        xfree(sfpriv);
+        xfree(*priv);
+        *priv = NULL;
         *num_priv = 0;
         return BadAlloc;
     }
@@ -578,7 +597,7 @@ static int I915XvMCCreateSurface(ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf,
     ctx = pSurf->context;
     bufsize = size_yuv420(ctx->width, ctx->height);
 
-    if (!i830_allocate_xvmc_surface(pScrn, &(sfpriv->surface), nbuffers * bufsize)) {
+    if (!i830_allocate_xvmc_surface(pScrn, &(sfpriv->surface), bufsize)) {
         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
                    "[XvMC] I915XvMCCreateSurface: Failed to allocate XvMC surface space!\n");
         xfree(sfpriv);
@@ -588,21 +607,37 @@ static int I915XvMCCreateSurface(ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf,
         return BadAlloc;
     }
 
-    for (sfno = 0; sfno < I915_XVMC_MAX_SURFACES; ++sfno) {
-        if (!pXvMC->surfaces[sfno])
-            break;
+    if (drmAddMap(pI830->drmSubFD,
+                  (drm_handle_t)(sfpriv->surface->offset + pI830->LinearAddr),
+                  sfpriv->surface->size, DRM_AGP, 0,
+                  (drmAddress)&sfpriv->surface_handle) < 0) {
+        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                   "[drm] drmAddMap(surface_handle) failed!\n");
+        i830_free_memory(pScrn, sfpriv->surface);
+        xfree(sfpriv);
+        xfree(*priv);
+        *priv = NULL;
+        *num_priv = 0;
+        return BadAlloc;
     }
 
-    (*priv)[0] = sfno;
-    (*priv)[1] = nbuffers;
-    (*priv)[2] = sfpriv->offsets[0] = sfpriv->surface->offset;
-
-    for (i = 1; i < nbuffers; ++i) {
-        (*priv)[i + 2] = sfpriv->offsets[i] = sfpriv->offsets[i - 1] + bufsize;
+    memset(pI830->FbBase + sfpriv->surface->offset, 0x5a, size_y420(ctx->width, ctx->height));
+    memset(pI830->FbBase + sfpriv->surface->offset + size_y420(ctx->width, ctx->height),
+           0x5c, size_uv420(ctx->width, ctx->height));
+    memset(pI830->FbBase + sfpriv->surface->offset + size_y420(ctx->width, ctx->height) + size_uv420(ctx->width, ctx->height),
+           0x5f, size_uv420(ctx->width, ctx->height));
+    for (srfno = 0; srfno < I915_XVMC_MAX_SURFACES; ++srfno) {
+        if (!pXvMC->surfaces[srfno])
+            break;
     }
 
-    pXvMC->surfaces[sfno] = pSurf->surface_id;
-    pXvMC->sfprivs[sfno]= sfpriv;
+    surfaceRec->srfno = srfno;
+    surfaceRec->srf.handle = sfpriv->surface_handle;
+    surfaceRec->srf.offset = sfpriv->surface->offset;
+    surfaceRec->srf.size = sfpriv->surface->size;
+
+    pXvMC->surfaces[srfno] = pSurf->surface_id;
+    pXvMC->sfprivs[srfno]= sfpriv;
     pXvMC->nsurfaces++;
 
     return Success;
@@ -614,36 +649,41 @@ static int I915XvMCCreateSubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSubp,
     I830Ptr pI830 = I830PTR(pScrn);
     I915XvMCPtr pXvMC = pI830->xvmc;
     I915XvMCSurfacePriv *sfpriv = NULL;
+    I915XvMCCreateSurfaceRec *surfaceRec = NULL;
     XvMCContextPtr ctx = NULL;
     unsigned srfno;
     unsigned bufsize;
 
-    if (I915_XVMC_MAX_SURFACES == pXvMC->nsurfaces) {
+    *priv = NULL;
+    *num_priv = 0;
+
+    if (pXvMC->nsurfaces >= I915_XVMC_MAX_SURFACES) {
         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
                    "[XvMC] I915XvMCCreateSubpicture: Too many surfaces !\n");
         return BadAlloc;
     }
 
-    sfpriv = (I915XvMCSurfacePriv *)xcalloc(1, sizeof(I915XvMCSurfacePriv));
+    *priv = xcalloc(1, sizeof(I915XvMCCreateSurfaceRec));
+    surfaceRec = (I915XvMCCreateSurfaceRec *)*priv;     
 
-    if (!sfpriv) {
+    if (!*priv) {
         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
                    "[XvMC] I915XvMCCreateSubpicture: Unable to allocate memory!\n");
-        *num_priv = 0;
         return BadAlloc;
     }
 
-    *priv = (INT32 *)xcalloc(3, sizeof(INT32));
+    *num_priv = sizeof(I915XvMCCreateSurfaceRec) >> 2;
+    sfpriv = (I915XvMCSurfacePriv *)xcalloc(1, sizeof(I915XvMCSurfacePriv));
 
-    if (!*priv) {
+    if (!sfpriv) {
         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
                    "[XvMC] I915XvMCCreateSubpicture: Unable to allocate memory!\n");
+        xfree(*priv);
+        *priv = NULL;
         *num_priv = 0;
-        xfree(sfpriv);
         return BadAlloc;
     }
 
-    *num_priv = 2;
     ctx = pSubp->context;
     bufsize = size_xx44(ctx->width, ctx->height);
 
@@ -651,7 +691,20 @@ static int I915XvMCCreateSubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSubp,
         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
                    "[XvMC] I915XvMCCreateSurface: Failed to allocate XvMC surface space!\n");
         xfree(sfpriv);
-        sfpriv = NULL;
+        xfree(*priv);
+        *priv = NULL;
+        *num_priv = 0;
+        return BadAlloc;
+    }
+
+    if (drmAddMap(pI830->drmSubFD,
+                  (drm_handle_t)(sfpriv->surface->offset + pI830->LinearAddr),
+                  sfpriv->surface->size, DRM_AGP, 0,
+                  (drmAddress)&sfpriv->surface_handle) < 0) {
+        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                   "[drm] drmAddMap(surface_handle) failed!\n");
+        i830_free_memory(pScrn, sfpriv->surface);
+        xfree(sfpriv);
         xfree(*priv);
         *priv = NULL;
         *num_priv = 0;
@@ -659,12 +712,15 @@ static int I915XvMCCreateSubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSubp,
     }
 
     for (srfno = 0; srfno < I915_XVMC_MAX_SURFACES; ++srfno) {
-        if (0 == pXvMC->sfprivs[srfno])
+        if (!pXvMC->surfaces[srfno])
             break;
     }
 
-    (*priv)[0] = srfno;
-    (*priv)[1] = sfpriv->offsets[0] = sfpriv->surface->offset;
+    surfaceRec->srfno = srfno;
+    surfaceRec->srf.handle = sfpriv->surface_handle;
+    surfaceRec->srf.offset = sfpriv->surface->offset;
+    surfaceRec->srf.size = sfpriv->surface->size;
+
     pXvMC->sfprivs[srfno] = sfpriv;
     pXvMC->surfaces[srfno] = pSubp->subpicture_id;
     pXvMC->nsurfaces++;
@@ -818,12 +874,20 @@ static int I915XvMCInterceptPutImage(ScrnInfoPtr pScrn, short src_x, short src_y
 
             case I915_XVMC_COMMAND_DISPLAY:
                 for (i = 0; i < I915_XVMC_MAX_SURFACES; i++) {
-                    if (pXvMC->surfaces[i] == i915XvMCData->srfNo) {
-                        i830_memory *mem = pXvMC->sfprivs[i]->surface;
-                        buf = pI830 + mem->offset;
-                        id = i915XvMCData->real_id;
-                        break;
-                    }
+                   i830_memory *mem = NULL;
+
+                   if ((i915XvMCData->srfNo >= I915_XVMC_MAX_SURFACES) ||
+                       !pXvMC->surfaces[i915XvMCData->srfNo] ||
+                       !pXvMC->sfprivs[i915XvMCData->srfNo]) {
+                      xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                                 "[XvMC] I915XvMCInterceptPutImage: Invalid parameters !\n");
+                      return 1;
+                   }
+                   
+                   mem = pXvMC->sfprivs[i]->surface;
+                   buf = pI830->FbBase + mem->offset;
+                   id = i915XvMCData->real_id;
+                   break;
                 }
 
                 if (i >= I915_XVMC_MAX_SURFACES)
@@ -861,7 +925,6 @@ void I915InitMC(ScreenPtr pScreen)
     I915XvMCPtr pXvMC = NULL; 
 
     pI830->XvMCEnabled = FALSE;
-    return;
     if (!pI830->directRenderingEnabled) {
         xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
                    "[XvMC] Cannot use XvMC without DRI!\n");
@@ -892,7 +955,6 @@ int I915XvMCInitXv(ScrnInfoPtr pScrn, XF86VideoAdaptorPtr XvAdapt)
     GetPortAttributeFuncPtr getportattribute = XvAdapt->GetPortAttribute;
     PutImageFuncPtr putimage = XvAdapt->PutImage;
 
-    return Success;
     XvAdapt->GetPortAttribute = I915XvMCInterceptXvGetAttribute;
     XvAdapt->SetPortAttribute = I915XvMCInterceptXvAttribute;
     XvAdapt->PutImage = I915XvMCInterceptPutImage;
@@ -916,8 +978,8 @@ int I915XvMCInitXv(ScrnInfoPtr pScrn, XF86VideoAdaptorPtr XvAdapt)
         vx->newAttribute = 1;
 
         /* set up wrappers */
-        vx->GetPortAttribute = setportattribute;
-        vx->SetPortAttribute = getportattribute;
+        vx->GetPortAttribute = getportattribute;
+        vx->SetPortAttribute = setportattribute;
         vx->PutImage = putimage;
 
         for (i = 0; i < I915_NUM_XVMC_ATTRIBUTES; ++i) {
diff --git a/src/i915_hwmc.h b/src/i915_hwmc.h
index 882dea0..b87ba31 100644
--- a/src/i915_hwmc.h
+++ b/src/i915_hwmc.h
@@ -61,4 +61,10 @@ typedef struct
     I915XvMCAttrHolder initAttrs;
 } I915XvMCCreateContextRec;
 
+typedef struct 
+{
+    unsigned srfno;
+    struct hwmc_buffer srf;
+} I915XvMCCreateSurfaceRec;
+
 #endif /* _I915_HWMC_H */
diff --git a/src/xvmc/I915XvMC.c b/src/xvmc/I915XvMC.c
index c51f89b..937eee9 100644
--- a/src/xvmc/I915XvMC.c
+++ b/src/xvmc/I915XvMC.c
@@ -168,28 +168,30 @@ _STATIC_ void UNLOCK_HARDWARE(i915XvMCContext *pI915XvMC)
 
 _STATIC_ unsigned stride(int w)
 {
-    return (w + 31) & ~31;
+    return (w + 3) & ~3;
 }
 
 _STATIC_ unsigned long size_y(int w, int h)
 {
-    unsigned cpp = 4;
+    unsigned cpp = 1;
+    unsigned yPitch = stride(w) * cpp;
 
-    return h * stride(w) * cpp;
+    return h * yPitch;
 }
 
 _STATIC_ unsigned long size_uv(int w, int h)
 {
-    unsigned cpp = 4;
-
-    return h / 2 * stride(w / 2) * cpp;
+    unsigned cpp = 1;
+    unsigned uvPitch = stride(w >> 1) * cpp;
+    
+    return h / 2 * uvPitch;
 }
 
 _STATIC_ unsigned long size_yuv420(int w, int h)
 {
-    unsigned cpp = 4;
+    unsigned cpp = 1;
     unsigned yPitch = stride(w) * cpp;
-    unsigned uvPitch = stride(w / 2) * cpp;
+    unsigned uvPitch = stride(w >> 1) * cpp;
 
     return h * (yPitch + uvPitch);
 }
@@ -238,8 +240,10 @@ _STATIC_ void __i915_flush(i915XvMCContext *pI915XvMC)
 
 /* for MC picture rendering */
 _STATIC_ void i915_mc_static_indirect_state_buffer(XvMCContext *context, 
-                                                 XvMCSurface *surface,
-                                                 unsigned int picture_coding_type)
+                                                   XvMCSurface *surface,
+                                                   unsigned picture_structure,
+                                                   unsigned flags,
+                                                   unsigned picture_coding_type)
 {
     struct i915_3dstate_buffer_info *buffer_info;
     struct i915_3dstate_dest_buffer_variables *dest_buffer_variables;
@@ -247,7 +251,6 @@ _STATIC_ void i915_mc_static_indirect_state_buffer(XvMCContext *context,
     i915XvMCSurface *pI915Surface = (i915XvMCSurface *)surface->privData;
     i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
     unsigned w = surface->width, h = surface->height;
-    unsigned cpp = 4;
 
     /* 3DSTATE_BUFFER_INFO */
     /* DEST Y */
@@ -258,11 +261,11 @@ _STATIC_ void i915_mc_static_indirect_state_buffer(XvMCContext *context,
     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 */
+    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 = stride(w);
-    buffer_info->dw2.base_address = pI915Surface->offsets[pI915Surface->curbuf];
+    buffer_info->dw1.pitch = (pI915Surface->yStride >> 2);      /* in DWords */
+    buffer_info->dw2.base_address = pI915Surface->srf.offset;
 
     /* DEST U */
     ++buffer_info;
@@ -275,9 +278,9 @@ _STATIC_ void i915_mc_static_indirect_state_buffer(XvMCContext *context,
     buffer_info->dw1.fence_regs = 0;
     buffer_info->dw1.tiled_surface = 0;
     buffer_info->dw1.walk = TILEWALK_XMAJOR; 
-    buffer_info->dw1.pitch = stride(w / 2);
-    buffer_info->dw2.base_address = pI915Surface->offsets[pI915Surface->curbuf] 
-        + size_y(w, h);
+    buffer_info->dw1.pitch = (pI915Surface->uvStride >> 2);      /* in DWords */
+    buffer_info->dw2.base_address = pI915Surface->srf.offset +
+        size_y(w, h) + size_uv(w, h);
 
     /* DEST V */
     ++buffer_info;
@@ -290,9 +293,9 @@ _STATIC_ void i915_mc_static_indirect_state_buffer(XvMCContext *context,
     buffer_info->dw1.fence_regs = 0;
     buffer_info->dw1.tiled_surface = 0;
     buffer_info->dw1.walk = TILEWALK_XMAJOR; 
-    buffer_info->dw1.pitch = stride(w / 2);
-    buffer_info->dw2.base_address = pI915Surface->offsets[pI915Surface->curbuf] 
-        + size_y(w, h) + size_uv(w, h);
+    buffer_info->dw1.pitch = (pI915Surface->uvStride >> 2);      /* in Dwords */
+    buffer_info->dw2.base_address = pI915Surface->srf.offset +
+        size_y(w, h);
 
     /* 3DSTATE_DEST_BUFFER_VARIABLES */
     dest_buffer_variables = (struct i915_3dstate_dest_buffer_variables *)(++buffer_info);
@@ -302,8 +305,8 @@ _STATIC_ void i915_mc_static_indirect_state_buffer(XvMCContext *context,
     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.v_ls = 0;         /* FIXME */
-    dest_buffer_variables->dw1.v_ls_offset = 0;
+    dest_buffer_variables->dw1.v_ls = 0;    
+    dest_buffer_variables->dw1.v_ls_offset = 1;
 
     /* 3DSTATE_DEST_BUFFER_VARIABLES_MPEG */
     dest_buffer_variables_mpeg = (struct i915_3dstate_dest_buffer_variables_mpeg *)(++dest_buffer_variables);
@@ -311,12 +314,27 @@ _STATIC_ void i915_mc_static_indirect_state_buffer(XvMCContext *context,
     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.decoder_mode = MPEG_DECODE_MC;
-    dest_buffer_variables_mpeg->dw1.rcontrol = 0;       /* for MPEG-2/MPEG-1 */
-    dest_buffer_variables_mpeg->dw1.bidir_avrg_control = 0; 
+    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.intra8 = 0;         /* 16-bit formatted correction data */
-    dest_buffer_variables_mpeg->dw1.tff = 0;            /* FIXME */
-    dest_buffer_variables_mpeg->dw1.picture_width = w >> 4;
+    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;
+        else
+            dest_buffer_variables_mpeg->dw1.tff = 1;
+    } else if (picture_structure & XVMC_BOTTOM_FIELD) {
+        if (flags & XVMC_SECOND_FIELD)
+            dest_buffer_variables_mpeg->dw1.tff = 1;
+        else
+            dest_buffer_variables_mpeg->dw1.tff = 0;
+    }
+        
+    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 */
@@ -337,45 +355,15 @@ _STATIC_ void i915_mc_static_indirect_state_buffer(XvMCContext *context,
 }
 
 _STATIC_ void i915_mc_map_state_buffer(XvMCContext *context, 
-                                     XvMCSurface *target_surface,
-                                     XvMCSurface *past_surface,
-                                     XvMCSurface *future_surface)
+                                       i915XvMCSurface *privTarget,
+                                       i915XvMCSurface *privPast,
+                                       i915XvMCSurface *privFuture)
 {
     struct i915_3dstate_map_state *map_state;
     struct texture_map *tm;
-    i915XvMCSurface *privTarget = NULL;
-    i915XvMCSurface *privPast = NULL;
-    i915XvMCSurface *privFuture = NULL;
     i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
-    unsigned w = target_surface->width, h = target_surface->height;
+    unsigned w = context->width, h = context->height;
  
-    privTarget = (i915XvMCSurface *)target_surface->privData;
-
-    /* P Frame Test */
-    if (!past_surface) {
-        privPast = privTarget;
-    } else {
-        if (!past_surface->privData) {
-            printf("Error, Invalid Past Surface!\n");
-            return;
-        }
-
-        privPast = (i915XvMCSurface *)past_surface->privData;
-    }
-
-    /* B Frame Test */
-    if (!future_surface) {
-        privFuture = privTarget;
-    } else {
-        if (!future_surface->privData || !past_surface) {
-            printf("Error, Invalid Future Surface or No Past Surface!\n");
-            return;
-        }
-
-        privFuture = (i915XvMCSurface *)future_surface->privData;
-    }
-
-
     /* 3DSATE_MAP_STATE: Y */
     map_state = (struct i915_3dstate_map_state *)pI915XvMC->msb.map;
     memset(map_state, 0, sizeof(*map_state));
@@ -390,36 +378,36 @@ _STATIC_ void i915_mc_map_state_buffer(XvMCContext *context,
     memset(tm, 0, sizeof(*tm));
     tm->tm0.v_ls_offset = 0;
     tm->tm0.v_ls = 0;
-    tm->tm0.base_address = privPast->offsets[privPast->curbuf];
+    tm->tm0.base_address = privPast->srf.offset;
     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.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 = stride(w) - 1;
+    tm->tm2.pitch = (privPast->yStride >> 2) - 1;       /* in DWords - 1 */
 
     /* 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 = privFuture->offsets[privFuture->curbuf];
+    tm->tm0.base_address = privFuture->srf.offset;
     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.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 = stride(w) - 1;
+    tm->tm2.pitch = (privFuture->yStride >> 2) - 1;
 
     /* 3DSATE_MAP_STATE: U*/
     map_state = (struct i915_3dstate_map_state *)(++tm);
@@ -435,25 +423,27 @@ _STATIC_ void i915_mc_map_state_buffer(XvMCContext *context,
     memset(tm, 0, sizeof(*tm));
     tm->tm0.v_ls_offset = 0;
     tm->tm0.v_ls = 0;
-    tm->tm0.base_address = privPast->offsets[privPast->curbuf] + size_y(w, h);
+    tm->tm0.base_address = privPast->srf.offset +
+        size_y(w, h) + size_uv(w, h);
     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.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 = stride(w / 2) - 1;
+    tm->tm2.pitch = (privPast->uvStride >> 2) - 1;       /* in DWords - 1 */
 
     /* texture map: Backward */
     ++tm;
     memset(tm, 0, sizeof(*tm));
     tm->tm0.v_ls_offset = 0;
     tm->tm0.v_ls = 0;
-    tm->tm0.base_address = privFuture->offsets[privFuture->curbuf] + size_y(w, h);
+    tm->tm0.base_address = privFuture->srf.offset +
+        size_y(w, h) + size_uv(w, h);
     tm->tm1.tile_walk = TILEWALK_XMAJOR;
     tm->tm1.tiled_surface = 0;
     tm->tm1.utilize_fence_regs = 0;
@@ -464,7 +454,7 @@ _STATIC_ void i915_mc_map_state_buffer(XvMCContext *context,
     tm->tm2.depth = 0;
     tm->tm2.max_lod = 0;
     tm->tm2.cube_face = 0;
-    tm->tm2.pitch = stride(w / 2) - 1;
+    tm->tm2.pitch = (privFuture->uvStride >> 2) - 1;     
 
     /* 3DSATE_MAP_STATE: V */
     map_state = (struct i915_3dstate_map_state *)(++tm);
@@ -480,7 +470,8 @@ _STATIC_ void i915_mc_map_state_buffer(XvMCContext *context,
     memset(tm, 0, sizeof(*tm));
     tm->tm0.v_ls_offset = 0;
     tm->tm0.v_ls = 0;
-    tm->tm0.base_address = privPast->offsets[privPast->curbuf] + size_y(w, h) + size_uv(w, h);
+    tm->tm0.base_address = privPast->srf.offset +
+        size_y(w, h);
     tm->tm1.tile_walk = TILEWALK_XMAJOR;
     tm->tm1.tiled_surface = 0;
     tm->tm1.utilize_fence_regs = 0;
@@ -491,14 +482,15 @@ _STATIC_ void i915_mc_map_state_buffer(XvMCContext *context,
     tm->tm2.depth = 0;
     tm->tm2.max_lod = 0;
     tm->tm2.cube_face = 0;
-    tm->tm2.pitch = stride(w / 2) - 1;
+    tm->tm2.pitch = (privPast->uvStride >> 2) - 1;       /* in DWords - 1 */
 
     /* texture map: Backward */
     ++tm;
     memset(tm, 0, sizeof(*tm));
     tm->tm0.v_ls_offset = 0;
     tm->tm0.v_ls = 0;
-    tm->tm0.base_address = privFuture->offsets[privFuture->curbuf] + size_y(w, h) + size_uv(w, h);
+    tm->tm0.base_address = privFuture->srf.offset +
+        size_y(w, h);
     tm->tm1.tile_walk = TILEWALK_XMAJOR;
     tm->tm1.tiled_surface = 0;
     tm->tm1.utilize_fence_regs = 0;
@@ -509,7 +501,7 @@ _STATIC_ void i915_mc_map_state_buffer(XvMCContext *context,
     tm->tm2.depth = 0;
     tm->tm2.max_lod = 0;
     tm->tm2.cube_face = 0;
-    tm->tm2.pitch = stride(w / 2) - 1;
+    tm->tm2.pitch = (privFuture->uvStride >> 2) - 1;
 }
 
 _STATIC_ void i915_mc_load_indirect_buffer(XvMCContext *context)
@@ -531,7 +523,7 @@ _STATIC_ void i915_mc_load_indirect_buffer(XvMCContext *context)
     load_indirect->dw0.opcode = OPC_3DSTATE_LOAD_INDIRECT;
     load_indirect->dw0.mem_select = 1;  /* Bearlake only */
     load_indirect->dw0.block_mask = BLOCK_SIS | BLOCK_MSB;
-    load_indirect->dw0.length = 3;
+    load_indirect->dw0.length = (size >> 2) - 2;
 
     /* SIS */
     sis = (sis_state *)(++load_indirect);
@@ -555,7 +547,7 @@ _STATIC_ void i915_mc_mpeg_set_origin(XvMCContext *context, XvMCMacroBlock *mb)
     i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
 
     /* 3DMPEG_SET_ORIGIN */
-    memset(&set_origin, sizeof(set_origin), 0);
+    memset(&set_origin, 0, sizeof(set_origin));
     set_origin.dw0.type = CMD_3D;
     set_origin.dw0.opcode = OPC_3DMPEG_SET_ORIGIN;
     set_origin.dw0.length = 0;
@@ -571,11 +563,11 @@ _STATIC_ void i915_mc_mpeg_macroblock_0mv(XvMCContext *context, XvMCMacroBlock *
     i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
 
     /* 3DMPEG_MACROBLOCK(0mv) */
-    memset(&macroblock_0mv, sizeof(macroblock_0mv), 0);
+    memset(&macroblock_0mv, 0, sizeof(macroblock_0mv));
     macroblock_0mv.header.dw0.type = CMD_3D;
     macroblock_0mv.header.dw0.opcode = OPC_3DMPEG_MACROBLOCK;
     macroblock_0mv.header.dw0.length = 0;
-    macroblock_0mv.header.dw1.intra = 1;        /* should be 1 */ 
+    macroblock_0mv.header.dw1.mb_intra = 1;     /* should be 1 */ 
     macroblock_0mv.header.dw1.forward = 0;      /* should be 0 */
     macroblock_0mv.header.dw1.backward = 0;     /* should be 0 */
     macroblock_0mv.header.dw1.h263_4mv = 0;     /* should be 0 */
@@ -602,28 +594,34 @@ _STATIC_ void i915_mc_mpeg_macroblock_1fbmv(XvMCContext *context, XvMCMacroBlock
     su_t bmv;
 
     /* 3DMPEG_MACROBLOCK(1fbmv) */
-    memset(&macroblock_1fbmv, sizeof(macroblock_1fbmv), 0);
+    memset(&macroblock_1fbmv, 0, sizeof(macroblock_1fbmv));
     macroblock_1fbmv.header.dw0.type = CMD_3D;
     macroblock_1fbmv.header.dw0.opcode = OPC_3DMPEG_MACROBLOCK;
     macroblock_1fbmv.header.dw0.length = 2;
-    macroblock_1fbmv.header.dw1.intra = (mb->macroblock_type & XVMC_MB_TYPE_INTRA);
-    macroblock_1fbmv.header.dw1.forward = (mb->macroblock_type & XVMC_MB_TYPE_MOTION_FORWARD);
-    macroblock_1fbmv.header.dw1.backward = (mb->macroblock_type & XVMC_MB_TYPE_MOTION_BACKWARD);
-    macroblock_1fbmv.header.dw1.h263_4mv = 0;     /* should be 0 */
+    macroblock_1fbmv.header.dw1.mb_intra = 0;   /* should be 0 */ 
+    macroblock_1fbmv.header.dw1.forward = ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_FORWARD) ? 1 : 0);
+    macroblock_1fbmv.header.dw1.backward = ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_BACKWARD) ? 1 : 0);
+    macroblock_1fbmv.header.dw1.h263_4mv = 0;   /* should be 0 */
     macroblock_1fbmv.header.dw1.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD);
     
-    if (!mb->coded_block_pattern)       /* FIXME */
+    if (!mb->coded_block_pattern)
         macroblock_1fbmv.header.dw1.dct_type = XVMC_DCT_TYPE_FRAME;
 
-    macroblock_1fbmv.header.dw1.motion_type = mb->motion_type;
-    macroblock_1fbmv.header.dw1.vertical_field_select = mb->motion_vertical_field_select;
-    macroblock_1fbmv.header.dw1.coded_block_pattern = mb->coded_block_pattern; /* FIXME */
-    macroblock_1fbmv.header.dw1.skipped_macroblocks = 0;      /* FIXME */
+    macroblock_1fbmv.header.dw1.motion_type = (mb->motion_type & 0x03);
+    macroblock_1fbmv.header.dw1.vertical_field_select = (mb->motion_vertical_field_select & 0x0f);
+    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][1];
     fmv.s[1] = mb->PMV[0][0][0];
     bmv.s[0] = mb->PMV[0][1][1];
     bmv.s[1] = mb->PMV[0][1][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];
 
     macroblock_1fbmv.dw2 = fmv.u[0];
     macroblock_1fbmv.dw3 = bmv.u[0];
@@ -641,32 +639,32 @@ _STATIC_ void i915_mc_mpeg_macroblock_2fbmv(XvMCContext *context, XvMCMacroBlock
     su_t bmv;
 
     /* 3DMPEG_MACROBLOCK(2fbmv) */
-    memset(&macroblock_2fbmv, sizeof(macroblock_2fbmv), 0);
+    memset(&macroblock_2fbmv, 0, sizeof(macroblock_2fbmv));
     macroblock_2fbmv.header.dw0.type = CMD_3D;
     macroblock_2fbmv.header.dw0.opcode = OPC_3DMPEG_MACROBLOCK;
-    macroblock_2fbmv.header.dw0.length = 2;
-    macroblock_2fbmv.header.dw1.intra = (mb->macroblock_type & XVMC_MB_TYPE_INTRA);
-    macroblock_2fbmv.header.dw1.forward = (mb->macroblock_type & XVMC_MB_TYPE_MOTION_FORWARD);
-    macroblock_2fbmv.header.dw1.backward = (mb->macroblock_type & XVMC_MB_TYPE_MOTION_BACKWARD);
-    macroblock_2fbmv.header.dw1.h263_4mv = 0;     /* should be 0 */
+    macroblock_2fbmv.header.dw0.length = 4;
+    macroblock_2fbmv.header.dw1.mb_intra = 0;   /* should be 0 */
+    macroblock_2fbmv.header.dw1.forward = ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_FORWARD) ? 1 : 0);
+    macroblock_2fbmv.header.dw1.backward = ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_BACKWARD) ? 1 : 0);
+    macroblock_2fbmv.header.dw1.h263_4mv = 0;   /* should be 0 */
     macroblock_2fbmv.header.dw1.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD);
     
-    if (!mb->coded_block_pattern)       /* FIXME */
+    if (!mb->coded_block_pattern)
         macroblock_2fbmv.header.dw1.dct_type = XVMC_DCT_TYPE_FRAME;
 
-    macroblock_2fbmv.header.dw1.motion_type = mb->motion_type;
-    macroblock_2fbmv.header.dw1.vertical_field_select = mb->motion_vertical_field_select;
-    macroblock_2fbmv.header.dw1.coded_block_pattern = mb->coded_block_pattern; /* FIXME */
-    macroblock_2fbmv.header.dw1.skipped_macroblocks = 0;      /* FIXME */
+    macroblock_2fbmv.header.dw1.motion_type = (mb->motion_type & 0x03);
+    macroblock_2fbmv.header.dw1.vertical_field_select = (mb->motion_vertical_field_select & 0x0f);
+    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][1];
-    fmv.s[1] = mb->PMV[0][0][0];
-    fmv.s[2] = mb->PMV[1][0][1];
-    fmv.s[3] = mb->PMV[1][0][0];
-    bmv.s[0] = mb->PMV[0][1][1];
-    bmv.s[1] = mb->PMV[0][1][0];
-    bmv.s[2] = mb->PMV[1][1][1];
-    bmv.s[3] = mb->PMV[1][1][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];
 
     macroblock_2fbmv.dw2 = fmv.u[0];
     macroblock_2fbmv.dw3 = bmv.u[0];
@@ -754,9 +752,11 @@ _STATIC_ void i915_inst_arith(unsigned *inst,
                             unsigned src0, unsigned src1, unsigned src2)
 {
     dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest));
-    *(inst++) = (op | A0_DEST(dest) | mask | saturate | A0_SRC0(src0));
-    *(inst++) = (A1_SRC0(src0) | A1_SRC1(src1));
-    *(inst++) = (A2_SRC1(src1) | A2_SRC2(src2));
+    *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 *inst, 
@@ -766,9 +766,11 @@ _STATIC_ void i915_inst_decl(unsigned *inst,
 {
     unsigned reg = UREG(type, nr);
     
-    *(inst++) = (D0_DCL | D0_DEST(reg) | d0_flags);
-    *(inst++) = D1_MBZ;
-    *(inst++) = D2_MBZ;
+    *inst = (D0_DCL | D0_DEST(reg) | d0_flags);
+    inst++;
+    *inst = D1_MBZ;
+    inst++;
+    *inst = D2_MBZ;
 }
 
 _STATIC_ void i915_inst_texld(unsigned *inst,
@@ -778,9 +780,11 @@ _STATIC_ void i915_inst_texld(unsigned *inst,
                               unsigned sampler)
 {
    dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest));
-   *(inst++) = (op | T0_DEST(dest) | T0_SAMPLER(sampler));
-   *(inst++) = T1_ADDRESS_REG(coord);
-   *(inst++) = T2_MBZ;
+   *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)
@@ -966,7 +970,7 @@ _STATIC_ void i915_mc_one_time_state_initialization(XvMCContext *context)
     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 = 1;
+    load_state_immediate_1->dw0.length = (size >> 2) - 2;
 
     s3 = (struct s3_dword *)(++load_state_immediate_1);
     s3->set0_pcd = 1;
@@ -1006,7 +1010,7 @@ _STATIC_ void i915_mc_one_time_state_initialization(XvMCContext *context)
     load_indirect->dw0.opcode = OPC_3DSTATE_LOAD_INDIRECT;
     load_indirect->dw0.mem_select = 1;      /* Bearlake only */
     load_indirect->dw0.block_mask = BLOCK_DIS | BLOCK_SSB | BLOCK_PSP | BLOCK_PSC;
-    load_indirect->dw0.length = 6;
+    load_indirect->dw0.length = (size >> 2) - 2;
 
     /* DIS */
     dis = (dis_state *)(++load_indirect);
@@ -1143,7 +1147,8 @@ _STATIC_ void i915_yuv2rgb_map_state_buffer(XvMCSurface *target_surface)
     memset(tm, 0, sizeof(*tm));
     tm->tm0.v_ls_offset = 0;
     tm->tm0.v_ls = 0;
-    tm->tm0.base_address = privTarget->offsets[privTarget->curbuf] + size_y(w, h);
+    tm->tm0.base_address = privTarget->srf.offset +
+        size_y(w, h);
     tm->tm1.tile_walk = TILEWALK_XMAJOR;
     tm->tm1.tiled_surface = 0;
     tm->tm1.utilize_fence_regs = 1;
@@ -1154,14 +1159,14 @@ _STATIC_ void i915_yuv2rgb_map_state_buffer(XvMCSurface *target_surface)
     tm->tm2.depth = 0;
     tm->tm2.max_lod = 0;
     tm->tm2.cube_face = 0;
-    tm->tm2.pitch = (stride(w) >> 1) - 1;
+    tm->tm2.pitch = (privTarget->uvStride >> 2) - 1;    /* in DWords - 1 */
 
     /* texture map 1: Y Plane */
     ++tm;
     memset(tm, 0, sizeof(*tm));
     tm->tm0.v_ls_offset = 0;
     tm->tm0.v_ls = 0;
-    tm->tm0.base_address = privTarget->offsets[privTarget->curbuf];
+    tm->tm0.base_address = privTarget->srf.offset;
     tm->tm1.tile_walk = TILEWALK_XMAJOR;
     tm->tm1.tiled_surface = 0;
     tm->tm1.utilize_fence_regs = 1;
@@ -1172,14 +1177,15 @@ _STATIC_ void i915_yuv2rgb_map_state_buffer(XvMCSurface *target_surface)
     tm->tm2.depth = 0;
     tm->tm2.max_lod = 0;
     tm->tm2.cube_face = 0;
-    tm->tm2.pitch = stride(w) - 1;
+    tm->tm2.pitch = (privTarget->yStride >> 2) - 1;     /* in DWords - 1 */
 
     /* texture map 2: U Plane */
     ++tm;
     memset(tm, 0, sizeof(*tm));
     tm->tm0.v_ls_offset = 0;
     tm->tm0.v_ls = 0;
-    tm->tm0.base_address = privTarget->offsets[privTarget->curbuf] + size_y(w, h) + (size_y(w, h) >> 2);
+    tm->tm0.base_address = privTarget->srf.offset +
+        size_y(w, h) + size_uv(w, h);
     tm->tm1.tile_walk = TILEWALK_XMAJOR;
     tm->tm1.tiled_surface = 0;
     tm->tm1.utilize_fence_regs = 1;
@@ -1190,7 +1196,7 @@ _STATIC_ void i915_yuv2rgb_map_state_buffer(XvMCSurface *target_surface)
     tm->tm2.depth = 0;
     tm->tm2.max_lod = 0;
     tm->tm2.cube_face = 0;
-    tm->tm2.pitch = (stride(w) >> 1) - 1;
+    tm->tm2.pitch = (privTarget->uvStride >> 2) - 1;    /* in DWords - 1 */
 }
 
 _STATIC_ void i915_yuv2rgb_sampler_state_buffer(XvMCSurface *surface)
@@ -1832,7 +1838,8 @@ Status XvMCCreateContext(Display *display, XvPortID port,
 
     /* Initialize private context values */
     setupAttribDesc(display, port, &pI915XvMC->attrib, pI915XvMC->attribDesc);
-    pI915XvMC->yStride = (width + 31) & ~31;
+    pI915XvMC->yStride = stride(width) * 1;     /* cpp = 1 */
+    pI915XvMC->uvStride = stride(width >> 1) * 1;
     pI915XvMC->haveXv = 0;
     pI915XvMC->attribChanged = 1;
     pI915XvMC->dual_prime = 0;
@@ -1878,7 +1885,8 @@ Status XvMCCreateSurface(Display *display, XvMCContext *context, XvMCSurface *su
     Status ret;
     i915XvMCContext *pI915XvMC;
     i915XvMCSurface *pI915Surface;
-    int priv_count, i;
+    I915XvMCCreateSurfaceRec *tmpComm = NULL;
+    int priv_count;
     uint *priv_data;
 
     if (!display || !context || !display)
@@ -1899,6 +1907,7 @@ Status XvMCCreateSurface(Display *display, XvMCContext *context, XvMCSurface *su
     pI915Surface->last_render = 0;
     pI915Surface->last_flip = 0;
     pI915Surface->yStride = pI915XvMC->yStride;
+    pI915Surface->uvStride = pI915XvMC->uvStride;
     pI915Surface->width = context->width;
     pI915Surface->height = context->height;
     pI915Surface->privContext = pI915XvMC;
@@ -1917,17 +1926,40 @@ Status XvMCCreateSurface(Display *display, XvMCContext *context, XvMCSurface *su
     }
 
     XUnlockDisplay(display);
-    pI915Surface->srfNo = priv_data[0];
-    pI915Surface->num_buffers = priv_data[1];
-    pI915Surface->curbuf = 0;
 
-    for (i = 0; i < pI915Surface->num_buffers; ++i)
-        pI915Surface->offsets[i] = priv_data[i + 2];
-    
+    if (priv_count != (sizeof(I915XvMCCreateSurfaceRec) >> 2)) {
+        printf("_xvmc_create_surface() returned incorrect data size!\n");
+        printf("\tExpected %d, got %d\n", 
+               (int)(sizeof(I915XvMCCreateSurfaceRec) >> 2), priv_count);
+        _xvmc_destroy_surface(display, surface);
+        free(priv_data);
+        free(pI915Surface);
+        surface->privData = NULL;
+        pthread_mutex_unlock(&pI915XvMC->ctxmutex);
+        return BadAlloc;
+    }
+
+    tmpComm = (I915XvMCCreateSurfaceRec *)priv_data;
+
+    pI915Surface->srfNo = tmpComm->srfno;
+    pI915Surface->srf.handle = tmpComm->srf.handle;
+    pI915Surface->srf.offset = tmpComm->srf.offset;
+    pI915Surface->srf.size = tmpComm->srf.size;
     free(priv_data);
+
+    if (drmMap(pI915XvMC->fd,
+               pI915Surface->srf.handle,
+               pI915Surface->srf.size,
+               (drmAddress *)&pI915Surface->srf.map) != 0) {
+        _xvmc_destroy_surface(display, surface);
+        free(pI915Surface);
+        surface->privData = NULL;
+        pthread_mutex_unlock(&pI915XvMC->ctxmutex);
+        return BadAlloc;
+    }
+
     pI915XvMC->ref++;
     pthread_mutex_unlock(&pI915XvMC->ctxmutex);
-
     return Success;
 }
 
@@ -2049,10 +2081,7 @@ Status XvMCDestroyMacroBlocks(Display *display, XvMCMacroBlockArray *block)
 // Function: XvMCRenderSurface
 // Description: This function does the actual HWMC. Given a list of
 //  macroblock structures it dispatched the hardware commands to execute
-//  them. DMA buffer containing Y data are dispatched as they fill up
-//  U and V DMA buffers are queued until all Y's are done. This minimizes
-//  the context flipping and flushing required when switching between Y
-//  U and V surfaces.
+//  them. 
 ***************************************************************************/
 Status XvMCRenderSurface(Display *display, XvMCContext *context,
                          unsigned int picture_structure,
@@ -2066,7 +2095,7 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context,
                          XvMCBlockArray *blocks) 
 {
     int i;
-
+    int picture_coding_type = MPEG_I_PICTURE;
     /* correction data buffer */
     char *corrdata_ptr;
     int corrdata_size = 0;
@@ -2126,6 +2155,8 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context,
             printf("Error, Invalid Past Surface!\n");
             return (error_base + XvMCBadSurface);
         }
+        
+        picture_coding_type = MPEG_P_PICTURE;
     }
 
     /* B Frame Test */
@@ -2141,8 +2172,14 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context,
             printf("Error, Invalid Future Surface!\n");
             return (error_base + XvMCBadSurface);
         }
+
+        picture_coding_type = MPEG_B_PICTURE;
     }
 
+    LOCK_HARDWARE(pI915XvMC);
+    intelFlushBatch(pI915XvMC, TRUE);
+    UNLOCK_HARDWARE(pI915XvMC);
+
     corrdata_ptr = pI915XvMC->corrdata.map;
     corrdata_size = 0;
 
@@ -2174,8 +2211,8 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context,
         memcpy(corrdata_ptr, block_ptr, bspm);
         corrdata_ptr += bspm;
     }
-
-    /* Lock For DMA */
+    //memset(privTarget->srf.map, 0x7f, 128);
+    /* Lock */
     LOCK_HARDWARE(pI915XvMC);
     i915_mc_sampler_state_buffer(context);
     i915_mc_pixel_shader_program_buffer(context);
@@ -2183,10 +2220,13 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context,
     i915_mc_one_time_state_initialization(context);
     intelFlushBatch(pI915XvMC, TRUE);
 
-    i915_mc_static_indirect_state_buffer(context, target_surface, picture_structure);
-    i915_mc_map_state_buffer(context, target_surface, past_surface, future_surface);
+    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_load_indirect_buffer(context);
-    i915_mc_mpeg_set_origin(context, &macroblock_array->macro_blocks[first_macroblock]);
+    i915_mc_mpeg_set_origin(context, 
+                            &macroblock_array->macro_blocks[first_macroblock]);
     intelFlushBatch(pI915XvMC, TRUE);
     for (i = first_macroblock; i < (num_macroblocks + first_macroblock); i++) {
         mb = &macroblock_array->macro_blocks[i];
@@ -2194,7 +2234,6 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context,
         /* Intra Blocks */
         if (mb->macroblock_type & XVMC_MB_TYPE_INTRA) {
             i915_mc_mpeg_macroblock_0mv(context, mb);
-            // i915_flush(pI915XvMC);
             intelFlushBatch(pI915XvMC, TRUE);
             continue;
         }
@@ -2204,39 +2243,40 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context,
             switch (mb->motion_type & 3) {
             case XVMC_PREDICTION_FIELD: /* Field Based */
                 i915_mc_mpeg_macroblock_2fbmv(context, mb);
-                continue;
+                break;
 
             case XVMC_PREDICTION_FRAME: /* Frame Based */
                 i915_mc_mpeg_macroblock_1fbmv(context, mb);
-                continue;
+                break;
 
             case XVMC_PREDICTION_DUAL_PRIME:    /* Dual Prime */
                 i915_mc_mpeg_macroblock_2fbmv(context, mb);
-                continue;
+                break;
 
             default:    /* No Motion Type */
                 renderError();
-                continue;
+                break;
             }   
         } else {        /* Frame Picture */
             switch (mb->motion_type & 3) {
             case XVMC_PREDICTION_FIELD: /* Field Based */
                 i915_mc_mpeg_macroblock_1fbmv(context, mb);
-                continue;
+                break;
 
             case XVMC_PREDICTION_16x8:  /* 16x8 MC */
                 i915_mc_mpeg_macroblock_2fbmv(context, mb);
-                continue;
+                break;
                 
             case XVMC_PREDICTION_DUAL_PRIME:    /* Dual Prime */
                 i915_mc_mpeg_macroblock_1fbmv(context, mb);
-                continue;
+                break;
 
             default:    /* No Motion Type */
                 renderError();
-                continue;
+                break;
             }
         }       /* Field Picture */
+        intelFlushBatch(pI915XvMC, TRUE);        
     }
 
     intelFlushBatch(pI915XvMC, TRUE);
@@ -2244,6 +2284,41 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context,
     privTarget->last_render = pI915XvMC->last_render;
 
     UNLOCK_HARDWARE(pI915XvMC);
+
+    {
+        int i;
+        corrdata_ptr = pI915XvMC->corrdata.map;
+
+        printf("correct data:\n");
+        for (i = 0; i < 32; i++) {
+            printf("%02x ", *corrdata_ptr++);
+        }
+        printf("\n");
+
+        printf("y data:\n");
+        corrdata_ptr = privTarget->srf.map;
+        for (i = 0; i < 32; i++) {
+            printf("%02x ", *corrdata_ptr++);
+        }
+        printf("\n");
+
+        printf("v data:\n");
+        corrdata_ptr = privTarget->srf.map + size_y(context->width, context->height);
+        for (i = 0; i < 32; i++) {
+            printf("%02x ", *corrdata_ptr++);
+        }
+        printf("\n");
+
+        printf("u data:\n");
+        corrdata_ptr = privTarget->srf.map + size_y(context->width, context->height) + 
+           size_uv(context->width, context->height);
+        for (i = 0; i < 32; i++) {
+            printf("%02x ", *corrdata_ptr++);
+        }
+        printf("\n");
+
+        fflush(NULL);
+    }
     return Success;
 }
 
@@ -2291,7 +2366,7 @@ Status XvMCPutSurface(Display *display,XvMCSurface *surface,
     i915XvMCSubpicture *pI915SubPic;
     I915XvMCCommandBuffer buf;
 
-    drawableInfo *drawInfo;
+    // drawableInfo *drawInfo;
     Status ret;
 
     if (!display || !surface)
@@ -2304,13 +2379,14 @@ Status XvMCPutSurface(Display *display,XvMCSurface *surface,
         return (error_base + XvMCBadSurface);
 
     pthread_mutex_lock(&pI915XvMC->ctxmutex);
+    /*
     if (getDRIDrawableInfoLocked(pI915XvMC->drawHash, display,
                                  pI915XvMC->screen, draw, 0, pI915XvMC->fd, pI915XvMC->hHWContext,
                                  pI915XvMC->sarea_address, FALSE, &drawInfo, sizeof(*drawInfo))) {
         pthread_mutex_unlock(&pI915XvMC->ctxmutex);
         return BadAccess;
     }
-    
+    */
     if (!pI915XvMC->haveXv) {
         pI915XvMC->xvImage =
             XvCreateImage(display, pI915XvMC->port, FOURCC_XVMC,
@@ -2519,11 +2595,12 @@ Status XvMCCreateSubpicture(Display *display, XvMCContext *context,
                             unsigned short width, unsigned short height,
                             int xvimage_id) 
 {
+    Status ret;
     i915XvMCContext *pI915XvMC;
     i915XvMCSubpicture *pI915Subpicture;
+    I915XvMCCreateSurfaceRec *tmpComm = NULL;
     int priv_count;
     uint *priv_data;
-    Status ret;
 
     if (!subpicture || !context || !display)
         return BadValue;
@@ -2539,7 +2616,6 @@ Status XvMCCreateSubpicture(Display *display, XvMCContext *context,
     if (!subpicture->privData)
         return BadAlloc;
 
-
     subpicture->context_id = context->context_id;
     subpicture->xvimage_id = xvimage_id;
     subpicture->width = width;
@@ -2553,16 +2629,34 @@ Status XvMCCreateSubpicture(Display *display, XvMCContext *context,
         return ret;
     }
 
-    if (priv_count != 2) {
-        printf("_xvmc_create_subpicture() returned incorrect data size.\n");
-        printf("Expected 2 got %d\n",priv_count);
+    if (priv_count != (sizeof(I915XvMCCreateSurfaceRec) >> 2)) {
+        printf("_xvmc_create_subpicture() returned incorrect data size!\n");
+        printf("\tExpected %d, got %d\n", 
+               (int)(sizeof(I915XvMCCreateSurfaceRec) >> 2), priv_count);
+        _xvmc_destroy_subpicture(display, subpicture);
         free(priv_data);
         free(pI915Subpicture);
         subpicture->privData = NULL;
         return BadAlloc;
     }
 
+    tmpComm = (I915XvMCCreateSurfaceRec *)priv_data;
+    pI915Subpicture->srfNo = tmpComm->srfno;
+    pI915Subpicture->srf.handle = tmpComm->srf.handle;
+    pI915Subpicture->srf.offset = tmpComm->srf.offset;
+    pI915Subpicture->srf.size = tmpComm->srf.size;
     free(priv_data);
+
+    if (drmMap(pI915XvMC->fd,
+               pI915Subpicture->srf.handle,
+               pI915Subpicture->srf.size,
+               (drmAddress *)&pI915Subpicture->srf.map) != 0) {
+        _xvmc_destroy_subpicture(display, subpicture);
+        free(pI915Subpicture);
+        subpicture->privData = NULL;
+        return BadAlloc;
+    }
+
     /* subpicture */
     subpicture->num_palette_entries = I915_SUBPIC_PALETTE_SIZE;
     subpicture->entry_bytes = 3;
@@ -2572,9 +2666,7 @@ Status XvMCCreateSubpicture(Display *display, XvMCContext *context,
     pI915Subpicture->privContext = pI915XvMC;
     pI915Subpicture->last_render= 0;
     pI915Subpicture->last_flip = 0;
-    pI915Subpicture->srfNo = priv_data[0];
-    pI915Subpicture->offset = priv_data[1];
-    pI915Subpicture->pitch = ((subpicture->width + 31) & ~31);
+    pI915Subpicture->pitch = ((subpicture->width + 3) & ~3);
 
     switch(subpicture->xvimage_id) {
     case FOURCC_IA44:
diff --git a/src/xvmc/I915XvMC.h b/src/xvmc/I915XvMC.h
index 0817083..1260084 100644
--- a/src/xvmc/I915XvMC.h
+++ b/src/xvmc/I915XvMC.h
@@ -59,6 +59,7 @@ typedef struct _i915XvMCContext {
     unsigned last_flip;
     unsigned dual_prime; /* Flag to identify when dual prime is in use. */
     unsigned yStride;
+    unsigned uvStride;
     unsigned short ref;
     pthread_mutex_t ctxmutex;
     char busIdString[21]; /* PCI:0:1:0 or PCI:0:2:0 */
@@ -123,9 +124,9 @@ typedef struct _i915XvMCSubpicture {
     unsigned srfNo;
     unsigned last_render;
     unsigned last_flip;
-    unsigned offset;
     unsigned pitch;
     unsigned char palette[3][16];
+    i915XvMCDrmMap srf;
     i915XvMCContext *privContext;
 } i915XvMCSubpicture;
 
@@ -137,14 +138,13 @@ typedef struct _i915XvMCSubpicture {
 #define I830_MAX_BUFS 2                   /*Number of YUV buffers per surface */
 typedef struct _i915XvMCSurface {
     unsigned srfNo;                    /* XvMC private surface numbers */
-    unsigned num_buffers;              /* Number of picture buffers */
-    unsigned curbuf;                   /* Which is the current buffer? */
-    unsigned offsets[I830_MAX_BUFS];    /* Offsets of picture buffers */
     unsigned last_render;
     unsigned last_flip;
     unsigned yStride;                  /* Stride of YUV420 Y component. */
+    unsigned uvStride;
     unsigned width;                    /* Dimensions */
     unsigned height;
+    i915XvMCDrmMap srf;
     i915XvMCContext *privContext;
     i915XvMCSubpicture *privSubPic;     /* Subpicture to be blended when
                                          * displaying. NULL if none. */
diff --git a/src/xvmc/i915_structs.h b/src/xvmc/i915_structs.h
index c9545af..cd842a8 100644
--- a/src/xvmc/i915_structs.h
+++ b/src/xvmc/i915_structs.h
@@ -55,7 +55,7 @@ struct i915_3dmpeg_macroblock_header
     } dw0;
     
     struct {
-        unsigned intra : 1;
+        unsigned mb_intra : 1;
         unsigned forward : 1;
         unsigned backward : 1;
         unsigned h263_4mv : 1;
@@ -274,7 +274,7 @@ struct i915_3dstate_dest_buffer_variables_mpeg
         unsigned pad2 : 4;
         unsigned bidir_avrg_control : 1;
         unsigned rcontrol : 1;
-        unsigned decoder_mode : 2;
+        unsigned decode_mode : 2;
     } dw1;
         
     struct {
commit ccac60bf035bb54661c13f306031def81e105a32
Author: Xiang, Haihao <haihao.xiang at intel.com>
Date:   Mon Jun 25 10:23:28 2007 +0800

    fix some bugs

diff --git a/src/i830_video.c b/src/i830_video.c
index 4f5ab43..9d9511e 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -580,7 +580,7 @@ I830InitVideo(ScreenPtr pScreen)
 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Set up textured video\n");
 
 #ifdef XF86DRI
-            if (pI830->XvMCEnabled && IS_I9XX(pI830))
+            if (/* pI830->XvMCEnabled && */IS_I9XX(pI830))
                I915XvMCInitXv(pScrn, texturedAdaptor);
 #endif
 	} else {
diff --git a/src/i915_hwmc.c b/src/i915_hwmc.c
index 119b908..ed4fe6c 100644
--- a/src/i915_hwmc.c
+++ b/src/i915_hwmc.c
@@ -197,9 +197,11 @@ static unsigned int stride(int w)
 
 static unsigned long size_yuv420(int w, int h)
 {
-    unsigned yPitch = stride(w);
+    unsigned cpp = 4;
+    unsigned yPitch = stride(w) * cpp;
+    unsigned uvPitch = stride(w / 2) * cpp;
 
-    return h * (yPitch + (yPitch >> 1));
+    return h * (yPitch + uvPitch);
 }
 
 static unsigned long size_xx44(int w, int h)
@@ -859,6 +861,7 @@ void I915InitMC(ScreenPtr pScreen)
     I915XvMCPtr pXvMC = NULL; 
 
     pI830->XvMCEnabled = FALSE;
+    return;
     if (!pI830->directRenderingEnabled) {
         xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
                    "[XvMC] Cannot use XvMC without DRI!\n");
@@ -885,6 +888,14 @@ int I915XvMCInitXv(ScrnInfoPtr pScrn, XF86VideoAdaptorPtr XvAdapt)
     I830PortPrivPtr pPriv;
     I915XvMCXVPriv *vx;
     unsigned i, j;
+    SetPortAttributeFuncPtr setportattribute = XvAdapt->SetPortAttribute;
+    GetPortAttributeFuncPtr getportattribute = XvAdapt->GetPortAttribute;
+    PutImageFuncPtr putimage = XvAdapt->PutImage;
+
+    return Success;
+    XvAdapt->GetPortAttribute = I915XvMCInterceptXvGetAttribute;
+    XvAdapt->SetPortAttribute = I915XvMCInterceptXvAttribute;
+    XvAdapt->PutImage = I915XvMCInterceptPutImage;
 
     for (j = 0; j < XvAdapt->nPorts; ++j) {
         pPriv = (I830PortPrivPtr) XvAdapt->pPortPrivates[j].ptr;
@@ -905,13 +916,9 @@ int I915XvMCInitXv(ScrnInfoPtr pScrn, XF86VideoAdaptorPtr XvAdapt)
         vx->newAttribute = 1;
 
         /* set up wrappers */
-        vx->GetPortAttribute = XvAdapt->GetPortAttribute;
-        vx->SetPortAttribute = XvAdapt->SetPortAttribute;
-        vx->PutImage = XvAdapt->PutImage;
-
-        XvAdapt->GetPortAttribute = I915XvMCInterceptXvGetAttribute;
-        XvAdapt->SetPortAttribute = I915XvMCInterceptXvAttribute;
-        XvAdapt->PutImage = I915XvMCInterceptPutImage;
+        vx->GetPortAttribute = setportattribute;
+        vx->SetPortAttribute = getportattribute;
+        vx->PutImage = putimage;
 
         for (i = 0; i < I915_NUM_XVMC_ATTRIBUTES; ++i) {
             vx->xvAttr.attributes[i].attribute = attrAtoms[i];
diff --git a/src/xvmc/I915XvMC.c b/src/xvmc/I915XvMC.c
index 685eea4..c51f89b 100644
--- a/src/xvmc/I915XvMC.c
+++ b/src/xvmc/I915XvMC.c
@@ -26,12 +26,14 @@
 #include "xf86dri.h"
 #include "driDrawable.h"
 
+#define _STATIC_
+
 #define SAREAPTR(ctx) ((drmI830Sarea *)                     \
                        (((CARD8 *)(ctx)->sarea_address) +   \
                         (ctx)->sarea_priv_offset))
 
 /* Lookup tables to speed common calculations */
-static unsigned mb_bytes[] = {
+_STATIC_ unsigned mb_bytes[] = {
     000, 128, 128, 256, 128, 256, 256, 384,  // 0
     128, 256, 256, 384, 256, 384, 384, 512,  // 1
     128, 256, 256, 384, 256, 384, 384, 512,  // 10
@@ -47,11 +49,11 @@ typedef union {
     uint  u[2];
 } su_t;
 
-static char I915KernelDriverName[] = "i915";
-static int error_base;
-static int event_base;
+_STATIC_ char I915KernelDriverName[] = "i915";
+_STATIC_ int error_base;
+_STATIC_ int event_base;
 
-static int findOverlap(unsigned width, unsigned height,
+_STATIC_ int findOverlap(unsigned width, unsigned height,
                        short *dstX, short *dstY,
                        short *srcX, short *srcY, 
                        unsigned short *areaW, unsigned short *areaH)
@@ -87,7 +89,7 @@ static int findOverlap(unsigned width, unsigned height,
     return 0;
 }
 
-static void setupAttribDesc(Display * display, XvPortID port,
+_STATIC_ void setupAttribDesc(Display * display, XvPortID port,
                             const I915XvMCAttrHolder * attrib, XvAttribute attribDesc[])
 {  
     XvAttribute *XvAttribs, *curAD;
@@ -116,7 +118,7 @@ static void setupAttribDesc(Display * display, XvPortID port,
     XUnlockDisplay(display);
 }
 
-static void releaseAttribDesc(int numAttr, XvAttribute attribDesc[])
+_STATIC_ void releaseAttribDesc(int numAttr, XvAttribute attribDesc[])
 {
     int i;
 
@@ -126,20 +128,20 @@ static void releaseAttribDesc(int numAttr, XvAttribute attribDesc[])
     }
 }
 
-static __inline__ void renderError(void) 
+_STATIC_ __inline__ void renderError(void) 
 {
     printf("Invalid Macroblock Parameters found.\n");
     return;
 }
 
-static void I915XvMCContendedLock(i915XvMCContext *pI915XvMC, unsigned flags)
+_STATIC_ void I915XvMCContendedLock(i915XvMCContext *pI915XvMC, unsigned flags)
 {
     drmGetLock(pI915XvMC->fd, pI915XvMC->hHWContext, flags);
 }
 
 /* Lock the hardware and validate our state.
  */
-static void LOCK_HARDWARE(i915XvMCContext  *pI915XvMC)
+_STATIC_ void LOCK_HARDWARE(i915XvMCContext  *pI915XvMC)
 {
     char __ret = 0;
     pthread_mutex_lock(&pI915XvMC->ctxmutex);
@@ -156,7 +158,7 @@ static void LOCK_HARDWARE(i915XvMCContext  *pI915XvMC)
 
 /* Unlock the hardware using the global current context
  */
-static void UNLOCK_HARDWARE(i915XvMCContext *pI915XvMC)
+_STATIC_ void UNLOCK_HARDWARE(i915XvMCContext *pI915XvMC)
 {
     pI915XvMC->locked = 0;
     DRM_UNLOCK(pI915XvMC->fd, pI915XvMC->driHwLock, 
@@ -164,24 +166,61 @@ static void UNLOCK_HARDWARE(i915XvMCContext *pI915XvMC)
     pthread_mutex_unlock(&pI915XvMC->ctxmutex);
 }
 
-static unsigned stride(int w)
+_STATIC_ unsigned stride(int w)
 {
     return (w + 31) & ~31;
 }
 
-static unsigned long size_y(int w, int h)
+_STATIC_ unsigned long size_y(int w, int h)
+{
+    unsigned cpp = 4;
+
+    return h * stride(w) * cpp;
+}
+
+_STATIC_ unsigned long size_uv(int w, int h)
 {
-    return stride(w) * h;
+    unsigned cpp = 4;
+
+    return h / 2 * stride(w / 2) * cpp;
 }
 
-static unsigned long size_yuv420(int w, int h)
+_STATIC_ unsigned long size_yuv420(int w, int h)
 {
-    unsigned yPitch = stride(w);
+    unsigned cpp = 4;
+    unsigned yPitch = stride(w) * cpp;
+    unsigned uvPitch = stride(w / 2) * cpp;
 
-    return h * (yPitch + (yPitch >> 1));
+    return h * (yPitch + uvPitch);
 }
 
-static void i915_flush(i915XvMCContext *pI915XvMC)
+_STATIC_ void i915_flush_with_flush_bit_clear(i915XvMCContext *pI915XvMC)
+{
+    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 = 1;
+    mi_flush.dw0.render_cache_flush_inhibit = 0;
+
+    intelBatchbufferData(pI915XvMC, &mi_flush, sizeof(mi_flush), 0);
+}
+
+_STATIC_ void i915_flush(i915XvMCContext *pI915XvMC)
+{
+    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 = 1;
+    mi_flush.dw0.render_cache_flush_inhibit = 1;
+
+    intelBatchbufferData(pI915XvMC, &mi_flush, sizeof(mi_flush), 0);
+}
+
+_STATIC_ void __i915_flush(i915XvMCContext *pI915XvMC)
 {
     struct i915_mi_flush mi_flush;
     unsigned cmd[2];
@@ -198,7 +237,7 @@ static void i915_flush(i915XvMCContext *pI915XvMC)
 }
 
 /* for MC picture rendering */
-static void i915_mc_static_indirect_state_buffer(XvMCContext *context, 
+_STATIC_ void i915_mc_static_indirect_state_buffer(XvMCContext *context, 
                                                  XvMCSurface *surface,
                                                  unsigned int picture_coding_type)
 {
@@ -208,8 +247,10 @@ static void i915_mc_static_indirect_state_buffer(XvMCContext *context,
     i915XvMCSurface *pI915Surface = (i915XvMCSurface *)surface->privData;
     i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
     unsigned w = surface->width, h = surface->height;
+    unsigned cpp = 4;
 
     /* 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;
@@ -223,6 +264,7 @@ static void i915_mc_static_indirect_state_buffer(XvMCContext *context,
     buffer_info->dw1.pitch = stride(w);
     buffer_info->dw2.base_address = pI915Surface->offsets[pI915Surface->curbuf];
 
+    /* DEST U */
     ++buffer_info;
     memset(buffer_info, 0, sizeof(*buffer_info));
     buffer_info->dw0.type = CMD_3D;
@@ -233,10 +275,11 @@ static void i915_mc_static_indirect_state_buffer(XvMCContext *context,
     buffer_info->dw1.fence_regs = 0;
     buffer_info->dw1.tiled_surface = 0;
     buffer_info->dw1.walk = TILEWALK_XMAJOR; 
-    buffer_info->dw1.pitch = stride(w) >> 1;
+    buffer_info->dw1.pitch = stride(w / 2);
     buffer_info->dw2.base_address = pI915Surface->offsets[pI915Surface->curbuf] 
         + size_y(w, h);
 
+    /* DEST V */
     ++buffer_info;
     memset(buffer_info, 0, sizeof(*buffer_info));
     buffer_info->dw0.type = CMD_3D;
@@ -247,9 +290,9 @@ static void i915_mc_static_indirect_state_buffer(XvMCContext *context,
     buffer_info->dw1.fence_regs = 0;
     buffer_info->dw1.tiled_surface = 0;
     buffer_info->dw1.walk = TILEWALK_XMAJOR; 
-    buffer_info->dw1.pitch = stride(w) >> 1;
+    buffer_info->dw1.pitch = stride(w / 2);
     buffer_info->dw2.base_address = pI915Surface->offsets[pI915Surface->curbuf] 
-        + size_y(w, h) + (size_y(w, h) >> 2);
+        + size_y(w, h) + size_uv(w, h);
 
     /* 3DSTATE_DEST_BUFFER_VARIABLES */
     dest_buffer_variables = (struct i915_3dstate_dest_buffer_variables *)(++buffer_info);
@@ -257,6 +300,8 @@ static void i915_mc_static_indirect_state_buffer(XvMCContext *context,
     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.v_ls = 0;         /* FIXME */
     dest_buffer_variables->dw1.v_ls_offset = 0;
 
@@ -269,12 +314,13 @@ static void i915_mc_static_indirect_state_buffer(XvMCContext *context,
     dest_buffer_variables_mpeg->dw1.decoder_mode = MPEG_DECODE_MC;
     dest_buffer_variables_mpeg->dw1.rcontrol = 0;       /* for MPEG-2/MPEG-1 */
     dest_buffer_variables_mpeg->dw1.bidir_avrg_control = 0; 
-    dest_buffer_variables_mpeg->dw1.intra8 = 0;         /* FIXME ? */
+    dest_buffer_variables_mpeg->dw1.intra8 = 0;         /* 16-bit formatted correction data */
     dest_buffer_variables_mpeg->dw1.tff = 0;            /* FIXME */
     dest_buffer_variables_mpeg->dw1.picture_width = w >> 4;
     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;
@@ -282,7 +328,6 @@ static void i915_mc_static_indirect_state_buffer(XvMCContext *context,
     buffer_info->dw0.length = 1;
     buffer_info->dw1.aux_id = 0;
     buffer_info->dw1.buffer_id = BUFFERID_MC_INTRA_CORR;
-    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; 
@@ -291,7 +336,7 @@ static void i915_mc_static_indirect_state_buffer(XvMCContext *context,
     buffer_info->dw2.base_address = pI915XvMC->corrdata.offset;
 }
 
-static void i915_mc_map_state_buffer(XvMCContext *context, 
+_STATIC_ void i915_mc_map_state_buffer(XvMCContext *context, 
                                      XvMCSurface *target_surface,
                                      XvMCSurface *past_surface,
                                      XvMCSurface *future_surface)
@@ -320,7 +365,7 @@ static void i915_mc_map_state_buffer(XvMCContext *context,
 
     /* B Frame Test */
     if (!future_surface) {
-        privFuture = privPast;
+        privFuture = privTarget;
     } else {
         if (!future_surface->privData || !past_surface) {
             printf("Error, Invalid Future Surface or No Past Surface!\n");
@@ -340,7 +385,7 @@ static void i915_mc_map_state_buffer(XvMCContext *context,
     map_state->dw0.length = 6;
     map_state->dw1.map_mask = MAP_MAP0 | MAP_MAP1;
 
-    /* texture map: Forward */
+    /* texture map: Forward (Past) */
     tm = (struct texture_map *)(++map_state);
     memset(tm, 0, sizeof(*tm));
     tm->tm0.v_ls_offset = 0;
@@ -351,14 +396,14 @@ static void i915_mc_map_state_buffer(XvMCContext *context,
     tm->tm1.utilize_fence_regs = 0;
     tm->tm1.texel_fmt = 0;
     tm->tm1.surface_fmt = 1;
-    tm->tm1.width = w;
-    tm->tm1.height = h;
+    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 = stride(w);
+    tm->tm2.pitch = stride(w) - 1;
 
-    /* texture map: Backward */
+    /* texture map: Backward (Future) */
     ++tm;
     memset(tm, 0, sizeof(*tm));
     tm->tm0.v_ls_offset = 0;
@@ -369,12 +414,12 @@ static void i915_mc_map_state_buffer(XvMCContext *context,
     tm->tm1.utilize_fence_regs = 0;
     tm->tm1.texel_fmt = 0;
     tm->tm1.surface_fmt = 1;
-    tm->tm1.width = w;
-    tm->tm1.height = h;
+    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 = stride(w);
+    tm->tm2.pitch = stride(w) - 1;
 
     /* 3DSATE_MAP_STATE: U*/
     map_state = (struct i915_3dstate_map_state *)(++tm);
@@ -396,12 +441,12 @@ static void i915_mc_map_state_buffer(XvMCContext *context,
     tm->tm1.utilize_fence_regs = 0;
     tm->tm1.texel_fmt = 0;
     tm->tm1.surface_fmt = 1;
-    tm->tm1.width = w >> 1;
-    tm->tm1.height = h >> 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 = stride(w) >> 1;
+    tm->tm2.pitch = stride(w / 2) - 1;
 
     /* texture map: Backward */
     ++tm;
@@ -414,12 +459,12 @@ static void i915_mc_map_state_buffer(XvMCContext *context,
     tm->tm1.utilize_fence_regs = 0;
     tm->tm1.texel_fmt = 0;
     tm->tm1.surface_fmt = 1;
-    tm->tm1.width = w >> 1;
-    tm->tm1.height = h >> 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 = stride(w) >> 1;
+    tm->tm2.pitch = stride(w / 2) - 1;
 
     /* 3DSATE_MAP_STATE: V */
     map_state = (struct i915_3dstate_map_state *)(++tm);
@@ -435,39 +480,39 @@ static void i915_mc_map_state_buffer(XvMCContext *context,
     memset(tm, 0, sizeof(*tm));
     tm->tm0.v_ls_offset = 0;
     tm->tm0.v_ls = 0;
-    tm->tm0.base_address = privPast->offsets[privPast->curbuf] + size_y(w, h) + (size_y(w, h) >> 2);
+    tm->tm0.base_address = privPast->offsets[privPast->curbuf] + size_y(w, h) + size_uv(w, h);
     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;
-    tm->tm1.height = h >> 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 = stride(w) >> 1;
+    tm->tm2.pitch = stride(w / 2) - 1;
 
     /* texture map: Backward */
     ++tm;
     memset(tm, 0, sizeof(*tm));
     tm->tm0.v_ls_offset = 0;
     tm->tm0.v_ls = 0;
-    tm->tm0.base_address = privFuture->offsets[privFuture->curbuf] + size_y(w, h) + (size_y(w, h) >> 2);
+    tm->tm0.base_address = privFuture->offsets[privFuture->curbuf] + size_y(w, h) + size_uv(w, h);
     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;
-    tm->tm1.height = h >> 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 = stride(w) >> 1;
+    tm->tm2.pitch = stride(w / 2) - 1;
 }
 
-static void i915_mc_load_indirect_buffer(XvMCContext *context)
+_STATIC_ void i915_mc_load_indirect_buffer(XvMCContext *context)
 {
     struct i915_3dstate_load_indirect *load_indirect;
     sis_state *sis = NULL;
@@ -476,12 +521,15 @@ static void i915_mc_load_indirect_buffer(XvMCContext *context)
     void *base = NULL;
     unsigned size;
 
+    i915_flush_with_flush_bit_clear(pI915XvMC);
+
     /* 3DSTATE_LOAD_INDIRECT */
     size = sizeof(*load_indirect) + sizeof(*sis) + sizeof(*msb);
     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.mem_select = 1;  /* Bearlake only */
     load_indirect->dw0.block_mask = BLOCK_SIS | BLOCK_MSB;
     load_indirect->dw0.length = 3;
 
@@ -501,7 +549,7 @@ static void i915_mc_load_indirect_buffer(XvMCContext *context)
     free(base);
 }
 
-static void i915_mc_mpeg_set_origin(XvMCContext *context, XvMCMacroBlock *mb)
+_STATIC_ void i915_mc_mpeg_set_origin(XvMCContext *context, XvMCMacroBlock *mb)
 {
     struct i915_3dmpeg_set_origin set_origin;
     i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
@@ -517,7 +565,7 @@ static void i915_mc_mpeg_set_origin(XvMCContext *context, XvMCMacroBlock *mb)
     intelBatchbufferData(pI915XvMC, &set_origin, sizeof(set_origin), 0);
 }
 
-static void i915_mc_mpeg_macroblock_0mv(XvMCContext *context, XvMCMacroBlock *mb)
+_STATIC_ void i915_mc_mpeg_macroblock_0mv(XvMCContext *context, XvMCMacroBlock *mb)
 {
     struct i915_3dmpeg_macroblock_0mv macroblock_0mv;
     i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
@@ -527,24 +575,24 @@ static void i915_mc_mpeg_macroblock_0mv(XvMCContext *context, XvMCMacroBlock *mb
     macroblock_0mv.header.dw0.type = CMD_3D;
     macroblock_0mv.header.dw0.opcode = OPC_3DMPEG_MACROBLOCK;
     macroblock_0mv.header.dw0.length = 0;
-    macroblock_0mv.header.dw1.intra = (mb->macroblock_type & XVMC_MB_TYPE_INTRA);
+    macroblock_0mv.header.dw1.intra = 1;        /* should be 1 */ 
     macroblock_0mv.header.dw1.forward = 0;      /* should be 0 */
     macroblock_0mv.header.dw1.backward = 0;     /* should be 0 */
     macroblock_0mv.header.dw1.h263_4mv = 0;     /* should be 0 */
     macroblock_0mv.header.dw1.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD);
     
-    if (!mb->coded_block_pattern)       /* FIXME */
+    if (!mb->coded_block_pattern)
         macroblock_0mv.header.dw1.dct_type = XVMC_DCT_TYPE_FRAME;
 
-    macroblock_0mv.header.dw1.motion_type = mb->motion_type;
-    macroblock_0mv.header.dw1.vertical_field_select = mb->motion_vertical_field_select;
-    macroblock_0mv.header.dw1.coded_block_pattern = mb->coded_block_pattern; /* FIXME */
-    macroblock_0mv.header.dw1.skipped_macroblocks = 0;      /* FIXME */
+    macroblock_0mv.header.dw1.motion_type = 0; // (mb->motion_type & 0x3)
+    macroblock_0mv.header.dw1.vertical_field_select = 0; // mb->motion_vertical_field_select & 0xf;
+    macroblock_0mv.header.dw1.coded_block_pattern = mb->coded_block_pattern;
+    macroblock_0mv.header.dw1.skipped_macroblocks = 0;
     
     intelBatchbufferData(pI915XvMC, &macroblock_0mv, sizeof(macroblock_0mv), 0);
 }
 
-static void i915_mc_mpeg_macroblock_1fbmv(XvMCContext *context, XvMCMacroBlock *mb)
+_STATIC_ void i915_mc_mpeg_macroblock_1fbmv(XvMCContext *context, XvMCMacroBlock *mb)
 {
     struct i915_3dmpeg_macroblock_1fbmv macroblock_1fbmv;
     i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
@@ -583,7 +631,7 @@ static void i915_mc_mpeg_macroblock_1fbmv(XvMCContext *context, XvMCMacroBlock *
     intelBatchbufferData(pI915XvMC, &macroblock_1fbmv, sizeof(macroblock_1fbmv), 0);
 }
 
-static void i915_mc_mpeg_macroblock_2fbmv(XvMCContext *context, XvMCMacroBlock *mb)
+_STATIC_ void i915_mc_mpeg_macroblock_2fbmv(XvMCContext *context, XvMCMacroBlock *mb)
 {
     struct i915_3dmpeg_macroblock_2fbmv macroblock_2fbmv;
     i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
@@ -629,7 +677,7 @@ static void i915_mc_mpeg_macroblock_2fbmv(XvMCContext *context, XvMCMacroBlock *
 }
 
 /* for MC context initialization */
-static void i915_mc_sampler_state_buffer(XvMCContext *context)
+_STATIC_ void i915_mc_sampler_state_buffer(XvMCContext *context)
 {
     struct i915_3dstate_sampler_state *sampler_state;
     struct texture_sampler *ts;
@@ -654,11 +702,11 @@ static void i915_mc_sampler_state_buffer(XvMCContext *context)
     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;
+    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;        /* Maximum Mip Level */
+    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;
@@ -681,11 +729,11 @@ static void i915_mc_sampler_state_buffer(XvMCContext *context)
     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;
+    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;        /* Maximum Mip Level */
+    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;
@@ -693,12 +741,12 @@ static void i915_mc_sampler_state_buffer(XvMCContext *context)
     ts->ts1.tcy_control = TEXCOORDMODE_CLAMP;
     ts->ts1.tcz_control = TEXCOORDMODE_CLAMP;
     ts->ts1.normalized_coor = 0;
-    ts->ts1.map_index = 0;
+    ts->ts1.map_index = 1;
     ts->ts1.east_deinterlacer = 0;
     ts->ts2.default_color = 0;
 }
 
-static void i915_inst_arith(unsigned *inst,
+_STATIC_ void i915_inst_arith(unsigned *inst,
                             unsigned op,
                             unsigned dest,
                             unsigned mask,
@@ -711,7 +759,7 @@ static void i915_inst_arith(unsigned *inst,
     *(inst++) = (A2_SRC1(src1) | A2_SRC2(src2));
 }
 
-static void i915_inst_decl(unsigned *inst, 
+_STATIC_ void i915_inst_decl(unsigned *inst, 
                            unsigned type,
                            unsigned nr,
                            unsigned d0_flags)
@@ -723,19 +771,19 @@ static void i915_inst_decl(unsigned *inst,
     *(inst++) = D2_MBZ;
 }
 
-static void i915_inst_texld(unsigned *inst,
-                            unsigned op,
-                            unsigned dest,
-                            unsigned sampler,
-                            unsigned coord)
+_STATIC_ void i915_inst_texld(unsigned *inst,
+                              unsigned op,
+                              unsigned dest,
+                              unsigned coord,
+                              unsigned sampler)
 {
-    dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest));
-    *(inst++) = (op | T0_DEST(dest) | T0_SAMPLER(sampler));
-    *(inst++) = T1_ADDRESS_REG(coord);
-    *(inst++) = T2_MBZ;
+   dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest));
+   *(inst++) = (op | T0_DEST(dest) | T0_SAMPLER(sampler));
+   *(inst++) = T1_ADDRESS_REG(coord);
+   *(inst++) = T2_MBZ;
 }
 
-static void i915_mc_pixel_shader_program_buffer(XvMCContext *context)
+_STATIC_ void i915_mc_pixel_shader_program_buffer(XvMCContext *context)
 {
     struct i915_3dstate_pixel_shader_program *pixel_shader_program;
     i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
@@ -749,6 +797,7 @@ static void i915_mc_pixel_shader_program_buffer(XvMCContext *context)
     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 *)(++pixel_shader_program);
     dest = UREG(REG_TYPE_OC, 0);
     src0 = UREG(REG_TYPE_CONST, 0);
@@ -765,20 +814,25 @@ static void i915_mc_pixel_shader_program_buffer(XvMCContext *context)
     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 *)(++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_S, 0); /* SAMPLER */
-    src1 = UREG(REG_TYPE_T, 0); /* COORD */
+    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_S, 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);
@@ -791,20 +845,25 @@ static void i915_mc_pixel_shader_program_buffer(XvMCContext *context)
     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 *)(++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_S, 1); /* SAMPLER */
-    src1 = UREG(REG_TYPE_T, 2); /* COORD */
+    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_S, 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);
@@ -817,28 +876,37 @@ static void i915_mc_pixel_shader_program_buffer(XvMCContext *context)
     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 *)(++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_S, 0); /* SAMPLER */
-    src1 = UREG(REG_TYPE_T, 0); /* COORD */
+    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_S, 1); /* SAMPLER */
-    src1 = UREG(REG_TYPE_T, 2); /* COORD */
+    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);
@@ -846,17 +914,18 @@ static void i915_mc_pixel_shader_program_buffer(XvMCContext *context)
     src2 = 0;
     i915_inst_arith(inst, A0_ADD, dest, A0_DEST_CHANNEL_ALL,
                     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_OC, 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)
+_STATIC_ void i915_mc_pixel_shader_constants_buffer(XvMCContext *context)
 {
     struct i915_3dstate_pixel_shader_constants *pixel_shader_constants;
     i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
@@ -875,7 +944,7 @@ static void i915_mc_pixel_shader_constants_buffer(XvMCContext *context)
     *(value++) = 0.5;
 }
 
-static void i915_mc_one_time_state_initialization(XvMCContext *context)
+_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;
@@ -926,12 +995,16 @@ static void i915_mc_one_time_state_initialization(XvMCContext *context)
     intelBatchbufferData(pI915XvMC, base, size, 0);
     free(base);
 
+    /* flush */
+    i915_flush_with_flush_bit_clear(pI915XvMC);
+
     /* 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.mem_select = 1;      /* Bearlake only */
     load_indirect->dw0.block_mask = BLOCK_DIS | BLOCK_SSB | BLOCK_PSP | BLOCK_PSC;
     load_indirect->dw0.length = 6;
 
@@ -945,72 +1018,72 @@ static void i915_mc_one_time_state_initialization(XvMCContext *context)
     ssb = (ssb_state *)(++dis);
     ssb->dw0.valid = 1;
     ssb->dw0.buffer_address = pI915XvMC->ssb.offset;
-    ssb->dw1.length = 8;
+    ssb->dw1.length = 7; /* 8 - 1 */
 
     /* PSP */
     psp = (psp_state *)(++ssb);
     psp->dw0.valid = 1;
     psp->dw0.buffer_address = pI915XvMC->psp.offset;
-    psp->dw1.length = 67; // 4 + 16 + 16 + 31
+    psp->dw1.length = 66; /* 4 + 16 + 16 + 31 - 1 */
     
     /* PSC */
     psc = (psc_state *)(++psp);
     psc->dw0.valid = 1;
     psc->dw0.buffer_address = pI915XvMC->psc.offset;
-    psc->dw1.length = 6;
+    psc->dw1.length = 5; /* 6 - 1 */
 
     intelBatchbufferData(pI915XvMC, base, size, 0);
     free(base);
 }
 
-static int i915_xvmc_map_buffers(i915XvMCContext *pI915XvMC)
+_STATIC_ int i915_xvmc_map_buffers(i915XvMCContext *pI915XvMC)
 {
     if (drmMap(pI915XvMC->fd,
                pI915XvMC->sis.handle,
                pI915XvMC->sis.size,
-               (drmAddress *)pI915XvMC->sis.map) != 0) {
+               (drmAddress *)&pI915XvMC->sis.map) != 0) {
         return -1;
     }
 
     if (drmMap(pI915XvMC->fd,
                pI915XvMC->msb.handle,
                pI915XvMC->msb.size,
-               (drmAddress *)pI915XvMC->msb.map) != 0) {
+               (drmAddress *)&pI915XvMC->msb.map) != 0) {
         return -1;
     }
 
     if (drmMap(pI915XvMC->fd,
                pI915XvMC->ssb.handle,
                pI915XvMC->ssb.size,
-               (drmAddress *)pI915XvMC->ssb.map) != 0) {
+               (drmAddress *)&pI915XvMC->ssb.map) != 0) {
         return -1;
     }
 
     if (drmMap(pI915XvMC->fd,
                pI915XvMC->psp.handle,
                pI915XvMC->psp.size,
-               (drmAddress *)pI915XvMC->psp.map) != 0) {
+               (drmAddress *)&pI915XvMC->psp.map) != 0) {
         return -1;
     }
 
     if (drmMap(pI915XvMC->fd,
                pI915XvMC->psc.handle,
                pI915XvMC->psc.size,
-               (drmAddress *)pI915XvMC->psc.map) != 0) {
+               (drmAddress *)&pI915XvMC->psc.map) != 0) {
         return -1;
     }
 
     if (drmMap(pI915XvMC->fd,
                pI915XvMC->corrdata.handle,
                pI915XvMC->corrdata.size,
-               (drmAddress *)pI915XvMC->corrdata.map) != 0) {
+               (drmAddress *)&pI915XvMC->corrdata.map) != 0) {
         return -1;
     }
 
     return 0;
 }
 
-static void i915_xvmc_unmap_buffers(i915XvMCContext *pI915XvMC)
+_STATIC_ void i915_xvmc_unmap_buffers(i915XvMCContext *pI915XvMC)
 {
     if (pI915XvMC->sis.map) {
         drmUnmap(pI915XvMC->sis.map, pI915XvMC->sis.size);
@@ -1046,7 +1119,7 @@ static void i915_xvmc_unmap_buffers(i915XvMCContext *pI915XvMC)
 /*
  * Video post processing 
  */
-static void i915_yuv2rgb_map_state_buffer(XvMCSurface *target_surface)
+_STATIC_ void i915_yuv2rgb_map_state_buffer(XvMCSurface *target_surface)
 {
     struct i915_3dstate_map_state *map_state;
     struct texture_map *tm;
@@ -1120,7 +1193,7 @@ static void i915_yuv2rgb_map_state_buffer(XvMCSurface *target_surface)
     tm->tm2.pitch = (stride(w) >> 1) - 1;
 }
 
-static void i915_yuv2rgb_sampler_state_buffer(XvMCSurface *surface)
+_STATIC_ void i915_yuv2rgb_sampler_state_buffer(XvMCSurface *surface)
 {
     struct i915_3dstate_sampler_state *sampler_state;
     struct texture_sampler *ts;
@@ -1185,7 +1258,7 @@ static void i915_yuv2rgb_sampler_state_buffer(XvMCSurface *surface)
     ts->ts1.tcy_control = TEXCOORDMODE_CLAMP;
     ts->ts1.tcz_control = TEXCOORDMODE_CLAMP;
     ts->ts1.normalized_coor = 0;
-    ts->ts1.map_index = 0;
+    ts->ts1.map_index = 1;
     ts->ts1.east_deinterlacer = 0;
     ts->ts2.default_color = 0;
 
@@ -1212,12 +1285,12 @@ static void i915_yuv2rgb_sampler_state_buffer(XvMCSurface *surface)
     ts->ts1.tcy_control = TEXCOORDMODE_CLAMP;
     ts->ts1.tcz_control = TEXCOORDMODE_CLAMP;
     ts->ts1.normalized_coor = 0;
-    ts->ts1.map_index = 0;
+    ts->ts1.map_index = 2;
     ts->ts1.east_deinterlacer = 0;
     ts->ts2.default_color = 0;
 }
 
-static void i915_yuv2rgb_static_indirect_state_buffer(XvMCSurface *surface,
+_STATIC_ void i915_yuv2rgb_static_indirect_state_buffer(XvMCSurface *surface,
                                                       unsigned dstaddr, 
                                                       int dstpitch)
 {
@@ -1251,7 +1324,7 @@ static void i915_yuv2rgb_static_indirect_state_buffer(XvMCSurface *surface,
     dest_buffer_variables->dw1.color_fmt = COLORBUFFER_A8R8G8B8;  /* FIXME */
 }
 
-static void i915_yuv2rgb_pixel_shader_program_buffer(XvMCSurface *surface)
+_STATIC_ void i915_yuv2rgb_pixel_shader_program_buffer(XvMCSurface *surface)
 {
     struct i915_3dstate_pixel_shader_program *pixel_shader_program;
     i915XvMCSurface *privSurface = (i915XvMCSurface *)surface->privData;
@@ -1266,34 +1339,42 @@ static void i915_yuv2rgb_pixel_shader_program_buffer(XvMCSurface *surface)
     pixel_shader_program->dw0.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM;
     pixel_shader_program->dw0.retain = 0;
     pixel_shader_program->dw0.length = 23;
+    /* dcl      t0.xy */
     inst = (unsigned *)(++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);
+    /* dcl_2D   s1 */
     inst += 3;
     i915_inst_decl(inst, REG_TYPE_S, 1, D0_SAMPLE_TYPE_2D);
+    /* dcl_2D   s2 */
     inst += 3;
     i915_inst_decl(inst, REG_TYPE_S, 2, D0_SAMPLE_TYPE_2D);
+    /* texld    r0 t1 s0 */
     inst += 3;
     dest = UREG(REG_TYPE_R, 0); 
-    src0 = UREG(REG_TYPE_S, 0); /* SAMPLER */
-    src1 = UREG(REG_TYPE_T, 1); /* COORD */
+    src0 = UREG(REG_TYPE_T, 1); /* COORD */
+    src1 = UREG(REG_TYPE_S, 0); /* SAMPLER */
     i915_inst_texld(inst, T0_TEXLD, dest, src0, src1);
+    /* texld    r0 t0 s1 */
     inst += 3;
     dest = UREG(REG_TYPE_R, 0); 
-    src0 = UREG(REG_TYPE_S, 1); /* SAMPLER */
-    src1 = UREG(REG_TYPE_T, 0); /* COORD */
+    src0 = UREG(REG_TYPE_T, 0); /* COORD */
+    src1 = UREG(REG_TYPE_S, 1); /* SAMPLER */
     i915_inst_texld(inst, T0_TEXLD, dest, src0, src1);
+    /* texld    oC t1 s2 */
     inst += 3;
     dest = UREG(REG_TYPE_OC, 0);
-    src0 = UREG(REG_TYPE_S, 2);
-    src1 = UREG(REG_TYPE_T, 1);
+    src0 = UREG(REG_TYPE_T, 1); /* COORD */
+    src1 = UREG(REG_TYPE_S, 2); /* SAMPLER */
     i915_inst_texld(inst, T0_TEXLD, dest, src0, src1);
 }
 
-static void i915_yuv2rgb_proc(XvMCSurface *surface)
+_STATIC_ void i915_yuv2rgb_proc(XvMCSurface *surface)
 {
     i915XvMCSurface *privSurface = (i915XvMCSurface *)surface->privData;
     i915XvMCContext *pI915XvMC = (i915XvMCContext *)privSurface->privContext;
@@ -1371,12 +1452,16 @@ static void i915_yuv2rgb_proc(XvMCSurface *surface)
     scissor_rectangle.dw2.max_y = 2047;
     intelBatchbufferData(pI915XvMC, &scissor_rectangle, sizeof(scissor_rectangle), 0);
 
+    /* flush */
+    i915_flush_with_flush_bit_clear(pI915XvMC);
+
     /* 3DSTATE_LOAD_INDIRECT */
     size = sizeof(*load_indirect) + sizeof(*sis) + sizeof(*ssb) + sizeof(*msb) + sizeof(*psp);
     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.mem_select = 1;  /* Bearlake only */
     load_indirect->dw0.block_mask = BLOCK_SIS | BLOCK_SSB | BLOCK_MSB | BLOCK_PSP;
     load_indirect->dw0.length = 7;
 
@@ -1453,7 +1538,7 @@ static void i915_yuv2rgb_proc(XvMCSurface *surface)
 // Function: i915_release_resource
 // Description:
 ***************************************************************************/
-static void i915_release_resource(Display *display, XvMCContext *context)
+_STATIC_ void i915_release_resource(Display *display, XvMCContext *context)
 {
     i915XvMCContext *pI915XvMC;
 
@@ -1535,11 +1620,12 @@ Status XvMCCreateContext(Display *display, XvPortID port,
 
     /* Limit use to root for now */
     /* FIXME: remove it ??? */
+/*
     if (geteuid()) {
         printf("Use of XvMC on i915 is currently limited to root\n");
         return BadAccess;
     }
-
+*/
     /*
      *FIXME: Check $DISPLAY for legal values here
      */
@@ -1571,7 +1657,7 @@ Status XvMCCreateContext(Display *display, XvPortID port,
     /* FIXME: Check Major and Minor here */
 
     /* Allocate private Context data */
-    context->privData = (void *)malloc(sizeof(i915XvMCContext));
+    context->privData = (void *)calloc(1, sizeof(i915XvMCContext));
     if (!context->privData) {
         printf("Unable to allocate resources for XvMC context.\n");
         return BadAlloc;
@@ -2066,24 +2152,18 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context,
         block_ptr = &(blocks->blocks[mb->index << 6]);
 
         /* Lockup can happen if the coordinates are too far out of range */
-        if(mb->x > (target_surface->width >> 4)) {
+        if (mb->x > (target_surface->width >> 4))
             mb->x = 0;
-        }
-        if(mb->y > (target_surface->height >> 4)) {
+
+        if (mb->y > (target_surface->height >> 4))
             mb->y = 0;
-        }
 
         /* Catch no pattern case */
-        if (!(mb->macroblock_type & XVMC_MB_TYPE_PATTERN)) {
+        if (!(mb->macroblock_type & XVMC_MB_TYPE_PATTERN) &&
+            !(mb->macroblock_type & XVMC_MB_TYPE_INTRA)) 
             mb->coded_block_pattern = 0;
-        }
-
-        if (mb->macroblock_type & XVMC_MB_TYPE_INTRA) {
-            bspm = 768;
-        } else {
-            bspm = mb_bytes[mb->coded_block_pattern];
-        }
-
+        
+        bspm = mb_bytes[mb->coded_block_pattern];
         corrdata_size += bspm;
 
         if (corrdata_size > pI915XvMC->corrdata.size) {
@@ -2101,18 +2181,21 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context,
     i915_mc_pixel_shader_program_buffer(context);
     i915_mc_pixel_shader_constants_buffer(context);
     i915_mc_one_time_state_initialization(context);
+    intelFlushBatch(pI915XvMC, TRUE);
 
     i915_mc_static_indirect_state_buffer(context, target_surface, picture_structure);
     i915_mc_map_state_buffer(context, target_surface, past_surface, future_surface);
-    i915_flush(pI915XvMC);
     i915_mc_load_indirect_buffer(context);
     i915_mc_mpeg_set_origin(context, &macroblock_array->macro_blocks[first_macroblock]);
+    intelFlushBatch(pI915XvMC, TRUE);
     for (i = first_macroblock; i < (num_macroblocks + first_macroblock); i++) {
         mb = &macroblock_array->macro_blocks[i];
 
         /* Intra Blocks */
         if (mb->macroblock_type & XVMC_MB_TYPE_INTRA) {
             i915_mc_mpeg_macroblock_0mv(context, mb);
+            // i915_flush(pI915XvMC);
+            intelFlushBatch(pI915XvMC, TRUE);
             continue;
         }
 
diff --git a/src/xvmc/i915_program.h b/src/xvmc/i915_program.h
index d11a518..82c920e 100644
--- a/src/xvmc/i915_program.h
+++ b/src/xvmc/i915_program.h
@@ -238,25 +238,25 @@
 #define GET_CHANNEL_SRC( reg, channel ) ((reg<<(channel*4)) & (0xf<<20))
 #define CHANNEL_SRC( src, channel ) (src>>(channel*4))
 
-#define GET_UREG_TYPE(reg) (((reg)>>UREG_TYPE_SHIFT)&REG_TYPE_MASK)
-#define GET_UREG_NR(reg)   (((reg)>>UREG_NR_SHIFT)&REG_NR_MASK)
+#define GET_UREG_TYPE(reg) (((reg) >> UREG_TYPE_SHIFT) & REG_TYPE_MASK)
+#define GET_UREG_NR(reg)   (((reg) >> UREG_NR_SHIFT) & REG_NR_MASK)
 
 #define UREG_XYZW_CHANNEL_MASK 0x00ffff00
 
-#define A0_DEST(reg) (((reg) & UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT)
-#define D0_DEST(reg) (((reg) & UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT)
-#define T0_DEST(reg) (((reg) & UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT)
-#define A0_SRC0(reg) (((reg) & UREG_MASK)>>UREG_A0_SRC0_SHIFT_LEFT)
-#define A1_SRC0(reg) (((reg) & UREG_MASK)<<UREG_A1_SRC0_SHIFT_RIGHT)
-#define A1_SRC1(reg) (((reg) & UREG_MASK)>>UREG_A1_SRC1_SHIFT_LEFT)
-#define A2_SRC1(reg) (((reg) & UREG_MASK)<<UREG_A2_SRC1_SHIFT_RIGHT)
-#define A2_SRC2(reg) (((reg) & UREG_MASK)>>UREG_A2_SRC2_SHIFT_LEFT)
+#define A0_DEST(reg) (((reg) & UREG_TYPE_NR_MASK) >> UREG_A0_DEST_SHIFT_LEFT)
+#define D0_DEST(reg) (((reg) & UREG_TYPE_NR_MASK) >> UREG_A0_DEST_SHIFT_LEFT)
+#define T0_DEST(reg) (((reg) & UREG_TYPE_NR_MASK) >> UREG_A0_DEST_SHIFT_LEFT)
+#define A0_SRC0(reg) (((reg) & UREG_MASK) >> UREG_A0_SRC0_SHIFT_LEFT)
+#define A1_SRC0(reg) (((reg) & UREG_MASK) << UREG_A1_SRC0_SHIFT_RIGHT)
+#define A1_SRC1(reg) (((reg) & UREG_MASK) >> UREG_A1_SRC1_SHIFT_LEFT)
+#define A2_SRC1(reg) (((reg) & UREG_MASK) << UREG_A2_SRC1_SHIFT_RIGHT)
+#define A2_SRC2(reg) (((reg) & UREG_MASK) >> UREG_A2_SRC2_SHIFT_LEFT)
 
 /* These are special, and don't have swizzle/negate bits.
  */
-#define T0_SAMPLER( reg )     (GET_UREG_NR(reg)<<T0_SAMPLER_NR_SHIFT)
-#define T1_ADDRESS_REG( reg ) ((GET_UREG_NR(reg)<<T1_ADDRESS_REG_NR_SHIFT) | \
-                               (GET_UREG_TYPE(reg)<<T1_ADDRESS_REG_TYPE_SHIFT))
+#define T0_SAMPLER( reg )     (GET_UREG_NR(reg) << T0_SAMPLER_NR_SHIFT)
+#define T1_ADDRESS_REG( reg ) ((GET_UREG_NR(reg) << T1_ADDRESS_REG_NR_SHIFT) | \
+                               (GET_UREG_TYPE(reg) << T1_ADDRESS_REG_TYPE_SHIFT))
 
 
 /* Macros for translating UREG's into the various register fields used
diff --git a/src/xvmc/intel_batchbuffer.c b/src/xvmc/intel_batchbuffer.c
index ef38a44..080a939 100644
--- a/src/xvmc/intel_batchbuffer.c
+++ b/src/xvmc/intel_batchbuffer.c
@@ -6,6 +6,7 @@
 #include <fcntl.h>
 #include <dirent.h>
 #include <string.h>
+#include <assert.h>
 
 #include <sys/ioctl.h>
 #include <X11/Xlibint.h>
@@ -20,95 +21,108 @@
 
 int intelEmitIrqLocked(i915XvMCContext *pI915XvMC)
 {
-    drmI830IrqEmit ie;
-    int ret, seq;
+   drmI830IrqEmit ie;
+   int ret, seq;
 
-    ie.irq_seq = &seq;
-    ret = drmCommandWriteRead(pI915XvMC->fd, DRM_I830_IRQ_EMIT,
-                               &ie, sizeof(ie));
+   ie.irq_seq = &seq;
+   ret = drmCommandWriteRead(pI915XvMC->fd, DRM_I830_IRQ_EMIT,
+                             &ie, sizeof(ie));
 
-    if ( ret ) {
-        fprintf(stderr, "%s: drmI830IrqEmit: %d\n", __FUNCTION__, ret);
-        exit(1);
-    }
+   if ( ret ) {
+      fprintf(stderr, "%s: drmI830IrqEmit: %d\n", __FUNCTION__, ret);
+      exit(1);
+   }
 
-    return seq;
+   return seq;
 }
 
 void intelWaitIrq(i915XvMCContext *pI915XvMC, int seq)
 {
-    int ret;
-    drmI830IrqWait iw;
+   int ret;
+   drmI830IrqWait iw;
 
-    iw.irq_seq = seq;
+   iw.irq_seq = seq;
 
-    do {
-        ret = drmCommandWrite(pI915XvMC->fd, DRM_I830_IRQ_WAIT, &iw, sizeof(iw) );
-    } while (ret == -EAGAIN || ret == -EINTR);
+   do {
+      ret = drmCommandWrite(pI915XvMC->fd, DRM_I830_IRQ_WAIT, &iw, sizeof(iw) );
+   } while (ret == -EAGAIN || ret == -EINTR);
 
-    if (ret) {
-        fprintf(stderr, "%s: drmI830IrqWait: %d\n", __FUNCTION__, ret);
-        exit(1);
-    }
+   if (ret) {
+      fprintf(stderr, "%s: drmI830IrqWait: %d\n", __FUNCTION__, ret);
+      exit(1);
+   }
 }
 
 void intelDestroyBatchBuffer(i915XvMCContext *pI915XvMC)
 {
-    if (pI915XvMC->alloc.offset) {
-        // FIXME: free the memory allocated from AGP
-    } else if (pI915XvMC->alloc.ptr) {
-        free(pI915XvMC->alloc.ptr);
-        pI915XvMC->alloc.ptr = NULL;
-    }
-
-    memset(&pI915XvMC->batch, 0, sizeof(pI915XvMC->batch));
+   if (pI915XvMC->alloc.offset) {
+      // FIXME: free the memory allocated from AGP
+   } else if (pI915XvMC->alloc.ptr) {
+      free(pI915XvMC->alloc.ptr);
+      pI915XvMC->alloc.ptr = NULL;
+   }
+
+   memset(&pI915XvMC->batch, 0, sizeof(pI915XvMC->batch));
 }
 
 
 void intelInitBatchBuffer(i915XvMCContext  *pI915XvMC)
 {
-    pI915XvMC->alloc.offset = 0;
-    pI915XvMC->alloc.size = 16 * 1024;
-    pI915XvMC->alloc.ptr = malloc(pI915XvMC->alloc.size);
-    pI915XvMC->alloc.active_buf = 0;
+   pI915XvMC->alloc.offset = 0;
+   pI915XvMC->alloc.size = 16 * 1024;
+   pI915XvMC->alloc.ptr = malloc(pI915XvMC->alloc.size);
+   pI915XvMC->alloc.active_buf = 0;
 
-    assert(pI915XvMC->alloc.ptr);
+   assert(pI915XvMC->alloc.ptr);
 }
 
 void intelBatchbufferRequireSpace(i915XvMCContext *pI915XvMC, unsigned sz)
 {
-    if (pI915XvMC->batch.space < sz)
-        intelFlushBatch(pI915XvMC, TRUE);
+   if (pI915XvMC->batch.space < sz)
+      intelFlushBatch(pI915XvMC, TRUE);
 }
 
 void intelBatchbufferData(i915XvMCContext *pI915XvMC, const void *data, 
                           unsigned bytes, unsigned flags)
 {
-    assert((bytes & 3) == 0);
-    intelBatchbufferRequireSpace(pI915XvMC, bytes);
-    memcpy(pI915XvMC->batch.ptr, data, bytes);
-    pI915XvMC->batch.ptr += bytes;
-    pI915XvMC->batch.space -= bytes;
-    assert(pI915XvMC->batch.space >= 0);
+   int extra = 0;
+
+   assert((bytes & 0x3) == 0);
+
+   if (bytes & 0x7)
+      extra = 1;
+
+   intelBatchbufferRequireSpace(pI915XvMC, bytes + extra << 2);
+   memcpy(pI915XvMC->batch.ptr, data, bytes);
+   pI915XvMC->batch.ptr += bytes;
+   pI915XvMC->batch.space -= bytes;
+
+   if (extra) {
+      *(int *)(pI915XvMC->batch.ptr) = 0;
+      pI915XvMC->batch.ptr += 4;
+      pI915XvMC->batch.space -= 4;
+   }
+
+   assert(pI915XvMC->batch.space >= 0);
 }
 
 void intelRefillBatchLocked(i915XvMCContext *pI915XvMC, Bool allow_unlock )
 {
-    unsigned last_irq = pI915XvMC->alloc.irq_emitted;
-    unsigned half = pI915XvMC->alloc.size >> 1;
-    unsigned buf = (pI915XvMC->alloc.active_buf ^= 1);
+   unsigned last_irq = pI915XvMC->alloc.irq_emitted;
+   unsigned half = pI915XvMC->alloc.size >> 1;
+   unsigned buf = (pI915XvMC->alloc.active_buf ^= 1);
 
-    pI915XvMC->alloc.irq_emitted = intelEmitIrqLocked(pI915XvMC);
+   pI915XvMC->alloc.irq_emitted = intelEmitIrqLocked(pI915XvMC);
 
-    if (last_irq) {
-        intelWaitIrq(pI915XvMC, last_irq);
-    }
+   if (last_irq) {
+      intelWaitIrq(pI915XvMC, last_irq);
+   }
 
-    pI915XvMC->batch.start_offset = pI915XvMC->alloc.offset + buf * half;
-    pI915XvMC->batch.ptr = (unsigned char *)pI915XvMC->alloc.ptr + buf * half;
-    pI915XvMC->batch.size = half - 8;
-    pI915XvMC->batch.space = half - 8;
-    assert(pI915XvMC->batch.space >= 0);
+   pI915XvMC->batch.start_offset = pI915XvMC->alloc.offset + buf * half;
+   pI915XvMC->batch.ptr = (unsigned char *)pI915XvMC->alloc.ptr + buf * half;
+   pI915XvMC->batch.size = half - 8;
+   pI915XvMC->batch.space = half - 8;
+   assert(pI915XvMC->batch.space >= 0);
 }
 
 
@@ -117,81 +131,81 @@ void intelFlushBatchLocked(i915XvMCContext *pI915XvMC,
                            Bool refill,
                            Bool allow_unlock)
 {
-    drmI830BatchBuffer batch;
-
-    if (pI915XvMC->batch.space != pI915XvMC->batch.size) {
-
-        batch.start = pI915XvMC->batch.start_offset;
-        batch.used = pI915XvMC->batch.size - pI915XvMC->batch.space;
-        batch.cliprects = 0;
-        batch.num_cliprects = 0;
-        batch.DR1 = 0;
-        batch.DR4 = 0;
-
-        if (pI915XvMC->alloc.offset) {
-            // FIXME: MI_BATCH_BUFFER_END
-        }
-
-        pI915XvMC->batch.start_offset += batch.used;
-        pI915XvMC->batch.size -= batch.used;
-
-        if (pI915XvMC->batch.size < 8) {
-            refill = TRUE;
-            pI915XvMC->batch.space = pI915XvMC->batch.size = 0;
-        }
-        else {
-            pI915XvMC->batch.size -= 8;
-            pI915XvMC->batch.space = pI915XvMC->batch.size;
-        }
-
-        assert(pI915XvMC->batch.space >= 0);
-        assert(batch.start >= pI915XvMC->alloc.offset);
-        assert(batch.start < pI915XvMC->alloc.offset + pI915XvMC->alloc.size);
-        assert(batch.start + batch.used > pI915XvMC->alloc.offset);
-        assert(batch.start + batch.used <= pI915XvMC->alloc.offset + pI915XvMC->alloc.size);
-
-        if (pI915XvMC->alloc.offset) {
-            // DRM_I830_BATCHBUFFER
-        } else {
-            drmI830CmdBuffer cmd;
-            cmd.buf = (char *)pI915XvMC->alloc.ptr + batch.start;
-            cmd.sz = batch.used;
-            cmd.DR1 = batch.DR1;
-            cmd.DR4 = batch.DR4;
-            cmd.num_cliprects = batch.num_cliprects;
-            cmd.cliprects = batch.cliprects;
-
-            if (drmCommandWrite(pI915XvMC->fd, DRM_I830_CMDBUFFER, 
-                                 &cmd, sizeof(cmd))) {
-                fprintf(stderr, "DRM_I915_CMDBUFFER: %d\n",  -errno);
-                exit(1);
-            }
-        }
-    }
-
-    if (refill)
-        intelRefillBatchLocked(pI915XvMC, allow_unlock);
+   drmI830BatchBuffer batch;
+
+   if (pI915XvMC->batch.space != pI915XvMC->batch.size) {
+
+      batch.start = pI915XvMC->batch.start_offset;
+      batch.used = pI915XvMC->batch.size - pI915XvMC->batch.space;
+      batch.cliprects = 0;
+      batch.num_cliprects = 0;
+      batch.DR1 = 0;
+      batch.DR4 = 0;
+
+      if (pI915XvMC->alloc.offset) {
+         // FIXME: MI_BATCH_BUFFER_END
+      }
+
+      pI915XvMC->batch.start_offset += batch.used;
+      pI915XvMC->batch.size -= batch.used;
+
+      if (pI915XvMC->batch.size < 8) {
+         refill = TRUE;
+         pI915XvMC->batch.space = pI915XvMC->batch.size = 0;
+      }
+      else {
+         pI915XvMC->batch.size -= 8;
+         pI915XvMC->batch.space = pI915XvMC->batch.size;
+      }
+
+      assert(pI915XvMC->batch.space >= 0);
+      assert(batch.start >= pI915XvMC->alloc.offset);
+      assert(batch.start < pI915XvMC->alloc.offset + pI915XvMC->alloc.size);
+      assert(batch.start + batch.used > pI915XvMC->alloc.offset);
+      assert(batch.start + batch.used <= pI915XvMC->alloc.offset + pI915XvMC->alloc.size);
+
+      if (pI915XvMC->alloc.offset) {
+         // DRM_I830_BATCHBUFFER
+      } else {
+         drmI830CmdBuffer cmd;
+         cmd.buf = (char *)pI915XvMC->alloc.ptr + batch.start;
+         cmd.sz = batch.used;
+         cmd.DR1 = batch.DR1;
+         cmd.DR4 = batch.DR4;
+         cmd.num_cliprects = batch.num_cliprects;
+         cmd.cliprects = batch.cliprects;
+
+         if (drmCommandWrite(pI915XvMC->fd, DRM_I830_CMDBUFFER, 
+                             &cmd, sizeof(cmd))) {
+            fprintf(stderr, "DRM_I915_CMDBUFFER: %d\n",  -errno);
+            exit(1);
+         }
+      }
+   }
+
+   if (refill)
+      intelRefillBatchLocked(pI915XvMC, allow_unlock);
 }
 
 void intelFlushBatch(i915XvMCContext *pI915XvMC, Bool refill )
 {
-    intelFlushBatchLocked(pI915XvMC, FALSE, refill, TRUE);
+   intelFlushBatchLocked(pI915XvMC, FALSE, refill, TRUE);
 }
 
 void intelCmdIoctl(i915XvMCContext *pI915XvMC, char *buf, unsigned used)
 {
-    drmI830CmdBuffer cmd;
-
-    cmd.buf = buf;
-    cmd.sz = used;
-    cmd.cliprects = 0;
-    cmd.num_cliprects = 0;
-    cmd.DR1 = 0;
-    cmd.DR4 = 0;
-
-    if (drmCommandWrite(pI915XvMC->fd, DRM_I830_CMDBUFFER, 
-                        &cmd, sizeof(cmd))) {
-        fprintf(stderr, "DRM_I830_CMDBUFFER: %d\n",  -errno);
-        exit(1);
-    }
+   drmI830CmdBuffer cmd;
+
+   cmd.buf = buf;
+   cmd.sz = used;
+   cmd.cliprects = 0;
+   cmd.num_cliprects = 0;
+   cmd.DR1 = 0;
+   cmd.DR4 = 0;
+
+   if (drmCommandWrite(pI915XvMC->fd, DRM_I830_CMDBUFFER, 
+                       &cmd, sizeof(cmd))) {
+      fprintf(stderr, "DRM_I830_CMDBUFFER: %d\n",  -errno);
+      exit(1);
+   }
 }
commit 934da9f2b83716bb37d0719a61b8e6b179fff2cd
Author: Xiang, Haihao <haihao.xiang at intel.com>
Date:   Mon Jun 25 10:17:08 2007 +0800

    enable XvMC for i915

diff --git a/src/Makefile.am b/src/Makefile.am
index 858ffd1..028dcfd 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -59,6 +59,8 @@ INTEL_DRI_SRCS = \
          i810_dri.h \
          i830_dri.c \
          i810_hwmc.c \
+         i915_hwmc.c \
+         i915_hwmc.h \
          i830_dri.h
 
 intel_drv_la_SOURCES = \
diff --git a/src/i830.h b/src/i830.h
index aa2b240..2149782 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -309,6 +309,11 @@ typedef struct _I830Rec {
    /* For Xvideo */
    i830_memory *overlay_regs;
 #endif
+   
+   /* For XvMC */
+   void *xvmc;
+   Bool XvMCEnabled;
+
    XF86ModReqInfo shadowReq; /* to test for later libshadow */
    Rotation rotation;
    void (*PointerMoved)(int, int, int);
@@ -644,7 +649,10 @@ extern long I830CheckAvailableMemory(ScrnInfoPtr pScrn);
 Bool i830_allocate_2d_memory(ScrnInfoPtr pScrn);
 Bool i830_allocate_texture_memory(ScrnInfoPtr pScrn);
 Bool i830_allocate_3d_memory(ScrnInfoPtr pScrn);
-
+Bool i830_allocate_xvmc_surface(ScrnInfoPtr pScrn, i830_memory **surface,
+                                unsigned long size);
+Bool i830_allocate_xvmc_buffer(ScrnInfoPtr pScrn, const char *name,
+                               i830_memory **buffer, unsigned long size);
 extern Bool I830IsPrimary(ScrnInfoPtr pScrn);
 
 extern Bool I830I2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, int i2c_reg,
@@ -738,6 +746,11 @@ static inline int i830_fb_compression_supported(I830Ptr pI830)
     return TRUE;
 }
 
+/* i915 XvMC */
+int I915XvMCInitXv(ScrnInfoPtr, XF86VideoAdaptorPtr);
+void I915InitMC(ScreenPtr);
+unsigned long I915XvMCPutImageSize(ScrnInfoPtr);
+
 extern const int I830PatternROP[16];
 extern const int I830CopyROP[16];
 
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 9bb12c6..9cae291 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -2720,6 +2720,12 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
    if (pI830->directRenderingEnabled) {
       pI830->directRenderingEnabled = I830DRIFinishScreenInit(pScreen);
    }
+
+#ifdef XvMCExtension
+   if ((pI830->directRenderingEnabled) && IS_I9XX(pI830)) {
+       I915InitMC(pScreen);
+   }
+#endif
 #endif
 
    /* Setup 3D engine, needed for rotation too */
diff --git a/src/i830_memory.c b/src/i830_memory.c
index b38a5df..7022167 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -1758,4 +1758,42 @@ i830_xf86AllocateOffscreenLinear(ScreenPtr pScreen, int length,
 
     return linear;
 }
+
+/*
+ * Allocate memory for XvMC surface
+ */
+Bool
+i830_allocate_xvmc_surface(ScrnInfoPtr pScrn, i830_memory **surface, unsigned long size)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+
+    *surface = i830_allocate_memory(pScrn, "XvMC surface", size,
+                                    GTT_PAGE_SIZE, ALIGN_BOTH_ENDS);
+
+    if (!*surface) {
+        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                   "Failed to allocate XvMC surface space.\n");
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+/*
+ * Allocate memory for MC compensation
+ */
+Bool i830_allocate_xvmc_buffer(ScrnInfoPtr pScrn, const char *name, i830_memory **buffer, unsigned long size)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+
+    *buffer = i830_allocate_memory(pScrn, name, size,
+                                   GTT_PAGE_SIZE, ALIGN_BOTH_ENDS);
+
+    if (!*buffer) {
+        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                   "Failed to allocate memory for %s.\n", name);
+        return FALSE;
+    }
+    return TRUE;
+}
 #endif
diff --git a/src/i830_video.c b/src/i830_video.c
index b4f9e74..4f5ab43 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -74,6 +74,8 @@
 #include "dixstruct.h"
 #include "fourcc.h"
 
+#include "i915_hwmc.h"
+
 #ifndef USE_USLEEP_FOR_VIDEO
 #define USE_USLEEP_FOR_VIDEO 0
 #endif
@@ -576,6 +578,11 @@ I830InitVideo(ScreenPtr pScreen)
 	if (texturedAdaptor != NULL) {
 	    adaptors[num_adaptors++] = texturedAdaptor;
 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Set up textured video\n");
+
+#ifdef XF86DRI
+            if (pI830->XvMCEnabled && IS_I9XX(pI830))
+               I915XvMCInitXv(pScrn, texturedAdaptor);
+#endif
 	} else {
 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 		       "Failed to set up textured video\n");
@@ -2587,6 +2594,16 @@ I830QueryImageAttributes(ScrnInfoPtr pScrn,
 	    ErrorF("size is %d\n", size);
 #endif
 	break;
+    case FOURCC_XVMC:
+        *h = (*h + 1) & ~1;
+#ifdef XF86DRI
+        size = I915XvMCPutImageSize(pScrn);
+#else
+        size = 0;
+#endif
+        if (pitches)
+            pitches[0] = size;
+        break;
     case FOURCC_UYVY:
     case FOURCC_YUY2:
     default:
diff --git a/src/i830_video.h b/src/i830_video.h
index 7e2d149..67022f6 100644
--- a/src/i830_video.h
+++ b/src/i830_video.h
@@ -77,6 +77,7 @@ typedef struct {
    int oneLineMode;
    int scaleRatio;
    Bool textured;
+   void *xvmc_priv;
 } I830PortPrivRec, *I830PortPrivPtr;
 
 #define GET_PORT_PRIVATE(pScrn) \
diff --git a/src/i915_hwmc.c b/src/i915_hwmc.c
new file mode 100644
index 0000000..119b908
--- /dev/null
+++ b/src/i915_hwmc.c
@@ -0,0 +1,932 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86Resources.h"
+#include "compiler.h"
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+#include "xf86fbman.h"
+#include "regionstr.h"
+
+#include "i830.h"
+#include "i830_dri.h"
+#include "i830_video.h"
+#include "xf86xv.h"
+#include "xf86xvmc.h"
+#include <X11/extensions/Xv.h>
+#include <X11/extensions/XvMC.h>
+#include "xaa.h"
+#include "xaalocal.h"
+#include "dixstruct.h"
+#include "fourcc.h"
+
+#if defined(X_NEED_XVPRIV_H) || defined (_XF86_FOURCC_H_)
+#include "xf86xvpriv.h"
+#endif
+
+#include "i915_hwmc.h"
+
+#define MAKE_ATOM(a) MakeAtom(a, strlen(a), TRUE)
+
+/*
+ * List Attributes for the XvMC extension to handle:
+ * As long as the attribute is supported by the Xv adaptor, it needs only to
+ * be added here to be supported also by XvMC.
+ * Currently, only colorkey seems to be supported by Xv for Putimage.
+ */
+static char *attrXvMC[I915_NUM_XVMC_ATTRIBUTES] = { 
+    "XV_BRIGHTNESS",
+    "XV_CONTRAST",
+};
+static Atom attrAtoms[I915_NUM_XVMC_ATTRIBUTES];
+
+typedef struct
+{
+    unsigned ctxDisplaying;
+    int xvmc_port;
+    I915XvMCAttrHolder xvAttr;
+    int newAttribute;
+
+    SetPortAttributeFuncPtr SetPortAttribute;
+    GetPortAttributeFuncPtr GetPortAttribute;
+    PutImageFuncPtr PutImage;
+} I915XvMCXVPriv;
+
+#define I915_XVMC_MAX_BUFFERS 2
+#define I915_XVMC_MAX_CONTEXTS 4
+#define I915_XVMC_MAX_SURFACES 20
+
+typedef struct _I915XvMCSurfacePriv
+{
+    i830_memory *surface;
+    unsigned long offsets[I915_XVMC_MAX_BUFFERS];
+} I915XvMCSurfacePriv;
+
+typedef struct _I915XvMCContextPriv
+{
+    i830_memory *mcStaticIndirectState;
+    drm_handle_t sis_handle;
+    i830_memory *mcMapState;
+    drm_handle_t msb_handle;
+    i830_memory *mcSamplerState;
+    drm_handle_t ssb_handle;
+    i830_memory *mcPixelShaderProgram;
+    drm_handle_t psp_handle;
+    i830_memory *mcPixelShaderConstants;
+    drm_handle_t psc_handle;
+    i830_memory *mcCorrdata;
+    drm_handle_t corrdata_handle;
+} I915XvMCContextPriv;
+
+typedef struct _I915XvMC 
+{
+    XID contexts[I915_XVMC_MAX_CONTEXTS];
+    XID surfaces[I915_XVMC_MAX_SURFACES];
+    I915XvMCSurfacePriv *sfprivs[I915_XVMC_MAX_SURFACES];
+    I915XvMCContextPriv *ctxprivs[I915_XVMC_MAX_CONTEXTS];
+    int ncontexts,nsurfaces;
+} I915XvMC, *I915XvMCPtr;
+
+#define ARRARY_SIZE(a) (sizeof(a) / sizeof(a[0]))
+static int I915XvMCCreateContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext,
+                                  int *num_priv, long **priv );
+static void I915XvMCDestroyContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext);
+
+static int I915XvMCCreateSurface (ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf,
+                                  int *num_priv, long **priv );
+static void I915XvMCDestroySurface (ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf);
+
+static int I915XvMCCreateSubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSurf,
+                                     int *num_priv, long **priv );
+static void I915XvMCDestroySubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSurf);
+
+static int yv12_subpicture_index_list[2] = 
+{
+    FOURCC_IA44,
+    FOURCC_AI44
+};
+
+static XF86MCImageIDList yv12_subpicture_list =
+{
+    ARRARY_SIZE(yv12_subpicture_index_list),
+    yv12_subpicture_index_list
+};
+ 
+static XF86MCSurfaceInfoRec i915_YV12_mpg2_surface =
+{
+    FOURCC_YV12,  
+    XVMC_CHROMA_FORMAT_420,
+    0,
+    720,
+    576,
+    720,
+    576,
+    XVMC_MPEG_2,
+    XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING |
+    XVMC_INTRA_UNSIGNED,
+    &yv12_subpicture_list
+};
+
+static XF86MCSurfaceInfoRec i915_YV12_mpg1_surface =
+{
+    FOURCC_YV12,  
+    XVMC_CHROMA_FORMAT_420,
+    0,
+    720,
+    576,
+    720,
+    576,
+    XVMC_MPEG_1,
+    XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING |
+    XVMC_INTRA_UNSIGNED,
+    &yv12_subpicture_list
+};
+
+static XF86MCSurfaceInfoPtr ppSI[2] = 
+{
+    (XF86MCSurfaceInfoPtr)&i915_YV12_mpg2_surface,
+    (XF86MCSurfaceInfoPtr)&i915_YV12_mpg1_surface
+};
+
+/* List of subpicture types that we support */
+static XF86ImageRec ia44_subpicture = XVIMAGE_IA44;
+static XF86ImageRec ai44_subpicture = XVIMAGE_AI44;
+
+static XF86ImagePtr i915_subpicture_list[2] =
+{
+    (XF86ImagePtr)&ia44_subpicture,
+    (XF86ImagePtr)&ai44_subpicture
+};
+
+/* Fill in the device dependent adaptor record. 
+ * This is named "Intel(R) Textured Video" because this code falls under the
+ * XV extenstion, the name must match or it won't be used.
+ *
+ * Surface and Subpicture - see above
+ * Function pointers to functions below
+ */
+static XF86MCAdaptorRec pAdapt = 
+{
+    "Intel(R) Textured Video",		                        /* name */
+    ARRARY_SIZE(ppSI),                                          /* num_surfaces */
+    ppSI,				                        /* surfaces */
+    ARRARY_SIZE(i915_subpicture_list),                          /* num_subpictures */
+    i915_subpicture_list,		                        /* subpictures */
+    (xf86XvMCCreateContextProcPtr)I915XvMCCreateContext,
+    (xf86XvMCDestroyContextProcPtr)I915XvMCDestroyContext,
+    (xf86XvMCCreateSurfaceProcPtr)I915XvMCCreateSurface,
+    (xf86XvMCDestroySurfaceProcPtr)I915XvMCDestroySurface,
+    (xf86XvMCCreateSubpictureProcPtr)I915XvMCCreateSubpicture,
+    (xf86XvMCDestroySubpictureProcPtr)I915XvMCDestroySubpicture
+};
+
+static XF86MCAdaptorPtr ppAdapt[1] = 
+{
+    (XF86MCAdaptorPtr)&pAdapt
+};
+
+static unsigned int stride(int w)
+{
+    return (w + 31) & ~31;
+}
+
+static unsigned long size_yuv420(int w, int h)
+{
+    unsigned yPitch = stride(w);
+
+    return h * (yPitch + (yPitch >> 1));
+}
+
+static unsigned long size_xx44(int w, int h)
+{
+    return h * stride(w);
+}
+
+/*
+ * Init and clean up the screen private parts of XvMC.
+ */
+static void initI915XvMC(I915XvMCPtr xvmc)
+{
+    unsigned int i;
+
+    for (i = 0; i < I915_XVMC_MAX_CONTEXTS; i++) {
+        xvmc->contexts[i] = 0;
+        xvmc->ctxprivs[i] = NULL;
+    }
+
+    for (i = 0; i < I915_XVMC_MAX_SURFACES; i++) {
+        xvmc->surfaces[i] = 0;
+        xvmc->sfprivs[i] = NULL;
+    }
+}
+
+static void cleanupI915XvMC(I915XvMCPtr xvmc, XF86VideoAdaptorPtr * XvAdaptors, int XvAdaptorCount)
+{
+    unsigned int i;
+
+    for (i = 0; i < I915_XVMC_MAX_CONTEXTS; i++) {
+        xvmc->contexts[i] = 0;
+
+        if (xvmc->ctxprivs[i]) {
+            xfree(xvmc->ctxprivs[i]);
+            xvmc->ctxprivs[i] = NULL;
+        }
+    }
+
+    for (i = 0; i < I915_XVMC_MAX_SURFACES; i++) {
+        xvmc->surfaces[i] = 0;
+        
+        if (xvmc->sfprivs[i]) {
+            xfree(xvmc->sfprivs[i]);
+            xvmc->sfprivs[i] = NULL;
+        }
+    }
+}
+
+static Bool i915_map_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *ctxpriv)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+
+    if (drmAddMap(pI830->drmSubFD,
+                  (drm_handle_t)(ctxpriv->mcStaticIndirectState->offset + pI830->LinearAddr),
+                  ctxpriv->mcStaticIndirectState->size, DRM_AGP, 0,
+                  (drmAddress)&ctxpriv->sis_handle) < 0) {
+        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                   "[drm] drmAddMap(sis_handle) failed!\n");
+        return FALSE;
+    }
+
+    if (drmAddMap(pI830->drmSubFD,
+                  (drm_handle_t)(ctxpriv->mcMapState->offset + pI830->LinearAddr),
+                  ctxpriv->mcMapState->size, DRM_AGP, 0,
+                  (drmAddress)&ctxpriv->msb_handle) < 0) {
+        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                   "[drm] drmAddMap(msb_handle) failed!\n");
+        return FALSE;
+    }
+
+    if (drmAddMap(pI830->drmSubFD, 
+                  (drm_handle_t)(ctxpriv->mcSamplerState->offset + pI830->LinearAddr),
+                  ctxpriv->mcSamplerState->size, DRM_AGP, 0,
+                  (drmAddress)&ctxpriv->ssb_handle) < 0) {
+        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                   "[drm] drmAddress(ssb_handle) failed!\n");
+        return FALSE;
+    }
+
+    if (drmAddMap(pI830->drmSubFD, 
+                  (drm_handle_t)(ctxpriv->mcPixelShaderProgram->offset + pI830->LinearAddr),
+                  ctxpriv->mcPixelShaderProgram->size, DRM_AGP, 0,
+                  (drmAddress)&ctxpriv->psp_handle) < 0) {
+        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                   "[drm] drmAddress(psp_handle) failed!\n");
+        return FALSE;
+    }
+
+    if (drmAddMap(pI830->drmSubFD, 
+                  (drm_handle_t)(ctxpriv->mcPixelShaderConstants->offset + pI830->LinearAddr),
+                  ctxpriv->mcPixelShaderConstants->size, DRM_AGP, 0,
+                  (drmAddress)&ctxpriv->psc_handle) < 0) {
+        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                   "[drm] drmAddress(psc_handle) failed!\n");
+        return FALSE;
+    }
+
+    if (drmAddMap(pI830->drmSubFD,
+                  (drm_handle_t)(ctxpriv->mcCorrdata->offset + pI830->LinearAddr),
+                  ctxpriv->mcCorrdata->size, DRM_AGP, 0,
+                  (drmAddress)&ctxpriv->corrdata_handle) < 0) {
+        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                   "[drm] drmAddMap(corrdata_handle) failed!\n");
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+static void i915_unmap_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *ctxpriv)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+    
+    if (ctxpriv->sis_handle) {
+        drmRmMap(pI830->drmSubFD, ctxpriv->sis_handle);
+        ctxpriv->sis_handle = 0;
+    }
+
+    if (ctxpriv->msb_handle) {
+        drmRmMap(pI830->drmSubFD, ctxpriv->msb_handle);
+        ctxpriv->msb_handle = 0;
+    }
+
+    if (ctxpriv->ssb_handle) {
+        drmRmMap(pI830->drmSubFD, ctxpriv->ssb_handle);
+        ctxpriv->ssb_handle = 0;
+    }
+
+    if (ctxpriv->psp_handle) {
+        drmRmMap(pI830->drmSubFD, ctxpriv->psp_handle);
+        ctxpriv->psp_handle = 0;
+    }
+
+    if (ctxpriv->psc_handle) {
+        drmRmMap(pI830->drmSubFD, ctxpriv->psc_handle);
+        ctxpriv->psc_handle = 0;
+    }
+
+    if (ctxpriv->corrdata_handle) {
+        drmRmMap(pI830->drmSubFD, ctxpriv->corrdata_handle);
+        ctxpriv->corrdata_handle = 0;
+    }
+}
+
+static Bool i915_allocate_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *ctxpriv)
+{
+    if (!i830_allocate_xvmc_buffer(pScrn, "Static Indirect State", 
+                                   &(ctxpriv->mcStaticIndirectState), 512)) {
+        return FALSE;
+    }
+
+    if (!i830_allocate_xvmc_buffer(pScrn, "Map State", 
+                                   &(ctxpriv->mcMapState), 512)) {
+        return FALSE;
+    }
+
+    if (!i830_allocate_xvmc_buffer(pScrn, "Sampler State",
+                                   &(ctxpriv->mcSamplerState), 512)) {
+        return FALSE;
+    }
+
+    if (!i830_allocate_xvmc_buffer(pScrn, "Pixel Shader Program",
+                                   &(ctxpriv->mcPixelShaderProgram), 512)) {
+        return FALSE;
+    }
+
+    if (!i830_allocate_xvmc_buffer(pScrn, "Pixel Shader Constants",
+                                   &(ctxpriv->mcPixelShaderConstants), 128)) {
+        return FALSE;
+    }
+
+    if (!i830_allocate_xvmc_buffer(pScrn, "Correction Data Buffer", 
+                                   &(ctxpriv->mcCorrdata), 2 * 1024 * 1024)) {
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+static void i915_free_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *ctxpriv)
+{
+    if (ctxpriv->mcStaticIndirectState) {
+        i830_free_memory(pScrn, ctxpriv->mcStaticIndirectState);
+        ctxpriv->mcStaticIndirectState = NULL;
+    }
+
+    if (ctxpriv->mcMapState) {
+        i830_free_memory(pScrn, ctxpriv->mcMapState);
+        ctxpriv->mcMapState = NULL;
+    }
+
+    if (ctxpriv->mcSamplerState) {
+        i830_free_memory(pScrn, ctxpriv->mcSamplerState);
+        ctxpriv->mcSamplerState = NULL;
+    }
+
+    if (ctxpriv->mcPixelShaderProgram) {
+        i830_free_memory(pScrn, ctxpriv->mcPixelShaderProgram);
+        ctxpriv->mcPixelShaderProgram = NULL;
+    }
+
+    if (ctxpriv->mcPixelShaderConstants) {
+        i830_free_memory(pScrn, ctxpriv->mcPixelShaderConstants);
+        ctxpriv->mcPixelShaderConstants = NULL;
+    }
+
+    if (ctxpriv->mcCorrdata) {
+        i830_free_memory(pScrn, ctxpriv->mcCorrdata);
+        ctxpriv->mcCorrdata = NULL;
+    }
+}
+
+/**************************************************************************
+ *
+ *  I915XvMCCreateContext
+ *
+ *  Some info about the private data:
+ *
+ *  Set *num_priv to the number of 32bit words that make up the size of
+ *  of the data that priv will point to.
+ *
+ *  *priv = (long *) xcalloc (elements, sizeof(element))
+ *  *num_priv = (elements * sizeof(element)) >> 2;
+ *
+ **************************************************************************/
+
+static int I915XvMCCreateContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext,
+                                  int *num_priv, long **priv )
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+    DRIInfoPtr pDRIInfo = pI830->pDRIInfo;
+    I915XvMCCreateContextRec *contextRec = NULL;
+    I915XvMCPtr pXvMC = pI830->xvmc;
+    I915XvMCContextPriv *ctxpriv = NULL;
+    XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)pContext->port_priv;
+    I830PortPrivPtr pPriv = (I830PortPrivPtr)portPriv->DevPriv.ptr;
+    I915XvMCXVPriv *vx = (I915XvMCXVPriv *)pPriv->xvmc_priv;
+
+    int i;
+
+    *priv = NULL;
+    *num_priv = 0;
+
+    if (!pI830->directRenderingEnabled) {
+        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                   "[XvMC] I915XvMCCreateContext: Cannot use XvMC without DRI!\n");
+        return BadAlloc;
+    }
+
+    if (pXvMC->ncontexts >= I915_XVMC_MAX_CONTEXTS) {
+        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                   "[XvMC] I915XvMCCreateContext: Out of contexts.\n");
+        return BadAlloc;
+    }
+
+    *priv = xcalloc(1, sizeof(I915XvMCCreateContextRec));
+    contextRec = (I915XvMCCreateContextRec *)*priv;
+
+    if (!*priv) {
+        *num_priv = 0;
+        return BadAlloc;
+    }
+
+    *num_priv = sizeof(I915XvMCCreateContextRec) >> 2;
+
+    for (i = 0; i < I915_XVMC_MAX_CONTEXTS; i++) {
+        if (!pXvMC->contexts[i])
+            break;
+    }
+
+    ctxpriv = (I915XvMCContextPriv *)xcalloc(1, sizeof(I915XvMCContextPriv));
+
+    if (!ctxpriv) {
+        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                   "[XvMC] I915XvMCCreateContext: Unable to allocate memory!\n");
+        xfree(*priv);
+        *priv = NULL;
+        *num_priv = 0;
+        return BadAlloc;
+    }
+
+    if (!i915_allocate_xvmc_buffers(pScrn, ctxpriv)) {
+        i915_free_xvmc_buffers(pScrn, ctxpriv);
+        xfree(ctxpriv);
+        ctxpriv = NULL;
+        xfree(*priv);
+        *priv = NULL;
+        *num_priv = 0;
+        return BadAlloc;
+    }
+
+    if (!i915_map_xvmc_buffers(pScrn, ctxpriv)) {
+        i915_unmap_xvmc_buffers(pScrn, ctxpriv);
+        i915_free_xvmc_buffers(pScrn, ctxpriv);
+        xfree(ctxpriv);
+        ctxpriv = NULL;
+        xfree(*priv);
+        *priv = NULL;
+        *num_priv = 0;
+        return BadAlloc;
+    }
+
+    contextRec->ctxno = i;
+    contextRec->sis.handle = ctxpriv->sis_handle;
+    contextRec->sis.offset = ctxpriv->mcStaticIndirectState->offset;
+    contextRec->sis.size = ctxpriv->mcStaticIndirectState->size;
+    contextRec->msb.handle = ctxpriv->msb_handle;
+    contextRec->msb.offset = ctxpriv->mcMapState->offset;
+    contextRec->msb.size = ctxpriv->mcMapState->size;
+    contextRec->ssb.handle = ctxpriv->ssb_handle;
+    contextRec->ssb.offset = ctxpriv->mcSamplerState->offset;
+    contextRec->ssb.size = ctxpriv->mcSamplerState->size;
+    contextRec->psp.handle = ctxpriv->psp_handle;
+    contextRec->psp.offset = ctxpriv->mcPixelShaderProgram->offset;
+    contextRec->psp.size = ctxpriv->mcPixelShaderProgram->size;
+    contextRec->psc.handle = ctxpriv->psc_handle;
+    contextRec->psc.offset = ctxpriv->mcPixelShaderConstants->offset;
+    contextRec->psc.size = ctxpriv->mcPixelShaderConstants->size;
+    contextRec->corrdata.handle = ctxpriv->corrdata_handle;
+    contextRec->corrdata.offset = ctxpriv->mcCorrdata->offset;
+    contextRec->corrdata.size = ctxpriv->mcCorrdata->size;
+    contextRec->sarea_size = pDRIInfo->SAREASize;
+    contextRec->sarea_priv_offset = sizeof(XF86DRISAREARec);
+    contextRec->screen = pScrn->pScreen->myNum;
+    contextRec->depth = pScrn->bitsPerPixel;
+    contextRec->initAttrs = vx->xvAttr;
+
+    pXvMC->ncontexts++;
+    pXvMC->contexts[i] = pContext->context_id;
+    pXvMC->ctxprivs[i] = ctxpriv;
+
+    return Success;
+}
+
+static int I915XvMCCreateSurface(ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf,
+                                 int *num_priv, long **priv )
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+    I915XvMCPtr pXvMC = pI830->xvmc;
+    I915XvMCSurfacePriv *sfpriv = NULL;
+    XvMCContextPtr ctx = NULL;
+    unsigned int sfno, i, nbuffers;
+    unsigned long bufsize;
+
+    *priv = NULL;
+    *num_priv = 0;
+
+    if (pXvMC->nsurfaces >= I915_XVMC_MAX_SURFACES) {
+        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                   "[XvMC] I915XvMCCreateSurface: Too many surfaces !\n");
+        return BadAlloc;
+    }
+
+    sfpriv = (I915XvMCSurfacePriv *)xcalloc(1, sizeof(I915XvMCSurfacePriv));
+
+    if (!sfpriv) {
+        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                   "[XvMC] I915XvMCCreateSurface: Unable to allocate memory!\n");
+        return BadAlloc;
+    }
+
+    nbuffers = 1;
+    *num_priv = nbuffers + 2;
+    *priv = (long *)xcalloc(*num_priv, sizeof(unsigned long));
+    
+    if (!*priv) {
+        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                   "[XvMC] I915XvMCCreateSurface: Unable to allocate memory!\n");
+        xfree(sfpriv);
+        *num_priv = 0;
+        return BadAlloc;
+    }
+
+    ctx = pSurf->context;
+    bufsize = size_yuv420(ctx->width, ctx->height);
+
+    if (!i830_allocate_xvmc_surface(pScrn, &(sfpriv->surface), nbuffers * bufsize)) {
+        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                   "[XvMC] I915XvMCCreateSurface: Failed to allocate XvMC surface space!\n");
+        xfree(sfpriv);
+        xfree(*priv);
+        *priv = NULL;
+        *num_priv = 0;
+        return BadAlloc;
+    }
+
+    for (sfno = 0; sfno < I915_XVMC_MAX_SURFACES; ++sfno) {
+        if (!pXvMC->surfaces[sfno])
+            break;
+    }
+
+    (*priv)[0] = sfno;
+    (*priv)[1] = nbuffers;
+    (*priv)[2] = sfpriv->offsets[0] = sfpriv->surface->offset;
+
+    for (i = 1; i < nbuffers; ++i) {
+        (*priv)[i + 2] = sfpriv->offsets[i] = sfpriv->offsets[i - 1] + bufsize;
+    }
+
+    pXvMC->surfaces[sfno] = pSurf->surface_id;
+    pXvMC->sfprivs[sfno]= sfpriv;
+    pXvMC->nsurfaces++;
+
+    return Success;
+}
+
+static int I915XvMCCreateSubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSubp,
+                                     int *num_priv, long **priv )
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+    I915XvMCPtr pXvMC = pI830->xvmc;
+    I915XvMCSurfacePriv *sfpriv = NULL;
+    XvMCContextPtr ctx = NULL;
+    unsigned srfno;
+    unsigned bufsize;
+
+    if (I915_XVMC_MAX_SURFACES == pXvMC->nsurfaces) {
+        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                   "[XvMC] I915XvMCCreateSubpicture: Too many surfaces !\n");
+        return BadAlloc;
+    }
+
+    sfpriv = (I915XvMCSurfacePriv *)xcalloc(1, sizeof(I915XvMCSurfacePriv));
+
+    if (!sfpriv) {
+        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                   "[XvMC] I915XvMCCreateSubpicture: Unable to allocate memory!\n");
+        *num_priv = 0;
+        return BadAlloc;
+    }
+
+    *priv = (INT32 *)xcalloc(3, sizeof(INT32));
+
+    if (!*priv) {
+        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                   "[XvMC] I915XvMCCreateSubpicture: Unable to allocate memory!\n");
+        *num_priv = 0;
+        xfree(sfpriv);
+        return BadAlloc;
+    }
+
+    *num_priv = 2;
+    ctx = pSubp->context;
+    bufsize = size_xx44(ctx->width, ctx->height);
+
+    if (!i830_allocate_xvmc_surface(pScrn, &(sfpriv->surface), bufsize)) {
+        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                   "[XvMC] I915XvMCCreateSurface: Failed to allocate XvMC surface space!\n");
+        xfree(sfpriv);
+        sfpriv = NULL;
+        xfree(*priv);
+        *priv = NULL;
+        *num_priv = 0;
+        return BadAlloc;
+    }
+
+    for (srfno = 0; srfno < I915_XVMC_MAX_SURFACES; ++srfno) {
+        if (0 == pXvMC->sfprivs[srfno])
+            break;
+    }
+
+    (*priv)[0] = srfno;
+    (*priv)[1] = sfpriv->offsets[0] = sfpriv->surface->offset;
+    pXvMC->sfprivs[srfno] = sfpriv;
+    pXvMC->surfaces[srfno] = pSubp->subpicture_id;
+    pXvMC->nsurfaces++;
+
+    return Success;
+}
+
+static void I915XvMCDestroyContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+    I915XvMCPtr pXvMC = pI830->xvmc;
+    int i;
+
+    for (i = 0; i < I915_XVMC_MAX_CONTEXTS; i++) {
+        if (pXvMC->contexts[i] == pContext->context_id) {
+            i915_unmap_xvmc_buffers(pScrn, pXvMC->ctxprivs[i]);
+            i915_free_xvmc_buffers(pScrn, pXvMC->ctxprivs[i]);
+            xfree(pXvMC->ctxprivs[i]);
+            pXvMC->ctxprivs[i] = 0;
+            pXvMC->ncontexts--;
+            pXvMC->contexts[i] = 0;
+            return;
+        }
+    }
+
+    return;
+}
+
+static void I915XvMCDestroySurface (ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+    I915XvMCPtr pXvMC = pI830->xvmc;
+    int i;
+
+    for (i = 0; i < I915_XVMC_MAX_SURFACES; i++) {
+        if (pXvMC->surfaces[i] == pSurf->surface_id) {
+            i830_free_memory(pScrn, pXvMC->sfprivs[i]->surface);            
+            xfree(pXvMC->sfprivs[i]);
+            pXvMC->nsurfaces--;
+            pXvMC->sfprivs[i] = 0;
+            pXvMC->surfaces[i] = 0;
+            return;
+        }
+    }
+
+    return;
+}
+
+static void I915XvMCDestroySubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSubp)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+    I915XvMCPtr pXvMC = pI830->xvmc;
+    int i;
+
+    for (i = 0; i < I915_XVMC_MAX_SURFACES; i++) {
+        if (pXvMC->surfaces[i] == pSubp->subpicture_id) {
+            i830_free_memory(pScrn, pXvMC->sfprivs[i]->surface);            
+            xfree(pXvMC->sfprivs[i]);
+            pXvMC->nsurfaces--;
+            pXvMC->sfprivs[i] = 0;
+            pXvMC->surfaces[i] = 0;
+            return;
+        }
+    }
+
+    return;
+}
+
+/*
+ *
+ */
+static int I915XvMCInterceptXvGetAttribute(ScrnInfoPtr pScrn, Atom attribute,
+                                           INT32 * value, pointer data)
+{
+    unsigned i;
+    I830PortPrivPtr pPriv = (I830PortPrivPtr)data;
+    I915XvMCXVPriv *vx = (I915XvMCXVPriv *)pPriv->xvmc_priv;
+
+    if (I830PTR(pScrn)->XvMCEnabled) {
+        for (i = 0; i < vx->xvAttr.numAttr; ++i) {
+            if (vx->xvAttr.attributes[i].attribute == attribute) {
+                *value = vx->xvAttr.attributes[i].value;
+                return Success;
+            }
+        }
+    }
+
+    return vx->GetPortAttribute(pScrn, attribute, value, data);
+}
+
+static int I915XvMCInterceptXvAttribute(ScrnInfoPtr pScrn, Atom attribute,
+                                        INT32 value, pointer data)
+{
+    unsigned i;
+    I830PortPrivPtr pPriv = (I830PortPrivPtr)data;
+    I915XvMCXVPriv *vx = (I915XvMCXVPriv *)pPriv->xvmc_priv;
+
+    if (I830PTR(pScrn)->XvMCEnabled) {
+        for (i = 0; i < vx->xvAttr.numAttr; ++i) {
+            if (vx->xvAttr.attributes[i].attribute == attribute) {
+                vx->xvAttr.attributes[i].value = value;
+                return Success;
+            }
+        }
+    }
+
+    return vx->SetPortAttribute(pScrn, attribute, value, data);
+}
+
+static int I915XvMCDisplayAttributes(ScrnInfoPtr pScrn,
+                                     const I915XvMCAttrHolder * ah, I830PortPrivPtr pPriv)
+{
+    I915XvMCXVPriv *vx = (I915XvMCXVPriv *) pPriv->xvmc_priv;
+    unsigned i;
+    int ret;
+
+    for (i = 0; i < ah->numAttr; ++i) {
+        ret = vx->SetPortAttribute(pScrn, ah->attributes[i].attribute,
+                                   ah->attributes[i].value, pPriv);
+        if (ret)
+            return ret;
+    }
+
+    return Success;
+}
+
+static int I915XvMCInterceptPutImage(ScrnInfoPtr pScrn, short src_x, short src_y,
+                                     short drw_x, short drw_y, short src_w,
+                                     short src_h, short drw_w, short drw_h,
+                                     int id, unsigned char *buf, short width,
+                                     short height, Bool sync, RegionPtr clipBoxes, pointer data,
+                                     DrawablePtr pDraw)
+{
+    I830PortPrivPtr pPriv = (I830PortPrivPtr)data;
+    I915XvMCXVPriv *vx = (I915XvMCXVPriv *)pPriv->xvmc_priv;
+
+    if (I830PTR(pScrn)->XvMCEnabled) {
+        if (FOURCC_XVMC == id) {
+            I830Ptr pI830 = I830PTR(pScrn);
+            I915XvMCPtr pXvMC = pI830->xvmc;
+            I915XvMCCommandBuffer *i915XvMCData = (I915XvMCCommandBuffer *)buf;
+            int i;
+
+            switch (i915XvMCData->command) {
+            case I915_XVMC_COMMAND_ATTRIBUTES:
+                if ((i915XvMCData->ctxNo | I915_XVMC_VALID) != vx->ctxDisplaying)
+                    return 1;
+
+                I915XvMCDisplayAttributes(pScrn, &i915XvMCData->attrib, pPriv);
+                return 0;
+
+            case I915_XVMC_COMMAND_DISPLAY:
+                for (i = 0; i < I915_XVMC_MAX_SURFACES; i++) {
+                    if (pXvMC->surfaces[i] == i915XvMCData->srfNo) {
+                        i830_memory *mem = pXvMC->sfprivs[i]->surface;
+                        buf = pI830 + mem->offset;
+                        id = i915XvMCData->real_id;
+                        break;
+                    }
+                }
+
+                if (i >= I915_XVMC_MAX_SURFACES)
+                    return 1;
+
+                break;
+
+            default:
+                return 0;
+            }
+        }
+    }
+
+    return vx->PutImage(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);
+}
+
+/*********************************** Public Function **************************************/
+
+/**************************************************************************
+ *
+ *  I915InitMC
+ *
+ *  Inputs:
+ *    Screen pointer
+ *
+ *  Outputs:
+ *    None
+ *  
+ **************************************************************************/
+void I915InitMC(ScreenPtr pScreen)
+{
+    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+    I830Ptr pI830 = I830PTR(pScrn);
+    I915XvMCPtr pXvMC = NULL; 
+
+    pI830->XvMCEnabled = FALSE;
+    if (!pI830->directRenderingEnabled) {
+        xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+                   "[XvMC] Cannot use XvMC without DRI!\n");
+        return;
+    }
+
+    pXvMC = (I915XvMCPtr)calloc(1, sizeof(I915XvMC));
+    if (!pXvMC) {
+        xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+                   "[XvMC] Failure!\n");
+        return;
+    }
+
+    pI830->xvmc = pXvMC;
+    initI915XvMC(pXvMC);
+    xf86XvMCScreenInit(pScreen, 1, ppAdapt);
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+               "[XvMC] Initialized XvMC extension.\n");
+    pI830->XvMCEnabled = TRUE;
+}
+
+int I915XvMCInitXv(ScrnInfoPtr pScrn, XF86VideoAdaptorPtr XvAdapt)
+{
+    I830PortPrivPtr pPriv;
+    I915XvMCXVPriv *vx;
+    unsigned i, j;
+
+    for (j = 0; j < XvAdapt->nPorts; ++j) {
+        pPriv = (I830PortPrivPtr) XvAdapt->pPortPrivates[j].ptr;
+
+        if (NULL == (pPriv->xvmc_priv = xcalloc(1, sizeof(I915XvMCXVPriv)))) {
+            return BadAlloc;
+        }
+
+        for (i = 0; i < I915_NUM_XVMC_ATTRIBUTES; ++i) {
+            attrAtoms[i] = MAKE_ATOM(attrXvMC[i]);
+        }
+
+        vx = (I915XvMCXVPriv *) pPriv->xvmc_priv;
+
+        vx->ctxDisplaying = 0;
+        vx->xvAttr.numAttr = I915_NUM_XVMC_ATTRIBUTES;
+        vx->xvmc_port = -1;
+        vx->newAttribute = 1;
+
+        /* set up wrappers */
+        vx->GetPortAttribute = XvAdapt->GetPortAttribute;
+        vx->SetPortAttribute = XvAdapt->SetPortAttribute;
+        vx->PutImage = XvAdapt->PutImage;
+
+        XvAdapt->GetPortAttribute = I915XvMCInterceptXvGetAttribute;
+        XvAdapt->SetPortAttribute = I915XvMCInterceptXvAttribute;
+        XvAdapt->PutImage = I915XvMCInterceptPutImage;
+
+        for (i = 0; i < I915_NUM_XVMC_ATTRIBUTES; ++i) {
+            vx->xvAttr.attributes[i].attribute = attrAtoms[i];
+            vx->xvAttr.attributes[i].value = 0;
+            vx->GetPortAttribute(pScrn, attrAtoms[i],
+                                 &(vx->xvAttr.attributes[i].value), pPriv);
+        }
+    }
+    return Success;
+}
+
+unsigned long I915XvMCPutImageSize(ScrnInfoPtr pScrn)
+{
+    if (I830PTR(pScrn)->XvMCEnabled)
+        return sizeof(I915XvMCCommandBuffer);
+
+    return 0;
+}
diff --git a/src/i915_hwmc.h b/src/i915_hwmc.h
new file mode 100644
index 0000000..882dea0
--- /dev/null
+++ b/src/i915_hwmc.h
@@ -0,0 +1,64 @@
+#ifndef _I915_HWMC_H
+#define _I915_HWMC_H
+
+#define FOURCC_XVMC     (('C' << 24) + ('M' << 16) + ('V' << 8) + 'X')
+
+#define I915_NUM_XVMC_ATTRIBUTES       0x02
+#define I915_XVMC_VALID 0x80000000
+
+/*
+ * Commands that client submits through XvPutImage:
+ */
+
+#define I915_XVMC_COMMAND_DISPLAY      0x00
+#define I915_XVMC_COMMAND_UNDISPLAY    0x01
+#define I915_XVMC_COMMAND_ATTRIBUTES   0x02
+
+typedef struct
+{
+    INT32 attribute;
+    INT32 value;
+} I915AttrPair;
+
+typedef struct
+{
+    unsigned numAttr;
+    I915AttrPair attributes[I915_NUM_XVMC_ATTRIBUTES];
+} I915XvMCAttrHolder;
+
+typedef struct
+{
+    unsigned command;
+    unsigned ctxNo;
+    unsigned srfNo;
+    unsigned subPicNo;
+    I915XvMCAttrHolder attrib;
+    int real_id;
+    unsigned pad;
+} I915XvMCCommandBuffer;
+
+struct hwmc_buffer
+{
+    unsigned handle;
+    unsigned offset;
+    unsigned size;
+};
+
+typedef struct 
+{
+    unsigned ctxno; /* XvMC private context reference number */
+    drm_context_t drmcontext;
+    struct hwmc_buffer sis;     /* Static Indirect State Buffer */
+    struct hwmc_buffer msb;     /* Map State Block */
+    struct hwmc_buffer ssb;     /* Sampler State Block */
+    struct hwmc_buffer psp;     /* Pixel Shader Program Buffer */
+    struct hwmc_buffer psc;     /* Pixel Shader Constants Buffer */
+    struct hwmc_buffer corrdata;/* Correction Data Buffer */
+    unsigned sarea_size;
+    unsigned sarea_priv_offset;
+    unsigned screen;
+    unsigned depth;
+    I915XvMCAttrHolder initAttrs;
+} I915XvMCCreateContextRec;
+
+#endif /* _I915_HWMC_H */
diff --git a/src/xvmc/I915XvMC.c b/src/xvmc/I915XvMC.c
new file mode 100644
index 0000000..685eea4
--- /dev/null
+++ b/src/xvmc/I915XvMC.c
@@ -0,0 +1,3056 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <string.h>
+#include <assert.h>
+
+#include <pthread.h>
+#include <sys/ioctl.h>
+#include <X11/Xlibint.h>
+#include <fourcc.h>
+#include <X11/extensions/Xv.h>
+#include <X11/extensions/Xvlib.h>
+#include <X11/extensions/XvMC.h>
+#include <X11/extensions/XvMClib.h>
+#include <xf86drm.h>
+#include <drm_sarea.h>
+
+#include "I915XvMC.h"
+#include "i915_structs.h"
+#include "i915_program.h"
+#include "intel_batchbuffer.h"
+#include "xf86dri.h"
+#include "driDrawable.h"
+
+#define SAREAPTR(ctx) ((drmI830Sarea *)                     \
+                       (((CARD8 *)(ctx)->sarea_address) +   \
+                        (ctx)->sarea_priv_offset))
+
+/* Lookup tables to speed common calculations */
+static unsigned mb_bytes[] = {
+    000, 128, 128, 256, 128, 256, 256, 384,  // 0
+    128, 256, 256, 384, 256, 384, 384, 512,  // 1
+    128, 256, 256, 384, 256, 384, 384, 512,  // 10
+    256, 384, 384, 512, 384, 512, 512, 640,  // 11
+    128, 256, 256, 384, 256, 384, 384, 512,  // 100
+    256, 384, 384, 512, 384, 512, 512, 640,  // 101    
+    256, 384, 384, 512, 384, 512, 512, 640,  // 110
+    384, 512, 512, 640, 512, 640, 640, 768   // 111
+};
+
+typedef union {
+    short s[4];
+    uint  u[2];
+} su_t;
+
+static char I915KernelDriverName[] = "i915";
+static int error_base;
+static int event_base;
+
+static int findOverlap(unsigned width, unsigned height,
+                       short *dstX, short *dstY,
+                       short *srcX, short *srcY, 
+                       unsigned short *areaW, unsigned short *areaH)
+{
+    int w, h;
+    unsigned mWidth, mHeight;
+
+    w = *areaW;
+    h = *areaH;
+
+    if ((*dstX >= width) || (*dstY >= height))
+        return 1;
+
+    if (*dstX < 0) {
+        w += *dstX;
+        *srcX -= *dstX;
+        *dstX = 0;
+    }
+
+    if (*dstY < 0) {
+        h += *dstY;
+        *srcY -= *dstY;
+        *dstY = 0;
+    }
+
+    if ((w <= 0) || ((h <= 0)))
+        return 1;
+
+    mWidth = width - *dstX;
+    mHeight = height - *dstY;
+    *areaW = (w <= mWidth) ? w : mWidth;
+    *areaH = (h <= mHeight) ? h : mHeight;
+    return 0;
+}
+
+static void setupAttribDesc(Display * display, XvPortID port,
+                            const I915XvMCAttrHolder * attrib, XvAttribute attribDesc[])
+{  
+    XvAttribute *XvAttribs, *curAD;
+    int num;
+    unsigned i, j;
+
+    XLockDisplay(display);
+    XvAttribs = XvQueryPortAttributes(display, port, &num);
+    for (i = 0; i < attrib->numAttr; ++i) {
+        curAD = attribDesc + i;
+        curAD->flags = 0;
+        curAD->min_value = 0;
+        curAD->max_value = 0;
+        curAD->name = NULL;
+        for (j = 0; j < num; ++j) {
+            if (attrib->attributes[i].attribute ==
+                XInternAtom(display, XvAttribs[j].name, TRUE)) {
+                *curAD = XvAttribs[j];
+                curAD->name = strdup(XvAttribs[j].name);
+                break;
+            }
+        }
+    }
+    if (XvAttribs)
+        XFree(XvAttribs);
+    XUnlockDisplay(display);
+}
+
+static void releaseAttribDesc(int numAttr, XvAttribute attribDesc[])
+{
+    int i;
+
+    for (i = 0; i < numAttr; ++i) {
+        if (attribDesc[i].name)
+            free(attribDesc[i].name);
+    }
+}
+
+static __inline__ void renderError(void) 
+{
+    printf("Invalid Macroblock Parameters found.\n");
+    return;
+}
+
+static void I915XvMCContendedLock(i915XvMCContext *pI915XvMC, unsigned flags)
+{
+    drmGetLock(pI915XvMC->fd, pI915XvMC->hHWContext, flags);
+}
+
+/* Lock the hardware and validate our state.
+ */
+static void LOCK_HARDWARE(i915XvMCContext  *pI915XvMC)
+{
+    char __ret = 0;
+    pthread_mutex_lock(&pI915XvMC->ctxmutex);
+    assert(!pI915XvMC->locked);
+
+    DRM_CAS(pI915XvMC->driHwLock, pI915XvMC->hHWContext,
+            (DRM_LOCK_HELD|pI915XvMC->hHWContext), __ret);
+
+    if (__ret)
+        I915XvMCContendedLock(pI915XvMC, 0);
+
+    pI915XvMC->locked = 1;
+}
+
+/* Unlock the hardware using the global current context
+ */
+static void UNLOCK_HARDWARE(i915XvMCContext *pI915XvMC)
+{
+    pI915XvMC->locked = 0;
+    DRM_UNLOCK(pI915XvMC->fd, pI915XvMC->driHwLock, 
+               pI915XvMC->hHWContext);
+    pthread_mutex_unlock(&pI915XvMC->ctxmutex);
+}
+
+static unsigned stride(int w)
+{
+    return (w + 31) & ~31;
+}
+
+static unsigned long size_y(int w, int h)
+{
+    return stride(w) * h;
+}
+
+static unsigned long size_yuv420(int w, int h)
+{
+    unsigned yPitch = stride(w);
+
+    return h * (yPitch + (yPitch >> 1));
+}
+
+static void i915_flush(i915XvMCContext *pI915XvMC)
+{
+    struct i915_mi_flush mi_flush;
+    unsigned cmd[2];
+
+    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 = 1;
+    mi_flush.dw0.render_cache_flush_inhibit = 1;
+
+    cmd[0] = *(unsigned *)((char *)&mi_flush);
+    cmd[1] = 0;
+    intelCmdIoctl(pI915XvMC, (char *)&cmd[0], sizeof(cmd));
+}
+
+/* for MC picture rendering */
+static void i915_mc_static_indirect_state_buffer(XvMCContext *context, 
+                                                 XvMCSurface *surface,
+                                                 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 w = surface->width, h = surface->height;
+
+    /* 3DSTATE_BUFFER_INFO */
+    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 */
+    buffer_info->dw1.tiled_surface = 0; /* linear */
+    buffer_info->dw1.walk = TILEWALK_XMAJOR;
+    buffer_info->dw1.pitch = stride(w);
+    buffer_info->dw2.base_address = pI915Surface->offsets[pI915Surface->curbuf];
+
+    ++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 = stride(w) >> 1;
+    buffer_info->dw2.base_address = pI915Surface->offsets[pI915Surface->curbuf] 
+        + size_y(w, h);
+
+    ++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 = stride(w) >> 1;
+    buffer_info->dw2.base_address = pI915Surface->offsets[pI915Surface->curbuf] 
+        + size_y(w, h) + (size_y(w, h) >> 2);
+
+    /* 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.v_ls = 0;         /* FIXME */
+    dest_buffer_variables->dw1.v_ls_offset = 0;
+
+    /* 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.decoder_mode = MPEG_DECODE_MC;
+    dest_buffer_variables_mpeg->dw1.rcontrol = 0;       /* for MPEG-2/MPEG-1 */
+    dest_buffer_variables_mpeg->dw1.bidir_avrg_control = 0; 
+    dest_buffer_variables_mpeg->dw1.intra8 = 0;         /* FIXME ? */
+    dest_buffer_variables_mpeg->dw1.tff = 0;            /* FIXME */
+    dest_buffer_variables_mpeg->dw1.picture_width = w >> 4;
+    dest_buffer_variables_mpeg->dw2.picture_coding_type = picture_coding_type;
+
+    /* 3DSATE_BUFFER_INFO */
+    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.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;
+}
+
+static void i915_mc_map_state_buffer(XvMCContext *context, 
+                                     XvMCSurface *target_surface,
+                                     XvMCSurface *past_surface,
+                                     XvMCSurface *future_surface)
+{
+    struct i915_3dstate_map_state *map_state;
+    struct texture_map *tm;
+    i915XvMCSurface *privTarget = NULL;
+    i915XvMCSurface *privPast = NULL;
+    i915XvMCSurface *privFuture = NULL;
+    i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
+    unsigned w = target_surface->width, h = target_surface->height;
+ 
+    privTarget = (i915XvMCSurface *)target_surface->privData;
+
+    /* P Frame Test */
+    if (!past_surface) {
+        privPast = privTarget;
+    } else {
+        if (!past_surface->privData) {
+            printf("Error, Invalid Past Surface!\n");
+            return;
+        }
+
+        privPast = (i915XvMCSurface *)past_surface->privData;
+    }
+
+    /* B Frame Test */
+    if (!future_surface) {
+        privFuture = privPast;
+    } else {
+        if (!future_surface->privData || !past_surface) {
+            printf("Error, Invalid Future Surface or No Past Surface!\n");
+            return;
+        }
+
+        privFuture = (i915XvMCSurface *)future_surface->privData;
+    }
+
+
+    /* 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;
+
+    /* 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 = privPast->offsets[privPast->curbuf];
+    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;
+    tm->tm1.height = h;
+    tm->tm2.depth = 0;
+    tm->tm2.max_lod = 0;
+    tm->tm2.cube_face = 0;
+    tm->tm2.pitch = stride(w);
+
+    /* texture map: Backward */
+    ++tm;
+    memset(tm, 0, sizeof(*tm));
+    tm->tm0.v_ls_offset = 0;
+    tm->tm0.v_ls = 0;
+    tm->tm0.base_address = privFuture->offsets[privFuture->curbuf];
+    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;
+    tm->tm1.height = h;
+    tm->tm2.depth = 0;
+    tm->tm2.max_lod = 0;
+    tm->tm2.cube_face = 0;
+    tm->tm2.pitch = stride(w);
+
+    /* 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;
+
+    /* 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 = privPast->offsets[privPast->curbuf] + size_y(w, h);
+    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;
+    tm->tm1.height = h >> 1;
+    tm->tm2.depth = 0;
+    tm->tm2.max_lod = 0;
+    tm->tm2.cube_face = 0;
+    tm->tm2.pitch = stride(w) >> 1;
+
+    /* texture map: Backward */
+    ++tm;
+    memset(tm, 0, sizeof(*tm));
+    tm->tm0.v_ls_offset = 0;
+    tm->tm0.v_ls = 0;
+    tm->tm0.base_address = privFuture->offsets[privFuture->curbuf] + size_y(w, h);
+    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;
+    tm->tm1.height = h >> 1;
+    tm->tm2.depth = 0;
+    tm->tm2.max_lod = 0;
+    tm->tm2.cube_face = 0;
+    tm->tm2.pitch = stride(w) >> 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;
+
+    /* 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 = privPast->offsets[privPast->curbuf] + size_y(w, h) + (size_y(w, h) >> 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;
+    tm->tm1.height = h >> 1;
+    tm->tm2.depth = 0;
+    tm->tm2.max_lod = 0;
+    tm->tm2.cube_face = 0;
+    tm->tm2.pitch = stride(w) >> 1;
+
+    /* texture map: Backward */
+    ++tm;
+    memset(tm, 0, sizeof(*tm));
+    tm->tm0.v_ls_offset = 0;
+    tm->tm0.v_ls = 0;
+    tm->tm0.base_address = privFuture->offsets[privFuture->curbuf] + size_y(w, h) + (size_y(w, h) >> 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;
+    tm->tm1.height = h >> 1;
+    tm->tm2.depth = 0;
+    tm->tm2.max_lod = 0;
+    tm->tm2.cube_face = 0;
+    tm->tm2.pitch = stride(w) >> 1;
+}
+
+static void i915_mc_load_indirect_buffer(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 size;
+
+    /* 3DSTATE_LOAD_INDIRECT */
+    size = sizeof(*load_indirect) + sizeof(*sis) + sizeof(*msb);
+    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_SIS | BLOCK_MSB;
+    load_indirect->dw0.length = 3;
+
+    /* SIS */
+    sis = (sis_state *)(++load_indirect);
+    sis->dw0.valid = 1;
+    sis->dw0.buffer_address = pI915XvMC->sis.offset;
+    sis->dw1.length = 16; // 4 * 3 + 2 + 3 - 1
+
+    /* MSB */
+    msb = (msb_state *)(++sis);
+    msb->dw0.valid = 1;
+    msb->dw0.buffer_address = pI915XvMC->msb.offset;
+    msb->dw1.length = 23; // 3 * 8 - 1
+
+    intelBatchbufferData(pI915XvMC, base, size, 0);
+    free(base);
+}
+
+static void i915_mc_mpeg_set_origin(XvMCContext *context, XvMCMacroBlock *mb)
+{
+    struct i915_3dmpeg_set_origin set_origin;
+    i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
+
+    /* 3DMPEG_SET_ORIGIN */
+    memset(&set_origin, sizeof(set_origin), 0);
+    set_origin.dw0.type = CMD_3D;
+    set_origin.dw0.opcode = OPC_3DMPEG_SET_ORIGIN;
+    set_origin.dw0.length = 0;
+    set_origin.dw1.h_origin = mb->x;
+    set_origin.dw1.v_origin = mb->y;
+
+    intelBatchbufferData(pI915XvMC, &set_origin, sizeof(set_origin), 0);
+}
+
+static void i915_mc_mpeg_macroblock_0mv(XvMCContext *context, XvMCMacroBlock *mb)
+{
+    struct i915_3dmpeg_macroblock_0mv macroblock_0mv;
+    i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
+
+    /* 3DMPEG_MACROBLOCK(0mv) */
+    memset(&macroblock_0mv, sizeof(macroblock_0mv), 0);
+    macroblock_0mv.header.dw0.type = CMD_3D;
+    macroblock_0mv.header.dw0.opcode = OPC_3DMPEG_MACROBLOCK;
+    macroblock_0mv.header.dw0.length = 0;
+    macroblock_0mv.header.dw1.intra = (mb->macroblock_type & XVMC_MB_TYPE_INTRA);
+    macroblock_0mv.header.dw1.forward = 0;      /* should be 0 */
+    macroblock_0mv.header.dw1.backward = 0;     /* should be 0 */
+    macroblock_0mv.header.dw1.h263_4mv = 0;     /* should be 0 */
+    macroblock_0mv.header.dw1.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD);
+    
+    if (!mb->coded_block_pattern)       /* FIXME */
+        macroblock_0mv.header.dw1.dct_type = XVMC_DCT_TYPE_FRAME;
+
+    macroblock_0mv.header.dw1.motion_type = mb->motion_type;
+    macroblock_0mv.header.dw1.vertical_field_select = mb->motion_vertical_field_select;
+    macroblock_0mv.header.dw1.coded_block_pattern = mb->coded_block_pattern; /* FIXME */
+    macroblock_0mv.header.dw1.skipped_macroblocks = 0;      /* FIXME */
+    
+    intelBatchbufferData(pI915XvMC, &macroblock_0mv, sizeof(macroblock_0mv), 0);
+}
+
+static void i915_mc_mpeg_macroblock_1fbmv(XvMCContext *context, XvMCMacroBlock *mb)
+{
+    struct i915_3dmpeg_macroblock_1fbmv macroblock_1fbmv;
+    i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
+    
+    /* Motion Vectors */
+    su_t fmv;
+    su_t bmv;
+
+    /* 3DMPEG_MACROBLOCK(1fbmv) */
+    memset(&macroblock_1fbmv, sizeof(macroblock_1fbmv), 0);
+    macroblock_1fbmv.header.dw0.type = CMD_3D;
+    macroblock_1fbmv.header.dw0.opcode = OPC_3DMPEG_MACROBLOCK;
+    macroblock_1fbmv.header.dw0.length = 2;
+    macroblock_1fbmv.header.dw1.intra = (mb->macroblock_type & XVMC_MB_TYPE_INTRA);
+    macroblock_1fbmv.header.dw1.forward = (mb->macroblock_type & XVMC_MB_TYPE_MOTION_FORWARD);
+    macroblock_1fbmv.header.dw1.backward = (mb->macroblock_type & XVMC_MB_TYPE_MOTION_BACKWARD);
+    macroblock_1fbmv.header.dw1.h263_4mv = 0;     /* should be 0 */
+    macroblock_1fbmv.header.dw1.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD);
+    
+    if (!mb->coded_block_pattern)       /* FIXME */
+        macroblock_1fbmv.header.dw1.dct_type = XVMC_DCT_TYPE_FRAME;
+
+    macroblock_1fbmv.header.dw1.motion_type = mb->motion_type;
+    macroblock_1fbmv.header.dw1.vertical_field_select = mb->motion_vertical_field_select;
+    macroblock_1fbmv.header.dw1.coded_block_pattern = mb->coded_block_pattern; /* FIXME */
+    macroblock_1fbmv.header.dw1.skipped_macroblocks = 0;      /* FIXME */
+
+    fmv.s[0] = mb->PMV[0][0][1];
+    fmv.s[1] = mb->PMV[0][0][0];
+    bmv.s[0] = mb->PMV[0][1][1];
+    bmv.s[1] = mb->PMV[0][1][0];
+
+    macroblock_1fbmv.dw2 = fmv.u[0];
+    macroblock_1fbmv.dw3 = bmv.u[0];
+    
+    intelBatchbufferData(pI915XvMC, &macroblock_1fbmv, sizeof(macroblock_1fbmv), 0);
+}
+
+static void i915_mc_mpeg_macroblock_2fbmv(XvMCContext *context, XvMCMacroBlock *mb)
+{
+    struct i915_3dmpeg_macroblock_2fbmv macroblock_2fbmv;
+    i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
+    
+    /* Motion Vectors */
+    su_t fmv;
+    su_t bmv;
+
+    /* 3DMPEG_MACROBLOCK(2fbmv) */
+    memset(&macroblock_2fbmv, sizeof(macroblock_2fbmv), 0);
+    macroblock_2fbmv.header.dw0.type = CMD_3D;
+    macroblock_2fbmv.header.dw0.opcode = OPC_3DMPEG_MACROBLOCK;
+    macroblock_2fbmv.header.dw0.length = 2;
+    macroblock_2fbmv.header.dw1.intra = (mb->macroblock_type & XVMC_MB_TYPE_INTRA);
+    macroblock_2fbmv.header.dw1.forward = (mb->macroblock_type & XVMC_MB_TYPE_MOTION_FORWARD);
+    macroblock_2fbmv.header.dw1.backward = (mb->macroblock_type & XVMC_MB_TYPE_MOTION_BACKWARD);
+    macroblock_2fbmv.header.dw1.h263_4mv = 0;     /* should be 0 */
+    macroblock_2fbmv.header.dw1.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD);
+    
+    if (!mb->coded_block_pattern)       /* FIXME */
+        macroblock_2fbmv.header.dw1.dct_type = XVMC_DCT_TYPE_FRAME;
+
+    macroblock_2fbmv.header.dw1.motion_type = mb->motion_type;
+    macroblock_2fbmv.header.dw1.vertical_field_select = mb->motion_vertical_field_select;
+    macroblock_2fbmv.header.dw1.coded_block_pattern = mb->coded_block_pattern; /* FIXME */
+    macroblock_2fbmv.header.dw1.skipped_macroblocks = 0;      /* FIXME */
+
+    fmv.s[0] = mb->PMV[0][0][1];
+    fmv.s[1] = mb->PMV[0][0][0];
+    fmv.s[2] = mb->PMV[1][0][1];
+    fmv.s[3] = mb->PMV[1][0][0];
+    bmv.s[0] = mb->PMV[0][1][1];
+    bmv.s[1] = mb->PMV[0][1][0];
+    bmv.s[2] = mb->PMV[1][1][1];
+    bmv.s[3] = mb->PMV[1][1][0];
+
+    macroblock_2fbmv.dw2 = fmv.u[0];
+    macroblock_2fbmv.dw3 = bmv.u[0];
+    macroblock_2fbmv.dw4 = fmv.u[1];
+    macroblock_2fbmv.dw5 = bmv.u[1];
+
+    intelBatchbufferData(pI915XvMC, &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;
+    ts->ts0.shadow_enable = 0;
+    ts->ts0.max_anisotropy = ANISORATIO_2;
+    ts->ts0.shadow_function = PREFILTEROP_ALWAYS;
+    ts->ts1.min_lod = 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;
+    ts->ts0.shadow_enable = 0;
+    ts->ts0.max_anisotropy = ANISORATIO_2;
+    ts->ts0.shadow_function = PREFILTEROP_ALWAYS;
+    ts->ts1.min_lod = 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;
+}
+
+static void i915_inst_arith(unsigned *inst,
+                            unsigned op,
+                            unsigned dest,
+                            unsigned mask,
+                            unsigned saturate,
+                            unsigned src0, unsigned src1, unsigned src2)
+{
+    dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest));
+    *(inst++) = (op | A0_DEST(dest) | mask | saturate | A0_SRC0(src0));
+    *(inst++) = (A1_SRC0(src0) | A1_SRC1(src1));
+    *(inst++) = (A2_SRC1(src1) | A2_SRC2(src2));
+}
+
+static void i915_inst_decl(unsigned *inst, 
+                           unsigned type,
+                           unsigned nr,
+                           unsigned d0_flags)
+{
+    unsigned reg = UREG(type, nr);
+    
+    *(inst++) = (D0_DCL | D0_DEST(reg) | d0_flags);
+    *(inst++) = D1_MBZ;
+    *(inst++) = D2_MBZ;
+}
+
+static void i915_inst_texld(unsigned *inst,
+                            unsigned op,
+                            unsigned dest,
+                            unsigned sampler,
+                            unsigned coord)
+{
+    dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest));
+    *(inst++) = (op | T0_DEST(dest) | T0_SAMPLER(sampler));
+    *(inst++) = T1_ADDRESS_REG(coord);
+    *(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 *inst;
+    unsigned 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;
+    inst = (unsigned *)(++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;
+    inst = (unsigned *)(++pixel_shader_program);
+    i915_inst_decl(inst, REG_TYPE_T, T_TEX0, D0_CHANNEL_XY);
+    inst += 3;
+    i915_inst_decl(inst, REG_TYPE_T, T_TEX1, D0_CHANNEL_XY);
+    inst += 3;
+    i915_inst_decl(inst, REG_TYPE_S, 0, D0_SAMPLE_TYPE_2D);
+    inst += 3;
+    dest = UREG(REG_TYPE_R, 0); 
+    src0 = UREG(REG_TYPE_S, 0); /* SAMPLER */
+    src1 = UREG(REG_TYPE_T, 0); /* COORD */
+    i915_inst_texld(inst, T0_TEXLD, dest, src0, src1);
+    inst += 3;
+    dest = UREG(REG_TYPE_OC, 0);
+    src0 = UREG(REG_TYPE_S, 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;
+    inst = (unsigned *)(++pixel_shader_program);
+    i915_inst_decl(inst, REG_TYPE_T, T_TEX2, D0_CHANNEL_XY);
+    inst += 3;
+    i915_inst_decl(inst, REG_TYPE_T, T_TEX3, D0_CHANNEL_XY);
+    inst += 3;
+    i915_inst_decl(inst, REG_TYPE_S, 1, D0_SAMPLE_TYPE_2D);
+    inst += 3;
+    dest = UREG(REG_TYPE_R, 0); 
+    src0 = UREG(REG_TYPE_S, 1); /* SAMPLER */
+    src1 = UREG(REG_TYPE_T, 2); /* COORD */
+    i915_inst_texld(inst, T0_TEXLD, dest, src0, src1);
+    inst += 3;
+    dest = UREG(REG_TYPE_OC, 0);
+    src0 = UREG(REG_TYPE_S, 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;
+    inst = (unsigned *)(++pixel_shader_program);
+    i915_inst_decl(inst, REG_TYPE_T, T_TEX0, D0_CHANNEL_XY);
+    inst += 3;
+    i915_inst_decl(inst, REG_TYPE_T, T_TEX1, D0_CHANNEL_XY);
+    inst += 3;
+    i915_inst_decl(inst, REG_TYPE_T, T_TEX2, D0_CHANNEL_XY);
+    inst += 3;
+    i915_inst_decl(inst, REG_TYPE_T, T_TEX3, D0_CHANNEL_XY);
+    inst += 3;
+    i915_inst_decl(inst, REG_TYPE_S, 0, D0_SAMPLE_TYPE_2D);
+    inst += 3;
+    i915_inst_decl(inst, REG_TYPE_S, 1, D0_SAMPLE_TYPE_2D);
+    inst += 3;
+    dest = UREG(REG_TYPE_R, 0); 
+    src0 = UREG(REG_TYPE_S, 0); /* SAMPLER */
+    src1 = UREG(REG_TYPE_T, 0); /* COORD */
+    i915_inst_texld(inst, T0_TEXLD, dest, src0, src1);
+    inst += 3;
+    dest = UREG(REG_TYPE_R, 1); 
+    src0 = UREG(REG_TYPE_S, 1); /* SAMPLER */
+    src1 = UREG(REG_TYPE_T, 2); /* COORD */
+    i915_inst_texld(inst, T0_TEXLD, dest, src0, src1);
+    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,
+                    A0_DEST_SATURATE, src0, src1, src2);
+    inst += 3;
+    dest = UREG(REG_TYPE_OC, 0);
+    src0 = UREG(REG_TYPE_R, 0);
+    src1 = UREG(REG_TYPE_OC, 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 size;
+    void *base = NULL;
+
+    /* 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 = 1;
+
+    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(pI915XvMC, 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 = 6;
+
+    /* 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.buffer_address = pI915XvMC->ssb.offset;
+    ssb->dw1.length = 8;
+
+    /* PSP */
+    psp = (psp_state *)(++ssb);
+    psp->dw0.valid = 1;
+    psp->dw0.buffer_address = pI915XvMC->psp.offset;
+    psp->dw1.length = 67; // 4 + 16 + 16 + 31
+    
+    /* PSC */
+    psc = (psc_state *)(++psp);
+    psc->dw0.valid = 1;
+    psc->dw0.buffer_address = pI915XvMC->psc.offset;
+    psc->dw1.length = 6;
+
+    intelBatchbufferData(pI915XvMC, base, size, 0);
+    free(base);
+}
+
+static int i915_xvmc_map_buffers(i915XvMCContext *pI915XvMC)
+{
+    if (drmMap(pI915XvMC->fd,
+               pI915XvMC->sis.handle,
+               pI915XvMC->sis.size,
+               (drmAddress *)pI915XvMC->sis.map) != 0) {
+        return -1;
+    }
+
+    if (drmMap(pI915XvMC->fd,
+               pI915XvMC->msb.handle,
+               pI915XvMC->msb.size,
+               (drmAddress *)pI915XvMC->msb.map) != 0) {
+        return -1;
+    }
+
+    if (drmMap(pI915XvMC->fd,
+               pI915XvMC->ssb.handle,
+               pI915XvMC->ssb.size,
+               (drmAddress *)pI915XvMC->ssb.map) != 0) {
+        return -1;
+    }
+
+    if (drmMap(pI915XvMC->fd,
+               pI915XvMC->psp.handle,
+               pI915XvMC->psp.size,
+               (drmAddress *)pI915XvMC->psp.map) != 0) {
+        return -1;
+    }
+
+    if (drmMap(pI915XvMC->fd,
+               pI915XvMC->psc.handle,
+               pI915XvMC->psc.size,
+               (drmAddress *)pI915XvMC->psc.map) != 0) {
+        return -1;
+    }
+
+    if (drmMap(pI915XvMC->fd,
+               pI915XvMC->corrdata.handle,
+               pI915XvMC->corrdata.size,
+               (drmAddress *)pI915XvMC->corrdata.map) != 0) {
+        return -1;
+    }
+
+    return 0;
+}
+
+static void i915_xvmc_unmap_buffers(i915XvMCContext *pI915XvMC)
+{
+    if (pI915XvMC->sis.map) {
+        drmUnmap(pI915XvMC->sis.map, pI915XvMC->sis.size);
+        pI915XvMC->sis.map = NULL;
+    }
+
+    if (pI915XvMC->msb.map) {
+        drmUnmap(pI915XvMC->msb.map, pI915XvMC->msb.size);
+        pI915XvMC->msb.map = NULL;
+    }
+
+    if (pI915XvMC->ssb.map) {
+        drmUnmap(pI915XvMC->ssb.map, pI915XvMC->ssb.size);
+        pI915XvMC->ssb.map = NULL;
+    }
+
+    if (pI915XvMC->psp.map) {
+        drmUnmap(pI915XvMC->psp.map, pI915XvMC->psp.size);
+        pI915XvMC->psp.map = NULL;
+    }
+
+    if (pI915XvMC->psc.map) {
+        drmUnmap(pI915XvMC->psc.map, pI915XvMC->psc.size);
+        pI915XvMC->psc.map = NULL;
+    }
+
+    if (pI915XvMC->corrdata.map) {
+        drmUnmap(pI915XvMC->corrdata.map, pI915XvMC->corrdata.size);
+        pI915XvMC->corrdata.map = NULL;
+    }
+}
+
+/*
+ * Video post processing 
+ */
+static void i915_yuv2rgb_map_state_buffer(XvMCSurface *target_surface)
+{
+    struct i915_3dstate_map_state *map_state;
+    struct texture_map *tm;
+    i915XvMCSurface *privTarget = NULL;
+    i915XvMCContext *pI915XvMC = NULL;
+    unsigned w = target_surface->width, h = target_surface->height;
+
+    privTarget = (i915XvMCSurface *)target_surface->privData;
+    pI915XvMC = (i915XvMCContext *)privTarget->privContext;
+    /* 3DSATE_MAP_STATE */
+    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 = 0;
+    map_state->dw0.length = 9;
+    map_state->dw1.map_mask = MAP_MAP0 | MAP_MAP1 | MAP_MAP2;
+
+    /* texture map 0: V Plane */
+    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 = privTarget->offsets[privTarget->curbuf] + size_y(w, h);
+    tm->tm1.tile_walk = TILEWALK_XMAJOR;
+    tm->tm1.tiled_surface = 0;
+    tm->tm1.utilize_fence_regs = 1;
+    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 = (stride(w) >> 1) - 1;
+
+    /* texture map 1: Y Plane */
+    ++tm;
+    memset(tm, 0, sizeof(*tm));
+    tm->tm0.v_ls_offset = 0;
+    tm->tm0.v_ls = 0;
+    tm->tm0.base_address = privTarget->offsets[privTarget->curbuf];
+    tm->tm1.tile_walk = TILEWALK_XMAJOR;
+    tm->tm1.tiled_surface = 0;
+    tm->tm1.utilize_fence_regs = 1;
+    tm->tm1.texel_fmt = 0;
+    tm->tm1.surface_fmt = 1;
+    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 = stride(w) - 1;
+
+    /* texture map 2: U Plane */
+    ++tm;
+    memset(tm, 0, sizeof(*tm));
+    tm->tm0.v_ls_offset = 0;
+    tm->tm0.v_ls = 0;
+    tm->tm0.base_address = privTarget->offsets[privTarget->curbuf] + size_y(w, h) + (size_y(w, h) >> 2);
+    tm->tm1.tile_walk = TILEWALK_XMAJOR;
+    tm->tm1.tiled_surface = 0;
+    tm->tm1.utilize_fence_regs = 1;
+    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 = (stride(w) >> 1) - 1;
+}
+
+static void i915_yuv2rgb_sampler_state_buffer(XvMCSurface *surface)
+{
+    struct i915_3dstate_sampler_state *sampler_state;
+    struct texture_sampler *ts;
+    i915XvMCSurface *privSurface = (i915XvMCSurface *)surface->privData;
+    i915XvMCContext *pI915XvMC = (i915XvMCContext *)privSurface->privContext;
+    
+    /* 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 = 9;
+    sampler_state->dw1.sampler_masker = SAMPLER_SAMPLER0 | SAMPLER_SAMPLER1 | SAMPLER_SAMPLER2;
+
+    /* Sampler 0 */
+    ts = (struct texture_sampler *)(++sampler_state);
+    memset(ts, 0, sizeof(*ts));
+    ts->ts0.reverse_gamma = 0;
+    ts->ts0.planar2packet = 1;
+    ts->ts0.color_conversion = 1;
+    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;
+    ts->ts0.shadow_enable = 0;
+    ts->ts0.max_anisotropy = ANISORATIO_2;
+    ts->ts0.shadow_function = PREFILTEROP_ALWAYS;
+    ts->ts1.min_lod = 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 = 1;
+    ts->ts0.color_conversion = 1;
+    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;
+    ts->ts0.shadow_enable = 0;
+    ts->ts0.max_anisotropy = ANISORATIO_2;
+    ts->ts0.shadow_function = PREFILTEROP_ALWAYS;
+    ts->ts1.min_lod = 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 2 */
+    ++ts;
+    memset(ts, 0, sizeof(*ts));
+    ts->ts0.reverse_gamma = 0;
+    ts->ts0.planar2packet = 1;
+    ts->ts0.color_conversion = 1;
+    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;
+    ts->ts0.shadow_enable = 0;
+    ts->ts0.max_anisotropy = ANISORATIO_2;
+    ts->ts0.shadow_function = PREFILTEROP_ALWAYS;
+    ts->ts1.min_lod = 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;
+}
+
+static void i915_yuv2rgb_static_indirect_state_buffer(XvMCSurface *surface,
+                                                      unsigned dstaddr, 
+                                                      int dstpitch)
+{
+    struct i915_3dstate_buffer_info *buffer_info;
+    struct i915_3dstate_dest_buffer_variables *dest_buffer_variables;
+    i915XvMCSurface *privSurface = (i915XvMCSurface *)surface->privData;
+    i915XvMCContext *pI915XvMC = (i915XvMCContext *)privSurface->privContext;
+
+    /* 3DSTATE_BUFFER_INFO */
+    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 = 1;   
+    buffer_info->dw1.tiled_surface = 0;   /* linear */
+    buffer_info->dw1.walk = TILEWALK_XMAJOR;
+    buffer_info->dw1.pitch = dstpitch;
+    buffer_info->dw2.base_address = dstaddr;
+
+    /* 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; /* FIXME 0x1000 .5 ??? */
+    dest_buffer_variables->dw1.dest_h_bias = 8;
+    dest_buffer_variables->dw1.color_fmt = COLORBUFFER_A8R8G8B8;  /* FIXME */
+}
+
+static void i915_yuv2rgb_pixel_shader_program_buffer(XvMCSurface *surface)
+{
+    struct i915_3dstate_pixel_shader_program *pixel_shader_program;
+    i915XvMCSurface *privSurface = (i915XvMCSurface *)surface->privData;
+    i915XvMCContext *pI915XvMC = (i915XvMCContext *)privSurface->privContext;
+    unsigned *inst;
+    unsigned dest, src0, src1;
+
+    /* 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 = 0;
+    pixel_shader_program->dw0.length = 23;
+    inst = (unsigned *)(++pixel_shader_program);
+    i915_inst_decl(inst, REG_TYPE_T, T_TEX0, D0_CHANNEL_XY);
+    inst += 3;
+    i915_inst_decl(inst, REG_TYPE_T, T_TEX1, D0_CHANNEL_XY);
+    inst += 3;
+    i915_inst_decl(inst, REG_TYPE_S, 0, D0_SAMPLE_TYPE_2D);
+    inst += 3;
+    i915_inst_decl(inst, REG_TYPE_S, 1, D0_SAMPLE_TYPE_2D);
+    inst += 3;
+    i915_inst_decl(inst, REG_TYPE_S, 2, D0_SAMPLE_TYPE_2D);
+    inst += 3;
+    dest = UREG(REG_TYPE_R, 0); 
+    src0 = UREG(REG_TYPE_S, 0); /* SAMPLER */
+    src1 = UREG(REG_TYPE_T, 1); /* COORD */
+    i915_inst_texld(inst, T0_TEXLD, dest, src0, src1);
+    inst += 3;
+    dest = UREG(REG_TYPE_R, 0); 
+    src0 = UREG(REG_TYPE_S, 1); /* SAMPLER */
+    src1 = UREG(REG_TYPE_T, 0); /* COORD */
+    i915_inst_texld(inst, T0_TEXLD, dest, src0, src1);
+    inst += 3;
+    dest = UREG(REG_TYPE_OC, 0);
+    src0 = UREG(REG_TYPE_S, 2);
+    src1 = UREG(REG_TYPE_T, 1);
+    i915_inst_texld(inst, T0_TEXLD, dest, src0, src1);
+}
+
+static void i915_yuv2rgb_proc(XvMCSurface *surface)
+{
+    i915XvMCSurface *privSurface = (i915XvMCSurface *)surface->privData;
+    i915XvMCContext *pI915XvMC = (i915XvMCContext *)privSurface->privContext;
+    struct i915_3dstate_load_state_immediate_1 *load_state_immediate_1 = NULL;
+    struct s2_dword *s2 = NULL;
+    struct s3_dword *s3 = NULL;
+    struct s4_dword *s4 = NULL;
+    struct s5_dword *s5 = NULL;
+    struct s6_dword *s6 = NULL;
+    struct s7_dword *s7 = NULL;
+    struct i915_3dstate_scissor_rectangle scissor_rectangle;
+    struct i915_3dstate_load_indirect *load_indirect = NULL;
+    sis_state *sis = NULL;
+    ssb_state *ssb = NULL;
+    msb_state *msb = NULL;
+    psp_state *psp = NULL;
+    struct i915_3dprimitive *_3dprimitive = NULL;
+    struct vertex_data *vd = NULL;
+    unsigned size;
+    void *base = NULL;
+
+    /* 3DSTATE_LOAD_STATE_IMMEDIATE_1 */
+    size = sizeof(*load_state_immediate_1) + sizeof(*s2) + sizeof(*s3) +
+        sizeof(*s4) + sizeof(*s5) + sizeof(*s6) + sizeof(*s7);
+    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_s2 = 1;
+    load_state_immediate_1->dw0.load_s3 = 1;
+    load_state_immediate_1->dw0.load_s4 = 1;
+    load_state_immediate_1->dw0.load_s5 = 1;
+    load_state_immediate_1->dw0.load_s6 = 1;
+    load_state_immediate_1->dw0.load_s7 = 1;
+    load_state_immediate_1->dw0.length = 5;
+
+    s2 = (struct s2_dword *)(++load_state_immediate_1);
+    s2->set0_texcoord_fmt = TEXCOORDFMT_2FP;
+    s2->set1_texcoord_fmt = TEXCOORDFMT_2FP;
+    s2->set2_texcoord_fmt = TEXCOORDFMT_NOT_PRESENT;
+    s2->set3_texcoord_fmt = TEXCOORDFMT_NOT_PRESENT;
+    s2->set4_texcoord_fmt = TEXCOORDFMT_NOT_PRESENT;
+    s2->set5_texcoord_fmt = TEXCOORDFMT_NOT_PRESENT;
+    s2->set6_texcoord_fmt = TEXCOORDFMT_NOT_PRESENT;
+    s2->set7_texcoord_fmt = TEXCOORDFMT_NOT_PRESENT;
+
+    s3 = (struct s3_dword *)(++s2);
+    s4 = (struct s4_dword *)(++s3);
+    s4->position_mask = VERTEXHAS_XY;
+    s4->cull_mode = CULLMODE_NONE;
+    s4->color_shade_mode = SHADEMODE_FLAT;
+    s4->specular_shade_mode = SHADEMODE_FLAT;
+    s4->fog_shade_mode = SHADEMODE_FLAT;
+    s4->alpha_shade_mode = SHADEMODE_FLAT;
+    s4->line_width = 0x2;     /* FIXME: 1.0??? */
+    s4->point_width = 0x1; 
+
+    s5 = (struct s5_dword *)(++s4);
+    s6 = (struct s6_dword *)(++s5);
+    s6->src_blend_factor = 1;
+    s6->dest_blend_factor = 1;
+    s6->color_buffer_write = 1;
+
+    s7 = (struct s7_dword *)(++s6);
+    intelBatchbufferData(pI915XvMC, base, size, 0);
+    free(base);
+
+    /* 3DSTATE_3DSTATE_SCISSOR_RECTANGLE */
+    scissor_rectangle.dw0.type = CMD_3D;
+    scissor_rectangle.dw0.opcode = OPC_3DSTATE_SCISSOR_RECTANGLE;
+    scissor_rectangle.dw0.length = 1;
+    scissor_rectangle.dw1.min_x = 0;
+    scissor_rectangle.dw1.min_y = 0;
+    scissor_rectangle.dw2.max_x = 2047;
+    scissor_rectangle.dw2.max_y = 2047;
+    intelBatchbufferData(pI915XvMC, &scissor_rectangle, sizeof(scissor_rectangle), 0);
+
+    /* 3DSTATE_LOAD_INDIRECT */
+    size = sizeof(*load_indirect) + sizeof(*sis) + sizeof(*ssb) + sizeof(*msb) + sizeof(*psp);
+    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_SIS | BLOCK_SSB | BLOCK_MSB | BLOCK_PSP;
+    load_indirect->dw0.length = 7;
+
+    /* SIS */
+    sis = (sis_state *)(++load_indirect);
+    sis->dw0.valid = 1;
+    sis->dw0.buffer_address = pI915XvMC->sis.offset;
+    sis->dw1.length = ((sizeof(struct i915_3dstate_buffer_info) +
+                        sizeof(struct i915_3dstate_dest_buffer_variables)) >> 2) - 1;
+
+    /* SSB */
+    ssb = (ssb_state *)(++sis);
+    ssb->dw0.valid = 1;
+    ssb->dw0.buffer_address = pI915XvMC->ssb.offset;
+    ssb->dw1.length = ((sizeof(struct i915_3dstate_sampler_state) + 
+                        sizeof(struct texture_sampler) * 3) >> 2) - 1;
+
+    /* MSB */
+    msb = (msb_state *)(++ssb);
+    msb->dw0.valid = 1;
+    msb->dw0.buffer_address = pI915XvMC->msb.offset;
+    msb->dw1.length = ((sizeof(struct i915_3dstate_map_state) + 
+                        sizeof(struct texture_map) * 3) >> 2) - 1;
+
+    /* PSP */
+    psp = (psp_state *)(++msb);
+    psp->dw0.valid = 1;
+    psp->dw0.buffer_address = pI915XvMC->psp.offset;
+    psp->dw1.length = ((sizeof(struct i915_3dstate_pixel_shader_program) +
+                        sizeof(union shader_inst)) >> 2) - 1;
+
+    intelBatchbufferData(pI915XvMC, base, size, 0);
+    free(base);
+
+    /* 3DPRIMITIVE */
+    size = sizeof(*_3dprimitive) + sizeof(*vd) * 3;
+    base = calloc(1, size);
+    _3dprimitive = (struct i915_3dprimitive *)base;
+    _3dprimitive->dw0.inline_prim.type = CMD_3D;
+    _3dprimitive->dw0.inline_prim.opcode = OPC_3DPRIMITIVE;
+    _3dprimitive->dw0.inline_prim.vertex_location = VERTEX_INLINE;
+    _3dprimitive->dw0.inline_prim.prim = PRIM_RECTLIST;
+    _3dprimitive->dw0.inline_prim.length = size - 2;
+
+    vd = (struct vertex_data *)(++_3dprimitive);
+    vd->x = 0;          /* FIXME!!! */
+    vd->x = 0;          /* FIXME */
+    vd->tc0.tcx = 0;
+    vd->tc0.tcy = 0;
+    vd->tc1.tcx = 0;
+    vd->tc1.tcy = 0;
+
+    ++vd;
+    vd->x = 0;          /* FIXME!!! */
+    vd->x = 0;          /* FIXME */
+    vd->tc0.tcx = 0;
+    vd->tc0.tcy = 0;
+    vd->tc1.tcx = 0;
+    vd->tc1.tcy = 0;
+
+    ++vd;
+    vd->x = 0;          /* FIXME!!! */
+    vd->x = 0;          /* FIXME */
+    vd->tc0.tcx = 0;
+    vd->tc0.tcy = 0;
+    vd->tc1.tcx = 0;
+    vd->tc1.tcy = 0;
+
+    intelBatchbufferData(pI915XvMC, base, size, 0);
+    free(base);
+}
+
+/***************************************************************************
+// Function: i915_release_resource
+// Description:
+***************************************************************************/
+static void i915_release_resource(Display *display, XvMCContext *context)
+{
+    i915XvMCContext *pI915XvMC;
+
+    if (!display || !context)
+        return;
+
+    if (!(pI915XvMC = context->privData))
+        return;
+
+    pI915XvMC->ref--;
+    i915_xvmc_unmap_buffers(pI915XvMC);
+    releaseAttribDesc(pI915XvMC->attrib.numAttr, pI915XvMC->attribDesc);
+
+    driDestroyHashContents(pI915XvMC->drawHash);
+    drmHashDestroy(pI915XvMC->drawHash);
+
+    pthread_mutex_destroy(&pI915XvMC->ctxmutex);
+
+    XLockDisplay(display);
+    uniDRIDestroyContext(display, pI915XvMC->screen, pI915XvMC->id);
+    XUnlockDisplay(display);
+
+    intelDestroyBatchBuffer(pI915XvMC);
+    drmUnmap(pI915XvMC->sarea_address, pI915XvMC->sarea_size);
+
+    if (pI915XvMC->fd >= 0)
+        drmClose(pI915XvMC->fd);
+    pI915XvMC->fd = -1;
+
+    XLockDisplay(display);
+    uniDRICloseConnection(display, pI915XvMC->screen);
+    _xvmc_destroy_context(display, context);
+    XUnlockDisplay(display);
+
+    free(pI915XvMC);
+    context->privData = NULL;
+}
+
+/***************************************************************************
+// Function: XvMCCreateContext
+// Description: Create a XvMC context for the given surface parameters.
+// Arguments:
+//   display - Connection to the X server.
+//   port - XvPortID to use as avertised by the X connection.
+//   surface_type_id - Unique identifier for the Surface type.
+//   width - Width of the surfaces.
+//   height - Height of the surfaces.
+//   flags - one or more of the following
+//      XVMC_DIRECT - A direct rendered context is requested.
+//
+// Notes: surface_type_id and width/height parameters must match those
+//        returned by XvMCListSurfaceTypes.
+// Returns: Status
+***************************************************************************/
+Status XvMCCreateContext(Display *display, XvPortID port,
+                         int surface_type_id, int width, int height, 
+                         int flags, XvMCContext *context) 
+{  
+    i915XvMCContext *pI915XvMC = NULL;
+    I915XvMCCreateContextRec *tmpComm = NULL;
+    Status ret;
+    drm_sarea_t *pSAREA;
+    char *curBusID;
+    uint *priv_data = NULL;
+    uint magic;
+    int major, minor;
+    int priv_count;
+    int isCapable;
+
+    /* Verify Obvious things first */
+    if (!display || !context)
+        return BadValue;
+
+    if (!(flags & XVMC_DIRECT)) {
+        /* Indirect */
+        printf("Indirect Rendering not supported! Using Direct.\n");
+        return BadAccess;
+    }
+
+    /* Limit use to root for now */
+    /* FIXME: remove it ??? */
+    if (geteuid()) {
+        printf("Use of XvMC on i915 is currently limited to root\n");
+        return BadAccess;
+    }
+
+    /*
+     *FIXME: Check $DISPLAY for legal values here
+     */
+    context->surface_type_id = surface_type_id;
+    context->width = (unsigned short)((width + 15) & ~15);
+    context->height = (unsigned short)((height + 15) & ~15);
+    context->flags = flags;
+    context->port = port;
+
+    /* 
+       Width, Height, and flags are checked against surface_type_id
+       and port for validity inside the X server, no need to check
+       here.
+    */
+
+    /* Verify the XvMC extension exists */
+    XLockDisplay(display);
+    if (!XvMCQueryExtension(display, &event_base, &error_base)) {
+        printf("XvMCExtension is not available!\n");
+        XUnlockDisplay(display);
+        return BadAlloc;
+    }
+    /* Verify XvMC version */
+    ret = XvMCQueryVersion(display, &major, &minor);
+    if (ret) {
+        printf("XvMCQueryVersion Failed, unable to determine protocol version\n");
+    }
+    XUnlockDisplay(display);
+    /* FIXME: Check Major and Minor here */
+
+    /* Allocate private Context data */
+    context->privData = (void *)malloc(sizeof(i915XvMCContext));
+    if (!context->privData) {
+        printf("Unable to allocate resources for XvMC context.\n");
+        return BadAlloc;
+    }
+    pI915XvMC = (i915XvMCContext *)context->privData;
+
+    /* Check for drm */
+    if (!drmAvailable()) {
+        printf("Direct Rendering is not avilable on this system!\n");
+        free(pI915XvMC);
+        context->privData = NULL;
+        return BadAccess;
+    }
+
+    /*
+      Pass control to the X server to create a drm_context_t for us and
+      validate the with/height and flags.
+    */
+    if ((ret = _xvmc_create_context(display, context, &priv_count, &priv_data))) {
+        printf("Unable to create XvMC Context.\n");
+        free(pI915XvMC);
+        context->privData = NULL;
+        return ret;
+    }
+
+    if (priv_count != (sizeof(I915XvMCCreateContextRec) >> 2)) {
+        printf("_xvmc_create_context() returned incorrect data size!\n");
+        printf("\tExpected %d, got %d\n", 
+               (int)(sizeof(I915XvMCCreateContextRec) >> 2),priv_count);
+        _xvmc_destroy_context(display, context);
+        free(priv_data);
+        free(pI915XvMC);
+        context->privData = NULL;
+        return BadAlloc;
+    }
+
+    tmpComm = (I915XvMCCreateContextRec *)priv_data;
+    pI915XvMC->ctxno = tmpComm->ctxno;
+    pI915XvMC->sis.handle = tmpComm->sis.handle;
+    pI915XvMC->sis.offset = tmpComm->sis.offset;
+    pI915XvMC->sis.size = tmpComm->sis.size;
+    pI915XvMC->msb.handle = tmpComm->msb.handle;
+    pI915XvMC->msb.offset = tmpComm->msb.offset;
+    pI915XvMC->msb.size = tmpComm->msb.size;
+    pI915XvMC->ssb.handle = tmpComm->ssb.handle;
+    pI915XvMC->ssb.offset = tmpComm->ssb.offset;
+    pI915XvMC->ssb.size = tmpComm->ssb.size;
+    pI915XvMC->psp.handle = tmpComm->psp.handle;
+    pI915XvMC->psp.offset = tmpComm->psp.offset;
+    pI915XvMC->psp.size = tmpComm->psp.size;
+    pI915XvMC->psc.handle = tmpComm->psc.handle;
+    pI915XvMC->psc.offset = tmpComm->psc.offset;
+    pI915XvMC->psc.size = tmpComm->psc.size;
+    pI915XvMC->corrdata.handle = tmpComm->corrdata.handle;
+    pI915XvMC->corrdata.offset = tmpComm->corrdata.offset;
+    pI915XvMC->corrdata.size = tmpComm->corrdata.size;
+    pI915XvMC->sarea_size = tmpComm->sarea_size;
+    pI915XvMC->sarea_priv_offset = tmpComm->sarea_priv_offset;
+    pI915XvMC->screen = tmpComm->screen;
+    pI915XvMC->depth = tmpComm->depth;
+    pI915XvMC->attrib = tmpComm->initAttrs;
+
+    /* Must free the private data we were passed from X */
+    free(priv_data);
+    priv_data = NULL;
+
+    XLockDisplay(display);
+    ret = uniDRIQueryDirectRenderingCapable(display, pI915XvMC->screen,
+                                            &isCapable);
+    if (!ret || !isCapable) {
+        XUnlockDisplay(display);
+        fprintf(stderr,
+                "Direct Rendering is not available on this system!\n");
+        free(pI915XvMC);
+        context->privData = NULL;
+        return BadAlloc;
+    }
+
+    if (!uniDRIOpenConnection(display, pI915XvMC->screen,
+                              &pI915XvMC->hsarea, &curBusID)) {
+        XUnlockDisplay(display);
+        fprintf(stderr, "Could not open DRI connection to X server!\n");
+        free(pI915XvMC);
+        context->privData = NULL;
+        return BadAlloc;
+    }
+    XUnlockDisplay(display);
+
+    strncpy(pI915XvMC->busIdString, curBusID, 20);
+    pI915XvMC->busIdString[20] = '\0';
+    free(curBusID);
+
+    /* Open DRI Device */
+    if((pI915XvMC->fd = drmOpen(I915KernelDriverName, NULL)) < 0) {
+        printf("DRM Device for %s could not be opened.\n", I915KernelDriverName);
+        free(pI915XvMC);
+        context->privData = NULL;
+        return BadAccess;
+    } /* !pI915XvMC->fd */
+
+    /* Get magic number */
+    drmGetMagic(pI915XvMC->fd, &magic);
+    // context->flags = (unsigned long)magic;
+
+    XLockDisplay(display);
+    if (!uniDRIAuthConnection(display, pI915XvMC->screen, magic)) {
+        XUnlockDisplay(display);
+        fprintf(stderr,
+                "[XvMC]: X server did not allow DRI. Check permissions.\n");
+        free(pI915XvMC);
+        context->privData = NULL;
+        return BadAlloc;
+    }
+    XUnlockDisplay(display);
+
+    /*
+     * Map DRI Sarea.
+     */
+    if (drmMap(pI915XvMC->fd, pI915XvMC->hsarea,
+               pI915XvMC->sarea_size, &pI915XvMC->sarea_address) < 0) {
+        fprintf(stderr, "Unable to map DRI SAREA.\n");
+        free(pI915XvMC);
+        context->privData = NULL;
+        return BadAlloc;
+    }
+
+    pSAREA = (drm_sarea_t *)pI915XvMC->sarea_address;
+    pI915XvMC->driHwLock = (drmLock *)&pSAREA->lock;
+    pI915XvMC->sarea = SAREAPTR(pI915XvMC);
+    XLockDisplay(display);
+    ret = XMatchVisualInfo(display, pI915XvMC->screen,
+                           (pI915XvMC->depth == 32) ? 24 : pI915XvMC->depth, TrueColor,
+                           &pI915XvMC->visualInfo);
+    XUnlockDisplay(display);
+
+    if (!ret) {
+        fprintf(stderr,
+                "[XvMC]: Could not find a matching TrueColor visual.\n");
+        free(pI915XvMC);
+        context->privData = NULL;
+        drmUnmap(pI915XvMC->sarea_address, pI915XvMC->sarea_size);
+        return BadAlloc;
+    }
+
+    if (!uniDRICreateContext(display, pI915XvMC->screen,
+                             pI915XvMC->visualInfo.visual, &pI915XvMC->id,
+                             &pI915XvMC->hHWContext)) {
+
+        fprintf(stderr, "[XvMC]: Could not create DRI context.\n");
+        free(pI915XvMC);
+        context->privData = NULL;
+        drmUnmap(pI915XvMC->sarea_address, pI915XvMC->sarea_size);
+        return BadAlloc;
+    }
+
+    if (NULL == (pI915XvMC->drawHash = drmHashCreate())) {
+        fprintf(stderr, 
+                "[XvMC]: Could not allocate drawable hash table.\n");
+        free(pI915XvMC);
+        context->privData = NULL;
+        drmUnmap(pI915XvMC->sarea_address, pI915XvMC->sarea_size);
+        return BadAlloc;
+    }
+
+    if (i915_xvmc_map_buffers(pI915XvMC)) {
+        i915_xvmc_unmap_buffers(pI915XvMC);
+        free(pI915XvMC);
+        context->privData = NULL;
+        drmUnmap(pI915XvMC->sarea_address, pI915XvMC->sarea_size);
+        return BadAlloc;
+    }
+
+    /* Initialize private context values */
+    setupAttribDesc(display, port, &pI915XvMC->attrib, pI915XvMC->attribDesc);
+    pI915XvMC->yStride = (width + 31) & ~31;
+    pI915XvMC->haveXv = 0;
+    pI915XvMC->attribChanged = 1;
+    pI915XvMC->dual_prime = 0;
+    pI915XvMC->last_flip = 0;
+    pI915XvMC->locked = 0;
+    pI915XvMC->port = context->port;
+    pthread_mutex_init(&pI915XvMC->ctxmutex, NULL);
+    intelInitBatchBuffer(pI915XvMC);
+    pI915XvMC->ref = 1;
+    return Success;
+}
+
+/***************************************************************************
+// Function: XvMCDestroyContext
+// Description: Destorys the specified context.
+//
+// Arguments:
+//   display - Specifies the connection to the server.
+//   context - The context to be destroyed.
+//
+// Returns: Status
+***************************************************************************/
+Status XvMCDestroyContext(Display *display, XvMCContext *context)
+{
+    i915XvMCContext *pI915XvMC;
+
+    if (!display || !context)
+        return BadValue;
+
+    if (!(pI915XvMC = context->privData))
+        return (error_base + XvMCBadContext);
+
+    /* Pass Control to the X server to destroy the drm_context_t */
+    i915_release_resource(display,context);
+    return Success;
+}
+
+/***************************************************************************
+// Function: XvMCCreateSurface
+***************************************************************************/
+Status XvMCCreateSurface(Display *display, XvMCContext *context, XvMCSurface *surface) 
+{
+    Status ret;
+    i915XvMCContext *pI915XvMC;
+    i915XvMCSurface *pI915Surface;
+    int priv_count, i;
+    uint *priv_data;
+
+    if (!display || !context || !display)
+        return BadValue;
+
+    if (!(pI915XvMC = context->privData))
+        return (error_base + XvMCBadContext);
+
+    pthread_mutex_lock(&pI915XvMC->ctxmutex);
+    surface->privData = (i915XvMCSurface *)malloc(sizeof(i915XvMCSurface));
+
+    if (!(pI915Surface = surface->privData)) {
+        pthread_mutex_unlock(&pI915XvMC->ctxmutex);
+        return BadAlloc;
+    }
+
+    /* Initialize private values */
+    pI915Surface->last_render = 0;
+    pI915Surface->last_flip = 0;
+    pI915Surface->yStride = pI915XvMC->yStride;
+    pI915Surface->width = context->width;
+    pI915Surface->height = context->height;
+    pI915Surface->privContext = pI915XvMC;
+    pI915Surface->privSubPic = NULL;
+
+    XLockDisplay(display);
+
+    if ((ret = _xvmc_create_surface(display, context, surface,
+                                    &priv_count, &priv_data))) {
+        XUnlockDisplay(display);
+        printf("Unable to create XvMCSurface.\n");
+        free(pI915Surface);
+        surface->privData = NULL;
+        pthread_mutex_unlock(&pI915XvMC->ctxmutex);
+        return ret;
+    }
+
+    XUnlockDisplay(display);
+    pI915Surface->srfNo = priv_data[0];
+    pI915Surface->num_buffers = priv_data[1];
+    pI915Surface->curbuf = 0;
+
+    for (i = 0; i < pI915Surface->num_buffers; ++i)
+        pI915Surface->offsets[i] = priv_data[i + 2];
+    
+    free(priv_data);
+    pI915XvMC->ref++;
+    pthread_mutex_unlock(&pI915XvMC->ctxmutex);
+
+    return Success;
+}
+
+
+/***************************************************************************
+// Function: XvMCDestroySurface
+***************************************************************************/
+Status XvMCDestroySurface(Display *display, XvMCSurface *surface) 
+{
+    i915XvMCSurface *pI915Surface;
+    i915XvMCContext *pI915XvMC;
+
+    if (!display || !surface)
+        return BadValue;
+
+    if (!(pI915Surface = surface->privData))
+        return (error_base + XvMCBadSurface);
+
+    if (!(pI915XvMC = pI915Surface->privContext))
+        return (error_base + XvMCBadSurface);
+
+    if (pI915Surface->last_flip)
+        XvMCSyncSurface(display,surface);
+
+    XLockDisplay(display);
+    _xvmc_destroy_surface(display,surface);
+    XUnlockDisplay(display);
+
+    free(pI915Surface);
+    surface->privData = NULL;
+    pI915XvMC->ref--;
+
+    return Success;
+}
+
+/***************************************************************************
+// Function: XvMCCreateBlocks
+***************************************************************************/
+Status XvMCCreateBlocks(Display *display, XvMCContext *context,
+                        unsigned int num_blocks, 
+                        XvMCBlockArray *block) 
+{
+    if (!display || !context || !num_blocks || !block)
+        return BadValue;
+
+    memset(block, 0, sizeof(XvMCBlockArray));
+
+    if (!(block->blocks = (short *)malloc(num_blocks << 6 * sizeof(short))))
+        return BadAlloc;
+
+    block->num_blocks = num_blocks;
+    block->context_id = context->context_id;
+    block->privData = NULL;
+
+    return Success;
+}
+
+/***************************************************************************
+// Function: XvMCDestroyBlocks
+***************************************************************************/
+Status XvMCDestroyBlocks(Display *display, XvMCBlockArray *block) 
+{
+    if (!display || block)
+        return BadValue;
+
+    if (block->blocks)
+        free(block->blocks);
+
+    block->context_id = 0;
+    block->num_blocks = 0;
+    block->blocks = NULL;
+    block->privData = NULL;
+
+    return Success;
+}
+
+/***************************************************************************
+// Function: XvMCCreateMacroBlocks
+***************************************************************************/
+Status XvMCCreateMacroBlocks(Display *display, XvMCContext *context,
+                             unsigned int num_blocks,
+                             XvMCMacroBlockArray *blocks) 
+{
+    if (!display || !context || !blocks || !num_blocks)
+        return BadValue;
+
+    memset(blocks, 0, sizeof(XvMCMacroBlockArray));
+    blocks->macro_blocks = (XvMCMacroBlock *)malloc(num_blocks * sizeof(XvMCMacroBlock));
+
+    if (!blocks->macro_blocks)
+        return BadAlloc;
+
+    blocks->num_blocks = num_blocks;
+    blocks->context_id = context->context_id;
+    blocks->privData = NULL;
+
+    return Success;
+}
+
+/***************************************************************************
+// Function: XvMCDestroyMacroBlocks
+***************************************************************************/
+Status XvMCDestroyMacroBlocks(Display *display, XvMCMacroBlockArray *block) 
+{
+    if (!display || !block)
+        return BadValue;
+    if (block->macro_blocks)
+        free(block->macro_blocks);
+
+    block->context_id = 0;
+    block->num_blocks = 0;
+    block->macro_blocks = NULL;
+    block->privData = NULL;
+
+    return Success;
+}
+
+/***************************************************************************
+// Function: XvMCRenderSurface
+// Description: This function does the actual HWMC. Given a list of
+//  macroblock structures it dispatched the hardware commands to execute
+//  them. DMA buffer containing Y data are dispatched as they fill up
+//  U and V DMA buffers are queued until all Y's are done. This minimizes
+//  the context flipping and flushing required when switching between Y
+//  U and V surfaces.
+***************************************************************************/
+Status XvMCRenderSurface(Display *display, XvMCContext *context,
+                         unsigned int picture_structure,
+                         XvMCSurface *target_surface,
+                         XvMCSurface *past_surface,
+                         XvMCSurface *future_surface,
+                         unsigned int flags,
+                         unsigned int num_macroblocks,
+                         unsigned int first_macroblock,
+                         XvMCMacroBlockArray *macroblock_array,
+                         XvMCBlockArray *blocks) 
+{
+    int i;
+
+    /* correction data buffer */
+    char *corrdata_ptr;
+    int corrdata_size = 0;
+
+    /* Block Pointer */
+    short *block_ptr;
+    /* Current Macroblock Pointer */
+    XvMCMacroBlock *mb;
+
+    i915XvMCSurface *privTarget = NULL;
+    i915XvMCSurface *privFuture = NULL;
+    i915XvMCSurface *privPast = NULL;
+    i915XvMCContext *pI915XvMC = NULL;
+
+    /* Check Parameters for validity */
+    if (!display) {
+        printf("Error, Invalid display!\n");
+        return BadValue;
+    }
+
+    if (!display || !context || !target_surface) {
+        printf("Error, Invalid Display, Context or Target!\n");
+        return BadValue;
+    }
+
+    if (!num_macroblocks)
+        return Success;
+
+    if (!macroblock_array || !blocks) {
+        printf("Error, Invalid block data!\n");
+        return BadValue;
+    }
+
+    if (macroblock_array->num_blocks < (num_macroblocks + first_macroblock)) {
+        printf("Error, Too many macroblocks requested for MB array size.\n");
+        return BadValue;
+    }
+
+    if (!(pI915XvMC = context->privData))
+        return (error_base + XvMCBadContext);
+
+    if (!(privTarget = target_surface->privData))
+        return (error_base + XvMCBadSurface);
+
+    /* Test For YV12 Surface */
+    if (context->surface_type_id != FOURCC_YV12) {
+        printf("Error, HWMC only possible on YV12 Surfaces\n");
+        return BadValue;
+    }
+
+    /* P Frame Test */
+    if (!past_surface) {
+        /* Just to avoid some ifs later. */
+        privPast = privTarget;
+    } else {
+        if (!(privPast = past_surface->privData)) {
+            printf("Error, Invalid Past Surface!\n");
+            return (error_base + XvMCBadSurface);
+        }
+    }
+
+    /* B Frame Test */
+    if (!future_surface) {
+        privFuture = privTarget;
+    } else {
+        if (!past_surface) {
+            printf("Error, No Past Surface!\n");
+            return BadValue;
+        }
+
+        if (!(privFuture = future_surface->privData)) {
+            printf("Error, Invalid Future Surface!\n");
+            return (error_base + XvMCBadSurface);
+        }
+    }
+
+    corrdata_ptr = pI915XvMC->corrdata.map;
+    corrdata_size = 0;
+
+    for (i = first_macroblock; i < (num_macroblocks + first_macroblock); i++) {
+        int bspm = 0;
+        mb = &macroblock_array->macro_blocks[i];
+        block_ptr = &(blocks->blocks[mb->index << 6]);
+
+        /* Lockup can happen if the coordinates are too far out of range */
+        if(mb->x > (target_surface->width >> 4)) {
+            mb->x = 0;
+        }
+        if(mb->y > (target_surface->height >> 4)) {
+            mb->y = 0;
+        }
+
+        /* Catch no pattern case */
+        if (!(mb->macroblock_type & XVMC_MB_TYPE_PATTERN)) {
+            mb->coded_block_pattern = 0;
+        }
+
+        if (mb->macroblock_type & XVMC_MB_TYPE_INTRA) {
+            bspm = 768;
+        } else {
+            bspm = mb_bytes[mb->coded_block_pattern];
+        }
+
+        corrdata_size += bspm;
+
+        if (corrdata_size > pI915XvMC->corrdata.size) {
+            printf("Error, correction data buffer overflow\n");
+            break;
+        }
+
+        memcpy(corrdata_ptr, block_ptr, bspm);
+        corrdata_ptr += bspm;
+    }
+
+    /* Lock For DMA */
+    LOCK_HARDWARE(pI915XvMC);
+    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_static_indirect_state_buffer(context, target_surface, picture_structure);
+    i915_mc_map_state_buffer(context, target_surface, past_surface, future_surface);
+    i915_flush(pI915XvMC);
+    i915_mc_load_indirect_buffer(context);
+    i915_mc_mpeg_set_origin(context, &macroblock_array->macro_blocks[first_macroblock]);
+    for (i = first_macroblock; i < (num_macroblocks + first_macroblock); i++) {
+        mb = &macroblock_array->macro_blocks[i];
+
+        /* Intra Blocks */
+        if (mb->macroblock_type & XVMC_MB_TYPE_INTRA) {
+            i915_mc_mpeg_macroblock_0mv(context, mb);
+            continue;
+        }
+
+        /* Frame Picture */
+        if ((picture_structure & XVMC_FRAME_PICTURE) == XVMC_FRAME_PICTURE) {
+            switch (mb->motion_type & 3) {
+            case XVMC_PREDICTION_FIELD: /* Field Based */
+                i915_mc_mpeg_macroblock_2fbmv(context, mb);
+                continue;
+
+            case XVMC_PREDICTION_FRAME: /* Frame Based */
+                i915_mc_mpeg_macroblock_1fbmv(context, mb);
+                continue;
+
+            case XVMC_PREDICTION_DUAL_PRIME:    /* Dual Prime */
+                i915_mc_mpeg_macroblock_2fbmv(context, mb);
+                continue;
+
+            default:    /* No Motion Type */
+                renderError();
+                continue;
+            }   
+        } else {        /* Frame Picture */
+            switch (mb->motion_type & 3) {
+            case XVMC_PREDICTION_FIELD: /* Field Based */
+                i915_mc_mpeg_macroblock_1fbmv(context, mb);
+                continue;
+
+            case XVMC_PREDICTION_16x8:  /* 16x8 MC */
+                i915_mc_mpeg_macroblock_2fbmv(context, mb);
+                continue;
+                
+            case XVMC_PREDICTION_DUAL_PRIME:    /* Dual Prime */
+                i915_mc_mpeg_macroblock_1fbmv(context, mb);
+                continue;
+
+            default:    /* No Motion Type */
+                renderError();
+                continue;
+            }
+        }       /* Field Picture */
+    }
+
+    intelFlushBatch(pI915XvMC, TRUE);
+    pI915XvMC->last_render = pI915XvMC->alloc.irq_emitted;
+    privTarget->last_render = pI915XvMC->last_render;
+
+    UNLOCK_HARDWARE(pI915XvMC);
+    return Success;
+}
+
+/***************************************************************************
+// Function: XvMCPutSurface
+// Description:
+// Arguments:
+//  display: Connection to X server
+//  surface: Surface to be displayed
+//  draw: X Drawable on which to display the surface
+//  srcx: X coordinate of the top left corner of the region to be
+//          displayed within the surface.
+//  srcy: Y coordinate of the top left corner of the region to be
+//          displayed within the surface.
+//  srcw: Width of the region to be displayed.
+//  srch: Height of the region to be displayed.
+//  destx: X cordinate of the top left corner of the destination region
+//         in the drawable coordinates.
+//  desty: Y cordinate of the top left corner of the destination region
+//         in the drawable coordinates.
+//  destw: Width of the destination region.
+//  desth: Height of the destination region.
+//  flags: One or more of the following.
+//     XVMC_TOP_FIELD - Display only the Top field of the surface.
+//     XVMC_BOTTOM_FIELD - Display only the Bottom Field of the surface.
+//     XVMC_FRAME_PICTURE - Display both fields or frame.
+//
+// Info: Portions of this function derived from i915_video.c (XFree86)
+//
+//   This function is organized so that we wait as long as possible before
+//   touching the overlay registers. Since we don't know that the last
+//   flip has happened yet we want to give the overlay as long as
+//   possible to catch up before we have to check on its progress. This
+//   makes it unlikely that we have to wait on the last flip.
+***************************************************************************/
+Status XvMCPutSurface(Display *display,XvMCSurface *surface,
+                      Drawable draw, short srcx, short srcy,
+                      unsigned short srcw, unsigned short srch,
+                      short destx, short desty,
+                      unsigned short destw, unsigned short desth,
+                      int flags) 
+{
+    i915XvMCContext *pI915XvMC;
+    i915XvMCSurface *pI915Surface;
+    i915XvMCSubpicture *pI915SubPic;
+    I915XvMCCommandBuffer buf;
+
+    drawableInfo *drawInfo;
+    Status ret;
+
+    if (!display || !surface)
+        return BadValue;
+
+    if (!(pI915Surface = surface->privData))
+        return (error_base + XvMCBadSurface);
+
+    if (!(pI915XvMC = pI915Surface->privContext))
+        return (error_base + XvMCBadSurface);
+
+    pthread_mutex_lock(&pI915XvMC->ctxmutex);
+    if (getDRIDrawableInfoLocked(pI915XvMC->drawHash, display,
+                                 pI915XvMC->screen, draw, 0, pI915XvMC->fd, pI915XvMC->hHWContext,
+                                 pI915XvMC->sarea_address, FALSE, &drawInfo, sizeof(*drawInfo))) {
+        pthread_mutex_unlock(&pI915XvMC->ctxmutex);
+        return BadAccess;
+    }
+    
+    if (!pI915XvMC->haveXv) {
+        pI915XvMC->xvImage =
+            XvCreateImage(display, pI915XvMC->port, FOURCC_XVMC,
+                          (char *)&buf, pI915Surface->width, pI915Surface->height);
+        pI915XvMC->gc = XCreateGC(display, draw, 0, 0);
+        pI915XvMC->haveXv = 1;
+    }
+
+    pI915XvMC->draw = draw;
+    pI915XvMC->xvImage->data = (char *)&buf;
+
+    buf.command = I915_XVMC_COMMAND_DISPLAY;
+    buf.ctxNo = pI915XvMC->ctxno;
+    buf.srfNo = pI915Surface->srfNo;
+    pI915SubPic = pI915Surface->privSubPic;
+    buf.subPicNo = (!pI915SubPic ? 0 : pI915SubPic->srfNo);
+    buf.attrib = pI915XvMC->attrib;
+    buf.real_id = FOURCC_YV12;
+
+    XLockDisplay(display);
+
+    if ((ret = XvPutImage(display, pI915XvMC->port, draw, pI915XvMC->gc,
+                          pI915XvMC->xvImage, srcx, srcy, srcw, srch,
+                          destx, desty, destw, desth))) {
+        XUnlockDisplay(display);
+        pthread_mutex_unlock(&pI915XvMC->ctxmutex);
+
+        return ret;
+    }
+
+    XSync(display, 0);
+    XUnlockDisplay(display);
+    pI915XvMC->attribChanged = 0;
+    pthread_mutex_unlock(&pI915XvMC->ctxmutex);
+
+    return Success;
+}
+
+/***************************************************************************
+// Function: XvMCSyncSurface
+// Arguments:
+//   display - Connection to the X server
+//   surface - The surface to synchronize
+// Info:
+// Returns: Status
+***************************************************************************/
+Status XvMCSyncSurface(Display *display, XvMCSurface *surface) 
+{
+    Status ret;
+    int stat = 0;
+
+    do {
+        ret = XvMCGetSurfaceStatus(display, surface, &stat);
+    } while (!ret && (stat & XVMC_RENDERING));
+
+    return ret;
+}
+
+/***************************************************************************
+// Function: XvMCFlushSurface
+// Description:
+//   This function commits pending rendering requests to ensure that they
+//   wll be completed in a finite amount of time.
+// Arguments:
+//   display - Connection to X server
+//   surface - Surface to flush
+// Returns: Status
+***************************************************************************/
+Status XvMCFlushSurface(Display * display, XvMCSurface *surface) 
+{
+    return Success;
+}
+
+/***************************************************************************
+// Function: XvMCGetSurfaceStatus
+// Description:
+// Arguments:
+//  display: connection to X server
+//  surface: The surface to query
+//  stat: One of the Following
+//    XVMC_RENDERING - The last XvMCRenderSurface command has not
+//                     completed.
+//    XVMC_DISPLAYING - The surface is currently being displayed or a
+//                     display is pending.
+***************************************************************************/
+Status XvMCGetSurfaceStatus(Display *display, XvMCSurface *surface, int *stat) 
+{
+    i915XvMCSurface *pI915Surface;
+    i915XvMCContext *pI915XvMC;
+
+    if (!display || !surface || !stat)
+        return BadValue;
+    
+    *stat = 0;
+
+    if (!(pI915Surface = surface->privData))
+        return (error_base + XvMCBadSurface);
+
+    if (!(pI915XvMC = pI915Surface->privContext))
+        return (error_base + XvMCBadSurface);
+
+    LOCK_HARDWARE(pI915XvMC);
+
+    if (pI915Surface->last_flip) {
+        /* This can not happen */
+        if (pI915XvMC->last_flip < pI915Surface->last_flip) {
+            printf("Error: Context last flip is less than surface last flip.\n");
+            return BadValue;
+        }
+
+        /*
+          If the context has 2 or more flips after this surface it
+          cannot be displaying. Don't bother to check.
+        */
+        if (!(pI915XvMC->last_flip > (pI915Surface->last_flip + 1))) {
+            /*
+              If this surface was the last flipped it is either displaying
+              or about to be so don't bother checking.
+            */
+            if (pI915XvMC->last_flip == pI915Surface->last_flip) {
+                *stat |= XVMC_DISPLAYING;
+            }
+        }
+    }
+
+    if (pI915Surface->last_render &&
+        (pI915Surface->last_render > pI915XvMC->sarea->last_dispatch)) {
+        *stat |= XVMC_RENDERING;
+    }
+
+    UNLOCK_HARDWARE(pI915XvMC);
+    return Success;
+}
+
+/***************************************************************************
+// 
+//  Surface manipulation functions
+//
+***************************************************************************/
+
+/***************************************************************************
+// Function: XvMCHideSurface
+// Description: Stops the display of a surface.
+// Arguments:
+//   display - Connection to the X server.
+//   surface - surface to be hidden.
+//
+// Returns: Status
+***************************************************************************/
+Status XvMCHideSurface(Display *display, XvMCSurface *surface) 
+{
+    i915XvMCSurface *pI915Surface;
+    i915XvMCContext *pI915XvMC;
+    int stat = 0, ret;
+
+    if (!display || !surface)
+        return BadValue;
+
+    if (!(pI915Surface = surface->privData))
+        return (error_base + XvMCBadSurface);
+
+    /* Get the associated context pointer */
+    if (!(pI915XvMC = pI915Surface->privContext))
+        return (error_base + XvMCBadSurface);
+
+    XvMCSyncSurface(display, surface);
+
+    /*
+      Get the status of the surface, if it is not currently displayed
+      we don't need to worry about it.
+    */
+    if ((ret = XvMCGetSurfaceStatus(display, surface, &stat)) != Success)
+        return ret;
+
+    if (!(stat & XVMC_DISPLAYING))
+        return Success;
+
+    /* FIXME: */
+    return Success;
+}
+
+/***************************************************************************
+//
+// Functions that deal with subpictures
+//
+***************************************************************************/
+
+
+
+/***************************************************************************
+// Function: XvMCCreateSubpicture
+// Description: This creates a subpicture by filling out the XvMCSubpicture
+//              structure passed to it and returning Success.
+// Arguments:
+//   display - Connection to the X server.
+//   context - The context to create the subpicture for.
+//   subpicture - Pre-allocated XvMCSubpicture structure to be filled in.
+//   width - of subpicture
+//   height - of subpicture
+//   xvimage_id - The id describing the XvImage format.
+//
+// Returns: Status
+***************************************************************************/
+Status XvMCCreateSubpicture(Display *display, XvMCContext *context,
+                            XvMCSubpicture *subpicture,
+                            unsigned short width, unsigned short height,
+                            int xvimage_id) 
+{
+    i915XvMCContext *pI915XvMC;
+    i915XvMCSubpicture *pI915Subpicture;
+    int priv_count;
+    uint *priv_data;
+    Status ret;
+
+    if (!subpicture || !context || !display)
+        return BadValue;
+  
+    pI915XvMC = (i915XvMCContext *)context->privData;
+
+    if (!pI915XvMC)
+        return (error_base + XvMCBadContext);
+
+    subpicture->privData =
+        (i915XvMCSubpicture *)malloc(sizeof(i915XvMCSubpicture));
+
+    if (!subpicture->privData)
+        return BadAlloc;
+
+
+    subpicture->context_id = context->context_id;
+    subpicture->xvimage_id = xvimage_id;
+    subpicture->width = width;
+    subpicture->height = height;
+    pI915Subpicture = (i915XvMCSubpicture *)subpicture->privData;
+
+    if ((ret = _xvmc_create_subpicture(display, context, subpicture,
+                                       &priv_count, &priv_data))) {
+        printf("Unable to create XvMCSubpicture.\n");
+        free(pI915Subpicture);
+        return ret;
+    }
+
+    if (priv_count != 2) {
+        printf("_xvmc_create_subpicture() returned incorrect data size.\n");
+        printf("Expected 2 got %d\n",priv_count);
+        free(priv_data);
+        free(pI915Subpicture);
+        subpicture->privData = NULL;
+        return BadAlloc;
+    }
+
+    free(priv_data);
+    /* subpicture */
+    subpicture->num_palette_entries = I915_SUBPIC_PALETTE_SIZE;
+    subpicture->entry_bytes = 3;
+    strncpy(subpicture->component_order, "YUV", 4);
+
+    /* Initialize private values */
+    pI915Subpicture->privContext = pI915XvMC;
+    pI915Subpicture->last_render= 0;
+    pI915Subpicture->last_flip = 0;
+    pI915Subpicture->srfNo = priv_data[0];
+    pI915Subpicture->offset = priv_data[1];
+    pI915Subpicture->pitch = ((subpicture->width + 31) & ~31);
+
+    switch(subpicture->xvimage_id) {
+    case FOURCC_IA44:
+    case FOURCC_AI44:
+        break;
+
+    default:
+        free(pI915Subpicture);
+        subpicture->privData = NULL;
+        return BadMatch;
+    }
+
+    pI915XvMC->ref++;
+    return Success;
+}
+
+/***************************************************************************
+// Function: XvMCClearSubpicture
+// Description: Clear the area of the given subpicture to "color".
+//              structure passed to it and returning Success.
+// Arguments:
+//   display - Connection to the X server.
+//   subpicture - Subpicture to clear.
+//   x, y, width, height - rectangle in the subpicture to clear.
+//   color - The data to file the rectangle with.
+//
+// Returns: Status
+***************************************************************************/
+Status XvMCClearSubpicture(Display *display, XvMCSubpicture *subpicture,
+                           short x, short y,
+                           unsigned short width, unsigned short height,
+                           unsigned int color) 
+{
+    i915XvMCContext *pI915XvMC;
+    i915XvMCSubpicture *pI915Subpicture;
+
+    if (!display || !subpicture)
+        return BadValue;
+
+    if (!(pI915Subpicture = subpicture->privData))
+        return (error_base + XvMCBadSubpicture);
+
+    if (!(pI915XvMC = pI915Subpicture->privContext))
+        return (error_base + XvMCBadSubpicture);
+
+    if ((x < 0) || (x + width) > subpicture->width)
+        return BadValue;
+
+    if ((y < 0) || (y + height) > subpicture->height)
+        return BadValue;
+
+    /* FIXME: clear the area */
+
+    return Success;
+}
+
+/***************************************************************************
+// Function: XvMCCompositeSubpicture
+// Description: Composite the XvImae on the subpicture. This composit uses
+//              non-premultiplied alpha. Destination alpha is utilized
+//              except for with indexed subpictures. Indexed subpictures
+//              use a simple "replace".
+// Arguments:
+//   display - Connection to the X server.
+//   subpicture - Subpicture to clear.
+//   image - the XvImage to be used as the source of the composite.
+//   srcx, srcy, width, height - The rectangle from the image to be used.
+//   dstx, dsty - location in the subpicture to composite the source.
+//
+// Returns: Status
+***************************************************************************/
+Status XvMCCompositeSubpicture(Display *display, XvMCSubpicture *subpicture,
+                               XvImage *image,
+                               short srcx, short srcy,
+                               unsigned short width, unsigned short height,
+                               short dstx, short dsty) 
+{
+    i915XvMCContext *pI915XvMC;
+    i915XvMCSubpicture *pI915Subpicture;
+
+    if (!display || !subpicture)
+        return BadValue;
+
+    if (!(pI915Subpicture = subpicture->privData))
+        return (error_base + XvMCBadSubpicture);
+
+    if (!(pI915XvMC = pI915Subpicture->privContext))
+        return (error_base + XvMCBadSubpicture);
+
+    if ((srcx < 0) || (srcx + width) > subpicture->width)
+        return BadValue;
+
+    if ((srcy < 0) || (srcy + height) > subpicture->height)
+        return BadValue;
+
+    if ((dstx < 0) || (dstx + width) > subpicture->width)
+        return BadValue;
+
+    if ((dsty < 0) || (dsty + width) > subpicture->height)
+        return BadValue;
+
+    if (image->id != subpicture->xvimage_id)
+        return BadMatch;
+
+    /* FIXME */
+    return Success;
+}
+
+
+/***************************************************************************
+// Function: XvMCDestroySubpicture
+// Description: Destroys the specified subpicture.
+// Arguments:
+//   display - Connection to the X server.
+//   subpicture - Subpicture to be destroyed.
+//
+// Returns: Status
+***************************************************************************/
+Status XvMCDestroySubpicture(Display *display, XvMCSubpicture *subpicture) 
+{
+    i915XvMCSubpicture *pI915Subpicture;
+    i915XvMCContext *pI915XvMC;
+
+    if (!display || !subpicture)
+        return BadValue;
+
+    if (!(pI915Subpicture = subpicture->privData))
+        return (error_base + XvMCBadSubpicture);
+
+    if (!(pI915XvMC = pI915Subpicture->privContext))
+        return (error_base + XvMCBadSubpicture);
+
+    if (pI915Subpicture->last_render)
+        XvMCSyncSubpicture(display, subpicture);
+
+    XLockDisplay(display);
+    _xvmc_destroy_subpicture(display,subpicture);
+    XUnlockDisplay(display);
+
+    free(pI915Subpicture);
+    subpicture->privData = NULL;
+    pI915XvMC->ref--;
+
+    return Success;
+}
+
+
+/***************************************************************************
+// Function: XvMCSetSubpicturePalette
+// Description: Set the subpictures palette
+// Arguments:
+//   display - Connection to the X server.
+//   subpicture - Subpiture to set palette for.
+//   palette - A pointer to an array holding the palette data. The array
+//     is num_palette_entries * entry_bytes in size.
+// Returns: Status
+***************************************************************************/
+
+Status XvMCSetSubpicturePalette(Display *display, XvMCSubpicture *subpicture,
+                                unsigned char *palette) 
+{
+    i915XvMCSubpicture *pI915Subpicture;
+    int i, j;
+
+    if (!display || !subpicture)
+        return BadValue;
+
+    if (!(pI915Subpicture = subpicture->privData))
+        return (error_base + XvMCBadSubpicture);
+
+    j = 0;
+    for (i = 0; i < 16; i++) {
+        pI915Subpicture->palette[0][i] = palette[j++];
+        pI915Subpicture->palette[1][i] = palette[j++];
+        pI915Subpicture->palette[2][i] = palette[j++];
+    }
+
+    /* FIXME: Update the subpicture with the new palette */
+    return Success;
+}
+
+/***************************************************************************
+// Function: XvMCBlendSubpicture
+// Description: 
+//    The behavior of this function is different depending on whether
+//    or not the XVMC_BACKEND_SUBPICTURE flag is set in the XvMCSurfaceInfo.
+//    i915 only support frontend behavior.
+//  
+//    XVMC_BACKEND_SUBPICTURE not set ("frontend" behavior):
+//   
+//    XvMCBlendSubpicture is a no-op in this case.
+//   
+// Arguments:
+//   display - Connection to the X server.
+//   subpicture - The subpicture to be blended into the video.
+//   target_surface - The surface to be displayed with the blended subpic.
+//   source_surface - Source surface prior to blending.
+//   subx, suby, subw, subh - The rectangle from the subpicture to use.
+//   surfx, surfy, surfw, surfh - The rectangle in the surface to blend
+//      blend the subpicture rectangle into. Scaling can ocure if 
+//      XVMC_SUBPICTURE_INDEPENDENT_SCALING is set.
+//
+// Returns: Status
+***************************************************************************/
+Status XvMCBlendSubpicture(Display *display, XvMCSurface *target_surface,
+                           XvMCSubpicture *subpicture,
+                           short subx, short suby,
+                           unsigned short subw, unsigned short subh,
+                           short surfx, short surfy,
+                           unsigned short surfw, unsigned short surfh) 
+{
+    i915XvMCSubpicture *pI915Subpicture;
+    i915XvMCSurface *privTargetSurface;
+
+    if (!display || !target_surface)
+        return BadValue;
+
+    if (!(privTargetSurface = target_surface->privData))
+        return (error_base + XvMCBadSurface);
+
+    if (subpicture) {
+        if (!(pI915Subpicture = subpicture->privData))
+            return (error_base + XvMCBadSubpicture);
+
+        if ((FOURCC_AI44 != subpicture->xvimage_id) &&
+            (FOURCC_IA44 != subpicture->xvimage_id))
+            return (error_base + XvMCBadSubpicture);
+
+        privTargetSurface->privSubPic = pI915Subpicture;
+    } else {
+        privTargetSurface->privSubPic = NULL;
+    }
+
+    return Success;
+}
+
+/***************************************************************************
+// Function: XvMCBlendSubpicture2
+// Description: 
+//    The behavior of this function is different depending on whether
+//    or not the XVMC_BACKEND_SUBPICTURE flag is set in the XvMCSurfaceInfo.
+//    i915 only supports frontend blending.
+//  
+//    XVMC_BACKEND_SUBPICTURE not set ("frontend" behavior):
+//   
+//    XvMCBlendSubpicture2 blends the source_surface and subpicture and
+//    puts it in the target_surface.  This does not effect the status of
+//    the source surface but will cause the target_surface to query
+//    XVMC_RENDERING until the blend is completed.
+//   
+// Arguments:
+//   display - Connection to the X server.
+//   subpicture - The subpicture to be blended into the video.
+//   target_surface - The surface to be displayed with the blended subpic.
+//   source_surface - Source surface prior to blending.
+//   subx, suby, subw, subh - The rectangle from the subpicture to use.
+//   surfx, surfy, surfw, surfh - The rectangle in the surface to blend
+//      blend the subpicture rectangle into. Scaling can ocure if 
+//      XVMC_SUBPICTURE_INDEPENDENT_SCALING is set.
+//
+// Returns: Status
+***************************************************************************/
+Status XvMCBlendSubpicture2(Display *display, 
+                            XvMCSurface *source_surface,
+                            XvMCSurface *target_surface,
+                            XvMCSubpicture *subpicture,
+                            short subx, short suby,
+                            unsigned short subw, unsigned short subh,
+                            short surfx, short surfy,
+                            unsigned short surfw, unsigned short surfh)
+{
+    i915XvMCContext *pI915XvMC;
+    i915XvMCSubpicture *pI915Subpicture;
+    i915XvMCSurface *privSourceSurface;
+    i915XvMCSurface *privTargetSurface;
+
+    if (!display || !source_surface || !target_surface)
+        return BadValue;
+
+    if (!(privSourceSurface = source_surface->privData))
+        return (error_base + XvMCBadSurface);
+
+    if (!(privTargetSurface = target_surface->privData))
+        return (error_base + XvMCBadSurface);
+
+    if (!(pI915XvMC = privTargetSurface->privContext))
+        return (error_base + XvMCBadSurface);
+
+    if (((surfx + surfw) > privTargetSurface->width) ||
+        ((surfy + surfh) > privTargetSurface->height))
+        return BadValue;
+
+    if ((privSourceSurface->width != privTargetSurface->width) ||
+        (privTargetSurface->height != privTargetSurface->height))
+        return BadValue;
+
+    if (XvMCSyncSurface(display, source_surface))
+        return BadValue;
+
+    /* FIXME: update Target Surface */
+
+    if (subpicture) {
+        if (((subx + subw) > subpicture->width) ||
+            ((suby + subh) > subpicture->height))
+            return BadValue;
+
+        if (!(pI915Subpicture = subpicture->privData))
+            return (error_base + XvMCBadSubpicture);
+
+        if ((FOURCC_AI44 != subpicture->xvimage_id) &&
+            (FOURCC_IA44 != subpicture->xvimage_id))
+            return (error_base + XvMCBadSubpicture);
+
+        privTargetSurface->privSubPic = pI915Subpicture;
+    } else {
+        privTargetSurface->privSubPic = NULL;
+    }
+
+    return Success;
+}
+
+/***************************************************************************
+// Function: XvMCSyncSubpicture
+// Description: This function blocks until all composite/clear requests on
+//              the subpicture have been complete.
+// Arguments:
+//   display - Connection to the X server.
+//   subpicture - The subpicture to synchronize
+//
+// Returns: Status
+***************************************************************************/
+Status XvMCSyncSubpicture(Display *display, XvMCSubpicture *subpicture) 
+{
+    Status ret;
+    int stat = 0;
+
+    if (!display || !subpicture)
+        return BadValue;
+
+    do {
+        ret = XvMCGetSubpictureStatus(display, subpicture, &stat);
+    } while(!ret && (stat & XVMC_RENDERING));
+
+    return ret;
+}
+
+/***************************************************************************
+// Function: XvMCFlushSubpicture
+// Description: This function commits pending composite/clear requests to
+//              ensure that they will be completed in a finite amount of
+//              time.
+// Arguments:
+//   display - Connection to the X server.
+//   subpicture - The subpicture whos compsiting should be flushed
+//
+// Returns: Status
+***************************************************************************/
+Status XvMCFlushSubpicture(Display *display, XvMCSubpicture *subpicture) 
+{
+    i915XvMCSubpicture *pI915Subpicture;
+
+    if (!display || !subpicture)
+        return BadValue;
+
+    if (!(pI915Subpicture = subpicture->privData))
+        return (error_base + XvMCBadSubpicture);
+
+    return Success;
+}
+
+/***************************************************************************
+// Function: XvMCGetSubpictureStatus
+// Description: This function gets the current status of a subpicture
+//
+// Arguments:
+//   display - Connection to the X server.
+//   subpicture - The subpicture whos status is being queried
+//   stat - The status of the subpicture. It can be any of the following
+//          OR'd together:
+//          XVMC_RENDERING  - Last composite or clear request not completed
+//          XVMC_DISPLAYING - Suppicture currently being displayed.
+//
+// Returns: Status
+***************************************************************************/
+Status XvMCGetSubpictureStatus(Display *display, XvMCSubpicture *subpicture,
+                               int *stat) 
+{
+    i915XvMCSubpicture *pI915Subpicture;
+    i915XvMCContext *pI915XvMC;
+
+    if (!display || !subpicture || stat)
+        return BadValue;
+
+    *stat = 0;
+
+    if (!(pI915Subpicture = subpicture->privData))
+        return (error_base + XvMCBadSubpicture);
+
+    if (!(pI915XvMC = pI915Subpicture->privContext))
+        return (error_base + XvMCBadSubpicture);
+
+    LOCK_HARDWARE(pI915XvMC);
+    /* FIXME: */
+    if (pI915Subpicture->last_render &&
+        (pI915Subpicture->last_render > pI915XvMC->sarea->last_dispatch)) {
+        *stat |= XVMC_RENDERING;
+    }
+
+    UNLOCK_HARDWARE(pI915XvMC);
+    return Success;
+}
+
+/***************************************************************************
+// Function: XvMCQueryAttributes
+// Description: An array of XvAttributes of size "number" is returned by
+//   this function. If there are no attributes, NULL is returned and number
+//   is set to 0. The array may be freed with xfree().
+//
+// Arguments:
+//   display - Connection to the X server.
+//   context - The context whos attributes we are querying.
+//   number - The returned number of recognized atoms
+//
+// Returns:
+//  An array of XvAttributes.
+***************************************************************************/
+XvAttribute *XvMCQueryAttributes(Display *display, XvMCContext *context,
+                                 int *number) 
+{
+    i915XvMCContext *pI915XvMC;
+    XvAttribute *attributes;
+
+    if (!number)
+        return NULL;
+
+    *number = 0;
+
+    if (!display || !context)
+        return NULL;
+
+    if (!(pI915XvMC = context->privData))
+        return NULL;
+
+    pthread_mutex_lock(&pI915XvMC->ctxmutex);
+    if (NULL != (attributes = (XvAttribute *)
+                 malloc(I915_NUM_XVMC_ATTRIBUTES * sizeof(XvAttribute)))) {
+        memcpy(attributes, pI915XvMC->attribDesc, I915_NUM_XVMC_ATTRIBUTES);
+        *number = I915_NUM_XVMC_ATTRIBUTES;
+    }
+    pthread_mutex_unlock(&pI915XvMC->ctxmutex);
+
+    return attributes;
+}
+
+/***************************************************************************
+// Function: XvMCSetAttribute
+// Description: This function sets a context-specific attribute.
+//
+// Arguments:
+//   display - Connection to the X server.
+//   context - The context whos attributes we are querying.
+//   attribute - The X atom of the attribute to be changed.
+//   value - The new value for the attribute.
+//
+// Returns:
+//  Status
+***************************************************************************/
+Status XvMCSetAttribute(Display *display, XvMCContext *context,
+                        Atom attribute, int value)
+{
+    i915XvMCContext *pI915XvMC;
+    I915XvMCCommandBuffer buf;
+    int found = 0;
+    unsigned i;
+
+    if (!display)
+        return BadValue;
+
+    if (!context || !(pI915XvMC = context->privData))
+        return (error_base + XvMCBadContext);
+
+    pthread_mutex_lock(&pI915XvMC->ctxmutex);
+    for (i = 0; i < pI915XvMC->attrib.numAttr; ++i) {
+        if (attribute == pI915XvMC->attrib.attributes[i].attribute) {
+            if ((!(pI915XvMC->attribDesc[i].flags & XvSettable)) ||
+                value < pI915XvMC->attribDesc[i].min_value ||
+                value > pI915XvMC->attribDesc[i].max_value)
+                return BadValue;
+
+            pI915XvMC->attrib.attributes[i].value = value;
+            found = 1;
+            pI915XvMC->attribChanged = 1;
+            break;
+        }
+    }
+
+    if (!found) {
+        pthread_mutex_unlock(&pI915XvMC->ctxmutex);
+        return BadMatch;
+    }
+
+    if (pI915XvMC->haveXv) {
+        buf.command = I915_XVMC_COMMAND_ATTRIBUTES;
+        pI915XvMC->xvImage->data = (char *)&buf;
+        buf.ctxNo = pI915XvMC->ctxno | I915_XVMC_VALID;
+        buf.attrib = pI915XvMC->attrib;
+        XLockDisplay(display);
+        pI915XvMC->attribChanged =
+            XvPutImage(display, pI915XvMC->port, pI915XvMC->draw,
+                       pI915XvMC->gc, pI915XvMC->xvImage, 0, 0, 1, 1, 0, 0, 1, 1);
+        XUnlockDisplay(display);
+    }
+
+    pthread_mutex_unlock(&pI915XvMC->ctxmutex);
+    return Success;
+}
+
+/***************************************************************************
+// Function: XvMCGetAttribute
+// Description: This function queries a context-specific attribute and
+//   returns the value.
+//
+// Arguments:
+//   display - Connection to the X server.
+//   context - The context whos attributes we are querying.
+//   attribute - The X atom of the attribute to be queried
+//   value - The returned attribute value
+//
+// Returns:
+//  Status
+// Notes:
+***************************************************************************/
+Status XvMCGetAttribute(Display *display, XvMCContext *context,
+                        Atom attribute, int *value) 
+{
+    i915XvMCContext *pI915XvMC;
+    int found = 0;
+    unsigned i;
+
+    if (!display || !value)
+        return BadValue;
+
+    if (!context || !(pI915XvMC = context->privData))
+        return (error_base + XvMCBadContext);
+
+    pthread_mutex_lock(&pI915XvMC->ctxmutex);
+    for (i = 0; i < pI915XvMC->attrib.numAttr; ++i) {
+        if (attribute == pI915XvMC->attrib.attributes[i].attribute) {
+            if (pI915XvMC->attribDesc[i].flags & XvGettable) {
+                *value = pI915XvMC->attrib.attributes[i].value;
+                found = 1;
+                break;
+            }
+        }
+    }
+    pthread_mutex_unlock(&pI915XvMC->ctxmutex);
+
+    if (!found)
+        return BadMatch;
+    
+    return Success;
+}
diff --git a/src/xvmc/I915XvMC.h b/src/xvmc/I915XvMC.h
new file mode 100644
index 0000000..0817083
--- /dev/null
+++ b/src/xvmc/I915XvMC.h
@@ -0,0 +1,178 @@
+/***************************************************************************
+
+Copyright 2001 Intel Corporation.  All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL INTEL, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#ifndef _I915XVMC_H
+#define _I915XVMC_H
+
+/* #define XVMC_DEBUG(x) do {x; }while(0); */
+#define XVMC_DEBUG(x)
+
+#include "xf86drm.h"
+#include "i830_common.h"
+#include "i915_hwmc.h"
+#include <X11/Xlibint.h>
+#include <X11/Xutil.h>
+
+#define I915_SUBPIC_PALETTE_SIZE        16
+
+/***************************************************************************
+// i915XvMCDrmMap: Holds the data about the DRM maps
+***************************************************************************/
+typedef struct _i915XvMCDrmMap {
+    drm_handle_t handle;
+    unsigned offset;
+    unsigned size;
+    drmAddress map;
+} i915XvMCDrmMap, *i915XvMCDrmMapPtr;
+
+/***************************************************************************
+// i915XvMCContext: Private Context data referenced via the privData
+//  pointer in the XvMCContext structure.
+***************************************************************************/
+typedef struct _i915XvMCContext {
+    unsigned ctxno;
+    int fd;   /* File descriptor for /dev/dri */
+    unsigned last_render;
+    unsigned last_flip;
+    unsigned dual_prime; /* Flag to identify when dual prime is in use. */
+    unsigned yStride;
+    unsigned short ref;
+    pthread_mutex_t ctxmutex;
+    char busIdString[21]; /* PCI:0:1:0 or PCI:0:2:0 */
+    int lock;   /* Lightweight lock to avoid locking twice */
+    int locked;
+    volatile drmI830Sarea *sarea;
+
+    drmLock *driHwLock;
+    drm_context_t hHWContext; /* drmcontext; */
+    drm_handle_t hsarea;                /* Handle to drm shared memory area */
+    drmAddress sarea_address;	        /* Virtual address of shared memory area */
+    unsigned sarea_size;                /* Size of drm shared memory area */
+    unsigned sarea_priv_offset;	        /* Offset in sarea to private part */
+    unsigned screen;
+    unsigned depth;
+    XvPortID port;		       /* Xv Port ID when displaying */
+    I915XvMCAttrHolder attrib;          /* This contexts attributes and their values */
+    XvAttribute attribDesc[I915_NUM_XVMC_ATTRIBUTES];    /* Attribute decriptions */
+    int haveXv;                        /* Have I initialized the Xv
+                                        * connection for this surface? */
+    XvImage *xvImage;                  /* Fake Xv Image used for command
+                                        * buffer transport to the X server */
+    int attribChanged;                 /* Attributes have changed and need to
+                                        * be uploaded to Xv at next frame
+                                        * display */
+    GC  gc;                            /* X GC needed for displaying */
+    Drawable draw;                     /* Drawable to undisplay from */
+    XID id;
+    XVisualInfo visualInfo;
+    void *drawHash;
+
+    i915XvMCDrmMap sis;
+    i915XvMCDrmMap msb;
+    i915XvMCDrmMap ssb;
+    i915XvMCDrmMap psp;
+    i915XvMCDrmMap psc;
+    i915XvMCDrmMap corrdata;
+
+    struct {
+        unsigned start_offset;
+        unsigned size;
+        unsigned space;
+        unsigned char *ptr;
+    } batch;
+
+    struct 
+    {
+        void *ptr;
+        unsigned size;
+        unsigned offset;
+        unsigned active_buf;
+        unsigned irq_emitted;
+    } alloc;
+} i915XvMCContext;
+
+/***************************************************************************
+// i915XvMCSubpicture: Private data structure for each XvMCSubpicture. This
+//  structure is referenced by the privData pointer in the XvMCSubpicture
+//  structure.
+***************************************************************************/
+typedef struct _i915XvMCSubpicture {
+    unsigned srfNo;
+    unsigned last_render;
+    unsigned last_flip;
+    unsigned offset;
+    unsigned pitch;
+    unsigned char palette[3][16];
+    i915XvMCContext *privContext;
+} i915XvMCSubpicture;
+
+/***************************************************************************
+// i915XvMCSurface: Private data structure for each XvMCSurface. This
+//  structure is referenced by the privData pointer in the XvMCSurface
+//  structure.
+***************************************************************************/
+#define I830_MAX_BUFS 2                   /*Number of YUV buffers per surface */
+typedef struct _i915XvMCSurface {
+    unsigned srfNo;                    /* XvMC private surface numbers */
+    unsigned num_buffers;              /* Number of picture buffers */
+    unsigned curbuf;                   /* Which is the current buffer? */
+    unsigned offsets[I830_MAX_BUFS];    /* Offsets of picture buffers */
+    unsigned last_render;
+    unsigned last_flip;
+    unsigned yStride;                  /* Stride of YUV420 Y component. */
+    unsigned width;                    /* Dimensions */
+    unsigned height;
+    i915XvMCContext *privContext;
+    i915XvMCSubpicture *privSubPic;     /* Subpicture to be blended when
+                                         * displaying. NULL if none. */
+} i915XvMCSurface;
+
+/* Subpicture fourcc */
+#define FOURCC_IA44 0x34344149
+
+/*
+  Definitions for temporary wire protocol hooks to be replaced
+  when a HW independent libXvMC is created.
+*/
+extern Status _xvmc_create_context(Display *dpy, XvMCContext *context,
+				   int *priv_count, uint **priv_data);
+
+extern Status _xvmc_destroy_context(Display *dpy, XvMCContext *context);
+
+extern Status _xvmc_create_surface(Display *dpy, XvMCContext *context,
+				   XvMCSurface *surface, int *priv_count,
+				   uint **priv_data);
+
+extern Status _xvmc_destroy_surface(Display *dpy, XvMCSurface *surface);
+
+extern Status  _xvmc_create_subpicture(Display *dpy, XvMCContext *context,
+				       XvMCSubpicture *subpicture,
+				       int *priv_count, uint **priv_data);
+
+extern Status   _xvmc_destroy_subpicture(Display *dpy,
+					 XvMCSubpicture *subpicture);
+
+#endif /* _I915XVMC_H */
diff --git a/src/xvmc/Makefile.am b/src/xvmc/Makefile.am
index b5c9db9..6733809 100644
--- a/src/xvmc/Makefile.am
+++ b/src/xvmc/Makefile.am
@@ -1,5 +1,6 @@
 if DRI
-lib_LTLIBRARIES=libI810XvMC.la
+lib_LTLIBRARIES=libI810XvMC.la libI915XvMC.la
+
 libI810XvMC_la_SOURCES = I810XvMC.c \
 			 I810XvMC.h
 
@@ -7,4 +8,17 @@ libI810XvMC_la_CFLAGS = @WARN_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@ \
 	-I$(top_srcdir)/src -DTRUE=1 -DFALSE=0
 libI810XvMC_la_LDFLAGS = -version-number 1:0:0
 libI810XvMC_la_LIBADD = @DRI_LIBS@ 
+
+libI915XvMC_la_SOURCES = I915XvMC.c \
+                         I915XvMC.h \
+                         intel_batchbuffer.c \
+                         intel_batchbuffer.h \
+                         xf86dri.c \
+                         xf86dri.h \
+                         xf86dristr.h \
+                         driDrawable.c \
+                         driDrawable.h
+libI915XvMC_la_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@ -I$(top_srcdir)/src -DTRUE=1 -DFALSE=0
+libI915XvMC_la_LDFLAGS = -version-number 1:0:0
+libI915XvMC_la_LIBADD = @DRI_LIBS@
 endif
diff --git a/src/xvmc/driDrawable.c b/src/xvmc/driDrawable.c
new file mode 100644
index 0000000..8386334
--- /dev/null
+++ b/src/xvmc/driDrawable.c
@@ -0,0 +1,174 @@
+/*****************************************************************************
+ * driDrawable.c: Lean Version of DRI utilities.
+ *
+ * Copyright (c) 2005 Thomas Hellstrom. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHOR(S) OR COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+
+#include <X11/Xlibint.h>
+#include <X11/Xutil.h>
+#include "xf86drm.h"
+#include "drm.h"
+#include "xf86dri.h"
+#include "drm_sarea.h"
+#include "driDrawable.h"
+
+static unsigned
+drawStamp(volatile drm_sarea_t * pSarea, int index)
+{
+    return pSarea->drawableTable[index].stamp;
+}
+
+int
+getDRIDrawableInfoLocked(void *drawHash, Display * display, int screen,
+    Drawable draw, unsigned lockFlags, int drmFD, drm_context_t drmContext,
+    drmAddress sarea, Bool updateInfo, drawableInfo ** info,
+    unsigned long infoSize)
+{
+    drawableInfo *drawInfo;
+    void *res;
+    drm_drawable_t drmDraw = 0;
+    volatile drm_sarea_t *pSarea = (drm_sarea_t *) sarea;
+    drm_clip_rect_t *clipFront, *clipBack;
+
+    int ret;
+
+    if (drmHashLookup(drawHash, (unsigned long)draw, &res)) {
+
+	/*
+	 * The drawable is unknown to us. Create it and put it in the
+	 * hash table.
+	 */
+
+	DRM_UNLOCK(drmFD, &pSarea->lock, drmContext);
+	if (!uniDRICreateDrawable(display, screen, draw, &drmDraw)) {
+	    DRM_LOCK(drmFD, &pSarea->lock, drmContext, lockFlags);
+	    return 1;
+	}
+	DRM_LOCK(drmFD, &pSarea->lock, drmContext, lockFlags);
+
+	drawInfo = (drawableInfo *) malloc(infoSize);
+	if (!drawInfo)
+	    return 1;
+
+	drawInfo->drmDraw = drmDraw;
+	drawInfo->stamp = 0;
+	drawInfo->clipFront = 0;
+	drawInfo->clipBack = 0;
+
+	drmHashInsert(drawHash, (unsigned long)draw, drawInfo);
+
+    } else {
+	drawInfo = res;
+    }
+
+    drawInfo->touched = FALSE;
+    while (!drawInfo->clipFront
+	|| drawInfo->stamp != drawStamp(pSarea, drawInfo->index)) {
+
+	/*
+	 * The drawable has been touched since we last got info about it.
+	 * obtain new info from the X server.
+	 */
+
+	drawInfo->touched = TRUE;
+
+	if (updateInfo || !drawInfo->clipFront) {
+	    DRM_UNLOCK(drmFD, &pSarea->lock, drmContext);
+
+	    ret = uniDRIGetDrawableInfo(display, screen, draw,
+		&drawInfo->index, &drawInfo->stamp, &drawInfo->x,
+		&drawInfo->y, &drawInfo->w, &drawInfo->h,
+		&drawInfo->numClipFront, &clipFront,
+		&drawInfo->backX, &drawInfo->backY,
+		&drawInfo->numClipBack, &clipBack);
+
+	    DRM_LIGHT_LOCK(drmFD, &pSarea->lock, drmContext);
+
+	    /*
+	     * Error. Probably the drawable is destroyed. Return error and old values.
+	     */
+
+	    if (!ret) {
+		free(drawInfo);
+		drawInfo = NULL;
+		drmHashDelete(drawHash, (unsigned long)draw);
+
+		DRM_UNLOCK(drmFD, &pSarea->lock, drmContext);
+		uniDRIDestroyDrawable(display, screen, draw);
+		DRM_LOCK(drmFD, &pSarea->lock, drmContext, lockFlags);
+
+		return 1;
+	    }
+
+	    if (drawInfo->stamp != drawStamp(pSarea, drawInfo->index)) {
+
+		/*
+		 * The info is already outdated. Sigh. Have another go.
+		 */
+
+		XFree(clipFront);
+		XFree(clipBack);
+		continue;
+	    }
+
+	    if (drawInfo->clipFront)
+		XFree(drawInfo->clipFront);
+	    drawInfo->clipFront = clipFront;
+	    if (drawInfo->clipBack)
+		XFree(drawInfo->clipBack);
+	    drawInfo->clipBack = clipBack;
+	} else {
+	    if (!drawInfo->clipFront)
+		drawInfo->clipFront = (drm_clip_rect_t *) ~ 0UL;
+	    drawInfo->stamp = drawStamp(pSarea, drawInfo->index);
+	}
+    }
+    *info = drawInfo;
+    return 0;
+}
+
+void
+driDestroyHashContents(void *drawHash)
+{
+    unsigned long key;
+    void *content;
+    drawableInfo *drawInfo;
+
+    if (drmHashFirst(drawHash, &key, &content) < 1)
+	return;
+    drawInfo = (drawableInfo *) content;
+    if (drawInfo->clipBack)
+	XFree(drawInfo->clipBack);
+    if (drawInfo->clipFront)
+	XFree(drawInfo->clipFront);
+    free(drawInfo);
+    while (drmHashNext(drawHash, &key, &content) == 1) {
+	drawInfo = (drawableInfo *) content;
+	if (drawInfo->clipBack)
+	    XFree(drawInfo->clipBack);
+	if (drawInfo->clipFront)
+	    XFree(drawInfo->clipFront);
+	free(drawInfo);
+    }
+
+    return;
+}
diff --git a/src/xvmc/driDrawable.h b/src/xvmc/driDrawable.h
new file mode 100644
index 0000000..a758c7c
--- /dev/null
+++ b/src/xvmc/driDrawable.h
@@ -0,0 +1,64 @@
+/*****************************************************************************
+ * driDrawable.h: Lean Version of DRI utilities.
+ *
+ * Copyright (c) 2005 Thomas Hellstrom. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHOR(S) OR COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _DRIDRAWABLE_H
+#define _DRIDRAWABLE_H
+
+typedef struct _drawableInfo
+{
+    drm_drawable_t drmDraw;
+    unsigned stamp;
+    unsigned index;
+    drm_clip_rect_t *clipFront;
+    drm_clip_rect_t *clipBack;
+    int x;
+    int y;
+    int w;
+    int h;
+    int backX;
+    int backY;
+    int numClipFront;
+    int numClipBack;
+    Bool touched;
+} drawableInfo;
+
+/*
+ * Get updated info about the drawable "draw". The drawableInfo record returned is malloced
+ * and administrated internally. Never free it unless you know exactly what you are doing.
+ * The drm hash table "drawHash" needs to be initialized externally.
+ */
+
+extern int
+getDRIDrawableInfoLocked(void *drawHash, Display * display, int screen,
+    Drawable draw, unsigned lockFlags, int drmFD, drm_context_t drmContext,
+    drmAddress sarea, Bool updateInfo, drawableInfo ** info,
+    unsigned long infoSize);
+
+/*
+ * Free all resources created by the above function. Typically done on exit.
+ */
+
+extern void driDestroyHashContents(void *drawHash);
+
+#endif
diff --git a/src/xvmc/i915_program.h b/src/xvmc/i915_program.h
new file mode 100644
index 0000000..d11a518
--- /dev/null
+++ b/src/xvmc/i915_program.h
@@ -0,0 +1,276 @@
+#ifndef _I915_PROGRAM_H
+#define _I915_PROGRAM_H
+
+#define REG_TYPE_R                 0    /* temporary regs, no need to
+                                         * dcl, must be written before
+                                         * read -- Preserved between
+                                         * phases.
+                                         */
+#define REG_TYPE_T                 1    /* Interpolated values, must be
+                                         * dcl'ed before use.
+                                         *
+                                         * 0..7: texture coord,
+                                         * 8: diffuse spec,
+                                         * 9: specular color,
+                                         * 10: fog parameter in w.
+                                         */
+#define REG_TYPE_CONST             2    /* Restriction: only one const
+                                         * can be referenced per
+                                         * instruction, though it may be
+                                         * selected for multiple inputs.
+                                         * Constants not initialized
+                                         * default to zero.
+                                         */
+#define REG_TYPE_S                 3    /* sampler */
+#define REG_TYPE_OC                4    /* output color (rgba) */
+#define REG_TYPE_OD                5    /* output depth (w), xyz are
+                                         * temporaries.  If not written,
+                                         * interpolated depth is used?
+                                         */
+#define REG_TYPE_U                 6    /* unpreserved temporaries */
+#define REG_TYPE_MASK              0x7
+#define REG_NR_MASK                0xf
+
+/* REG_TYPE_T:
+ */
+#define T_TEX0     0
+#define T_TEX1     1
+#define T_TEX2     2
+#define T_TEX3     3
+#define T_TEX4     4
+#define T_TEX5     5
+#define T_TEX6     6
+#define T_TEX7     7
+#define T_DIFFUSE  8
+#define T_SPECULAR 9
+#define T_FOG_W    10           /* interpolated fog is in W coord */
+
+/* Arithmetic instructions */
+
+/* .replicate_swizzle == selection and replication of a particular
+ * scalar channel, ie., .xxxx, .yyyy, .zzzz or .wwww
+ */
+#define A0_NOP    (0x0<<24)     /* no operation */
+#define A0_ADD    (0x1<<24)     /* dst = src0 + src1 */
+#define A0_MOV    (0x2<<24)     /* dst = src0 */
+#define A0_MUL    (0x3<<24)     /* dst = src0 * src1 */
+#define A0_MAD    (0x4<<24)     /* dst = src0 * src1 + src2 */
+#define A0_DP2ADD (0x5<<24)     /* dst.xyzw = src0.xy dot src1.xy + src2.replicate_swizzle */
+#define A0_DP3    (0x6<<24)     /* dst.xyzw = src0.xyz dot src1.xyz */
+#define A0_DP4    (0x7<<24)     /* dst.xyzw = src0.xyzw dot src1.xyzw */
+#define A0_FRC    (0x8<<24)     /* dst = src0 - floor(src0) */
+#define A0_RCP    (0x9<<24)     /* dst.xyzw = 1/(src0.replicate_swizzle) */
+#define A0_RSQ    (0xa<<24)     /* dst.xyzw = 1/(sqrt(abs(src0.replicate_swizzle))) */
+#define A0_EXP    (0xb<<24)     /* dst.xyzw = exp2(src0.replicate_swizzle) */
+#define A0_LOG    (0xc<<24)     /* dst.xyzw = log2(abs(src0.replicate_swizzle)) */
+#define A0_CMP    (0xd<<24)     /* dst = (src0 >= 0.0) ? src1 : src2 */
+#define A0_MIN    (0xe<<24)     /* dst = (src0 < src1) ? src0 : src1 */
+#define A0_MAX    (0xf<<24)     /* dst = (src0 >= src1) ? src0 : src1 */
+#define A0_FLR    (0x10<<24)    /* dst = floor(src0) */
+#define A0_MOD    (0x11<<24)    /* dst = src0 fmod 1.0 */
+#define A0_TRC    (0x12<<24)    /* dst = int(src0) */
+#define A0_SGE    (0x13<<24)    /* dst = src0 >= src1 ? 1.0 : 0.0 */
+#define A0_SLT    (0x14<<24)    /* dst = src0 < src1 ? 1.0 : 0.0 */
+#define A0_DEST_SATURATE                 (1<<22)
+#define A0_DEST_TYPE_SHIFT                19
+/* Allow: R, OC, OD, U */
+#define A0_DEST_NR_SHIFT                 14
+/* Allow R: 0..15, OC,OD: 0..0, U: 0..2 */
+#define A0_DEST_CHANNEL_X                (1<<10)
+#define A0_DEST_CHANNEL_Y                (2<<10)
+#define A0_DEST_CHANNEL_Z                (4<<10)
+#define A0_DEST_CHANNEL_W                (8<<10)
+#define A0_DEST_CHANNEL_ALL              (0xf<<10)
+#define A0_DEST_CHANNEL_SHIFT            10
+#define A0_SRC0_TYPE_SHIFT               7
+#define A0_SRC0_NR_SHIFT                 2
+
+#define A0_DEST_CHANNEL_XY              (A0_DEST_CHANNEL_X|A0_DEST_CHANNEL_Y)
+#define A0_DEST_CHANNEL_XYZ             (A0_DEST_CHANNEL_XY|A0_DEST_CHANNEL_Z)
+
+#define SRC_X        0
+#define SRC_Y        1
+#define SRC_Z        2
+#define SRC_W        3
+#define SRC_ZERO     4
+#define SRC_ONE      5
+
+#define A1_SRC0_CHANNEL_X_NEGATE         (1<<31)
+#define A1_SRC0_CHANNEL_X_SHIFT          28
+#define A1_SRC0_CHANNEL_Y_NEGATE         (1<<27)
+#define A1_SRC0_CHANNEL_Y_SHIFT          24
+#define A1_SRC0_CHANNEL_Z_NEGATE         (1<<23)
+#define A1_SRC0_CHANNEL_Z_SHIFT          20
+#define A1_SRC0_CHANNEL_W_NEGATE         (1<<19)
+#define A1_SRC0_CHANNEL_W_SHIFT          16
+#define A1_SRC1_TYPE_SHIFT               13
+#define A1_SRC1_NR_SHIFT                 8
+#define A1_SRC1_CHANNEL_X_NEGATE         (1<<7)
+#define A1_SRC1_CHANNEL_X_SHIFT          4
+#define A1_SRC1_CHANNEL_Y_NEGATE         (1<<3)
+#define A1_SRC1_CHANNEL_Y_SHIFT          0
+
+#define A2_SRC1_CHANNEL_Z_NEGATE         (1<<31)
+#define A2_SRC1_CHANNEL_Z_SHIFT          28
+#define A2_SRC1_CHANNEL_W_NEGATE         (1<<27)
+#define A2_SRC1_CHANNEL_W_SHIFT          24
+#define A2_SRC2_TYPE_SHIFT               21
+#define A2_SRC2_NR_SHIFT                 16
+#define A2_SRC2_CHANNEL_X_NEGATE         (1<<15)
+#define A2_SRC2_CHANNEL_X_SHIFT          12
+#define A2_SRC2_CHANNEL_Y_NEGATE         (1<<11)
+#define A2_SRC2_CHANNEL_Y_SHIFT          8
+#define A2_SRC2_CHANNEL_Z_NEGATE         (1<<7)
+#define A2_SRC2_CHANNEL_Z_SHIFT          4
+#define A2_SRC2_CHANNEL_W_NEGATE         (1<<3)
+#define A2_SRC2_CHANNEL_W_SHIFT          0
+
+/* Declaration instructions */
+#define D0_DCL       (0x19<<24) /* Declare a t (interpolated attrib)
+                                 * register or an s (sampler)
+                                 * register. */
+#define D0_SAMPLE_TYPE_SHIFT              22
+#define D0_SAMPLE_TYPE_2D                 (0x0<<22)
+#define D0_SAMPLE_TYPE_CUBE               (0x1<<22)
+#define D0_SAMPLE_TYPE_VOLUME             (0x2<<22)
+#define D0_SAMPLE_TYPE_MASK               (0x3<<22)
+
+#define D0_TYPE_SHIFT                19
+/* Allow: T, S */
+#define D0_NR_SHIFT                  14
+/* Allow T: 0..10, S: 0..15 */
+#define D0_CHANNEL_X                (1<<10)
+#define D0_CHANNEL_Y                (2<<10)
+#define D0_CHANNEL_Z                (4<<10)
+#define D0_CHANNEL_W                (8<<10)
+#define D0_CHANNEL_ALL              (0xf<<10)
+#define D0_CHANNEL_NONE             (0<<10)
+
+#define D0_CHANNEL_XY               (D0_CHANNEL_X|D0_CHANNEL_Y)
+#define D0_CHANNEL_XYZ              (D0_CHANNEL_XY|D0_CHANNEL_Z)
+
+/* I915 Errata: Do not allow (xz), (xw), (xzw) combinations for diffuse
+ * or specular declarations.
+ *
+ * For T dcls, only allow: (x), (xy), (xyz), (w), (xyzw)
+ *
+ * Must be zero for S (sampler) dcls
+ */
+#define D1_MBZ                          0
+#define D2_MBZ                          0
+
+/* Texture instructions */
+#define T0_TEXLD     (0x15<<24) /* Sample texture using predeclared
+                                 * sampler and address, and output
+                                 * filtered texel data to destination
+                                 * register */
+#define T0_TEXLDP    (0x16<<24) /* Same as texld but performs a
+                                 * perspective divide of the texture
+                                 * coordinate .xyz values by .w before
+                                 * sampling. */
+#define T0_TEXLDB    (0x17<<24) /* Same as texld but biases the
+                                 * computed LOD by w.  Only S4.6 two's
+                                 * comp is used.  This implies that a
+                                 * float to fixed conversion is
+                                 * done. */
+#define T0_TEXKILL   (0x18<<24) /* Does not perform a sampling
+                                 * operation.  Simply kills the pixel
+                                 * if any channel of the address
+                                 * register is < 0.0. */
+#define T0_DEST_TYPE_SHIFT                19
+/* Allow: R, OC, OD, U */
+/* Note: U (unpreserved) regs do not retain their values between
+ * phases (cannot be used for feedback)
+ *
+ * Note: oC and OD registers can only be used as the destination of a
+ * texture instruction once per phase (this is an implementation
+ * restriction).
+ */
+#define T0_DEST_NR_SHIFT                 14
+/* Allow R: 0..15, OC,OD: 0..0, U: 0..2 */
+#define T0_SAMPLER_NR_SHIFT              0      /* This field ignored for TEXKILL */
+#define T0_SAMPLER_NR_MASK               (0xf<<0)
+
+#define T1_ADDRESS_REG_TYPE_SHIFT        24     /* Reg to use as texture coord */
+/* Allow R, T, OC, OD -- R, OC, OD are 'dependent' reads, new program phase */
+#define T1_ADDRESS_REG_NR_SHIFT          17
+#define T2_MBZ                           0
+
+
+/* Having zero and one in here makes the definition of swizzle a lot
+ * easier.
+ */
+#define UREG_TYPE_SHIFT               29
+#define UREG_NR_SHIFT                 24
+#define UREG_CHANNEL_X_NEGATE_SHIFT   23
+#define UREG_CHANNEL_X_SHIFT          20
+#define UREG_CHANNEL_Y_NEGATE_SHIFT   19
+#define UREG_CHANNEL_Y_SHIFT          16
+#define UREG_CHANNEL_Z_NEGATE_SHIFT   15
+#define UREG_CHANNEL_Z_SHIFT          12
+#define UREG_CHANNEL_W_NEGATE_SHIFT   11
+#define UREG_CHANNEL_W_SHIFT          8
+#define UREG_CHANNEL_ZERO_NEGATE_MBZ  5
+#define UREG_CHANNEL_ZERO_SHIFT       4
+#define UREG_CHANNEL_ONE_NEGATE_MBZ   1
+#define UREG_CHANNEL_ONE_SHIFT        0
+
+#define UREG_BAD          0xffffffff    /* not a valid ureg */
+
+#define X    SRC_X
+#define Y    SRC_Y
+#define Z    SRC_Z
+#define W    SRC_W
+#define ZERO SRC_ZERO
+#define ONE  SRC_ONE
+
+/* Construct a ureg:
+ */
+#define UREG(type, nr) (((type) << UREG_TYPE_SHIFT) |           \
+                        ((nr)  << UREG_NR_SHIFT) |              \
+                        (X     << UREG_CHANNEL_X_SHIFT) |       \
+                        (Y     << UREG_CHANNEL_Y_SHIFT) |       \
+                        (Z     << UREG_CHANNEL_Z_SHIFT) |       \
+                        (W     << UREG_CHANNEL_W_SHIFT) |       \
+                        (ZERO  << UREG_CHANNEL_ZERO_SHIFT) |    \
+                        (ONE   << UREG_CHANNEL_ONE_SHIFT))
+
+#define GET_CHANNEL_SRC( reg, channel ) ((reg<<(channel*4)) & (0xf<<20))
+#define CHANNEL_SRC( src, channel ) (src>>(channel*4))
+
+#define GET_UREG_TYPE(reg) (((reg)>>UREG_TYPE_SHIFT)&REG_TYPE_MASK)
+#define GET_UREG_NR(reg)   (((reg)>>UREG_NR_SHIFT)&REG_NR_MASK)
+
+#define UREG_XYZW_CHANNEL_MASK 0x00ffff00
+
+#define A0_DEST(reg) (((reg) & UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT)
+#define D0_DEST(reg) (((reg) & UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT)
+#define T0_DEST(reg) (((reg) & UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT)
+#define A0_SRC0(reg) (((reg) & UREG_MASK)>>UREG_A0_SRC0_SHIFT_LEFT)
+#define A1_SRC0(reg) (((reg) & UREG_MASK)<<UREG_A1_SRC0_SHIFT_RIGHT)
+#define A1_SRC1(reg) (((reg) & UREG_MASK)>>UREG_A1_SRC1_SHIFT_LEFT)
+#define A2_SRC1(reg) (((reg) & UREG_MASK)<<UREG_A2_SRC1_SHIFT_RIGHT)
+#define A2_SRC2(reg) (((reg) & UREG_MASK)>>UREG_A2_SRC2_SHIFT_LEFT)
+
+/* These are special, and don't have swizzle/negate bits.
+ */
+#define T0_SAMPLER( reg )     (GET_UREG_NR(reg)<<T0_SAMPLER_NR_SHIFT)
+#define T1_ADDRESS_REG( reg ) ((GET_UREG_NR(reg)<<T1_ADDRESS_REG_NR_SHIFT) | \
+                               (GET_UREG_TYPE(reg)<<T1_ADDRESS_REG_TYPE_SHIFT))
+
+
+/* Macros for translating UREG's into the various register fields used
+ * by the I915 programmable unit.
+ */
+#define UREG_A0_DEST_SHIFT_LEFT  (UREG_TYPE_SHIFT - A0_DEST_TYPE_SHIFT)
+#define UREG_A0_SRC0_SHIFT_LEFT  (UREG_TYPE_SHIFT - A0_SRC0_TYPE_SHIFT)
+#define UREG_A1_SRC0_SHIFT_RIGHT (A1_SRC0_CHANNEL_W_SHIFT - UREG_CHANNEL_W_SHIFT)
+#define UREG_A1_SRC1_SHIFT_LEFT  (UREG_TYPE_SHIFT - A1_SRC1_TYPE_SHIFT)
+#define UREG_A2_SRC1_SHIFT_RIGHT (A2_SRC1_CHANNEL_W_SHIFT - UREG_CHANNEL_W_SHIFT)
+#define UREG_A2_SRC2_SHIFT_LEFT  (UREG_TYPE_SHIFT - A2_SRC2_TYPE_SHIFT)
+
+#define UREG_MASK         0xffffff00
+#define UREG_TYPE_NR_MASK ((REG_TYPE_MASK << UREG_TYPE_SHIFT) | \
+                           (REG_NR_MASK << UREG_NR_SHIFT))
+
+#endif
diff --git a/src/xvmc/i915_structs.h b/src/xvmc/i915_structs.h
new file mode 100644
index 0000000..c9545af
--- /dev/null
+++ b/src/xvmc/i915_structs.h
@@ -0,0 +1,898 @@
+#ifndef _I915_STRUCTS_H
+#define _I915_STRUCTS_H
+
+/* MI_INSTRUCTION */
+#define CMD_MI          0x00
+
+#define OPC_MI_FLUSH                            (0x04)
+
+struct i915_mi_flush
+{
+    struct {
+        unsigned map_cache_invalidate : 1;
+        unsigned pad0 : 1;
+        unsigned render_cache_flush_inhibit : 1;
+        unsigned scene_count : 1;
+        unsigned end_scene : 1;
+        unsigned pad1 : 18;
+        unsigned opcode : 6;
+        unsigned type : 3;
+    } dw0;
+};
+
+/* 3D_INSTRUCTION */
+#define CMD_3D          0x03
+
+#define OPC_3DMPEG_MACROBLOCK_IPICTURE          (0x01 + (0x1e << 5))
+#define OPC_3DMPEG_SET_ORIGIN                   (0x10 + (0x1e << 5))
+#define OPC_3DMPEG_MACROBLOCK                   (0x11 + (0x1e << 5))        
+#define OPC_3DMPEG_SLICE                        (0x12 + (0x1e << 5))
+#define OPC_3DMPEG_QM_PALETTE_LOAD              (0x13 + (0x1e << 5))
+
+#define OPC_3DSTATE_MAP_STATE                   (0x00 + (0x1d << 8))
+#define OPC_3DSTATE_SAMPLER_STATE               (0x01 + (0x1d << 8))
+#define OPC_3DSTATE_LOAD_STATE_IMMEDIATE_1      (0x04 + (0x1d << 8))
+#define OPC_3DSTATE_PIXEL_SHADER_PROGRAM        (0x05 + (0x1d << 8))
+#define OPC_3DSTATE_PIXEL_SHADER_CONSTANTS      (0x06 + (0x1d << 8))
+#define OPC_3DSTATE_LOAD_INDIRECT               (0x07 + (0x1d << 8))
+
+#define OPC_3DPRIMITIVE                         (0x1f)
+
+#define OPC_3DSTATE_SCISSOR_RECTANGLE           (0x81 + (0x1d << 8))
+#define OPC_3DSTATE_DEST_BUFFER_VARIABLES       (0x85 + (0x1d << 8))
+#define OPC_3DSTATE_DEST_BUFFER_VARIABLES_MPEG  (0x87 + (0x1d << 8))
+#define OPC_3DSTATE_BUFFER_INFO                 (0x8e + (0x1d << 8))
+
+/*
+ * 3DMPEG instructions
+ */
+struct i915_3dmpeg_macroblock_header
+{
+    struct {
+        unsigned length : 19;
+        unsigned opcode : 10;
+        unsigned type : 3;
+    } dw0;
+    
+    struct {
+        unsigned intra : 1;
+        unsigned forward : 1;
+        unsigned backward : 1;
+        unsigned h263_4mv : 1;
+        unsigned pad0 : 1;
+        unsigned dct_type : 1;
+        unsigned pad1 : 2;
+        unsigned motion_type : 2;
+        unsigned pad2 : 2;
+        unsigned vertical_field_select : 4;
+        unsigned coded_block_pattern : 6;
+        unsigned pad3 : 2;
+        unsigned skipped_macroblocks : 7;
+        unsigned pad4 : 1;
+    } dw1;
+};
+
+struct i915_3dmpeg_macroblock_0mv
+{
+    struct i915_3dmpeg_macroblock_header header;
+};
+
+struct i915_3dmpeg_macroblock_1fbmv
+{
+    struct i915_3dmpeg_macroblock_header header;    
+    unsigned dw2;
+    unsigned dw3;
+};
+struct i915_3dmpeg_macroblock_2fbmv
+{
+    struct i915_3dmpeg_macroblock_header header;
+    unsigned dw2;
+    unsigned dw3;
+    unsigned dw4;
+    unsigned dw5;
+};
+
+struct i915_3dmpeg_macroblock_5fmv
+{
+    struct i915_3dmpeg_macroblock_header header;
+    unsigned dw2;
+    unsigned dw3;
+    unsigned dw4;
+    unsigned dw5;
+    unsigned dw6;
+};
+  
+struct i915_3dmpeg_macroblock_ipicture
+{
+    struct {
+        unsigned pad0 : 5;
+        unsigned dct_type : 1;
+        unsigned pad1 : 13;
+        unsigned opcode : 10;
+        unsigned type : 3;
+    } dw0;
+};
+
+struct i915_3dmpeg_set_origin
+{
+    struct {
+        unsigned length : 19;
+        unsigned opcode : 10;
+        unsigned type : 3;
+    } dw0;
+
+    struct {
+        unsigned v_origin : 7;
+        unsigned pad0 : 1;
+        unsigned h_origin : 7;
+        unsigned pad1 : 17;
+    } dw1;
+};
+      
+struct i915_3dmpeg_slice
+{
+    struct {
+        unsigned length : 19;
+        unsigned opcode : 10;
+        unsigned type : 3;
+    } dw0;
+    
+    struct {
+        unsigned fst_mb_bit_off : 3;
+        unsigned pad0 : 5;
+        unsigned mb_count : 7;
+        unsigned pad1 : 1;
+        unsigned v_position : 7;
+        unsigned pad2 : 1;
+        unsigned h_position : 7;
+        unsigned pad3 : 1;
+    } dw1;
+
+    struct {
+        unsigned length_minus_one : 17;
+        unsigned pad0 : 7;
+        unsigned qt_scale_code : 5;
+        unsigned pad1 : 3;
+    } dw2;
+};
+
+struct i915_3dmpeg_qm_palette_load
+{
+    struct {
+        unsigned length : 4;
+        unsigned pad0 : 15;
+        unsigned opcode : 10;
+        unsigned type : 3;
+    } dw0;
+    
+    unsigned quantmatrix[16];    
+};        
+
+
+/*
+ * 3DSTATE instruction
+ */
+#define BUFFERID_COLOR_BACK     3
+#define BUFFERID_COLOR_AUX      4
+#define BUFFERID_MC_INTRA_CORR  5
+
+#define TILEWALK_XMAJOR         0
+#define TILEWALK_YMAJOR         1
+
+struct i915_3dstate_buffer_info
+{
+    struct {
+        unsigned length : 16;
+        unsigned opcode : 13;
+        unsigned type : 3;
+    } dw0;
+
+    struct {
+        unsigned pad0 : 2;
+        unsigned pitch : 12;
+        unsigned pad1 : 7;
+        unsigned walk : 1;
+        unsigned tiled_surface : 1;
+        unsigned fence_regs : 1;
+        unsigned buffer_id : 4;
+        unsigned aux_id : 1;
+        unsigned pad2 : 3;
+    } dw1;
+
+    struct {
+        unsigned pad0 : 2;
+        unsigned base_address : 27;
+        unsigned pad1 : 3;
+    } dw2;
+};
+
+#define COLORBUFFER_X1R5G5B5     0x01
+#define COLORBUFFER_R5G6B5       0x02
+#define COLORBUFFER_A8R8G8B8     0x03
+#define COLORBUFFER_YCRCB_SWAP   0x04
+#define COLORBUFFER_YCRCB_NORMAL 0x05
+#define COLORBUFFER_YCRCB_SWAPUV 0x06
+#define COLORBUFFER_YCRCB_SWAPUVY   0x07
+#define COLORBUFFER_A4R4G4B4     0x08
+#define COLORBUFFER_A1R5G5B5     0x09
+#define COLORBUFFER_A2R10G10B10  0x0a
+
+
+struct i915_3dstate_dest_buffer_variables
+{
+    struct {
+        unsigned length : 16;
+        unsigned opcode : 13;
+        unsigned type : 3;
+    } dw0;
+    
+    struct {
+        unsigned v_ls_offset : 1;
+        unsigned v_ls : 1;
+        unsigned depth_fmt : 2;
+        unsigned pad0 : 4;
+        unsigned color_fmt : 4;
+        unsigned yuv422_select : 3;
+        unsigned pad1 : 1;
+        unsigned dest_v_bias : 4;
+        unsigned dest_h_bias : 4;
+        unsigned dither_enhancement : 1;
+        unsigned linear_gamma : 1;
+        unsigned dither_pattern : 2;
+        unsigned lod_preclamp : 1;
+        unsigned edt_zone : 1;          /* early depth test in zone rendering */
+        unsigned texture_default_color : 1;
+        unsigned edt_classic : 1;       /* early depth test in classic mode */
+    } dw1;
+};
+
+#define MPEG_DECODE_MC          0
+#define MPEG_DECODE_VLD_IDCT_MC 1
+
+#define MPEG_I_PICTURE          1
+#define MPEG_P_PICTURE          2
+#define MPEG_B_PICTURE          3
+
+struct i915_3dstate_dest_buffer_variables_mpeg
+{
+    struct {
+        unsigned length : 16;
+        unsigned opcode : 13;
+        unsigned type : 3;
+    } dw0;
+
+    struct {
+        unsigned picture_width : 7;
+        unsigned pad0 : 1;
+        unsigned v_subsample_factor : 2;
+        unsigned h_subsample_factor : 2;
+        unsigned tff : 1;
+        unsigned mismatch : 1;
+        unsigned pad1 : 1;
+        unsigned intra8 : 1;
+        unsigned abort_on_error : 8;
+        unsigned pad2 : 4;
+        unsigned bidir_avrg_control : 1;
+        unsigned rcontrol : 1;
+        unsigned decoder_mode : 2;
+    } dw1;
+        
+    struct {
+        unsigned pad0 : 1;
+        unsigned picture_coding_type : 2;
+        unsigned pad1 : 2;
+        unsigned scan_order : 1;
+        unsigned pad2 : 2;
+        unsigned q_scale_type : 1;
+        unsigned concealment : 1;
+        unsigned fpf_dct : 1;
+        unsigned pad3 : 2;
+        unsigned intra_dc : 2;
+        unsigned intra_vlc : 1;
+        unsigned f_code00 : 4;
+        unsigned f_code01 : 4;
+        unsigned f_code10 : 4;
+        unsigned f_code11 : 4;
+    } dw2;
+};
+
+#define MAP_MAP0        0x0001
+#define MAP_MAP1        0x0002
+#define MAP_MAP2        0x0004
+#define MAP_MAP3        0x0008
+#define MAP_MAP4        0x0010
+#define MAP_MAP5        0x0020
+#define MAP_MAP6        0x0040
+#define MAP_MAP7        0x0080
+#define MAP_MAP8        0x0100
+#define MAP_MAP9        0x0200
+#define MAP_MAP10       0x0400
+#define MAP_MAP11       0x0800
+#define MAP_MAP12       0x1000
+#define MAP_MAP13       0x2000
+#define MAP_MAP14       0x4000
+#define MAP_MAP15       0x8000
+
+struct texture_map
+{
+    struct {
+        unsigned v_ls_offset : 1;
+        unsigned v_ls : 1;
+        unsigned base_address : 27;
+        unsigned pad0 : 2;
+        unsigned untrusted : 1;
+    } tm0;
+
+    struct {
+        unsigned tile_walk : 1;
+        unsigned tiled_surface : 1;
+        unsigned utilize_fence_regs : 1;
+        unsigned texel_fmt : 4;
+        unsigned surface_fmt : 3;
+        unsigned width : 11;
+        unsigned height : 11;
+    } tm1;
+    
+    struct {
+        unsigned depth : 8;
+        unsigned mipmap_layout : 1;
+        unsigned max_lod : 6;
+        unsigned cube_face : 6;
+        unsigned pitch : 11;
+    } tm2;
+};
+
+struct i915_3dstate_map_state
+{
+    struct {
+        unsigned length : 6;
+        unsigned pad0 : 9;
+        unsigned retain : 1;
+        unsigned opcode : 13;
+        unsigned type : 3;
+    } dw0;
+
+    struct {
+        unsigned pad0 : 16;
+        unsigned map_mask : 16;
+    } dw1;
+//    struct texture_map *tms;
+};
+
+#define SAMPLER_SAMPLER0        0x0001
+#define SAMPLER_SAMPLER1        0x0002
+#define SAMPLER_SAMPLER2        0x0004
+#define SAMPLER_SAMPLER3        0x0008
+#define SAMPLER_SAMPLER4        0x0010
+#define SAMPLER_SAMPLER5        0x0020
+#define SAMPLER_SAMPLER6        0x0040
+#define SAMPLER_SAMPLER7        0x0080
+#define SAMPLER_SAMPLER8        0x0100
+#define SAMPLER_SAMPLER9        0x0200
+#define SAMPLER_SAMPLER10       0x0400
+#define SAMPLER_SAMPLER11       0x0800
+#define SAMPLER_SAMPLER12       0x1000
+#define SAMPLER_SAMPLER13       0x2000
+#define SAMPLER_SAMPLER14       0x4000
+#define SAMPLER_SAMPLER15       0x8000
+
+#define MIPFILTER_NONE          0
+#define MIPFILTER_NEAREST       1
+#define MIPFILTER_LINEAR        3
+
+#define MAPFILTER_NEAREST       0
+#define MAPFILTER_LINEAR        1
+#define MAPFILTER_ANISOTROPIC   2
+#define MAPFILTER_4X4_1         3
+#define MAPFILTER_4X4_2         4
+#define MAPFILTER_4X4_FLAT      5
+#define MAPFILTER_MONO          6
+
+#define ANISORATIO_2            0
+#define ANISORATIO_4            1
+
+#define PREFILTEROP_ALWAYS      0
+#define PREFILTEROP_NEVER       1
+#define PREFILTEROP_LESS        2
+#define PREFILTEROP_EQUAL       3
+#define PREFILTEROP_LEQUAL      4
+#define PREFILTEROP_GREATER     5
+#define PREFILTEROP_NOTEQUAL    6
+#define PREFILTEROP_GEQUAL      7
+
+#define TEXCOORDMODE_WRAP       0
+#define TEXCOORDMODE_MIRROR     1
+#define TEXCOORDMODE_CLAMP      2
+#define TEXCOORDMODE_CUBE       3
+#define TEXCOORDMODE_CLAMP_BORDER       4
+#define TEXCOORDMODE_MIRROR_ONCE        5
+
+struct texture_sampler
+{
+    struct {
+        unsigned shadow_function : 3;
+        unsigned max_anisotropy : 1;
+        unsigned shadow_enable : 1;
+        unsigned lod_bias : 9;
+        unsigned min_filter : 3;
+        unsigned mag_filter : 3;
+        unsigned mip_filter : 2;
+        unsigned base_level : 5;
+        unsigned chromakey_index : 2;
+        unsigned color_conversion : 1;
+        unsigned planar2packet : 1;
+        unsigned reverse_gamma : 1;
+    } ts0;
+
+    struct {
+        unsigned east_deinterlacer : 1;
+        unsigned map_index : 4;
+        unsigned normalized_coor : 1;
+        unsigned tcz_control : 3;
+        unsigned tcy_control : 3;
+        unsigned tcx_control : 3;
+        unsigned chromakey_enable : 1;
+        unsigned keyed_texture_filter : 1;
+        unsigned kill_pixel : 1;
+        unsigned pad0 : 6;
+        unsigned min_lod : 8;
+    } ts1;
+
+    struct {
+        unsigned default_color;
+    } ts2;
+};
+
+struct i915_3dstate_sampler_state
+{
+    struct {
+        unsigned length : 6;
+        unsigned pad0 : 10;
+        unsigned opcode : 13;
+        unsigned type : 3;
+    } dw0;
+
+    struct {
+        unsigned sampler_masker : 16;
+        unsigned pad0 : 16;
+    } dw1;
+};
+
+struct arithmetic_inst
+{
+    struct {
+        unsigned pad0 : 2;
+        unsigned src0_reg : 5;
+        unsigned src0_reg_t : 3;
+        unsigned dest_channel_mask : 4;
+        unsigned dest_reg : 4;
+        unsigned pad1 : 1;
+        unsigned dest_reg_t: 3;
+        unsigned dest_saturate : 1;
+        unsigned pad2 : 1;
+        unsigned opcode : 5;
+        unsigned pad3 : 3;
+    } dw0;
+
+    struct {
+        unsigned src1_y_select : 3;
+        unsigned src1_y_negate : 1;
+        unsigned src1_x_select : 3;
+        unsigned src1_x_negate : 1;
+        unsigned src1_reg : 5;
+        unsigned src1_reg_t : 3;
+        unsigned src0_w_select : 3;
+        unsigned src0_w_negate : 1;
+        unsigned src0_z_select : 3;
+        unsigned src0_z_negate : 1;
+        unsigned src0_y_select : 3;
+        unsigned src0_y_negate : 1;
+        unsigned src0_x_select : 3;
+        unsigned src0_x_negate : 1;
+    } dw1;
+
+    struct {
+        unsigned src2_w_select : 3;
+        unsigned src2_w_negate : 1;
+        unsigned src2_z_select : 3;
+        unsigned src2_z_negate : 1;
+        unsigned src2_y_select : 3;
+        unsigned src2_y_negate : 1;
+        unsigned src2_x_select : 3;
+        unsigned src2_x_negate : 1;
+        unsigned src2_reg : 5;
+        unsigned src2_reg_t : 3;
+        unsigned src1_w_select : 3;
+        unsigned src1_w_negate : 1;
+        unsigned src1_z_select : 3;
+        unsigned src1_z_negate : 1;
+    } dw2;
+};
+
+struct texture_inst
+{
+    struct {
+        unsigned sampler_reg : 4;
+        unsigned pad0 : 10;
+        unsigned dest_reg : 4;
+        unsigned pad1 : 1;
+        unsigned dest_reg_t : 3;
+        unsigned pad2 : 2;
+        unsigned opcode : 5;
+        unsigned pad3 : 3;
+    } dw0;
+
+    struct {
+        unsigned pad0 : 16;
+        unsigned address_reg : 5;
+        unsigned pad1 : 3;
+        unsigned address_reg_t : 3;
+        unsigned pad2 : 5;
+    } dw1;
+
+    struct {
+        unsigned pad0;
+    } dw2;
+};
+
+struct declaration_inst
+{
+    struct {
+        unsigned pad0 : 10;
+        unsigned decl_channel_mask : 4;
+        unsigned decl_reg : 4;
+        unsigned pad1 : 1;
+        unsigned decl_reg_t : 2;
+        unsigned pad2 : 1;
+        unsigned sampler_type : 2;
+        unsigned opcode : 5;
+        unsigned pad3 : 3;
+    } dw0;
+
+    struct {
+        unsigned pad0;
+    } dw1;
+
+    struct {
+        unsigned pad0;
+    } dw2;
+};
+
+union shader_inst 
+{
+    struct arithmetic_inst a;
+    struct texture_inst t;
+    struct declaration_inst d;
+};
+
+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;
+};
+
+#define REG_CR0         0x00000001
+#define REG_CR1         0x00000002
+#define REG_CR2         0x00000004
+#define REG_CR3         0x00000008
+#define REG_CR4         0x00000010
+#define REG_CR5         0x00000020
+#define REG_CR6         0x00000040
+#define REG_CR7         0x00000080
+#define REG_CR8         0x00000100
+#define REG_CR9         0x00000200
+#define REG_CR10        0x00000400
+#define REG_CR11        0x00000800
+#define REG_CR12        0x00001000
+#define REG_CR13        0x00002000
+#define REG_CR14        0x00004000
+#define REG_CR15        0x00008000
+#define REG_CR16        0x00010000
+#define REG_CR17        0x00020000
+#define REG_CR18        0x00040000
+#define REG_CR19        0x00080000
+#define REG_CR20        0x00100000
+#define REG_CR21        0x00200000
+#define REG_CR22        0x00400000
+#define REG_CR23        0x00800000
+#define REG_CR24        0x01000000
+#define REG_CR25        0x02000000
+#define REG_CR26        0x04000000
+#define REG_CR27        0x08000000
+#define REG_CR28        0x10000000
+#define REG_CR29        0x20000000
+#define REG_CR30        0x40000000
+#define REG_CR31        0x80000000
+
+struct shader_constant
+{
+    float x;
+    float y;
+    float z;
+    float w;
+};
+
+struct i915_3dstate_pixel_shader_constants
+{
+    struct {
+        unsigned length : 8;
+        unsigned pad0 : 8;
+        unsigned opcode : 13;
+        unsigned type : 3;
+    } dw0;
+
+    struct {
+        unsigned reg_mask;
+    } dw1;
+    // struct shader_constant *consts;
+};
+
+#define BLOCK_SIS       0x01
+#define BLOCK_DIS       0x02
+#define BLOCK_SSB       0x04
+#define BLOCK_MSB       0x08
+#define BLOCK_PSP       0x10
+#define BLOCK_PSC       0x20
+
+typedef struct _state_ddword
+{
+    struct {
+        unsigned valid : 1;
+        unsigned force : 1;
+        unsigned buffer_address : 30;
+    } dw0;
+
+    struct {
+        unsigned length : 9;
+        unsigned pad0 : 23;
+    } dw1;
+} sis_state, ssb_state, msb_state, psp_state, psc_state;
+
+typedef struct _state_dword
+{
+    struct {
+        unsigned valid : 1;
+        unsigned reset : 1;
+        unsigned buffer_address : 30;
+    } dw0;
+} dis_state;
+
+struct i915_3dstate_load_indirect
+{
+    struct {
+        unsigned length : 8;
+        unsigned block_mask : 6;
+        unsigned mem_select : 1;
+        unsigned pad0 : 1;
+        unsigned opcode : 13;
+        unsigned type : 3;
+    } dw0;
+};
+
+#define TEXCOORDFMT_2FP       0x00
+#define TEXCOORDFMT_3FP       0x01
+#define TEXCOORDFMT_4FP       0x02
+#define TEXCOORDFMT_1FP       0x03
+#define TEXCOORDFMT_2FP_16    0x04
+#define TEXCOORDFMT_4FP_16    0x05
+#define TEXCOORDFMT_NOT_PRESENT  0x0f
+struct s2_dword
+{
+    unsigned set0_texcoord_fmt : 4;
+    unsigned set1_texcoord_fmt : 4;
+    unsigned set2_texcoord_fmt : 4;
+    unsigned set3_texcoord_fmt : 4;
+    unsigned set4_texcoord_fmt : 4;
+    unsigned set5_texcoord_fmt : 4;
+    unsigned set6_texcoord_fmt : 4;
+    unsigned set7_texcoord_fmt : 4;
+};
+
+struct s3_dword
+{
+    unsigned set0_pcd : 1;
+    unsigned set0_ws_tcz : 1;
+    unsigned set0_ws_tcy : 1;
+    unsigned set0_ws_tcx : 1;
+    unsigned set1_pcd : 1;
+    unsigned set1_ws_tcz : 1;
+    unsigned set1_ws_tcy : 1;
+    unsigned set1_ws_tcx : 1;
+    unsigned set2_pcd : 1;
+    unsigned set2_ws_tcz : 1;
+    unsigned set2_ws_tcy : 1;
+    unsigned set2_ws_tcx : 1;
+    unsigned set3_pcd : 1;
+    unsigned set3_ws_tcz : 1;
+    unsigned set3_ws_tcy : 1;
+    unsigned set3_ws_tcx : 1;
+    unsigned set4_pcd : 1;
+    unsigned set4_ws_tcz : 1;
+    unsigned set4_ws_tcy : 1;
+    unsigned set4_ws_tcx : 1;
+    unsigned set5_pcd : 1;
+    unsigned set5_ws_tcz : 1;
+    unsigned set5_ws_tcy : 1;
+    unsigned set5_ws_tcx : 1;
+    unsigned set6_pcd : 1;
+    unsigned set6_ws_tcz : 1;
+    unsigned set6_ws_tcy : 1;
+    unsigned set6_ws_tcx : 1;
+    unsigned set7_pcd : 1;
+    unsigned set7_ws_tcz : 1;
+    unsigned set7_ws_tcy : 1;
+    unsigned set7_ws_tcx : 1;
+};
+
+#define VERTEXHAS_XYZ      1
+#define VERTEXHAS_XYZW     2
+#define VERTEXHAS_XY       3
+#define VERTEXHAS_XYW      4
+
+#define CULLMODE_BOTH      0
+#define CULLMODE_NONE      1
+#define CULLMODE_CW        2
+#define CULLMODE_CCW       3
+
+#define SHADEMODE_LINEAR   0
+#define SHADEMODE_FLAT     1
+struct s4_dword
+{
+    unsigned anti_aliasing_enable : 1;
+    unsigned sprite_point_enable : 1;
+    unsigned fog_parameter_present : 1;
+    unsigned local_depth_offset_enable : 1;
+    unsigned force_specular_diffuse_color : 1;
+    unsigned force_default_diffuse_color : 1;
+    unsigned position_mask : 3;
+    unsigned local_depth_offset_present : 1;
+    unsigned diffuse_color_presetn : 1;
+    unsigned specular_color_fog_factor_present : 1;
+    unsigned point_width_present : 1;
+    unsigned cull_mode : 2;
+    unsigned color_shade_mode : 1;
+    unsigned specular_shade_mode : 1;
+    unsigned fog_shade_mode : 1;
+    unsigned alpha_shade_mode : 1;
+    unsigned line_width : 4;
+    unsigned point_width : 9;
+};
+
+struct s5_dword 
+{
+    unsigned logic_op_enable : 1;
+    unsigned color_dither_enable  : 1;
+    unsigned stencil_test_enable : 1;
+    unsigned stencil_buffer_write_enable : 1;
+    unsigned stencil_pass_depth_pass_op : 3;
+    unsigned stencil_pass_depth_fail_op : 3;
+    unsigned stencil_fail_op : 3;
+    unsigned stencil_test_function : 3;
+    unsigned stencil_reference_value : 8;
+    unsigned fog_enable : 1;
+    unsigned global_depth_offset_enable : 1;
+    unsigned last_pixel_enable : 1;
+    unsigned force_default_point_width : 1;
+    unsigned color_buffer_component_write_disable : 4;
+};
+
+struct s6_dword
+{
+    unsigned triangle_pv : 2;
+    unsigned color_buffer_write : 1;
+    unsigned depth_buffer_write : 1;
+    unsigned dest_blend_factor : 4;
+    unsigned src_blend_factor : 4;
+    unsigned color_blend_function : 3;
+    unsigned color_buffer_blend : 1;
+    unsigned depth_test_function : 3;
+    unsigned depth_test_enable : 1;
+    unsigned alpha_reference_value : 8;
+    unsigned alpha_test_function : 3;
+    unsigned alpha_test_enable : 1;
+    
+};
+
+struct s7_dword
+{
+    unsigned global_depth_offset_const;
+};
+
+struct i915_3dstate_load_state_immediate_1
+{
+    struct {
+        unsigned length : 4;
+        unsigned load_s0 : 1;
+        unsigned load_s1 : 1;
+        unsigned load_s2 : 1;
+        unsigned load_s3 : 1;
+        unsigned load_s4 : 1;
+        unsigned load_s5 : 1;
+        unsigned load_s6 : 1;
+        unsigned load_s7 : 1;
+        unsigned pad0 : 4;
+        unsigned opcode : 13;
+        unsigned type : 3;
+    } dw0;
+};
+
+struct i915_3dstate_scissor_rectangle
+{
+    struct {
+        unsigned length : 16;
+        unsigned opcode : 13;
+        unsigned type : 3;
+    } dw0;
+
+    struct {
+        unsigned min_x : 16;
+        unsigned min_y : 16;
+    } dw1;
+
+    struct {
+        unsigned max_x : 16;
+        unsigned max_y : 16;
+    } dw2;
+};
+
+#define VERTEX_INLINE         0x00
+#define VERTEX_INDIRECT       0x01
+
+#define PRIM_TRILIST          0x00
+#define PRIM_TRISTRIP         0x01
+#define PRIM_TRISTRIP_REVERSE 0x02
+#define PRIM_TRIFAN           0x03
+#define PRIM_POLYGON          0x04
+#define PRIM_LINELIST         0x05
+#define PRIM_LINESTRIP        0x06
+#define PRIM_RECTLIST         0x07
+#define PRIM_POINTLIST        0x08
+#define PRIM_DIB              0x09
+#define PRIM_CLEAR_RECT       0x0a
+#define PRIM_ZONE_INIT        0x0d
+
+struct texture_coordinate_set
+{
+    unsigned tcx;
+    unsigned tcy;
+};
+
+struct vertex_data
+{
+    unsigned x;
+    unsigned y;
+    struct texture_coordinate_set tc0;
+    struct texture_coordinate_set tc1;
+};
+
+struct i915_3dprimitive
+{
+    union {
+        struct {
+            unsigned length : 18;
+            unsigned prim : 5;
+            unsigned vertex_location : 1;
+            unsigned opcode : 5;
+            unsigned type : 3;
+        } inline_prim;
+
+        struct {
+            unsigned vertex_count : 16;
+            unsigned pad0 : 1;
+            unsigned vertex_access_mode : 1;
+            unsigned prim : 5;
+            unsigned vertex_location : 1;
+            unsigned opcode : 5;
+            unsigned type : 3;
+        } indirect_prim;            
+    } dw0;
+};
+
+#endif /*_I915_STRUCTS_H */
diff --git a/src/xvmc/intel_batchbuffer.c b/src/xvmc/intel_batchbuffer.c
new file mode 100644
index 0000000..ef38a44
--- /dev/null
+++ b/src/xvmc/intel_batchbuffer.c
@@ -0,0 +1,197 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <string.h>
+
+#include <sys/ioctl.h>
+#include <X11/Xlibint.h>
+#include <fourcc.h>
+#include <X11/extensions/Xv.h>
+#include <X11/extensions/Xvlib.h>
+#include <X11/extensions/XvMC.h>
+#include <X11/extensions/XvMClib.h>
+
+#include "I915XvMC.h"
+#include "intel_batchbuffer.h"
+
+int intelEmitIrqLocked(i915XvMCContext *pI915XvMC)
+{
+    drmI830IrqEmit ie;
+    int ret, seq;
+
+    ie.irq_seq = &seq;
+    ret = drmCommandWriteRead(pI915XvMC->fd, DRM_I830_IRQ_EMIT,
+                               &ie, sizeof(ie));
+
+    if ( ret ) {
+        fprintf(stderr, "%s: drmI830IrqEmit: %d\n", __FUNCTION__, ret);
+        exit(1);
+    }
+
+    return seq;
+}
+
+void intelWaitIrq(i915XvMCContext *pI915XvMC, int seq)
+{
+    int ret;
+    drmI830IrqWait iw;
+
+    iw.irq_seq = seq;
+
+    do {
+        ret = drmCommandWrite(pI915XvMC->fd, DRM_I830_IRQ_WAIT, &iw, sizeof(iw) );
+    } while (ret == -EAGAIN || ret == -EINTR);
+
+    if (ret) {
+        fprintf(stderr, "%s: drmI830IrqWait: %d\n", __FUNCTION__, ret);
+        exit(1);
+    }
+}
+
+void intelDestroyBatchBuffer(i915XvMCContext *pI915XvMC)
+{
+    if (pI915XvMC->alloc.offset) {
+        // FIXME: free the memory allocated from AGP
+    } else if (pI915XvMC->alloc.ptr) {
+        free(pI915XvMC->alloc.ptr);
+        pI915XvMC->alloc.ptr = NULL;
+    }
+
+    memset(&pI915XvMC->batch, 0, sizeof(pI915XvMC->batch));
+}
+
+
+void intelInitBatchBuffer(i915XvMCContext  *pI915XvMC)
+{
+    pI915XvMC->alloc.offset = 0;
+    pI915XvMC->alloc.size = 16 * 1024;
+    pI915XvMC->alloc.ptr = malloc(pI915XvMC->alloc.size);
+    pI915XvMC->alloc.active_buf = 0;
+
+    assert(pI915XvMC->alloc.ptr);
+}
+
+void intelBatchbufferRequireSpace(i915XvMCContext *pI915XvMC, unsigned sz)
+{
+    if (pI915XvMC->batch.space < sz)
+        intelFlushBatch(pI915XvMC, TRUE);
+}
+
+void intelBatchbufferData(i915XvMCContext *pI915XvMC, const void *data, 
+                          unsigned bytes, unsigned flags)
+{
+    assert((bytes & 3) == 0);
+    intelBatchbufferRequireSpace(pI915XvMC, bytes);
+    memcpy(pI915XvMC->batch.ptr, data, bytes);
+    pI915XvMC->batch.ptr += bytes;
+    pI915XvMC->batch.space -= bytes;
+    assert(pI915XvMC->batch.space >= 0);
+}
+
+void intelRefillBatchLocked(i915XvMCContext *pI915XvMC, Bool allow_unlock )
+{
+    unsigned last_irq = pI915XvMC->alloc.irq_emitted;
+    unsigned half = pI915XvMC->alloc.size >> 1;
+    unsigned buf = (pI915XvMC->alloc.active_buf ^= 1);
+
+    pI915XvMC->alloc.irq_emitted = intelEmitIrqLocked(pI915XvMC);
+
+    if (last_irq) {
+        intelWaitIrq(pI915XvMC, last_irq);
+    }
+
+    pI915XvMC->batch.start_offset = pI915XvMC->alloc.offset + buf * half;
+    pI915XvMC->batch.ptr = (unsigned char *)pI915XvMC->alloc.ptr + buf * half;
+    pI915XvMC->batch.size = half - 8;
+    pI915XvMC->batch.space = half - 8;
+    assert(pI915XvMC->batch.space >= 0);
+}
+
+
+void intelFlushBatchLocked(i915XvMCContext *pI915XvMC,
+                           Bool ignore_cliprects,
+                           Bool refill,
+                           Bool allow_unlock)
+{
+    drmI830BatchBuffer batch;
+
+    if (pI915XvMC->batch.space != pI915XvMC->batch.size) {
+
+        batch.start = pI915XvMC->batch.start_offset;
+        batch.used = pI915XvMC->batch.size - pI915XvMC->batch.space;
+        batch.cliprects = 0;
+        batch.num_cliprects = 0;
+        batch.DR1 = 0;
+        batch.DR4 = 0;
+
+        if (pI915XvMC->alloc.offset) {
+            // FIXME: MI_BATCH_BUFFER_END
+        }
+
+        pI915XvMC->batch.start_offset += batch.used;
+        pI915XvMC->batch.size -= batch.used;
+
+        if (pI915XvMC->batch.size < 8) {
+            refill = TRUE;
+            pI915XvMC->batch.space = pI915XvMC->batch.size = 0;
+        }
+        else {
+            pI915XvMC->batch.size -= 8;
+            pI915XvMC->batch.space = pI915XvMC->batch.size;
+        }
+
+        assert(pI915XvMC->batch.space >= 0);
+        assert(batch.start >= pI915XvMC->alloc.offset);
+        assert(batch.start < pI915XvMC->alloc.offset + pI915XvMC->alloc.size);
+        assert(batch.start + batch.used > pI915XvMC->alloc.offset);
+        assert(batch.start + batch.used <= pI915XvMC->alloc.offset + pI915XvMC->alloc.size);
+
+        if (pI915XvMC->alloc.offset) {
+            // DRM_I830_BATCHBUFFER
+        } else {
+            drmI830CmdBuffer cmd;
+            cmd.buf = (char *)pI915XvMC->alloc.ptr + batch.start;
+            cmd.sz = batch.used;
+            cmd.DR1 = batch.DR1;
+            cmd.DR4 = batch.DR4;
+            cmd.num_cliprects = batch.num_cliprects;
+            cmd.cliprects = batch.cliprects;
+
+            if (drmCommandWrite(pI915XvMC->fd, DRM_I830_CMDBUFFER, 
+                                 &cmd, sizeof(cmd))) {
+                fprintf(stderr, "DRM_I915_CMDBUFFER: %d\n",  -errno);
+                exit(1);
+            }
+        }
+    }
+
+    if (refill)
+        intelRefillBatchLocked(pI915XvMC, allow_unlock);
+}
+
+void intelFlushBatch(i915XvMCContext *pI915XvMC, Bool refill )
+{
+    intelFlushBatchLocked(pI915XvMC, FALSE, refill, TRUE);
+}
+
+void intelCmdIoctl(i915XvMCContext *pI915XvMC, char *buf, unsigned used)
+{
+    drmI830CmdBuffer cmd;
+
+    cmd.buf = buf;
+    cmd.sz = used;
+    cmd.cliprects = 0;
+    cmd.num_cliprects = 0;
+    cmd.DR1 = 0;
+    cmd.DR4 = 0;
+
+    if (drmCommandWrite(pI915XvMC->fd, DRM_I830_CMDBUFFER, 
+                        &cmd, sizeof(cmd))) {
+        fprintf(stderr, "DRM_I830_CMDBUFFER: %d\n",  -errno);
+        exit(1);
+    }
+}
diff --git a/src/xvmc/intel_batchbuffer.h b/src/xvmc/intel_batchbuffer.h
new file mode 100644
index 0000000..5b3e8e1
--- /dev/null
+++ b/src/xvmc/intel_batchbuffer.h
@@ -0,0 +1,42 @@
+#ifndef _INTEL_BATCHBUFFER_H
+#define _INTEL_BATCHBUFFER_H
+
+/* #define VERBOSE 0 */
+#ifndef VERBOSE
+extern int VERBOSE;
+#endif
+
+#define BATCH_LOCALS    char *batch_ptr;
+
+#define BEGIN_BATCH(n)                                                  \
+    do {                                                                \
+        if (VERBOSE) fprintf(stderr,                                    \
+                             "BEGIN_BATCH(%ld) in %s, %d dwords free\n", \
+                             ((unsigned long)n), __FUNCTION__,          \
+                             pI915XvMC->batch.space/4);                     \
+        if (pI915XvMC->batch.space < (n)*4)                                 \
+            intelFlushBatch(pI915XvMC, TRUE);                            \
+        batch_ptr = pI915XvMC->batch.ptr;                                   \
+    } while (0)
+
+#define OUT_BATCH(n)                                                    \
+    do {                                                                \
+        *(GLuint *)batch_ptr = (n);                                     \
+        if (VERBOSE) fprintf(stderr, " -- %08x at %s/%d\n", (n), __FILE__, __LINE__); \
+        batch_ptr += 4;                                                 \
+    } while (0)
+
+#define ADVANCE_BATCH()                                        \
+    do {                                                       \
+        if (VERBOSE) fprintf(stderr, "ADVANCE_BATCH()\n");     \
+        pI915XvMC->batch.space -= (batch_ptr - pI915XvMC->batch.ptr);  \
+        pI915XvMC->batch.ptr = batch_ptr;                          \
+        assert(pI915XvMC->batch.space >= 0);                       \
+    } while(0)
+
+extern void intelFlushBatch(i915XvMCContext *, Bool);
+extern void intelBatchbufferData(i915XvMCContext *, const void *, unsigned, unsigned);
+extern void intelInitBatchBuffer(i915XvMCContext *);
+extern void intelDestroyBatchBuffer(i915XvMCContext *);
+extern void intelCmdIoctl(i915XvMCContext *, char *, unsigned);
+#endif /* _INTEL_BATCHBUFFER_H */
diff --git a/src/xvmc/xf86dri.c b/src/xvmc/xf86dri.c
new file mode 100644
index 0000000..1feb232
--- /dev/null
+++ b/src/xvmc/xf86dri.c
@@ -0,0 +1,599 @@
+/* $XFree86: xc/lib/GL/dri/XF86dri.c,v 1.13 2002/10/30 12:51:25 alanh Exp $ */
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+Copyright 2000 VA Linux Systems, Inc.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ *   Kevin E. Martin <martin at valinux.com>
+ *   Jens Owen <jens at tungstengraphics.com>
+ *   Rickard E. (Rik) Faith <faith at valinux.com>
+ *
+ */
+
+/* THIS IS NOT AN X CONSORTIUM STANDARD */
+
+#define NEED_REPLIES
+#include <X11/Xlibint.h>
+#include <X11/extensions/Xext.h>
+#include <X11/extensions/extutil.h>
+#include "xf86dristr.h"
+
+static XExtensionInfo _xf86dri_info_data;
+static XExtensionInfo *xf86dri_info = &_xf86dri_info_data;
+static char xf86dri_extension_name[] = XF86DRINAME;
+
+#define uniDRICheckExtension(dpy,i,val) \
+  XextCheckExtension (dpy, i, xf86dri_extension_name, val)
+
+/*****************************************************************************
+ *                                                                           *
+ *			   private utility routines                          *
+ *                                                                           *
+ *****************************************************************************/
+
+static int close_display(Display * dpy, XExtCodes * extCodes);
+static /* const */ XExtensionHooks xf86dri_extension_hooks = {
+    NULL,			       /* create_gc */
+    NULL,			       /* copy_gc */
+    NULL,			       /* flush_gc */
+    NULL,			       /* free_gc */
+    NULL,			       /* create_font */
+    NULL,			       /* free_font */
+    close_display,		       /* close_display */
+    NULL,			       /* wire_to_event */
+    NULL,			       /* event_to_wire */
+    NULL,			       /* error */
+    NULL,			       /* error_string */
+};
+
+static
+XEXT_GENERATE_FIND_DISPLAY(find_display, xf86dri_info,
+    xf86dri_extension_name, &xf86dri_extension_hooks, 0, NULL)
+
+    static XEXT_GENERATE_CLOSE_DISPLAY(close_display, xf86dri_info)
+
+/*****************************************************************************
+ *                                                                           *
+ *		    public XFree86-DRI Extension routines                    *
+ *                                                                           *
+ *****************************************************************************/
+#if 0
+#include <stdio.h>
+#define TRACE(msg)  fprintf(stderr,"uniDRI%s\n", msg);
+#else
+#define TRACE(msg)
+#endif
+    Bool uniDRIQueryExtension(dpy, event_basep, error_basep)
+    Display *dpy;
+    int *event_basep, *error_basep;
+{
+    XExtDisplayInfo *info = find_display(dpy);
+
+    TRACE("QueryExtension...");
+    if (XextHasExtension(info)) {
+	*event_basep = info->codes->first_event;
+	*error_basep = info->codes->first_error;
+	TRACE("QueryExtension... return True");
+	return True;
+    } else {
+	TRACE("QueryExtension... return False");
+	return False;
+    }
+}
+
+Bool
+uniDRIQueryVersion(dpy, majorVersion, minorVersion, patchVersion)
+    Display *dpy;
+    int *majorVersion;
+    int *minorVersion;
+    int *patchVersion;
+{
+    XExtDisplayInfo *info = find_display(dpy);
+    xXF86DRIQueryVersionReply rep;
+    xXF86DRIQueryVersionReq *req;
+
+    TRACE("QueryVersion...");
+    uniDRICheckExtension(dpy, info, False);
+
+    LockDisplay(dpy);
+    GetReq(XF86DRIQueryVersion, req);
+    req->reqType = info->codes->major_opcode;
+    req->driReqType = X_XF86DRIQueryVersion;
+    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
+	UnlockDisplay(dpy);
+	SyncHandle();
+	TRACE("QueryVersion... return False");
+	return False;
+    }
+    *majorVersion = rep.majorVersion;
+    *minorVersion = rep.minorVersion;
+    *patchVersion = rep.patchVersion;
+    UnlockDisplay(dpy);
+    SyncHandle();
+    TRACE("QueryVersion... return True");
+    return True;
+}
+
+Bool
+uniDRIQueryDirectRenderingCapable(dpy, screen, isCapable)
+    Display *dpy;
+    int screen;
+    Bool *isCapable;
+{
+    XExtDisplayInfo *info = find_display(dpy);
+    xXF86DRIQueryDirectRenderingCapableReply rep;
+    xXF86DRIQueryDirectRenderingCapableReq *req;
+
+    TRACE("QueryDirectRenderingCapable...");
+    uniDRICheckExtension(dpy, info, False);
+
+    LockDisplay(dpy);
+    GetReq(XF86DRIQueryDirectRenderingCapable, req);
+    req->reqType = info->codes->major_opcode;
+    req->driReqType = X_XF86DRIQueryDirectRenderingCapable;
+    req->screen = screen;
+    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
+	UnlockDisplay(dpy);
+	SyncHandle();
+	TRACE("QueryDirectRenderingCapable... return False");
+	return False;
+    }
+    *isCapable = rep.isCapable;
+    UnlockDisplay(dpy);
+    SyncHandle();
+    TRACE("QueryDirectRenderingCapable... return True");
+    return True;
+}
+
+Bool
+uniDRIOpenConnection(dpy, screen, hSAREA, busIdString)
+    Display *dpy;
+    int screen;
+    drm_handle_t *hSAREA;
+    char **busIdString;
+{
+    XExtDisplayInfo *info = find_display(dpy);
+    xXF86DRIOpenConnectionReply rep;
+    xXF86DRIOpenConnectionReq *req;
+
+    TRACE("OpenConnection...");
+    uniDRICheckExtension(dpy, info, False);
+
+    LockDisplay(dpy);
+    GetReq(XF86DRIOpenConnection, req);
+    req->reqType = info->codes->major_opcode;
+    req->driReqType = X_XF86DRIOpenConnection;
+    req->screen = screen;
+    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
+	UnlockDisplay(dpy);
+	SyncHandle();
+	TRACE("OpenConnection... return False");
+	return False;
+    }
+
+    *hSAREA = rep.hSAREALow;
+#ifdef LONG64
+    if (sizeof(drm_handle_t) == 8) {
+	*hSAREA |= ((unsigned long)rep.hSAREAHigh) << 32;
+    }
+#endif
+    if (rep.length) {
+	if (!(*busIdString = (char *)Xcalloc(rep.busIdStringLength + 1, 1))) {
+	    _XEatData(dpy, ((rep.busIdStringLength + 3) & ~3));
+	    UnlockDisplay(dpy);
+	    SyncHandle();
+	    TRACE("OpenConnection... return False");
+	    return False;
+	}
+	_XReadPad(dpy, *busIdString, rep.busIdStringLength);
+    } else {
+	*busIdString = NULL;
+    }
+    UnlockDisplay(dpy);
+    SyncHandle();
+    TRACE("OpenConnection... return True");
+    return True;
+}
+
+Bool
+uniDRIAuthConnection(dpy, screen, magic)
+    Display *dpy;
+    int screen;
+    drm_magic_t magic;
+{
+    XExtDisplayInfo *info = find_display(dpy);
+    xXF86DRIAuthConnectionReq *req;
+    xXF86DRIAuthConnectionReply rep;
+
+    TRACE("AuthConnection...");
+    uniDRICheckExtension(dpy, info, False);
+
+    LockDisplay(dpy);
+    GetReq(XF86DRIAuthConnection, req);
+    req->reqType = info->codes->major_opcode;
+    req->driReqType = X_XF86DRIAuthConnection;
+    req->screen = screen;
+    req->magic = magic;
+    rep.authenticated = 0;
+    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse) || !rep.authenticated) {
+	UnlockDisplay(dpy);
+	SyncHandle();
+	TRACE("AuthConnection... return False");
+	return False;
+    }
+    UnlockDisplay(dpy);
+    SyncHandle();
+    TRACE("AuthConnection... return True");
+    return True;
+}
+
+Bool
+uniDRICloseConnection(dpy, screen)
+    Display *dpy;
+    int screen;
+{
+    XExtDisplayInfo *info = find_display(dpy);
+    xXF86DRICloseConnectionReq *req;
+
+    TRACE("CloseConnection...");
+
+    uniDRICheckExtension(dpy, info, False);
+
+    LockDisplay(dpy);
+    GetReq(XF86DRICloseConnection, req);
+    req->reqType = info->codes->major_opcode;
+    req->driReqType = X_XF86DRICloseConnection;
+    req->screen = screen;
+    UnlockDisplay(dpy);
+    SyncHandle();
+    TRACE("CloseConnection... return True");
+    return True;
+}
+
+Bool
+uniDRIGetClientDriverName(dpy, screen, ddxDriverMajorVersion,
+    ddxDriverMinorVersion, ddxDriverPatchVersion, clientDriverName)
+    Display *dpy;
+    int screen;
+    int *ddxDriverMajorVersion;
+    int *ddxDriverMinorVersion;
+    int *ddxDriverPatchVersion;
+    char **clientDriverName;
+{
+    XExtDisplayInfo *info = find_display(dpy);
+    xXF86DRIGetClientDriverNameReply rep;
+    xXF86DRIGetClientDriverNameReq *req;
+
+    TRACE("GetClientDriverName...");
+    uniDRICheckExtension(dpy, info, False);
+
+    LockDisplay(dpy);
+    GetReq(XF86DRIGetClientDriverName, req);
+    req->reqType = info->codes->major_opcode;
+    req->driReqType = X_XF86DRIGetClientDriverName;
+    req->screen = screen;
+    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
+	UnlockDisplay(dpy);
+	SyncHandle();
+	TRACE("GetClientDriverName... return False");
+	return False;
+    }
+
+    *ddxDriverMajorVersion = rep.ddxDriverMajorVersion;
+    *ddxDriverMinorVersion = rep.ddxDriverMinorVersion;
+    *ddxDriverPatchVersion = rep.ddxDriverPatchVersion;
+
+    if (rep.length) {
+	if (!(*clientDriverName =
+		(char *)Xcalloc(rep.clientDriverNameLength + 1, 1))) {
+	    _XEatData(dpy, ((rep.clientDriverNameLength + 3) & ~3));
+	    UnlockDisplay(dpy);
+	    SyncHandle();
+	    TRACE("GetClientDriverName... return False");
+	    return False;
+	}
+	_XReadPad(dpy, *clientDriverName, rep.clientDriverNameLength);
+    } else {
+	*clientDriverName = NULL;
+    }
+    UnlockDisplay(dpy);
+    SyncHandle();
+    TRACE("GetClientDriverName... return True");
+    return True;
+}
+
+Bool
+uniDRICreateContextWithConfig(dpy, screen, configID, context, hHWContext)
+    Display *dpy;
+    int screen;
+    int configID;
+    XID *context;
+    drm_context_t *hHWContext;
+{
+    XExtDisplayInfo *info = find_display(dpy);
+    xXF86DRICreateContextReply rep;
+    xXF86DRICreateContextReq *req;
+
+    TRACE("CreateContext...");
+    uniDRICheckExtension(dpy, info, False);
+
+    LockDisplay(dpy);
+    GetReq(XF86DRICreateContext, req);
+    req->reqType = info->codes->major_opcode;
+    req->driReqType = X_XF86DRICreateContext;
+    req->visual = configID;
+    req->screen = screen;
+    *context = XAllocID(dpy);
+    req->context = *context;
+    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
+	UnlockDisplay(dpy);
+	SyncHandle();
+	TRACE("CreateContext... return False");
+	return False;
+    }
+    *hHWContext = rep.hHWContext;
+    UnlockDisplay(dpy);
+    SyncHandle();
+    TRACE("CreateContext... return True");
+    return True;
+}
+
+Bool
+uniDRICreateContext(dpy, screen, visual, context, hHWContext)
+    Display *dpy;
+    int screen;
+    Visual *visual;
+    XID *context;
+    drm_context_t *hHWContext;
+{
+    return uniDRICreateContextWithConfig(dpy, screen, visual->visualid,
+	context, hHWContext);
+}
+
+Bool
+uniDRIDestroyContext(Display * ndpy, int screen, XID context)
+{
+    Display *const dpy = (Display *) ndpy;
+    XExtDisplayInfo *info = find_display(dpy);
+    xXF86DRIDestroyContextReq *req;
+
+    TRACE("DestroyContext...");
+    uniDRICheckExtension(dpy, info, False);
+
+    LockDisplay(dpy);
+    GetReq(XF86DRIDestroyContext, req);
+    req->reqType = info->codes->major_opcode;
+    req->driReqType = X_XF86DRIDestroyContext;
+    req->screen = screen;
+    req->context = context;
+    UnlockDisplay(dpy);
+    SyncHandle();
+    TRACE("DestroyContext... return True");
+    return True;
+}
+
+Bool
+uniDRICreateDrawable(Display * ndpy, int screen,
+    Drawable drawable, drm_drawable_t * hHWDrawable)
+{
+    Display *const dpy = (Display *) ndpy;
+    XExtDisplayInfo *info = find_display(dpy);
+    xXF86DRICreateDrawableReply rep;
+    xXF86DRICreateDrawableReq *req;
+
+    TRACE("CreateDrawable...");
+    uniDRICheckExtension(dpy, info, False);
+
+    LockDisplay(dpy);
+    GetReq(XF86DRICreateDrawable, req);
+    req->reqType = info->codes->major_opcode;
+    req->driReqType = X_XF86DRICreateDrawable;
+    req->screen = screen;
+    req->drawable = drawable;
+    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
+	UnlockDisplay(dpy);
+	SyncHandle();
+	TRACE("CreateDrawable... return False");
+	return False;
+    }
+    *hHWDrawable = rep.hHWDrawable;
+    UnlockDisplay(dpy);
+    SyncHandle();
+    TRACE("CreateDrawable... return True");
+    return True;
+}
+
+Bool
+uniDRIDestroyDrawable(Display * ndpy, int screen, Drawable drawable)
+{
+    Display *const dpy = (Display *) ndpy;
+    XExtDisplayInfo *info = find_display(dpy);
+    xXF86DRIDestroyDrawableReq *req;
+
+    TRACE("DestroyDrawable...");
+    uniDRICheckExtension(dpy, info, False);
+
+    LockDisplay(dpy);
+    GetReq(XF86DRIDestroyDrawable, req);
+    req->reqType = info->codes->major_opcode;
+    req->driReqType = X_XF86DRIDestroyDrawable;
+    req->screen = screen;
+    req->drawable = drawable;
+    UnlockDisplay(dpy);
+    SyncHandle();
+    TRACE("DestroyDrawable... return True");
+    return True;
+}
+
+Bool
+uniDRIGetDrawableInfo(Display * dpy, int screen, Drawable drawable,
+    unsigned int *index, unsigned int *stamp,
+    int *X, int *Y, int *W, int *H,
+    int *numClipRects, drm_clip_rect_t ** pClipRects,
+    int *backX, int *backY,
+    int *numBackClipRects, drm_clip_rect_t ** pBackClipRects)
+{
+    XExtDisplayInfo *info = find_display(dpy);
+    xXF86DRIGetDrawableInfoReply rep;
+    xXF86DRIGetDrawableInfoReq *req;
+    int total_rects;
+
+    TRACE("GetDrawableInfo...");
+    uniDRICheckExtension(dpy, info, False);
+
+    LockDisplay(dpy);
+    GetReq(XF86DRIGetDrawableInfo, req);
+    req->reqType = info->codes->major_opcode;
+    req->driReqType = X_XF86DRIGetDrawableInfo;
+    req->screen = screen;
+    req->drawable = drawable;
+
+    if (!_XReply(dpy, (xReply *) & rep, 1, xFalse)) {
+	UnlockDisplay(dpy);
+	SyncHandle();
+	TRACE("GetDrawableInfo... return False");
+	return False;
+    }
+    *index = rep.drawableTableIndex;
+    *stamp = rep.drawableTableStamp;
+    *X = (int)rep.drawableX;
+    *Y = (int)rep.drawableY;
+    *W = (int)rep.drawableWidth;
+    *H = (int)rep.drawableHeight;
+    *numClipRects = rep.numClipRects;
+    total_rects = *numClipRects;
+
+    *backX = rep.backX;
+    *backY = rep.backY;
+    *numBackClipRects = rep.numBackClipRects;
+    total_rects += *numBackClipRects;
+
+#if 0
+    /* Because of the fix in Xserver/GL/dri/xf86dri.c, this check breaks
+     * backwards compatibility (Because of the >> 2 shift) but the fix
+     * enables multi-threaded apps to work.
+     */
+    if (rep.length != ((((SIZEOF(xXF86DRIGetDrawableInfoReply) -
+			SIZEOF(xGenericReply) +
+			total_rects * sizeof(drm_clip_rect_t)) +
+		    3) & ~3) >> 2)) {
+	_XEatData(dpy, rep.length);
+	UnlockDisplay(dpy);
+	SyncHandle();
+	TRACE("GetDrawableInfo... return False");
+	return False;
+    }
+#endif
+
+    if (*numClipRects) {
+	int len = sizeof(drm_clip_rect_t) * (*numClipRects);
+
+	*pClipRects = (drm_clip_rect_t *) Xcalloc(len, 1);
+	if (*pClipRects)
+	    _XRead(dpy, (char *)*pClipRects, len);
+    } else {
+	*pClipRects = NULL;
+    }
+
+    if (*numBackClipRects) {
+	int len = sizeof(drm_clip_rect_t) * (*numBackClipRects);
+
+	*pBackClipRects = (drm_clip_rect_t *) Xcalloc(len, 1);
+	if (*pBackClipRects)
+	    _XRead(dpy, (char *)*pBackClipRects, len);
+    } else {
+	*pBackClipRects = NULL;
+    }
+
+    UnlockDisplay(dpy);
+    SyncHandle();
+    TRACE("GetDrawableInfo... return True");
+    return True;
+}
+
+Bool
+uniDRIGetDeviceInfo(dpy, screen, hFrameBuffer,
+    fbOrigin, fbSize, fbStride, devPrivateSize, pDevPrivate)
+    Display *dpy;
+    int screen;
+    drm_handle_t *hFrameBuffer;
+    int *fbOrigin;
+    int *fbSize;
+    int *fbStride;
+    int *devPrivateSize;
+    void **pDevPrivate;
+{
+    XExtDisplayInfo *info = find_display(dpy);
+    xXF86DRIGetDeviceInfoReply rep;
+    xXF86DRIGetDeviceInfoReq *req;
+
+    TRACE("GetDeviceInfo...");
+    uniDRICheckExtension(dpy, info, False);
+
+    LockDisplay(dpy);
+    GetReq(XF86DRIGetDeviceInfo, req);
+    req->reqType = info->codes->major_opcode;
+    req->driReqType = X_XF86DRIGetDeviceInfo;
+    req->screen = screen;
+    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
+	UnlockDisplay(dpy);
+	SyncHandle();
+	TRACE("GetDeviceInfo... return False");
+	return False;
+    }
+
+    *hFrameBuffer = rep.hFrameBufferLow;
+#ifdef LONG64
+    if (sizeof(drm_handle_t) == 8) {
+	*hFrameBuffer |= ((unsigned long)rep.hFrameBufferHigh) << 32;
+    }
+#endif
+
+    *fbOrigin = rep.framebufferOrigin;
+    *fbSize = rep.framebufferSize;
+    *fbStride = rep.framebufferStride;
+    *devPrivateSize = rep.devPrivateSize;
+
+    if (rep.length) {
+	if (!(*pDevPrivate = (void *)Xcalloc(rep.devPrivateSize, 1))) {
+	    _XEatData(dpy, ((rep.devPrivateSize + 3) & ~3));
+	    UnlockDisplay(dpy);
+	    SyncHandle();
+	    TRACE("GetDeviceInfo... return False");
+	    return False;
+	}
+	_XRead(dpy, (char *)*pDevPrivate, rep.devPrivateSize);
+    } else {
+	*pDevPrivate = NULL;
+    }
+
+    UnlockDisplay(dpy);
+    SyncHandle();
+    TRACE("GetDeviceInfo... return True");
+    return True;
+}
diff --git a/src/xvmc/xf86dri.h b/src/xvmc/xf86dri.h
new file mode 100644
index 0000000..d7580a1
--- /dev/null
+++ b/src/xvmc/xf86dri.h
@@ -0,0 +1,109 @@
+/* $XFree86: xc/lib/GL/dri/xf86dri.h,v 1.8 2002/10/30 12:51:25 alanh Exp $ */
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+Copyright 2000 VA Linux Systems, Inc.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/**
+ * \file xf86dri.h
+ * Protocol numbers and function prototypes for DRI X protocol.
+ *
+ * \author Kevin E. Martin <martin at valinux.com>
+ * \author Jens Owen <jens at tungstengraphics.com>
+ * \author Rickard E. (Rik) Faith <faith at valinux.com>
+ */
+
+#ifndef _XF86DRI_H_
+#define _XF86DRI_H_
+
+#include <X11/Xfuncproto.h>
+#include <xf86drm.h>
+
+#define X_XF86DRIQueryVersion			0
+#define X_XF86DRIQueryDirectRenderingCapable	1
+#define X_XF86DRIOpenConnection			2
+#define X_XF86DRICloseConnection		3
+#define X_XF86DRIGetClientDriverName		4
+#define X_XF86DRICreateContext			5
+#define X_XF86DRIDestroyContext			6
+#define X_XF86DRICreateDrawable			7
+#define X_XF86DRIDestroyDrawable		8
+#define X_XF86DRIGetDrawableInfo		9
+#define X_XF86DRIGetDeviceInfo			10
+#define X_XF86DRIAuthConnection                 11
+#define X_XF86DRIOpenFullScreen                 12	/* Deprecated */
+#define X_XF86DRICloseFullScreen                13	/* Deprecated */
+
+#define XF86DRINumberEvents		0
+
+#define XF86DRIClientNotLocal		0
+#define XF86DRIOperationNotSupported	1
+#define XF86DRINumberErrors		(XF86DRIOperationNotSupported + 1)
+
+#ifndef _XF86DRI_SERVER_
+
+_XFUNCPROTOBEGIN
+    Bool uniDRIQueryExtension(Display * dpy, int *event_base,
+    int *error_base);
+
+Bool uniDRIQueryVersion(Display * dpy, int *majorVersion, int *minorVersion,
+    int *patchVersion);
+
+Bool uniDRIQueryDirectRenderingCapable(Display * dpy, int screen,
+    Bool * isCapable);
+
+Bool uniDRIOpenConnection(Display * dpy, int screen, drm_handle_t * hSAREA,
+    char **busIDString);
+
+Bool uniDRIAuthConnection(Display * dpy, int screen, drm_magic_t magic);
+
+Bool uniDRICloseConnection(Display * dpy, int screen);
+
+Bool uniDRIGetClientDriverName(Display * dpy, int screen,
+    int *ddxDriverMajorVersion, int *ddxDriverMinorVersion,
+    int *ddxDriverPatchVersion, char **clientDriverName);
+
+Bool uniDRICreateContext(Display * dpy, int screen, Visual * visual,
+    XID * ptr_to_returned_context_id, drm_context_t * hHWContext);
+
+Bool uniDRICreateContextWithConfig(Display * dpy, int screen, int configID,
+    XID * ptr_to_returned_context_id, drm_context_t * hHWContext);
+
+extern Bool uniDRIDestroyContext(Display * dpy, int screen, XID context_id);
+
+extern Bool uniDRICreateDrawable(Display * dpy, int screen,
+    Drawable drawable, drm_drawable_t * hHWDrawable);
+
+extern Bool uniDRIDestroyDrawable(Display * dpy, int screen,
+    Drawable drawable);
+
+Bool uniDRIGetDeviceInfo(Display * dpy, int screen,
+    drm_handle_t * hFrameBuffer, int *fbOrigin, int *fbSize,
+    int *fbStride, int *devPrivateSize, void **pDevPrivate);
+
+_XFUNCPROTOEND
+#endif /* _XF86DRI_SERVER_ */
+#endif /* _XF86DRI_H_ */
diff --git a/src/xvmc/xf86dristr.h b/src/xvmc/xf86dristr.h
new file mode 100644
index 0000000..3b43438
--- /dev/null
+++ b/src/xvmc/xf86dristr.h
@@ -0,0 +1,390 @@
+/* $XFree86: xc/lib/GL/dri/xf86dristr.h,v 1.10 2002/10/30 12:51:25 alanh Exp $ */
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+Copyright 2000 VA Linux Systems, Inc.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ *   Kevin E. Martin <martin at valinux.com>
+ *   Jens Owen <jens at tungstengraphics.com>
+ *   Rickard E. (Rik) Fiath <faith at valinux.com>
+ *
+ */
+
+#ifndef _XF86DRISTR_H_
+#define _XF86DRISTR_H_
+
+#include "xf86dri.h"
+
+#define XF86DRINAME "XFree86-DRI"
+
+/* The DRI version number.  This was originally set to be the same of the
+ * XFree86 version number.  However, this version is really indepedent of
+ * the XFree86 version.
+ *
+ * Version History:
+ *    4.0.0: Original
+ *    4.0.1: Patch to bump clipstamp when windows are destroyed, 28 May 02
+ *    4.1.0: Add transition from single to multi in DRMInfo rec, 24 Jun 02
+ */
+#define XF86DRI_MAJOR_VERSION	4
+#define XF86DRI_MINOR_VERSION	1
+#define XF86DRI_PATCH_VERSION	0
+
+typedef struct _XF86DRIQueryVersion
+{
+    CARD8 reqType;		       /* always DRIReqCode */
+    CARD8 driReqType;		       /* always X_DRIQueryVersion */
+    CARD16 length B16;
+} xXF86DRIQueryVersionReq;
+
+#define sz_xXF86DRIQueryVersionReq	4
+
+typedef struct
+{
+    BYTE type;			       /* X_Reply */
+    BOOL pad1;
+    CARD16 sequenceNumber B16;
+    CARD32 length B32;
+    CARD16 majorVersion B16;	       /* major version of DRI protocol */
+    CARD16 minorVersion B16;	       /* minor version of DRI protocol */
+    CARD32 patchVersion B32;	       /* patch version of DRI protocol */
+    CARD32 pad3 B32;
+    CARD32 pad4 B32;
+    CARD32 pad5 B32;
+    CARD32 pad6 B32;
+} xXF86DRIQueryVersionReply;
+
+#define sz_xXF86DRIQueryVersionReply	32
+
+typedef struct _XF86DRIQueryDirectRenderingCapable
+{
+    CARD8 reqType;		       /* always DRIReqCode */
+    CARD8 driReqType;		       /* X_DRIQueryDirectRenderingCapable */
+    CARD16 length B16;
+    CARD32 screen B32;
+} xXF86DRIQueryDirectRenderingCapableReq;
+
+#define sz_xXF86DRIQueryDirectRenderingCapableReq	8
+
+typedef struct
+{
+    BYTE type;			       /* X_Reply */
+    BOOL pad1;
+    CARD16 sequenceNumber B16;
+    CARD32 length B32;
+    BOOL isCapable;
+    BOOL pad2;
+    BOOL pad3;
+    BOOL pad4;
+    CARD32 pad5 B32;
+    CARD32 pad6 B32;
+    CARD32 pad7 B32;
+    CARD32 pad8 B32;
+    CARD32 pad9 B32;
+} xXF86DRIQueryDirectRenderingCapableReply;
+
+#define sz_xXF86DRIQueryDirectRenderingCapableReply	32
+
+typedef struct _XF86DRIOpenConnection
+{
+    CARD8 reqType;		       /* always DRIReqCode */
+    CARD8 driReqType;		       /* always X_DRIOpenConnection */
+    CARD16 length B16;
+    CARD32 screen B32;
+} xXF86DRIOpenConnectionReq;
+
+#define sz_xXF86DRIOpenConnectionReq	8
+
+typedef struct
+{
+    BYTE type;			       /* X_Reply */
+    BOOL pad1;
+    CARD16 sequenceNumber B16;
+    CARD32 length B32;
+    CARD32 hSAREALow B32;
+    CARD32 hSAREAHigh B32;
+    CARD32 busIdStringLength B32;
+    CARD32 pad6 B32;
+    CARD32 pad7 B32;
+    CARD32 pad8 B32;
+} xXF86DRIOpenConnectionReply;
+
+#define sz_xXF86DRIOpenConnectionReply	32
+
+typedef struct _XF86DRIAuthConnection
+{
+    CARD8 reqType;		       /* always DRIReqCode */
+    CARD8 driReqType;		       /* always X_DRICloseConnection */
+    CARD16 length B16;
+    CARD32 screen B32;
+    CARD32 magic B32;
+} xXF86DRIAuthConnectionReq;
+
+#define sz_xXF86DRIAuthConnectionReq	12
+
+typedef struct
+{
+    BYTE type;
+    BOOL pad1;
+    CARD16 sequenceNumber B16;
+    CARD32 length B32;
+    CARD32 authenticated B32;
+    CARD32 pad2 B32;
+    CARD32 pad3 B32;
+    CARD32 pad4 B32;
+    CARD32 pad5 B32;
+    CARD32 pad6 B32;
+} xXF86DRIAuthConnectionReply;
+
+#define zx_xXF86DRIAuthConnectionReply  32
+
+typedef struct _XF86DRICloseConnection
+{
+    CARD8 reqType;		       /* always DRIReqCode */
+    CARD8 driReqType;		       /* always X_DRICloseConnection */
+    CARD16 length B16;
+    CARD32 screen B32;
+} xXF86DRICloseConnectionReq;
+
+#define sz_xXF86DRICloseConnectionReq	8
+
+typedef struct _XF86DRIGetClientDriverName
+{
+    CARD8 reqType;		       /* always DRIReqCode */
+    CARD8 driReqType;		       /* always X_DRIGetClientDriverName */
+    CARD16 length B16;
+    CARD32 screen B32;
+} xXF86DRIGetClientDriverNameReq;
+
+#define sz_xXF86DRIGetClientDriverNameReq	8
+
+typedef struct
+{
+    BYTE type;			       /* X_Reply */
+    BOOL pad1;
+    CARD16 sequenceNumber B16;
+    CARD32 length B32;
+    CARD32 ddxDriverMajorVersion B32;
+    CARD32 ddxDriverMinorVersion B32;
+    CARD32 ddxDriverPatchVersion B32;
+    CARD32 clientDriverNameLength B32;
+    CARD32 pad5 B32;
+    CARD32 pad6 B32;
+} xXF86DRIGetClientDriverNameReply;
+
+#define sz_xXF86DRIGetClientDriverNameReply	32
+
+typedef struct _XF86DRICreateContext
+{
+    CARD8 reqType;		       /* always DRIReqCode */
+    CARD8 driReqType;		       /* always X_DRICreateContext */
+    CARD16 length B16;
+    CARD32 screen B32;
+    CARD32 visual B32;
+    CARD32 context B32;
+} xXF86DRICreateContextReq;
+
+#define sz_xXF86DRICreateContextReq	16
+
+typedef struct
+{
+    BYTE type;			       /* X_Reply */
+    BOOL pad1;
+    CARD16 sequenceNumber B16;
+    CARD32 length B32;
+    CARD32 hHWContext B32;
+    CARD32 pad2 B32;
+    CARD32 pad3 B32;
+    CARD32 pad4 B32;
+    CARD32 pad5 B32;
+    CARD32 pad6 B32;
+} xXF86DRICreateContextReply;
+
+#define sz_xXF86DRICreateContextReply	32
+
+typedef struct _XF86DRIDestroyContext
+{
+    CARD8 reqType;		       /* always DRIReqCode */
+    CARD8 driReqType;		       /* always X_DRIDestroyContext */
+    CARD16 length B16;
+    CARD32 screen B32;
+    CARD32 context B32;
+} xXF86DRIDestroyContextReq;
+
+#define sz_xXF86DRIDestroyContextReq	12
+
+typedef struct _XF86DRICreateDrawable
+{
+    CARD8 reqType;		       /* always DRIReqCode */
+    CARD8 driReqType;		       /* always X_DRICreateDrawable */
+    CARD16 length B16;
+    CARD32 screen B32;
+    CARD32 drawable B32;
+} xXF86DRICreateDrawableReq;
+
+#define sz_xXF86DRICreateDrawableReq	12
+
+typedef struct
+{
+    BYTE type;			       /* X_Reply */
+    BOOL pad1;
+    CARD16 sequenceNumber B16;
+    CARD32 length B32;
+    CARD32 hHWDrawable B32;
+    CARD32 pad2 B32;
+    CARD32 pad3 B32;
+    CARD32 pad4 B32;
+    CARD32 pad5 B32;
+    CARD32 pad6 B32;
+} xXF86DRICreateDrawableReply;
+
+#define sz_xXF86DRICreateDrawableReply	32
+
+typedef struct _XF86DRIDestroyDrawable
+{
+    CARD8 reqType;		       /* always DRIReqCode */
+    CARD8 driReqType;		       /* always X_DRIDestroyDrawable */
+    CARD16 length B16;
+    CARD32 screen B32;
+    CARD32 drawable B32;
+} xXF86DRIDestroyDrawableReq;
+
+#define sz_xXF86DRIDestroyDrawableReq	12
+
+typedef struct _XF86DRIGetDrawableInfo
+{
+    CARD8 reqType;		       /* always DRIReqCode */
+    CARD8 driReqType;		       /* always X_DRIGetDrawableInfo */
+    CARD16 length B16;
+    CARD32 screen B32;
+    CARD32 drawable B32;
+} xXF86DRIGetDrawableInfoReq;
+
+#define sz_xXF86DRIGetDrawableInfoReq	12
+
+typedef struct
+{
+    BYTE type;			       /* X_Reply */
+    BOOL pad1;
+    CARD16 sequenceNumber B16;
+    CARD32 length B32;
+    CARD32 drawableTableIndex B32;
+    CARD32 drawableTableStamp B32;
+    INT16 drawableX B16;
+    INT16 drawableY B16;
+    INT16 drawableWidth B16;
+    INT16 drawableHeight B16;
+    CARD32 numClipRects B32;
+    INT16 backX B16;
+    INT16 backY B16;
+    CARD32 numBackClipRects B32;
+} xXF86DRIGetDrawableInfoReply;
+
+#define sz_xXF86DRIGetDrawableInfoReply	36
+
+typedef struct _XF86DRIGetDeviceInfo
+{
+    CARD8 reqType;		       /* always DRIReqCode */
+    CARD8 driReqType;		       /* always X_DRIGetDeviceInfo */
+    CARD16 length B16;
+    CARD32 screen B32;
+} xXF86DRIGetDeviceInfoReq;
+
+#define sz_xXF86DRIGetDeviceInfoReq	8
+
+typedef struct
+{
+    BYTE type;			       /* X_Reply */
+    BOOL pad1;
+    CARD16 sequenceNumber B16;
+    CARD32 length B32;
+    CARD32 hFrameBufferLow B32;
+    CARD32 hFrameBufferHigh B32;
+    CARD32 framebufferOrigin B32;
+    CARD32 framebufferSize B32;
+    CARD32 framebufferStride B32;
+    CARD32 devPrivateSize B32;
+} xXF86DRIGetDeviceInfoReply;
+
+#define sz_xXF86DRIGetDeviceInfoReply	32
+
+typedef struct _XF86DRIOpenFullScreen
+{
+    CARD8 reqType;		       /* always DRIReqCode */
+    CARD8 driReqType;		       /* always X_DRIOpenFullScreen */
+    CARD16 length B16;
+    CARD32 screen B32;
+    CARD32 drawable B32;
+} xXF86DRIOpenFullScreenReq;
+
+#define sz_xXF86DRIOpenFullScreenReq    12
+
+typedef struct
+{
+    BYTE type;
+    BOOL pad1;
+    CARD16 sequenceNumber B16;
+    CARD32 length B32;
+    CARD32 isFullScreen B32;
+    CARD32 pad2 B32;
+    CARD32 pad3 B32;
+    CARD32 pad4 B32;
+    CARD32 pad5 B32;
+    CARD32 pad6 B32;
+} xXF86DRIOpenFullScreenReply;
+
+#define sz_xXF86DRIOpenFullScreenReply  32
+
+typedef struct _XF86DRICloseFullScreen
+{
+    CARD8 reqType;		       /* always DRIReqCode */
+    CARD8 driReqType;		       /* always X_DRICloseFullScreen */
+    CARD16 length B16;
+    CARD32 screen B32;
+    CARD32 drawable B32;
+} xXF86DRICloseFullScreenReq;
+
+#define sz_xXF86DRICloseFullScreenReq   12
+
+typedef struct
+{
+    BYTE type;
+    BOOL pad1;
+    CARD16 sequenceNumber B16;
+    CARD32 length B32;
+    CARD32 pad2 B32;
+    CARD32 pad3 B32;
+    CARD32 pad4 B32;
+    CARD32 pad5 B32;
+    CARD32 pad6 B32;
+    CARD32 pad7 B32;
+} xXF86DRICloseFullScreenReply;
+
+#define sz_xXF86DRICloseFullScreenReply  32
+
+#endif /* _XF86DRISTR_H_ */


More information about the xorg-commit mailing list