OSDN Git Service

ROI:enable on gen8 and gen9
[android-x86/hardware-intel-common-vaapi.git] / src / i965_drv_video.c
index 9bbd67f..1c24d00 100644 (file)
@@ -48,6 +48,8 @@
 #include "i965_decoder.h"
 #include "i965_encoder.h"
 
+#include "gen9_vp9_encapi.h"
+
 #define CONFIG_ID_OFFSET                0x01000000
 #define CONTEXT_ID_OFFSET               0x02000000
 #define SURFACE_ID_OFFSET               0x04000000
@@ -67,6 +69,9 @@
 #define HAS_H264_ENCODING(ctx)  ((ctx)->codec_info->has_h264_encoding && \
                                  (ctx)->intel.has_bsd)
 
+#define HAS_LP_H264_ENCODING(ctx)  ((ctx)->codec_info->has_lp_h264_encoding && \
+                                    (ctx)->intel.has_bsd)
+
 #define HAS_VC1_DECODING(ctx)   ((ctx)->codec_info->has_vc1_decoding && \
                                  (ctx)->intel.has_bsd)
 
 #define HAS_HEVC_ENCODING(ctx)          ((ctx)->codec_info->has_hevc_encoding && \
                                          (ctx)->intel.has_bsd)
 
+#define HAS_VP9_DECODING(ctx)          ((ctx)->codec_info->has_vp9_decoding && \
+                                         (ctx)->intel.has_bsd)
+
+#define HAS_VP9_DECODING_PROFILE(ctx, profile)                     \
+    (HAS_VP9_DECODING(ctx) &&                                      \
+     ((ctx)->codec_info->vp9_dec_profiles & (1U << (profile - VAProfileVP9Profile0))))
+
+#define HAS_HEVC10_DECODING(ctx)        ((ctx)->codec_info->has_hevc10_decoding && \
+                                         (ctx)->intel.has_bsd)
+
+#define HAS_VPP_P010(ctx)        ((ctx)->codec_info->has_vpp_p010 && \
+                                         (ctx)->intel.has_bsd)
+
+#define HAS_VP9_ENCODING(ctx)          ((ctx)->codec_info->has_vp9_encoding && \
+                                         (ctx)->intel.has_bsd)
+
 static int get_sampling_from_fourcc(unsigned int fourcc);
 
 /* Check whether we are rendering to X11 (VA/X11 or VA/GLX API) */
@@ -141,11 +162,13 @@ static int get_sampling_from_fourcc(unsigned int fourcc);
 #define I_YV12  2, 2, 3, {I965_8BITS, I965_2BITS, I965_2BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_2, OFFSET_0}, {PLANE_1, OFFSET_0} }
 #define I_IMC1  I_YV12
 
+#define I_P010  2, 2, 2, {I965_16BITS, I965_8BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_1, OFFSET_0}, {PLANE_1, OFFSET_16} }
+
 #define I_422H  2, 1, 3, {I965_8BITS, I965_4BITS, I965_4BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_1, OFFSET_0}, {PLANE_2, OFFSET_0} }
 #define I_422V  1, 2, 3, {I965_8BITS, I965_4BITS, I965_4BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_1, OFFSET_0}, {PLANE_2, OFFSET_0} }
 #define I_YV16  2, 1, 3, {I965_8BITS, I965_4BITS, I965_4BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_2, OFFSET_0}, {PLANE_1, OFFSET_0} }
-#define I_YUY2  2, 1, 1, {I965_32BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_0, OFFSET_8}, {PLANE_0, OFFSET_24} }
-#define I_UYVY  2, 1, 1, {I965_32BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_0, OFFSET_8}, {PLANE_0, OFFSET_16} }
+#define I_YUY2  2, 1, 1, {I965_16BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_0, OFFSET_8}, {PLANE_0, OFFSET_24} }
+#define I_UYVY  2, 1, 1, {I965_16BITS}, 3, { {PLANE_0, OFFSET_8}, {PLANE_0, OFFSET_0}, {PLANE_0, OFFSET_16} }
 
 #define I_444P  1, 1, 3, {I965_8BITS, I965_8BITS, I965_8BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_1, OFFSET_0}, {PLANE_2, OFFSET_0} }
 
