diff options
-rw-r--r-- | src/i830_hwmc.h | 3 | ||||
-rw-r--r-- | src/i965_hwmc.c | 90 | ||||
-rw-r--r-- | src/i965_hwmc.h | 3 | ||||
-rw-r--r-- | src/xvmc/Makefile.am | 2 | ||||
-rw-r--r-- | src/xvmc/i965_xvmc.c | 634 | ||||
-rw-r--r-- | src/xvmc/intel_batchbuffer.c | 234 | ||||
-rw-r--r-- | src/xvmc/intel_batchbuffer.h | 10 | ||||
-rw-r--r-- | src/xvmc/intel_xvmc.c | 16 | ||||
-rw-r--r-- | src/xvmc/intel_xvmc.h | 10 | ||||
-rw-r--r-- | src/xvmc/xvmc_vld.c | 457 |
10 files changed, 815 insertions, 644 deletions
diff --git a/src/i830_hwmc.h b/src/i830_hwmc.h index ad95e1e5..7db6a86a 100644 --- a/src/i830_hwmc.h +++ b/src/i830_hwmc.h @@ -66,6 +66,7 @@ struct hwmc_buffer struct _intel_xvmc_common { unsigned int type; struct hwmc_buffer batchbuffer; + unsigned int kernel_exec_fencing:1; }; /* Intel private XvMC command to DDX driver */ @@ -76,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]; }; diff --git a/src/i965_hwmc.c b/src/i965_hwmc.c index efcdf127..4dc2e3ac 100644 --- a/src/i965_hwmc.c +++ b/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) { @@ -106,31 +73,8 @@ static int create_context(ScrnInfoPtr pScrn, private_context->is_g4x = IS_G4X(I830); private_context->is_965_q = IS_965_Q(I830); + private_context->comm.kernel_exec_fencing = I830->kernel_exec_fencing; private_context->comm.type = xvmc_driver->flag; - 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; @@ -143,12 +87,7 @@ static int create_context(ScrnInfoPtr pScrn, 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); } @@ -159,7 +98,6 @@ static int create_surface(ScrnInfoPtr pScrn, XvMCSurfacePtr surface, 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) { @@ -172,13 +110,10 @@ static int create_surface(ScrnInfoPtr pScrn, XvMCSurfacePtr surface, 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; @@ -200,7 +135,6 @@ static void destory_surface(ScrnInfoPtr pScrn, XvMCSurfacePtr surface) 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); } @@ -224,21 +158,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; diff --git a/src/i965_hwmc.h b/src/i965_hwmc.h index 9db0f359..fb61516c 100644 --- a/src/i965_hwmc.h +++ b/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 { diff --git a/src/xvmc/Makefile.am b/src/xvmc/Makefile.am index 45670605..fc402bb4 100644 --- a/src/xvmc/Makefile.am +++ b/src/xvmc/Makefile.am @@ -31,4 +31,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 diff --git a/src/xvmc/i965_xvmc.c b/src/xvmc/i965_xvmc.c index 4b1c4812..51a7ae63 100644 --- a/src/xvmc/i965_xvmc.c +++ b/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,137 @@ static const uint32_t dual_prime_igd_kernel_static[][4]= { #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) drm_intel_bo_unreference(bo) + 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) { - drmUnmap(mem->ptr, mem->size); + int i; + + for (i = 0; i < MAX_SURFACE_NUM; i++) { + s->binding_table.surface_states[i].bo = + drm_intel_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 = drm_intel_bo_alloc(xvmc_driver->bufmgr, "surface", + size, 0x1000); return Success; } @@ -160,7 +234,9 @@ static Status destroy_surface(Display *display, XvMCSurface *surface) { struct i965_xvmc_surface *priv_surface = surface->privData; - unmap_buffer(&priv_surface->buffer); + XSync(display, False); + + drm_intel_bo_unreference(priv_surface->bo); return Success; } @@ -206,21 +282,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 +290,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 +302,89 @@ static void media_state_pointers(struct media_state *media_state) 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) + drm_intel_bo_unreference(media_state->binding_table.surface_states[surface_num].bo); + media_state->binding_table.surface_states[surface_num].bo = + drm_intel_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; + + drm_intel_bo_subdata( + media_state->binding_table.surface_states[surface_num].bo, + 0, sizeof(*ss), ss); + + drm_intel_bo_emit_reloc(media_state->binding_table.surface_states[surface_num].bo, + offsetof(struct brw_surface_state, ss1), + bo, + offset, + I915_GEM_DOMAIN_RENDER, write?I915_GEM_DOMAIN_RENDER:0); + + 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); + 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_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); + 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 +395,39 @@ static void setup_blocks(struct media_state *media_state, }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) + drm_intel_bo_unreference(media_state->binding_table.surface_states[3].bo); + + media_state->binding_table.surface_states[3].bo = + drm_intel_bo_alloc(xvmc_driver->bufmgr, "surface_state", + sizeof(struct brw_surface_state), 0x1000); + if (!media_state->binding_table.surface_states[3].bo) + return BadAlloc; + + drm_intel_bo_subdata(media_state->binding_table.surface_states[3].bo, 0, + sizeof(ss), &ss); + + drm_intel_bo_emit_reloc(media_state->binding_table.surface_states[3].bo, + offsetof(struct brw_surface_state, ss1), + media_state->indirect_data.bo, 0, + I915_GEM_DOMAIN_SAMPLER, 0); + 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 +436,7 @@ static void state_base_address(int offset) 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 +464,13 @@ static void send_media_object(XvMCMacroBlock *mb, int offset, enum interface int OUT_BATCH(0); }else { OUT_BATCH(6*128); - OUT_BATCH(offset); + OUT_RELOC(media_state.indirect_data.bo, I915_GEM_DOMAIN_INSTRUCTION, 0, offset); } 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 +491,152 @@ static void send_media_object(XvMCMacroBlock *mb, int offset, enum interface int 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) + drm_intel_bo_unreference(media_state->binding_table.bo); + media_state->binding_table.bo = + drm_intel_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; + drm_intel_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]; + drm_intel_bo_emit_reloc(media_state->binding_table.bo, + i * sizeof(unsigned int), + media_state->binding_table.surface_states[i].bo, 0, + I915_GEM_DOMAIN_INSTRUCTION, 0); + return Success; } -static void media_kernels(struct media_state *media_state) +static int 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); + struct kernel_struct *kernels; + int kernel_array_size, i; + 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); + 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++) { + media_state->vfe_state.interface.kernels[i].bo = + drm_intel_bo_alloc(xvmc_driver->bufmgr, "kernel", + kernels[i].size, 0x1000); + if (!media_state->vfe_state.interface.kernels[i].bo) + goto out; } + + for (i = 0; i < kernel_array_size; i++) { + dri_bo *bo = media_state->vfe_state.interface.kernels[i].bo; + drm_intel_bo_subdata(bo, 0, kernels[i].size, kernels[i].bin); + } + return 0; +out: + free_object(media_state); + return BadAlloc; } 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; + + drm_intel_bo_subdata(media_state->vfe_state.interface.bo, i*sizeof(desc), + sizeof(desc), &desc); + + drm_intel_bo_emit_reloc( + media_state->vfe_state.interface.bo, + i * sizeof(desc) + + offsetof(struct brw_interface_descriptor, desc0), + media_state->vfe_state.interface.kernels[i].bo, + desc.desc0.grf_reg_blocks, + I915_GEM_DOMAIN_INSTRUCTION, 0); + + drm_intel_bo_emit_reloc( + media_state->vfe_state.interface.bo, + i * sizeof(desc) + + offsetof(struct brw_interface_descriptor, desc3), + media_state->binding_table.bo, + desc.desc3.binding_table_entry_count, + I915_GEM_DOMAIN_INSTRUCTION, 0); } -static void interface_descriptor(struct media_state *media_state) +static Status interface_descriptor(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); + if (media_state->vfe_state.interface.bo) + drm_intel_bo_unreference(media_state->vfe_state.interface.bo); + media_state->vfe_state.interface.bo = drm_intel_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; } -static void vfe_state(struct media_state *media_state) +static Status 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) + drm_intel_bo_unreference(media_state->vfe_state.bo); + media_state->vfe_state.bo = drm_intel_bo_alloc(xvmc_driver->bufmgr, + "vfe state", sizeof(struct brw_vfe_state), 0x1000); + if (!media_state->vfe_state.bo) + return BadAlloc; + + drm_intel_bo_subdata(media_state->vfe_state.bo, 0, sizeof(state), &state); + + drm_intel_bo_emit_reloc(media_state->vfe_state.bo, + offsetof(struct brw_vfe_state, vfe2), + media_state->vfe_state.interface.bo, 0, + I915_GEM_DOMAIN_INSTRUCTION, 0); + return Success; } static Status render_surface(Display *display, @@ -588,13 +669,35 @@ static Status render_surface(Display *display, XVMC_ERR("Can't find intel xvmc context\n"); return BadValue; } + + if (media_state.indirect_data.bo) { + if (xvmc_driver->kernel_exec_fencing) + drm_intel_gem_bo_unmap_gtt(media_state.indirect_data.bo); + else + drm_intel_bo_unmap(media_state.indirect_data.bo); + + drm_intel_bo_unreference(media_state.indirect_data.bo); + } + media_state.indirect_data.bo = drm_intel_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); + + if (xvmc_driver->kernel_exec_fencing) + drm_intel_gem_bo_map_gtt(media_state.indirect_data.bo); + else + drm_intel_bo_map(media_state.indirect_data.bo, 1); - block_ptr = i965_ctx->blocks.ptr; + 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 +738,15 @@ static Status render_surface(Display *display, 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 +798,11 @@ static Status put_surface(Display *display,XvMCSurface *surface, { struct i965_xvmc_surface *private_surface = surface->privData; + uint32_t handle = 0; + + drm_intel_bo_flink(private_surface->bo, &handle); + data->handle = handle; - data->surf_offset = private_surface->buffer.offset; return Success; } @@ -718,25 +819,14 @@ static Status create_context(Display *display, XvMCContext *context, 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)) + return BadAlloc; + if (media_kernels(&media_state)) + return BadAlloc; return Success; } diff --git a/src/xvmc/intel_batchbuffer.c b/src/xvmc/intel_batchbuffer.c index 6d4b496e..02fbd5ae 100644 --- a/src/xvmc/intel_batchbuffer.c +++ b/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 each time, so the size can be small */ static int intelEmitIrqLocked(void) { drmI830IrqEmit ie; @@ -82,192 +83,105 @@ 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"); + int i; + + if((xvmc_driver->batch.buf = + drm_intel_bo_alloc(xvmc_driver->bufmgr, + "batch buffer", BATCH_SIZE, 0x1000)) == NULL) { + fprintf(stderr, "unable to alloc 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; - 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->kernel_exec_fencing) + drm_intel_gem_bo_map_gtt(xvmc_driver->batch.buf); + else + drm_intel_bo_map(xvmc_driver->batch.buf, 1); - xvmc_driver->alloc.active_buf = 0; - assert(xvmc_driver->alloc.ptr); + 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(); -} - -static void intelBatchbufferRequireSpace(unsigned int sz) -{ - if (xvmc_driver->batch.space < sz) - intelFlushBatch(TRUE); -} - -void intelBatchbufferData(const void *data, unsigned bytes, unsigned flags) -{ - assert((bytes & 0x3) == 0); - - intelBatchbufferRequireSpace(bytes); - memcpy(xvmc_driver->batch.ptr, data, bytes); - xvmc_driver->batch.ptr += bytes; - xvmc_driver->batch.space -= bytes; + if (xvmc_driver->kernel_exec_fencing) + drm_intel_gem_bo_unmap_gtt(xvmc_driver->batch.buf); + else + drm_intel_bo_unmap(xvmc_driver->batch.buf); - assert(xvmc_driver->batch.space >= 0); + drm_intel_bo_unreference(xvmc_driver->batch.buf); } -#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 intelFlushBatch(Bool refill ) { - 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(); + i965_end_batch(); + + if (xvmc_driver->kernel_exec_fencing) + drm_intel_gem_bo_unmap_gtt(xvmc_driver->batch.buf); + else + drm_intel_bo_unmap(xvmc_driver->batch.buf); + + drm_intel_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); + + drm_intel_bo_unreference(xvmc_driver->batch.buf); + if((xvmc_driver->batch.buf = + drm_intel_bo_alloc(xvmc_driver->bufmgr, + "batch buffer", BATCH_SIZE, 0x1000)) == NULL) { + fprintf(stderr, "unable to alloc batch buffer\n"); + } - if (xvmc_driver->alloc.irq_emitted) { - intelWaitIrq(xvmc_driver->alloc.irq_emitted); - } + if (xvmc_driver->kernel_exec_fencing) + drm_intel_gem_bo_map_gtt(xvmc_driver->batch.buf); + else + drm_intel_bo_map(xvmc_driver->batch.buf, 1); - 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); + 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; } - -static void intelFlushBatchLocked(Bool ignore_cliprects, - Bool refill, - Bool allow_unlock) +void intelBatchbufferRequireSpace(int size) { - 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); + assert(xvmc_driver->batch.ptr - xvmc_driver->batch.init_ptr + size < + xvmc_driver->batch.size - 8); + 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); - } + drm_intel_bo_emit_reloc(xvmc_driver->batch.buf, + ptr - xvmc_driver->batch.init_ptr, bo, delta, + read_domain, write_domain); } diff --git a/src/xvmc/intel_batchbuffer.h b/src/xvmc/intel_batchbuffer.h index d4d8037a..ea9058ce 100644 --- a/src/xvmc/intel_batchbuffer.h +++ b/src/xvmc/intel_batchbuffer.h @@ -10,6 +10,7 @@ extern int VERBOSE; #define BEGIN_BATCH(n) \ do { \ + assert(xvmc_driver->batch.space >= (n) *4); \ if (xvmc_driver->batch.space < (n)*4) \ intelFlushBatch(TRUE); \ batch_ptr = xvmc_driver->batch.ptr; \ @@ -21,6 +22,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) + #define OUT_BATCH_SHORT(n) \ do { \ *(short *)batch_ptr = (n); \ @@ -44,4 +52,6 @@ extern void intelBatchbufferData(const void *, unsigned, unsigned); 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 */ diff --git a/src/xvmc/intel_xvmc.c b/src/xvmc/intel_xvmc.c index 71ae77b4..6f559028 100644 --- a/src/xvmc/intel_xvmc.c +++ b/src/xvmc/intel_xvmc.c @@ -342,9 +342,7 @@ _X_EXPORT Status XvMCCreateContext(Display *display, XvPortID port, XVMC_INFO("decoder type is %s", intel_xvmc_decoder_string(comm->type)); - xvmc_driver->batchbuffer.handle = comm->batchbuffer.handle; - xvmc_driver->batchbuffer.offset = comm->batchbuffer.offset; - xvmc_driver->batchbuffer.size = comm->batchbuffer.size; + xvmc_driver->kernel_exec_fencing = comm->kernel_exec_fencing; /* assign local ctx info */ intel_ctx = intel_xvmc_new_context(display); @@ -410,6 +408,13 @@ _X_EXPORT Status XvMCCreateContext(Display *display, XvPortID port, return ret; } + 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); @@ -451,6 +456,10 @@ _X_EXPORT Status XvMCDestroyContext(Display *display, XvMCContext *context) return ret; } + intelFiniBatchBuffer(); + + dri_bufmgr_destroy(xvmc_driver->bufmgr); + intel_xvmc_free_context(context->context_id); ret = _xvmc_destroy_context(display, context); @@ -466,7 +475,6 @@ _X_EXPORT Status XvMCDestroyContext(Display *display, XvMCContext *context) close(xvmc_driver->fd); xvmc_driver->fd = -1; - intelFiniBatchBuffer(); intel_xvmc_dump_close(); } return Success; diff --git a/src/xvmc/intel_xvmc.h b/src/xvmc/intel_xvmc.h index f9c517af..862b30e3 100644 --- a/src/xvmc/intel_xvmc.h +++ b/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" @@ -131,11 +132,16 @@ typedef struct _intel_xvmc_driver { int fd; /* drm file handler */ + dri_bufmgr *bufmgr; + unsigned int kernel_exec_fencing:1; + 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 diff --git a/src/xvmc/xvmc_vld.c b/src/xvmc/xvmc_vld.c index 204cfb7c..9bb98942 100644 --- a/src/xvmc/xvmc_vld.c +++ b/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,89 @@ 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) \ + drm_intel_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 < I965_MAX_SURFACES; i++) { + s->binding_table.surface_states[i].bo = + drm_intel_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 +222,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) +static Status vfe_state() { - return media_state.state_ptr + (offset - media_state.state_base); -} - -static void 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 +232,148 @@ 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) + drm_intel_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 = drm_intel_bo_alloc(xvmc_driver->bufmgr, + "vfe state", sizeof(struct brw_vfe_state), 0x1000); + if (!media_state.vfe_state.bo) + return BadAlloc; + + drm_intel_bo_subdata(media_state.vfe_state.bo, 0, sizeof(tmp), &tmp); + + drm_intel_bo_emit_reloc(media_state.vfe_state.bo, + offsetof(struct brw_vfe_state, vfe2), + media_state.vfe_state.interface.bo, 0, + I915_GEM_DOMAIN_INSTRUCTION, 0); + 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) + drm_intel_bo_unreference(media_state.vfe_state.interface.bo); + + media_state.vfe_state.interface.bo = drm_intel_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; + + drm_intel_bo_subdata(media_state.vfe_state.interface.bo, i*sizeof(tmp), sizeof(tmp), desc); + + drm_intel_bo_emit_reloc( + media_state.vfe_state.interface.bo, + i * sizeof(*desc) + + offsetof(struct brw_interface_descriptor, desc0), + media_state.vfe_state.interface.kernels[i].bo, + desc->desc0.grf_reg_blocks, + I915_GEM_DOMAIN_INSTRUCTION, 0); + + drm_intel_bo_emit_reloc( + media_state.vfe_state.interface.bo, + i * sizeof(*desc) + + offsetof(struct brw_interface_descriptor, desc3), + media_state.binding_table.bo, + desc->desc3.binding_table_entry_count, + I915_GEM_DOMAIN_INSTRUCTION, 0); } + return Success; } -static void setup_media_kernels() +static int 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); + media_state.vfe_state.interface.kernels[i].bo = + drm_intel_bo_alloc(xvmc_driver->bufmgr, "kernel", + media_kernels[i].size, 0x1000); + if (!media_state.vfe_state.interface.kernels[i].bo) + goto out; } + + for (i = 0; i < MEDIA_KERNEL_NUM; i++) { + dri_bo *bo = media_state.vfe_state.interface.kernels[i].bo; + drm_intel_bo_subdata(bo, 0, media_kernels[i].size, media_kernels[i].bin); + } + return 0; +out: + free_object(&media_state); + return BadAlloc; } -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) + drm_intel_bo_unreference(media_state.binding_table.bo); + media_state.binding_table.bo = + drm_intel_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; + drm_intel_bo_emit_reloc(media_state.binding_table.bo, + i * sizeof(unsigned int), + media_state.binding_table.surface_states[i].bo, 0, + I915_GEM_DOMAIN_INSTRUCTION, 0); + } + + drm_intel_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) + drm_intel_bo_unreference(media_state.cs_object.bo); + + media_state.cs_object.bo = drm_intel_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.kernel_offsets[LIB_INTERFACE]; + lib_reloc[i] = media_state.vfe_state.interface.kernels[LIB_INTERFACE].bo->offset; + drm_intel_bo_subdata(media_state.cs_object.bo, 32*4, 32*16 + 8*sizeof(unsigned int), buf + 32*4); + + for (i = 0; i < 8; i++) + drm_intel_bo_emit_reloc(media_state.cs_object.bo, + 32*20 + sizeof(unsigned int) * i, + media_state.vfe_state.interface.kernels[LIB_INTERFACE].bo, 0, + I915_GEM_DOMAIN_INSTRUCTION, 0); + + return Success; } static Status create_context(Display *display, XvMCContext *context, @@ -265,18 +382,12 @@ static Status create_context(Display *display, XvMCContext *context, 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(); - setup_media_kernels(); - binding_tables(); - cs_init(); + + if (alloc_object(&media_state)) + return BadAlloc; + + if (setup_media_kernels()) + return BadAlloc; return Success; } @@ -284,34 +395,45 @@ static Status destroy_context(Display *display, XvMCContext *context) { 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 = drm_intel_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); + drm_intel_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; + drm_intel_bo_subdata(media_state.cs_object.bo, 0, 64, qmx->intra_quantiser_matrix); + drm_intel_bo_subdata(media_state.cs_object.bo, 64, 64, qmx->non_intra_quantiser_matrix); + return Success; } @@ -322,12 +444,18 @@ static Status get_surface_status(Display *display, XvMCSurface *surface, 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) + drm_intel_bo_unreference(media_state.vld_state.bo); + media_state.vld_state.bo = drm_intel_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 +490,80 @@ static void vld_state(const XvMCMpegControl *control) 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; + + drm_intel_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) + drm_intel_bo_unreference(media_state.binding_table.surface_states[index].bo); + + media_state.binding_table.surface_states[index].bo = + drm_intel_bo_alloc(xvmc_driver->bufmgr, "surface_state", + sizeof(struct brw_surface_state), 0x1000); + if (!media_state.binding_table.surface_states[index].bo) + return BadAlloc; + + drm_intel_bo_subdata( + media_state.binding_table.surface_states[index].bo, + 0, sizeof(*ss), ss); + drm_intel_bo_emit_reloc(media_state.binding_table.surface_states[index].bo, + offsetof(struct brw_surface_state, ss1), + bo, offset, + I915_GEM_DOMAIN_RENDER, write?I915_GEM_DOMAIN_RENDER:0); + 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 +575,30 @@ static Status begin_surface(Display *display, XvMCContext *context, 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 +636,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 +694,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 +707,12 @@ static void vld_send_media_object(unsigned long slice_offset, 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 +727,26 @@ static Status put_slice2(Display *display, XvMCContext *context, 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) { + if (xvmc_driver->kernel_exec_fencing) + drm_intel_gem_bo_unmap_gtt(media_state.slice_data.bo); + else + drm_intel_bo_unmap(media_state.slice_data.bo); + drm_intel_bo_unreference(media_state.slice_data.bo); + } + media_state.slice_data.bo = drm_intel_bo_alloc(xvmc_driver->bufmgr, + "slice data", VLD_MAX_SLICE_SIZE, 64); + if (!media_state.slice_data.bo) + return BadAlloc; + if (xvmc_driver->kernel_exec_fencing) + drm_intel_gem_bo_map_gtt(media_state.slice_data.bo); + else + drm_intel_bo_map(media_state.slice_data.bo, 1); + + 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 +754,7 @@ static Status put_slice2(Display *display, XvMCContext *context, 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 +772,10 @@ static Status put_surface(Display *display,XvMCSurface *surface, { struct i965_xvmc_surface *private_surface = surface->privData; + uint32_t handle; - data->surf_offset = private_surface->buffer.offset; + drm_intel_bo_flink(private_surface->bo, &handle); + data->handle = handle; return Success; } |