OSDN Git Service

ENC:disable SVC feature of AVC encoder on SKL/APL/KBL
[android-x86/hardware-intel-common-vaapi.git] / src / gen9_mfd.c
index 03ae052..fed1bc1 100644 (file)
 
 #include "gen9_mfd.h"
 #include "intel_media.h"
+#include "vp9_probs.h"
 
 #define OUT_BUFFER(buf_bo, is_target, ma)  do {                         \
         if (buf_bo) {                                                   \
-            OUT_BCS_RELOC(batch,                                        \
+            OUT_BCS_RELOC64(batch,                                        \
                           buf_bo,                                       \
                           I915_GEM_DOMAIN_RENDER,                       \
                           is_target ? I915_GEM_DOMAIN_RENDER : 0,       \
                           0);                                           \
         } else {                                                        \
             OUT_BCS_BATCH(batch, 0);                                    \
+            OUT_BCS_BATCH(batch, 0);                                    \
         }                                                               \
-        OUT_BCS_BATCH(batch, 0);                                        \
         if (ma)                                                         \
-            OUT_BCS_BATCH(batch, 0);                                    \
+            OUT_BCS_BATCH(batch, i965->intel.mocs_state);                                    \
     } while (0)
 
 #define OUT_BUFFER_MA_TARGET(buf_bo)       OUT_BUFFER(buf_bo, 1, 1)