@@ -185,6 +208,8 @@ static const i965_fourcc_info i965_fourcc_infos[] = {
     DEF_YUV(YV12, YUV420, I_SI),
     DEF_YUV(IMC1, YUV420, I_S),
 
+    DEF_YUV(P010, YUV420, I_SI),
+
     DEF_YUV(422H, YUV422H, I_SI),
     DEF_YUV(422V, YUV422V, I_S),
     DEF_YUV(YV16, YUV422H, I_S),
@@ -217,7 +242,7 @@ get_fourcc_info(unsigned int fourcc)
 {
     unsigned int i;
 
-    for (i = 0; ARRAY_ELEMS(i965_fourcc_infos); i++) {
+    for (i = 0; i < ARRAY_ELEMS(i965_fourcc_infos); i++) {
         const i965_fourcc_info * const info = &i965_fourcc_infos[i];
 
         if (info->fourcc == fourcc)
@@ -227,6 +252,22 @@ get_fourcc_info(unsigned int fourcc)
     return NULL;
 }
 
+static int
+get_bpp_from_fourcc(unsigned int fourcc)
+{
+    const i965_fourcc_info *info = get_fourcc_info(fourcc);
+    unsigned int i = 0;
+    unsigned int bpp = 0;
+
+    if (!info)
+        return 0;
+
+    for (i = 0; i < info->num_planes; i++)
+        bpp += info->bpp[i];
+
+    return bpp;
+}
+
 enum {
     I965_SURFACETYPE_RGBA = 1,
     I965_SURFACETYPE_YUV,
@@ -290,6 +331,8 @@ i965_image_formats_map[I965_MAX_IMAGE_FORMATS + 1] = {
       { VA_FOURCC_RGBX, VA_LSB_FIRST, 32, 24, 0x000000ff, 0x0000ff00, 0x00ff0000 } },
     { I965_SURFACETYPE_RGBA,
       { VA_FOURCC_BGRX, VA_LSB_FIRST, 32, 24, 0x00ff0000, 0x0000ff00, 0x000000ff } },
+    { I965_SURFACETYPE_YUV,
+      { VA_FOURCC_P010, VA_LSB_FIRST, 24, } },
 };
 
 /* List of supported subpicture formats */
@@ -524,14 +567,17 @@ i965_QueryConfigProfiles(VADriverContextP ctx,
     }
 
     if (HAS_H264_DECODING(i965) ||
-        HAS_H264_ENCODING(i965)) {
+        HAS_H264_ENCODING(i965) ||
+        HAS_LP_H264_ENCODING(i965)) {
         profile_list[i++] = VAProfileH264ConstrainedBaseline;
         profile_list[i++] = VAProfileH264Main;
         profile_list[i++] = VAProfileH264High;
     }
-    if (HAS_H264_MVC_DECODING_PROFILE(i965, VAProfileH264MultiviewHigh))
+    if (HAS_H264_MVC_DECODING_PROFILE(i965, VAProfileH264MultiviewHigh) ||
+        HAS_H264_MVC_ENCODING(i965))
         profile_list[i++] = VAProfileH264MultiviewHigh;
-    if (HAS_H264_MVC_DECODING_PROFILE(i965, VAProfileH264StereoHigh))
+    if (HAS_H264_MVC_DECODING_PROFILE(i965, VAProfileH264StereoHigh) ||
+        HAS_H264_MVC_ENCODING(i965))
         profile_list[i++] = VAProfileH264StereoHigh;
 
     if (HAS_VC1_DECODING(i965)) {
@@ -554,16 +600,24 @@ i965_QueryConfigProfiles(VADriverContextP ctx,
         profile_list[i++] = VAProfileVP8Version0_3;
     }
 
-    if (HAS_H264_MVC_ENCODING(i965)) {
-        profile_list[i++] = VAProfileH264MultiviewHigh;
-        profile_list[i++] = VAProfileH264StereoHigh;
-    }
-
     if (HAS_HEVC_DECODING(i965)||
         HAS_HEVC_ENCODING(i965)) {
         profile_list[i++] = VAProfileHEVCMain;
     }
 
+    if (HAS_HEVC10_DECODING(i965)) {
+        profile_list[i++] = VAProfileHEVCMain10;
+    }
+
+    if(HAS_VP9_DECODING_PROFILE(i965, VAProfileVP9Profile0) ||
+        HAS_VP9_ENCODING(i965)) {
+        profile_list[i++] = VAProfileVP9Profile0;
+    }
+
+    if(HAS_VP9_DECODING_PROFILE(i965, VAProfileVP9Profile2)) {
+        profile_list[i++] = VAProfileVP9Profile2;
+    }
+
     if (i965->wrapper_pdrvctx) {
         VAProfile wrapper_list[4];
         int wrapper_num;
@@ -619,6 +673,9 @@ i965_QueryConfigEntrypoints(VADriverContextP ctx,
         if (HAS_H264_ENCODING(i965))
             entrypoint_list[n++] = VAEntrypointEncSlice;
 
+        if (HAS_LP_H264_ENCODING(i965))
+            entrypoint_list[n++] = VAEntrypointEncSliceLP;
+
         break;
    case VAProfileH264MultiviewHigh:
    case VAProfileH264StereoHigh:
@@ -667,16 +724,31 @@ i965_QueryConfigEntrypoints(VADriverContextP ctx,
 
         break;
 
+    case VAProfileHEVCMain10:
+        if (HAS_HEVC10_DECODING(i965))
+            entrypoint_list[n++] = VAEntrypointVLD;
+
+        break;
+
     case VAProfileVP9Profile0:
-        if (i965->wrapper_pdrvctx) {
-            VAStatus va_status = VA_STATUS_SUCCESS;
-            VADriverContextP pdrvctx = i965->wrapper_pdrvctx;
+    case VAProfileVP9Profile2:
+        if(HAS_VP9_DECODING_PROFILE(i965, profile))
+            entrypoint_list[n++] = VAEntrypointVLD;
 
-            CALL_VTABLE(pdrvctx, va_status,
-                        vaQueryConfigEntrypoints(pdrvctx, profile,
-                                                 entrypoint_list,
-                                                 num_entrypoints));
-            return va_status;
+        if (HAS_VP9_ENCODING(i965) && (profile == VAProfileVP9Profile0))
+            entrypoint_list[n++] = VAEntrypointEncSlice;
+
+        if(profile == VAProfileVP9Profile0) {
+          if (i965->wrapper_pdrvctx) {
+              VAStatus va_status = VA_STATUS_SUCCESS;
+              VADriverContextP pdrvctx = i965->wrapper_pdrvctx;
+
+              CALL_VTABLE(pdrvctx, va_status,
+                          vaQueryConfigEntrypoints(pdrvctx, profile,
+                                                   entrypoint_list,
+                                                   num_entrypoints));
+              return va_status;
+          }
         }
 
         break;
@@ -714,7 +786,8 @@ i965_validate_config(VADriverContextP ctx, VAProfile profile,
     case VAProfileH264Main:
     case VAProfileH264High:
         if ((HAS_H264_DECODING(i965) && entrypoint == VAEntrypointVLD) ||
-            (HAS_H264_ENCODING(i965) && entrypoint == VAEntrypointEncSlice)) {
+            (HAS_H264_ENCODING(i965) && entrypoint == VAEntrypointEncSlice) ||
+            (HAS_LP_H264_ENCODING(i965) && entrypoint == VAEntrypointEncSliceLP)) {
             va_status = VA_STATUS_SUCCESS;
         } else {
             va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
@@ -778,8 +851,21 @@ i965_validate_config(VADriverContextP ctx, VAProfile profile,
 
         break;
 
+    case VAProfileHEVCMain10:
+        if (HAS_HEVC10_DECODING(i965) && (entrypoint == VAEntrypointVLD))
+            va_status = VA_STATUS_SUCCESS;
+        else
+            va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
+
+        break;
+
     case VAProfileVP9Profile0:
-        if (i965->wrapper_pdrvctx)
+    case VAProfileVP9Profile2:
+        if ((HAS_VP9_DECODING_PROFILE(i965, profile)) && (entrypoint == VAEntrypointVLD))
+            va_status = VA_STATUS_SUCCESS;
+       else if ((HAS_VP9_ENCODING(i965)) && (entrypoint == VAEntrypointEncSlice))
+            va_status = VA_STATUS_SUCCESS;
+        else if ((profile == VAProfileVP9Profile0) && i965->wrapper_pdrvctx)
             va_status = VA_STATUS_SUCCESS;
         else
             va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
@@ -818,7 +904,22 @@ i965_get_default_chroma_formats(VADriverContextP ctx, VAProfile profile,
             chroma_formats |= i965->codec_info->jpeg_dec_chroma_formats;
         if (HAS_JPEG_ENCODING(i965) && entrypoint == VAEntrypointEncPicture)
             chroma_formats |= i965->codec_info->jpeg_enc_chroma_formats;
-        
+        break;
+
+    case VAProfileHEVCMain10:
+        if (HAS_HEVC10_DECODING(i965) && entrypoint == VAEntrypointVLD)
+            chroma_formats |= i965->codec_info->hevc_dec_chroma_formats;
+        break;
+
+    case VAProfileNone:
+       if(HAS_VPP_P010(i965))
+            chroma_formats |= VA_RT_FORMAT_YUV420_10BPP;
+        break;
+
+    case VAProfileVP9Profile0:
+    case VAProfileVP9Profile2:
+        if (HAS_VP9_DECODING_PROFILE(i965, profile) && entrypoint == VAEntrypointVLD)
+            chroma_formats |= i965->codec_info->vp9_dec_chroma_formats;
         break;
 
     default:
@@ -858,12 +959,29 @@ i965_GetConfigAttributes(VADriverContextP ctx,
                 if (profile != VAProfileMPEG2Main &&
                     profile != VAProfileMPEG2Simple)
                     attrib_list[i].value |= VA_RC_CBR;
+
+                if (profile == VAProfileVP9Profile0)
+                    attrib_list[i].value |= VA_RC_VBR;
+
                 break;
-            }
+            } else if (entrypoint == VAEntrypointEncSliceLP) {
+                struct i965_driver_data * const i965 = i965_driver_data(ctx);
+
+                /* Support low power encoding for H.264 only by now */
+                if (profile == VAProfileH264ConstrainedBaseline ||
+                    profile == VAProfileH264Main ||
+                    profile == VAProfileH264High)
+                    attrib_list[i].value = i965->codec_info->lp_h264_brc_mode;
+                else
+                    attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
+            } else
+                attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
+
             break;
 
         case VAConfigAttribEncPackedHeaders:
-            if (entrypoint == VAEntrypointEncSlice) {
+            if (entrypoint == VAEntrypointEncSlice ||
+                entrypoint == VAEntrypointEncSliceLP) {
                 attrib_list[i].value = VA_ENC_PACKED_HEADER_SEQUENCE | VA_ENC_PACKED_HEADER_PICTURE | VA_ENC_PACKED_HEADER_MISC;
                 if (profile == VAProfileH264ConstrainedBaseline ||
                     profile == VAProfileH264Main ||
@@ -874,6 +992,8 @@ i965_GetConfigAttributes(VADriverContextP ctx,
                     attrib_list[i].value |= (VA_ENC_PACKED_HEADER_RAW_DATA |
                                              VA_ENC_PACKED_HEADER_SLICE);
                 }
+                else if (profile == VAProfileVP9Profile0)
+                    attrib_list[i].value = VA_ENC_PACKED_HEADER_RAW_DATA;
                 break;
             }
             else if (entrypoint == VAEntrypointEncPicture) {
@@ -883,14 +1003,23 @@ i965_GetConfigAttributes(VADriverContextP ctx,
             break;
 
         case VAConfigAttribEncMaxRefFrames:
-            if (entrypoint == VAEntrypointEncSlice) {
+            if (entrypoint == VAEntrypointEncSlice)
                 attrib_list[i].value = (1 << 16) | (1 << 0);
-                break;
+            else if (entrypoint == VAEntrypointEncSliceLP) {
+                /* Don't support B frame for low power mode */
+                if (profile == VAProfileH264ConstrainedBaseline ||
+                    profile == VAProfileH264Main ||
+                    profile == VAProfileH264High)
+                    attrib_list[i].value = (1 << 0);
+                else
+                    attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
             }
+
             break;
 
         case VAConfigAttribEncQualityRange:
-            if (entrypoint == VAEntrypointEncSlice) {
+            if (entrypoint == VAEntrypointEncSlice ||
+                entrypoint == VAEntrypointEncSliceLP) {
                 attrib_list[i].value = 1;
                 if (profile == VAProfileH264ConstrainedBaseline ||
                     profile == VAProfileH264Main ||
@@ -918,6 +1047,27 @@ i965_GetConfigAttributes(VADriverContextP ctx,
             attrib_list[i].value = VA_DEC_SLICE_MODE_NORMAL;
             break;
 
+        case VAConfigAttribEncROI:
+            if (profile == VAProfileH264ConstrainedBaseline ||
+                profile == VAProfileH264Main ||
+                profile == VAProfileH264High) {
+                VAConfigAttribValEncROI *roi_config = (VAConfigAttribValEncROI *)&(attrib_list[i].value);
+
+                if(entrypoint == VAEntrypointEncSliceLP) {
+                    roi_config->bits.num_roi_regions = 3;
+                    roi_config->bits.roi_rc_priority_support = 0;
+                    roi_config->bits.roi_rc_qp_delat_support = 0;
+                } else {
+                    roi_config->bits.num_roi_regions = I965_MAX_NUM_ROI_REGIONS;
+                    roi_config->bits.roi_rc_priority_support = 0;
+                    roi_config->bits.roi_rc_qp_delat_support = 1;
+                }
+            }else {
+                attrib_list[i].value = 0;
+            }
+
+            break;
+
         default:
             /* Do nothing */
             attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
@@ -1030,7 +1180,9 @@ i965_CreateConfig(VADriverContextP ctx,
     }
 
     if ((vaStatus == VA_STATUS_SUCCESS) &&
-        (profile == VAProfileVP9Profile0)) {
+        (profile == VAProfileVP9Profile0) &&
+        (entrypoint == VAEntrypointVLD) &&
+        !HAS_VP9_DECODING(i965)) {
 
         if (i965->wrapper_pdrvctx) {
             VAGenericID wrapper_config;
@@ -1181,6 +1333,7 @@ i965_suface_external_memory(VADriverContextP ctx,
 
     switch (obj_surface->fourcc) {
     case VA_FOURCC_NV12:
+    case VA_FOURCC_P010:
         ASSERT_RET(memory_attibute->num_planes == 2, VA_STATUS_ERROR_INVALID_PARAMETER);
         ASSERT_RET(memory_attibute->pitches[0] == memory_attibute->pitches[1], VA_STATUS_ERROR_INVALID_PARAMETER);
 
@@ -1408,6 +1561,7 @@ i965_CreateSurfaces2(
     /* support 420 & 422 & RGB32 format, 422 and RGB32 are only used
      * for post-processing (including color conversion) */
     if (VA_RT_FORMAT_YUV420 != format &&
+        VA_RT_FORMAT_YUV420_10BPP != format &&
         VA_RT_FORMAT_YUV422 != format &&
         VA_RT_FORMAT_YUV444 != format &&
         VA_RT_FORMAT_YUV411 != format &&
@@ -1432,6 +1586,7 @@ i965_CreateSurfaces2(
         obj_surface->user_disable_tiling = false;
         obj_surface->user_h_stride_set = false;
         obj_surface->user_v_stride_set = false;
+        obj_surface->border_cleared = false;
 
         obj_surface->subpic_render_idx = 0;
         for(j = 0; j < I965_MAX_SUBPIC_SUM; j++){
@@ -1472,10 +1627,10 @@ i965_CreateSurfaces2(
                 if (memory_attibute->pitches[0]) {
                     int bpp_1stplane = bpp_1stplane_by_fourcc(expected_fourcc);
                     ASSERT_RET(bpp_1stplane, VA_STATUS_ERROR_INVALID_PARAMETER);
-                    obj_surface->width = memory_attibute->pitches[0]/bpp_1stplane;
+                    obj_surface->width = memory_attibute->pitches[0];
                     obj_surface->user_h_stride_set = true;
                     ASSERT_RET(IS_ALIGNED(obj_surface->width, 16), VA_STATUS_ERROR_INVALID_PARAMETER);
-                    ASSERT_RET(obj_surface->width >= width, VA_STATUS_ERROR_INVALID_PARAMETER);
+                    ASSERT_RET(obj_surface->width >= width * bpp_1stplane, VA_STATUS_ERROR_INVALID_PARAMETER);
 
                     if (memory_attibute->offsets[1]) {
                         ASSERT_RET(!memory_attibute->offsets[0], VA_STATUS_ERROR_INVALID_PARAMETER);
@@ -1916,6 +2071,9 @@ i965_destroy_context(struct object_heap *heap, struct object_base *obj)
         i965_release_buffer_store(&obj_context->codec_state.encode.pic_param);
         i965_release_buffer_store(&obj_context->codec_state.encode.seq_param);
 
+        i965_release_buffer_store(&obj_context->codec_state.encode.q_matrix);
+        i965_release_buffer_store(&obj_context->codec_state.encode.huffman_table);
+
         for (i = 0; i < obj_context->codec_state.encode.num_slice_params; i++)
             i965_release_buffer_store(&obj_context->codec_state.encode.slice_params[i]);
 
@@ -1960,6 +2118,7 @@ i965_destroy_context(struct object_heap *heap, struct object_base *obj)
             i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_data_ext[i]);
         free(obj_context->codec_state.encode.packed_header_data_ext);
 
+        i965_release_buffer_store(&obj_context->codec_state.encode.encmb_map);
     } else {
         assert(obj_context->codec_state.decode.num_slice_params <= obj_context->codec_state.decode.max_slice_params);
         assert(obj_context->codec_state.decode.num_slice_datas <= obj_context->codec_state.decode.max_slice_datas);
@@ -1982,6 +2141,20 @@ i965_destroy_context(struct object_heap *heap, struct object_base *obj)
     object_heap_free(heap, obj);
 }
 
+static inline void
+max_resolution(struct i965_driver_data *i965,
+               struct object_config *obj_config,
+               int *w,                                  /* out */
+               int *h)                                  /* out */
+{
+    if (i965->codec_info->max_resolution) {
+        i965->codec_info->max_resolution(i965, obj_config, w, h);
+    } else {
+        *w = i965->codec_info->max_width;
+        *h = i965->codec_info->max_height;
+    }
+}
+
 VAStatus
 i965_CreateContext(VADriverContextP ctx,
                    VAConfigID config_id,
@@ -1999,14 +2172,18 @@ i965_CreateContext(VADriverContextP ctx,
     VAStatus vaStatus = VA_STATUS_SUCCESS;
     int contextID;
     int i;
+    int max_width;
+    int max_height;
 
     if (NULL == obj_config) {
         vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
         return vaStatus;
     }
 
-    if (picture_width > i965->codec_info->max_width ||
-        picture_height > i965->codec_info->max_height) {
+    max_resolution(i965, obj_config, &max_width, &max_height);
+
+    if (picture_width > max_width ||
+        picture_height > max_height) {
         vaStatus = VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED;
         return vaStatus;
     }
@@ -2053,7 +2230,8 @@ i965_CreateContext(VADriverContextP ctx,
             assert(i965->codec_info->proc_hw_context_init);
             obj_context->hw_context = i965->codec_info->proc_hw_context_init(ctx, obj_config);
          } else if ((VAEntrypointEncSlice == obj_config->entrypoint) || 
-                   (VAEntrypointEncPicture == obj_config->entrypoint)) { /*encode routine only*/
+                    (VAEntrypointEncPicture == obj_config->entrypoint) ||
+                    (VAEntrypointEncSliceLP == obj_config->entrypoint)) {
             VAConfigAttrib *packed_attrib;
             obj_context->codec_type = CODEC_ENC;
             memset(&obj_context->codec_state.encode, 0, sizeof(obj_context->codec_state.encode));
@@ -2084,9 +2262,12 @@ i965_CreateContext(VADriverContextP ctx,
 
             obj_context->codec_state.encode.slice_index = 0;
             packed_attrib = i965_lookup_config_attribute(obj_config, VAConfigAttribEncPackedHeaders);
-            if (packed_attrib)
+            if (packed_attrib) {
                 obj_context->codec_state.encode.packed_header_flag = packed_attrib->value;
-            else {
+                if (obj_config->profile == VAProfileVP9Profile0)
+                    obj_context->codec_state.encode.packed_header_flag =
+                            packed_attrib->value & VA_ENC_PACKED_HEADER_RAW_DATA;
+            } else {
                 /* use the default value. SPS/PPS/RAWDATA is passed from user
                  * while Slice_header data is generated by driver.
                  */
@@ -2094,6 +2275,10 @@ i965_CreateContext(VADriverContextP ctx,
                                VA_ENC_PACKED_HEADER_SEQUENCE |
                                VA_ENC_PACKED_HEADER_PICTURE |
                                VA_ENC_PACKED_HEADER_RAW_DATA;
+
+                /* it is not used for VP9 */
+                if (obj_config->profile == VAProfileVP9Profile0)
+                    obj_context->codec_state.encode.packed_header_flag = 0;
             }
             assert(i965->codec_info->enc_hw_context_init);
             obj_context->hw_context = i965->codec_info->enc_hw_context_init(ctx, obj_config);
@@ -2230,6 +2415,7 @@ i965_create_buffer_internal(VADriverContextP ctx,
     case VAProcFilterParameterBufferType:
     case VAHuffmanTableBufferType:
     case VAProbabilityBufferType:
+    case VAEncMacroblockMapBufferType:
         /* Ok */
         break;
 
@@ -2256,6 +2442,7 @@ i965_create_buffer_internal(VADriverContextP ctx,
     obj_buffer->export_refcount = 0;
     obj_buffer->buffer_store = NULL;
     obj_buffer->wrapper_buffer = VA_INVALID_ID;
+    obj_buffer->context_id = context;
 
     buffer_store = calloc(1, sizeof(struct buffer_store));
     assert(buffer_store);
@@ -2289,6 +2476,7 @@ i965_create_buffer_internal(VADriverContextP ctx,
     } else if (type == VASliceDataBufferType || 
                type == VAImageBufferType || 
                type == VAEncCodedBufferType ||
+               type == VAEncMacroblockMapBufferType ||
                type == VAProbabilityBufferType) {
 
         /* If the buffer is wrapped, the bo/buffer of buffer_store is bogus.
@@ -2320,6 +2508,7 @@ i965_create_buffer_internal(VADriverContextP ctx,
             coded_buffer_segment->base.next = NULL;
             coded_buffer_segment->mapped = 0;
             coded_buffer_segment->codec = 0;
+            coded_buffer_segment->status_support = 0;
             dri_bo_unmap(buffer_store->bo);
           } else if (data) {
               dri_bo_subdata(buffer_store->bo, 0, size * num_elements, data);
@@ -2410,9 +2599,12 @@ i965_MapBuffer(VADriverContextP ctx,
     struct i965_driver_data *i965 = i965_driver_data(ctx);
     struct object_buffer *obj_buffer = BUFFER(buf_id);
     VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
+    struct object_context *obj_context;
 
     ASSERT_RET(obj_buffer && obj_buffer->buffer_store, VA_STATUS_ERROR_INVALID_BUFFER);
 
+    obj_context = CONTEXT(obj_buffer->context_id);
+
     /* When the wrapper_buffer exists, it will wrapper to the
      * buffer allocated from backend driver.
      */
@@ -2443,6 +2635,7 @@ i965_MapBuffer(VADriverContextP ctx,
 
         ASSERT_RET(obj_buffer->buffer_store->bo->virtual, VA_STATUS_ERROR_OPERATION_FAILED);
         *pbuf = obj_buffer->buffer_store->bo->virtual;
+        vaStatus = VA_STATUS_SUCCESS;
 
         if (obj_buffer->type == VAEncCodedBufferType) {
             int i;
@@ -2455,69 +2648,89 @@ i965_MapBuffer(VADriverContextP ctx,
 
                 coded_buffer_segment->base.buf = buffer = (unsigned char *)(obj_buffer->buffer_store->bo->virtual) + I965_CODEDBUFFER_HEADER_SIZE;
 
-                if (coded_buffer_segment->codec == CODEC_H264 ||
-                    coded_buffer_segment->codec == CODEC_H264_MVC) {
-                    delimiter0 = H264_DELIMITER0;
-                    delimiter1 = H264_DELIMITER1;
-                    delimiter2 = H264_DELIMITER2;
-                    delimiter3 = H264_DELIMITER3;
-                    delimiter4 = H264_DELIMITER4;
-                } else if (coded_buffer_segment->codec == CODEC_MPEG2) {
-                    delimiter0 = MPEG2_DELIMITER0;
-                    delimiter1 = MPEG2_DELIMITER1;
-                    delimiter2 = MPEG2_DELIMITER2;
-                    delimiter3 = MPEG2_DELIMITER3;
-                    delimiter4 = MPEG2_DELIMITER4;
-                } else if(coded_buffer_segment->codec == CODEC_JPEG) {
-                    //In JPEG End of Image (EOI = 0xDDF9) marker can be used for delimiter.
-                    delimiter0 = 0xFF;
-                    delimiter1 = 0xD9;
-                } else if (coded_buffer_segment->codec == CODEC_HEVC) {
-                    delimiter0 = HEVC_DELIMITER0;
-                    delimiter1 = HEVC_DELIMITER1;
-                    delimiter2 = HEVC_DELIMITER2;
-                    delimiter3 = HEVC_DELIMITER3;
-                    delimiter4 = HEVC_DELIMITER4;
-                } else if (coded_buffer_segment->codec != CODEC_VP8) {
-                    ASSERT_RET(0, VA_STATUS_ERROR_UNSUPPORTED_PROFILE);
-                }
+                if (obj_context &&
+                    obj_context->hw_context &&
+                    obj_context->hw_context->get_status &&
+                    coded_buffer_segment->status_support) {
+                    vaStatus = obj_context->hw_context->get_status(ctx, obj_context->hw_context, coded_buffer_segment);
+                } else {
 
-                if(coded_buffer_segment->codec == CODEC_JPEG) {
-                    for(i = 0; i <  obj_buffer->size_element - header_offset - 1 - 0x1000; i++) {
-                        if( (buffer[i] == 0xFF) && (buffer[i + 1] == 0xD9)) {
-                            break;
+                    if (coded_buffer_segment->codec == CODEC_VP9) {
+
+                        if (obj_context == NULL)
+                            return VA_STATUS_ERROR_ENCODING_ERROR;
+
+                        gen9_vp9_get_coded_status(ctx, (char *)coded_buffer_segment,
+                                                  obj_context->hw_context);
+                    }
+                    else if (coded_buffer_segment->codec == CODEC_H264 ||
+                        coded_buffer_segment->codec == CODEC_H264_MVC) {
+                        delimiter0 = H264_DELIMITER0;
+                        delimiter1 = H264_DELIMITER1;
+                        delimiter2 = H264_DELIMITER2;
+                        delimiter3 = H264_DELIMITER3;
+                        delimiter4 = H264_DELIMITER4;
+                    } else if (coded_buffer_segment->codec == CODEC_MPEG2) {
+                        delimiter0 = MPEG2_DELIMITER0;
+                        delimiter1 = MPEG2_DELIMITER1;
+                        delimiter2 = MPEG2_DELIMITER2;
+                        delimiter3 = MPEG2_DELIMITER3;
+                        delimiter4 = MPEG2_DELIMITER4;
+                    } else if(coded_buffer_segment->codec == CODEC_JPEG) {
+                        //In JPEG End of Image (EOI = 0xDDF9) marker can be used for delimiter.
+                        delimiter0 = 0xFF;
+                        delimiter1 = 0xD9;
+                    } else if (coded_buffer_segment->codec == CODEC_HEVC) {
+                        delimiter0 = HEVC_DELIMITER0;
+                        delimiter1 = HEVC_DELIMITER1;
+                        delimiter2 = HEVC_DELIMITER2;
+                        delimiter3 = HEVC_DELIMITER3;
+                        delimiter4 = HEVC_DELIMITER4;
+                    } else if (coded_buffer_segment->codec != CODEC_VP8) {
+                        ASSERT_RET(0, VA_STATUS_ERROR_UNSUPPORTED_PROFILE);
+                    }
+
+                    if(coded_buffer_segment->codec == CODEC_VP9) {
+                        /* it is already handled */
+                    } else
+                    if(coded_buffer_segment->codec == CODEC_JPEG) {
+                        for(i = 0; i <  obj_buffer->size_element - header_offset - 1 - 0x1000; i++) {
+                            if( (buffer[i] == 0xFF) && (buffer[i + 1] == 0xD9)) {
+                                break;
+                            }
                         }
-                   }
-                   coded_buffer_segment->base.size = i + 2;
-                } else if (coded_buffer_segment->codec != CODEC_VP8) {
-                    /* vp8 coded buffer size can be told by vp8 internal statistics buffer,
-                       so it don't need to traversal the coded buffer */
-                    for (i = 0; i < obj_buffer->size_element - header_offset - 3 - 0x1000; i++) {
-                        if ((buffer[i] == delimiter0) &&
-                            (buffer[i + 1] == delimiter1) &&
-                            (buffer[i + 2] == delimiter2) &&
-                            (buffer[i + 3] == delimiter3) &&
-                            (buffer[i + 4] == delimiter4))
-                            break;
+                        coded_buffer_segment->base.size = i + 2;
+                    } else if (coded_buffer_segment->codec != CODEC_VP8) {
+                        /* vp8 coded buffer size can be told by vp8 internal statistics buffer,
+                           so it don't need to traversal the coded buffer */
+                        for (i = 0; i < obj_buffer->size_element - header_offset - 3 - 0x1000; i++) {
+                            if ((buffer[i] == delimiter0) &&
+                                (buffer[i + 1] == delimiter1) &&
+                                (buffer[i + 2] == delimiter2) &&
+                                (buffer[i + 3] == delimiter3) &&
+                                (buffer[i + 4] == delimiter4))
+                                break;
+                        }
+
+                        if (i == obj_buffer->size_element - header_offset - 3 - 0x1000) {
+                            coded_buffer_segment->base.status |= VA_CODED_BUF_STATUS_SLICE_OVERFLOW_MASK;
+                        }
+                        coded_buffer_segment->base.size = i;
                     }
 
-                    if (i == obj_buffer->size_element - header_offset - 3 - 0x1000) {
+                    if (coded_buffer_segment->base.size >= obj_buffer->size_element - header_offset - 0x1000) {
                         coded_buffer_segment->base.status |= VA_CODED_BUF_STATUS_SLICE_OVERFLOW_MASK;
                     }
-                    coded_buffer_segment->base.size = i;
-                }
 
-                if (coded_buffer_segment->base.size >= obj_buffer->size_element - header_offset - 0x1000) {
-                    coded_buffer_segment->base.status |= VA_CODED_BUF_STATUS_SLICE_OVERFLOW_MASK;
+                    vaStatus = VA_STATUS_SUCCESS;
                 }
 
                 coded_buffer_segment->mapped = 1;
             } else {
                 assert(coded_buffer_segment->base.buf);
+                vaStatus = VA_STATUS_SUCCESS;
             }
         }
-
-        vaStatus = VA_STATUS_SUCCESS;
     } else if (NULL != obj_buffer->buffer_store->buffer) {
         *pbuf = obj_buffer->buffer_store->buffer;
         vaStatus = VA_STATUS_SUCCESS;
@@ -2654,6 +2867,24 @@ i965_BeginPicture(VADriverContextP ctx,
         obj_context->codec_state.encode.num_packed_header_data_ext = 0;
         obj_context->codec_state.encode.slice_index = 0;
         obj_context->codec_state.encode.vps_sps_seq_index = 0;
+        /*
+        * Based on ROI definition in va/va.h, the ROI set through this
+        * structure is applicable only to the current frame or field.
+        * That is to say: it is on-the-fly setting. If it is not set,
+        * the current frame doesn't use ROI.
+        * It is uncertain whether the other misc buffer should be released.
+        * So only release the previous ROI buffer.
+        */
+        i965_release_buffer_store(&obj_context->codec_state.encode.misc_param[VAEncMiscParameterTypeROI]);
+
+        i965_release_buffer_store(&obj_context->codec_state.encode.encmb_map);
+
+        if (obj_config->profile == VAProfileVP9Profile0) {
+            for (i = 0; i < ARRAY_ELEMS(obj_context->codec_state.encode.misc_param); i++)
+                i965_release_buffer_store(&obj_context->codec_state.encode.misc_param[i]);
+
+            i965_release_buffer_store(&obj_context->codec_state.encode.seq_param_ext);
+        }
     } else {
         obj_context->codec_state.decode.current_render_target = render_target;
         i965_release_buffer_store(&obj_context->codec_state.decode.pic_param);
@@ -2813,6 +3044,9 @@ i965_decoder_wrapper_picture(VADriverContextP ctx,
     VADriverContextP pdrvctx;
     struct object_buffer *obj_buffer;
 
+    if (obj_context == NULL)
+        return VA_STATUS_ERROR_INVALID_CONTEXT;
+
     /* When it is not wrapped context, continue the normal flowchart */
     if (obj_context->wrapper_context == VA_INVALID_ID)
         return vaStatus;
@@ -2916,6 +3150,7 @@ DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(huffman_table, huffman_table)
 /* extended buffer */
 DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(sequence_parameter_ext, seq_param_ext)
 DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(picture_parameter_ext, pic_param_ext)
+DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(encmb_map, encmb_map)
 
 #define DEF_RENDER_ENCODE_MULTI_BUFFER_FUNC(name, member) DEF_RENDER_MULTI_BUFFER_FUNC(encode, name, member)
 // DEF_RENDER_ENCODE_MULTI_BUFFER_FUNC(slice_parameter, slice_params)
@@ -3067,7 +3302,7 @@ i965_encoder_render_picture(VADriverContextP ctx,
             if ((param->type == VAEncPackedHeaderRawData) ||
                 (param->type == VAEncPackedHeaderSlice)) {
                 vaStatus = I965_RENDER_ENCODE_BUFFER(packed_header_params_ext);
-            } else if((obj_config->profile == VAProfileHEVCMain)&&
+            } else if((obj_config->profile == VAProfileHEVCMain) &&
                 (encode->last_packed_header_type == VAEncPackedHeaderSequence)) {
                 vaStatus = i965_encoder_render_packed_header_parameter_buffer(ctx,
                                                                           obj_context,
@@ -3089,10 +3324,14 @@ i965_encoder_render_picture(VADriverContextP ctx,
                 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
                 return vaStatus;
             }
+
             if (encode->last_packed_header_type == VAEncPackedHeaderRawData ||
                 encode->last_packed_header_type == VAEncPackedHeaderSlice) {
                 vaStatus = I965_RENDER_ENCODE_BUFFER(packed_header_data_ext);
 
+                if (obj_config->profile == VAProfileVP9Profile0)
+                    break;
+
                 /* When the PACKED_SLICE_HEADER flag is passed, it will use
                  * the packed_slice_header as the delimeter to decide how
                  * the packed rawdata is inserted for the given slice.
@@ -3161,7 +3400,7 @@ i965_encoder_render_picture(VADriverContextP ctx,
                     ((encode->last_packed_header_type & (~VAEncPackedHeaderMiscMask)) != 0)),
                     VA_STATUS_ERROR_ENCODING_ERROR);
 
-                if((obj_config->profile == VAProfileHEVCMain)&&
+                if((obj_config->profile == VAProfileHEVCMain) &&
                     (encode->last_packed_header_type == VAEncPackedHeaderSequence)) {
 
                         vaStatus = i965_encoder_render_packed_header_data_buffer(ctx,
@@ -3187,6 +3426,10 @@ i965_encoder_render_picture(VADriverContextP ctx,
                                                                  obj_buffer);
             break;
             
+        case VAEncMacroblockMapBufferType:
+            vaStatus = I965_RENDER_ENCODE_BUFFER(encmb_map);
+            break;
+
         default:
             vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
             break;
@@ -3257,7 +3500,8 @@ i965_RenderPicture(VADriverContextP ctx,
     if (VAEntrypointVideoProc == obj_config->entrypoint) {
         vaStatus = i965_proc_render_picture(ctx, context, buffers, num_buffers);
     } else if ((VAEntrypointEncSlice == obj_config->entrypoint ) || 
-               (VAEntrypointEncPicture == obj_config->entrypoint)) {
+               (VAEntrypointEncPicture == obj_config->entrypoint) ||
+               (VAEntrypointEncSliceLP == obj_config->entrypoint)) {
         vaStatus = i965_encoder_render_picture(ctx, context, buffers, num_buffers);
     } else {
         vaStatus = i965_decoder_render_picture(ctx, context, buffers, num_buffers);
@@ -3280,7 +3524,10 @@ i965_EndPicture(VADriverContextP ctx, VAContextID context)
     if (obj_context->codec_type == CODEC_PROC) {
         ASSERT_RET(VAEntrypointVideoProc == obj_config->entrypoint, VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT);
     } else if (obj_context->codec_type == CODEC_ENC) {
-        ASSERT_RET(((VAEntrypointEncSlice == obj_config->entrypoint) || (VAEntrypointEncPicture == obj_config->entrypoint)), VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT);
+        ASSERT_RET(((VAEntrypointEncSlice == obj_config->entrypoint) ||
+                    (VAEntrypointEncPicture == obj_config->entrypoint) ||
+                    (VAEntrypointEncSliceLP == obj_config->entrypoint)),
+                   VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT);
 
         if (obj_context->codec_state.encode.num_packed_header_params_ext !=
                obj_context->codec_state.encode.num_packed_header_data_ext) {
@@ -3294,11 +3541,14 @@ i965_EndPicture(VADriverContextP ctx, VAContextID context)
         if (!(obj_context->codec_state.encode.seq_param ||
                 obj_context->codec_state.encode.seq_param_ext) &&
                 (VAEntrypointEncPicture != obj_config->entrypoint)) {
-            return VA_STATUS_ERROR_INVALID_PARAMETER;
+            /* The seq_param is not mandatory for VP9 encoding */
+            if (obj_config->profile != VAProfileVP9Profile0)
+                return VA_STATUS_ERROR_INVALID_PARAMETER;
         }
         if ((obj_context->codec_state.encode.num_slice_params <=0) &&
                 (obj_context->codec_state.encode.num_slice_params_ext <=0) &&
-                (obj_config->profile != VAProfileVP8Version0_3)) {
+                ((obj_config->profile != VAProfileVP8Version0_3) &&
+                 (obj_config->profile != VAProfileVP9Profile0))) {
             return VA_STATUS_ERROR_INVALID_PARAMETER;
         }
 
@@ -3697,6 +3947,14 @@ i965_CreateImage(VADriverContextP ctx,
         image->offsets[0] = 0;
         image->data_size  = size * 2;
         break;
+    case VA_FOURCC_P010:
+        image->num_planes = 2;
+        image->pitches[0] = awidth * 2;
+        image->offsets[0] = 0;
+        image->pitches[1] = awidth * 2;
+        image->offsets[1] = size * 2;
+        image->data_size  = size * 2 + 2 * size2 * 2;
+        break;
     default:
         goto error;
     }
@@ -3755,25 +4013,29 @@ i965_check_alloc_surface_bo(VADriverContextP ctx,
     obj_surface->x_cb_offset = 0; /* X offset is always 0 */
     obj_surface->x_cr_offset = 0;
 
+    int bpp_1stplane = bpp_1stplane_by_fourcc(fourcc);
+
     if ((tiled && !obj_surface->user_disable_tiling)) {
         ASSERT_RET(fourcc != VA_FOURCC_I420 &&
                fourcc != VA_FOURCC_IYUV &&
                fourcc != VA_FOURCC_YV12,
                VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT);
+
         if (obj_surface->user_h_stride_set) {
-            ASSERT_RET(IS_ALIGNED(obj_surface->width, 128), VA_STATUS_ERROR_INVALID_PARAMETER);
+           ASSERT_RET(IS_ALIGNED(obj_surface->width, 128), VA_STATUS_ERROR_INVALID_PARAMETER);
         } else
-            obj_surface->width = ALIGN(obj_surface->orig_width, 128);
+          obj_surface->width = ALIGN(obj_surface->orig_width * bpp_1stplane, 128);
 
         if (obj_surface->user_v_stride_set) {
-            ASSERT_RET(IS_ALIGNED(obj_surface->height, 32), VA_STATUS_ERROR_INVALID_PARAMETER);
-        } else
-            obj_surface->height = ALIGN(obj_surface->orig_height, 32);
+          ASSERT_RET(IS_ALIGNED(obj_surface->height, 32), VA_STATUS_ERROR_INVALID_PARAMETER);
+        }else
+          obj_surface->height = ALIGN(obj_surface->orig_height, 32);
 
         region_height = obj_surface->height;
 
         switch (fourcc) {
         case VA_FOURCC_NV12:
+        case VA_FOURCC_P010:
             assert(subsampling == SUBSAMPLE_YUV420);
             obj_surface->cb_cr_pitch = obj_surface->width;
             obj_surface->cb_cr_width = obj_surface->orig_width / 2;
@@ -3877,7 +4139,7 @@ i965_check_alloc_surface_bo(VADriverContextP ctx,
             obj_surface->y_cb_offset = 0; 
             obj_surface->y_cr_offset = 0; 
             obj_surface->cb_cr_width = obj_surface->orig_width / 2;
-            obj_surface->cb_cr_height = obj_surface->orig_height / 2;
+            obj_surface->cb_cr_height = obj_surface->orig_height;
             region_width = obj_surface->width;
             region_height = obj_surface->height;
             
@@ -3910,6 +4172,7 @@ i965_check_alloc_surface_bo(VADriverContextP ctx,
 
         switch (fourcc) {
         case VA_FOURCC_NV12:
+        case VA_FOURCC_P010:
             obj_surface->y_cb_offset = obj_surface->height;
             obj_surface->y_cr_offset = obj_surface->height;
             obj_surface->cb_cr_width = obj_surface->orig_width / 2;
@@ -3920,10 +4183,12 @@ i965_check_alloc_surface_bo(VADriverContextP ctx,
 
         case VA_FOURCC_YV16:
             obj_surface->cb_cr_width = obj_surface->orig_width / 2;
+            obj_surface->width = ALIGN(obj_surface->cb_cr_width, i965->codec_info->min_linear_wpitch) * 2;
             obj_surface->cb_cr_height = obj_surface->orig_height;
             obj_surface->y_cr_offset = obj_surface->height;
             obj_surface->y_cb_offset = obj_surface->y_cr_offset + ALIGN(obj_surface->cb_cr_height, 32) / 2;
             obj_surface->cb_cr_pitch = obj_surface->width / 2;
+            region_width = obj_surface->width;
             region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32);
             break;
 
@@ -3938,8 +4203,10 @@ i965_check_alloc_surface_bo(VADriverContextP ctx,
             }
 
             obj_surface->cb_cr_width = obj_surface->orig_width / 2;
+            obj_surface->width = ALIGN(obj_surface->cb_cr_width, i965->codec_info->min_linear_wpitch) * 2;
             obj_surface->cb_cr_height = obj_surface->orig_height / 2;
             obj_surface->cb_cr_pitch = obj_surface->width / 2;
+            region_width = obj_surface->width;
             region_height = obj_surface->height + obj_surface->height / 2;
             break;
 
@@ -4057,7 +4324,10 @@ VAStatus i965_DeriveImage(VADriverContextP ctx,
 
     image->format.fourcc = obj_surface->fourcc;
     image->format.byte_order = VA_LSB_FIRST;
-    image->format.bits_per_pixel = 12;
+    image->format.bits_per_pixel = get_bpp_from_fourcc(obj_surface->fourcc);
+
+    if (!image->format.bits_per_pixel)
+        goto error;
 
     switch (image->format.fourcc) {
     case VA_FOURCC_YV12:
@@ -4081,6 +4351,7 @@ VAStatus i965_DeriveImage(VADriverContextP ctx,
         break;
 
     case VA_FOURCC_NV12:
+    case VA_FOURCC_P010:
         image->num_planes = 2;
         image->pitches[0] = w_pitch; /* Y */
         image->offsets[0] = 0;
@@ -4116,6 +4387,39 @@ VAStatus i965_DeriveImage(VADriverContextP ctx,
     case VA_FOURCC_BGRX:
         image->num_planes = 1;
         image->pitches[0] = obj_surface->width;
+
+        switch (image->format.fourcc) {
+        case VA_FOURCC_RGBA:
+        case VA_FOURCC_RGBX:
+            image->format.red_mask = 0x000000ff;
+            image->format.green_mask = 0x0000ff00;
+            image->format.blue_mask = 0x00ff0000;
+            break;
+        case VA_FOURCC_BGRA:
+        case VA_FOURCC_BGRX:
+            image->format.red_mask = 0x00ff0000;
+            image->format.green_mask = 0x0000ff00;
+            image->format.blue_mask = 0x000000ff;
+            break;
+        default:
+            goto error;
+        }
+
+        switch (image->format.fourcc) {
+        case VA_FOURCC_RGBA:
+        case VA_FOURCC_BGRA:
+            image->format.alpha_mask = 0xff000000;
+            image->format.depth = 32;
+            break;
+        case VA_FOURCC_RGBX:
+        case VA_FOURCC_BGRX:
+            image->format.alpha_mask = 0x00000000;
+            image->format.depth = 24;
+            break;
+        default:
+            goto error;
+        }
+
         break;
     default:
         goto error;
@@ -5164,7 +5468,8 @@ i965_GetSurfaceAttributes(
                            IS_GEN8(i965->intel.device_info) ||
                            IS_GEN9(i965->intel.device_info)) {
                     if (obj_config->entrypoint == VAEntrypointEncSlice ||
-                        obj_config->entrypoint == VAEntrypointVideoProc) {
+                        obj_config->entrypoint == VAEntrypointVideoProc ||
+                        obj_config->entrypoint == VAEntrypointEncSliceLP) {
                         switch (attrib_list[i].value.value.i) {
                         case VA_FOURCC_NV12:
                         case VA_FOURCC_I420:
@@ -5223,7 +5528,9 @@ i965_QuerySurfaceAttributes(VADriverContextP ctx,
     struct object_config *obj_config;
     int i = 0;
     VASurfaceAttrib *attribs = NULL;
-    
+    int max_width;
+    int max_height;
+
     if (config == VA_INVALID_ID)
         return VA_STATUS_ERROR_INVALID_CONFIG;
 
@@ -5384,7 +5691,13 @@ i965_QuerySurfaceAttributes(VADriverContextP ctx,
                 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
                 attribs[i].value.value.i = VA_FOURCC_444P;
                 i++;
-            } else {
+            } else if (obj_config->profile == VAProfileHEVCMain10) {
+                attribs[i].type = VASurfaceAttribPixelFormat;
+                attribs[i].value.type = VAGenericValueTypeInteger;
+                attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
+                attribs[i].value.value.i = VA_FOURCC_P010;
+                i++;
+             } else {
                 attribs[i].type = VASurfaceAttribPixelFormat;
                 attribs[i].value.type = VAGenericValueTypeInteger;
                 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
@@ -5506,33 +5819,51 @@ i965_QuerySurfaceAttributes(VADriverContextP ctx,
                 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
                 attribs[i].value.value.i = VA_FOURCC_NV12;
                 i++;
+
+                if ((obj_config->profile == VAProfileHEVCMain10) ||
+                    (obj_config->profile == VAProfileVP9Profile2)) {
+                    attribs[i].type = VASurfaceAttribPixelFormat;
+                    attribs[i].value.type = VAGenericValueTypeInteger;
+                    attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
+                    attribs[i].value.value.i = VA_FOURCC_P010;
+                    i++;
+                }
             }
         } else if (obj_config->entrypoint == VAEntrypointEncSlice ||  /* encode */
-                   obj_config->entrypoint == VAEntrypointVideoProc) { /* vpp */
-
-            attribs[i].type = VASurfaceAttribPixelFormat;
-            attribs[i].value.type = VAGenericValueTypeInteger;
-            attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
-            attribs[i].value.value.i = VA_FOURCC_NV12;
-            i++;
-
-            attribs[i].type = VASurfaceAttribPixelFormat;
-            attribs[i].value.type = VAGenericValueTypeInteger;
-            attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
-            attribs[i].value.value.i = VA_FOURCC_I420;
-            i++;
+                   obj_config->entrypoint == VAEntrypointVideoProc ||
+                   obj_config->entrypoint == VAEntrypointEncSliceLP) {
 
-            attribs[i].type = VASurfaceAttribPixelFormat;
-            attribs[i].value.type = VAGenericValueTypeInteger;
-            attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
-            attribs[i].value.value.i = VA_FOURCC_YV12;
-            i++;
-
-            attribs[i].type = VASurfaceAttribPixelFormat;
-            attribs[i].value.type = VAGenericValueTypeInteger;
-            attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
-            attribs[i].value.value.i = VA_FOURCC_IMC3;
-            i++;
+            if (obj_config->profile == VAProfileHEVCMain10) {
+                attribs[i].type = VASurfaceAttribPixelFormat;
+                attribs[i].value.type = VAGenericValueTypeInteger;
+                attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
+                attribs[i].value.value.i = VA_FOURCC_P010;
+                i++;
+            } else {
+              attribs[i].type = VASurfaceAttribPixelFormat;
+              attribs[i].value.type = VAGenericValueTypeInteger;
+              attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
+              attribs[i].value.value.i = VA_FOURCC_NV12;
+              i++;
+
+              attribs[i].type = VASurfaceAttribPixelFormat;
+              attribs[i].value.type = VAGenericValueTypeInteger;
+              attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
+              attribs[i].value.value.i = VA_FOURCC_I420;
+              i++;
+
+              attribs[i].type = VASurfaceAttribPixelFormat;
+              attribs[i].value.type = VAGenericValueTypeInteger;
+              attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
+              attribs[i].value.value.i = VA_FOURCC_YV12;
+              i++;
+
+              attribs[i].type = VASurfaceAttribPixelFormat;
+              attribs[i].value.type = VAGenericValueTypeInteger;
+              attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
+              attribs[i].value.value.i = VA_FOURCC_IMC3;
+              i++;
+            }
 
             if (obj_config->entrypoint == VAEntrypointVideoProc) {
                 attribs[i].type = VASurfaceAttribPixelFormat;
@@ -5570,6 +5901,14 @@ i965_QuerySurfaceAttributes(VADriverContextP ctx,
                 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
                 attribs[i].value.value.i = VA_FOURCC_YV16;
                 i++;
+
+                if(HAS_VPP_P010(i965)) {
+                  attribs[i].type = VASurfaceAttribPixelFormat;
+                  attribs[i].value.type = VAGenericValueTypeInteger;
+                  attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
+                  attribs[i].value.value.i = VA_FOURCC_P010;
+                  i++;
+                }
             }
         }
     }
@@ -5588,16 +5927,18 @@ i965_QuerySurfaceAttributes(VADriverContextP ctx,
     attribs[i].value.value.p = NULL; /* ignore */
     i++;
 
+    max_resolution(i965, obj_config, &max_width, &max_height);
+
     attribs[i].type = VASurfaceAttribMaxWidth;
     attribs[i].value.type = VAGenericValueTypeInteger;
     attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE;
-    attribs[i].value.value.i = i965->codec_info->max_width;
+    attribs[i].value.value.i = max_width;
     i++;
 
     attribs[i].type = VASurfaceAttribMaxHeight;
     attribs[i].value.type = VAGenericValueTypeInteger;
     attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE;
-    attribs[i].value.value.i = i965->codec_info->max_height;
+    attribs[i].value.value.i = max_height;
     i++;
 
     if (i > *num_attribs) {
@@ -6196,6 +6537,11 @@ i965_initialize_wrapper(VADriverContextP ctx, const char *driver_name)
     VAStatus va_status = VA_STATUS_SUCCESS;
     bool driver_loaded = false;
 
+    if (HAS_VP9_DECODING(i965)) {
+        i965->wrapper_pdrvctx = NULL;
+        return va_status;
+    }
+
     wrapper_pdrvctx = calloc(1, sizeof(*wrapper_pdrvctx));
     vtable = calloc(1, sizeof(*vtable));