diff options
Diffstat (limited to 'i965_drv_video/i965_media.c')
-rw-r--r-- | i965_drv_video/i965_media.c | 283 |
1 files changed, 283 insertions, 0 deletions
diff --git a/i965_drv_video/i965_media.c b/i965_drv_video/i965_media.c new file mode 100644 index 0000000..f7d5846 --- /dev/null +++ b/i965_drv_video/i965_media.c @@ -0,0 +1,283 @@ +/* + * Copyright © 2009 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Xiang Haihao <haihao.xiang@intel.com> + * Zou Nan hai <nanhai.zou@intel.com> + * + */ + +#include <stdio.h> +#include <string.h> +#include <assert.h> + +#include "va_backend.h" + +#include "intel_batchbuffer.h" +#include "intel_driver.h" + +#include "i965_defines.h" +#include "i965_media_mpeg2.h" +#include "i965_media.h" +#include "i965_drv_video.h" + +static void +i965_media_pipeline_select(VADriverContextP ctx) +{ + BEGIN_BATCH(ctx, 1); + OUT_BATCH(ctx, CMD_PIPELINE_SELECT | PIPELINE_SELECT_MEDIA); + ADVANCE_BATCH(ctx); +} + +static void +i965_media_urb_layout(VADriverContextP ctx) +{ + struct i965_driver_data *i965 = i965_driver_data(ctx); + struct i965_media_state *media_state = &i965->media_state; + unsigned int vfe_fence, cs_fence; + + vfe_fence = media_state->urb.cs_start; + cs_fence = URB_SIZE((&i965->intel)); + + BEGIN_BATCH(ctx, 3); + OUT_BATCH(ctx, CMD_URB_FENCE | UF0_VFE_REALLOC | UF0_CS_REALLOC | 1); + OUT_BATCH(ctx, 0); + OUT_BATCH(ctx, + (vfe_fence << UF2_VFE_FENCE_SHIFT) | /* VFE_SIZE */ + (cs_fence << UF2_CS_FENCE_SHIFT)); /* CS_SIZE */ + ADVANCE_BATCH(ctx); +} + +static void +i965_media_state_base_address(VADriverContextP ctx) +{ + struct i965_driver_data *i965 = i965_driver_data(ctx); + + if (IS_IGDNG(i965->intel.device_id)) { + BEGIN_BATCH(ctx, 8); + OUT_BATCH(ctx, CMD_STATE_BASE_ADDRESS | 6); + OUT_BATCH(ctx, 0 | BASE_ADDRESS_MODIFY); + OUT_BATCH(ctx, 0 | BASE_ADDRESS_MODIFY); + OUT_BATCH(ctx, 0 | BASE_ADDRESS_MODIFY); + OUT_BATCH(ctx, 0 | BASE_ADDRESS_MODIFY); + OUT_BATCH(ctx, 0 | BASE_ADDRESS_MODIFY); + OUT_BATCH(ctx, 0 | BASE_ADDRESS_MODIFY); + OUT_BATCH(ctx, 0 | BASE_ADDRESS_MODIFY); + ADVANCE_BATCH(ctx); + } else { + BEGIN_BATCH(ctx, 6); + OUT_BATCH(ctx, CMD_STATE_BASE_ADDRESS | 4); + OUT_BATCH(ctx, 0 | BASE_ADDRESS_MODIFY); + OUT_BATCH(ctx, 0 | BASE_ADDRESS_MODIFY); + OUT_BATCH(ctx, 0 | BASE_ADDRESS_MODIFY); + OUT_BATCH(ctx, 0 | BASE_ADDRESS_MODIFY); + OUT_BATCH(ctx, 0 | BASE_ADDRESS_MODIFY); + ADVANCE_BATCH(ctx); + } +} + +static void +i965_media_state_pointers(VADriverContextP ctx) +{ + struct i965_driver_data *i965 = i965_driver_data(ctx); + struct i965_media_state *media_state = &i965->media_state; + + BEGIN_BATCH(ctx, 3); + OUT_BATCH(ctx, CMD_MEDIA_STATE_POINTERS | 1); + + if (media_state->extended_state.enabled) + OUT_RELOC(ctx, media_state->extended_state.bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 1); + else + OUT_BATCH(ctx, 0); + + OUT_RELOC(ctx, media_state->vfe_state.bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0); + ADVANCE_BATCH(ctx); +} + +static void +i965_media_cs_urb_layout(VADriverContextP ctx) +{ + struct i965_driver_data *i965 = i965_driver_data(ctx); + struct i965_media_state *media_state = &i965->media_state; + + BEGIN_BATCH(ctx, 2); + OUT_BATCH(ctx, CMD_CS_URB_STATE | 0); + OUT_BATCH(ctx, + ((media_state->urb.size_cs_entry - 1) << 4) | /* URB Entry Allocation Size */ + (media_state->urb.num_cs_entries << 0)); /* Number of URB Entries */ + ADVANCE_BATCH(ctx); +} + +static void +i965_media_pipeline_state(VADriverContextP ctx) +{ + i965_media_state_base_address(ctx); + i965_media_state_pointers(ctx); + i965_media_cs_urb_layout(ctx); +} + +static void +i965_media_constant_buffer(VADriverContextP ctx, struct decode_state *decode_state) +{ + struct i965_driver_data *i965 = i965_driver_data(ctx); + struct i965_media_state *media_state = &i965->media_state; + + BEGIN_BATCH(ctx, 2); + OUT_BATCH(ctx, CMD_CONSTANT_BUFFER | (1 << 8) | (2 - 2)); + OUT_RELOC(ctx, media_state->curbe.bo, + I915_GEM_DOMAIN_INSTRUCTION, 0, + media_state->urb.size_cs_entry - 1); + ADVANCE_BATCH(ctx); +} + +static void +i965_media_pipeline_setup(VADriverContextP ctx, struct decode_state *decode_state) +{ + struct i965_driver_data *i965 = i965_driver_data(ctx); + struct i965_media_state *media_state = &i965->media_state; + + intel_batchbuffer_start_atomic(ctx, 0x1000); + intel_batchbuffer_emit_mi_flush(ctx); /* step 1 */ + i965_media_pipeline_select(ctx); /* step 2 */ + i965_media_urb_layout(ctx); /* step 3 */ + i965_media_pipeline_state(ctx); /* step 4 */ + i965_media_constant_buffer(ctx, decode_state); /* step 5 */ + assert(media_state->media_objects); + media_state->media_objects(ctx, decode_state); /* step 6 */ + intel_batchbuffer_end_atomic(ctx); +} + +static void +i965_media_decode_init(VADriverContextP ctx, VAProfile profile) +{ + int i; + struct i965_driver_data *i965 = i965_driver_data(ctx); + struct i965_media_state *media_state = &i965->media_state; + dri_bo *bo; + + /* constant buffer */ + dri_bo_unreference(media_state->curbe.bo); + bo = dri_bo_alloc(i965->intel.bufmgr, + "constant buffer", + 4096, 64); + assert(bo); + media_state->curbe.bo = bo; + + /* surface state */ + for (i = 0; i < MAX_MEDIA_SURFACES; i++) { + dri_bo_unreference(media_state->surface_state[i].bo); + media_state->surface_state[i].bo = NULL; + } + + /* binding table */ + dri_bo_unreference(media_state->binding_table.bo); + bo = dri_bo_alloc(i965->intel.bufmgr, + "binding table", + MAX_MEDIA_SURFACES * sizeof(unsigned int), 32); + assert(bo); + media_state->binding_table.bo = bo; + + /* interface descriptor remapping table */ + dri_bo_unreference(media_state->idrt.bo); + bo = dri_bo_alloc(i965->intel.bufmgr, + "interface discriptor", + MAX_INTERFACE_DESC * sizeof(struct i965_interface_descriptor), 16); + assert(bo); + media_state->idrt.bo = bo; + + /* vfe state */ + dri_bo_unreference(media_state->vfe_state.bo); + bo = dri_bo_alloc(i965->intel.bufmgr, + "vfe state", + sizeof(struct i965_vfe_state), 32); + assert(bo); + media_state->vfe_state.bo = bo; + + /* extended state */ + media_state->extended_state.enabled = 0; + + switch (profile) { + case VAProfileMPEG2Simple: + case VAProfileMPEG2Main: + i965_media_mpeg2_decode_init(ctx); + break; + + default: + assert(0); + break; + } +} + +void +i965_media_decode_picture(VADriverContextP ctx, + VAProfile profile, + struct decode_state *decode_state) +{ + struct i965_driver_data *i965 = i965_driver_data(ctx); + struct i965_media_state *media_state = &i965->media_state; + + i965_media_decode_init(ctx, profile); + assert(media_state->states_setup); + media_state->states_setup(ctx, decode_state); + i965_media_pipeline_setup(ctx, decode_state); + intel_batchbuffer_flush(ctx); +} + +Bool +i965_media_init(VADriverContextP ctx) +{ + i965_media_mpeg2_init(ctx); + return True; +} + +Bool +i965_media_terminate(VADriverContextP ctx) +{ + struct i965_driver_data *i965 = i965_driver_data(ctx); + struct i965_media_state *media_state = &i965->media_state; + int i; + + for (i = 0; i < MAX_MEDIA_SURFACES; i++) { + dri_bo_unreference(media_state->surface_state[i].bo); + media_state->surface_state[i].bo = NULL; + } + + dri_bo_unreference(media_state->extended_state.bo); + media_state->extended_state.bo = NULL; + + dri_bo_unreference(media_state->vfe_state.bo); + media_state->vfe_state.bo = NULL; + + dri_bo_unreference(media_state->idrt.bo); + media_state->idrt.bo = NULL; + + dri_bo_unreference(media_state->binding_table.bo); + media_state->binding_table.bo = NULL; + + dri_bo_unreference(media_state->curbe.bo); + media_state->curbe.bo = NULL; + + i965_media_mpeg2_ternimate(ctx); + return True; +} + |