[Intel-gfx] [PATCH]convert xvmc to use gem

Eric Anholt eric at anholt.net
Tue Apr 28 09:43:25 CEST 2009


On Tue, 2009-04-28 at 13:41 +0800, Shaohua Li wrote:
> This is the patch to convert xvmc using GEM. patch is against xvmc-vld tree.

I'd really rather see the stuff in master get fixed up so we can
actually ship XVMC finally.  Or is xvmc-vld landing in the next month?

Other than that, review inline.

> Signed-off-by: Shaohua Li<shaohua.li at intel.com>
> ---
>  src/i830_hwmc.h              |    2 
>  src/i965_hwmc.c              |   89 -----
>  src/i965_hwmc.h              |    3 
>  src/xvmc/Makefile.am         |    2 
>  src/xvmc/i965_xvmc.c         |  641 ++++++++++++++++++++++++-------------------
>  src/xvmc/intel_batchbuffer.c |  218 +++-----------
>  src/xvmc/intel_batchbuffer.h |    9 
>  src/xvmc/intel_xvmc.c        |   15 -
>  src/xvmc/intel_xvmc.h        |    9 
>  src/xvmc/xvmc_vld.c          |  437 ++++++++++++++++++++---------
>  10 files changed, 776 insertions(+), 649 deletions(-)
> 
> Index: xf86_video_intel/src/i965_hwmc.h
> ===================================================================
> --- xf86_video_intel.orig/src/i965_hwmc.h
> +++ xf86_video_intel/src/i965_hwmc.h
> @@ -10,9 +10,10 @@ struct  drm_memory_block {
>  };
>  
>  struct i965_xvmc_surface {
> -    struct 		drm_memory_block buffer;
> +    int			w, h;
>      unsigned int 	no;
>      void 		*handle; 
> +    dri_bo		*bo;
>  };
>  
>  struct i965_xvmc_context {
> Index: xf86_video_intel/src/xvmc/intel_batchbuffer.c
> ===================================================================
> --- xf86_video_intel.orig/src/xvmc/intel_batchbuffer.c
> +++ xf86_video_intel/src/xvmc/intel_batchbuffer.c
> @@ -45,9 +45,10 @@
>  
>  #include "intel_xvmc.h"
>  #include "intel_batchbuffer.h"
> -
> +#include "brw_defines.h"
> +#include "brw_structs.h"
>  #define MI_BATCH_BUFFER_END     (0xA << 23)
> -
> +#define BATCH_SIZE 8*1024 /* one bo is allocated one time, so the size can be small */

This comment appears to be wrong.

>  static int intelEmitIrqLocked(void)
>  {
>     drmI830IrqEmit ie;
> @@ -82,192 +83,85 @@ static void intelWaitIrq(int seq)
>     }
>  }
>  
> -static void intelDestroyBatchBuffer(void)
> +static void i965_end_batch(void)
>  {
> -   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(&xvmc_driver->batch, 0, sizeof(xvmc_driver->batch));
> +    unsigned int size = xvmc_driver->batch.ptr - 
> +	xvmc_driver->batch.init_ptr;
> +    if ((size & 4) == 0) {
> +	*(unsigned int*)xvmc_driver->batch.ptr = 0;
> +	xvmc_driver->batch.ptr += 4;
> +    }
> +    *(unsigned int*)xvmc_driver->batch.ptr = MI_BATCH_BUFFER_END;
> +    xvmc_driver->batch.ptr += 4;
>  }
>  
> -
>  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;
> -    }
> +    int i;
>  
> -    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 {
> -	xvmc_driver->alloc.size = 8 * 1024;
> -	xvmc_driver->alloc.offset = 0;
> -	xvmc_driver->alloc.ptr = malloc(xvmc_driver->alloc.size);
> +    if((xvmc_driver->batch.buf = 
> +		dri_bo_alloc(xvmc_driver->bufmgr, 
> +		    "batch buffer", BATCH_SIZE, 0x1000)) == NULL) {

It would be nice to see new code use drm_intel_bo_* instead of the
compatibility names.  I've been slowly converting code as I touch it.

> +	fprintf(stderr, "unable to alloc batch buffer\n");
> +	return False;
>      }
>  
> -    xvmc_driver->alloc.active_buf = 0;
> -    assert(xvmc_driver->alloc.ptr);
> +    drm_intel_gem_bo_map_gtt(xvmc_driver->batch.buf);

This needs to be protected for 2.6.28 kernels.  See Mesa's use of
drm_intel_gem_bo_map_gtt.

> +    xvmc_driver->batch.init_ptr = xvmc_driver->batch.buf->virtual;
> +    xvmc_driver->batch.size = BATCH_SIZE;
> +    xvmc_driver->batch.space = BATCH_SIZE;
> +    xvmc_driver->batch.ptr = xvmc_driver->batch.init_ptr;
>      return True;
>  }
>  
>  void intelFiniBatchBuffer(void)
>  {
> -    if (xvmc_driver->batchbuffer.map) {
> -        drmUnmap(xvmc_driver->batchbuffer.map, xvmc_driver->batchbuffer.size);
> -        xvmc_driver->batchbuffer.map = NULL;
> -    }
> -    intelDestroyBatchBuffer();
> +    dri_bo_unreference(xvmc_driver->batch.buf);
>  }
>  
> -static void intelBatchbufferRequireSpace(unsigned int sz)
> -{
> -   if (xvmc_driver->batch.space < sz)
> -      intelFlushBatch(TRUE);
> -}
>  
> -void intelBatchbufferData(const void *data, unsigned bytes, unsigned flags)
> +void intelFlushBatch(Bool refill )
>  {
> -   assert((bytes & 0x3) == 0);
> +    i965_end_batch();
> +    dri_bo_exec(xvmc_driver->batch.buf, 
> +	    xvmc_driver->batch.ptr - xvmc_driver->batch.init_ptr,
> +	    0, 0, 0);
> +//dri_bo_wait_rendering(xvmc_driver->batch.buf);

whitespace, // comment

> +
> +    dri_bo_unreference(xvmc_driver->batch.buf);
> +    if((xvmc_driver->batch.buf = 
> +		dri_bo_alloc(xvmc_driver->bufmgr, 
> +		    "batch buffer", BATCH_SIZE, 0x1000)) == NULL) {
> +	fprintf(stderr, "unable to alloc batch buffer\n");
> +    }
>  
> -   intelBatchbufferRequireSpace(bytes);
> -   memcpy(xvmc_driver->batch.ptr, data, bytes);
> -   xvmc_driver->batch.ptr += bytes;
> -   xvmc_driver->batch.space -= bytes;
> +    drm_intel_gem_bo_map_gtt(xvmc_driver->batch.buf);
>  
> -   assert(xvmc_driver->batch.space >= 0);
> +    xvmc_driver->batch.init_ptr = xvmc_driver->batch.buf->virtual;
> +    xvmc_driver->batch.size = BATCH_SIZE;
> +    xvmc_driver->batch.space = BATCH_SIZE;
> +    xvmc_driver->batch.ptr = xvmc_driver->batch.init_ptr;
>  }
>  
> -#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)
> -
> -static void intelRefillBatchLocked(Bool allow_unlock)
> +void intelBatchbufferRequireSpace(int size)
>  {
> -   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((char *)&dword[0], sizeof(dword));
> -
> -   xvmc_driver->alloc.irq_emitted = intelEmitIrqLocked();
> -
> -   if (xvmc_driver->alloc.irq_emitted) {
> -       intelWaitIrq(xvmc_driver->alloc.irq_emitted);
> -   }
> -
> -   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);
> -}
> -
> -
> -static void intelFlushBatchLocked(Bool ignore_cliprects,
> -				  Bool refill,
> -				  Bool allow_unlock)
> -{
> -   drmI830BatchBuffer batch;
> -
> -   if (xvmc_driver->batch.space != xvmc_driver->batch.size) {
> -
> -      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 (xvmc_driver->alloc.offset) {
> -          if ((batch.used & 0x4) == 0) {
> -              ((int *)xvmc_driver->batch.ptr)[0] = 0;
> -              ((int *)xvmc_driver->batch.ptr)[1] = MI_BATCH_BUFFER_END;
> -              batch.used += 0x8;
> -              xvmc_driver->batch.ptr += 0x8;
> -          } else {
> -              ((int *)xvmc_driver->batch.ptr)[0] = MI_BATCH_BUFFER_END;
> -              batch.used += 0x4;
> -              xvmc_driver->batch.ptr += 0x4;
> -          }
> -      }
> -
> -      xvmc_driver->batch.start_offset += batch.used;
> -      xvmc_driver->batch.size -= batch.used;
> -
> -      if (xvmc_driver->batch.size < 8) {
> -         refill = TRUE;
> -         xvmc_driver->batch.space = xvmc_driver->batch.size = 0;
> -      }
> -      else {
> -         xvmc_driver->batch.size -= 8;
> -         xvmc_driver->batch.space = xvmc_driver->batch.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 (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 *)xvmc_driver->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(xvmc_driver->fd, DRM_I830_CMDBUFFER, 
> -                             &cmd, sizeof(cmd))) {
> -            fprintf(stderr, "DRM_I915_CMDBUFFER: %d\n",  -errno);
> -            exit(1);
> -         }
> -      }
> -   }
> -
> -   if (refill)
> -      intelRefillBatchLocked(allow_unlock);
> +    if (xvmc_driver->batch.ptr - xvmc_driver->batch.init_ptr + size 
> +	    >= xvmc_driver->batch.size - 8) 
> +	intelFlushBatch(1);
>  }
>  
> -void intelFlushBatch(Bool refill )
> +void intelBatchbufferData(const void *data, unsigned bytes, unsigned flags)
>  {
> -   intelFlushBatchLocked(FALSE, refill, TRUE);
> +   intelBatchbufferRequireSpace(bytes);
> +   memcpy(xvmc_driver->batch.ptr, data, bytes);
> +   xvmc_driver->batch.ptr += bytes;
> +   xvmc_driver->batch.space -= bytes;
>  }
>  
> -void intelCmdIoctl(char *buf, unsigned used)
> +void intel_batch_emit_reloc(dri_bo *bo, uint32_t read_domain,
> +	uint32_t write_domain, uint32_t delta, unsigned char *ptr)
>  {
> -   drmI830CmdBuffer cmd;
> -
> -   cmd.buf = buf;
> -   cmd.sz = used;
> -   cmd.cliprects = 0;
> -   cmd.num_cliprects = 0;
> -   cmd.DR1 = 0;
> -   cmd.DR4 = 0;
> -
> -   if (drmCommandWrite(xvmc_driver->fd, DRM_I830_CMDBUFFER, 
> -                       &cmd, sizeof(cmd))) {
> -      fprintf(stderr, "DRM_I830_CMDBUFFER: %d\n",  -errno);
> -      exit(1);
> -   }
> +    dri_bo_emit_reloc(xvmc_driver->batch.buf, 
> +	    read_domain, write_domain, delta, 
> +	    ptr - xvmc_driver->batch.init_ptr, bo);

This appears to be missing setup of the presumed offset.  Just copy the
function in the 2D driver.

> Index: xf86_video_intel/src/xvmc/intel_batchbuffer.h
> ===================================================================
> --- xf86_video_intel.orig/src/xvmc/intel_batchbuffer.h
> +++ xf86_video_intel/src/xvmc/intel_batchbuffer.h
> @@ -21,6 +21,13 @@ extern int VERBOSE;
>          batch_ptr += 4;                                                 \
>      } while (0)
>  
> +#define OUT_RELOC(bo,read_domains,write_domains,delta)  \
> +    do { \
> +        *(unsigned int *)batch_ptr = delta + bo->offset; \
> +        intel_batch_emit_reloc(bo, read_domains, write_domains, delta, batch_ptr); \
> +        batch_ptr += 4;                                                 \
> +    } while (0)
> +

