diff options
author | Carl Worth <cworth@cworth.org> | 2008-07-17 00:38:54 -0700 |
---|---|---|
committer | Carl Worth <cworth@cworth.org> | 2008-07-17 00:38:54 -0700 |
commit | a6ad50402cb879b08de95f94959bb1f59701c1ff (patch) | |
tree | 9ee9fc89a52d8791b272721a910ea5c11d4e4aa7 /src/xvmc | |
parent | e9916b9d496fd0b4df717892dda33f81a2e2990a (diff) | |
parent | c4565a9811487402d899d0933cc63e27ffe1ff08 (diff) |
Merge branch 'master' into drm-gem
Conflicts:
configure.ac
src/reg_dumper/Makefile.am
Diffstat (limited to 'src/xvmc')
-rw-r--r-- | src/xvmc/I810XvMC.c | 2 | ||||
-rw-r--r-- | src/xvmc/i915_structs.h | 81 | ||||
-rw-r--r-- | src/xvmc/i915_xvmc.c | 1385 | ||||
-rw-r--r-- | src/xvmc/intel_xvmc.c | 12 | ||||
-rw-r--r-- | src/xvmc/intel_xvmc.h | 3 | ||||
-rw-r--r-- | src/xvmc/intel_xvmc_dump.c | 31 |
6 files changed, 776 insertions, 738 deletions
diff --git a/src/xvmc/I810XvMC.c b/src/xvmc/I810XvMC.c index 03be2514..ce5395ac 100644 --- a/src/xvmc/I810XvMC.c +++ b/src/xvmc/I810XvMC.c @@ -130,7 +130,6 @@ Status XvMCCreateContext(Display *display, XvPortID port, int surface_type_id, int width, int height, int flags, XvMCContext *context) { i810XvMCContext *pI810XvMC; - char busIdString[10]; int priv_count; uint *priv_data; uint magic; @@ -217,7 +216,6 @@ Status XvMCCreateContext(Display *display, XvPortID port, /* Open DRI Device */ if((pI810XvMC->fd = drmOpen("i810",NULL)) < 0) { printf("DRM Device for i810 could not be opened.\n"); - free(busIdString); free(pI810XvMC); return BadAccess; } /* !pI810XvMC->fd */ diff --git a/src/xvmc/i915_structs.h b/src/xvmc/i915_structs.h index a25d7349..b5185cb7 100644 --- a/src/xvmc/i915_structs.h +++ b/src/xvmc/i915_structs.h @@ -28,6 +28,8 @@ #ifndef _I915_STRUCTS_H #define _I915_STRUCTS_H +#include <stdint.h> + /* MI_INSTRUCTION */ #define CMD_MI 0x00 @@ -352,7 +354,7 @@ struct i915_3dstate_dest_buffer_variables_mpeg unsigned rcontrol : 1; unsigned decode_mode : 2; } dw1; - + struct { unsigned pad0 : 1; unsigned picture_coding_type : 2; @@ -372,6 +374,15 @@ struct i915_3dstate_dest_buffer_variables_mpeg } dw2; }; +struct i915_mc_static_indirect_state_buffer { + struct i915_3dstate_buffer_info dest_y; + struct i915_3dstate_buffer_info dest_u; + struct i915_3dstate_buffer_info dest_v; + struct i915_3dstate_dest_buffer_variables dest_buf; + struct i915_3dstate_dest_buffer_variables_mpeg dest_buf_mpeg; + struct i915_3dstate_buffer_info corr; +}; + #define MAP_MAP0 0x0001 #define MAP_MAP1 0x0002 #define MAP_MAP2 0x0004 @@ -432,7 +443,18 @@ struct i915_3dstate_map_state unsigned map_mask : 16; unsigned pad0 : 16; } dw1; -// struct texture_map *tms; +}; + +struct i915_mc_map_state { + struct i915_3dstate_map_state y_map; + struct texture_map y_forward; + struct texture_map y_backward; + struct i915_3dstate_map_state u_map; + struct texture_map u_forward; + struct texture_map u_backward; + struct i915_3dstate_map_state v_map; + struct texture_map v_forward; + struct texture_map v_backward; }; #define SAMPLER_SAMPLER0 0x0001 @@ -532,6 +554,9 @@ struct i915_3dstate_sampler_state unsigned sampler_masker : 16; unsigned pad0 : 16; } dw1; + /* we always use two samplers for mc */ + struct texture_sampler sampler0; + struct texture_sampler sampler1; }; struct arithmetic_inst @@ -641,17 +666,48 @@ union shader_inst struct declaration_inst d; }; +struct i915_3dstate_pixel_shader_header { + unsigned length : 9; + unsigned pad0 : 6; + unsigned retain : 1; + unsigned opcode : 13; + unsigned type : 3; +}; + struct i915_3dstate_pixel_shader_program { - struct { - unsigned length : 9; - unsigned pad0 : 6; - unsigned retain : 1; - unsigned opcode : 13; - unsigned type : 3; - } dw0; - - // union shader_inst *insts; + struct i915_3dstate_pixel_shader_header shader0; + /* mov oC, c0.0000 */ + uint32_t inst0[3]; + + struct i915_3dstate_pixel_shader_header shader1; + /* dcl t0.xy */ + /* dcl t1.xy */ + /* dcl_2D s0 */ + /* texld r0, t0, s0 */ + /* mov oC, r0 */ + uint32_t inst1[3*5]; + + struct i915_3dstate_pixel_shader_header shader2; + /* dcl t2.xy */ + /* dcl t3.xy */ + /* dcl_2D s1 */ + /* texld r0, t2, s1 */ + /* mov oC, r0 */ + uint32_t inst2[3*5]; + + struct i915_3dstate_pixel_shader_header shader3; + /* dcl t0.xy */ + /* dcl t1.xy */ + /* dcl t2.xy */ + /* dcl t3.xy */ + /* dcl_2D s0 */ + /* dcl_2D s1 */ + /* texld r0, t0, s0 */ + /* texld r0, t2, s1 */ + /* add r0, r0, r1*/ + /* mov oC, r0 */ + uint32_t inst3[3*10]; }; #define REG_CR0 0x00000001 @@ -707,7 +763,8 @@ struct i915_3dstate_pixel_shader_constants struct { unsigned reg_mask; } dw1; - // struct shader_constant *consts; + /* we only need one constant */ + struct shader_constant value; }; #define BLOCK_SIS 0x01 diff --git a/src/xvmc/i915_xvmc.c b/src/xvmc/i915_xvmc.c index 519de5a3..c32073a1 100644 --- a/src/xvmc/i915_xvmc.c +++ b/src/xvmc/i915_xvmc.c @@ -39,9 +39,9 @@ SIZE_Y420(surface->width, surface->height)) typedef union { - short s[4]; - uint u[2]; -} su_t; + int16_t component[2]; + int32_t v; +} vector_t; #if 0 static int findOverlap(unsigned int width, unsigned int height, @@ -81,577 +81,6 @@ static int findOverlap(unsigned int width, unsigned int height, } #endif -static void i915_flush(int map, int render) -{ - struct i915_mi_flush mi_flush; - - memset(&mi_flush, 0, sizeof(mi_flush)); - mi_flush.dw0.type = CMD_MI; - mi_flush.dw0.opcode = OPC_MI_FLUSH; - mi_flush.dw0.map_cache_invalidate = map; - mi_flush.dw0.render_cache_flush_inhibit = render; - - intelBatchbufferData(&mi_flush, sizeof(mi_flush), 0); -} - -/* for MC picture rendering */ -static void i915_mc_static_indirect_state_buffer(XvMCContext *context, - XvMCSurface *surface, - unsigned int picture_structure, - unsigned int flags, - unsigned int picture_coding_type) -{ - struct i915_3dstate_buffer_info *buffer_info; - struct i915_3dstate_dest_buffer_variables *dest_buffer_variables; - struct i915_3dstate_dest_buffer_variables_mpeg *dest_buffer_variables_mpeg; - i915XvMCSurface *pI915Surface = (i915XvMCSurface *)surface->privData; - i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData; - unsigned int w = surface->width; - - /* 3DSTATE_BUFFER_INFO */ - /* DEST Y */ - buffer_info = (struct i915_3dstate_buffer_info *)pI915XvMC->sis.map; - memset(buffer_info, 0, sizeof(*buffer_info)); - buffer_info->dw0.type = CMD_3D; - buffer_info->dw0.opcode = OPC_3DSTATE_BUFFER_INFO; - buffer_info->dw0.length = 1; - buffer_info->dw1.aux_id = 0; - buffer_info->dw1.buffer_id = BUFFERID_COLOR_BACK; - buffer_info->dw1.fence_regs = 0; /* disabled */ /* FIXME: tiled y for performance */ - buffer_info->dw1.tiled_surface = 0; /* linear */ - buffer_info->dw1.walk = TILEWALK_XMAJOR; - buffer_info->dw1.pitch = (pI915Surface->yStride >> 2); /* in DWords */ - buffer_info->dw2.base_address = (YOFFSET(pI915Surface) >> 2); /* starting DWORD address */ - - /* DEST U */ - ++buffer_info; - memset(buffer_info, 0, sizeof(*buffer_info)); - buffer_info->dw0.type = CMD_3D; - buffer_info->dw0.opcode = OPC_3DSTATE_BUFFER_INFO; - buffer_info->dw0.length = 1; - buffer_info->dw1.aux_id = 0; - buffer_info->dw1.buffer_id = BUFFERID_COLOR_AUX; - buffer_info->dw1.fence_regs = 0; - buffer_info->dw1.tiled_surface = 0; - buffer_info->dw1.walk = TILEWALK_XMAJOR; - buffer_info->dw1.pitch = (pI915Surface->uvStride >> 2); /* in DWords */ - buffer_info->dw2.base_address = (UOFFSET(pI915Surface) >> 2); /* starting DWORD address */ - - /* DEST V */ - ++buffer_info; - memset(buffer_info, 0, sizeof(*buffer_info)); - buffer_info->dw0.type = CMD_3D; - buffer_info->dw0.opcode = OPC_3DSTATE_BUFFER_INFO; - buffer_info->dw0.length = 1; - buffer_info->dw1.aux_id = 1; - buffer_info->dw1.buffer_id = BUFFERID_COLOR_AUX; - buffer_info->dw1.fence_regs = 0; - buffer_info->dw1.tiled_surface = 0; - buffer_info->dw1.walk = TILEWALK_XMAJOR; - buffer_info->dw1.pitch = (pI915Surface->uvStride >> 2); /* in Dwords */ - buffer_info->dw2.base_address = (VOFFSET(pI915Surface) >> 2); /* starting DWORD address */ - - /* 3DSTATE_DEST_BUFFER_VARIABLES */ - dest_buffer_variables = (struct i915_3dstate_dest_buffer_variables *)(++buffer_info); - memset(dest_buffer_variables, 0, sizeof(*dest_buffer_variables)); - dest_buffer_variables->dw0.type = CMD_3D; - dest_buffer_variables->dw0.opcode = OPC_3DSTATE_DEST_BUFFER_VARIABLES; - dest_buffer_variables->dw0.length = 0; - dest_buffer_variables->dw1.dest_v_bias = 8; /* 0.5 */ - dest_buffer_variables->dw1.dest_h_bias = 8; /* 0.5 */ - dest_buffer_variables->dw1.color_fmt = COLORBUFFER_8BIT; - dest_buffer_variables->dw1.v_ls = 0; - dest_buffer_variables->dw1.v_ls_offset = 0; - - if ((picture_structure & XVMC_FRAME_PICTURE) == XVMC_FRAME_PICTURE) { - ; - } else if ((picture_structure & XVMC_FRAME_PICTURE) == XVMC_TOP_FIELD) { - dest_buffer_variables->dw1.v_ls = 1; - } else if ((picture_structure & XVMC_FRAME_PICTURE) == XVMC_BOTTOM_FIELD) { - dest_buffer_variables->dw1.v_ls = 1; - dest_buffer_variables->dw1.v_ls_offset = 1; - } - - /* 3DSTATE_DEST_BUFFER_VARIABLES_MPEG */ - dest_buffer_variables_mpeg = (struct i915_3dstate_dest_buffer_variables_mpeg *)(++dest_buffer_variables); - memset(dest_buffer_variables_mpeg, 0, sizeof(*dest_buffer_variables_mpeg)); - dest_buffer_variables_mpeg->dw0.type = CMD_3D; - dest_buffer_variables_mpeg->dw0.opcode = OPC_3DSTATE_DEST_BUFFER_VARIABLES_MPEG; - dest_buffer_variables_mpeg->dw0.length = 1; - dest_buffer_variables_mpeg->dw1.decode_mode = MPEG_DECODE_MC; - dest_buffer_variables_mpeg->dw1.rcontrol = 0; /* for MPEG-1/MPEG-2 */ - dest_buffer_variables_mpeg->dw1.bidir_avrg_control = 0; /* for MPEG-1/MPEG-2/MPEG-4 */ - dest_buffer_variables_mpeg->dw1.abort_on_error = 1; - dest_buffer_variables_mpeg->dw1.intra8 = 0; /* 16-bit formatted correction data */ - dest_buffer_variables_mpeg->dw1.tff = 1; - - if (picture_structure & XVMC_FRAME_PICTURE) { - ; - } else if (picture_structure & XVMC_TOP_FIELD) { - if (flags & XVMC_SECOND_FIELD) - dest_buffer_variables_mpeg->dw1.tff = 0; - else - dest_buffer_variables_mpeg->dw1.tff = 1; - } else if (picture_structure & XVMC_BOTTOM_FIELD) { - if (flags & XVMC_SECOND_FIELD) - dest_buffer_variables_mpeg->dw1.tff = 1; - else - dest_buffer_variables_mpeg->dw1.tff = 0; - } - - dest_buffer_variables_mpeg->dw1.v_subsample_factor = MC_SUB_1V; - dest_buffer_variables_mpeg->dw1.h_subsample_factor = MC_SUB_1H; - dest_buffer_variables_mpeg->dw1.picture_width = (w >> 4); /* in macroblocks */ - dest_buffer_variables_mpeg->dw2.picture_coding_type = picture_coding_type; - - /* 3DSATE_BUFFER_INFO */ - /* CORRECTION DATA */ - buffer_info = (struct i915_3dstate_buffer_info *)(++dest_buffer_variables_mpeg); - memset(buffer_info, 0, sizeof(*buffer_info)); - buffer_info->dw0.type = CMD_3D; - buffer_info->dw0.opcode = OPC_3DSTATE_BUFFER_INFO; - buffer_info->dw0.length = 1; - buffer_info->dw1.aux_id = 0; - buffer_info->dw1.buffer_id = BUFFERID_MC_INTRA_CORR; - buffer_info->dw1.aux_id = 0; - buffer_info->dw1.fence_regs = 0; - buffer_info->dw1.tiled_surface = 0; - buffer_info->dw1.walk = 0; - buffer_info->dw1.pitch = 0; - buffer_info->dw2.base_address = (pI915XvMC->corrdata.offset >> 2); /* starting DWORD address */ -} - -static void i915_mc_map_state_buffer(XvMCContext *context, - i915XvMCSurface *privTarget, - i915XvMCSurface *privPast, - i915XvMCSurface *privFuture) -{ - struct i915_3dstate_map_state *map_state; - struct texture_map *tm; - i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData; - unsigned int w = context->width, h = context->height; - - /* 3DSATE_MAP_STATE: Y */ - map_state = (struct i915_3dstate_map_state *)pI915XvMC->msb.map; - memset(map_state, 0, sizeof(*map_state)); - map_state->dw0.type = CMD_3D; - map_state->dw0.opcode = OPC_3DSTATE_MAP_STATE; - map_state->dw0.retain = 1; - map_state->dw0.length = 6; - map_state->dw1.map_mask = MAP_MAP0 | MAP_MAP1; - - /* texture map: Forward (Past) */ - tm = (struct texture_map *)(++map_state); - memset(tm, 0, sizeof(*tm)); - tm->tm0.v_ls_offset = 0; - tm->tm0.v_ls = 0; - tm->tm0.base_address = (YOFFSET(privPast) >> 2); - tm->tm1.tile_walk = TILEWALK_XMAJOR; /* FIXME: tiled y for performace */ - tm->tm1.tiled_surface = 0; - tm->tm1.utilize_fence_regs = 0; - tm->tm1.texel_fmt = 0; /* 8bit */ - tm->tm1.surface_fmt = 1; /* 8bit */ - tm->tm1.width = w - 1; - tm->tm1.height = h - 1; - tm->tm2.depth = 0; - tm->tm2.max_lod = 0; - tm->tm2.cube_face = 0; - tm->tm2.pitch = (privPast->yStride >> 2) - 1; /* in DWords - 1 */ - - /* texture map: Backward (Future) */ - ++tm; - memset(tm, 0, sizeof(*tm)); - tm->tm0.v_ls_offset = 0; - tm->tm0.v_ls = 0; - tm->tm0.base_address = (YOFFSET(privFuture) >> 2); - tm->tm1.tile_walk = TILEWALK_XMAJOR; - tm->tm1.tiled_surface = 0; - tm->tm1.utilize_fence_regs = 0; - tm->tm1.texel_fmt = 0; /* 8bit */ - tm->tm1.surface_fmt = 1; /* 8bit */ - tm->tm1.width = w - 1; - tm->tm1.height = h - 1; - tm->tm2.depth = 0; - tm->tm2.max_lod = 0; - tm->tm2.cube_face = 0; - tm->tm2.pitch = (privFuture->yStride >> 2) - 1; - - /* 3DSATE_MAP_STATE: U */ - map_state = (struct i915_3dstate_map_state *)(++tm); - memset(map_state, 0, sizeof(*map_state)); - map_state->dw0.type = CMD_3D; - map_state->dw0.opcode = OPC_3DSTATE_MAP_STATE; - map_state->dw0.retain = 1; - map_state->dw0.length = 6; - map_state->dw1.map_mask = MAP_MAP0 | MAP_MAP1; - - /* texture map: Forward */ - tm = (struct texture_map *)(++map_state); - memset(tm, 0, sizeof(*tm)); - tm->tm0.v_ls_offset = 0; - tm->tm0.v_ls = 0; - tm->tm0.base_address = (UOFFSET(privPast) >> 2); - tm->tm1.tile_walk = TILEWALK_XMAJOR; - tm->tm1.tiled_surface = 0; - tm->tm1.utilize_fence_regs = 0; - tm->tm1.texel_fmt = 0; /* 8bit */ - tm->tm1.surface_fmt = 1; /* 8bit */ - tm->tm1.width = (w >> 1) - 1; - tm->tm1.height = (h >> 1) - 1; - tm->tm2.depth = 0; - tm->tm2.max_lod = 0; - tm->tm2.cube_face = 0; - tm->tm2.pitch = (privPast->uvStride >> 2) - 1; /* in DWords - 1 */ - - /* texture map: Backward */ - ++tm; - memset(tm, 0, sizeof(*tm)); - tm->tm0.v_ls_offset = 0; - tm->tm0.v_ls = 0; - tm->tm0.base_address = (UOFFSET(privFuture) >> 2); - tm->tm1.tile_walk = TILEWALK_XMAJOR; - tm->tm1.tiled_surface = 0; - tm->tm1.utilize_fence_regs = 0; - tm->tm1.texel_fmt = 0; - tm->tm1.surface_fmt = 1; - tm->tm1.width = (w >> 1) - 1; - tm->tm1.height = (h >> 1) - 1; - tm->tm2.depth = 0; - tm->tm2.max_lod = 0; - tm->tm2.cube_face = 0; - tm->tm2.pitch = (privFuture->uvStride >> 2) - 1; - - /* 3DSATE_MAP_STATE: V */ - map_state = (struct i915_3dstate_map_state *)(++tm); - memset(map_state, 0, sizeof(*map_state)); - map_state->dw0.type = CMD_3D; - map_state->dw0.opcode = OPC_3DSTATE_MAP_STATE; - map_state->dw0.retain = 1; - map_state->dw0.length = 6; - map_state->dw1.map_mask = MAP_MAP0 | MAP_MAP1; - - /* texture map: Forward */ - tm = (struct texture_map *)(++map_state); - memset(tm, 0, sizeof(*tm)); - tm->tm0.v_ls_offset = 0; - tm->tm0.v_ls = 0; - tm->tm0.base_address = (VOFFSET(privPast) >> 2); - tm->tm1.tile_walk = TILEWALK_XMAJOR; - tm->tm1.tiled_surface = 0; - tm->tm1.utilize_fence_regs = 0; - tm->tm1.texel_fmt = 0; - tm->tm1.surface_fmt = 1; - tm->tm1.width = (w >> 1) - 1; - tm->tm1.height = (h >> 1) - 1; - tm->tm2.depth = 0; - tm->tm2.max_lod = 0; - tm->tm2.cube_face = 0; - tm->tm2.pitch = (privPast->uvStride >> 2) - 1; /* in DWords - 1 */ - - /* texture map: Backward */ - ++tm; - memset(tm, 0, sizeof(*tm)); - tm->tm0.v_ls_offset = 0; - tm->tm0.v_ls = 0; - tm->tm0.base_address = (VOFFSET(privFuture) >> 2); - tm->tm1.tile_walk = TILEWALK_XMAJOR; - tm->tm1.tiled_surface = 0; - tm->tm1.utilize_fence_regs = 0; - tm->tm1.texel_fmt = 0; - tm->tm1.surface_fmt = 1; - tm->tm1.width = (w >> 1) - 1; - tm->tm1.height = (h >> 1) - 1; - tm->tm2.depth = 0; - tm->tm2.max_lod = 0; - tm->tm2.cube_face = 0; - tm->tm2.pitch = (privFuture->uvStride >> 2) - 1; -} - -static void i915_mc_load_sis_msb_buffers(XvMCContext *context) -{ - struct i915_3dstate_load_indirect *load_indirect; - sis_state *sis = NULL; - msb_state *msb = NULL; - i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData; - void *base = NULL; - unsigned int size; - int mem_select = 1; - - /* 3DSTATE_LOAD_INDIRECT */ - size = sizeof(*load_indirect) + sizeof(*sis) + sizeof(*msb); - base = calloc(1, size); - load_indirect = (struct i915_3dstate_load_indirect *)base; - load_indirect->dw0.type = CMD_3D; - load_indirect->dw0.opcode = OPC_3DSTATE_LOAD_INDIRECT; - load_indirect->dw0.block_mask = BLOCK_SIS | BLOCK_MSB; - load_indirect->dw0.length = (size >> 2) - 2; - - if (pI915XvMC->deviceID == PCI_CHIP_I915_G || - pI915XvMC->deviceID == PCI_CHIP_I915_GM || - pI915XvMC->deviceID == PCI_CHIP_I945_G || - pI915XvMC->deviceID == PCI_CHIP_I945_GM) - mem_select = 0; - - load_indirect->dw0.mem_select = mem_select; - - /* SIS */ - sis = (sis_state *)(++load_indirect); - sis->dw0.valid = 1; - sis->dw0.force = 1; - sis->dw1.length = 16; // 4 * 3 + 2 + 3 - 1 - - if (mem_select) - sis->dw0.buffer_address = (pI915XvMC->sis.offset >> 2); - else - sis->dw0.buffer_address = (pI915XvMC->sis.bus_addr >> 2); - - /* MSB */ - msb = (msb_state *)(++sis); - msb->dw0.valid = 1; - msb->dw0.force = 1; - msb->dw1.length = 23; // 3 * 8 - 1 - - if (mem_select) - msb->dw0.buffer_address = (pI915XvMC->msb.offset >> 2); - else - msb->dw0.buffer_address = (pI915XvMC->msb.bus_addr >> 2); - - intelBatchbufferData(base, size, 0); - free(base); -} - -static void i915_mc_mpeg_set_origin(XvMCContext *context, XvMCMacroBlock *mb) -{ - struct i915_3dmpeg_set_origin set_origin; - - /* 3DMPEG_SET_ORIGIN */ - memset(&set_origin, 0, sizeof(set_origin)); - set_origin.dw0.type = CMD_3D; - set_origin.dw0.opcode = OPC_3DMPEG_SET_ORIGIN; - set_origin.dw0.length = 0; - set_origin.dw1.h_origin = mb->x; - set_origin.dw1.v_origin = mb->y; - - intelBatchbufferData(&set_origin, sizeof(set_origin), 0); -} - -static void i915_mc_mpeg_macroblock_ipicture(XvMCContext *context, XvMCMacroBlock *mb) -{ - struct i915_3dmpeg_macroblock_ipicture macroblock_ipicture; - - /* 3DMPEG_MACROBLOCK_IPICTURE */ - memset(¯oblock_ipicture, 0, sizeof(macroblock_ipicture)); - macroblock_ipicture.dw0.type = CMD_3D; - macroblock_ipicture.dw0.opcode = OPC_3DMPEG_MACROBLOCK_IPICTURE; - macroblock_ipicture.dw0.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD); - - intelBatchbufferData(¯oblock_ipicture, sizeof(macroblock_ipicture), 0); -} - -#if 0 -static void i915_mc_mpeg_macroblock_0mv(XvMCContext *context, XvMCMacroBlock *mb) -{ - struct i915_3dmpeg_macroblock_0mv macroblock_0mv; - - /* 3DMPEG_MACROBLOCK(0mv) */ - memset(¯oblock_0mv, 0, sizeof(macroblock_0mv)); - macroblock_0mv.header.dw0.type = CMD_3D; - macroblock_0mv.header.dw0.opcode = OPC_3DMPEG_MACROBLOCK; - macroblock_0mv.header.dw0.length = 0; - macroblock_0mv.header.dw1.mb_intra = 1; /* should be 1 */ - macroblock_0mv.header.dw1.forward = 0; /* should be 0 */ - macroblock_0mv.header.dw1.backward = 0; /* should be 0 */ - macroblock_0mv.header.dw1.h263_4mv = 0; /* should be 0 */ - macroblock_0mv.header.dw1.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD); - -/* - if (!mb->coded_block_pattern) - macroblock_0mv.header.dw1.dct_type = XVMC_DCT_TYPE_FRAME; -*/ - - macroblock_0mv.header.dw1.motion_type = 0; // (mb->motion_type & 0x3); - macroblock_0mv.header.dw1.vertical_field_select = 0; // mb->motion_vertical_field_select & 0xf; - macroblock_0mv.header.dw1.coded_block_pattern = mb->coded_block_pattern; - macroblock_0mv.header.dw1.skipped_macroblocks = 0; - - intelBatchbufferData(¯oblock_0mv, sizeof(macroblock_0mv), 0); -} -#endif - -static void i915_mc_mpeg_macroblock_1fbmv(XvMCContext *context, XvMCMacroBlock *mb) -{ - struct i915_3dmpeg_macroblock_1fbmv macroblock_1fbmv; - - /* Motion Vectors */ - su_t fmv; - su_t bmv; - - /* 3DMPEG_MACROBLOCK(1fbmv) */ - memset(¯oblock_1fbmv, 0, sizeof(macroblock_1fbmv)); - macroblock_1fbmv.header.dw0.type = CMD_3D; - macroblock_1fbmv.header.dw0.opcode = OPC_3DMPEG_MACROBLOCK; - macroblock_1fbmv.header.dw0.length = 2; - macroblock_1fbmv.header.dw1.mb_intra = 0; /* should be 0 */ - macroblock_1fbmv.header.dw1.forward = ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_FORWARD) ? 1 : 0); - macroblock_1fbmv.header.dw1.backward = ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_BACKWARD) ? 1 : 0); - macroblock_1fbmv.header.dw1.h263_4mv = 0; /* should be 0 */ - macroblock_1fbmv.header.dw1.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD); - - if (!(mb->coded_block_pattern & 0x3f)) - macroblock_1fbmv.header.dw1.dct_type = XVMC_DCT_TYPE_FRAME; - - macroblock_1fbmv.header.dw1.motion_type = (mb->motion_type & 0x03); - macroblock_1fbmv.header.dw1.vertical_field_select = (mb->motion_vertical_field_select & 0x0f); - macroblock_1fbmv.header.dw1.coded_block_pattern = mb->coded_block_pattern; - macroblock_1fbmv.header.dw1.skipped_macroblocks = 0; - - fmv.s[0] = mb->PMV[0][0][0]; - fmv.s[1] = mb->PMV[0][0][1]; - bmv.s[0] = mb->PMV[0][1][0]; - bmv.s[1] = mb->PMV[0][1][1]; - - macroblock_1fbmv.dw2 = fmv.u[0]; - macroblock_1fbmv.dw3 = bmv.u[0]; - - intelBatchbufferData(¯oblock_1fbmv, sizeof(macroblock_1fbmv), 0); -} - -static void i915_mc_mpeg_macroblock_2fbmv(XvMCContext *context, XvMCMacroBlock *mb, unsigned int ps) -{ - struct i915_3dmpeg_macroblock_2fbmv macroblock_2fbmv; - - /* Motion Vectors */ - su_t fmv; - su_t bmv; - - /* 3DMPEG_MACROBLOCK(2fbmv) */ - memset(¯oblock_2fbmv, 0, sizeof(macroblock_2fbmv)); - macroblock_2fbmv.header.dw0.type = CMD_3D; - macroblock_2fbmv.header.dw0.opcode = OPC_3DMPEG_MACROBLOCK; - macroblock_2fbmv.header.dw0.length = 4; - macroblock_2fbmv.header.dw1.mb_intra = 0; /* should be 0 */ - macroblock_2fbmv.header.dw1.forward = ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_FORWARD) ? 1 : 0); - macroblock_2fbmv.header.dw1.backward = ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_BACKWARD) ? 1 : 0); - macroblock_2fbmv.header.dw1.h263_4mv = 0; /* should be 0 */ - macroblock_2fbmv.header.dw1.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD); - - if (!(mb->coded_block_pattern & 0x3f)) - macroblock_2fbmv.header.dw1.dct_type = XVMC_DCT_TYPE_FRAME; - - macroblock_2fbmv.header.dw1.motion_type = (mb->motion_type & 0x03); - macroblock_2fbmv.header.dw1.vertical_field_select = (mb->motion_vertical_field_select & 0x0f); - macroblock_2fbmv.header.dw1.coded_block_pattern = mb->coded_block_pattern; - macroblock_2fbmv.header.dw1.skipped_macroblocks = 0; - - fmv.s[0] = mb->PMV[0][0][0]; - fmv.s[1] = mb->PMV[0][0][1]; - fmv.s[2] = mb->PMV[1][0][0]; - fmv.s[3] = mb->PMV[1][0][1]; - bmv.s[0] = mb->PMV[0][1][0]; - bmv.s[1] = mb->PMV[0][1][1]; - bmv.s[2] = mb->PMV[1][1][0]; - bmv.s[3] = mb->PMV[1][1][1]; - - if ((ps & XVMC_FRAME_PICTURE) == XVMC_FRAME_PICTURE) { - if ((mb->motion_type & 3) == XVMC_PREDICTION_FIELD) { - fmv.s[0] = mb->PMV[0][0][0]; - fmv.s[1] = mb->PMV[0][0][1] >> 1; - fmv.s[2] = mb->PMV[1][0][0]; - fmv.s[3] = mb->PMV[1][0][1] >> 1; - bmv.s[0] = mb->PMV[0][1][0]; - bmv.s[1] = mb->PMV[0][1][1] >> 1; - bmv.s[2] = mb->PMV[1][1][0]; - bmv.s[3] = mb->PMV[1][1][1] >> 1; - } else if ((mb->motion_type & 3) == XVMC_PREDICTION_DUAL_PRIME) { - fmv.s[0] = mb->PMV[0][0][0]; - fmv.s[1] = mb->PMV[0][0][1] >> 1; - fmv.s[2] = mb->PMV[0][0][0]; - fmv.s[3] = mb->PMV[0][0][1] >> 1; // MPEG2 MV[0][1] isn't used - bmv.s[0] = mb->PMV[1][0][0]; - bmv.s[1] = mb->PMV[1][0][1] >> 1; - bmv.s[2] = mb->PMV[1][1][0]; - bmv.s[3] = mb->PMV[1][1][1] >> 1; - } - } - - macroblock_2fbmv.dw2 = fmv.u[0]; - macroblock_2fbmv.dw3 = bmv.u[0]; - macroblock_2fbmv.dw4 = fmv.u[1]; - macroblock_2fbmv.dw5 = bmv.u[1]; - - intelBatchbufferData(¯oblock_2fbmv, sizeof(macroblock_2fbmv), 0); -} - -/* for MC context initialization */ -static void i915_mc_sampler_state_buffer(XvMCContext *context) -{ - struct i915_3dstate_sampler_state *sampler_state; - struct texture_sampler *ts; - i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData; - - /* 3DSATE_SAMPLER_STATE */ - sampler_state = (struct i915_3dstate_sampler_state *)pI915XvMC->ssb.map; - memset(sampler_state, 0, sizeof(*sampler_state)); - sampler_state->dw0.type = CMD_3D; - sampler_state->dw0.opcode = OPC_3DSTATE_SAMPLER_STATE; - sampler_state->dw0.length = 6; - sampler_state->dw1.sampler_masker = SAMPLER_SAMPLER0 | SAMPLER_SAMPLER1; - - /* Sampler 0 */ - ts = (struct texture_sampler *)(++sampler_state); - memset(ts, 0, sizeof(*ts)); - ts->ts0.reverse_gamma = 0; - ts->ts0.planar2packet = 0; - ts->ts0.color_conversion = 0; - ts->ts0.chromakey_index = 0; - ts->ts0.base_level = 0; - ts->ts0.mip_filter = MIPFILTER_NONE; /* NONE */ - ts->ts0.mag_filter = MAPFILTER_LINEAR; /* LINEAR */ - ts->ts0.min_filter = MAPFILTER_LINEAR; /* LINEAR */ - ts->ts0.lod_bias = 0; /* 0.0 */ - ts->ts0.shadow_enable = 0; - ts->ts0.max_anisotropy = ANISORATIO_2; - ts->ts0.shadow_function = PREFILTEROP_ALWAYS; - ts->ts1.min_lod = 0; /* 0.0 Maximum Mip Level */ - ts->ts1.kill_pixel = 0; - ts->ts1.keyed_texture_filter = 0; - ts->ts1.chromakey_enable = 0; - ts->ts1.tcx_control = TEXCOORDMODE_CLAMP; - ts->ts1.tcy_control = TEXCOORDMODE_CLAMP; - ts->ts1.tcz_control = TEXCOORDMODE_CLAMP; - ts->ts1.normalized_coor = 0; - ts->ts1.map_index = 0; - ts->ts1.east_deinterlacer = 0; - ts->ts2.default_color = 0; - - /* Sampler 1 */ - ++ts; - memset(ts, 0, sizeof(*ts)); - ts->ts0.reverse_gamma = 0; - ts->ts0.planar2packet = 0; - ts->ts0.color_conversion = 0; - ts->ts0.chromakey_index = 0; - ts->ts0.base_level = 0; - ts->ts0.mip_filter = MIPFILTER_NONE; /* NONE */ - ts->ts0.mag_filter = MAPFILTER_LINEAR; /* LINEAR */ - ts->ts0.min_filter = MAPFILTER_LINEAR; /* LINEAR */ - ts->ts0.lod_bias = 0; /* 0.0 */ - ts->ts0.shadow_enable = 0; - ts->ts0.max_anisotropy = ANISORATIO_2; - ts->ts0.shadow_function = PREFILTEROP_ALWAYS; - ts->ts1.min_lod = 0; /* 0.0 Maximum Mip Level */ - ts->ts1.kill_pixel = 0; - ts->ts1.keyed_texture_filter = 0; - ts->ts1.chromakey_enable = 0; - ts->ts1.tcx_control = TEXCOORDMODE_CLAMP; - ts->ts1.tcy_control = TEXCOORDMODE_CLAMP; - ts->ts1.tcz_control = TEXCOORDMODE_CLAMP; - ts->ts1.normalized_coor = 0; - ts->ts1.map_index = 1; - ts->ts1.east_deinterlacer = 0; - ts->ts2.default_color = 0; -} - static void i915_inst_arith(unsigned int *inst, unsigned int op, unsigned int dest, @@ -695,191 +124,245 @@ static void i915_inst_texld(unsigned int *inst, *inst = T2_MBZ; } -static void i915_mc_pixel_shader_program_buffer(XvMCContext *context) +static void i915_emit_batch(void *data, int size, int flag) +{ + intelBatchbufferData(data, size, flag); +} + +/* one time context initialization buffer */ +static uint32_t *one_time_load_state_imm1; +static uint32_t *one_time_load_indirect; +static int one_time_load_state_imm1_size, one_time_load_indirect_size; + +/* load indirect buffer for mc rendering */ +static uint32_t *mc_render_load_indirect; +static int mc_render_load_indirect_size; + +static void i915_mc_one_time_context_init(XvMCContext *context) { - struct i915_3dstate_pixel_shader_program *pixel_shader_program; - i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData; - unsigned int *inst; unsigned int dest, src0, src1, src2; + i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData; + int i; + struct i915_3dstate_sampler_state *sampler_state; + struct i915_3dstate_pixel_shader_program *pixel_shader_program; + struct i915_3dstate_pixel_shader_constants *pixel_shader_constants; - /* Shader 0 */ + /* sampler static state */ + sampler_state = (struct i915_3dstate_sampler_state *)pI915XvMC->ssb.map; + /* pixel shader static state */ pixel_shader_program = (struct i915_3dstate_pixel_shader_program *)pI915XvMC->psp.map; + /* pixel shader contant static state */ + pixel_shader_constants = (struct i915_3dstate_pixel_shader_constants *)pI915XvMC->psc.map; + + memset(sampler_state, 0, sizeof(*sampler_state)); + sampler_state->dw0.type = CMD_3D; + sampler_state->dw0.opcode = OPC_3DSTATE_SAMPLER_STATE; + sampler_state->dw0.length = 6; + sampler_state->dw1.sampler_masker = SAMPLER_SAMPLER0 | SAMPLER_SAMPLER1; + + sampler_state->sampler0.ts0.reverse_gamma = 0; + sampler_state->sampler0.ts0.planar2packet = 0; + sampler_state->sampler0.ts0.color_conversion = 0; + sampler_state->sampler0.ts0.chromakey_index = 0; + sampler_state->sampler0.ts0.base_level = 0; + sampler_state->sampler0.ts0.mip_filter = MIPFILTER_NONE; /* NONE */ + sampler_state->sampler0.ts0.mag_filter = MAPFILTER_LINEAR; /* LINEAR */ + sampler_state->sampler0.ts0.min_filter = MAPFILTER_LINEAR; /* LINEAR */ + sampler_state->sampler0.ts0.lod_bias = 0; /* 0.0 */ + sampler_state->sampler0.ts0.shadow_enable = 0; + sampler_state->sampler0.ts0.max_anisotropy = ANISORATIO_2; + sampler_state->sampler0.ts0.shadow_function = PREFILTEROP_ALWAYS; + sampler_state->sampler0.ts1.min_lod = 0; /* 0.0 Maximum Mip Level */ + sampler_state->sampler0.ts1.kill_pixel = 0; + sampler_state->sampler0.ts1.keyed_texture_filter = 0; + sampler_state->sampler0.ts1.chromakey_enable = 0; + sampler_state->sampler0.ts1.tcx_control = TEXCOORDMODE_CLAMP; + sampler_state->sampler0.ts1.tcy_control = TEXCOORDMODE_CLAMP; + sampler_state->sampler0.ts1.tcz_control = TEXCOORDMODE_CLAMP; + sampler_state->sampler0.ts1.normalized_coor = 0; + sampler_state->sampler0.ts1.map_index = 0; + sampler_state->sampler0.ts1.east_deinterlacer = 0; + sampler_state->sampler0.ts2.default_color = 0; + + sampler_state->sampler1.ts0.reverse_gamma = 0; + sampler_state->sampler1.ts0.planar2packet = 0; + sampler_state->sampler1.ts0.color_conversion = 0; + sampler_state->sampler1.ts0.chromakey_index = 0; + sampler_state->sampler1.ts0.base_level = 0; + sampler_state->sampler1.ts0.mip_filter = MIPFILTER_NONE; /* NONE */ + sampler_state->sampler1.ts0.mag_filter = MAPFILTER_LINEAR; /* LINEAR */ + sampler_state->sampler1.ts0.min_filter = MAPFILTER_LINEAR; /* LINEAR */ + sampler_state->sampler1.ts0.lod_bias = 0; /* 0.0 */ + sampler_state->sampler1.ts0.shadow_enable = 0; + sampler_state->sampler1.ts0.max_anisotropy = ANISORATIO_2; + sampler_state->sampler1.ts0.shadow_function = PREFILTEROP_ALWAYS; + sampler_state->sampler1.ts1.min_lod = 0; /* 0.0 Maximum Mip Level */ + sampler_state->sampler1.ts1.kill_pixel = 0; + sampler_state->sampler1.ts1.keyed_texture_filter = 0; + sampler_state->sampler1.ts1.chromakey_enable = 0; + sampler_state->sampler1.ts1.tcx_control = TEXCOORDMODE_CLAMP; + sampler_state->sampler1.ts1.tcy_control = TEXCOORDMODE_CLAMP; + sampler_state->sampler1.ts1.tcz_control = TEXCOORDMODE_CLAMP; + sampler_state->sampler1.ts1.normalized_coor = 0; + sampler_state->sampler1.ts1.map_index = 1; + sampler_state->sampler1.ts1.east_deinterlacer = 0; + sampler_state->sampler1.ts2.default_color = 0; + memset(pixel_shader_program, 0, sizeof(*pixel_shader_program)); - pixel_shader_program->dw0.type = CMD_3D; - pixel_shader_program->dw0.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM; - pixel_shader_program->dw0.retain = 1; - pixel_shader_program->dw0.length = 2; - /* mov oC, c0.0000 */ - inst = (unsigned int*)(++pixel_shader_program); + pixel_shader_program->shader0.type = CMD_3D; + pixel_shader_program->shader0.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM; + pixel_shader_program->shader0.retain = 1; + pixel_shader_program->shader0.length = 2; /* 1 inst */ + i = 0; + dest = UREG(REG_TYPE_OC, 0); src0 = UREG(REG_TYPE_CONST, 0); src1 = 0; src2 = 0; - i915_inst_arith(inst, A0_MOV, dest, A0_DEST_CHANNEL_ALL, - A0_DEST_SATURATE, src0, src1, src2); - inst += 3; - - /* Shader 1 */ - pixel_shader_program = (struct i915_3dstate_pixel_shader_program *)inst; - memset(pixel_shader_program, 0, sizeof(*pixel_shader_program)); - pixel_shader_program->dw0.type = CMD_3D; - pixel_shader_program->dw0.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM; - pixel_shader_program->dw0.retain = 1; - pixel_shader_program->dw0.length = 14; + i915_inst_arith(&pixel_shader_program->inst0[i], A0_MOV, + dest, A0_DEST_CHANNEL_ALL, A0_DEST_SATURATE, src0, src1, src2); + + pixel_shader_program->shader1.type = CMD_3D; + pixel_shader_program->shader1.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM; + pixel_shader_program->shader1.retain = 1; + pixel_shader_program->shader1.length = 14; /* 5 inst */ + i = 0; /* dcl t0.xy */ - inst = (unsigned int*)(++pixel_shader_program); - i915_inst_decl(inst, REG_TYPE_T, T_TEX0, D0_CHANNEL_XY); + i915_inst_decl(&pixel_shader_program->inst1[i], REG_TYPE_T, T_TEX0, D0_CHANNEL_XY); + i+=3; /* dcl t1.xy */ - inst += 3; - i915_inst_decl(inst, REG_TYPE_T, T_TEX1, D0_CHANNEL_XY); + i915_inst_decl(&pixel_shader_program->inst1[i], REG_TYPE_T, T_TEX1, D0_CHANNEL_XY); /* dcl_2D s0 */ - inst += 3; - i915_inst_decl(inst, REG_TYPE_S, 0, D0_SAMPLE_TYPE_2D); + i += 3; + i915_inst_decl(&pixel_shader_program->inst1[i], REG_TYPE_S, 0, D0_SAMPLE_TYPE_2D); /* texld r0, t0, s0 */ - inst += 3; + i += 3; dest = UREG(REG_TYPE_R, 0); src0 = UREG(REG_TYPE_T, 0); /* COORD */ src1 = UREG(REG_TYPE_S, 0); /* SAMPLER */ - i915_inst_texld(inst, T0_TEXLD, dest, src0, src1); + i915_inst_texld(&pixel_shader_program->inst1[i], T0_TEXLD, dest, src0, src1); /* mov oC, r0 */ - inst += 3; + i += 3; dest = UREG(REG_TYPE_OC, 0); src0 = UREG(REG_TYPE_R, 0); src1 = src2 = 0; - i915_inst_arith(inst, A0_MOV, dest, A0_DEST_CHANNEL_ALL, + i915_inst_arith(&pixel_shader_program->inst1[i], A0_MOV, dest, A0_DEST_CHANNEL_ALL, A0_DEST_SATURATE, src0, src1, src2); - inst += 3; - /* Shader 2 */ - pixel_shader_program = (struct i915_3dstate_pixel_shader_program *)inst; - memset(pixel_shader_program, 0, sizeof(*pixel_shader_program)); - pixel_shader_program->dw0.type = CMD_3D; - pixel_shader_program->dw0.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM; - pixel_shader_program->dw0.retain = 1; - pixel_shader_program->dw0.length = 14; + + pixel_shader_program->shader2.type = CMD_3D; + pixel_shader_program->shader2.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM; + pixel_shader_program->shader2.retain = 1; + pixel_shader_program->shader2.length = 14; /* 5 inst */ + i = 0; /* dcl t2.xy */ - inst = (unsigned int*)(++pixel_shader_program); - i915_inst_decl(inst, REG_TYPE_T, T_TEX2, D0_CHANNEL_XY); + i915_inst_decl(&pixel_shader_program->inst2[i], REG_TYPE_T, T_TEX2, D0_CHANNEL_XY); /* dcl t3.xy */ - inst += 3; - i915_inst_decl(inst, REG_TYPE_T, T_TEX3, D0_CHANNEL_XY); + i += 3; + i915_inst_decl(&pixel_shader_program->inst2[i], REG_TYPE_T, T_TEX3, D0_CHANNEL_XY); /* dcl_2D s1 */ - inst += 3; - i915_inst_decl(inst, REG_TYPE_S, 1, D0_SAMPLE_TYPE_2D); + i += 3; + i915_inst_decl(&pixel_shader_program->inst2[i], REG_TYPE_S, 1, D0_SAMPLE_TYPE_2D); /* texld r0, t2, s1 */ - inst += 3; + i += 3; dest = UREG(REG_TYPE_R, 0); src0 = UREG(REG_TYPE_T, 2); /* COORD */ src1 = UREG(REG_TYPE_S, 1); /* SAMPLER */ - i915_inst_texld(inst, T0_TEXLD, dest, src0, src1); + i915_inst_texld(&pixel_shader_program->inst2[i], T0_TEXLD, dest, src0, src1); /* mov oC, r0 */ - inst += 3; + i += 3; dest = UREG(REG_TYPE_OC, 0); src0 = UREG(REG_TYPE_R, 0); src1 = src2 = 0; - i915_inst_arith(inst, A0_MOV, dest, A0_DEST_CHANNEL_ALL, + i915_inst_arith(&pixel_shader_program->inst2[i], A0_MOV, dest, A0_DEST_CHANNEL_ALL, A0_DEST_SATURATE, src0, src1, src2); - inst += 3; /* Shader 3 */ - pixel_shader_program = (struct i915_3dstate_pixel_shader_program *)inst; - memset(pixel_shader_program, 0, sizeof(*pixel_shader_program)); - pixel_shader_program->dw0.type = CMD_3D; - pixel_shader_program->dw0.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM; - pixel_shader_program->dw0.retain = 1; - pixel_shader_program->dw0.length = 29; + pixel_shader_program->shader3.type = CMD_3D; + pixel_shader_program->shader3.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM; + pixel_shader_program->shader3.retain = 1; + pixel_shader_program->shader3.length = 29; /* 10 inst */ + i = 0; /* dcl t0.xy */ - inst = (unsigned int*)(++pixel_shader_program); - i915_inst_decl(inst, REG_TYPE_T, T_TEX0, D0_CHANNEL_XY); + i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_T, T_TEX0, D0_CHANNEL_XY); /* dcl t1.xy */ - inst += 3; - i915_inst_decl(inst, REG_TYPE_T, T_TEX1, D0_CHANNEL_XY); + i += 3; + i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_T, T_TEX1, D0_CHANNEL_XY); /* dcl t2.xy */ - inst += 3; - i915_inst_decl(inst, REG_TYPE_T, T_TEX2, D0_CHANNEL_XY); + i += 3; + i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_T, T_TEX2, D0_CHANNEL_XY); /* dcl t3.xy */ - inst += 3; - i915_inst_decl(inst, REG_TYPE_T, T_TEX3, D0_CHANNEL_XY); + i += 3; + i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_T, T_TEX3, D0_CHANNEL_XY); /* dcl_2D s0 */ - inst += 3; - i915_inst_decl(inst, REG_TYPE_S, 0, D0_SAMPLE_TYPE_2D); + i += 3; + i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_S, 0, D0_SAMPLE_TYPE_2D); /* dcl_2D s1 */ - inst += 3; - i915_inst_decl(inst, REG_TYPE_S, 1, D0_SAMPLE_TYPE_2D); + i += 3; + i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_S, 1, D0_SAMPLE_TYPE_2D); /* texld r0, t0, s0 */ - inst += 3; + i += 3; dest = UREG(REG_TYPE_R, 0); src0 = UREG(REG_TYPE_T, 0); /* COORD */ src1 = UREG(REG_TYPE_S, 0); /* SAMPLER */ - i915_inst_texld(inst, T0_TEXLD, dest, src0, src1); + i915_inst_texld(&pixel_shader_program->inst3[i], T0_TEXLD, dest, src0, src1); /* texld r1, t2, s1 */ - inst += 3; + i += 3; dest = UREG(REG_TYPE_R, 1); src0 = UREG(REG_TYPE_T, 2); /* COORD */ src1 = UREG(REG_TYPE_S, 1); /* SAMPLER */ - i915_inst_texld(inst, T0_TEXLD, dest, src0, src1); + i915_inst_texld(&pixel_shader_program->inst3[i], T0_TEXLD, dest, src0, src1); /* add r0, r0, r1 */ - inst += 3; + i += 3; dest = UREG(REG_TYPE_R, 0); src0 = UREG(REG_TYPE_R, 0); src1 = UREG(REG_TYPE_R, 1); src2 = 0; - i915_inst_arith(inst, A0_ADD, dest, A0_DEST_CHANNEL_ALL, + i915_inst_arith(&pixel_shader_program->inst3[i], A0_ADD, dest, A0_DEST_CHANNEL_ALL, 0 /* A0_DEST_SATURATE */, src0, src1, src2); /* mul oC, r0, c0 */ - inst += 3; + i += 3; dest = UREG(REG_TYPE_OC, 0); src0 = UREG(REG_TYPE_R, 0); src1 = UREG(REG_TYPE_CONST, 0); src2 = 0; - i915_inst_arith(inst, A0_MUL, dest, A0_DEST_CHANNEL_ALL, + i915_inst_arith(&pixel_shader_program->inst3[i], A0_MUL, dest, A0_DEST_CHANNEL_ALL, A0_DEST_SATURATE, src0, src1, src2); - inst += 3; -} - -static void i915_mc_pixel_shader_constants_buffer(XvMCContext *context) -{ - struct i915_3dstate_pixel_shader_constants *pixel_shader_constants; - i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData; - float *value; - pixel_shader_constants = (struct i915_3dstate_pixel_shader_constants *)pI915XvMC->psc.map; memset(pixel_shader_constants, 0, sizeof(*pixel_shader_constants)); pixel_shader_constants->dw0.type = CMD_3D; pixel_shader_constants->dw0.opcode = OPC_3DSTATE_PIXEL_SHADER_CONSTANTS; pixel_shader_constants->dw0.length = 4; pixel_shader_constants->dw1.reg_mask = REG_CR0; - value = (float *)(++pixel_shader_constants); - *(value++) = 0.5; - *(value++) = 0.5; - *(value++) = 0.5; - *(value++) = 0.5; + pixel_shader_constants->value.x = 0.5; + pixel_shader_constants->value.y = 0.5; + pixel_shader_constants->value.z = 0.5; + pixel_shader_constants->value.w = 0.5; + } -static void i915_mc_one_time_state_initialization(XvMCContext *context) +static void i915_mc_one_time_state_init(XvMCContext *context) { - struct i915_3dstate_load_state_immediate_1 *load_state_immediate_1 = NULL; struct s3_dword *s3 = NULL; struct s6_dword *s6 = NULL; - struct i915_3dstate_load_indirect *load_indirect = NULL; dis_state *dis = NULL; ssb_state *ssb = NULL; psp_state *psp = NULL; psc_state *psc = NULL; i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData; - unsigned int size; - void *base = NULL; - int mem_select = 1; + struct i915_3dstate_load_state_immediate_1 *load_state_immediate_1; + struct i915_3dstate_load_indirect *load_indirect; + int mem_select; /* 3DSTATE_LOAD_STATE_IMMEDIATE_1 */ - size = sizeof(*load_state_immediate_1) + sizeof(*s3) + sizeof(*s6); - base = calloc(1, size); - load_state_immediate_1 = (struct i915_3dstate_load_state_immediate_1 *)base; + one_time_load_state_imm1_size = sizeof(*load_state_immediate_1) + sizeof(*s3) + sizeof(*s6); + one_time_load_state_imm1 = calloc(1, one_time_load_state_imm1_size); + load_state_immediate_1 = (struct i915_3dstate_load_state_immediate_1 *)one_time_load_state_imm1; load_state_immediate_1->dw0.type = CMD_3D; load_state_immediate_1->dw0.opcode = OPC_3DSTATE_LOAD_STATE_IMMEDIATE_1; load_state_immediate_1->dw0.load_s3 = 1; load_state_immediate_1->dw0.load_s6 = 1; - load_state_immediate_1->dw0.length = (size >> 2) - 2; + load_state_immediate_1->dw0.length = (one_time_load_state_imm1_size >> 2) - 2; s3 = (struct s3_dword *)(++load_state_immediate_1); s3->set0_pcd = 1; @@ -905,33 +388,31 @@ static void i915_mc_one_time_state_initialization(XvMCContext *context) s6->color_buffer_write = 1; s6->triangle_pv = 0; - intelBatchbufferData(base, size, 0); - free(base); - /* 3DSTATE_LOAD_INDIRECT */ - size = sizeof(*load_indirect) + sizeof(*dis) + sizeof(*ssb) + sizeof(*psp) + sizeof(*psc); - base = calloc(1, size); - load_indirect = (struct i915_3dstate_load_indirect *)base; + one_time_load_indirect_size = sizeof(*load_indirect) + sizeof(*dis) + sizeof(*ssb) + sizeof(*psp) + sizeof(*psc); + one_time_load_indirect = calloc(1, one_time_load_indirect_size); + load_indirect = (struct i915_3dstate_load_indirect *)one_time_load_indirect; load_indirect->dw0.type = CMD_3D; load_indirect->dw0.opcode = OPC_3DSTATE_LOAD_INDIRECT; load_indirect->dw0.block_mask = BLOCK_DIS | BLOCK_SSB | BLOCK_PSP | BLOCK_PSC; - load_indirect->dw0.length = (size >> 2) - 2; + load_indirect->dw0.length = (one_time_load_indirect_size >> 2) - 2; if (pI915XvMC->deviceID == PCI_CHIP_I915_G || - pI915XvMC->deviceID == PCI_CHIP_I915_GM || - pI915XvMC->deviceID == PCI_CHIP_I945_G || - pI915XvMC->deviceID == PCI_CHIP_I945_GM) - mem_select = 0; + pI915XvMC->deviceID == PCI_CHIP_I915_GM) + mem_select = 0; /* use physical address */ + else + mem_select = 1; /* use gfx address */ load_indirect->dw0.mem_select = mem_select; - /* DIS */ + + /* Dynamic indirect state buffer */ dis = (dis_state *)(++load_indirect); dis->dw0.valid = 0; dis->dw0.reset = 0; dis->dw0.buffer_address = 0; - /* SSB */ + /* Sample state buffer */ ssb = (ssb_state *)(++dis); ssb->dw0.valid = 1; ssb->dw0.force = 1; @@ -940,20 +421,20 @@ static void i915_mc_one_time_state_initialization(XvMCContext *context) if (mem_select) ssb->dw0.buffer_address = (pI915XvMC->ssb.offset >> 2); else - ssb->dw0.buffer_address = (pI915XvMC->ssb.bus_addr >> 2); + ssb->dw0.buffer_address = (pI915XvMC->ssb.bus_addr >> 2); - /* PSP */ + /* Pixel shader program buffer */ psp = (psp_state *)(++ssb); psp->dw0.valid = 1; psp->dw0.force = 1; psp->dw1.length = 66; /* 4 + 16 + 16 + 31 - 1 */ if (mem_select) - psp->dw0.buffer_address = (pI915XvMC->psp.offset >> 2); + psp->dw0.buffer_address = (pI915XvMC->psp.offset >> 2); else - psp->dw0.buffer_address = (pI915XvMC->psp.bus_addr >> 2); + psp->dw0.buffer_address = (pI915XvMC->psp.bus_addr >> 2); - /* PSC */ + /* Pixel shader constant buffer */ psc = (psc_state *)(++psp); psc->dw0.valid = 1; psc->dw0.force = 1; @@ -963,9 +444,483 @@ static void i915_mc_one_time_state_initialization(XvMCContext *context) psc->dw0.buffer_address = (pI915XvMC->psc.offset >> 2); else psc->dw0.buffer_address = (pI915XvMC->psc.bus_addr >> 2); +} - intelBatchbufferData(base, size, 0); - free(base); +static void i915_mc_one_time_state_emit(void) +{ + i915_emit_batch(one_time_load_state_imm1, one_time_load_state_imm1_size, 0); + i915_emit_batch(one_time_load_indirect, one_time_load_indirect_size, 0); +} + +static void i915_mc_static_indirect_state_init(XvMCContext *context) +{ + i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData; + struct i915_mc_static_indirect_state_buffer *buffer_info = + (struct i915_mc_static_indirect_state_buffer *)pI915XvMC->sis.map; + + memset(buffer_info, 0, sizeof(*buffer_info)); + /* dest Y */ + buffer_info->dest_y.dw0.type = CMD_3D; + buffer_info->dest_y.dw0.opcode = OPC_3DSTATE_BUFFER_INFO; + buffer_info->dest_y.dw0.length = 1; + buffer_info->dest_y.dw1.aux_id = 0; + buffer_info->dest_y.dw1.buffer_id = BUFFERID_COLOR_BACK; + buffer_info->dest_y.dw1.fence_regs = 0; /* disabled */ /* FIXME: tiled y for performance */ + buffer_info->dest_y.dw1.tiled_surface = 0; /* linear */ + buffer_info->dest_y.dw1.walk = TILEWALK_XMAJOR; + + /* dest U */ + buffer_info->dest_u.dw0.type = CMD_3D; + buffer_info->dest_u.dw0.opcode = OPC_3DSTATE_BUFFER_INFO; + buffer_info->dest_u.dw0.length = 1; + buffer_info->dest_u.dw1.aux_id = 0; + buffer_info->dest_u.dw1.buffer_id = BUFFERID_COLOR_AUX; + buffer_info->dest_u.dw1.fence_regs = 0; + buffer_info->dest_u.dw1.tiled_surface = 0; + buffer_info->dest_u.dw1.walk = TILEWALK_XMAJOR; + + /* dest V */ + buffer_info->dest_v.dw0.type = CMD_3D; + buffer_info->dest_v.dw0.opcode = OPC_3DSTATE_BUFFER_INFO; + buffer_info->dest_v.dw0.length = 1; + buffer_info->dest_v.dw1.aux_id = 1; + buffer_info->dest_v.dw1.buffer_id = BUFFERID_COLOR_AUX; + buffer_info->dest_v.dw1.fence_regs = 0; + buffer_info->dest_v.dw1.tiled_surface = 0; + buffer_info->dest_v.dw1.walk = TILEWALK_XMAJOR; + + buffer_info->dest_buf.dw0.type = CMD_3D; + buffer_info->dest_buf.dw0.opcode = OPC_3DSTATE_DEST_BUFFER_VARIABLES; + buffer_info->dest_buf.dw0.length = 0; + buffer_info->dest_buf.dw1.dest_v_bias = 8; /* 0.5 */ + buffer_info->dest_buf.dw1.dest_h_bias = 8; /* 0.5 */ + buffer_info->dest_buf.dw1.color_fmt = COLORBUFFER_8BIT; + buffer_info->dest_buf.dw1.v_ls = 0; /* fill later */ + buffer_info->dest_buf.dw1.v_ls_offset = 0; /* fill later */ + + buffer_info->dest_buf_mpeg.dw0.type = CMD_3D; + buffer_info->dest_buf_mpeg.dw0.opcode = OPC_3DSTATE_DEST_BUFFER_VARIABLES_MPEG; + buffer_info->dest_buf_mpeg.dw0.length = 1; + buffer_info->dest_buf_mpeg.dw1.decode_mode = MPEG_DECODE_MC; + buffer_info->dest_buf_mpeg.dw1.rcontrol = 0; /* for MPEG-1/MPEG-2 */ + buffer_info->dest_buf_mpeg.dw1.bidir_avrg_control = 0; /* for MPEG-1/MPEG-2/MPEG-4 */ + buffer_info->dest_buf_mpeg.dw1.abort_on_error = 1; + buffer_info->dest_buf_mpeg.dw1.intra8 = 0; /* 16-bit formatted correction data */ + buffer_info->dest_buf_mpeg.dw1.tff = 1; /* fill later */ + + buffer_info->dest_buf_mpeg.dw1.v_subsample_factor = MC_SUB_1V; + buffer_info->dest_buf_mpeg.dw1.h_subsample_factor = MC_SUB_1H; + + buffer_info->corr.dw0.type = CMD_3D; + buffer_info->corr.dw0.opcode = OPC_3DSTATE_BUFFER_INFO; + buffer_info->corr.dw0.length = 1; + buffer_info->corr.dw1.aux_id = 0; + buffer_info->corr.dw1.buffer_id = BUFFERID_MC_INTRA_CORR; + buffer_info->corr.dw1.aux_id = 0; + buffer_info->corr.dw1.fence_regs = 0; + buffer_info->corr.dw1.tiled_surface = 0; + buffer_info->corr.dw1.walk = 0; + buffer_info->corr.dw1.pitch = 0; + buffer_info->corr.dw2.base_address = (pI915XvMC->corrdata.offset >> 2); /* starting DWORD address */ +} + +static void i915_mc_static_indirect_state_set(XvMCContext *context, XvMCSurface *dest, + unsigned int picture_structure, unsigned int flags, unsigned int picture_coding_type) +{ + i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData; + i915XvMCSurface *pI915Surface = (i915XvMCSurface *)dest->privData; + struct i915_mc_static_indirect_state_buffer *buffer_info = + (struct i915_mc_static_indirect_state_buffer *)pI915XvMC->sis.map; + unsigned int w = dest->width; + + buffer_info->dest_y.dw1.pitch = (pI915Surface->yStride >> 2); /* in DWords */ + buffer_info->dest_y.dw2.base_address = (YOFFSET(pI915Surface) >> 2); /* starting DWORD address */ + buffer_info->dest_u.dw1.pitch = (pI915Surface->uvStride >> 2); /* in DWords */ + buffer_info->dest_u.dw2.base_address = (UOFFSET(pI915Surface) >> 2); /* starting DWORD address */ + buffer_info->dest_v.dw1.pitch = (pI915Surface->uvStride >> 2); /* in Dwords */ + buffer_info->dest_v.dw2.base_address = (VOFFSET(pI915Surface) >> 2); /* starting DWORD address */ + + if ((picture_structure & XVMC_FRAME_PICTURE) == XVMC_FRAME_PICTURE) { + ; + } else if ((picture_structure & XVMC_FRAME_PICTURE) == XVMC_TOP_FIELD) { + buffer_info->dest_buf.dw1.v_ls = 1; + } else if ((picture_structure & XVMC_FRAME_PICTURE) == XVMC_BOTTOM_FIELD) { + buffer_info->dest_buf.dw1.v_ls = 1; + buffer_info->dest_buf.dw1.v_ls_offset = 1; + } + + if (picture_structure & XVMC_FRAME_PICTURE) { + ; + } else if (picture_structure & XVMC_TOP_FIELD) { + if (flags & XVMC_SECOND_FIELD) + buffer_info->dest_buf_mpeg.dw1.tff = 0; + else + buffer_info->dest_buf_mpeg.dw1.tff = 1; + } else if (picture_structure & XVMC_BOTTOM_FIELD) { + if (flags & XVMC_SECOND_FIELD) + buffer_info->dest_buf_mpeg.dw1.tff = 1; + else + buffer_info->dest_buf_mpeg.dw1.tff = 0; + } + + buffer_info->dest_buf_mpeg.dw1.picture_width = (dest->width >> 4); /* in macroblocks */ + buffer_info->dest_buf_mpeg.dw2.picture_coding_type = picture_coding_type; +} + +static void i915_mc_map_state_init(XvMCContext *context) +{ + i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData; + unsigned int w = context->width; + unsigned int h = context->height; + struct i915_mc_map_state *map_state; + + map_state = (struct i915_mc_map_state *)pI915XvMC->msb.map; + + memset(map_state, 0, sizeof(*map_state)); + + /* 3DSATE_MAP_STATE: Y */ + map_state->y_map.dw0.type = CMD_3D; + map_state->y_map.dw0.opcode = OPC_3DSTATE_MAP_STATE; + map_state->y_map.dw0.retain = 1; + map_state->y_map.dw0.length = 6; + map_state->y_map.dw1.map_mask = MAP_MAP0 | MAP_MAP1; + + /* Y Forward (Past) */ + map_state->y_forward.tm0.v_ls_offset = 0; + map_state->y_forward.tm0.v_ls = 0; + map_state->y_forward.tm1.tile_walk = TILEWALK_XMAJOR; + map_state->y_forward.tm1.tiled_surface = 0; + map_state->y_forward.tm1.utilize_fence_regs = 0; + map_state->y_forward.tm1.texel_fmt = 0; /* 8bit */ + map_state->y_forward.tm1.surface_fmt = 1; /* 8bit */ + map_state->y_forward.tm1.width = w - 1; + map_state->y_forward.tm1.height = h - 1; + map_state->y_forward.tm2.depth = 0; + map_state->y_forward.tm2.max_lod = 0; + map_state->y_forward.tm2.cube_face = 0; + + /* Y Backward (Future) */ + map_state->y_backward.tm0.v_ls_offset = 0; + map_state->y_backward.tm0.v_ls = 0; + map_state->y_backward.tm1.tile_walk = TILEWALK_XMAJOR; + map_state->y_backward.tm1.tiled_surface = 0; + map_state->y_backward.tm1.utilize_fence_regs = 0; + map_state->y_backward.tm1.texel_fmt = 0; /* 8bit */ + map_state->y_backward.tm1.surface_fmt = 1; /* 8bit */ + map_state->y_backward.tm1.width = w - 1; + map_state->y_backward.tm1.height = h - 1; + map_state->y_backward.tm2.depth = 0; + map_state->y_backward.tm2.max_lod = 0; + map_state->y_backward.tm2.cube_face = 0; + + /* 3DSATE_MAP_STATE: U */ + map_state->u_map.dw0.type = CMD_3D; + map_state->u_map.dw0.opcode = OPC_3DSTATE_MAP_STATE; + map_state->u_map.dw0.retain = 1; + map_state->u_map.dw0.length = 6; + map_state->u_map.dw1.map_mask = MAP_MAP0 | MAP_MAP1; + + /* U Forward */ + map_state->u_forward.tm0.v_ls_offset = 0; + map_state->u_forward.tm0.v_ls = 0; + map_state->u_forward.tm1.tile_walk = TILEWALK_XMAJOR; + map_state->u_forward.tm1.tiled_surface = 0; + map_state->u_forward.tm1.utilize_fence_regs = 0; + map_state->u_forward.tm1.texel_fmt = 0; /* 8bit */ + map_state->u_forward.tm1.surface_fmt = 1; /* 8bit */ + map_state->u_forward.tm1.width = (w >> 1) - 1; + map_state->u_forward.tm1.height = (h >> 1) - 1; + map_state->u_forward.tm2.depth = 0; + map_state->u_forward.tm2.max_lod = 0; + map_state->u_forward.tm2.cube_face = 0; + + /* U Backward */ + map_state->u_backward.tm0.v_ls_offset = 0; + map_state->u_backward.tm0.v_ls = 0; + map_state->u_backward.tm1.tile_walk = TILEWALK_XMAJOR; + map_state->u_backward.tm1.tiled_surface = 0; + map_state->u_backward.tm1.utilize_fence_regs = 0; + map_state->u_backward.tm1.texel_fmt = 0; + map_state->u_backward.tm1.surface_fmt = 1; + map_state->u_backward.tm1.width = (w >> 1) - 1; + map_state->u_backward.tm1.height = (h >> 1) - 1; + map_state->u_backward.tm2.depth = 0; + map_state->u_backward.tm2.max_lod = 0; + map_state->u_backward.tm2.cube_face = 0; + + /* 3DSATE_MAP_STATE: V */ + map_state->v_map.dw0.type = CMD_3D; + map_state->v_map.dw0.opcode = OPC_3DSTATE_MAP_STATE; + map_state->v_map.dw0.retain = 1; + map_state->v_map.dw0.length = 6; + map_state->v_map.dw1.map_mask = MAP_MAP0 | MAP_MAP1; + + /* V Forward */ + map_state->v_forward.tm0.v_ls_offset = 0; + map_state->v_forward.tm0.v_ls = 0; + map_state->v_forward.tm1.tile_walk = TILEWALK_XMAJOR; + map_state->v_forward.tm1.tiled_surface = 0; + map_state->v_forward.tm1.utilize_fence_regs = 0; + map_state->v_forward.tm1.texel_fmt = 0; + map_state->v_forward.tm1.surface_fmt = 1; + map_state->v_forward.tm1.width = (w >> 1) - 1; + map_state->v_forward.tm1.height = (h >> 1) - 1; + map_state->v_forward.tm2.depth = 0; + map_state->v_forward.tm2.max_lod = 0; + map_state->v_forward.tm2.cube_face = 0; + + /* V Backward */ + map_state->v_backward.tm0.v_ls_offset = 0; + map_state->v_backward.tm0.v_ls = 0; + map_state->v_backward.tm1.tile_walk = TILEWALK_XMAJOR; + map_state->v_backward.tm1.tiled_surface = 0; + map_state->v_backward.tm1.utilize_fence_regs = 0; + map_state->v_backward.tm1.texel_fmt = 0; + map_state->v_backward.tm1.surface_fmt = 1; + map_state->v_backward.tm1.width = (w >> 1) - 1; + map_state->v_backward.tm1.height = (h >> 1) - 1; + map_state->v_backward.tm2.depth = 0; + map_state->v_backward.tm2.max_lod = 0; + map_state->v_backward.tm2.cube_face = 0; +} + +static void i915_mc_map_state_set(XvMCContext *context, + i915XvMCSurface *privPast, + i915XvMCSurface *privFuture) +{ + i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData; + struct i915_mc_map_state *map_state; + + map_state = (struct i915_mc_map_state *)pI915XvMC->msb.map; + + map_state->y_forward.tm0.base_address = (YOFFSET(privPast) >> 2); + map_state->y_forward.tm2.pitch = (privPast->yStride >> 2) - 1; /* in DWords - 1 */ + map_state->y_backward.tm0.base_address = (YOFFSET(privFuture) >> 2); + map_state->y_backward.tm2.pitch = (privFuture->yStride >> 2) - 1; + map_state->u_forward.tm0.base_address = (UOFFSET(privPast) >> 2); + map_state->u_forward.tm2.pitch = (privPast->uvStride >> 2) - 1; /* in DWords - 1 */ + map_state->u_backward.tm0.base_address = (UOFFSET(privFuture) >> 2); + map_state->u_backward.tm2.pitch = (privFuture->uvStride >> 2) - 1; + map_state->v_forward.tm0.base_address = (VOFFSET(privPast) >> 2); + map_state->v_forward.tm2.pitch = (privPast->uvStride >> 2) - 1; /* in DWords - 1 */ + map_state->v_backward.tm0.base_address = (VOFFSET(privFuture) >> 2); + map_state->v_backward.tm2.pitch = (privFuture->uvStride >> 2) - 1; +} + +static void i915_flush(int map, int render) +{ + struct i915_mi_flush mi_flush; + + memset(&mi_flush, 0, sizeof(mi_flush)); + mi_flush.dw0.type = CMD_MI; + mi_flush.dw0.opcode = OPC_MI_FLUSH; + mi_flush.dw0.map_cache_invalidate = map; + mi_flush.dw0.render_cache_flush_inhibit = render; + + intelBatchbufferData(&mi_flush, sizeof(mi_flush), 0); +} + +static void i915_mc_load_indirect_render_init(XvMCContext *context) +{ + i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData; + sis_state *sis; + msb_state *msb; + struct i915_3dstate_load_indirect *load_indirect; + int mem_select; + + mc_render_load_indirect_size = sizeof(*load_indirect) + sizeof(*sis) + + sizeof(*msb); + mc_render_load_indirect = calloc(1, mc_render_load_indirect_size); + + load_indirect = (struct i915_3dstate_load_indirect *)mc_render_load_indirect; + load_indirect->dw0.type = CMD_3D; + load_indirect->dw0.opcode = OPC_3DSTATE_LOAD_INDIRECT; + load_indirect->dw0.block_mask = BLOCK_SIS | BLOCK_MSB; + load_indirect->dw0.length = (mc_render_load_indirect_size >> 2) - 2; + + if (pI915XvMC->deviceID == PCI_CHIP_I915_G || + pI915XvMC->deviceID == PCI_CHIP_I915_GM) + mem_select = 0; + else + mem_select = 1; + + load_indirect->dw0.mem_select = mem_select; + + /* Static Indirect state buffer (dest buffer info) */ + sis = (sis_state *)(++load_indirect); + sis->dw0.valid = 1; + sis->dw0.force = 1; + sis->dw1.length = 16; /* 4 * 3 + 2 + 3 - 1 */ + + if (mem_select) + sis->dw0.buffer_address = (pI915XvMC->sis.offset >> 2); + else + sis->dw0.buffer_address = (pI915XvMC->sis.bus_addr >> 2); + + /* Map state buffer (reference buffer info) */ + msb = (msb_state *)(++sis); + msb->dw0.valid = 1; + msb->dw0.force = 1; + msb->dw1.length = 23; /* 3 * 8 - 1 */ + + if (mem_select) + msb->dw0.buffer_address = (pI915XvMC->msb.offset >> 2); + else + msb->dw0.buffer_address = (pI915XvMC->msb.bus_addr >> 2); +} + +static void i915_mc_load_indirect_render_emit(void) +{ + i915_emit_batch(mc_render_load_indirect, mc_render_load_indirect_size, 0); +} + +static void i915_mc_mpeg_set_origin(XvMCContext *context, XvMCMacroBlock *mb) +{ + struct i915_3dmpeg_set_origin set_origin; + + /* 3DMPEG_SET_ORIGIN */ + memset(&set_origin, 0, sizeof(set_origin)); + set_origin.dw0.type = CMD_3D; + set_origin.dw0.opcode = OPC_3DMPEG_SET_ORIGIN; + set_origin.dw0.length = 0; + set_origin.dw1.h_origin = mb->x; + set_origin.dw1.v_origin = mb->y; + + intelBatchbufferData(&set_origin, sizeof(set_origin), 0); +} + +static void i915_mc_mpeg_macroblock_ipicture(XvMCContext *context, XvMCMacroBlock *mb) +{ + struct i915_3dmpeg_macroblock_ipicture macroblock_ipicture; + + /* 3DMPEG_MACROBLOCK_IPICTURE */ + memset(¯oblock_ipicture, 0, sizeof(macroblock_ipicture)); + macroblock_ipicture.dw0.type = CMD_3D; + macroblock_ipicture.dw0.opcode = OPC_3DMPEG_MACROBLOCK_IPICTURE; + macroblock_ipicture.dw0.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD); + + intelBatchbufferData(¯oblock_ipicture, sizeof(macroblock_ipicture), 0); +} + +#if 0 +static void i915_mc_mpeg_macroblock_0mv(XvMCContext *context, XvMCMacroBlock *mb) +{ + struct i915_3dmpeg_macroblock_0mv macroblock_0mv; + + /* 3DMPEG_MACROBLOCK(0mv) */ + memset(¯oblock_0mv, 0, sizeof(macroblock_0mv)); + macroblock_0mv.header.dw0.type = CMD_3D; + macroblock_0mv.header.dw0.opcode = OPC_3DMPEG_MACROBLOCK; + macroblock_0mv.header.dw0.length = 0; + macroblock_0mv.header.dw1.mb_intra = 1; /* should be 1 */ + macroblock_0mv.header.dw1.forward = 0; /* should be 0 */ + macroblock_0mv.header.dw1.backward = 0; /* should be 0 */ + macroblock_0mv.header.dw1.h263_4mv = 0; /* should be 0 */ + macroblock_0mv.header.dw1.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD); + +/* + if (!mb->coded_block_pattern) + macroblock_0mv.header.dw1.dct_type = XVMC_DCT_TYPE_FRAME; +*/ + + macroblock_0mv.header.dw1.motion_type = 0; // (mb->motion_type & 0x3); + macroblock_0mv.header.dw1.vertical_field_select = 0; // mb->motion_vertical_field_select & 0xf; + macroblock_0mv.header.dw1.coded_block_pattern = mb->coded_block_pattern; + macroblock_0mv.header.dw1.skipped_macroblocks = 0; + + intelBatchbufferData(¯oblock_0mv, sizeof(macroblock_0mv), 0); +} +#endif + +static void i915_mc_mpeg_macroblock_1fbmv(XvMCContext *context, XvMCMacroBlock *mb) +{ + struct i915_3dmpeg_macroblock_1fbmv macroblock_1fbmv; + vector_t mv0[2]; + + /* 3DMPEG_MACROBLOCK(1fbmv) */ + memset(¯oblock_1fbmv, 0, sizeof(macroblock_1fbmv)); + macroblock_1fbmv.header.dw0.type = CMD_3D; + macroblock_1fbmv.header.dw0.opcode = OPC_3DMPEG_MACROBLOCK; + macroblock_1fbmv.header.dw0.length = 2; + macroblock_1fbmv.header.dw1.mb_intra = 0; /* should be 0 */ + macroblock_1fbmv.header.dw1.forward = ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_FORWARD) ? 1 : 0); + macroblock_1fbmv.header.dw1.backward = ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_BACKWARD) ? 1 : 0); + macroblock_1fbmv.header.dw1.h263_4mv = 0; /* should be 0 */ + macroblock_1fbmv.header.dw1.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD); + + if (!(mb->coded_block_pattern & 0x3f)) + macroblock_1fbmv.header.dw1.dct_type = XVMC_DCT_TYPE_FRAME; + + macroblock_1fbmv.header.dw1.motion_type = (mb->motion_type & 0x03); + macroblock_1fbmv.header.dw1.vertical_field_select = (mb->motion_vertical_field_select & 0x0f); + macroblock_1fbmv.header.dw1.coded_block_pattern = mb->coded_block_pattern; + macroblock_1fbmv.header.dw1.skipped_macroblocks = 0; + + mv0[0].component[0] = mb->PMV[0][0][0]; + mv0[0].component[1] = mb->PMV[0][0][1]; + mv0[1].component[0] = mb->PMV[0][1][0]; + mv0[1].component[1] = mb->PMV[0][1][1]; + + macroblock_1fbmv.dw2 = mv0[0].v; + macroblock_1fbmv.dw3 = mv0[1].v; + + intelBatchbufferData(¯oblock_1fbmv, sizeof(macroblock_1fbmv), 0); +} + +static void i915_mc_mpeg_macroblock_2fbmv(XvMCContext *context, XvMCMacroBlock *mb, unsigned int ps) +{ + struct i915_3dmpeg_macroblock_2fbmv macroblock_2fbmv; + vector_t mv0[2]; + vector_t mv1[2]; + + /* 3DMPEG_MACROBLOCK(2fbmv) */ + memset(¯oblock_2fbmv, 0, sizeof(macroblock_2fbmv)); + macroblock_2fbmv.header.dw0.type = CMD_3D; + macroblock_2fbmv.header.dw0.opcode = OPC_3DMPEG_MACROBLOCK; + macroblock_2fbmv.header.dw0.length = 4; + macroblock_2fbmv.header.dw1.mb_intra = 0; /* should be 0 */ + macroblock_2fbmv.header.dw1.forward = ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_FORWARD) ? 1 : 0); + macroblock_2fbmv.header.dw1.backward = ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_BACKWARD) ? 1 : 0); + macroblock_2fbmv.header.dw1.h263_4mv = 0; /* should be 0 */ + macroblock_2fbmv.header.dw1.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD); + + if (!(mb->coded_block_pattern & 0x3f)) + macroblock_2fbmv.header.dw1.dct_type = XVMC_DCT_TYPE_FRAME; + + macroblock_2fbmv.header.dw1.motion_type = (mb->motion_type & 0x03); + macroblock_2fbmv.header.dw1.vertical_field_select = (mb->motion_vertical_field_select & 0x0f); + macroblock_2fbmv.header.dw1.coded_block_pattern = mb->coded_block_pattern; + macroblock_2fbmv.header.dw1.skipped_macroblocks = 0; + + mv0[0].component[0] = mb->PMV[0][0][0]; + mv0[0].component[1] = mb->PMV[0][0][1]; + mv0[1].component[0] = mb->PMV[0][1][0]; + mv0[1].component[1] = mb->PMV[0][1][1]; + mv1[0].component[0] = mb->PMV[1][0][0]; + mv1[0].component[1] = mb->PMV[1][0][1]; + mv1[1].component[0] = mb->PMV[1][1][0]; + mv1[1].component[1] = mb->PMV[1][1][1]; + + if ((ps & XVMC_FRAME_PICTURE) == XVMC_FRAME_PICTURE) { + if ((mb->motion_type & 3) == XVMC_PREDICTION_FIELD) { + mv0[0].component[1] = mb->PMV[0][0][1] >> 1; + mv0[1].component[1] = mb->PMV[0][1][1] >> 1; + mv1[0].component[1] = mb->PMV[1][0][1] >> 1; + mv1[1].component[1] = mb->PMV[1][1][1] >> 1; + } else if ((mb->motion_type & 3) == XVMC_PREDICTION_DUAL_PRIME) { + mv0[0].component[1] = mb->PMV[0][0][1] >> 1; + mv0[1].component[1] = mb->PMV[0][1][1] >> 1; // MPEG2 MV[0][1] isn't used + mv1[0].component[1] = mb->PMV[1][0][1] >> 1; + mv1[1].component[1] = mb->PMV[1][1][1] >> 1; + } + } + + macroblock_2fbmv.dw2 = mv0[0].v; + macroblock_2fbmv.dw3 = mv0[1].v; + macroblock_2fbmv.dw4 = mv1[0].v; + macroblock_2fbmv.dw5 = mv1[1].v; + + intelBatchbufferData(¯oblock_2fbmv, sizeof(macroblock_2fbmv), 0); } #if 0 @@ -1646,9 +1601,7 @@ static Status i915_xvmc_mc_create_context(Display *display, XvMCContext *context pI915XvMC->psc.size = tmpComm->psc.size; if (pI915XvMC->deviceID == PCI_CHIP_I915_G || - pI915XvMC->deviceID == PCI_CHIP_I915_GM || - pI915XvMC->deviceID == PCI_CHIP_I945_G || - pI915XvMC->deviceID == PCI_CHIP_I945_GM) { + pI915XvMC->deviceID == PCI_CHIP_I915_GM) { pI915XvMC->sis.bus_addr = tmpComm->sis.bus_addr; pI915XvMC->ssb.bus_addr = tmpComm->ssb.bus_addr; pI915XvMC->msb.bus_addr = tmpComm->msb.bus_addr; @@ -1683,6 +1636,16 @@ static Status i915_xvmc_mc_create_context(Display *display, XvMCContext *context pI915XvMC->last_flip = 0; pI915XvMC->port = context->port; pI915XvMC->ref = 1; + + /* pre-init state buffers */ + i915_mc_one_time_context_init(context); + i915_mc_one_time_state_init(context); + + i915_mc_static_indirect_state_init(context); + + i915_mc_map_state_init(context); + + i915_mc_load_indirect_render_init(context); return Success; } @@ -1695,6 +1658,10 @@ static int i915_xvmc_mc_destroy_context(Display *display, XvMCContext *context) /* Pass Control to the X server to destroy the drm_context_t */ i915_release_resource(display,context); + + free(one_time_load_state_imm1); + free(one_time_load_indirect); + free(mc_render_load_indirect); return Success; } @@ -1850,9 +1817,8 @@ static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context, if (!(privTarget = target_surface->privData)) return XvMCBadSurface; - /* Test For YV12 Surface */ - if (context->surface_type_id != FOURCC_YV12) { - XVMC_ERR("HWMC only possible on YV12 Surfaces."); + if (context->surface_type_id >= SURFACE_TYPE_MAX) { + XVMC_ERR("Unsupprted surface_type_id %d.", context->surface_type_id); return BadValue; } @@ -1938,16 +1904,15 @@ static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context, // i915_mc_invalidate_subcontext_buffers(context, BLOCK_SIS | BLOCK_DIS | BLOCK_SSB // | BLOCK_MSB | BLOCK_PSP | BLOCK_PSC); - i915_mc_sampler_state_buffer(context); - i915_mc_pixel_shader_program_buffer(context); - i915_mc_pixel_shader_constants_buffer(context); - i915_mc_one_time_state_initialization(context); + i915_mc_one_time_state_emit(); + + i915_mc_static_indirect_state_set(context, target_surface, picture_structure, + flags, picture_coding_type); + /* setup reference surfaces */ + i915_mc_map_state_set(context, privPast, privFuture); + + i915_mc_load_indirect_render_emit(); - i915_mc_static_indirect_state_buffer(context, target_surface, - picture_structure, flags, - picture_coding_type); - i915_mc_map_state_buffer(context, privTarget, privPast, privFuture); - i915_mc_load_sis_msb_buffers(context); i915_mc_mpeg_set_origin(context, ¯oblock_array->macro_blocks[first_macroblock]); for (i = first_macroblock; i < (num_macroblocks + first_macroblock); i++) { diff --git a/src/xvmc/intel_xvmc.c b/src/xvmc/intel_xvmc.c index ae357aa5..8fabb35e 100644 --- a/src/xvmc/intel_xvmc.c +++ b/src/xvmc/intel_xvmc.c @@ -98,9 +98,17 @@ unsigned int mb_bytes_420[] = { 768 /* 111111 */ }; +int DEBUG; + static int error_base; static int event_base; +static void intel_xvmc_debug_init(void) +{ + if (getenv("INTEL_XVMC_DEBUG")) + DEBUG = 1; +} + /* locking */ static void intel_xvmc_try_heavy_lock(drm_context_t ctx) { @@ -282,6 +290,8 @@ Status XvMCCreateContext(Display *display, XvPortID port, return BadValue; } + intel_xvmc_debug_init(); + /* Open DRI Device */ if((fd = drmOpen("i915", NULL)) < 0) { XVMC_ERR("DRM Device could not be opened."); @@ -588,7 +598,7 @@ Status XvMCCreateBlocks(Display *display, XvMCContext *context, */ Status XvMCDestroyBlocks(Display *display, XvMCBlockArray *block) { - if (!display || block) + if (!display || !block) return BadValue; if (block->blocks) diff --git a/src/xvmc/intel_xvmc.h b/src/xvmc/intel_xvmc.h index 31196238..c4dfd770 100644 --- a/src/xvmc/intel_xvmc.h +++ b/src/xvmc/intel_xvmc.h @@ -38,6 +38,7 @@ #include <string.h> #include <assert.h> #include <signal.h> +#include <stdint.h> #include <xf86drm.h> #include "i830_common.h" @@ -56,7 +57,7 @@ #include "intel_batchbuffer.h" -#define DEBUG 0 +extern int DEBUG; #define XVMC_ERR(s, arg...) \ do { \ diff --git a/src/xvmc/intel_xvmc_dump.c b/src/xvmc/intel_xvmc_dump.c index 12fc52a5..419bd0d8 100644 --- a/src/xvmc/intel_xvmc_dump.c +++ b/src/xvmc/intel_xvmc_dump.c @@ -116,18 +116,25 @@ void intel_xvmc_dump_render(XvMCContext *context, unsigned int picture_structure fprintf(fp, "intra "); fprintf(fp, ") "); fprintf(fp, "mc type "); - if (mb->motion_type & XVMC_PREDICTION_FIELD) - fprintf(fp, "(field) "); - else if (mb->motion_type & XVMC_PREDICTION_FRAME) - fprintf(fp, "(frame) "); - else if (mb->motion_type & XVMC_PREDICTION_DUAL_PRIME) - fprintf(fp, "(dual-prime) "); - else if (mb->motion_type & XVMC_PREDICTION_16x8) - fprintf(fp, "(16x8) "); - else if (mb->motion_type & XVMC_PREDICTION_4MV) - fprintf(fp, "(4MV) "); - else - fprintf(fp, "(none) "); + if (picture_structure == XVMC_FRAME_PICTURE) { + if (mb->motion_type & XVMC_PREDICTION_FIELD) + fprintf(fp, "(field) "); + else if (mb->motion_type & XVMC_PREDICTION_FRAME) + fprintf(fp, "(frame) "); + else if (mb->motion_type & XVMC_PREDICTION_DUAL_PRIME) + fprintf(fp, "(dual-prime) "); + else + fprintf(fp, "(unknown %d) ", mb->motion_type); + } else { /* field */ + if (mb->motion_type & XVMC_PREDICTION_FIELD) + fprintf(fp, "(field) "); + else if (mb->motion_type & XVMC_PREDICTION_DUAL_PRIME) + fprintf(fp, "(dual-prime) "); + else if (mb->motion_type & XVMC_PREDICTION_16x8) + fprintf(fp, "(16x8) "); + else + fprintf(fp, "(unknown %d) ", mb->motion_type); + } if (mb->dct_type == XVMC_DCT_TYPE_FRAME) fprintf(fp, "dct type (frame) "); |