diff options
author | Li Shao Hua <shaohua.li@intel.com> | 2009-05-19 16:27:32 +0800 |
---|---|---|
committer | Zou Nan hai <nanhai.zou@intel.com> | 2009-05-19 16:27:32 +0800 |
commit | 52054b6a4c1ca5117c9750361f71aedd91220c39 (patch) | |
tree | 14371ab2a95d6d62527b4be6502a8759efaf1674 /src/xvmc/i965_xvmc.c | |
parent | b622860429e00d6ab4407980232659c283a8fe8d (diff) |
switch XvMC to gem
Diffstat (limited to 'src/xvmc/i965_xvmc.c')
-rw-r--r-- | src/xvmc/i965_xvmc.c | 634 |
1 files changed, 362 insertions, 272 deletions
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; } |