Oh, I see.  Still, I think the other copy of this macro/function is
better (more things into the inline function, and inline it).

>  #define OUT_BATCH_SHORT(n)                                              \
>      do {                                                                \
>          *(short *)batch_ptr = (n);                                      \
> @@ -44,4 +51,6 @@ extern void intelBatchbufferData(const v
>  extern Bool intelInitBatchBuffer(void);
>  extern void intelFiniBatchBuffer(void);
>  extern void intelCmdIoctl(char *, unsigned);
> +extern void intel_batch_emit_reloc(dri_bo *bo, uint32_t read_domain,
> +	uint32_t write_domain, uint32_t delta, unsigned char *);
>  #endif /* _INTEL_BATCHBUFFER_H */
> Index: xf86_video_intel/src/xvmc/intel_xvmc.h
> ===================================================================
> --- xf86_video_intel.orig/src/xvmc/intel_xvmc.h
> +++ xf86_video_intel/src/xvmc/intel_xvmc.h
> @@ -53,8 +53,9 @@
>  #include <X11/extensions/XvMClib.h>
>  #include <X11/extensions/vldXvMC.h>
>  #include <drm_sarea.h>
> -
> +#include "i915_drm.h"
>  #include "xf86dri.h"
> +#include "intel_bufmgr.h"
>  
>  #include "intel_batchbuffer.h"
>  
> @@ -133,14 +134,18 @@ typedef struct _intel_xvmc_driver {
>      drm_handle_t hsarea;	/* DRI open connect */
>      char busID[32];
>  
> +    dri_bufmgr      *bufmgr;
> +
>      unsigned int sarea_size;
>      drmAddress sarea_address;
>  
>      struct {
> -	unsigned int start_offset;
> +	unsigned int init_offset;
>  	unsigned int size;
>  	unsigned int space;
>  	unsigned char *ptr;
> +	unsigned char *init_ptr;
> +	dri_bo *buf;
>      } batch;
>  
>      struct
> Index: xf86_video_intel/src/xvmc/i965_xvmc.c
> ===================================================================
> --- xf86_video_intel.orig/src/xvmc/i965_xvmc.c
> +++ xf86_video_intel/src/xvmc/i965_xvmc.c
> @@ -32,13 +32,15 @@
>  #include "i965_hwmc.h"
>  #define BATCH_STRUCT(x) intelBatchbufferData(&x, sizeof(x), 0)
>  #define URB_SIZE     256        /* XXX */
> +
> +#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
> +
>  enum interface {
> -    INTRA_INTERFACE,            /* non field intra */
> +    INTRA_INTERFACE = 0,            /* non field intra */
>      NULL_INTERFACE,             /* fill with white, do nothing, for debug */
>      FORWARD_INTERFACE,          /* non field forward predict */
>      BACKWARD_INTERFACE,         /* non field backward predict */
>      F_B_INTERFACE,              /* non field forward and backward predict */
> -    FIELD_INTRA_INTERFACE,      /* field intra */
>      FIELD_FORWARD_INTERFACE,    /* field forward predict */
>      FIELD_BACKWARD_INTERFACE,   /* field backward predict */
>      FIELD_F_B_INTERFACE,        /* field forward and backward predict */
> @@ -94,65 +96,156 @@ static const uint32_t dual_prime_igd_ker
>  	#include "shader/mc/dual_prime_igd.g4b"
>  }; 
>  
> +struct kernel_struct{
> +	const uint32_t (*bin)[4];
> +	uint32_t size;
> +};
> +
> +struct kernel_struct kernels_igd[] = {
> +    {ipicture_kernel_static, sizeof(ipicture_kernel_static)},
> +    {null_kernel_static, sizeof(null_kernel_static)},
> +    {frame_forward_igd_kernel_static, sizeof(frame_forward_igd_kernel_static)},
> +    {frame_backward_igd_kernel_static, sizeof(frame_backward_igd_kernel_static)},
> +    {frame_f_b_igd_kernel_static, sizeof(frame_f_b_igd_kernel_static)},
> +    {field_forward_igd_kernel_static, sizeof(field_forward_igd_kernel_static)},
> +    {field_backward_igd_kernel_static, sizeof(field_backward_igd_kernel_static)},
> +    {field_f_b_igd_kernel_static, sizeof(field_f_b_igd_kernel_static)},
> +    {dual_prime_igd_kernel_static, sizeof(dual_prime_igd_kernel_static)}
> +};
> +
> +struct kernel_struct kernels_965[] = {
> +    {ipicture_kernel_static, sizeof(ipicture_kernel_static)},
> +    {null_kernel_static, sizeof(null_kernel_static)},
> +    {frame_forward_kernel_static, sizeof(frame_forward_kernel_static)},
> +    {frame_backward_kernel_static, sizeof(frame_backward_kernel_static)},
> +    {frame_f_b_kernel_static, sizeof(frame_f_b_kernel_static)},
> +    {field_forward_kernel_static, sizeof(field_forward_kernel_static)},
> +    {field_backward_kernel_static, sizeof(field_backward_kernel_static)},
> +    {field_f_b_kernel_static, sizeof(field_f_b_kernel_static)},
> +    {dual_prime_kernel_static, sizeof(dual_prime_kernel_static)}
> +};
> +
>  #define ALIGN(i,m)    (((i) + (m) - 1) & ~((m) - 1))
>  
>  #define MAX_SURFACE_NUM	10
>  #define DESCRIPTOR_NUM 12
>  
> +struct media_kernel_obj {
> +    dri_bo *bo;
> +};
> +
> +struct interface_descriptor_obj {
> +   dri_bo *bo;
> +   struct media_kernel_obj kernels[DESCRIPTOR_NUM];
> +};
> +
> +struct vfe_state_obj {
> +   dri_bo *bo;
> +   struct interface_descriptor_obj interface;
> +};
> +
> +struct surface_obj {
> +     dri_bo *bo; 
> +};
> +
> +struct surface_state_obj {
> +      struct surface_obj surface; 
> +      dri_bo *bo;
> +};
> +
> +struct binding_table_obj {
> +    dri_bo *bo;
> +    struct surface_state_obj surface_states[MAX_SURFACE_NUM];
> +};
> +
> +struct indirect_data_obj {
> +    dri_bo *bo;
> +};
> +
>  struct media_state {
> -    unsigned long state_base;
> -    void 	      *state_ptr;
> -    unsigned int  binding_table_entry_count;
> -    unsigned long vfe_state_offset;
> -    unsigned long interface_descriptor_offset[DESCRIPTOR_NUM];
> -    unsigned long ipicture_kernel_offset;
> -    unsigned long frame_forward_kernel_offset;
> -    unsigned long frame_backward_kernel_offset;
> -    unsigned long frame_f_b_kernel_offset;
> -    unsigned long ipicture_field_kernel_offset;
> -    unsigned long field_forward_kernel_offset;
> -    unsigned long field_backward_kernel_offset;
> -    unsigned long field_f_b_kernel_offset;
> -    unsigned long dual_prime_kernel_offset;
> -    unsigned long null_kernel_offset;
> -    unsigned long surface_offsets[MAX_SURFACE_NUM];
> -    unsigned long binding_table_offset;
>      unsigned int  is_g4x:1;
>      unsigned int  is_965_q:1;
> +
> +    struct vfe_state_obj vfe_state;
> +    struct binding_table_obj binding_table;
> +    struct indirect_data_obj indirect_data;
>  };
>  struct media_state media_state;
>  
> -static int map_buffer(struct  drm_memory_block *mem)
> +static int free_object(struct media_state *s)
>  {
> -    return (drmMap(xvmc_driver->fd, 
> -		mem->handle, mem->size, &mem->ptr));
> +    int i;
> +#define FREE_ONE_BO(bo) \
> +    if (bo) \
> +        dri_bo_unreference(bo)

drm_intel_bo_unreference() doesn't need NULL protection, so this is just
obfuscation.

> +    FREE_ONE_BO(s->vfe_state.bo);
> +    FREE_ONE_BO(s->vfe_state.interface.bo);
> +    for (i = 0; i < DESCRIPTOR_NUM; i++)
> +        FREE_ONE_BO(s->vfe_state.interface.kernels[i].bo);
> +    FREE_ONE_BO(s->binding_table.bo);
> +    for (i = 0; i < MAX_SURFACE_NUM; i++)
> +        FREE_ONE_BO(s->binding_table.surface_states[i].bo);
> +    FREE_ONE_BO(s->indirect_data.bo);
>  }
>  
> -static void unmap_buffer(struct  drm_memory_block *mem)
> +static int alloc_object(struct media_state *s, unsigned long w, unsigned long h)
>  {
> -    drmUnmap(mem->ptr, mem->size);
> +    struct kernel_struct *kernels;
> +    int kernel_array_size, i;
> +
> +    if (s->is_g4x) {
> +        kernels = kernels_igd;
> +        kernel_array_size = ARRAY_SIZE(kernels_igd);

Could you call it g4x if it's g4x?

> +    } else {
> +        kernels = kernels_965;
> +        kernel_array_size = ARRAY_SIZE(kernels_965);
> +    }
> +
> +    for (i = 0; i < kernel_array_size; i++) {
> +        s->vfe_state.interface.kernels[i].bo =
> +		dri_bo_alloc(xvmc_driver->bufmgr, "kernel",
> +			kernels[i].size, 0x1000);
> +        if (!s->vfe_state.interface.kernels[i].bo)
> +            goto out;
> +    }

This code should probably live down where the data is uploaded, since
you statically upload all the programs once.

> +
> +    for (i = 0; i < MAX_SURFACE_NUM; i++) {
> +        s->binding_table.surface_states[i].bo =
> +            dri_bo_alloc(xvmc_driver->bufmgr, "surface_state", 
> + 		sizeof(struct brw_surface_state), 0x1000);
> +        if (!s->binding_table.surface_states[i].bo)
> +            goto out;
> +    }
> +    return 0;
> +out:
> +    free_object(s);
> +    return BadAlloc;
>  }
>  
> +
>  static Status destroy_context(Display *display, XvMCContext *context)
>  {
>      struct i965_xvmc_context *private_context;
>      private_context = context->privData;
> -    unmap_buffer(&private_context->static_buffer);
> -    unmap_buffer(&private_context->blocks);
>  
> +    free_object(&media_state);
>      Xfree(private_context);
>      return Success;
>  }
>  
> +#define STRIDE(w)               (w)
> +#define SIZE_YUV420(w, h)       (h * (STRIDE(w) + STRIDE(w >> 1)))
> +
>  static Status create_surface(Display *display,
>  	XvMCContext *context, XvMCSurface *surface, int priv_count,
>  	CARD32 *priv_data)
>  {
>      struct i965_xvmc_surface *priv_surface = 
>  	(struct i965_xvmc_surface *)priv_data;
> -    if (map_buffer(&priv_surface->buffer))
> -	return BadAlloc;
> +    size_t size = SIZE_YUV420(priv_surface->w, priv_surface->h);
>      surface->privData = priv_data;
> +    priv_surface->bo = dri_bo_alloc(xvmc_driver->bufmgr, "surface", 
> +	    size, 0x1000);
>      return Success;
>  }
>  
> @@ -160,7 +253,9 @@ static Status destroy_surface(Display *d
>  {
>      struct i965_xvmc_surface *priv_surface = 
>  	surface->privData;
> -    unmap_buffer(&priv_surface->buffer);
> +    XSync(display, False);
> +
> +    dri_bo_unreference(priv_surface->bo);
>      return Success;
>  }
>  
> @@ -206,21 +301,6 @@ static void urb_layout()
>      OUT_BATCH(BRW_URB_FENCE |
>  	    UF0_VFE_REALLOC |
>  	    UF0_CS_REALLOC |
> -	    1);
> -    OUT_BATCH(0);
> -    OUT_BATCH(((URB_SIZE)<< UF2_VFE_FENCE_SHIFT) |	/* VFE_SIZE */
> -	    ((URB_SIZE)<< UF2_CS_FENCE_SHIFT));		/* CS_SIZE is 0 */
> -    ADVANCE_BATCH();
> -}
> -
> -/* clear previous urb layout */
> -static void clear_urb_state()
> -{
> -    BATCH_LOCALS;
> -    align_urb_fence();
> -    BEGIN_BATCH(3);
> -    OUT_BATCH(BRW_URB_FENCE |
> -	    UF0_CS_REALLOC |
>  	    UF0_SF_REALLOC |
>  	    UF0_CLIP_REALLOC |
>  	    UF0_GS_REALLOC |
> @@ -229,8 +309,9 @@ static void clear_urb_state()
>      OUT_BATCH((0 << UF1_CLIP_FENCE_SHIFT) |
>  	    (0 << UF1_GS_FENCE_SHIFT) |
>  	    (0 << UF1_VS_FENCE_SHIFT));
> -    OUT_BATCH((0 << UF2_CS_FENCE_SHIFT) |
> -	    (0 << UF2_SF_FENCE_SHIFT));
> +
> +    OUT_BATCH(((URB_SIZE)<< UF2_VFE_FENCE_SHIFT) |	/* VFE_SIZE */
> +	    ((URB_SIZE)<< UF2_CS_FENCE_SHIFT));		/* CS_SIZE is 0 */
>      ADVANCE_BATCH();
>  }
>  
> @@ -240,62 +321,88 @@ static void media_state_pointers(struct 
>      BEGIN_BATCH(3);
>      OUT_BATCH(BRW_MEDIA_STATE_POINTERS|1);
>      OUT_BATCH(0);
> -    OUT_BATCH(media_state->vfe_state_offset);
> -    ADVANCE_BATCH();
> -}
> -
> -static void cs_urb_layout()
> -{
> -    BATCH_LOCALS;
> -    BEGIN_BATCH(2);
> -    OUT_BATCH(BRW_CS_URB_STATE | 0);
> -    OUT_BATCH((0 << 4) |    /* URB Entry Allocation Size */
> -	      (0 << 0));    /* Number of URB Entries */
> +    OUT_RELOC(media_state->vfe_state.bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
>      ADVANCE_BATCH();
>  }
>  
>  /* setup 2D surface for media_read or media_write 
>   */
> -static void setup_media_surface(struct media_state *media_state,
> -	int surface_num, unsigned long offset, int w, int h)
> +static Status setup_media_surface(struct media_state *media_state,
> +	int surface_num, dri_bo *bo, unsigned long offset, int w, int h, Bool write)
>  {
> -    struct brw_surface_state *ss;
> -    ss = media_state->state_ptr +
> -	(media_state->surface_offsets[surface_num] - media_state->state_base);
> +    struct brw_surface_state s, *ss = &s;
> +
>      memset(ss, 0, sizeof(struct brw_surface_state));
>      ss->ss0.surface_type = BRW_SURFACE_2D;
>      ss->ss0.surface_format = BRW_SURFACEFORMAT_R8_SINT;
> -    ss->ss1.base_addr = offset;
> +    ss->ss1.base_addr = offset + bo->offset;
>      ss->ss2.width = w - 1;
>      ss->ss2.height = h - 1;
>      ss->ss3.pitch = w - 1;
> +
> +    if (media_state->binding_table.surface_states[surface_num].bo)
> +        dri_bo_unreference(media_state->binding_table.surface_states[surface_num].bo);
> +    media_state->binding_table.surface_states[surface_num].bo =
> +            dri_bo_alloc(xvmc_driver->bufmgr, "surface_state", 
> + 		sizeof(struct brw_surface_state), 0x1000);
> +    if (!media_state->binding_table.surface_states[surface_num].bo)
> +        return BadAlloc;
> +
> +    dri_bo_subdata(
> +	    media_state->binding_table.surface_states[surface_num].bo,
> +	    0, sizeof(*ss), ss);
> +
> +    dri_bo_emit_reloc(media_state->binding_table.surface_states[surface_num].bo, 
> +	    I915_GEM_DOMAIN_RENDER, write?I915_GEM_DOMAIN_RENDER:0,
> +	    offset,
> +	    offsetof(struct brw_surface_state, ss1),
> +	    bo);
> +    return Success;
>  }
>  
> -static void setup_surfaces(struct media_state *media_state, 
> -	unsigned long dst_offset, unsigned long past_offset, 
> -	unsigned long future_offset, 
> +static Status setup_surfaces(struct media_state *media_state, 
> +	dri_bo *dst_bo, dri_bo *past_bo, dri_bo *future_bo, 
>  	int w, int h)
>  {
> -    setup_media_surface(media_state, 0, dst_offset, w, h);
> -    setup_media_surface(media_state, 1, dst_offset+w*h, w/2, h/2);
> -    setup_media_surface(media_state, 2, dst_offset+w*h + w*h/4, w/2, h/2);
> -    if (past_offset) {
> -	setup_media_surface(media_state, 4, past_offset, w, h);
> -	setup_media_surface(media_state, 5, past_offset+w*h, w/2, h/2);
> -	setup_media_surface(media_state, 6, past_offset+w*h + w*h/4, w/2, h/2);
> -    }
> -    if (future_offset) {
> -	setup_media_surface(media_state, 7, future_offset, w, h);
> -	setup_media_surface(media_state, 8, future_offset+w*h, w/2, h/2);
> -	setup_media_surface(media_state, 9, future_offset+w*h + w*h/4, w/2, h/2);
> +    Status ret;
> +    ret = setup_media_surface(media_state, 0, dst_bo, 0, w, h, TRUE);
> +    if (ret != Success)
> +        return ret;
> +    ret = setup_media_surface(media_state, 1, dst_bo, w*h, w/2, h/2, TRUE);
> +    if (ret != Success)
> +        return ret;
> +    ret = setup_media_surface(media_state, 2, dst_bo, w*h + w*h/4, w/2, h/2, TRUE);
> +    if (ret != Success)
> +        return ret;
> +    if (past_bo) {
> +	ret = setup_media_surface(media_state, 4, past_bo, 0, w, h, FALSE);
> +        if (ret != Success)
> +            return ret;
> +	ret = setup_media_surface(media_state, 5, past_bo, w*h, w/2, h/2, FALSE);
> +        if (ret != Success)
> +            return ret;
> +	ret = setup_media_surface(media_state, 6, past_bo, w*h + w*h/4, w/2, h/2, FALSE);
> +        if (ret != Success)
> +            return ret;
>      }
> +    if (future_bo) {
> +	ret = setup_media_surface(media_state, 7, future_bo, 0, w, h, FALSE);
> +        if (ret != Success)
> +            return ret;
> +	ret = setup_media_surface(media_state, 8, future_bo, w*h, w/2, h/2, FALSE);
> +        if (ret != Success)
> +            return ret;
> +	ret = setup_media_surface(media_state, 9, future_bo, w*h + w*h/4, w/2, h/2, FALSE);
> +        if (ret != Success)
> +            return ret;
> +    }
> +    return Success;
>  }
>  /* BUFFER SURFACE has a strange format
>   * the size of the surface is in part of w h and d component
>   */
>  
> -static void setup_blocks(struct media_state *media_state, 
> -	unsigned long offset, unsigned int block_size)
> +static Status setup_blocks(struct media_state *media_state, unsigned int block_size)
>  {
>      union element{
>  		struct {
> @@ -306,22 +413,39 @@ static void setup_blocks(struct media_st
>  		}whd;
>  		unsigned int size;	
>      }e;
> -    struct brw_surface_state *ss;
> -    ss = media_state->state_ptr +
> -	(media_state->surface_offsets[3] - media_state->state_base);
> -    memset(ss, 0, sizeof(struct brw_surface_state));
> -    ss->ss0.surface_type = BRW_SURFACE_BUFFER;
> -    ss->ss0.surface_format = BRW_SURFACEFORMAT_R8_UINT;
> -    ss->ss1.base_addr = offset;
> +    struct brw_surface_state ss;
> +    memset(&ss, 0, sizeof(struct brw_surface_state));
> +    ss.ss0.surface_type = BRW_SURFACE_BUFFER;
> +    ss.ss0.surface_format = BRW_SURFACEFORMAT_R8_UINT;
> +    ss.ss1.base_addr = media_state->indirect_data.bo->offset;
> +
>      e.size = block_size - 1;
> -    ss->ss2.width = e.whd.w;
> -    ss->ss2.height = e.whd.h;
> -    ss->ss3.depth = e.whd.d;
> -    ss->ss3.pitch = block_size - 1;
> +    ss.ss2.width = e.whd.w;
> +    ss.ss2.height = e.whd.h;
> +    ss.ss3.depth = e.whd.d;
> +    ss.ss3.pitch = block_size - 1;
> +  
> +    if (media_state->binding_table.surface_states[3].bo)
> +        dri_bo_unreference(media_state->binding_table.surface_states[3].bo);
> +
> +    media_state->binding_table.surface_states[3].bo =
> +            dri_bo_alloc(xvmc_driver->bufmgr, "surface_state", 
> + 		sizeof(struct brw_surface_state), 0x1000);
> +    if (!media_state->binding_table.surface_states[3].bo)
> +        return BadAlloc;
> +  
> +    dri_bo_subdata(media_state->binding_table.surface_states[3].bo, 0, 
> +	    sizeof(ss), &ss);
> +
> +    dri_bo_emit_reloc(media_state->binding_table.surface_states[3].bo,
> +        I915_GEM_DOMAIN_SAMPLER, 0, 0,
> +        offsetof(struct brw_surface_state, ss1),
> +        media_state->indirect_data.bo);
> +    return Success;
>  }
>  
>  /* setup state base address */
> -static void state_base_address(int offset)
> +static void state_base_address()
>  {
>      BATCH_LOCALS;
>      BEGIN_BATCH(6);
> @@ -330,7 +454,7 @@ static void state_base_address(int offse
>      OUT_BATCH(0 | BASE_ADDRESS_MODIFY); 
>      OUT_BATCH(0 | BASE_ADDRESS_MODIFY);
>      OUT_BATCH(0 | BASE_ADDRESS_MODIFY);
> -    OUT_BATCH((0xFFFFF<<12) | BASE_ADDRESS_MODIFY);
> +    OUT_BATCH(BASE_ADDRESS_MODIFY);
>      ADVANCE_BATCH();
>  }
>  
> @@ -358,12 +482,14 @@ static void send_media_object(XvMCMacroB
>  	OUT_BATCH(0);
>      }else {
>  	OUT_BATCH(6*128);
> -	OUT_BATCH(offset);
> +        OUT_RELOC(media_state.indirect_data.bo,
> +            I915_GEM_DOMAIN_INSTRUCTION, 0, offset);

weird whitespace

>      }
>      
>      OUT_BATCH(mb->x<<4);                 //g1.0
>      OUT_BATCH(mb->y<<4);
> -    OUT_BATCH(offset);               //g1.8
> +    OUT_RELOC(media_state.indirect_data.bo, //g1.8
> +            I915_GEM_DOMAIN_INSTRUCTION, 0, offset);
>      OUT_BATCH_SHORT(mb->coded_block_pattern);  //g1.12
>      OUT_BATCH_SHORT(mb->PMV[0][0][0]);         //g1.14
>      OUT_BATCH_SHORT(mb->PMV[0][0][1]);         //g1.16
> @@ -384,178 +510,140 @@ static void send_media_object(XvMCMacroB
>      ADVANCE_BATCH();
>  }
>  
> -static void binding_tables(struct media_state *media_state)
> +static Status binding_tables(struct media_state *media_state)
>  {
> -    unsigned int *binding_table;
> +    unsigned int binding_table[MAX_SURFACE_NUM];
>      int i;
> -    binding_table = media_state->state_ptr +
> -	(media_state->binding_table_offset - media_state->state_base);
> +
> +    if (media_state->binding_table.bo)
> +        dri_bo_unreference(media_state->binding_table.bo);
> +    media_state->binding_table.bo = 
> + 	dri_bo_alloc(xvmc_driver->bufmgr, "binding_table", 
> + 		MAX_SURFACE_NUM*4, 0x1000);
> +    if (!media_state->binding_table.bo)
> +        return BadAlloc;
> +
> +    for (i = 0; i < MAX_SURFACE_NUM; i++)
> +	binding_table[i] = media_state->binding_table.surface_states[i].bo->offset;
> +    dri_bo_subdata(media_state->binding_table.bo, 0, sizeof(binding_table),
> +        binding_table);
> +
>      for (i = 0; i < MAX_SURFACE_NUM; i++)
> -	binding_table[i] = media_state->surface_offsets[i];
> +        dri_bo_emit_reloc(media_state->binding_table.bo, 
> +	    I915_GEM_DOMAIN_INSTRUCTION, 0, 0,
> +	    i * sizeof(unsigned int),
> +	    media_state->binding_table.surface_states[i].bo);
> +     return Success;
>  }
>  
>  static void media_kernels(struct media_state *media_state)
>  {
> -	void *kernel; 
> -#define LOAD_KERNEL(name) kernel = media_state->state_ptr +\
> -	(media_state->name##_kernel_offset - media_state->state_base);\
> -	memcpy(kernel, name##_kernel_static, sizeof(name##_kernel_static));
> -#define LOAD_KERNEL_IGD(name) kernel = media_state->state_ptr +\
> -	(media_state->name##_kernel_offset - media_state->state_base);\
> -	memcpy(kernel, name##_igd_kernel_static, sizeof(name##_igd_kernel_static));
> -
> -	LOAD_KERNEL(ipicture);
> -	LOAD_KERNEL(null);
> -	if (media_state->is_g4x) {
> -		LOAD_KERNEL_IGD(frame_forward);
> -		LOAD_KERNEL_IGD(field_forward);
> -		LOAD_KERNEL_IGD(frame_backward);
> -		LOAD_KERNEL_IGD(field_backward);
> -		LOAD_KERNEL_IGD(frame_f_b);
> -		LOAD_KERNEL_IGD(field_f_b);
> -		LOAD_KERNEL_IGD(dual_prime);
> -
> -	}else {
> -		LOAD_KERNEL(frame_forward);
> -		LOAD_KERNEL(field_forward);
> -		LOAD_KERNEL(frame_backward);
> -		LOAD_KERNEL(field_backward);
> -		LOAD_KERNEL(frame_f_b);
> -		LOAD_KERNEL(field_f_b);
> -		LOAD_KERNEL(dual_prime);
> -	}
> +    struct kernel_struct *kernels;
> +    int kernel_array_size, i;
> +
> +   if (media_state->is_g4x) {
> +        kernels = kernels_igd;
> +        kernel_array_size = ARRAY_SIZE(kernels_igd);
> +    } else {
> +        kernels = kernels_965;
> +        kernel_array_size = ARRAY_SIZE(kernels_965);
> +    }
> +
> +    for (i = 0; i < kernel_array_size; i++) {
> +        dri_bo *bo = media_state->vfe_state.interface.kernels[i].bo;
> +	dri_bo_subdata(bo, 0, kernels[i].size, kernels[i].bin);

more weird whitespace (please consistently use tabs instead of 8 spaces)

> +    }
>  }
>  
>  static void setup_interface(struct media_state *media_state, 
> -	enum interface interface, unsigned int kernel_offset)
> +	enum interface i)
>  {
> -    struct brw_interface_descriptor *desc;
> -    desc = media_state->state_ptr +
> -	(media_state->interface_descriptor_offset[interface] 
> -	 - media_state->state_base);
> -    memset(desc, 0, sizeof(*desc));
> -    desc->desc0.grf_reg_blocks = 15;
> -    desc->desc0.kernel_start_pointer = kernel_offset >> 6;
> -    desc->desc1.floating_point_mode = BRW_FLOATING_POINT_NON_IEEE_754;
> +    struct brw_interface_descriptor desc;
> +    memset(&desc, 0, sizeof(desc));
> +
> +    desc.desc0.grf_reg_blocks = 15;
> +    desc.desc0.kernel_start_pointer =
> +        media_state->vfe_state.interface.kernels[i].bo->offset >> 6;
> +
> +    desc.desc1.floating_point_mode = BRW_FLOATING_POINT_NON_IEEE_754;
>  
>      /* use same binding table for all interface
>       * may change this if it affect performance
>       */
> -    desc->desc3.binding_table_entry_count = MAX_SURFACE_NUM;
> -    desc->desc3.binding_table_pointer = media_state->binding_table_offset >> 5;
> +    desc.desc3.binding_table_entry_count = MAX_SURFACE_NUM;
> +    desc.desc3.binding_table_pointer = media_state->binding_table.bo->offset >> 5;
> +
> +    dri_bo_subdata(media_state->vfe_state.interface.bo, i*sizeof(desc), 
> +	    sizeof(desc), &desc);
> +
> +    dri_bo_emit_reloc(
> +	    media_state->vfe_state.interface.bo,
> +	    I915_GEM_DOMAIN_INSTRUCTION, 0,
> +	    desc.desc0.grf_reg_blocks,
> +	    i * sizeof(desc) + 
> +	    offsetof(struct brw_interface_descriptor, desc0),
> +	    media_state->vfe_state.interface.kernels[i].bo);
> +
> +    dri_bo_emit_reloc(
> +	    media_state->vfe_state.interface.bo,
> +	    I915_GEM_DOMAIN_INSTRUCTION, 0,
> +	    desc.desc3.binding_table_entry_count,
> +	    i * sizeof(desc) + 
> +	    offsetof(struct brw_interface_descriptor, desc3),
> +	    media_state->binding_table.bo);
> +}
> +
> +static Status interface_descriptor(struct media_state *media_state)
> +{
> +	if (media_state->vfe_state.interface.bo)
> +		dri_bo_unreference(media_state->vfe_state.interface.bo);
> +	media_state->vfe_state.interface.bo = dri_bo_alloc(xvmc_driver->bufmgr,
> +	    "interfaces", DESCRIPTOR_NUM*sizeof(struct brw_interface_descriptor),
> +	    0x1000);
> +	if (!media_state->vfe_state.interface.bo)
> +		return BadAlloc;
> +
> +	setup_interface(media_state, INTRA_INTERFACE);
> +	setup_interface(media_state, NULL_INTERFACE);
> +	setup_interface(media_state, FORWARD_INTERFACE);
> +	setup_interface(media_state, FIELD_FORWARD_INTERFACE);
> +	setup_interface(media_state, BACKWARD_INTERFACE);
> +	setup_interface(media_state, FIELD_BACKWARD_INTERFACE);
> +	setup_interface(media_state, F_B_INTERFACE);
> +	setup_interface(media_state, FIELD_F_B_INTERFACE);
> +	setup_interface(media_state, DUAL_PRIME_INTERFACE);
> +	return Success;

One function of 8-space indents in the middle of a file full of
4-space-converted-from-3-space?  WTF?

>  }
>  
> -static void interface_descriptor(struct media_state *media_state)
> +static Status vfe_state(struct media_state *media_state)
>  {
> -	setup_interface(media_state, INTRA_INTERFACE, 
> -		media_state->ipicture_kernel_offset);
> -	setup_interface(media_state, NULL_INTERFACE, 
> -		media_state->null_kernel_offset);
> -	setup_interface(media_state, FORWARD_INTERFACE, 
> -		media_state->frame_forward_kernel_offset);
> -	setup_interface(media_state, FIELD_FORWARD_INTERFACE, 
> -		media_state->field_forward_kernel_offset);
> -	setup_interface(media_state, BACKWARD_INTERFACE, 
> -		media_state->frame_backward_kernel_offset);
> -	setup_interface(media_state, FIELD_BACKWARD_INTERFACE, 
> -		media_state->field_backward_kernel_offset);
> -	setup_interface(media_state, F_B_INTERFACE, 
> -		media_state->frame_f_b_kernel_offset);
> -	setup_interface(media_state, FIELD_F_B_INTERFACE, 
> -		media_state->field_f_b_kernel_offset);
> -	setup_interface(media_state, DUAL_PRIME_INTERFACE,
> -		media_state->dual_prime_kernel_offset);
> -}
> -
> -static void vfe_state(struct media_state *media_state)
> -{
> -	struct brw_vfe_state *state;
> -	state = media_state->state_ptr +
> -	    (media_state->vfe_state_offset - media_state->state_base);
> -	memset(state, 0, sizeof(*state));
> +	struct brw_vfe_state state;
> +	memset(&state, 0, sizeof(state));
> +
>  	/* no scratch space */
> -	state->vfe1.vfe_mode = VFE_GENERIC_MODE;
> -	state->vfe1.num_urb_entries = 1; 
> +	state.vfe1.vfe_mode = VFE_GENERIC_MODE;
> +	state.vfe1.num_urb_entries = 1;
>  	/* XXX TODO */
>  	/* should carefully caculate those values for performance */
> -	state->vfe1.urb_entry_alloc_size = 2; 
> -	state->vfe1.max_threads = 31; 
> -	state->vfe2.interface_descriptor_base = 
> -		media_state->interface_descriptor_offset[0] >> 4;
> -}
> -
> -static void calc_state_layouts(struct media_state *media_state)
> -{
> -    int i;
> -    media_state->vfe_state_offset = ALIGN(media_state->state_base, 64);
> -    media_state->interface_descriptor_offset[0] = 
> -	ALIGN(media_state->vfe_state_offset + sizeof(struct brw_vfe_state), 64);
> -    for (i = 1; i < DESCRIPTOR_NUM; i++)
> -	media_state->interface_descriptor_offset[i] = 
> -	    media_state->interface_descriptor_offset[i-1]
> -	    + sizeof(struct brw_interface_descriptor);
> -    media_state->binding_table_offset = 
> -	ALIGN(media_state->interface_descriptor_offset[DESCRIPTOR_NUM - 1]
> -		+ sizeof(struct brw_interface_descriptor), 64);
> -    media_state->surface_offsets[0] = 
> -	ALIGN(media_state->binding_table_offset
> -		+ 4*media_state->binding_table_entry_count , 32);
> -    for (i = 1; i < MAX_SURFACE_NUM; i++)
> -	media_state->surface_offsets[i] = 
> -	    ALIGN(media_state->surface_offsets[i - 1] 
> -		    + sizeof(struct brw_surface_state) , 32);
> -    media_state->ipicture_kernel_offset = 
> -	ALIGN(media_state->surface_offsets[MAX_SURFACE_NUM - 1] 
> -		+ sizeof(struct brw_surface_state) , 64);
> -
> -    media_state->frame_forward_kernel_offset = 
> -	    ALIGN(media_state->ipicture_kernel_offset + 
> -			    sizeof(ipicture_kernel_static), 64);
> -    if(!media_state->is_g4x) {
> -	    media_state->field_forward_kernel_offset = 
> -		    ALIGN(media_state->frame_forward_kernel_offset + 
> -				    sizeof(frame_forward_kernel_static), 64);
> -	    media_state->frame_backward_kernel_offset = 
> -		    ALIGN(media_state->field_forward_kernel_offset + 
> -				    sizeof(field_forward_kernel_static), 64);
> -	    media_state->field_backward_kernel_offset = 
> -		    ALIGN(media_state->frame_backward_kernel_offset + 
> -				    sizeof(frame_backward_kernel_static), 64);
> -	    media_state->frame_f_b_kernel_offset = 
> -		    ALIGN(media_state->field_backward_kernel_offset + 
> -				    sizeof(field_backward_kernel_static), 64);
> -	    media_state->field_f_b_kernel_offset = 
> -		    ALIGN(media_state->frame_f_b_kernel_offset + 
> -				    sizeof(frame_f_b_kernel_static), 64);
> -	    media_state->null_kernel_offset =
> -		    ALIGN(media_state->field_f_b_kernel_offset +
> -				    sizeof(field_f_b_kernel_static), 64);
> -	    media_state->dual_prime_kernel_offset =
> -		    ALIGN(media_state->null_kernel_offset +
> -				    sizeof(null_kernel_static), 64);
> -    } else {
> -	    media_state->field_forward_kernel_offset = 
> -		    ALIGN(media_state->frame_forward_kernel_offset + 
> -				    sizeof(frame_forward_igd_kernel_static), 64);
> -	    media_state->frame_backward_kernel_offset = 
> -		    ALIGN(media_state->field_forward_kernel_offset + 
> -				    sizeof(field_forward_igd_kernel_static), 64);
> -	    media_state->field_backward_kernel_offset = 
> -		    ALIGN(media_state->frame_backward_kernel_offset + 
> -				    sizeof(frame_backward_igd_kernel_static), 64);
> -	    media_state->frame_f_b_kernel_offset = 
> -		    ALIGN(media_state->field_backward_kernel_offset + 
> -				    sizeof(field_backward_igd_kernel_static), 64);
> -	    media_state->field_f_b_kernel_offset = 
> -		    ALIGN(media_state->frame_f_b_kernel_offset + 
> -				    sizeof(frame_f_b_igd_kernel_static), 64);
> -	    media_state->null_kernel_offset =
> -		    ALIGN(media_state->field_f_b_kernel_offset +
> -				    sizeof(field_f_b_igd_kernel_static), 64);
> -	    media_state->dual_prime_kernel_offset =
> -		    ALIGN(media_state->null_kernel_offset +
> -				    sizeof(null_kernel_static), 64);
> -    }
> +	state.vfe1.urb_entry_alloc_size = 2;
> +	state.vfe1.max_threads = 31;
> +        state.vfe2.interface_descriptor_base =
> +		media_state->vfe_state.interface.bo->offset >> 4;
> +
> +	if (media_state->vfe_state.bo)
> +		dri_bo_unreference(media_state->vfe_state.bo);
> +	media_state->vfe_state.bo = dri_bo_alloc(xvmc_driver->bufmgr,
> +		"vfe state", sizeof(struct brw_vfe_state), 0x1000);
> +	if (!media_state->vfe_state.bo)
> +		return BadAlloc;
> +
> +	dri_bo_subdata(media_state->vfe_state.bo, 0, sizeof(state), &state);
> +
> +	dri_bo_emit_reloc(media_state->vfe_state.bo,
> +		I915_GEM_DOMAIN_INSTRUCTION, 0, 0,
> +		offsetof(struct brw_vfe_state, vfe2),
> +		media_state->vfe_state.interface.bo);
> +	return Success;
>  }
>  
>  static Status render_surface(Display *display, 
> @@ -588,13 +676,26 @@ static Status render_surface(Display *di
>  	XVMC_ERR("Can't find intel xvmc context\n");
>  	return BadValue;
>      }
> +
> +    if (media_state.indirect_data.bo)
> +        dri_bo_unreference(media_state.indirect_data.bo);
> +    media_state.indirect_data.bo = dri_bo_alloc(xvmc_driver->bufmgr,
> +	    "indirect data", 128*6*num_macroblocks, 64);
> +    if (!media_state.indirect_data.bo)
> +        return BadAlloc;
>      setup_surfaces(&media_state, 
> -	    priv_target_surface->buffer.offset, 
> -	    past_surface? priv_past_surface->buffer.offset:0, 
> -	    future_surface?priv_future_surface->buffer.offset:0, 
> +	    priv_target_surface->bo, 
> +	    past_surface? priv_past_surface->bo:NULL, 
> +	    future_surface?priv_future_surface->bo:NULL, 
>  	    context->width, context->height);
> +    setup_blocks(&media_state, 128*6*num_macroblocks);
> +    binding_tables(&media_state);
> +    interface_descriptor(&media_state);
> +    vfe_state(&media_state);
>  
> -    block_ptr = i965_ctx->blocks.ptr;
> +    drm_intel_gem_bo_map_gtt(media_state.indirect_data.bo);
> +
> +    block_ptr = media_state.indirect_data.bo->virtual;
>      for (i = first_macroblock; 
>  	    i < num_macroblocks + first_macroblock; i++) {
>  	unsigned short *mb_block_ptr;
> @@ -635,20 +736,15 @@ static Status render_surface(Display *di
>  	    memcpy(block_ptr, mb_block_ptr, 128);
>  	block_ptr += 64;
>      }
> -
>      {
> -	int block_offset;
> -	block_offset = media_state.is_965_q?0:i965_ctx->blocks.offset;
> +	int block_offset = 0;
>  	LOCK_HARDWARE(intel_ctx->hw_context);
> -	state_base_address(block_offset);
> +	state_base_address();
>  	flush();	
>  	clear_sf_state();
> -	clear_urb_state();
>  	pipeline_select(&media_state);
>  	urb_layout();	
>  	media_state_pointers(&media_state);
> -	cs_urb_layout();
> -
>  	for (i = first_macroblock; 
>  		i < num_macroblocks + first_macroblock; 
>  		i++, block_offset += 128*6) {
> @@ -700,8 +796,11 @@ static Status put_surface(Display *displ
>  {
>  	struct i965_xvmc_surface *private_surface =
>  		surface->privData;
> +	uint32_t handle = 0;
> +
> +        dri_bo_flink(private_surface->bo, &handle);
> +	data->handle = handle;

More wonky whitespace.

>  
> -	data->surf_offset = private_surface->buffer.offset;
>  	return Success;
>  }
>  
> @@ -718,25 +817,13 @@ static Status create_context(Display *di
>      struct i965_xvmc_context *i965_ctx;
>      i965_ctx = (struct i965_xvmc_context *)priv_data;
>      context->privData = i965_ctx;
> -    if (map_buffer(&i965_ctx->static_buffer))
> -	return BadAlloc;
> -    if(map_buffer(&i965_ctx->blocks))
> -	return BadAlloc;
> -    {
> -	media_state.state_base = i965_ctx->static_buffer.offset;
> -	media_state.state_ptr = i965_ctx->static_buffer.ptr;
> -	media_state.is_g4x = i965_ctx->is_g4x;
> -	media_state.is_965_q = i965_ctx->is_965_q;
> -	media_state.binding_table_entry_count = MAX_SURFACE_NUM;
> -	calc_state_layouts(&media_state);
> -	vfe_state(&media_state);
> -	interface_descriptor(&media_state); 
> -	media_kernels(&media_state);
> -	setup_blocks(&media_state, 
> -		i965_ctx->blocks.offset, 
> -		6*context->width*context->height*sizeof(short));
> -	binding_tables(&media_state);
> -    }
> +
> +    media_state.is_g4x = i965_ctx->is_g4x;
> +    media_state.is_965_q = i965_ctx->is_965_q;
> +
> +    if (alloc_object(&media_state, context->width, context->height))
> +        return BadAlloc;
> +    media_kernels(&media_state);
>      return Success;
>  }
>  
> Index: xf86_video_intel/src/xvmc/intel_xvmc.c
> ===================================================================
> --- xf86_video_intel.orig/src/xvmc/intel_xvmc.c
> +++ xf86_video_intel/src/xvmc/intel_xvmc.c
> @@ -357,9 +357,6 @@ _X_EXPORT Status XvMCCreateContext(Displ
>      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;
> -    xvmc_driver->batchbuffer.size = comm->batchbuffer.size;
>  
>      /* assign local ctx info */
>      intel_ctx = intel_xvmc_new_context(display);
> @@ -435,6 +432,13 @@ _X_EXPORT Status XvMCCreateContext(Displ
>          return BadAlloc;
>      }
>  
> +    if ((xvmc_driver->bufmgr =
> +		intel_bufmgr_gem_init(xvmc_driver->fd, 1024*64)) == NULL) {
> +	XVMC_ERR("Can't init bufmgr\n");
> + 	return BadAlloc;
> +    }
> +    drm_intel_bufmgr_gem_enable_reuse(xvmc_driver->bufmgr);
> +
>      /* call driver hook.
>       * driver hook should free priv_data after return if success.*/
>      ret = (xvmc_driver->create_context)(display, context, priv_count, priv_data);
> @@ -475,6 +479,10 @@ _X_EXPORT Status XvMCDestroyContext(Disp
>  	return ret;
>      }
>  
> +    intelFiniBatchBuffer();
> +
> +    dri_bufmgr_destroy(xvmc_driver->bufmgr);
> +
>      uniDRIDestroyContext(display, screen, context->context_id);
>      intel_xvmc_free_context(context->context_id);
>  
> @@ -495,7 +503,6 @@ _X_EXPORT Status XvMCDestroyContext(Disp
>  	    drmClose(xvmc_driver->fd);
>  	xvmc_driver->fd = -1;
>  
> -	intelFiniBatchBuffer();
>  
>  	intel_xvmc_dump_close();
>      }
> Index: xf86_video_intel/src/i965_hwmc.c
> ===================================================================
> --- xf86_video_intel.orig/src/i965_hwmc.c
> +++ xf86_video_intel/src/i965_hwmc.c
> @@ -38,6 +38,7 @@
>  #define _INTEL_XVMC_SERVER_
>  #include "i830_hwmc.h"
>  #include "i965_hwmc.h"
> +#include "intel_bufmgr.h"
>  
>  #define STRIDE(w)               (w)
>  #define SIZE_YUV420(w, h)       (h * (STRIDE(w) + STRIDE(w >> 1)))
> @@ -50,40 +51,6 @@
>  static PutImageFuncPtr XvPutImage;
>  
> 
> -static int alloc_drm_memory(ScrnInfoPtr pScrn, 
> -	struct drm_memory_block *mem, 
> -	char *name, size_t size)
> -{
> -    I830Ptr pI830 = I830PTR(pScrn);
> -    if ((mem->buffer = i830_allocate_memory(pScrn, 
> -	    name, size, PITCH_NONE, GTT_PAGE_SIZE,
> -	    ALIGN_BOTH_ENDS, TILE_NONE)) == NULL) {
> -	ErrorF("Fail to alloc \n");
> -	return BadAlloc;
> -    }
> -
> -    if (drmAddMap(pI830->drmSubFD,
> -                  (drm_handle_t)(mem->buffer->offset + pI830->LinearAddr),
> -                  size, DRM_AGP, 0,
> -                  (drmAddress)&mem->handle) < 0) {
> -	ErrorF("Fail to map %d \n", errno);
> -	i830_free_memory(pScrn, mem->buffer);
> -	return BadAlloc;
> -    }
> -
> -    mem->size = size;
> -    mem->offset = mem->buffer->offset;
> -    return Success;
> -}
> -
> -static void free_drm_memory(ScrnInfoPtr pScrn,
> -		struct drm_memory_block *mem)
> -{
> -    I830Ptr pI830 = I830PTR(pScrn);
> -    drmRmMap(pI830->drmSubFD, mem->handle);
> -    i830_free_memory(pScrn, mem->buffer);
> -}
> -
>  static int create_context(ScrnInfoPtr pScrn, 
>  	XvMCContextPtr context, int *num_privates, CARD32 **private)
>  {
> @@ -109,30 +76,6 @@ static int create_context(ScrnInfoPtr pS
>      private_context->is_965_q = IS_965_Q(I830);
>      private_context->comm.type = xvmc_driver->flag;
>      private_context->comm.sarea_size = driinfo->SAREASize;
> -    private_context->comm.batchbuffer.offset = xvmc_driver->batch->offset;
> -    private_context->comm.batchbuffer.size = xvmc_driver->batch->size;
> -    private_context->comm.batchbuffer.handle = xvmc_driver->batch_handle;
> -
> -    if (alloc_drm_memory(pScrn, &private_context->static_buffer,
> -		"XVMC static buffers", 
> -		I965_MC_STATIC_BUFFER_SIZE)) {
> -	ErrorF("Unable to allocate and map static buffer for XVMC\n");	
> -	return BadAlloc;
> -    }
> -
> -    if (alloc_drm_memory(pScrn, &private_context->blocks,
> -		"XVMC blocks", blocksize)) {
> -	ErrorF("Unable to allocate and map block buffer for XVMC\n");	
> -	return BadAlloc;
> -    }
> -
> -    if (IS_G4X(I830)) {
> -	if (alloc_drm_memory(pScrn, &private_context->slice,
> -		    "XVMC vld slice", VLD_MAX_SLICE_LEN)) {
> -	    ErrorF("Unable to allocate and vld slice buffer for XVMC\n");	
> -	    return BadAlloc;
> -	}
> -    }
>  
>      *num_privates = sizeof(*private_context)/sizeof(CARD32);
>      *private = (CARD32 *)private_context;
> @@ -145,12 +88,7 @@ static int create_context(ScrnInfoPtr pS
>  static void destroy_context(ScrnInfoPtr pScrn, XvMCContextPtr context)
>  {
>      struct i965_xvmc_context *private_context;
> -    I830Ptr pI830 = I830PTR(pScrn);
>      private_context = context->driver_priv;
> -    free_drm_memory(pScrn, &private_context->static_buffer);
> -    free_drm_memory(pScrn, &private_context->blocks);
> -    if (IS_G4X(pI830))
> -	free_drm_memory(pScrn, &private_context->slice);
>      Xfree(private_context);
>  }
>  
> @@ -161,7 +99,6 @@ static int create_surface(ScrnInfoPtr pS
>  
>  	struct i965_xvmc_surface *priv_surface, *surface_dup;
>  	struct i965_xvmc_context *priv_ctx = ctx->driver_priv;
> -	size_t bufsize = SIZE_YUV420(ctx->width, ctx->height);
>  	int i;
>  	for (i = 0 ; i < I965_MAX_SURFACES; i++) {
>  	    if (priv_ctx->surfaces[i] == NULL) {
> @@ -174,13 +111,10 @@ static int create_surface(ScrnInfoPtr pS
>  		
>  		priv_surface->no = i;
>  		priv_surface->handle = priv_surface;
> +		priv_surface->w = ctx->width;
> +		priv_surface->h = ctx->height;
>  		priv_ctx->surfaces[i] = surface->driver_priv 
>  		    = priv_surface;
> -		if (alloc_drm_memory(pScrn, &priv_surface->buffer,
> -			    "surface buffer\n", (bufsize+0xFFF)&~(0xFFF))) {
> -		        ErrorF("Unable to allocate surface buffer\n");
> -            		return BadAlloc;
> -        	}
>  		memcpy(surface_dup, priv_surface, sizeof(*priv_surface));
>  		*num_priv = sizeof(*priv_surface)/sizeof(CARD32);
>  		*priv = (CARD32 *)surface_dup;
> @@ -202,7 +136,6 @@ static void destory_surface(ScrnInfoPtr 
>  	struct i965_xvmc_surface *priv_surface = surface->driver_priv; 
>  	struct i965_xvmc_context *priv_ctx = ctx->driver_priv;
>  	priv_ctx->surfaces[priv_surface->no] = NULL;
> -	free_drm_memory(pScrn, &priv_surface->buffer);
>  	Xfree(priv_surface);
>  }
>  
> @@ -226,21 +159,27 @@ static int put_image(ScrnInfoPtr pScrn,
>  {
>  	I830Ptr pI830 = I830PTR(pScrn);
>  	struct intel_xvmc_command *cmd = (struct intel_xvmc_command *)buf;
> +	dri_bo *bo;
> +
>  	if (id == FOURCC_XVMC) {
> -	    buf = pI830->FbBase + cmd->surf_offset;
> +            bo = intel_bo_gem_create_from_name(pI830->bufmgr, "surface", cmd->handle);
> +            dri_bo_pin(bo, 0x1000);
> +	    buf = pI830->FbBase + bo->offset;
>  	}
>  	XvPutImage(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);
> +
> +	if (id == FOURCC_XVMC) {
> +	    dri_bo_unpin(bo);
> +	    dri_bo_unreference(bo);
> +	}
> +
>  	return Success;
>  }
>  
>  static Bool init(ScrnInfoPtr screen_info, XF86VideoAdaptorPtr adaptor)
>  {
> -    if (!intel_xvmc_init_batch(screen_info)) {
> -	ErrorF("[XvMC] fail to init batch buffer\n");
> -	return FALSE;
> -    }
>      XvPutImage = adaptor->PutImage;
>      adaptor->PutImage = put_image;
>  
> Index: xf86_video_intel/src/xvmc/xvmc_vld.c
> ===================================================================
> --- xf86_video_intel.orig/src/xvmc/xvmc_vld.c
> +++ xf86_video_intel/src/xvmc/xvmc_vld.c
> @@ -35,6 +35,8 @@
>  
>  #define BATCH_STRUCT(x) intelBatchbufferData(&x, sizeof(x), 0)
>  
> +#define VLD_MAX_SLICE_SIZE (32 * 1024)
> +
>  #define CS_SIZE 30
>  #define URB_SIZE 384
>  /* idct table */
> @@ -125,25 +127,96 @@ struct media_kernel {
>  
>  #define MEDIA_KERNEL_NUM (sizeof(media_kernels)/sizeof(media_kernels[0]))
>  
> +struct media_kernel_obj {
> +    dri_bo *bo;
> +};
> +
> +struct interface_descriptor_obj {
> +   dri_bo *bo;
> +   struct media_kernel_obj kernels[MEDIA_KERNEL_NUM];
> +};
> +
> +struct vfe_state_obj {
> +   dri_bo *bo;
> +   struct interface_descriptor_obj interface;
> +};
> +
> +struct vld_state_obj {
> +   dri_bo *bo;
> +};
> +
> +struct surface_obj {
> +     dri_bo *bo; 
> +};
> +
> +struct surface_state_obj {
> +      struct surface_obj surface; 
> +      dri_bo *bo;
> +};
> +
> +struct binding_table_obj {
> +    dri_bo *bo;
> +    struct surface_state_obj surface_states[I965_MAX_SURFACES];
> +};
> +
> +struct slice_data_obj {
> +    dri_bo *bo;
> +};
> +
> +struct cs_state_obj {
> +    dri_bo *bo;
> +};
> +
>  static struct media_state {
> -    unsigned long state_base;
> -    void 	  *state_ptr;
> -    unsigned long vld_state_offset;
> -    unsigned long vfe_state_offset;
> -    unsigned long interface_descriptor_offsets[16];
> -    unsigned long kernel_offsets[MEDIA_KERNEL_NUM];
> -    unsigned long cs_offset;
> -    unsigned long surface_state_offsets[I965_MAX_SURFACES];
> -    unsigned long binding_table_offset;
> +    struct vfe_state_obj vfe_state;
> +    struct vld_state_obj vld_state;
> +    struct binding_table_obj binding_table;
> +    struct cs_state_obj cs_object;
> +    struct slice_data_obj slice_data;
>  } media_state;
>  
> -static int map_buffer(struct drm_memory_block *mem)
> +/* XvMCQMatrix * 2 + idct_table + 8 * kernel offset pointer */
> +#define CS_OBJECT_SIZE (32*20 + sizeof(unsigned int) * 8)
> +static int free_object(struct media_state *s)
>  {
> -    return drmMap(xvmc_driver->fd, mem->handle, mem->size, &mem->ptr);
> +    int i;
> +#define FREE_ONE_BO(bo) \
> +    if (bo) \
> +        dri_bo_unreference(bo)
> +    FREE_ONE_BO(s->vfe_state.bo);
> +    FREE_ONE_BO(s->vfe_state.interface.bo);
> +    for (i = 0; i < MEDIA_KERNEL_NUM; i++)
> +        FREE_ONE_BO(s->vfe_state.interface.kernels[i].bo);
> +    FREE_ONE_BO(s->binding_table.bo);
> +    for (i = 0; i < I965_MAX_SURFACES; i++)
> +        FREE_ONE_BO(s->binding_table.surface_states[i].bo);
> +    FREE_ONE_BO(s->slice_data.bo);
> +    FREE_ONE_BO(s->cs_object.bo);
> +    FREE_ONE_BO(s->vld_state.bo);
>  }
> -static void unmap_buffer(struct drm_memory_block *mem)
> +
> +static int alloc_object(struct media_state *s)
>  {
> -    drmUnmap(mem->ptr, mem->size);
> +    int i;
> +
> +    for (i = 0; i < MEDIA_KERNEL_NUM; i++) {
> +        s->vfe_state.interface.kernels[i].bo =
> +		dri_bo_alloc(xvmc_driver->bufmgr, "kernel",
> +			media_kernels[i].size, 0x1000);
> +        if (!s->vfe_state.interface.kernels[i].bo)
> +            goto out;
> +    }
> +    for (i = 0; i < I965_MAX_SURFACES; i++) {
> +        s->binding_table.surface_states[i].bo =
> +            dri_bo_alloc(xvmc_driver->bufmgr, "surface_state", 
> + 		sizeof(struct brw_surface_state), 0x1000);
> +        if (!s->binding_table.surface_states[i].bo)
> +            goto out;
> +    }
> +    return 0;
> +out:
> +    free_object(s);
> +    return BadAlloc;
>  }
>  
>  static void flush()
> @@ -156,47 +229,9 @@ static void flush()
>      BATCH_STRUCT(f);
>  }
>  
> -static void calc_state_layout()
> -{
> -  int i;
> -  media_state.vld_state_offset = media_state.state_base;
> -  media_state.vfe_state_offset = 
> -      ALIGN(media_state.vld_state_offset + sizeof(struct brw_vld_state), 64);
> -  media_state.interface_descriptor_offsets[0] =
> -      ALIGN(media_state.vfe_state_offset + sizeof(struct brw_vfe_state), 64);
> -  for (i = 1; i < 16; i++)
> -      media_state.interface_descriptor_offsets[i] =
> -	  media_state.interface_descriptor_offsets[i - 1] 
> -	  + sizeof(struct brw_interface_descriptor);
> -  media_state.binding_table_offset = 
> -	  ALIGN(media_state.interface_descriptor_offsets[15] + 
> -	  + sizeof(struct brw_interface_descriptor), 64);
> -  media_state.surface_state_offsets[0] = ALIGN(media_state.binding_table_offset 
> -	  + 4*I965_MAX_SURFACES, 32);
> -  for (i = 1; i < I965_MAX_SURFACES; i++)
> -      media_state.surface_state_offsets[i] = 
> -	  ALIGN(media_state.surface_state_offsets[i-1]
> -		  + sizeof(struct brw_surface_state), 32);
> -
> -  media_state.kernel_offsets[0] = 
> -      ALIGN(media_state.surface_state_offsets[I965_MAX_SURFACES - 1]
> -	      + sizeof(struct brw_surface_state), 64);
> -  for (i = 1; i < MEDIA_KERNEL_NUM; i++)
> -      media_state.kernel_offsets[i] = 
> -	  ALIGN(media_state.kernel_offsets[i-1] + media_kernels[i-1].size, 64);
> -  media_state.cs_offset = ALIGN(media_state.kernel_offsets[MEDIA_KERNEL_NUM-1]
> -	  + media_kernels[MEDIA_KERNEL_NUM-1].size, 64);
> -}
> -
> -static void *offset_to_ptr(unsigned long offset)
> -{
> -    return media_state.state_ptr + (offset - media_state.state_base);
> -}
> -
> -static void vfe_state()
> +static Status vfe_state()
>  {
> -  struct brw_vfe_state *vfe_state;
> -  vfe_state = offset_to_ptr(media_state.vfe_state_offset);
> +  struct brw_vfe_state tmp, *vfe_state = &tmp;
>    memset(vfe_state, 0, sizeof(*vfe_state));
>    vfe_state->vfe0.extend_vfe_state_present = 1;
>    vfe_state->vfe1.vfe_mode = VFE_VLD_MODE;
> @@ -204,59 +239,134 @@ static void vfe_state()
>    vfe_state->vfe1.children_present = 0;
>    vfe_state->vfe1.urb_entry_alloc_size = 2;
>    vfe_state->vfe1.max_threads = 31;
> +  vfe_state->vfe2.interface_descriptor_base =
> +      media_state.vfe_state.interface.bo->offset >> 4;
> +
> +    if (media_state.vfe_state.bo)
> +        dri_bo_unreference(media_state.vfe_state.bo);
>  
> -  vfe_state->vfe2.interface_descriptor_base = 
> -      media_state.interface_descriptor_offsets[0] >> 4;
> +    media_state.vfe_state.bo = dri_bo_alloc(xvmc_driver->bufmgr,
> +        "vfe state", sizeof(struct brw_vfe_state), 0x1000);
> +    if (!media_state.vfe_state.bo)
> +        return BadAlloc;
> +
> +    dri_bo_subdata(media_state.vfe_state.bo, 0, sizeof(tmp), &tmp);
> +
> +    dri_bo_emit_reloc(media_state.vfe_state.bo,
> +	I915_GEM_DOMAIN_INSTRUCTION, 0, 0,
> +	offsetof(struct brw_vfe_state, vfe2),
> +	media_state.vfe_state.interface.bo);
> +    return Success;
>  }
>  
> -static void interface_descriptor()
> +static Status interface_descriptor()
>  {
>      int i;
> -    struct brw_interface_descriptor *desc;
> +    struct brw_interface_descriptor tmp, *desc = &tmp;
> +
> +    if (media_state.vfe_state.interface.bo)
> +        dri_bo_unreference(media_state.vfe_state.interface.bo);
> +
> +    media_state.vfe_state.interface.bo = dri_bo_alloc(xvmc_driver->bufmgr,
> +        "interfaces", MEDIA_KERNEL_NUM*sizeof(struct brw_interface_descriptor),
> +	    0x1000);
> +    if (!media_state.vfe_state.interface.bo)
> +        return BadAlloc;
> +
>      for (i = 0; i < MEDIA_KERNEL_NUM; i++) {
> -	desc = offset_to_ptr(media_state.interface_descriptor_offsets[i]);
>  	memset(desc, 0, sizeof(*desc));
>  	desc->desc0.grf_reg_blocks = 15;
> -	desc->desc0.kernel_start_pointer = media_state.kernel_offsets[i] >> 6;
> +	desc->desc0.kernel_start_pointer =
> +            media_state.vfe_state.interface.kernels[i].bo->offset >> 6;
>  
>  	desc->desc1.const_urb_entry_read_offset = 0;
>  	desc->desc1.const_urb_entry_read_len = 30;
>  
>  	desc->desc3.binding_table_entry_count = I965_MAX_SURFACES - 1;
> -	desc->desc3.binding_table_pointer = media_state.binding_table_offset>>5;
> +	desc->desc3.binding_table_pointer =
> +            media_state.binding_table.bo->offset >> 5;
> +
> +        dri_bo_subdata(media_state.vfe_state.interface.bo, i*sizeof(tmp), sizeof(tmp), desc);
> +
> +        dri_bo_emit_reloc(
> +	    media_state.vfe_state.interface.bo,
> +	    I915_GEM_DOMAIN_INSTRUCTION, 0,
> +	    desc->desc0.grf_reg_blocks,
> +	    i * sizeof(*desc) + 
> +	    offsetof(struct brw_interface_descriptor, desc0),
> +	    media_state.vfe_state.interface.kernels[i].bo);
> +
> +       dri_bo_emit_reloc(
> +	    media_state.vfe_state.interface.bo,
> +	    I915_GEM_DOMAIN_INSTRUCTION, 0,
> +	    desc->desc3.binding_table_entry_count,
> +	    i * sizeof(*desc) + 
> +	    offsetof(struct brw_interface_descriptor, desc3),
> +	    media_state.binding_table.bo);
>      }
> +    return Success;
>  }
>  
>  static void setup_media_kernels()
>  {
>      int i;
> -    void *kernel_ptr;
>      for (i = 0; i < MEDIA_KERNEL_NUM; i++) {
> -	kernel_ptr = offset_to_ptr(media_state.kernel_offsets[i]);
> -	memcpy(kernel_ptr, media_kernels[i].bin, media_kernels[i].size);
> +        dri_bo *bo = media_state.vfe_state.interface.kernels[i].bo;
> +        dri_bo_subdata(bo, 0, media_kernels[i].size, media_kernels[i].bin);
>      }
>  }
>  
> -static void binding_tables()
> +static Status binding_tables()
>  {
> -   unsigned int *table;
> +   unsigned int table[I965_MAX_SURFACES];
>     int i;
> -   table = offset_to_ptr(media_state.binding_table_offset);
> -   for (i = 0; i < I965_MAX_SURFACES; i++)
> -       table[i] = media_state.surface_state_offsets[i];
> +
> +   if (media_state.binding_table.bo)
> +       dri_bo_unreference(media_state.binding_table.bo);
> +   media_state.binding_table.bo = 
> +	dri_bo_alloc(xvmc_driver->bufmgr, "binding_table", 
> +		I965_MAX_SURFACES*4, 0x1000);
> +   if (!media_state.binding_table.bo)
> +       return BadAlloc;
> +
> +   for (i = 0; i < I965_MAX_SURFACES; i++) {
> +       table[i] = media_state.binding_table.surface_states[i].bo->offset;
> +       dri_bo_emit_reloc(media_state.binding_table.bo, 
> +	    I915_GEM_DOMAIN_INSTRUCTION, 0, 0,
> +	    i * sizeof(unsigned int),
> +	    media_state.binding_table.surface_states[i].bo);
> +   }
> +
> +   dri_bo_subdata(media_state.binding_table.bo, 0, sizeof(table), table);
> +   return Success;
>  }
>  
> -static void cs_init()
> +static Status cs_init()
>  {
> -   void *buf;
> +   char buf[CS_OBJECT_SIZE];
>     unsigned int *lib_reloc;
>     int i;
> -   buf = offset_to_ptr(media_state.cs_offset);
> +
> +   if (media_state.cs_object.bo)
> +       dri_bo_unreference(media_state.cs_object.bo);
> +
> +   media_state.cs_object.bo = dri_bo_alloc(xvmc_driver->bufmgr, "cs object", CS_OBJECT_SIZE, 64);
> +   if (!media_state.cs_object.bo)
> +       return BadAlloc;
> +
>     memcpy(buf + 32*4, idct_table, sizeof(idct_table));
>     /* idct lib reloction */
> -   lib_reloc = buf + 32*20;
> +   lib_reloc = (unsigned int *)(buf + 32*20);
> +   for (i = 0; i < 8; i++)
> +       lib_reloc[i] = media_state.vfe_state.interface.kernels[LIB_INTERFACE].bo->offset;
> +   dri_bo_subdata(media_state.cs_object.bo, 32*4, 32*16 + 8*sizeof(unsigned int), buf + 32*4);
> +
>     for (i = 0; i < 8; i++)
> -       lib_reloc[i] = media_state.kernel_offsets[LIB_INTERFACE];
> +       dri_bo_emit_reloc(media_state.cs_object.bo, I915_GEM_DOMAIN_INSTRUCTION,
> +           0, 0,
> +           32*20 + sizeof(unsigned int) * i,
> +           media_state.vfe_state.interface.kernels[LIB_INTERFACE].bo);
> +   return Success;
>  }
>  
>  static Status create_context(Display *display, XvMCContext *context,
> @@ -265,18 +375,11 @@ static Status create_context(Display *di
>      struct i965_xvmc_context *i965_ctx;
>      i965_ctx = (struct i965_xvmc_context *)priv_data;
>      context->privData = priv_data;
> -    if (map_buffer(&i965_ctx->static_buffer))
> -	return BadAlloc;
> -    if (map_buffer(&i965_ctx->slice))
> -	return BadAlloc;
> -    media_state.state_base = i965_ctx->static_buffer.offset;
> -    media_state.state_ptr = i965_ctx->static_buffer.ptr;
> -    calc_state_layout();
> -    vfe_state();
> -    interface_descriptor();
> +
> +    if (alloc_object(&media_state))
> +        return BadAlloc;
> +
>      setup_media_kernels();
> -    binding_tables();
> -    cs_init();
>      return Success;
>  }
>  
> @@ -284,34 +387,45 @@ static Status destroy_context(Display *d
>  {
>      struct i965_xvmc_context *i965_ctx;
>      i965_ctx = context->privData;
> -    unmap_buffer(&i965_ctx->slice);
> -    unmap_buffer(&i965_ctx->static_buffer);
>      Xfree(i965_ctx);
>      return Success;
>  }
>  
> +#define STRIDE(w)               (w)
> +#define SIZE_YUV420(w, h)       (h * (STRIDE(w) + STRIDE(w >> 1)))
>  static Status create_surface(Display *display,
>  	XvMCContext *context, XvMCSurface *surface, int priv_count,
>  	CARD32 *priv_data)
>  {
> -    struct i965_xvmc_surface *x; 
> +    struct i965_xvmc_surface *priv_surface =
> +	(struct i965_xvmc_surface *)priv_data;
> +    size_t size = SIZE_YUV420(priv_surface->w, priv_surface->h);
>      surface->privData = priv_data;
> -    x = surface->privData;
> +    priv_surface->bo = dri_bo_alloc(xvmc_driver->bufmgr, "surface", 
> +	    size, 0x1000);
> +
>      return Success;
>  }
>  static Status destroy_surface(Display *display,
>  	XvMCSurface *surface)
>  {
> +    struct i965_xvmc_surface *priv_surface = 
> +	surface->privData;
> +    XSync(display, False);
> +    dri_bo_unreference(priv_surface->bo);
>      return Success;
>  }
>  
>  static Status load_qmatrix(Display *display, XvMCContext *context,
>  	const XvMCQMatrix *qmx)
>  {
> -    unsigned char *qmatrix;
> -    qmatrix = offset_to_ptr(media_state.cs_offset);
> -    memcpy(qmatrix, qmx->intra_quantiser_matrix, 64);
> -    memcpy(qmatrix + 64, qmx->non_intra_quantiser_matrix, 64);
> +    Status ret;
> +    ret = cs_init();
> +    if (ret != Success)
> +        return ret;
> +    dri_bo_subdata(media_state.cs_object.bo, 0, 64, qmx->intra_quantiser_matrix);
> +    dri_bo_subdata(media_state.cs_object.bo, 64, 64, qmx->non_intra_quantiser_matrix);
> +
>      return Success;
>  }
>  
> @@ -322,12 +436,18 @@ static Status get_surface_status(Display
>      return Success;
>  }
>  
> -static void vld_state(const XvMCMpegControl *control)
> +static Status vld_state(const XvMCMpegControl *control)
>  {
> -    struct brw_vld_state *vld;
> -    vld = offset_to_ptr(media_state.vld_state_offset);
> -    memset(vld, 0, sizeof(*vld));
> +    struct brw_vld_state tmp, *vld = &tmp;
> +
> +    if (media_state.vld_state.bo)
> +        dri_bo_unreference(media_state.vld_state.bo);
> +    media_state.vld_state.bo = dri_bo_alloc(xvmc_driver->bufmgr, 
> +	    "vld state", sizeof(struct brw_vld_state), 64);
> +    if (!media_state.vld_state.bo)
> +        return BadAlloc;
>  
> +    memset(vld, 0, sizeof(*vld));
>      vld->vld0.f_code_0_0 = control->FHMV_range + 1;
>      vld->vld0.f_code_0_1 = control->FVMV_range + 1;
>      vld->vld0.f_code_1_0 = control->BHMV_range + 1;
> @@ -362,44 +482,81 @@ static void vld_state(const XvMCMpegCont
>      vld->desc_remap_table1.index_13 = FIELD_BACKWARD_INTERFACE;
>      vld->desc_remap_table1.index_14 = F_B_INTERFACE;
>      vld->desc_remap_table1.index_15 = FIELD_F_B_INTERFACE;
> +
> +    dri_bo_subdata(media_state.vld_state.bo, 0, sizeof(tmp), vld);
> +    return Success;
>  }
>  
> -static void setup_media_surface(int binding_table_index, 
> -	unsigned long offset, int w, int h)
> +static Status setup_media_surface(int index, dri_bo *bo,
> +	unsigned long offset, int w, int h, Bool write)
>  {
> -    struct brw_surface_state *ss;
> -    ss = offset_to_ptr(media_state.surface_state_offsets[binding_table_index]);
> +    struct brw_surface_state tmp, *ss = &tmp;
>      memset(ss, 0, sizeof(*ss)); 
>      ss->ss0.surface_type = BRW_SURFACE_2D;
>      ss->ss0.surface_format = BRW_SURFACEFORMAT_R8_SINT;
> -    ss->ss1.base_addr = offset;
> +    ss->ss1.base_addr = offset + bo->offset;
>      ss->ss2.width = w - 1;
>      ss->ss2.height = h - 1;
>      ss->ss3.pitch = w - 1;
> +
> +    if (media_state.binding_table.surface_states[index].bo)
> +        dri_bo_unreference(media_state.binding_table.surface_states[index].bo);
> +
> +    media_state.binding_table.surface_states[index].bo =
> +            dri_bo_alloc(xvmc_driver->bufmgr, "surface_state", 
> + 		sizeof(struct brw_surface_state), 0x1000);
> +    if (!media_state.binding_table.surface_states[index].bo)
> +        return BadAlloc;
> +
> +    dri_bo_subdata(
> +	    media_state.binding_table.surface_states[index].bo,
> +	    0, sizeof(*ss), ss);
> +    dri_bo_emit_reloc(media_state.binding_table.surface_states[index].bo, 
> +	    I915_GEM_DOMAIN_RENDER, write?I915_GEM_DOMAIN_RENDER:0, 
> +	    offset,
> +	    offsetof(struct brw_surface_state, ss1),
> +	    bo);
> +    return Success;
>  }
>  
> -static void setup_surface(struct i965_xvmc_surface *target,
> +static Status setup_surface(struct i965_xvmc_surface *target,
>  	 struct i965_xvmc_surface *past,
>  	 struct i965_xvmc_surface *future,
>  	 int w, int h)
>  {
> -    unsigned long dst_offset, past_offset, future_offset;
> -    dst_offset = target->buffer.offset;
> -    setup_media_surface(0, dst_offset, w, h);
> -    setup_media_surface(1, dst_offset + w*h, w/2, h/2);
> -    setup_media_surface(2, dst_offset + w*h + w*h/4, w/2, h/2);
> +    Status ret;
> +    ret = setup_media_surface(0, target->bo, 0, w, h, TRUE);
> +    if (ret != Success)
> +        return ret;
> +    ret = setup_media_surface(1, target->bo, w*h, w/2, h/2, TRUE);
> +    if (ret != Success)
> +        return ret;
> +    ret = setup_media_surface(2, target->bo, w*h + w*h/4, w/2, h/2, TRUE);
> +    if (ret != Success)
> +        return ret;
>      if (past) {
> -	past_offset = past->buffer.offset;
> -	setup_media_surface(4, past_offset, w, h);
> -	setup_media_surface(5, past_offset + w*h, w/2, h/2);
> -	setup_media_surface(6, past_offset + w*h + w*h/4, w/2, h/2);
> +	ret = setup_media_surface(4, past->bo, 0, w, h, FALSE);
> +        if (ret != Success)
> +            return ret;
> +	ret = setup_media_surface(5, past->bo, w*h, w/2, h/2, FALSE);
> +        if (ret != Success)
> +            return ret;
> +	ret = setup_media_surface(6, past->bo, w*h + w*h/4, w/2, h/2, FALSE);
> +        if (ret != Success)
> +            return ret;
>      }
>      if (future) {
> -	future_offset = future->buffer.offset;
> -	setup_media_surface(7, future_offset, w, h);
> -	setup_media_surface(8, future_offset + w*h, w/2, h/2);
> -	setup_media_surface(9, future_offset + w*h + w*h/4, w/2, h/2);
> +	ret = setup_media_surface(7, future->bo, 0, w, h, FALSE);
> +        if (ret != Success)
> +            return ret;
> +	ret = setup_media_surface(8, future->bo, w*h, w/2, h/2, FALSE);
> +        if (ret != Success)
> +            return ret;
> +	ret = setup_media_surface(9, future->bo, w*h + w*h/4, w/2, h/2, FALSE);
> +        if (ret != Success)
> +            return ret;
>      }
> +    return Success;
>  }
>  
>  static  Status begin_surface(Display *display, XvMCContext *context,
> @@ -411,13 +568,30 @@ static  Status begin_surface(Display *di
>      struct i965_xvmc_contex *i965_ctx;
>      struct i965_xvmc_surface *priv_target, *priv_past, *priv_future;
>      intel_xvmc_context_ptr intel_ctx;
> +    Status ret;
> +
>      intel_ctx = intel_xvmc_find_context(context->context_id);
>      priv_target = target->privData;
>      priv_past = past?past->privData:NULL;
>      priv_future = future?future->privData:NULL;
> -    vld_state(control);
> -    setup_surface(priv_target, priv_past, priv_future, 
> +
> +    ret = vld_state(control);
> +    if (ret != Success)
> +        return ret;
> +    ret = setup_surface(priv_target, priv_past, priv_future, 
>  	    context->width, context->height);
> +    if (ret != Success)
> +        return ret;
> +    ret = binding_tables();
> +    if (ret != Success)
> +        return ret;
> +    ret = interface_descriptor();
> +    if (ret != Success)
> +        return ret;
> +    ret = vfe_state();
> +    if (ret != Success)
> +        return ret;
> +
>      LOCK_HARDWARE(intel_ctx->hw_context);
>      flush();
>      UNLOCK_HARDWARE(intel_ctx->hw_context);
> @@ -455,8 +629,8 @@ static void media_state_pointers()
>      BATCH_LOCALS;
>      BEGIN_BATCH(3);
>      OUT_BATCH(BRW_MEDIA_STATE_POINTERS|1);
> -    OUT_BATCH(media_state.vld_state_offset|1);
> -    OUT_BATCH(media_state.vfe_state_offset);
> +    OUT_RELOC(media_state.vld_state.bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 1);
> +    OUT_RELOC(media_state.vfe_state.bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
>      ADVANCE_BATCH();
>  }
>  static void align_urb_fence()
> @@ -513,11 +687,11 @@ static void cs_buffer()
>      BATCH_LOCALS;
>      BEGIN_BATCH(2);
>      OUT_BATCH(BRW_CONSTANT_BUFFER|0|(1<<8));
> -    OUT_BATCH(media_state.cs_offset|CS_SIZE);
> +    OUT_RELOC(media_state.cs_object.bo, I915_GEM_DOMAIN_INSTRUCTION, 0, CS_SIZE);
>      ADVANCE_BATCH();
>  }
>  
> -static void vld_send_media_object(unsigned long slice_offset,
> +static void vld_send_media_object(dri_bo *bo,
>  	int slice_len, int mb_h_pos, int mb_v_pos, int mb_bit_offset,
>  	int mb_count, int q_scale_code)
>  {
> @@ -526,11 +700,12 @@ static void vld_send_media_object(unsign
>      OUT_BATCH(BRW_MEDIA_OBJECT|4);
>      OUT_BATCH(0);
>      OUT_BATCH(slice_len);
> -    OUT_BATCH(slice_offset);
> +    OUT_RELOC(bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
>      OUT_BATCH((mb_h_pos<<24)|(mb_v_pos<<16)|(mb_count<<8)|(mb_bit_offset));
>      OUT_BATCH(q_scale_code<<24);
>      ADVANCE_BATCH();
>  }
> +
>  static Status put_slice2(Display *display, XvMCContext *context, 
>  	unsigned char *slice, int nbytes, int sliceCode)
>  {
> @@ -545,9 +720,17 @@ static Status put_slice2(Display *displa
>  
>      q_scale_code = bit_buf>>27;
>  
> -    memcpy(i965_ctx->slice.ptr, slice, nbytes);
> -    intel_ctx = intel_xvmc_find_context(context->context_id);
> +    if (media_state.slice_data.bo)
> +        dri_bo_unreference(media_state.slice_data.bo);
> +    media_state.slice_data.bo = dri_bo_alloc(xvmc_driver->bufmgr, 
> +	    "slice data", VLD_MAX_SLICE_SIZE, 64);
> +    if (!media_state.slice_data.bo)
> +        return BadAlloc;
> +    drm_intel_gem_bo_map_gtt(media_state.slice_data.bo);
>  
> +    memcpy(media_state.slice_data.bo->virtual, slice, nbytes);
> +
> +    intel_ctx = intel_xvmc_find_context(context->context_id);
>      LOCK_HARDWARE(intel_ctx->hw_context);
>      state_base_address();
>      pipeline_select(&media_state);
> @@ -555,7 +738,7 @@ static Status put_slice2(Display *displa
>      urb_layout();	
>      cs_urb_layout();
>      cs_buffer();
> -    vld_send_media_object(i965_ctx->slice.offset, 
> +    vld_send_media_object(media_state.slice_data.bo,
>  	    nbytes, 
>  	    0, mb_row, 6, 127, q_scale_code);
>      intelFlushBatch(TRUE);
> @@ -573,8 +756,10 @@ static Status put_surface(Display *displ
>  {
>  	struct i965_xvmc_surface *private_surface =
>  		surface->privData;
> +        uint32_t handle;
>  
> -	data->surf_offset = private_surface->buffer.offset;
> +        dri_bo_flink(private_surface->bo, &handle);
> +        data->handle = handle;
>  	return Success;
>  }
>  
> Index: xf86_video_intel/src/xvmc/Makefile.am
> ===================================================================
> --- xf86_video_intel.orig/src/xvmc/Makefile.am
> +++ xf86_video_intel/src/xvmc/Makefile.am
> @@ -32,4 +32,4 @@ libIntelXvMC_la_SOURCES = intel_xvmc.c \
>  libIntelXvMC_la_CFLAGS = @XORG_CFLAGS@ @DRM_CFLAGS@ @DRI_CFLAGS@ \
>  	@XVMCLIB_CFLAGS@ -I$(top_srcdir)/src -DTRUE=1 -DFALSE=0
>  libIntelXvMC_la_LDFLAGS = -version-number 1:0:0
> -libIntelXvMC_la_LIBADD = @DRI_LIBS@ @DRM_LIBS@ @XVMCLIB_LIBS@ @XEXT_LIBS@ -lpthread
> +libIntelXvMC_la_LIBADD = @DRI_LIBS@ @DRM_LIBS@ @XVMCLIB_LIBS@ @XEXT_LIBS@ -lpthread -ldrm_intel
> Index: xf86_video_intel/src/i830_hwmc.h
> ===================================================================
> --- xf86_video_intel.orig/src/i830_hwmc.h
> +++ xf86_video_intel/src/i830_hwmc.h
> @@ -77,7 +77,7 @@ struct intel_xvmc_command {
>      unsigned int subPicNo;
>      unsigned int flags;
>      unsigned int real_id;
> -    unsigned int surf_offset;
> +    uint32_t handle;
>      unsigned int pad[5];
>  };
>  
> 
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
-- 
Eric Anholt
eric at anholt.net                         eric.anholt at intel.com


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 197 bytes
Desc: This is a digitally signed message part
URL: <http://lists.freedesktop.org/archives/intel-gfx/attachments/20090428/1dc14e11/attachment.sig>


More information about the Intel-gfx mailing list