summaryrefslogtreecommitdiff
path: root/src/xvmc/i965_xvmc.c
diff options
context:
space:
mode:
authorLi Shao Hua <shaohua.li@intel.com>2009-05-19 16:27:32 +0800
committerZou Nan hai <nanhai.zou@intel.com>2009-05-19 16:27:32 +0800
commit52054b6a4c1ca5117c9750361f71aedd91220c39 (patch)
tree14371ab2a95d6d62527b4be6502a8759efaf1674 /src/xvmc/i965_xvmc.c
parentb622860429e00d6ab4407980232659c283a8fe8d (diff)
switch XvMC to gem
Diffstat (limited to 'src/xvmc/i965_xvmc.c')
-rw-r--r--src/xvmc/i965_xvmc.c634
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;
}