@@ -77,6 +78,7 @@ gen9_hcpd_init_hevc_surface(VADriverContextP ctx,
 
     if (!gen9_hevc_surface) {
         gen9_hevc_surface = calloc(sizeof(GenHevcSurface), 1);
+        assert(gen9_hevc_surface);
         gen9_hevc_surface->base.frame_store_id = -1;
         obj_surface->private_data = gen9_hevc_surface;
     }
@@ -106,25 +108,9 @@ gen9_hcpd_hevc_decode_init(VADriverContextP ctx,
 {
     struct i965_driver_data *i965 = i965_driver_data(ctx);
     VAPictureParameterBufferHEVC *pic_param;
-    VASliceParameterBufferHEVC *slice_param;
     struct object_surface *obj_surface;
     uint32_t size;
-    int i, j, has_inter = 0;
-
-    for (j = 0; j < decode_state->num_slice_params && !has_inter; j++) {
-        assert(decode_state->slice_params && decode_state->slice_params[j]->buffer);
-        slice_param = (VASliceParameterBufferHEVC *)decode_state->slice_params[j]->buffer;
-
-        for (i = 0; i < decode_state->slice_params[j]->num_elements; i++) {
-            if (slice_param->LongSliceFlags.fields.slice_type == HEVC_SLICE_B ||
-                slice_param->LongSliceFlags.fields.slice_type == HEVC_SLICE_P) {
-                has_inter = 1;
-                break;
-            }
-
-            slice_param++;
-        }
-    }
+    int size_shift = 3;
 
     assert(decode_state->pic_param && decode_state->pic_param->buffer);
     pic_param = (VAPictureParameterBufferHEVC *)decode_state->pic_param->buffer;
@@ -150,53 +136,50 @@ gen9_hcpd_hevc_decode_init(VADriverContextP ctx,
     hevc_ensure_surface_bo(ctx, decode_state, obj_surface, pic_param);
     gen9_hcpd_init_hevc_surface(ctx, pic_param, obj_surface, gen9_hcpd_context);
 
-    size = ALIGN(gen9_hcpd_context->picture_width_in_pixels, 32) >> 3;
+    if((pic_param->bit_depth_luma_minus8 > 0)
+        || (pic_param->bit_depth_chroma_minus8 > 0))
+        size_shift = 2;
+
+    size = ALIGN(gen9_hcpd_context->picture_width_in_pixels, 32) >> size_shift;
     size <<= 6;
     ALLOC_GEN_BUFFER((&gen9_hcpd_context->deblocking_filter_line_buffer), "line buffer", size);
     ALLOC_GEN_BUFFER((&gen9_hcpd_context->deblocking_filter_tile_line_buffer), "tile line buffer", size);
 
-    size = ALIGN(gen9_hcpd_context->picture_height_in_pixels + 6 * gen9_hcpd_context->picture_height_in_ctbs, 32) >> 3;
+    size = ALIGN(gen9_hcpd_context->picture_height_in_pixels + 6 * gen9_hcpd_context->picture_height_in_ctbs, 32) >> size_shift;
     size <<= 6;
     ALLOC_GEN_BUFFER((&gen9_hcpd_context->deblocking_filter_tile_column_buffer), "tile column buffer", size);
 
-    if (has_inter) {
-        size = (((gen9_hcpd_context->picture_width_in_pixels + 15) >> 4) * 188 + 9 * gen9_hcpd_context->picture_width_in_ctbs + 1023) >> 9;
-        size <<= 6;
-        ALLOC_GEN_BUFFER((&gen9_hcpd_context->metadata_line_buffer), "metadata line buffer", size);
-
-        size = (((gen9_hcpd_context->picture_width_in_pixels + 15) >> 4) * 172 + 9 * gen9_hcpd_context->picture_width_in_ctbs + 1023) >> 9;
-        size <<= 6;
-        ALLOC_GEN_BUFFER((&gen9_hcpd_context->metadata_tile_line_buffer), "metadata tile line buffer", size);
-
-        size = (((gen9_hcpd_context->picture_height_in_pixels + 15) >> 4) * 176 + 89 * gen9_hcpd_context->picture_width_in_ctbs + 1023) >> 9;
-        size <<= 6;
-        ALLOC_GEN_BUFFER((&gen9_hcpd_context->metadata_tile_column_buffer), "metadata tile column buffer", size);
-    } else {
-        size = (gen9_hcpd_context->picture_width_in_pixels + 8 * gen9_hcpd_context->picture_width_in_ctbs + 1023) >> 9;
-        size <<= 6;
-        ALLOC_GEN_BUFFER((&gen9_hcpd_context->metadata_line_buffer), "metadata line buffer", size);
+    size = (((gen9_hcpd_context->picture_width_in_pixels + 15) >> 4) * 188 + 9 * gen9_hcpd_context->picture_width_in_ctbs + 1023) >> 9;
+    size <<= 6;
+    ALLOC_GEN_BUFFER((&gen9_hcpd_context->metadata_line_buffer), "metadata line buffer", size);
 
-        size = (gen9_hcpd_context->picture_width_in_pixels + 16 * gen9_hcpd_context->picture_width_in_ctbs + 1023) >> 9;
-        size <<= 6;
-        ALLOC_GEN_BUFFER((&gen9_hcpd_context->metadata_tile_line_buffer), "metadata tile line buffer", size);
+    size = (((gen9_hcpd_context->picture_width_in_pixels + 15) >> 4) * 172 + 9 * gen9_hcpd_context->picture_width_in_ctbs + 1023) >> 9;
+    size <<= 6;
+    ALLOC_GEN_BUFFER((&gen9_hcpd_context->metadata_tile_line_buffer), "metadata tile line buffer", size);
 
-        size = (gen9_hcpd_context->picture_height_in_pixels + 8 * gen9_hcpd_context->picture_height_in_ctbs + 1023) >> 9;
-        size <<= 6;
-        ALLOC_GEN_BUFFER((&gen9_hcpd_context->metadata_tile_column_buffer), "metadata tile column buffer", size);
-    }
+    if (IS_CHERRYVIEW(i965->intel.device_info))
+        size = (((gen9_hcpd_context->picture_height_in_pixels + 15) >> 4) * 256 + 9 * gen9_hcpd_context->picture_height_in_ctbs + 1023) >> 9;
+    else
+        size = (((gen9_hcpd_context->picture_height_in_pixels + 15) >> 4) * 176 + 89 * gen9_hcpd_context->picture_height_in_ctbs + 1023) >> 9;
+    size <<= 6;
+    ALLOC_GEN_BUFFER((&gen9_hcpd_context->metadata_tile_column_buffer), "metadata tile column buffer", size);
 
-    size = ALIGN(((gen9_hcpd_context->picture_width_in_pixels >> 1) + 3 * gen9_hcpd_context->picture_width_in_ctbs), 16) >> 3;
+    size = ALIGN(((gen9_hcpd_context->picture_width_in_pixels >> 1) + 3 * gen9_hcpd_context->picture_width_in_ctbs), 16) >> size_shift;
     size <<= 6;
     ALLOC_GEN_BUFFER((&gen9_hcpd_context->sao_line_buffer), "sao line buffer", size);
 
-    size = ALIGN(((gen9_hcpd_context->picture_width_in_pixels >> 1) + 6 * gen9_hcpd_context->picture_width_in_ctbs), 16) >> 3;
+    size = ALIGN(((gen9_hcpd_context->picture_width_in_pixels >> 1) + 6 * gen9_hcpd_context->picture_width_in_ctbs), 16) >> size_shift;
     size <<= 6;
     ALLOC_GEN_BUFFER((&gen9_hcpd_context->sao_tile_line_buffer), "sao tile line buffer", size);
 
-    size = ALIGN(((gen9_hcpd_context->picture_height_in_pixels >> 1) + 6 * gen9_hcpd_context->picture_height_in_ctbs), 16) >> 3;
+    size = ALIGN(((gen9_hcpd_context->picture_height_in_pixels >> 1) + 6 * gen9_hcpd_context->picture_height_in_ctbs), 16) >> size_shift;
     size <<= 6;
     ALLOC_GEN_BUFFER((&gen9_hcpd_context->sao_tile_column_buffer), "sao tile column buffer", size);
 
+    gen9_hcpd_context->first_inter_slice_collocated_ref_idx = 0;
+    gen9_hcpd_context->first_inter_slice_collocated_from_l0_flag = 0;
+    gen9_hcpd_context->first_inter_slice_valid = 0;
+
     return VA_STATUS_SUCCESS;
 }
 
@@ -206,13 +189,23 @@ gen9_hcpd_pipe_mode_select(VADriverContextP ctx,
                            int codec,
                            struct gen9_hcpd_context *gen9_hcpd_context)
 {
+    struct i965_driver_data *i965 = i965_driver_data(ctx);
     struct intel_batchbuffer *batch = gen9_hcpd_context->base.batch;
 
-    assert(codec == HCP_CODEC_HEVC);
+    assert((codec == HCP_CODEC_HEVC) || (codec == HCP_CODEC_VP9));
+
+    if(IS_KBL(i965->intel.device_info))
+    {
+        BEGIN_BCS_BATCH(batch, 6);
 
-    BEGIN_BCS_BATCH(batch, 4);
+        OUT_BCS_BATCH(batch, HCP_PIPE_MODE_SELECT | (6 - 2));
+    }
+    else
+    {
+        BEGIN_BCS_BATCH(batch, 4);
 
-    OUT_BCS_BATCH(batch, HCP_PIPE_MODE_SELECT | (4 - 2));
+        OUT_BCS_BATCH(batch, HCP_PIPE_MODE_SELECT | (4 - 2));
+    }
     OUT_BCS_BATCH(batch,
                   (codec << 5) |
                   (0 << 3) | /* disable Pic Status / Error Report */
@@ -220,6 +213,16 @@ gen9_hcpd_pipe_mode_select(VADriverContextP ctx,
     OUT_BCS_BATCH(batch, 0);
     OUT_BCS_BATCH(batch, 0);
 
+    if(IS_KBL(i965->intel.device_info))
+    {
+        if(codec == HCP_CODEC_VP9)
+            OUT_BCS_BATCH(batch, 1<<6);
+        else
+            OUT_BCS_BATCH(batch, 0);
+
+        OUT_BCS_BATCH(batch, 0);
+    }
+
     ADVANCE_BCS_BATCH(batch);
 }
 
@@ -231,9 +234,11 @@ gen9_hcpd_surface_state(VADriverContextP ctx,
     struct intel_batchbuffer *batch = gen9_hcpd_context->base.batch;
     struct object_surface *obj_surface = decode_state->render_object;
     unsigned int y_cb_offset;
+    VAPictureParameterBufferHEVC *pic_param;
 
     assert(obj_surface);
 
+    pic_param = (VAPictureParameterBufferHEVC *)decode_state->pic_param->buffer;
     y_cb_offset = obj_surface->y_cb_offset;
 
     BEGIN_BCS_BATCH(batch, 3);
@@ -242,9 +247,19 @@ gen9_hcpd_surface_state(VADriverContextP ctx,
     OUT_BCS_BATCH(batch,
                   (0 << 28) |                   /* surface id */
                   (obj_surface->width - 1));    /* pitch - 1 */
-    OUT_BCS_BATCH(batch,
+    if((pic_param->bit_depth_luma_minus8 > 0)
+        || (pic_param->bit_depth_chroma_minus8 > 0))
+    {
+        OUT_BCS_BATCH(batch,
+                  (SURFACE_FORMAT_P010 << 28) |
+                  y_cb_offset);
+    }
+    else
+    {
+        OUT_BCS_BATCH(batch,
                   (SURFACE_FORMAT_PLANAR_420_8 << 28) |
                   y_cb_offset);
+    }
 
     ADVANCE_BCS_BATCH(batch);
 }
@@ -254,6 +269,7 @@ gen9_hcpd_pipe_buf_addr_state(VADriverContextP ctx,
                               struct decode_state *decode_state,
                               struct gen9_hcpd_context *gen9_hcpd_context)
 {
+    struct i965_driver_data *i965 = i965_driver_data(ctx);
     struct intel_batchbuffer *batch = gen9_hcpd_context->base.batch;
     struct object_surface *obj_surface;
     GenHevcSurface *gen9_hevc_surface;
@@ -323,6 +339,7 @@ gen9_hcpd_ind_obj_base_addr_state(VADriverContextP ctx,
                                   dri_bo *slice_data_bo,
                                   struct gen9_hcpd_context *gen9_hcpd_context)
 {
+    struct i965_driver_data *i965 = i965_driver_data(ctx);
     struct intel_batchbuffer *batch = gen9_hcpd_context->base.batch;
 
     BEGIN_BCS_BATCH(batch, 14);
@@ -489,6 +506,8 @@ gen9_hcpd_pic_state(VADriverContextP ctx,
                   pic_param->slice_parsing_fields.bits.sample_adaptive_offset_enabled_flag << 3 |
                   0);
     OUT_BCS_BATCH(batch,
+                  pic_param->bit_depth_luma_minus8 << 27 |
+                  pic_param->bit_depth_chroma_minus8 << 24 |
                   pcm_sample_bit_depth_luma_minus1 << 20 |
                   pcm_sample_bit_depth_chroma_minus1 << 16 |
                   pic_param->max_transform_hierarchy_depth_inter << 13 |
@@ -649,8 +668,8 @@ gen9_hcpd_weightoffset_state_1(struct intel_batchbuffer *batch,
     for (i = 0; i < 16; i++) {
         if (i < MIN((num_ref_minus1 + 1), 15)) {
             OUT_BCS_BATCH(batch,
-                          luma_offset[i] << 8 |
-                          delta_luma_weight[i]);
+                          (luma_offset[i] & 0xff) << 8 |
+                          (delta_luma_weight[i] & 0xff));
         } else {
             OUT_BCS_BATCH(batch, 0);
         }
@@ -658,10 +677,10 @@ gen9_hcpd_weightoffset_state_1(struct intel_batchbuffer *batch,
     for (i = 0; i < 16; i++) {
         if (i < MIN((num_ref_minus1 + 1), 15)) {
             OUT_BCS_BATCH(batch,
-                          chroma_offset[i][1] << 24 |
-                          delta_chroma_weight[i][1] << 16 |
-                          chroma_offset[i][0] << 8 |
-                          delta_chroma_weight[i][0]);
+                          (chroma_offset[i][1] & 0xff) << 24 |
+                          (delta_chroma_weight[i][1] & 0xff) << 16 |
+                          (chroma_offset[i][0] & 0xff) << 8 |
+                          (delta_chroma_weight[i][0] & 0xff));
         } else {
             OUT_BCS_BATCH(batch, 0);
         }
@@ -707,6 +726,9 @@ gen9_hcpd_get_collocated_ref_idx(VADriverContextP ctx,
     if (slice_param->collocated_ref_idx > 14)
         return 0;
 
+    if (!slice_param->LongSliceFlags.fields.slice_temporal_mvp_enabled_flag)
+        return 0;
+
     if (slice_param->LongSliceFlags.fields.slice_type == HEVC_SLICE_I)
         return 0;
 
@@ -779,6 +801,8 @@ gen9_hcpd_slice_state(VADriverContextP ctx,
 {
     struct intel_batchbuffer *batch = gen9_hcpd_context->base.batch;
     int slice_hor_pos, slice_ver_pos, next_slice_hor_pos, next_slice_ver_pos;
+    unsigned short collocated_ref_idx, collocated_from_l0_flag;
+    int sliceqp_sign_flag = 0, sliceqp = 0;
 
     slice_hor_pos = slice_param->slice_segment_address % gen9_hcpd_context->picture_width_in_ctbs;
     slice_ver_pos = slice_param->slice_segment_address / gen9_hcpd_context->picture_width_in_ctbs;
@@ -791,6 +815,36 @@ gen9_hcpd_slice_state(VADriverContextP ctx,
         next_slice_ver_pos = 0;
     }
 
+    collocated_ref_idx = gen9_hcpd_get_collocated_ref_idx(ctx, pic_param, slice_param, gen9_hcpd_context);
+    collocated_from_l0_flag = slice_param->LongSliceFlags.fields.collocated_from_l0_flag;
+
+    if ((!gen9_hcpd_context->first_inter_slice_valid) &&
+        (slice_param->LongSliceFlags.fields.slice_type != HEVC_SLICE_I) &&
+        slice_param->LongSliceFlags.fields.slice_temporal_mvp_enabled_flag) {
+        gen9_hcpd_context->first_inter_slice_collocated_ref_idx = collocated_ref_idx;
+        gen9_hcpd_context->first_inter_slice_collocated_from_l0_flag = collocated_from_l0_flag;
+        gen9_hcpd_context->first_inter_slice_valid = 1;
+    }
+
+    /* HW requirement */
+    if (gen9_hcpd_context->first_inter_slice_valid &&
+        ((slice_param->LongSliceFlags.fields.slice_type == HEVC_SLICE_I) ||
+         (!slice_param->LongSliceFlags.fields.slice_temporal_mvp_enabled_flag))) {
+        collocated_ref_idx = gen9_hcpd_context->first_inter_slice_collocated_ref_idx;
+        collocated_from_l0_flag = gen9_hcpd_context->first_inter_slice_collocated_from_l0_flag;
+    }
+
+    sliceqp = pic_param->init_qp_minus26 + 26 + slice_param->slice_qp_delta;
+    if((pic_param->bit_depth_luma_minus8 > 0)
+        || (pic_param->bit_depth_chroma_minus8 > 0))
+    {
+        if(sliceqp < 0)
+        {
+            sliceqp_sign_flag = 1;
+            sliceqp = -sliceqp;
+        }
+    }
+
     BEGIN_BCS_BATCH(batch, 9);
 
     OUT_BCS_BATCH(batch, HCP_SLICE_STATE | (9 - 2));
@@ -804,18 +858,19 @@ gen9_hcpd_slice_state(VADriverContextP ctx,
     OUT_BCS_BATCH(batch,
                   (slice_param->slice_cr_qp_offset & 0x1f) << 17 |
                   (slice_param->slice_cb_qp_offset & 0x1f) << 12 |
-                  (pic_param->init_qp_minus26 + 26 + slice_param->slice_qp_delta) << 6 |
+                  sliceqp << 6 |
                   slice_param->LongSliceFlags.fields.slice_temporal_mvp_enabled_flag << 5 |
                   slice_param->LongSliceFlags.fields.dependent_slice_segment_flag << 4 |
+                  sliceqp_sign_flag << 3 |
                   !next_slice_param << 2 |
                   slice_param->LongSliceFlags.fields.slice_type);
     OUT_BCS_BATCH(batch,
-                  gen9_hcpd_get_collocated_ref_idx(ctx, pic_param, slice_param, gen9_hcpd_context) << 26 |
+                  collocated_ref_idx << 26 |
                   (5 - slice_param->five_minus_max_num_merge_cand - 1) << 23 |
                   slice_param->LongSliceFlags.fields.cabac_init_flag << 22 |
                   slice_param->luma_log2_weight_denom << 19 |
-                  (slice_param->luma_log2_weight_denom + slice_param->delta_chroma_log2_weight_denom) << 16 |
-                  slice_param->LongSliceFlags.fields.collocated_from_l0_flag << 15 |
+                  ((slice_param->luma_log2_weight_denom + slice_param->delta_chroma_log2_weight_denom) & 0x7) << 16 |
+                  collocated_from_l0_flag << 15 |
                   gen9_hcpd_is_low_delay(ctx, pic_param, slice_param) << 14 |
                   slice_param->LongSliceFlags.fields.mvd_l1_zero_flag << 13 |
                   slice_param->LongSliceFlags.fields.slice_sao_luma_flag << 12 |
@@ -859,6 +914,7 @@ gen9_hcpd_hevc_decode_picture(VADriverContextP ctx,
                               struct gen9_hcpd_context *gen9_hcpd_context)
 {
     VAStatus vaStatus;
+    struct i965_driver_data *i965 = i965_driver_data(ctx);
     struct intel_batchbuffer *batch = gen9_hcpd_context->base.batch;
     VAPictureParameterBufferHEVC *pic_param;
     VASliceParameterBufferHEVC *slice_param, *next_slice_param, *next_slice_group_param;
@@ -873,7 +929,10 @@ gen9_hcpd_hevc_decode_picture(VADriverContextP ctx,
     assert(decode_state->pic_param && decode_state->pic_param->buffer);
     pic_param = (VAPictureParameterBufferHEVC *)decode_state->pic_param->buffer;
 
-    intel_batchbuffer_start_atomic_bcs(batch, 0x1000);
+    if (i965->intel.has_bsd2)
+        intel_batchbuffer_start_atomic_bcs_override(batch, 0x1000, BSD_RING0);
+    else
+        intel_batchbuffer_start_atomic_bcs(batch, 0x1000);
     intel_batchbuffer_emit_mi_flush(batch);
 
     gen9_hcpd_pipe_mode_select(ctx, decode_state, HCP_CODEC_HEVC, gen9_hcpd_context);
@@ -919,6 +978,881 @@ out:
     return vaStatus;
 }
 
+/*********************************************************/
+/*                  VP9 Code                             */
+/*********************************************************/
+
+
+#define VP9_PROB_BUFFER_FIRST_PART_SIZE 2010
+#define VP9_PROB_BUFFER_SECOND_PART_SIZE 10
+#define VP9_PROB_BUFFER_KEY_INTER_OFFSET 1667
+#define VP9_PROB_BUFFER_KEY_INTER_SIZE   343
+
+#define VP9_PROB_BUFFER_UPDATE_NO   0
+#define VP9_PROB_BUFFER_UPDATE_SECNE_1    1
+#define VP9_PROB_BUFFER_UPDATE_SECNE_2    2
+#define VP9_PROB_BUFFER_UPDATE_SECNE_3    3
+#define VP9_PROB_BUFFER_UPDATE_SECNE_4    4
+#define VP9_PROB_BUFFER_UPDATE_SECNE_5    5
+
+#define VP9_PROB_BUFFER_SAVED_NO   0
+#define VP9_PROB_BUFFER_SAVED_SECNE_1    1
+#define VP9_PROB_BUFFER_SAVED_SECNE_2    2
+
+#define VP9_PROB_BUFFER_RESTORED_NO   0
+#define VP9_PROB_BUFFER_RESTORED_SECNE_1    1
+#define VP9_PROB_BUFFER_RESTORED_SECNE_2    2
+#define VP9_PROB_BUFFER_RESTORED_SECNE_MAX    (VP9_PROB_BUFFER_RESTORED_SECNE_2 + 1)
+
+#define ALLOC_MV_BUFFER(gen_buffer, string, size,width,height)  \
+    do {                                                        \
+        dri_bo_unreference(gen_buffer->bo);                     \
+        gen_buffer->bo = dri_bo_alloc(i965->intel.bufmgr,       \
+                                      string,                   \
+                                      size,                     \
+                                      0x1000);                  \
+        assert(gen_buffer->bo);                                 \
+        gen_buffer->frame_width  = width ;                      \
+        gen_buffer->frame_height = height;                      \
+    } while (0)
+
+static void
+vp9_update_segmentId_buffer(VADriverContextP ctx,
+                          struct decode_state *decode_state,
+                          struct gen9_hcpd_context *gen9_hcpd_context)
+{
+    struct i965_driver_data *i965 = i965_driver_data(ctx);
+    VADecPictureParameterBufferVP9 *pic_param;
+
+    int size = 0;
+    int is_scaling = 0;
+    assert(decode_state->pic_param && decode_state->pic_param->buffer);
+    pic_param = (VADecPictureParameterBufferVP9 *)decode_state->pic_param->buffer;
+
+    size = gen9_hcpd_context->picture_width_in_ctbs * gen9_hcpd_context->picture_height_in_ctbs * 1 ;
+    size <<= 6;
+    if (gen9_hcpd_context->vp9_segment_id_buffer.bo == NULL || pic_param->frame_width > gen9_hcpd_context->last_frame.frame_width || pic_param->frame_height > gen9_hcpd_context->last_frame.frame_height)
+    {
+        ALLOC_GEN_BUFFER((&gen9_hcpd_context->vp9_segment_id_buffer), "vp9 segment id buffer", size);
+    }
+
+    is_scaling = (pic_param->frame_width != gen9_hcpd_context->last_frame.frame_width) || (pic_param->frame_height != gen9_hcpd_context->last_frame.frame_height);
+
+    if((pic_param->pic_fields.bits.frame_type == HCP_VP9_KEY_FRAME) ||
+        pic_param->pic_fields.bits.error_resilient_mode ||
+        pic_param->pic_fields.bits.intra_only || is_scaling) {
+
+        //VP9 Segment ID buffer needs to be zero
+        dri_bo_map(gen9_hcpd_context->vp9_segment_id_buffer.bo,1);
+        memset((unsigned char *)gen9_hcpd_context->vp9_segment_id_buffer.bo->virtual,0, size);
+        dri_bo_unmap(gen9_hcpd_context->vp9_segment_id_buffer.bo);
+    }
+}
+
+static void
+vp9_update_mv_temporal_buffer(VADriverContextP ctx,
+                          struct decode_state *decode_state,
+                          struct gen9_hcpd_context *gen9_hcpd_context)
+{
+    struct i965_driver_data *i965 = i965_driver_data(ctx);
+    VADecPictureParameterBufferVP9 *pic_param;
+    int size = 0;
+
+    assert(decode_state->pic_param && decode_state->pic_param->buffer);
+    pic_param = (VADecPictureParameterBufferVP9 *)decode_state->pic_param->buffer;
+
+    size = gen9_hcpd_context->picture_width_in_ctbs * gen9_hcpd_context->picture_height_in_ctbs * 9 ;
+    size <<= 6; //CL aligned
+    if (gen9_hcpd_context->vp9_mv_temporal_buffer_curr.bo == NULL || pic_param->frame_width > gen9_hcpd_context->vp9_mv_temporal_buffer_curr.frame_width || pic_param->frame_height > gen9_hcpd_context->vp9_mv_temporal_buffer_curr.frame_height)
+    {
+        ALLOC_MV_BUFFER((&gen9_hcpd_context->vp9_mv_temporal_buffer_curr), "vp9 curr mv temporal buffer", size,pic_param->frame_width,pic_param->frame_height);
+    }
+    if (gen9_hcpd_context->vp9_mv_temporal_buffer_last.bo == NULL)
+    {
+        ALLOC_MV_BUFFER((&gen9_hcpd_context->vp9_mv_temporal_buffer_last), "vp9 last mv temporal buffer", size,pic_param->frame_width,pic_param->frame_height);
+    }
+
+}
+
+static void
+vp9_gen_default_probabilities(VADriverContextP ctx, struct gen9_hcpd_context *gen9_hcpd_context)
+{
+    int i = 0;
+    uint32_t size = 0;
+
+    size = sizeof(FRAME_CONTEXT);
+    memset(&gen9_hcpd_context->vp9_fc_key_default,0,size);
+    memset(&gen9_hcpd_context->vp9_fc_inter_default,0,size);
+    memset(&gen9_hcpd_context->vp9_frame_ctx,0,size*FRAME_CONTEXTS);
+    //more code to come here below
+
+    //1. key default
+    gen9_hcpd_context->vp9_fc_key_default.tx_probs = default_tx_probs;
+    //dummy 52
+    vp9_copy(gen9_hcpd_context->vp9_fc_key_default.coeff_probs4x4, default_coef_probs_4x4);
+    vp9_copy(gen9_hcpd_context->vp9_fc_key_default.coeff_probs8x8, default_coef_probs_8x8);
+    vp9_copy(gen9_hcpd_context->vp9_fc_key_default.coeff_probs16x16, default_coef_probs_16x16);
+    vp9_copy(gen9_hcpd_context->vp9_fc_key_default.coeff_probs32x32, default_coef_probs_32x32);
+    //dummy 16
+    vp9_copy(gen9_hcpd_context->vp9_fc_key_default.skip_probs, default_skip_probs);
+    vp9_copy(gen9_hcpd_context->vp9_fc_key_default.partition_prob, vp9_kf_partition_probs);
+    //dummy 47
+    vp9_copy(gen9_hcpd_context->vp9_fc_key_default.uv_mode_prob, vp9_kf_uv_mode_prob);
+    vp9_copy(gen9_hcpd_context->vp9_fc_key_default.seg_tree_probs, default_seg_tree_probs);
+    vp9_copy(gen9_hcpd_context->vp9_fc_key_default.seg_pred_probs, default_seg_pred_probs);
+
+    //2. inter default
+    gen9_hcpd_context->vp9_fc_inter_default.tx_probs = default_tx_probs;
+    //dummy 52
+    vp9_copy(gen9_hcpd_context->vp9_fc_inter_default.coeff_probs4x4, default_coef_probs_4x4);
+    vp9_copy(gen9_hcpd_context->vp9_fc_inter_default.coeff_probs8x8, default_coef_probs_8x8);
+    vp9_copy(gen9_hcpd_context->vp9_fc_inter_default.coeff_probs16x16, default_coef_probs_16x16);
+    vp9_copy(gen9_hcpd_context->vp9_fc_inter_default.coeff_probs32x32, default_coef_probs_32x32);
+    //dummy 16
+    vp9_copy(gen9_hcpd_context->vp9_fc_inter_default.skip_probs, default_skip_probs);
+    vp9_copy(gen9_hcpd_context->vp9_fc_inter_default.inter_mode_probs, default_inter_mode_probs);
+    vp9_copy(gen9_hcpd_context->vp9_fc_inter_default.switchable_interp_prob, default_switchable_interp_prob);
+    vp9_copy(gen9_hcpd_context->vp9_fc_inter_default.intra_inter_prob, default_intra_inter_p);
+    vp9_copy(gen9_hcpd_context->vp9_fc_inter_default.comp_inter_prob, default_comp_inter_p);
+    vp9_copy(gen9_hcpd_context->vp9_fc_inter_default.single_ref_prob, default_single_ref_p);
+    vp9_copy(gen9_hcpd_context->vp9_fc_inter_default.comp_ref_prob, default_comp_ref_p);
+    vp9_copy(gen9_hcpd_context->vp9_fc_inter_default.y_mode_prob, default_if_y_probs);
+    vp9_copy(gen9_hcpd_context->vp9_fc_inter_default.partition_prob, default_partition_probs);
+    gen9_hcpd_context->vp9_fc_inter_default.nmvc = default_nmv_context;
+    //dummy 47
+    vp9_copy(gen9_hcpd_context->vp9_fc_inter_default.uv_mode_prob, default_if_uv_probs);
+    vp9_copy(gen9_hcpd_context->vp9_fc_inter_default.seg_tree_probs, default_seg_tree_probs);
+    vp9_copy(gen9_hcpd_context->vp9_fc_inter_default.seg_pred_probs, default_seg_pred_probs);
+
+    for(i = 0; i < FRAME_CONTEXTS; i++)
+    {
+        gen9_hcpd_context->vp9_frame_ctx[i] = gen9_hcpd_context->vp9_fc_inter_default;
+    }
+}
+
+static void
+vp9_update_probabilities(VADriverContextP ctx,
+                          struct decode_state *decode_state,
+                          struct gen9_hcpd_context *gen9_hcpd_context)
+{
+    VADecPictureParameterBufferVP9 *pic_param;
+    int i = 0;
+
+    assert(decode_state->pic_param && decode_state->pic_param->buffer);
+    pic_param = (VADecPictureParameterBufferVP9 *)decode_state->pic_param->buffer;
+
+    //first part buffer update: Case 1)Reset all 4 probablity buffers
+   if((pic_param->pic_fields.bits.frame_type == HCP_VP9_KEY_FRAME) ||pic_param->pic_fields.bits.intra_only||pic_param->pic_fields.bits.error_resilient_mode)
+    {
+        if((pic_param->pic_fields.bits.frame_type == HCP_VP9_KEY_FRAME) ||
+            (pic_param->pic_fields.bits.reset_frame_context == 3)||
+            pic_param->pic_fields.bits.error_resilient_mode)
+        {
+            //perform full buffer update
+            for(i = 0; i < FRAME_CONTEXTS; i++)
+            {
+                memcpy(&gen9_hcpd_context->vp9_frame_ctx[i],&gen9_hcpd_context->vp9_fc_inter_default,VP9_PROB_BUFFER_FIRST_PART_SIZE);
+
+                vp9_copy(gen9_hcpd_context->vp9_frame_ctx[i].seg_tree_probs, default_seg_tree_probs);
+                vp9_copy(gen9_hcpd_context->vp9_frame_ctx[i].seg_pred_probs, default_seg_pred_probs);
+            }
+        }else if(pic_param->pic_fields.bits.reset_frame_context == 2&&pic_param->pic_fields.bits.intra_only)
+        {
+            memcpy(&gen9_hcpd_context->vp9_frame_ctx[pic_param->pic_fields.bits.frame_context_idx],&gen9_hcpd_context->vp9_fc_inter_default,VP9_PROB_BUFFER_FIRST_PART_SIZE);
+        }
+        pic_param->pic_fields.bits.frame_context_idx = 0;
+    }
+
+    //Case 3) Update only segment probabilities
+    if((pic_param->pic_fields.bits.segmentation_enabled &&
+        pic_param->pic_fields.bits.segmentation_update_map))
+    {
+        //Update seg_tree_probs and seg_pred_probs accordingly
+        for (i=0; i<SEG_TREE_PROBS; i++)
+        {
+            gen9_hcpd_context->vp9_frame_ctx[pic_param->pic_fields.bits.frame_context_idx].seg_tree_probs[i] = pic_param->mb_segment_tree_probs[i];
+        }
+        for (i=0; i<PREDICTION_PROBS; i++)
+        {
+            gen9_hcpd_context->vp9_frame_ctx[pic_param->pic_fields.bits.frame_context_idx].seg_pred_probs[i] = pic_param->segment_pred_probs[i];
+        }
+    }
+
+    //update vp9_fc according to frame_context_id
+    {
+        void *pfc = (void *)&gen9_hcpd_context->vp9_frame_ctx[pic_param->pic_fields.bits.frame_context_idx];
+        void *pprob = NULL;
+
+        dri_bo_map(gen9_hcpd_context->vp9_probability_buffer.bo,1);
+
+        pprob = (void *)gen9_hcpd_context->vp9_probability_buffer.bo->virtual;
+        memcpy(pprob,pfc,2048);
+        //only update 343bytes for key or intra_only frame
+        if(pic_param->pic_fields.bits.frame_type == HCP_VP9_KEY_FRAME ||
+            pic_param->pic_fields.bits.intra_only)
+        {
+            memcpy(pprob + VP9_PROB_BUFFER_FIRST_PART_SIZE - VP9_PROB_BUFFER_KEY_INTER_SIZE
+                    , gen9_hcpd_context->vp9_fc_key_default.inter_mode_probs
+                    , VP9_PROB_BUFFER_KEY_INTER_SIZE);
+        }
+
+        dri_bo_unmap(gen9_hcpd_context->vp9_probability_buffer.bo);
+    }
+}
+
+static void
+gen9_hcpd_init_vp9_surface(VADriverContextP ctx,
+                            VADecPictureParameterBufferVP9 *pic_param,
+                            struct object_surface *obj_surface,
+                            struct gen9_hcpd_context *gen9_hcpd_context)
+{
+    GenVP9Surface *gen9_vp9_surface;
+
+    if (!obj_surface)
+        return;
+
+    obj_surface->free_private_data = gen_free_vp9_surface;
+    gen9_vp9_surface = obj_surface->private_data;
+
+    if (!gen9_vp9_surface) {
+        gen9_vp9_surface = calloc(sizeof(GenVP9Surface), 1);
+        assert(gen9_vp9_surface);
+        gen9_vp9_surface->base.frame_store_id = -1;
+        obj_surface->private_data = gen9_vp9_surface;
+    }
+
+    gen9_vp9_surface->frame_width  = pic_param->frame_width;
+    gen9_vp9_surface->frame_height = pic_param->frame_height;
+
+}
+
+static VAStatus
+gen9_hcpd_vp9_decode_init(VADriverContextP ctx,
+                           struct decode_state *decode_state,
+                           struct gen9_hcpd_context *gen9_hcpd_context)
+{
+    struct i965_driver_data *i965 = i965_driver_data(ctx);
+    VADecPictureParameterBufferVP9 *pic_param;
+    struct object_surface *obj_surface;
+    uint32_t size;
+    int width_in_mbs=0, height_in_mbs=0;
+    int bit_depth_minus8 = 0;
+
+    assert(decode_state->pic_param && decode_state->pic_param->buffer);
+    pic_param = (VADecPictureParameterBufferVP9 *)decode_state->pic_param->buffer;
+
+    width_in_mbs = (pic_param->frame_width + 15) / 16;
+    height_in_mbs = (pic_param->frame_height + 15) / 16;
+
+    //For BXT, we support only till 4K
+    assert(width_in_mbs > 0 && width_in_mbs <= 256); /* 4K */
+    assert(height_in_mbs > 0 && height_in_mbs <= 256);
+
+    if(!(i965->codec_info->vp9_dec_profiles & (1U<<pic_param->profile)))
+        return VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
+
+    if(pic_param->profile >= 2)
+    {
+        if(pic_param->bit_depth >= 8)
+            bit_depth_minus8 = pic_param->bit_depth - 8;
+
+        if(bit_depth_minus8 == 2)
+        {
+            if(!(i965->codec_info->vp9_dec_chroma_formats & VA_RT_FORMAT_YUV420_10BPP))
+                return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
+        }
+        else if((bit_depth_minus8 > 2) || (bit_depth_minus8 == 1) || (bit_depth_minus8 < 0))
+            return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
+    }
+
+    //Update the frame store buffers with the reference frames information
+    intel_update_vp9_frame_store_index(ctx,
+                                        decode_state,
+                                        pic_param,
+                                        gen9_hcpd_context->reference_surfaces);
+
+    /* Current decoded picture */
+    obj_surface = decode_state->render_object;
+    //Ensure there is a tiled render surface in NV12 format. If not, create one.
+    vp9_ensure_surface_bo(ctx, decode_state, obj_surface, pic_param);
+
+
+    //Super block in VP9 is 64x64
+    gen9_hcpd_context->ctb_size = 64;
+    gen9_hcpd_context->min_cb_size = 8; //Min block size is 4 or 8?
+
+    //If picture width/height is not multiple of 64, needs to upsize it to the next 64 pixels
+    //before calculation below.
+    gen9_hcpd_context->picture_width_in_ctbs  = ALIGN(pic_param->frame_width, gen9_hcpd_context->ctb_size) / gen9_hcpd_context->ctb_size;
+    gen9_hcpd_context->picture_height_in_ctbs = ALIGN(pic_param->frame_height, gen9_hcpd_context->ctb_size) / gen9_hcpd_context->ctb_size;
+
+    gen9_hcpd_context->picture_width_in_min_cb_minus1  = ALIGN(pic_param->frame_width, gen9_hcpd_context->min_cb_size) / gen9_hcpd_context->min_cb_size - 1;
+    gen9_hcpd_context->picture_height_in_min_cb_minus1 = ALIGN(pic_param->frame_height, gen9_hcpd_context->min_cb_size) / gen9_hcpd_context->min_cb_size - 1;
+
+    gen9_hcpd_context->picture_width_in_pixels  = (gen9_hcpd_context->picture_width_in_min_cb_minus1  + 1) * gen9_hcpd_context->min_cb_size ;
+    gen9_hcpd_context->picture_height_in_pixels = (gen9_hcpd_context->picture_height_in_min_cb_minus1 + 1) * gen9_hcpd_context->min_cb_size ;
+
+    gen9_hcpd_init_vp9_surface(ctx, pic_param, obj_surface, gen9_hcpd_context);
+
+    if(pic_param->profile >= 2)
+        size = gen9_hcpd_context->picture_width_in_ctbs*36; //num_width_in_SB * 36
+    else
+        size = gen9_hcpd_context->picture_width_in_ctbs*18; //num_width_in_SB * 18
+    size<<=6;
+    ALLOC_GEN_BUFFER((&gen9_hcpd_context->deblocking_filter_line_buffer), "line buffer", size);
+    ALLOC_GEN_BUFFER((&gen9_hcpd_context->deblocking_filter_tile_line_buffer), "tile line buffer", size);
+
+    if(pic_param->profile >= 2)
+        size = gen9_hcpd_context->picture_height_in_ctbs*34; //num_height_in_SB * 17
+    else
+        size = gen9_hcpd_context->picture_height_in_ctbs*17; //num_height_in_SB * 17
+    size<<=6;
+    ALLOC_GEN_BUFFER((&gen9_hcpd_context->deblocking_filter_tile_column_buffer), "tile column buffer", size);
+
+    size = gen9_hcpd_context->picture_width_in_ctbs*5; //num_width_in_SB * 5
+    size<<=6;
+    ALLOC_GEN_BUFFER((&gen9_hcpd_context->metadata_line_buffer), "metadata line buffer", size);
+    ALLOC_GEN_BUFFER((&gen9_hcpd_context->metadata_tile_line_buffer), "metadata tile line buffer", size);
+
+    size = gen9_hcpd_context->picture_height_in_ctbs*5; //num_height_in_SB * 5
+    size<<=6;
+    ALLOC_GEN_BUFFER((&gen9_hcpd_context->metadata_tile_column_buffer), "metadata tile column buffer", size);
+
+    size =gen9_hcpd_context->picture_width_in_ctbs*1; //num_width_in_SB * 1
+    size<<=6;
+    ALLOC_GEN_BUFFER((&gen9_hcpd_context->hvd_line_rowstore_buffer), "hvd line rowstore buffer", size);
+    ALLOC_GEN_BUFFER((&gen9_hcpd_context->hvd_tile_rowstore_buffer), "hvd tile rowstore buffer", size);
+
+    size = 32;
+    size<<=6;
+    ALLOC_GEN_BUFFER((&gen9_hcpd_context->vp9_probability_buffer), "vp9 probability buffer", size);
+
+    gen9_hcpd_context->first_inter_slice_collocated_ref_idx = 0;
+    gen9_hcpd_context->first_inter_slice_collocated_from_l0_flag = 0;
+    gen9_hcpd_context->first_inter_slice_valid = 0;
+
+    return VA_STATUS_SUCCESS;
+}
+
+static void
+gen9_hcpd_vp9_surface_state(VADriverContextP ctx,
+                        struct decode_state *decode_state,
+                        struct gen9_hcpd_context *gen9_hcpd_context)
+{
+    struct intel_batchbuffer *batch = gen9_hcpd_context->base.batch;
+    struct object_surface *obj_surface = decode_state->render_object;
+    struct object_surface *tmp_obj_surface = NULL;
+    unsigned int y_cb_offset;
+    int i = 0;
+
+    assert(obj_surface);
+
+    y_cb_offset = obj_surface->y_cb_offset;
+
+    BEGIN_BCS_BATCH(batch, 3);
+
+    OUT_BCS_BATCH(batch, HCP_SURFACE_STATE | (3 - 2));
+    OUT_BCS_BATCH(batch,
+                  (0 << 28) |                   /* surface id */
+                  (obj_surface->width - 1));    /* pitch - 1 */
+    OUT_BCS_BATCH(batch,
+                  (((obj_surface->fourcc == VA_FOURCC_P010) ? SURFACE_FORMAT_P010: SURFACE_FORMAT_PLANAR_420_8) << 28) |
+                  y_cb_offset);
+    ADVANCE_BCS_BATCH(batch);
+
+    tmp_obj_surface = obj_surface;
+
+    for(i = 0; i < 3; i++)
+    {
+        obj_surface = gen9_hcpd_context->reference_surfaces[i].obj_surface;
+        if (obj_surface && obj_surface->private_data)
+        {
+            BEGIN_BCS_BATCH(batch, 3);
+
+            OUT_BCS_BATCH(batch, HCP_SURFACE_STATE | (3 - 2));
+            OUT_BCS_BATCH(batch,
+                ((i + 2) << 28) |                   /* surface id */
+                (obj_surface->width - 1));    /* pitch - 1 */
+            OUT_BCS_BATCH(batch,
+                (((obj_surface->fourcc == VA_FOURCC_P010) ? SURFACE_FORMAT_P010: SURFACE_FORMAT_PLANAR_420_8) << 28) |
+                obj_surface->y_cb_offset);
+            ADVANCE_BCS_BATCH(batch);
+        }else
+        {
+            BEGIN_BCS_BATCH(batch, 3);
+
+            OUT_BCS_BATCH(batch, HCP_SURFACE_STATE | (3 - 2));
+            OUT_BCS_BATCH(batch,
+                ((i + 2) << 28) |                   /* surface id */
+                (tmp_obj_surface->width - 1));    /* pitch - 1 */
+            OUT_BCS_BATCH(batch,
+                (((tmp_obj_surface->fourcc == VA_FOURCC_P010) ? SURFACE_FORMAT_P010: SURFACE_FORMAT_PLANAR_420_8) << 28) |
+                tmp_obj_surface->y_cb_offset);
+            ADVANCE_BCS_BATCH(batch);
+        }
+    }
+}
+
+static void
+gen9_hcpd_vp9_pipe_buf_addr_state(VADriverContextP ctx,
+                              struct decode_state *decode_state,
+                              struct gen9_hcpd_context *gen9_hcpd_context)
+{
+    struct i965_driver_data *i965 = i965_driver_data(ctx);
+    struct intel_batchbuffer *batch = gen9_hcpd_context->base.batch;
+    struct object_surface *obj_surface;
+    int i=0;
+
+    BEGIN_BCS_BATCH(batch, 95);
+
+    OUT_BCS_BATCH(batch, HCP_PIPE_BUF_ADDR_STATE | (95 - 2));
+
+    obj_surface = decode_state->render_object;
+    assert(obj_surface && obj_surface->bo);
+
+    OUT_BUFFER_MA_TARGET(obj_surface->bo); /* DW 1..3 */
+    OUT_BUFFER_MA_TARGET(gen9_hcpd_context->deblocking_filter_line_buffer.bo);/* DW 4..6 */
+    OUT_BUFFER_MA_TARGET(gen9_hcpd_context->deblocking_filter_tile_line_buffer.bo); /* DW 7..9 */
+    OUT_BUFFER_MA_TARGET(gen9_hcpd_context->deblocking_filter_tile_column_buffer.bo); /* DW 10..12 */
+    OUT_BUFFER_MA_TARGET(gen9_hcpd_context->metadata_line_buffer.bo);         /* DW 13..15 */
+    OUT_BUFFER_MA_TARGET(gen9_hcpd_context->metadata_tile_line_buffer.bo);    /* DW 16..18 */
+    OUT_BUFFER_MA_TARGET(gen9_hcpd_context->metadata_tile_column_buffer.bo);  /* DW 19..21 */
+    OUT_BUFFER_MA_TARGET(NULL);    /* DW 22..24, ignore for VP9 */
+    OUT_BUFFER_MA_TARGET(NULL);    /* DW 25..27, ignore for VP9 */
+    OUT_BUFFER_MA_TARGET(NULL);    /* DW 28..30, ignore for VP9 */
+    OUT_BUFFER_MA_TARGET(gen9_hcpd_context->vp9_mv_temporal_buffer_curr.bo); /* DW 31..33 */
+
+    OUT_BUFFER_MA_TARGET(NULL); /* DW 34..36, reserved */
+
+    /* DW 37..52 - Reference picture address */
+    for (i = 0; i < 3; i++)
+    {
+        obj_surface = gen9_hcpd_context->reference_surfaces[i].obj_surface;
+
+        if (obj_surface)
+        {
+            OUT_BUFFER_NMA_REFERENCE(obj_surface->bo);
+        }
+        else
+            OUT_BUFFER_NMA_REFERENCE(NULL);
+    }
+    for (; i < ARRAY_ELEMS(gen9_hcpd_context->reference_surfaces); i++)
+    {
+       OUT_BUFFER_NMA_REFERENCE(NULL);
+    }
+    OUT_BCS_BATCH(batch, 0);    /* DW 53, memory address attributes */
+
+    OUT_BUFFER_MA_REFERENCE(NULL); /* DW 54..56, ignore for decoding mode */
+    OUT_BUFFER_MA_TARGET(NULL); /* DW 57..59, StreamOutEnable - used for transcoding */
+    OUT_BUFFER_MA_TARGET(NULL); /* DW 60..62, DecodedPictureStatusError, ignored */
+    OUT_BUFFER_MA_TARGET(NULL); /* DW 63..65, Ignored */
+
+    /* DW 66..81 - for 8 Collocated motion vectors */
+    for (i = 0; i < 1; i++)
+    {
+        OUT_BUFFER_NMA_REFERENCE(gen9_hcpd_context->vp9_mv_temporal_buffer_last.bo);
+    }
+    for (; i < ARRAY_ELEMS(gen9_hcpd_context->reference_surfaces); i++)
+    {
+        OUT_BUFFER_NMA_REFERENCE(NULL);
+    }
+
+    OUT_BCS_BATCH(batch, 0);    /* DW 82, memory address attributes */
+
+    OUT_BUFFER_MA_TARGET(gen9_hcpd_context->vp9_probability_buffer.bo); /* DW 83..85, VP9 Probability bufffer */
+    OUT_BUFFER_MA_TARGET(gen9_hcpd_context->vp9_segment_id_buffer.bo);  /* DW 86..88, VP9 Segment ID buffer */
+    OUT_BUFFER_MA_TARGET(gen9_hcpd_context->hvd_line_rowstore_buffer.bo);/* DW 89..91, VP9 HVD Line Rowstore buffer */
+    OUT_BUFFER_MA_TARGET(gen9_hcpd_context->hvd_tile_rowstore_buffer.bo);/* DW 92..94, VP9 HVD Tile Rowstore buffer */
+
+    ADVANCE_BCS_BATCH(batch);
+}
+
+static inline int
+gen9_hcpd_vp9_valid_ref_frame_size(int ref_width, int ref_height,
+                                   int cur_width, int cur_height) {
+  return 2 * cur_width >= ref_width &&
+         2 * cur_height >= ref_height &&
+         cur_width <= 16 * ref_width &&
+         cur_height <= 16 * ref_height;
+}
+static void
+gen9_hcpd_vp9_pic_state(VADriverContextP ctx,
+                       struct decode_state *decode_state,
+                       struct gen9_hcpd_context *gen9_hcpd_context)
+{
+    struct intel_batchbuffer *batch = gen9_hcpd_context->base.batch;
+    VADecPictureParameterBufferVP9 *pic_param;
+    struct object_surface *obj_surface;
+    GenVP9Surface *gen9_vp9_surface;
+    uint16_t scale_h = 0;
+    uint16_t scale_w = 0;
+    uint16_t frame_width_in_pixel = 0;
+    uint16_t frame_height_in_pixel = 0;
+    uint16_t fwidth = 64;
+    uint16_t fheight = 64;
+    int i;
+    int bit_depth_minus8 = 0;
+
+#define LEN_COMMAND_OWN 12
+    assert(decode_state->pic_param && decode_state->pic_param->buffer);
+    pic_param = (VADecPictureParameterBufferVP9 *)decode_state->pic_param->buffer;
+
+    uint8_t segmentIDStreamInEnable = 0;
+    uint8_t segmentIDStreamOutEnable = (pic_param->pic_fields.bits.segmentation_enabled && pic_param->pic_fields.bits.segmentation_update_map);
+
+    // For KEY_FRAME or INTRA_ONLY frame, this bit should be set to "0".
+    uint8_t segmentation_temporal_update =
+    ((pic_param->pic_fields.bits.frame_type == HCP_VP9_KEY_FRAME) || (pic_param->pic_fields.bits.intra_only)) ? 0 : pic_param->pic_fields.bits.segmentation_temporal_update;
+
+
+    if(pic_param->pic_fields.bits.intra_only || (pic_param->pic_fields.bits.frame_type == HCP_VP9_KEY_FRAME))
+    {
+        segmentIDStreamInEnable = 1;
+    }else if(pic_param->pic_fields.bits.segmentation_enabled)
+    {
+        if(!pic_param->pic_fields.bits.segmentation_update_map)
+        {
+            segmentIDStreamInEnable = 1;
+
+        }else if( pic_param->pic_fields.bits.segmentation_temporal_update)
+        {
+            segmentIDStreamInEnable = 1;
+        }
+    }
+
+    if(pic_param->pic_fields.bits.error_resilient_mode)
+    {
+        segmentIDStreamInEnable = 1;
+    }
+
+    //frame type of previous frame (Key or Non-Key Frame).
+    uint8_t last_frame_type = gen9_hcpd_context->last_frame.frame_type;
+
+    uint8_t use_pre_frame_mvs = 0;
+    use_pre_frame_mvs = !((pic_param->pic_fields.bits.error_resilient_mode) ||
+                                (pic_param->frame_width != gen9_hcpd_context->last_frame.frame_width) ||
+                                (pic_param->frame_height != gen9_hcpd_context->last_frame.frame_height) ||
+                                (pic_param->pic_fields.bits.intra_only) ||
+                                (pic_param->pic_fields.bits.frame_type == HCP_VP9_KEY_FRAME)||
+                                (gen9_hcpd_context->last_frame.intra_only)||
+                                (last_frame_type == HCP_VP9_KEY_FRAME) ||
+                                (!gen9_hcpd_context->last_frame.show_frame));
+
+    uint8_t adapt_probabilities_flag = 0;
+    if((pic_param->pic_fields.bits.error_resilient_mode || pic_param->pic_fields.bits.frame_parallel_decoding_mode))
+        adapt_probabilities_flag = 0; //0: Do not adapt (error resilient or frame_parallel_mode are set)
+    else if(!(pic_param->pic_fields.bits.error_resilient_mode) && !(pic_param->pic_fields.bits.frame_parallel_decoding_mode))
+        adapt_probabilities_flag = 1; //1: Adapt (not error resilient and not frame_ parallel_mode)
+
+    frame_width_in_pixel  = (gen9_hcpd_context->picture_width_in_min_cb_minus1  + 1) * gen9_hcpd_context->min_cb_size ;
+    frame_height_in_pixel = (gen9_hcpd_context->picture_height_in_min_cb_minus1 + 1) * gen9_hcpd_context->min_cb_size ;
+
+    fwidth = (fwidth > frame_width_in_pixel)?frame_width_in_pixel:fwidth;
+    fheight = (fheight > frame_height_in_pixel)?frame_height_in_pixel:fheight;
+
+    if(pic_param->profile >= 2)
+    {
+        if(pic_param->bit_depth >= 8)
+            bit_depth_minus8 = pic_param->bit_depth - 8;
+    }
+
+    BEGIN_BCS_BATCH(batch, LEN_COMMAND_OWN);
+
+    OUT_BCS_BATCH(batch, HCP_VP9_PIC_STATE | (LEN_COMMAND_OWN - 2));
+
+    OUT_BCS_BATCH(batch,
+                  (frame_height_in_pixel - 1) << 16 |
+                  (frame_width_in_pixel - 1));         /* DW 1 */
+    OUT_BCS_BATCH(batch,
+                  segmentIDStreamInEnable << 31 |
+                  segmentIDStreamOutEnable << 30 |
+                  pic_param->pic_fields.bits.lossless_flag << 29 |
+                  segmentation_temporal_update << 28 |
+                  pic_param->pic_fields.bits.segmentation_update_map << 27 |
+                  pic_param->pic_fields.bits.segmentation_enabled << 26   |
+                  pic_param->sharpness_level << 23 |
+                  pic_param->filter_level << 17 |
+                  pic_param->pic_fields.bits.frame_parallel_decoding_mode << 16 |
+                  pic_param->pic_fields.bits.error_resilient_mode << 15 |
+                  pic_param->pic_fields.bits.refresh_frame_context << 14 |
+                  last_frame_type << 13 |
+                  0 << 12 |   /* tx select mode */
+                  0 << 11 |   /* Hybrid Prediction Mode */
+                  use_pre_frame_mvs << 10 |
+                  pic_param->pic_fields.bits.alt_ref_frame_sign_bias << 9 |
+                  pic_param->pic_fields.bits.golden_ref_frame_sign_bias << 8 |
+                  pic_param->pic_fields.bits.last_ref_frame_sign_bias << 7 |
+                  pic_param->pic_fields.bits.mcomp_filter_type << 4 |
+                  pic_param->pic_fields.bits.allow_high_precision_mv << 3 |
+                  pic_param->pic_fields.bits.intra_only <<2 |
+                  adapt_probabilities_flag << 1 |
+                  pic_param->pic_fields.bits.frame_type <<0);               /* DW 2 */
+    OUT_BCS_BATCH(batch,
+        pic_param->profile << 28 |
+        bit_depth_minus8 << 24 |
+        0 << 22 | /* only support 4:2:0 */
+        pic_param->log2_tile_rows << 8 |
+        pic_param->log2_tile_columns <<0);                       /* DW 3 */
+    // resolution change case
+
+    // DW4-DW6
+    for(i = 0; i < 3; i++)
+    {
+        obj_surface = gen9_hcpd_context->reference_surfaces[i].obj_surface;
+        gen9_vp9_surface = NULL;
+        scale_w = 0;
+        scale_h = 0;
+        if (obj_surface && obj_surface->private_data)
+        {
+            gen9_vp9_surface = obj_surface->private_data;
+            if(!gen9_hcpd_vp9_valid_ref_frame_size(gen9_vp9_surface->frame_width,gen9_vp9_surface->frame_height,pic_param->frame_width,pic_param->frame_height))
+            {
+                scale_w = -1;
+                scale_h = -1;
+            }else
+            {
+                scale_w = (gen9_vp9_surface->frame_width  << 14) /pic_param->frame_width ;
+                scale_h = (gen9_vp9_surface->frame_height << 14) /pic_param->frame_height ;
+            }
+            OUT_BCS_BATCH(batch,
+                scale_w<<16 |
+                scale_h);
+        }else
+        {
+            OUT_BCS_BATCH(batch, 0);
+        }
+    }
+
+    // DW7-DW9
+    for(i = 0; i < 3; i++)
+    {
+        obj_surface = gen9_hcpd_context->reference_surfaces[i].obj_surface;
+        gen9_vp9_surface = NULL;
+
+        if (obj_surface && obj_surface->private_data)
+        {
+            gen9_vp9_surface = obj_surface->private_data;
+            OUT_BCS_BATCH(batch,
+                ((gen9_vp9_surface->frame_height- 1)&0x3fff)<<16 |
+                ((gen9_vp9_surface->frame_width - 1)&0x3fff));
+        }else
+        {
+            OUT_BCS_BATCH(batch, 0);
+        }
+    }
+
+    OUT_BCS_BATCH(batch,
+                  pic_param->first_partition_size << 16 |
+                  pic_param->frame_header_length_in_bytes <<0); /* DW 10 */
+    OUT_BCS_BATCH(batch,
+                  (0 << 3) |
+                  (0 << 2) |
+                  (1 << 1) |
+                  (0 << 0)); /* DW 11, ignored */
+    //Rest of the DWs are not valid for BXT
+    for(i = 12; i < LEN_COMMAND_OWN; i++)
+    {
+        OUT_BCS_BATCH(batch, 0);
+    }
+
+    ADVANCE_BCS_BATCH(batch);
+
+}
+
+static void
+gen9_hcpd_vp9_segment_state(VADriverContextP ctx,
+                            VADecPictureParameterBufferVP9 *pic_param,
+                            VASegmentParameterVP9 *seg_param, uint8_t seg_id,
+                            struct gen9_hcpd_context *gen9_hcpd_context)
+{
+    struct intel_batchbuffer *batch = gen9_hcpd_context->base.batch;
+
+    int segment_ref = seg_param->segment_flags.fields.segment_reference;
+
+    if((pic_param->pic_fields.bits.frame_type == HCP_VP9_KEY_FRAME)
+            || (pic_param->pic_fields.bits.intra_only))
+        segment_ref = 0;
+
+    BEGIN_BCS_BATCH(batch, 7);
+
+    OUT_BCS_BATCH(batch, HCP_VP9_SEGMENT_STATE | (7 - 2));
+    OUT_BCS_BATCH(batch, seg_id << 0); /* DW 1 - SegmentID */
+    OUT_BCS_BATCH(batch,
+                  seg_param->segment_flags.fields.segment_reference_enabled << 3 |
+                  segment_ref << 1 |
+                  seg_param->segment_flags.fields.segment_reference_skipped <<0 ); /* DW 2 */
+    if(pic_param->filter_level)
+    {
+        OUT_BCS_BATCH(batch,
+            seg_param->filter_level[1][1] << 24    | //FilterLevelRef1Mode1
+            seg_param->filter_level[1][0] << 16    | //FilterLevelRef1Mode0
+            seg_param->filter_level[0][1] << 8     | //FilterLevelRef0Mode1
+            seg_param->filter_level[0][0] << 0 );     //FilterLevelRef0Mode0 /* DW 3 */
+        OUT_BCS_BATCH(batch,
+            seg_param->filter_level[3][1] << 24    | //FilterLevelRef3Mode1
+            seg_param->filter_level[3][0] << 16    | //FilterLevelRef3Mode0
+            seg_param->filter_level[2][1] << 8     | //FilterLevelRef2Mode1
+            seg_param->filter_level[2][0] << 0 );    //FilterLevelRef2Mode0 /* DW 4 */
+    }else
+    {
+        OUT_BCS_BATCH(batch,
+            0 );      /* DW 3 */
+        OUT_BCS_BATCH(batch,
+            0 );      /* DW 4 */
+    }
+    OUT_BCS_BATCH(batch,
+                  seg_param->luma_ac_quant_scale << 16   |
+                  seg_param->luma_dc_quant_scale << 0 );    /* DW 5 */
+    OUT_BCS_BATCH(batch,
+                  seg_param->chroma_ac_quant_scale << 16 |
+                  seg_param->chroma_dc_quant_scale << 0 );  /* DW 6 */
+
+    ADVANCE_BCS_BATCH(batch);
+
+}
+
+static void
+gen9_hcpd_vp9_bsd_object(VADriverContextP ctx,
+                     VADecPictureParameterBufferVP9 *pic_param,
+                     VASliceParameterBufferVP9 *slice_param,
+                     struct gen9_hcpd_context *gen9_hcpd_context)
+{
+    struct intel_batchbuffer *batch = gen9_hcpd_context->base.batch;
+    int slice_data_size   = slice_param->slice_data_size - pic_param->frame_header_length_in_bytes;
+    int slice_data_offset = slice_param->slice_data_offset + pic_param->frame_header_length_in_bytes;
+
+    BEGIN_BCS_BATCH(batch, 3);
+
+    OUT_BCS_BATCH(batch, HCP_BSD_OBJECT | (3 - 2));
+
+    OUT_BCS_BATCH(batch, slice_data_size );
+    OUT_BCS_BATCH(batch, slice_data_offset);
+
+    ADVANCE_BCS_BATCH(batch);
+
+}
+
+static VAStatus
+gen9_hcpd_vp9_decode_picture(VADriverContextP ctx,
+                              struct decode_state *decode_state,
+                              struct gen9_hcpd_context *gen9_hcpd_context)
+{
+    VAStatus vaStatus = VA_STATUS_SUCCESS;
+    struct i965_driver_data *i965 = i965_driver_data(ctx);
+    struct intel_batchbuffer *batch = gen9_hcpd_context->base.batch;
+    VADecPictureParameterBufferVP9 *pic_param;
+    VASliceParameterBufferVP9 *slice_param;
+    dri_bo *slice_data_bo;
+    dri_bo *tmp_bo;
+    uint16_t tmp;
+    int i = 0, num_segments=0;
+
+    assert(decode_state->pic_param && decode_state->pic_param->buffer);
+    assert(decode_state->slice_params && decode_state->slice_params[0]->buffer);
+    slice_param = (VASliceParameterBufferVP9 *)decode_state->slice_params[0]->buffer;
+    pic_param = (VADecPictureParameterBufferVP9 *)decode_state->pic_param->buffer;
+
+    if(slice_param->slice_data_size == 1)
+    {
+        goto out;
+    }
+
+    vaStatus = gen9_hcpd_vp9_decode_init(ctx, decode_state, gen9_hcpd_context);
+
+    if (vaStatus != VA_STATUS_SUCCESS)
+        goto out;
+
+    //Update segment id buffer if needed
+    vp9_update_segmentId_buffer(ctx, decode_state, gen9_hcpd_context);
+    //Update mv buffer if needed
+    vp9_update_mv_temporal_buffer(ctx, decode_state, gen9_hcpd_context);
+    //Update probability buffer if needed
+    vp9_update_probabilities(ctx, decode_state, gen9_hcpd_context);
+
+    if (i965->intel.has_bsd2)
+        intel_batchbuffer_start_atomic_bcs_override(batch, 0x1000, BSD_RING0);
+    else
+        intel_batchbuffer_start_atomic_bcs(batch, 0x1000);
+    intel_batchbuffer_emit_mi_flush(batch);
+
+    gen9_hcpd_pipe_mode_select(ctx, decode_state, HCP_CODEC_VP9, gen9_hcpd_context);
+    //Not sure what the surface id value should be: Gold? ALtRef? PrevRef? or Just RefPic?
+    gen9_hcpd_vp9_surface_state(ctx, decode_state, gen9_hcpd_context);
+
+    //Only one VASliceParameterBufferVP9 should be sent per frame
+    slice_data_bo = decode_state->slice_datas[0]->bo;
+
+    gen9_hcpd_ind_obj_base_addr_state(ctx, slice_data_bo, gen9_hcpd_context);
+
+    gen9_hcpd_vp9_pipe_buf_addr_state(ctx, decode_state, gen9_hcpd_context);
+    //If segmentation is disabled, only SegParam[0] is valid,
+    //all others should be populated with 0
+    if(!pic_param->pic_fields.bits.segmentation_enabled)
+        num_segments = 1;
+    else  //If segmentation is enabled, all 8 entries should be valid.
+        num_segments = 8;
+
+    for(i=0; i<num_segments; i++) {
+        VASegmentParameterVP9 seg_param = slice_param->seg_param[i];
+        gen9_hcpd_vp9_segment_state(ctx, pic_param, &seg_param, i, gen9_hcpd_context);
+    }
+
+    gen9_hcpd_vp9_pic_state(ctx, decode_state, gen9_hcpd_context);
+
+    gen9_hcpd_vp9_bsd_object(ctx, pic_param, slice_param, gen9_hcpd_context);
+
+    intel_batchbuffer_end_atomic(batch);
+    intel_batchbuffer_flush(batch);
+
+    // keep track of the last frame status
+    gen9_hcpd_context->last_frame.frame_width = pic_param->frame_width;
+    gen9_hcpd_context->last_frame.frame_height = pic_param->frame_height;
+    gen9_hcpd_context->last_frame.show_frame = pic_param->pic_fields.bits.show_frame;
+    gen9_hcpd_context->last_frame.frame_type = pic_param->pic_fields.bits.frame_type;
+    gen9_hcpd_context->last_frame.refresh_frame_context = pic_param->pic_fields.bits.refresh_frame_context;
+    gen9_hcpd_context->last_frame.frame_context_idx = pic_param->pic_fields.bits.frame_context_idx;
+    gen9_hcpd_context->last_frame.intra_only = pic_param->pic_fields.bits.intra_only;
+
+    // switch mv buffer
+    if(pic_param->pic_fields.bits.frame_type != HCP_VP9_KEY_FRAME)
+    {
+        tmp_bo = gen9_hcpd_context->vp9_mv_temporal_buffer_last.bo;
+        gen9_hcpd_context->vp9_mv_temporal_buffer_last.bo = gen9_hcpd_context->vp9_mv_temporal_buffer_curr.bo;
+        gen9_hcpd_context->vp9_mv_temporal_buffer_curr.bo = tmp_bo;
+
+        tmp = gen9_hcpd_context->vp9_mv_temporal_buffer_last.frame_width;
+        gen9_hcpd_context->vp9_mv_temporal_buffer_last.frame_width = gen9_hcpd_context->vp9_mv_temporal_buffer_curr.frame_width;
+        gen9_hcpd_context->vp9_mv_temporal_buffer_curr.frame_width = tmp;
+
+        tmp = gen9_hcpd_context->vp9_mv_temporal_buffer_last.frame_height;
+        gen9_hcpd_context->vp9_mv_temporal_buffer_last.frame_height = gen9_hcpd_context->vp9_mv_temporal_buffer_curr.frame_height;
+        gen9_hcpd_context->vp9_mv_temporal_buffer_curr.frame_height = tmp;
+
+
+    }
+    //update vp9_frame_ctx according to frame_context_id
+    if (pic_param->pic_fields.bits.refresh_frame_context)
+    {
+        void *pfc = (void *)&gen9_hcpd_context->vp9_frame_ctx[pic_param->pic_fields.bits.frame_context_idx];
+        void *pprob = NULL;
+
+        //update vp9_fc to frame_context
+        dri_bo_map(gen9_hcpd_context->vp9_probability_buffer.bo,1);
+        pprob = (void *)gen9_hcpd_context->vp9_probability_buffer.bo->virtual;
+        if(pic_param->pic_fields.bits.frame_type == HCP_VP9_KEY_FRAME||
+                pic_param->pic_fields.bits.intra_only)
+            memcpy(pfc, pprob, VP9_PROB_BUFFER_FIRST_PART_SIZE - VP9_PROB_BUFFER_KEY_INTER_SIZE);
+        else
+            memcpy(pfc, pprob, VP9_PROB_BUFFER_FIRST_PART_SIZE);
+
+        dri_bo_unmap(gen9_hcpd_context->vp9_probability_buffer.bo);
+    }
+
+out:
+    return vaStatus;
+}
+
+
 static VAStatus
 gen9_hcpd_decode_picture(VADriverContextP ctx,
                          VAProfile profile,
@@ -941,6 +1875,10 @@ gen9_hcpd_decode_picture(VADriverContextP ctx,
     case VAProfileHEVCMain10:
         vaStatus = gen9_hcpd_hevc_decode_picture(ctx, decode_state, gen9_hcpd_context);
         break;
+    case VAProfileVP9Profile0:
+    case VAProfileVP9Profile2:
+        vaStatus = gen9_hcpd_vp9_decode_picture(ctx, decode_state, gen9_hcpd_context);
+        break;
 
     default:
         /* should never get here 1!! */
@@ -966,6 +1904,12 @@ gen9_hcpd_context_destroy(void *hw_context)
     FREE_GEN_BUFFER((&gen9_hcpd_context->sao_line_buffer));
     FREE_GEN_BUFFER((&gen9_hcpd_context->sao_tile_line_buffer));
     FREE_GEN_BUFFER((&gen9_hcpd_context->sao_tile_column_buffer));
+    FREE_GEN_BUFFER((&gen9_hcpd_context->hvd_line_rowstore_buffer));
+    FREE_GEN_BUFFER((&gen9_hcpd_context->hvd_tile_rowstore_buffer));
+    FREE_GEN_BUFFER((&gen9_hcpd_context->vp9_probability_buffer));
+    FREE_GEN_BUFFER((&gen9_hcpd_context->vp9_segment_id_buffer));
+    dri_bo_unreference(gen9_hcpd_context->vp9_mv_temporal_buffer_curr.bo);
+    dri_bo_unreference(gen9_hcpd_context->vp9_mv_temporal_buffer_last.bo);
 
     intel_batchbuffer_free(gen9_hcpd_context->base.batch);
     free(gen9_hcpd_context);
@@ -978,6 +1922,27 @@ gen9_hcpd_hevc_context_init(VADriverContextP ctx,
     hevc_gen_default_iq_matrix(&gen9_hcpd_context->iq_matrix_hevc);
 }
 
+static void
+gen9_hcpd_vp9_context_init(VADriverContextP ctx,
+                            struct gen9_hcpd_context *gen9_hcpd_context)
+{
+
+    gen9_hcpd_context->last_frame.frame_height  = 0;
+    gen9_hcpd_context->last_frame.show_frame    = 0;
+    gen9_hcpd_context->last_frame.frame_type    = 0;
+    gen9_hcpd_context->last_frame.refresh_frame_context = 0;
+    gen9_hcpd_context->last_frame.frame_context_idx = 0;
+    gen9_hcpd_context->last_frame.intra_only = 0;
+    gen9_hcpd_context->last_frame.prob_buffer_saved_flag = 0;
+    gen9_hcpd_context->last_frame.prob_buffer_restored_flag = 0;
+
+    //Super block in VP9 is 64x64
+    gen9_hcpd_context->ctb_size = 64;
+    gen9_hcpd_context->min_cb_size = 8; //Min block size is 8
+
+    vp9_gen_default_probabilities(ctx, gen9_hcpd_context);
+}
+
 static struct hw_context *
 gen9_hcpd_context_init(VADriverContextP ctx, struct object_config *object_config)
 {
@@ -1003,6 +1968,10 @@ gen9_hcpd_context_init(VADriverContextP ctx, struct object_config *object_config
     case VAProfileHEVCMain10:
         gen9_hcpd_hevc_context_init(ctx, gen9_hcpd_context);
         break;
+    case VAProfileVP9Profile0:
+    case VAProfileVP9Profile2:
+        gen9_hcpd_vp9_context_init(ctx, gen9_hcpd_context);
+        break;
 
     default:
         break;
@@ -1015,9 +1984,25 @@ struct hw_context *
 gen9_dec_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
 {
     if (obj_config->profile == VAProfileHEVCMain ||
-        obj_config->profile == VAProfileHEVCMain10) {
+        obj_config->profile == VAProfileHEVCMain10 ||
+        obj_config->profile == VAProfileVP9Profile0 ||
+        obj_config->profile == VAProfileVP9Profile2) {
         return gen9_hcpd_context_init(ctx, obj_config);
     } else {
         return gen8_dec_hw_context_init(ctx, obj_config);
     }
 }
+
+void gen9_max_resolution(struct i965_driver_data *i965,
+                         struct object_config *obj_config,
+                         int *w,                                /* out */
+                         int *h)                                /* out */
+{
+    if (obj_config->profile == VAProfileJPEGBaseline) {
+        *w = 8192;
+        *h = 8192;
+    } else {
+        *w = i965->codec_info->max_width;
+        *h = i965->codec_info->max_height;
+    }
+}