diff options
author | Zhong Li <zhong.li@intel.com> | 2015-01-15 22:04:53 +0800 |
---|---|---|
committer | Xiang, Haihao <haihao.xiang@intel.com> | 2015-03-19 10:01:29 +0800 |
commit | 4f0df22066c00528f463a0eb6f5c0b6f95e09b05 (patch) | |
tree | 386d8d04c39f2382ff505c7aae529219a9875011 | |
parent | 0255ffc21621b58188f55b18870fe8e85724d490 (diff) | |
download | libva-intel-driver-4f0df22066c00528f463a0eb6f5c0b6f95e09b05.tar.gz |
VP8 HWEnc: Build vp8 gen9 encoding vme pipeline
Signed-off-by: Zhong Li <zhong.li@intel.com>
(cherry picked from commit d8588862d85414ef412fd5e7ae1fb9ca78b69e84)
Conflicts:
src/i965_device_info.c
-rw-r--r-- | src/gen9_vme.c | 260 | ||||
-rw-r--r-- | src/i965_device_info.c | 1 | ||||
-rw-r--r-- | src/i965_drv_video.h | 2 | ||||
-rw-r--r-- | src/i965_encoder.c | 4 |
4 files changed, 213 insertions, 54 deletions
diff --git a/src/gen9_vme.c b/src/gen9_vme.c index b4310f28..03df88c2 100644 --- a/src/gen9_vme.c +++ b/src/gen9_vme.c @@ -120,6 +120,31 @@ static struct i965_kernel gen9_vme_mpeg2_kernels[] = { }, }; +static const uint32_t gen9_vme_vp8_intra_frame[][4] = { +#include "shaders/vme/vp8_intra_frame_gen9.g9b" +}; + +static const uint32_t gen9_vme_vp8_inter_frame[][4] = { +#include "shaders/vme/inter_frame_gen9.g9b" +}; + +static struct i965_kernel gen9_vme_vp8_kernels[] = { + { + "VME Intra Frame", + VME_INTRA_SHADER, /*index*/ + gen9_vme_vp8_intra_frame, + sizeof(gen9_vme_vp8_intra_frame), + NULL + }, + { + "VME inter Frame", + VME_INTER_SHADER, + gen9_vme_vp8_inter_frame, + sizeof(gen9_vme_vp8_inter_frame), + NULL + }, +}; + /* only used for VME source surface state */ static void gen9_vme_source_surface_state(VADriverContextP ctx, @@ -170,16 +195,14 @@ static void gen9_vme_output_buffer_setup(VADriverContextP ctx, struct encode_state *encode_state, int index, - struct intel_encoder_context *encoder_context) + struct intel_encoder_context *encoder_context, + int is_intra, + int width_in_mbs, + int height_in_mbs) { struct i965_driver_data *i965 = i965_driver_data(ctx); struct gen6_vme_context *vme_context = encoder_context->vme_context; - VAEncSequenceParameterBufferH264 *pSequenceParameter = (VAEncSequenceParameterBufferH264 *)encode_state->seq_param_ext->buffer; - VAEncSliceParameterBufferH264 *pSliceParameter = (VAEncSliceParameterBufferH264 *)encode_state->slice_params_ext[0]->buffer; - int is_intra = pSliceParameter->slice_type == SLICE_TYPE_I; - int width_in_mbs = pSequenceParameter->picture_width_in_mbs; - int height_in_mbs = pSequenceParameter->picture_height_in_mbs; vme_context->vme_output.num_blocks = width_in_mbs * height_in_mbs; vme_context->vme_output.pitch = 16; /* in bytes, always 16 */ @@ -207,17 +230,31 @@ gen9_vme_output_buffer_setup(VADriverContextP ctx, } static void +gen9_vme_avc_output_buffer_setup(VADriverContextP ctx, + struct encode_state *encode_state, + int index, + struct intel_encoder_context *encoder_context) +{ + VAEncSequenceParameterBufferH264 *pSequenceParameter = (VAEncSequenceParameterBufferH264 *)encode_state->seq_param_ext->buffer; + VAEncSliceParameterBufferH264 *pSliceParameter = (VAEncSliceParameterBufferH264 *)encode_state->slice_params_ext[0]->buffer; + int is_intra = pSliceParameter->slice_type == SLICE_TYPE_I; + int width_in_mbs = pSequenceParameter->picture_width_in_mbs; + int height_in_mbs = pSequenceParameter->picture_height_in_mbs; + + gen9_vme_output_buffer_setup(ctx, encode_state, index, encoder_context, is_intra, width_in_mbs, height_in_mbs); + +} + +static void gen9_vme_output_vme_batchbuffer_setup(VADriverContextP ctx, struct encode_state *encode_state, int index, - struct intel_encoder_context *encoder_context) - + struct intel_encoder_context *encoder_context, + int width_in_mbs, + int height_in_mbs) { struct i965_driver_data *i965 = i965_driver_data(ctx); struct gen6_vme_context *vme_context = encoder_context->vme_context; - VAEncSequenceParameterBufferH264 *pSequenceParameter = (VAEncSequenceParameterBufferH264 *)encode_state->seq_param_ext->buffer; - int width_in_mbs = pSequenceParameter->picture_width_in_mbs; - int height_in_mbs = pSequenceParameter->picture_height_in_mbs; vme_context->vme_batchbuffer.num_blocks = width_in_mbs * height_in_mbs + 1; vme_context->vme_batchbuffer.size_block = 64; /* 4 OWORDs */ @@ -226,15 +263,27 @@ gen9_vme_output_vme_batchbuffer_setup(VADriverContextP ctx, "VME batchbuffer", vme_context->vme_batchbuffer.num_blocks * vme_context->vme_batchbuffer.size_block, 0x1000); - /* vme_context->vme_buffer_suface_setup(ctx, &vme_context->gpe_context, &vme_context->vme_batchbuffer, BINDING_TABLE_OFFSET(index), SURFACE_STATE_OFFSET(index)); - */ } +static void +gen9_vme_avc_output_vme_batchbuffer_setup(VADriverContextP ctx, + struct encode_state *encode_state, + int index, + struct intel_encoder_context *encoder_context) +{ + VAEncSequenceParameterBufferH264 *pSequenceParameter = (VAEncSequenceParameterBufferH264 *)encode_state->seq_param_ext->buffer; + int width_in_mbs = pSequenceParameter->picture_width_in_mbs; + int height_in_mbs = pSequenceParameter->picture_height_in_mbs; + + gen9_vme_output_vme_batchbuffer_setup(ctx, encode_state, index, encoder_context, width_in_mbs, height_in_mbs); +} + + static VAStatus gen9_vme_surface_setup(VADriverContextP ctx, struct encode_state *encode_state, @@ -264,8 +313,8 @@ gen9_vme_surface_setup(VADriverContextP ctx, } /* VME output */ - gen9_vme_output_buffer_setup(ctx, encode_state, 3, encoder_context); - gen9_vme_output_vme_batchbuffer_setup(ctx, encode_state, 5, encoder_context); + gen9_vme_avc_output_buffer_setup(ctx, encode_state, 3, encoder_context); + gen9_vme_avc_output_vme_batchbuffer_setup(ctx, encode_state, 5, encoder_context); return VA_STATUS_SUCCESS; } @@ -727,35 +776,11 @@ gen9_vme_mpeg2_output_buffer_setup(VADriverContextP ctx, struct intel_encoder_context *encoder_context) { - struct i965_driver_data *i965 = i965_driver_data(ctx); - struct gen6_vme_context *vme_context = encoder_context->vme_context; VAEncSequenceParameterBufferMPEG2 *seq_param = (VAEncSequenceParameterBufferMPEG2 *)encode_state->seq_param_ext->buffer; int width_in_mbs = ALIGN(seq_param->picture_width, 16) / 16; int height_in_mbs = ALIGN(seq_param->picture_height, 16) / 16; - vme_context->vme_output.num_blocks = width_in_mbs * height_in_mbs; - vme_context->vme_output.pitch = 16; /* in bytes, always 16 */ - - if (is_intra) - vme_context->vme_output.size_block = INTRA_VME_OUTPUT_IN_BYTES * 2; - else - vme_context->vme_output.size_block = INTRA_VME_OUTPUT_IN_BYTES * 24; - /* - * Inter MV . 32-byte Intra search + 16 IME info + 128 IME MV + 32 IME Ref - * + 16 FBR Info + 128 FBR MV + 32 FBR Ref. - * 16 * (2 + 2 * (1 + 8 + 2))= 16 * 24. - */ - - vme_context->vme_output.bo = dri_bo_alloc(i965->intel.bufmgr, - "VME output buffer", - vme_context->vme_output.num_blocks * vme_context->vme_output.size_block, - 0x1000); - assert(vme_context->vme_output.bo); - vme_context->vme_buffer_suface_setup(ctx, - &vme_context->gpe_context, - &vme_context->vme_output, - BINDING_TABLE_OFFSET(index), - SURFACE_STATE_OFFSET(index)); + gen9_vme_output_buffer_setup(ctx, encode_state, index, encoder_context, is_intra, width_in_mbs, height_in_mbs); } static void @@ -765,24 +790,11 @@ gen9_vme_mpeg2_output_vme_batchbuffer_setup(VADriverContextP ctx, struct intel_encoder_context *encoder_context) { - struct i965_driver_data *i965 = i965_driver_data(ctx); - struct gen6_vme_context *vme_context = encoder_context->vme_context; VAEncSequenceParameterBufferMPEG2 *seq_param = (VAEncSequenceParameterBufferMPEG2 *)encode_state->seq_param_ext->buffer; int width_in_mbs = ALIGN(seq_param->picture_width, 16) / 16; int height_in_mbs = ALIGN(seq_param->picture_height, 16) / 16; - vme_context->vme_batchbuffer.num_blocks = width_in_mbs * height_in_mbs + 1; - vme_context->vme_batchbuffer.size_block = 64; /* 4 OWORDs */ - vme_context->vme_batchbuffer.pitch = 16; - vme_context->vme_batchbuffer.bo = dri_bo_alloc(i965->intel.bufmgr, - "VME batchbuffer", - vme_context->vme_batchbuffer.num_blocks * vme_context->vme_batchbuffer.size_block, - 0x1000); - vme_context->vme_buffer_suface_setup(ctx, - &vme_context->gpe_context, - &vme_context->vme_batchbuffer, - BINDING_TABLE_OFFSET(index), - SURFACE_STATE_OFFSET(index)); + gen9_vme_output_vme_batchbuffer_setup(ctx, encode_state, index, encoder_context, width_in_mbs, height_in_mbs); } static VAStatus @@ -1131,6 +1143,141 @@ gen9_vme_mpeg2_pipeline(VADriverContextP ctx, } static void +gen9_vme_vp8_output_buffer_setup(VADriverContextP ctx, + struct encode_state *encode_state, + int index, + int is_intra, + struct intel_encoder_context *encoder_context) +{ + VAEncSequenceParameterBufferVP8 *seq_param = (VAEncSequenceParameterBufferVP8 *)encode_state->seq_param_ext->buffer; + int width_in_mbs = ALIGN(seq_param->frame_width, 16) / 16; + int height_in_mbs = ALIGN(seq_param->frame_height, 16) / 16; + + gen9_vme_output_buffer_setup(ctx, encode_state, index, encoder_context, is_intra, width_in_mbs, height_in_mbs); +} + +static void +gen9_vme_vp8_output_vme_batchbuffer_setup(VADriverContextP ctx, + struct encode_state *encode_state, + int index, + struct intel_encoder_context *encoder_context) +{ + VAEncSequenceParameterBufferVP8 *seq_param = (VAEncSequenceParameterBufferVP8 *)encode_state->seq_param_ext->buffer; + int width_in_mbs = ALIGN(seq_param->frame_width, 16) / 16; + int height_in_mbs = ALIGN(seq_param->frame_height, 16) / 16; + + gen9_vme_output_vme_batchbuffer_setup(ctx, encode_state, index, encoder_context, width_in_mbs, height_in_mbs); +} + +static VAStatus +gen9_vme_vp8_surface_setup(VADriverContextP ctx, + struct encode_state *encode_state, + int is_intra, + struct intel_encoder_context *encoder_context) +{ + struct object_surface *obj_surface; + + /*Setup surfaces state*/ + /* current picture for encoding */ + obj_surface = encode_state->input_yuv_object; + gen9_vme_source_surface_state(ctx, 0, obj_surface, encoder_context); + gen9_vme_media_source_surface_state(ctx, 4, obj_surface, encoder_context); + gen9_vme_media_chroma_source_surface_state(ctx, 6, obj_surface, encoder_context); + + if (!is_intra) { + /* reference 0 */ + obj_surface = encode_state->reference_objects[0]; + + if (obj_surface->bo != NULL) + gen9_vme_source_surface_state(ctx, 1, obj_surface, encoder_context); + + /* reference 1 */ + obj_surface = encode_state->reference_objects[1]; + + if (obj_surface && obj_surface->bo != NULL) + gen9_vme_source_surface_state(ctx, 2, obj_surface, encoder_context); + } + + /* VME output */ + gen9_vme_vp8_output_buffer_setup(ctx, encode_state, 3, is_intra, encoder_context); + gen9_vme_vp8_output_vme_batchbuffer_setup(ctx, encode_state, 5, encoder_context); + + return VA_STATUS_SUCCESS; +} + +static void +gen9_vme_vp8_pipeline_programing(VADriverContextP ctx, + struct encode_state *encode_state, + int is_intra, + struct intel_encoder_context *encoder_context) +{ + struct gen6_vme_context *vme_context = encoder_context->vme_context; + struct intel_batchbuffer *batch = encoder_context->base.batch; + VAEncSequenceParameterBufferVP8 *seq_param = (VAEncSequenceParameterBufferVP8 *)encode_state->seq_param_ext->buffer; + int width_in_mbs = ALIGN(seq_param->frame_width, 16) / 16; + int height_in_mbs = ALIGN(seq_param->frame_height, 16) / 16; + int kernel_shader = (is_intra ? VME_INTRA_SHADER : VME_INTER_SHADER); + + gen9wa_vme_mpeg2_walker_fill_vme_batchbuffer(ctx, + encode_state, + width_in_mbs, height_in_mbs, + kernel_shader, + encoder_context); + + intel_batchbuffer_start_atomic(batch, 0x1000); + gen9_gpe_pipeline_setup(ctx, &vme_context->gpe_context, batch); + BEGIN_BATCH(batch, 4); + OUT_BATCH(batch, MI_BATCH_BUFFER_START | (1 << 8) | (1 << 0)); + OUT_RELOC(batch, + vme_context->vme_batchbuffer.bo, + I915_GEM_DOMAIN_COMMAND, 0, + 0); + OUT_BATCH(batch, 0); + OUT_BATCH(batch, 0); + ADVANCE_BATCH(batch); + + gen9_gpe_pipeline_end(ctx, &vme_context->gpe_context, batch); + + intel_batchbuffer_end_atomic(batch); +} + +static VAStatus gen9_vme_vp8_prepare(VADriverContextP ctx, + struct encode_state *encode_state, + struct intel_encoder_context *encoder_context) +{ + VAStatus vaStatus = VA_STATUS_SUCCESS; + VAEncPictureParameterBufferVP8 *pPicParameter = (VAEncPictureParameterBufferVP8 *)encode_state->pic_param_ext->buffer; + int is_intra = !pPicParameter->pic_flags.bits.frame_type; + + /* add update vp8 mbmv cost later */ + //intel_vme_update_mbmv_cost(ctx, encode_state, encoder_context); + + /*Setup all the memory object*/ + gen9_vme_vp8_surface_setup(ctx, encode_state, is_intra, encoder_context); + gen9_vme_interface_setup(ctx, encode_state, encoder_context); + gen9_vme_constant_setup(ctx, encode_state, encoder_context); + + /*Programing media pipeline*/ + gen9_vme_vp8_pipeline_programing(ctx, encode_state, is_intra, encoder_context); + + return vaStatus; +} + +static VAStatus +gen9_vme_vp8_pipeline(VADriverContextP ctx, + VAProfile profile, + struct encode_state *encode_state, + struct intel_encoder_context *encoder_context) +{ + gen9_vme_media_init(ctx, encoder_context); + gen9_vme_vp8_prepare(ctx, encode_state, encoder_context); + gen9_vme_run(ctx, encode_state, encoder_context); + gen9_vme_stop(ctx, encode_state, encoder_context); + + return VA_STATUS_SUCCESS; +} + +static void gen9_vme_context_destroy(void *context) { struct gen6_vme_context *vme_context = context; @@ -1172,7 +1319,12 @@ Bool gen9_vme_context_init(VADriverContextP ctx, struct intel_encoder_context *e vme_kernel_list = gen9_vme_mpeg2_kernels; encoder_context->vme_pipeline = gen9_vme_mpeg2_pipeline; i965_kernel_num = sizeof(gen9_vme_mpeg2_kernels) / sizeof(struct i965_kernel); + break; + case CODEC_VP8: + vme_kernel_list = gen9_vme_vp8_kernels; + encoder_context->vme_pipeline = gen9_vme_vp8_pipeline; + i965_kernel_num = sizeof(gen9_vme_vp8_kernels) / sizeof(struct i965_kernel); break; default: diff --git a/src/i965_device_info.c b/src/i965_device_info.c index 50bb78d8..d58c261f 100644 --- a/src/i965_device_info.c +++ b/src/i965_device_info.c @@ -341,6 +341,7 @@ static struct hw_codec_info skl_hw_codec_info = { .has_di_motion_adptive = 1, .has_di_motion_compensated = 1, .has_vp8_decoding = 1, + .has_vp8_encoding = 1, .has_h264_mvc_encoding = 1, .has_hevc_decoding = 1, diff --git a/src/i965_drv_video.h b/src/i965_drv_video.h index 96360105..ec34a3f7 100644 --- a/src/i965_drv_video.h +++ b/src/i965_drv_video.h @@ -34,6 +34,7 @@ #include <va/va_enc_h264.h> #include <va/va_enc_mpeg2.h> #include <va/va_enc_jpeg.h> +#include <va/va_enc_vp8.h> #include <va/va_vpp.h> #include <va/va_backend.h> #include <va/va_backend_vpp.h> @@ -453,6 +454,7 @@ va_enc_packed_type_to_idx(int packed_type); #define CODEC_MPEG2 1 #define CODEC_H264_MVC 2 #define CODEC_JPEG 3 +#define CODEC_VP8 4 #define H264_DELIMITER0 0x00 #define H264_DELIMITER1 0x00 diff --git a/src/i965_encoder.c b/src/i965_encoder.c index d924f5ab..86f87577 100644 --- a/src/i965_encoder.c +++ b/src/i965_encoder.c @@ -554,6 +554,10 @@ intel_enc_hw_context_init(VADriverContextP ctx, encoder_context->codec = CODEC_JPEG; break; + case VAProfileVP8Version0_3: + encoder_context->codec = CODEC_VP8; + break; + default: /* Never get here */ assert(0); |