#include "sysdeps.h"
#include <unistd.h>
#include <dlfcn.h>
+#include <drm_fourcc.h>
#ifdef HAVE_VA_X11
# include "i965_output_dri.h"
if (HAS_H264_DECODING(i965) ||
HAS_H264_ENCODING(i965) ||
- HAS_LP_H264_ENCODING(i965)) {
+ HAS_LP_H264_ENCODING(i965) ||
+ HAS_FEI_H264_ENCODING(i965) ||
+ HAS_H264_PREENC(i965)) {
profile_list[i++] = VAProfileH264ConstrainedBaseline;
profile_list[i++] = VAProfileH264Main;
profile_list[i++] = VAProfileH264High;
}
if (HAS_VP9_DECODING_PROFILE(i965, VAProfileVP9Profile0) ||
- HAS_VP9_ENCODING(i965)) {
+ HAS_VP9_ENCODING(i965) ||
+ HAS_LP_VP9_ENCODING(i965)) {
profile_list[i++] = VAProfileVP9Profile0;
}
if (HAS_LP_H264_ENCODING(i965))
entrypoint_list[n++] = VAEntrypointEncSliceLP;
+ if (HAS_FEI_H264_ENCODING(i965))
+ entrypoint_list[n++] = VAEntrypointFEI;
+
+ if (HAS_H264_PREENC(i965))
+ entrypoint_list[n++] = VAEntrypointStats;
break;
+
case VAProfileH264MultiviewHigh:
case VAProfileH264StereoHigh:
if (HAS_H264_MVC_DECODING_PROFILE(i965, profile))
if (HAS_VP9_ENCODING(i965) && (profile == VAProfileVP9Profile0))
entrypoint_list[n++] = VAEntrypointEncSlice;
+ if (HAS_LP_VP9_ENCODING(i965) && (profile == VAProfileVP9Profile0))
+ entrypoint_list[n++] = VAEntrypointEncSliceLP;
+
if (profile == VAProfileVP9Profile0) {
if (i965->wrapper_pdrvctx) {
VAStatus va_status = VA_STATUS_SUCCESS;
case VAProfileH264High:
if ((HAS_H264_DECODING(i965) && entrypoint == VAEntrypointVLD) ||
(HAS_H264_ENCODING(i965) && entrypoint == VAEntrypointEncSlice) ||
- (HAS_LP_H264_ENCODING(i965) && entrypoint == VAEntrypointEncSliceLP)) {
+ (HAS_LP_H264_ENCODING(i965) && entrypoint == VAEntrypointEncSliceLP) ||
+ (HAS_FEI_H264_ENCODING(i965) && entrypoint == VAEntrypointFEI) ||
+ (HAS_H264_PREENC(i965) && entrypoint == VAEntrypointStats)) {
va_status = VA_STATUS_SUCCESS;
} else if (!HAS_H264_DECODING(i965) && !HAS_H264_ENCODING(i965) &&
- !HAS_LP_H264_ENCODING(i965)) {
+ !HAS_LP_H264_ENCODING(i965) && !HAS_FEI_H264_ENCODING(i965) &&
+ !HAS_H264_PREENC(i965)) {
va_status = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
} else {
va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
} else if ((HAS_VP9_ENCODING_PROFILE(i965, profile)) &&
(entrypoint == VAEntrypointEncSlice)) {
va_status = VA_STATUS_SUCCESS;
+ } else if ((HAS_LP_VP9_ENCODING(i965) &&
+ profile == VAProfileVP9Profile0 &&
+ entrypoint == VAEntrypointEncSliceLP)) {
+ va_status = VA_STATUS_SUCCESS;
} else if (profile == VAProfileVP9Profile0 &&
entrypoint == VAEntrypointVLD &&
i965->wrapper_pdrvctx) {
va_status = VA_STATUS_SUCCESS;
} else if (!HAS_VP9_DECODING_PROFILE(i965, profile) &&
- !HAS_VP9_ENCODING(i965) && !i965->wrapper_pdrvctx) {
+ !HAS_VP9_ENCODING(i965) &&
+ !HAS_LP_VP9_ENCODING(i965) &&
+ !i965->wrapper_pdrvctx) {
va_status = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
} else {
va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
return chroma_formats;
}
+static uint32_t
+i965_get_rc_attributes(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoint)
+{
+ struct i965_driver_data * const i965 = i965_driver_data(ctx);
+
+ uint32_t rc_attribs = VA_ATTRIB_NOT_SUPPORTED;
+
+ if (entrypoint == VAEntrypointEncSlice) {
+
+ rc_attribs = VA_RC_CQP;
+
+ if (profile != VAProfileMPEG2Main &&
+ profile != VAProfileMPEG2Simple)
+ rc_attribs |= VA_RC_CBR;
+
+ if (profile == VAProfileVP8Version0_3 ||
+ profile == VAProfileHEVCMain ||
+ profile == VAProfileHEVCMain10)
+ rc_attribs |= VA_RC_VBR;
+
+ if (profile == VAProfileVP9Profile0)
+ rc_attribs = i965->codec_info->vp9_brc_mode;
+
+ if (profile == VAProfileH264ConstrainedBaseline ||
+ profile == VAProfileH264Main ||
+ profile == VAProfileH264High ||
+ profile == VAProfileH264MultiviewHigh ||
+ profile == VAProfileH264StereoHigh)
+ rc_attribs = i965->codec_info->h264_brc_mode;
+
+ } else if (entrypoint == VAEntrypointEncSliceLP) {
+
+ if (profile == VAProfileH264ConstrainedBaseline ||
+ profile == VAProfileH264Main ||
+ profile == VAProfileH264High ||
+ profile == VAProfileH264MultiviewHigh ||
+ profile == VAProfileH264StereoHigh)
+ rc_attribs = i965->codec_info->lp_h264_brc_mode;
+
+ else if (profile == VAProfileVP9Profile0)
+ rc_attribs = i965->codec_info->lp_vp9_brc_mode;
+
+ } else if (entrypoint == VAEntrypointFEI) {
+
+ if (profile == VAProfileH264ConstrainedBaseline ||
+ profile == VAProfileH264Main ||
+ profile == VAProfileH264High)
+ rc_attribs = VA_RC_CQP;
+
+ } else if (entrypoint == VAEntrypointEncPicture) {
+ if (profile == VAProfileJPEGBaseline)
+ rc_attribs = VA_RC_CQP;
+ }
+
+ return rc_attribs;
+}
+
+static uint32_t
+i965_get_enc_packed_attributes(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoint)
+{
+ uint32_t enc_packed_attribs = VA_ATTRIB_NOT_SUPPORTED;
+
+ if (entrypoint == VAEntrypointEncSlice ||
+ entrypoint == VAEntrypointEncSliceLP ||
+ entrypoint == VAEntrypointFEI) {
+
+ switch (profile) {
+ case VAProfileMPEG2Simple:
+ case VAProfileMPEG2Main:
+ enc_packed_attribs = VA_ENC_PACKED_HEADER_SEQUENCE | VA_ENC_PACKED_HEADER_PICTURE | VA_ENC_PACKED_HEADER_MISC;
+ break;
+
+ case VAProfileH264ConstrainedBaseline:
+ case VAProfileH264Main:
+ case VAProfileH264High:
+ case VAProfileH264StereoHigh:
+ case VAProfileH264MultiviewHigh:
+ case VAProfileHEVCMain:
+ case VAProfileHEVCMain10:
+ enc_packed_attribs = VA_ENC_PACKED_HEADER_SEQUENCE | VA_ENC_PACKED_HEADER_PICTURE | VA_ENC_PACKED_HEADER_MISC;
+ enc_packed_attribs |= (VA_ENC_PACKED_HEADER_RAW_DATA | VA_ENC_PACKED_HEADER_SLICE);
+ break;
+
+ case VAProfileVP9Profile0:
+ enc_packed_attribs = VA_ENC_PACKED_HEADER_RAW_DATA;
+ break;
+
+ default:
+ break;
+ }
+
+ } else if (entrypoint == VAEntrypointEncPicture) {
+ if (profile == VAProfileJPEGBaseline)
+ enc_packed_attribs = VA_ENC_PACKED_HEADER_RAW_DATA;
+ }
+
+ return enc_packed_attribs;
+}
+
VAStatus
i965_GetConfigAttributes(VADriverContextP ctx,
VAProfile profile,
break;
case VAConfigAttribRateControl:
- if (entrypoint == VAEntrypointEncSlice) {
- attrib_list[i].value = VA_RC_CQP;
-
- if (profile != VAProfileMPEG2Main &&
- profile != VAProfileMPEG2Simple)
- attrib_list[i].value |= VA_RC_CBR;
-
- if (profile == VAProfileVP9Profile0 ||
- profile == VAProfileH264ConstrainedBaseline ||
- profile == VAProfileH264Main ||
- profile == VAProfileH264High ||
- profile == VAProfileHEVCMain)
- attrib_list[i].value |= VA_RC_VBR;
+ attrib_list[i].value = i965_get_rc_attributes(ctx, profile, entrypoint);
- break;
- } else if (entrypoint == VAEntrypointEncSliceLP) {
- struct i965_driver_data * const i965 = i965_driver_data(ctx);
+ break;
- /* 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;
+ case VAConfigAttribEncPackedHeaders:
+ attrib_list[i].value = i965_get_enc_packed_attributes(ctx, profile, entrypoint);
break;
- case VAConfigAttribEncPackedHeaders:
- if (entrypoint == VAEntrypointEncSlice ||
- entrypoint == VAEntrypointEncSliceLP) {
- attrib_list[i].value = VA_ENC_PACKED_HEADER_SEQUENCE | VA_ENC_PACKED_HEADER_PICTURE | VA_ENC_PACKED_HEADER_MISC;
+ case VAConfigAttribEncMaxRefFrames:
+ if (entrypoint == VAEntrypointEncSlice || entrypoint == VAEntrypointFEI) {
+ attrib_list[i].value = (1 << 16) | (1 << 0);
if (profile == VAProfileH264ConstrainedBaseline ||
profile == VAProfileH264Main ||
profile == VAProfileH264High ||
profile == VAProfileH264StereoHigh ||
- profile == VAProfileH264MultiviewHigh ||
- profile == VAProfileHEVCMain ||
- profile == VAProfileHEVCMain10) {
- 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) {
- if (profile == VAProfileJPEGBaseline)
- attrib_list[i].value = VA_ENC_PACKED_HEADER_RAW_DATA;
- }
- break;
-
- case VAConfigAttribEncMaxRefFrames:
- if (entrypoint == VAEntrypointEncSlice)
- attrib_list[i].value = (1 << 16) | (1 << 0);
- else if (entrypoint == VAEntrypointEncSliceLP) {
+ profile == VAProfileH264MultiviewHigh) {
+ if (IS_GEN8(i965->intel.device_info) ||
+ IS_GEN9(i965->intel.device_info))
+ attrib_list[i].value = (1 << 16) | (4 << 0);
+ } else if (profile == VAProfileHEVCMain ||
+ profile == VAProfileHEVCMain10) {
+ if (IS_GEN9(i965->intel.device_info))
+ attrib_list[i].value = (1 << 16) | (3 << 0);
+ else if (IS_GEN10(i965->intel.device_info))
+ attrib_list[i].value = (1 << 16) | (3 << 0);
+ }
+ } else if (entrypoint == VAEntrypointEncSliceLP) {
/* Don't support B frame for low power mode */
if (profile == VAProfileH264ConstrainedBaseline ||
profile == VAProfileH264Main ||
attrib_list[i].value = (1 << 0);
else
attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
- }
+ } else if (entrypoint == VAEntrypointStats)
+ attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
break;
case VAConfigAttribEncQualityRange:
if (entrypoint == VAEntrypointEncSlice ||
- entrypoint == VAEntrypointEncSliceLP) {
+ entrypoint == VAEntrypointEncSliceLP ||
+ entrypoint == VAEntrypointFEI) {
attrib_list[i].value = 1;
if (profile == VAProfileH264ConstrainedBaseline ||
profile == VAProfileH264Main ||
profile == VAProfileH264High) {
attrib_list[i].value = ENCODER_QUALITY_RANGE;
if (entrypoint == VAEntrypointEncSlice) {
- if (IS_GEN9(i965->intel.device_info))
+ if (IS_GEN9(i965->intel.device_info) ||
+ IS_GEN10(i965->intel.device_info))
attrib_list[i].value = ENCODER_QUALITY_RANGE_AVC;
}
} else if (profile == VAProfileHEVCMain ||
profile == VAProfileHEVCMain10)
attrib_list[i].value = ENCODER_QUALITY_RANGE_HEVC;
+ else if (profile == VAProfileVP9Profile0 &&
+ entrypoint == VAEntrypointEncSliceLP) {
+ attrib_list[i].value = ENCODER_QUALITY_RANGE_VP9;
+ }
+
break;
- }
+ } else if (entrypoint == VAEntrypointStats)
+ attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
break;
case VAConfigAttribEncJPEG:
break;
case VAConfigAttribDecSliceMode:
- attrib_list[i].value = VA_DEC_SLICE_MODE_NORMAL;
+ if (entrypoint == VAEntrypointVLD)
+ attrib_list[i].value = VA_DEC_SLICE_MODE_NORMAL;
break;
case VAConfigAttribEncROI:
if (entrypoint == VAEntrypointEncSlice ||
- entrypoint == VAEntrypointEncSliceLP) {
+ entrypoint == VAEntrypointEncSliceLP ||
+ entrypoint == VAEntrypointFEI) {
+ VAConfigAttribValEncROI *roi_config =
+ (VAConfigAttribValEncROI *) & (attrib_list[i].value);
if (profile == VAProfileH264ConstrainedBaseline ||
profile == VAProfileH264Main ||
profile == VAProfileH264High) {
if (IS_GEN9(i965->intel.device_info) &&
- entrypoint == VAEntrypointEncSlice)
+ (entrypoint == VAEntrypointEncSlice ||
+ entrypoint == VAEntrypointFEI ||
+ entrypoint == VAEntrypointStats))
+ attrib_list[i].value = 0;
+ else if (IS_GEN10(i965->intel.device_info) &&
+ (entrypoint == VAEntrypointEncSlice || entrypoint == VAEntrypointFEI))
attrib_list[i].value = 0;
else {
-
- 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;
+ roi_config->bits.roi_rc_qp_delta_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;
+ roi_config->bits.roi_rc_qp_delta_support = 1;
}
}
+ } else if (profile == VAProfileHEVCMain ||
+ profile == VAProfileHEVCMain10) {
+ roi_config->bits.num_roi_regions =
+ I965_MAX_NUM_ROI_REGIONS;
+ roi_config->bits.roi_rc_priority_support = 1;
+ roi_config->bits.roi_rc_qp_delta_support = 1;
} else {
attrib_list[i].value = 0;
}
entrypoint == VAEntrypointEncSlice) {
if (IS_GEN9(i965->intel.device_info))
attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
+ else if (IS_GEN10(i965->intel.device_info))
+ attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
else {
VAConfigAttribValEncRateControlExt *val_config = (VAConfigAttribValEncRateControlExt *) & (attrib_list[i].value);
break;
case VAConfigAttribEncMaxSlices:
+ attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
if (entrypoint == VAEntrypointEncSlice) {
if ((profile == VAProfileH264ConstrainedBaseline ||
profile == VAProfileH264Main ||
profile == VAProfileH264High) ||
profile == VAProfileH264StereoHigh ||
profile == VAProfileH264MultiviewHigh) {
- if (IS_GEN9(i965->intel.device_info))
- attrib_list[i].value = 1;
- else
- attrib_list[i].value = I965_MAX_NUM_SLICE;
+ attrib_list[i].value = I965_MAX_NUM_SLICE;
} else if (profile == VAProfileHEVCMain ||
profile == VAProfileHEVCMain10) {
- attrib_list[i].value = 1;
+ attrib_list[i].value = I965_MAX_NUM_SLICE;
}
- } else if (entrypoint == VAEntrypointEncSliceLP) {
+ } else if (entrypoint == VAEntrypointEncSliceLP || entrypoint == VAEntrypointFEI) {
if ((profile == VAProfileH264ConstrainedBaseline ||
profile == VAProfileH264Main ||
profile == VAProfileH264High) ||
profile == VAProfileH264StereoHigh ||
profile == VAProfileH264MultiviewHigh)
attrib_list[i].value = I965_MAX_NUM_SLICE;
- } else
- attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
+ }
+
+ break;
+
+ case VAConfigAttribEncSliceStructure:
+ attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
+ if (entrypoint == VAEntrypointEncSlice) {
+ if ((profile == VAProfileH264ConstrainedBaseline ||
+ profile == VAProfileH264Main ||
+ profile == VAProfileH264High) ||
+ profile == VAProfileH264StereoHigh ||
+ profile == VAProfileH264MultiviewHigh ||
+ profile == VAProfileHEVCMain ||
+ profile == VAProfileHEVCMain10) {
+ attrib_list[i].value = VA_ENC_SLICE_STRUCTURE_ARBITRARY_MACROBLOCKS;
+ }
+ }
break;
+ case VAConfigAttribFEIFunctionType:
+ if (entrypoint == VAEntrypointFEI) {
+ /* Supporting all possible modes of FEI */
+ attrib_list[i].value = VA_FEI_FUNCTION_ENC |
+ VA_FEI_FUNCTION_PAK | VA_FEI_FUNCTION_ENC_PAK;
+ }
+ break;
+
+ case VAConfigAttribFEIMVPredictors:
+ if (entrypoint == VAEntrypointFEI)
+ attrib_list[i].value = 4;
+ break;
+
+ case VAConfigAttribStats:
+ if (entrypoint == VAEntrypointStats) {
+ VAConfigAttribValStats *configVal =
+ (VAConfigAttribValStats*) & (attrib_list[i].value);
+ (configVal->bits).max_num_past_references = STATS_MAX_NUM_PAST_REFS;
+ (configVal->bits).max_num_future_references = STATS_MAX_NUM_FUTURE_REFS;
+ (configVal->bits).num_outputs = STATS_MAX_NUM_OUTPUTS;
+ (configVal->bits).interlaced = STATS_INTERLACED_SUPPORT;
+ }
+ break;
+
default:
/* Do nothing */
attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
for (i = 0; i < num_attribs; i++) {
// add it later and ignore the user input for VAConfigAttribEncMaxSlices
- if (attrib_list[i].type == VAConfigAttribEncMaxSlices)
+ if (attrib_list[i].type == VAConfigAttribEncMaxSlices ||
+ attrib_list[i].type == VAConfigAttribEncSliceStructure)
continue;
vaStatus = i965_ensure_config_attribute(obj_config, &attrib_list[i]);
if (vaStatus != VA_STATUS_SUCCESS)
vaStatus = VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
}
+
+ if (vaStatus == VA_STATUS_SUCCESS) {
+ VAConfigAttrib *attrib_found = i965_lookup_config_attribute(obj_config, VAConfigAttribRateControl);
+
+ if (attrib_found) {
+ uint32_t rc_attribs = i965_get_rc_attributes(ctx, profile, entrypoint);
+
+ if (!(attrib_found->value & rc_attribs))
+ vaStatus = VA_STATUS_ERROR_INVALID_VALUE;
+ }
+ }
+
+ if (vaStatus == VA_STATUS_SUCCESS) {
+ VAConfigAttrib *attrib_found = i965_lookup_config_attribute(obj_config, VAConfigAttribEncPackedHeaders);
+
+ if (attrib_found) {
+ uint32_t enc_packed_attribs = i965_get_enc_packed_attributes(ctx, profile, entrypoint);
+
+ if (enc_packed_attribs == VA_ATTRIB_NOT_SUPPORTED) {
+ i965_log_info(ctx, "vaCreateConfig: invalid EncPackedHeaders attribute %#x: "
+ "packed headers are not supported.\n", attrib_found->value);
+ vaStatus = VA_STATUS_ERROR_INVALID_VALUE;
+ } else if (attrib_found->value == 0) {
+ i965_log_info(ctx, "vaCreateConfig: setting the EncPackedHeaders attribute to zero to "
+ "indicate that no packed headers will be used is deprecated.\n");
+ } else {
+ if (attrib_found->value & ~enc_packed_attribs) {
+ i965_log_info(ctx, "vaCreateConfig: invalid EncPackedHeaders attribute %#x: "
+ "some packed headers are not supported (supported set %#x).\n",
+ attrib_found->value, enc_packed_attribs);
+ vaStatus = VA_STATUS_ERROR_INVALID_VALUE;
+ }
+ }
+ }
+ }
+
if (vaStatus == VA_STATUS_SUCCESS) {
VAConfigAttrib attrib;
attrib.type = VAConfigAttribEncMaxSlices;
profile == VAProfileH264High) ||
profile == VAProfileH264StereoHigh ||
profile == VAProfileH264MultiviewHigh) {
- if (IS_GEN9(i965->intel.device_info))
- attrib.value = 1;
- else
- attrib.value = I965_MAX_NUM_SLICE;
+ attrib.value = I965_MAX_NUM_SLICE;
} else if (profile == VAProfileHEVCMain ||
- profile == VAProfileHEVCMain10) {
- attrib.value = 1;
- }
- } else if (entrypoint == VAEntrypointEncSliceLP) {
+ profile == VAProfileHEVCMain10)
+ attrib.value = I965_MAX_NUM_SLICE;
+ } else if (entrypoint == VAEntrypointEncSliceLP || entrypoint == VAEntrypointFEI) {
if ((profile == VAProfileH264ConstrainedBaseline ||
profile == VAProfileH264Main ||
profile == VAProfileH264High) ||
profile == VAProfileH264StereoHigh ||
profile == VAProfileH264MultiviewHigh)
attrib.value = I965_MAX_NUM_SLICE;
- } else
- attrib.value = VA_ATTRIB_NOT_SUPPORTED;
+ }
if (attrib.value != VA_ATTRIB_NOT_SUPPORTED)
vaStatus = i965_append_config_attribute(obj_config, &attrib);
}
+ if (vaStatus == VA_STATUS_SUCCESS) {
+ VAConfigAttrib attrib;
+ attrib.type = VAConfigAttribEncSliceStructure;
+ attrib.value = VA_ATTRIB_NOT_SUPPORTED;
+ if (entrypoint == VAEntrypointEncSlice) {
+ if ((profile == VAProfileH264ConstrainedBaseline ||
+ profile == VAProfileH264Main ||
+ profile == VAProfileH264High) ||
+ profile == VAProfileH264StereoHigh ||
+ profile == VAProfileH264MultiviewHigh) {
+ attrib.value = VA_ENC_SLICE_STRUCTURE_ARBITRARY_MACROBLOCKS;
+ }
+ }
+
+ if (attrib.value != VA_ATTRIB_NOT_SUPPORTED)
+ vaStatus = i965_append_config_attribute(obj_config, &attrib);
+ }
+
+ if (vaStatus == VA_STATUS_SUCCESS) {
+ VAConfigAttrib *attrib_found;
+
+ attrib_found = i965_lookup_config_attribute(obj_config, VAConfigAttribDecSliceMode);
+
+ if (attrib_found &&
+ (entrypoint != VAEntrypointVLD ||
+ attrib_found->value != VA_DEC_SLICE_MODE_NORMAL))
+ vaStatus = VA_STATUS_ERROR_INVALID_VALUE;
+ }
+
if ((vaStatus == VA_STATUS_SUCCESS) &&
(profile == VAProfileVP9Profile0) &&
(entrypoint == VAEntrypointVLD) &&
obj_surface->height = memory_attibute->data_size / obj_surface->width;
else
obj_surface->height = memory_attibute->offsets[1] / obj_surface->width;
- ASSERT_RET(IS_ALIGNED(obj_surface->height, 16), VA_STATUS_ERROR_INVALID_PARAMETER);
- ASSERT_RET(obj_surface->height >= obj_surface->orig_height, VA_STATUS_ERROR_INVALID_PARAMETER);
+
+ if (memory_attibute->num_planes > 1) {
+ ASSERT_RET(obj_surface->height >= obj_surface->orig_height, VA_STATUS_ERROR_INVALID_PARAMETER);
+ }
if (tiling) {
ASSERT_RET(IS_ALIGNED(obj_surface->width, 128), VA_STATUS_ERROR_INVALID_PARAMETER);
- ASSERT_RET(IS_ALIGNED(obj_surface->height, 32), VA_STATUS_ERROR_INVALID_PARAMETER);
+
+ if (memory_attibute->num_planes > 1)
+ ASSERT_RET(IS_ALIGNED(obj_surface->height, 32), VA_STATUS_ERROR_INVALID_PARAMETER);
} else {
ASSERT_RET(IS_ALIGNED(obj_surface->width, i965->codec_info->min_linear_wpitch), VA_STATUS_ERROR_INVALID_PARAMETER);
- ASSERT_RET(IS_ALIGNED(obj_surface->height, i965->codec_info->min_linear_hpitch), VA_STATUS_ERROR_INVALID_PARAMETER);
+
+ if (memory_attibute->num_planes > 1)
+ ASSERT_RET(IS_ALIGNED(obj_surface->height, i965->codec_info->min_linear_hpitch), VA_STATUS_ERROR_INVALID_PARAMETER);
}
obj_surface->x_cb_offset = 0; /* X offset is always 0 */
if (IS_GEN6(i965->intel.device_info) ||
IS_GEN7(i965->intel.device_info) ||
IS_GEN8(i965->intel.device_info) ||
+ IS_GEN10(i965->intel.device_info) ||
IS_GEN9(i965->intel.device_info)) {
*fourcc = VA_FOURCC_NV12;
*is_tiled = 1;
free(obj_context->codec_state.encode.packed_header_data_ext);
i965_release_buffer_store(&obj_context->codec_state.encode.encmb_map);
+ } else if (obj_context->codec_type == CODEC_PREENC) {
+ /* using the same encode codec_state for preenc too,
+ * since both sharig all most same code except in few places */
+ i965_release_buffer_store(&obj_context->codec_state.encode.stat_param_ext);
} 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);
i965_release_buffer_store(&obj_context->codec_state.decode.pic_param);
i965_release_buffer_store(&obj_context->codec_state.decode.iq_matrix);
+ i965_release_buffer_store(&obj_context->codec_state.decode.huffman_table);
i965_release_buffer_store(&obj_context->codec_state.decode.bit_plane);
for (i = 0; i < obj_context->codec_state.decode.num_slice_params; i++)
int i;
int max_width;
int max_height;
+ int min_width_height = I965_MIN_CODEC_ENC_RESOLUTION_WIDTH_HEIGHT;
if (NULL == obj_config) {
vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
return vaStatus;
}
+ if (obj_config->profile == VAProfileJPEGBaseline)
+ min_width_height = 1;
+
max_resolution(i965, obj_config, &max_width, &max_height);
if (picture_width > max_width ||
return vaStatus;
}
+ if ((VAEntrypointEncSlice == obj_config->entrypoint) ||
+ (VAEntrypointEncPicture == obj_config->entrypoint) ||
+ (VAEntrypointEncSliceLP == obj_config->entrypoint) ||
+ (VAEntrypointFEI == obj_config->entrypoint)) {
+ if (picture_width < min_width_height ||
+ picture_height < min_width_height) {
+ vaStatus = VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED;
+ return vaStatus;
+ }
+ }
+
/* Validate flag */
/* Validate picture dimensions */
contextID = NEW_CONTEXT_ID();
obj_context->hw_context = i965->codec_info->proc_hw_context_init(ctx, obj_config);
} else if ((VAEntrypointEncSlice == obj_config->entrypoint) ||
(VAEntrypointEncPicture == obj_config->entrypoint) ||
- (VAEntrypointEncSliceLP == obj_config->entrypoint)) {
+ (VAEntrypointEncSliceLP == obj_config->entrypoint) ||
+ (VAEntrypointFEI == 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));
}
assert(i965->codec_info->enc_hw_context_init);
obj_context->hw_context = i965->codec_info->enc_hw_context_init(ctx, obj_config);
+ } else if (VAEntrypointStats == obj_config->entrypoint) {
+ /* PreEnc sharing the ENC structures */
+ obj_context->codec_type = CODEC_PREENC;
+ memset(&obj_context->codec_state.encode, 0, sizeof(obj_context->codec_state.encode));
+ obj_context->codec_state.encode.current_render_target = VA_INVALID_ID;
+ assert(i965->codec_info->enc_hw_context_init);
+ obj_context->hw_context = i965->codec_info->enc_hw_context_init(ctx, obj_config);
} else {
obj_context->codec_type = CODEC_DEC;
memset(&obj_context->codec_state.decode, 0, sizeof(obj_context->codec_state.decode));
if (vaStatus == VA_STATUS_SUCCESS)
obj_context->wrapper_context = wrapper_context;
}
+
/* Error recovery */
if (VA_STATUS_SUCCESS != vaStatus) {
i965_destroy_context(&i965->context_heap, (struct object_base *)obj_context);
case VAHuffmanTableBufferType:
case VAProbabilityBufferType:
case VAEncMacroblockMapBufferType:
+ case VAEncQPBufferType:
+ case VAEncFEIMVBufferType:
+ case VAEncFEIMBCodeBufferType:
+ case VAEncFEIDistortionBufferType:
+ case VAEncFEIMBControlBufferType:
+ case VAEncFEIMVPredictorBufferType:
+ case VAStatsStatisticsParameterBufferType:
+ case VAStatsStatisticsBufferType:
+ case VAStatsStatisticsBottomFieldBufferType:
+ case VAStatsMVBufferType:
+ case VAStatsMVPredictorBufferType:
+
/* Ok */
break;
type == VAImageBufferType ||
type == VAEncCodedBufferType ||
type == VAEncMacroblockMapBufferType ||
- type == VAProbabilityBufferType) {
+ type == VAProbabilityBufferType ||
+ type == VAEncQPBufferType ||
+ type == VAEncFEIMVBufferType ||
+ type == VAEncFEIMBCodeBufferType ||
+ type == VAEncFEIDistortionBufferType ||
+ type == VAEncFEIMBControlBufferType ||
+ type == VAEncFEIMVPredictorBufferType ||
+ type == VAEncFEIMVPredictorBufferType ||
+ type == VAStatsStatisticsBufferType ||
+ type == VAStatsStatisticsBottomFieldBufferType ||
+ type == VAStatsMVBufferType ||
+ type == VAStatsMVPredictorBufferType) {
/* If the buffer is wrapped, the bo/buffer of buffer_store is bogus.
* So it is enough to allocate one 64 byte bo
return vaStatus;
}
- if ((num_elements < 0) ||
- (num_elements > obj_buffer->max_num_elements)) {
+ if (num_elements > obj_buffer->max_num_elements) {
vaStatus = VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
} else {
obj_buffer->num_elements = num_elements;
i965_release_buffer_store(&obj_context->codec_state.encode.misc_param[i][j]);
i965_release_buffer_store(&obj_context->codec_state.encode.encmb_map);
+ } else if (obj_context->codec_type == CODEC_PREENC) {
+ /* PreEnc sharing the ENC structures */
+ i965_release_buffer_store(&obj_context->codec_state.encode.stat_param_ext);
+ obj_context->codec_state.encode.current_render_target = render_target;
} else {
obj_context->codec_state.decode.current_render_target = render_target;
i965_release_buffer_store(&obj_context->codec_state.decode.pic_param);
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)
+DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(statistics_parameter_ext, stat_param_ext)
#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)
return vaStatus;
}
+static VAStatus
+i965_pre_encoder_render_picture(VADriverContextP ctx,
+ VAContextID context,
+ VABufferID *buffers,
+ int num_buffers)
+{
+ struct i965_driver_data *i965 = i965_driver_data(ctx);
+ struct object_context *obj_context = CONTEXT(context);
+ struct object_config *obj_config;
+ VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
+ int i;
+
+ ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
+ obj_config = obj_context->obj_config;
+ ASSERT_RET(obj_config, VA_STATUS_ERROR_INVALID_CONFIG);
+
+ for (i = 0; i < num_buffers; i++) {
+ struct object_buffer *obj_buffer = BUFFER(buffers[i]);
+
+ if (!obj_buffer)
+ return VA_STATUS_ERROR_INVALID_BUFFER;
+
+ switch (obj_buffer->type) {
+ case VAStatsStatisticsParameterBufferType:
+ vaStatus = I965_RENDER_ENCODE_BUFFER(statistics_parameter_ext);
+ break;
+
+ default:
+ vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
+ break;
+ }
+ }
+
+ return vaStatus;
+}
+
VAStatus
i965_RenderPicture(VADriverContextP ctx,
VAContextID context,
vaStatus = i965_proc_render_picture(ctx, context, buffers, num_buffers);
} else if ((VAEntrypointEncSlice == obj_config->entrypoint) ||
(VAEntrypointEncPicture == obj_config->entrypoint) ||
- (VAEntrypointEncSliceLP == obj_config->entrypoint)) {
+ (VAEntrypointEncSliceLP == obj_config->entrypoint) ||
+ (VAEntrypointFEI == obj_config->entrypoint)) {
vaStatus = i965_encoder_render_picture(ctx, context, buffers, num_buffers);
+ } else if (VAEntrypointStats == obj_config->entrypoint) {
+ vaStatus = i965_pre_encoder_render_picture(ctx, context, buffers, num_buffers);
} else {
vaStatus = i965_decoder_render_picture(ctx, context, buffers, num_buffers);
}
} else if (obj_context->codec_type == CODEC_ENC) {
ASSERT_RET(((VAEntrypointEncSlice == obj_config->entrypoint) ||
(VAEntrypointEncPicture == obj_config->entrypoint) ||
- (VAEntrypointEncSliceLP == obj_config->entrypoint)),
+ (VAEntrypointEncSliceLP == obj_config->entrypoint) ||
+ (VAEntrypointFEI == obj_config->entrypoint)),
VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT);
if (obj_context->codec_state.encode.num_packed_header_params_ext !=
" under packed SLICE_HEADER mode\n");
return VA_STATUS_ERROR_INVALID_PARAMETER;
}
+ } else if (obj_context->codec_type == CODEC_PREENC) {
+ ASSERT_RET((VAEntrypointStats == obj_config->entrypoint),
+ VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT);
+
+ if (!obj_context->codec_state.encode.stat_param_ext) {
+ return VA_STATUS_ERROR_INVALID_PARAMETER;
+ }
} else {
if (obj_context->codec_state.decode.pic_param == NULL) {
return VA_STATUS_ERROR_INVALID_PARAMETER;
attrib_list[i].value.value.i = VA_FOURCC_NV12;
} else if (IS_GEN7(i965->intel.device_info) ||
IS_GEN8(i965->intel.device_info) ||
- IS_GEN9(i965->intel.device_info)) {
+ IS_GEN9(i965->intel.device_info) ||
+ IS_GEN10(i965->intel.device_info)) {
if (obj_config->profile == VAProfileJPEGBaseline)
attrib_list[i].value.value.i = 0; /* internal format */
else
}
} else if (IS_GEN7(i965->intel.device_info) ||
IS_GEN8(i965->intel.device_info) ||
- IS_GEN9(i965->intel.device_info)) {
+ IS_GEN9(i965->intel.device_info) ||
+ IS_GEN10(i965->intel.device_info)) {
if (obj_config->entrypoint == VAEntrypointEncSlice ||
obj_config->entrypoint == VAEntrypointVideoProc ||
- obj_config->entrypoint == VAEntrypointEncSliceLP) {
+ obj_config->entrypoint == VAEntrypointEncSliceLP ||
+ obj_config->entrypoint == VAEntrypointFEI) {
switch (attrib_list[i].value.value.i) {
case VA_FOURCC_NV12:
case VA_FOURCC_I420:
attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
break;
}
+ } else if (obj_config->entrypoint == VAEntrypointStats) {
+ if (attrib_list[i].value.value.i != VA_FOURCC_NV12) {
+ attrib_list[i].value.value.i = 0;
+ attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
+ }
} else {
if (obj_config->profile == VAProfileJPEGBaseline) {
attrib_list[i].value.value.i = 0; /* JPEG decoding always uses an internal format */
attribs[i].value.value.i = VA_FOURCC_NV12;
i++;
+ break;
+
case VAProfileNone:
attribs[i].type = VASurfaceAttribPixelFormat;
attribs[i].value.type = VAGenericValueTypeInteger;
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_UYVY;
+ 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_RGBA;
i++;
}
}
} else if (IS_GEN8(i965->intel.device_info) ||
- IS_GEN9(i965->intel.device_info)) {
+ IS_GEN9(i965->intel.device_info) ||
+ IS_GEN10(i965->intel.device_info)) {
if (obj_config->entrypoint == VAEntrypointVLD) { /* decode */
if (obj_config->profile == VAProfileJPEGBaseline) {
attribs[i].type = VASurfaceAttribPixelFormat;
} else if (obj_config->entrypoint == VAEntrypointEncSlice || /* encode */
obj_config->entrypoint == VAEntrypointVideoProc ||
obj_config->entrypoint == VAEntrypointEncSliceLP ||
- obj_config->entrypoint == VAEntrypointEncPicture) {
+ obj_config->entrypoint == VAEntrypointEncPicture ||
+ obj_config->entrypoint == VAEntrypointFEI) {
if (obj_config->profile == VAProfileHEVCMain10) {
attribs[i].type = VASurfaceAttribPixelFormat;
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_UYVY;
+ 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_RGBA;
i++;
attribs[i].value.value.i = VA_FOURCC_Y800;
i++;
}
+ } else if (obj_config->entrypoint == VAEntrypointStats) {
+ 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].value.value.i = max_height;
i++;
+ if (obj_config->entrypoint == VAEntrypointEncSlice ||
+ obj_config->entrypoint == VAEntrypointEncSliceLP ||
+ obj_config->entrypoint == VAEntrypointEncPicture ||
+ obj_config->entrypoint == VAEntrypointFEI) {
+ attribs[i].type = VASurfaceAttribMinWidth;
+ attribs[i].value.type = VAGenericValueTypeInteger;
+ attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE;
+ attribs[i].value.value.i = I965_MIN_CODEC_ENC_RESOLUTION_WIDTH_HEIGHT;
+ if (obj_config->profile == VAProfileJPEGBaseline)
+ attribs[i].value.value.i = 1;
+ i++;
+
+ attribs[i].type = VASurfaceAttribMinHeight;
+ attribs[i].value.type = VAGenericValueTypeInteger;
+ attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE;
+ attribs[i].value.value.i = I965_MIN_CODEC_ENC_RESOLUTION_WIDTH_HEIGHT;
+ if (obj_config->profile == VAProfileJPEGBaseline)
+ attribs[i].value.value.i = 1;
+ i++;
+ }
+
if (i > *num_attribs) {
*num_attribs = i;
free(attribs);
return i965_release_buffer_handle(obj_buffer);
}
+// Locally define DRM_FORMAT values not available in older but still
+// supported versions of libdrm.
+#ifndef DRM_FORMAT_R8
+#define DRM_FORMAT_R8 fourcc_code('R', '8', ' ', ' ')
+#endif
+#ifndef DRM_FORMAT_R16
+#define DRM_FORMAT_R16 fourcc_code('R', '1', '6', ' ')
+#endif
+#ifndef DRM_FORMAT_GR88
+#define DRM_FORMAT_GR88 fourcc_code('G', 'R', '8', '8')
+#endif
+#ifndef DRM_FORMAT_GR1616
+#define DRM_FORMAT_GR1616 fourcc_code('G', 'R', '3', '2')
+#endif
+
+static uint32_t drm_format_of_separate_plane(uint32_t fourcc, int plane)
+{
+ if (plane == 0) {
+ switch (fourcc) {
+ case VA_FOURCC_NV12:
+ case VA_FOURCC_I420:
+ case VA_FOURCC_YV12:
+ case VA_FOURCC_YV16:
+ case VA_FOURCC_Y800:
+ return DRM_FORMAT_R8;
+ case VA_FOURCC_P010:
+ case VA_FOURCC_I010:
+ return DRM_FORMAT_R16;
+
+ case VA_FOURCC_YUY2:
+ case VA_FOURCC_UYVY:
+ // These are not representable as separate planes.
+ return 0;
+
+ case VA_FOURCC_RGBA:
+ return DRM_FORMAT_ABGR8888;
+ case VA_FOURCC_RGBX:
+ return DRM_FORMAT_XBGR8888;
+ case VA_FOURCC_BGRA:
+ return DRM_FORMAT_ARGB8888;
+ case VA_FOURCC_BGRX:
+ return DRM_FORMAT_XRGB8888;
+ case VA_FOURCC_ARGB:
+ return DRM_FORMAT_BGRA8888;
+ case VA_FOURCC_ABGR:
+ return DRM_FORMAT_RGBA8888;
+ }
+ } else {
+ switch (fourcc) {
+ case VA_FOURCC_NV12:
+ return DRM_FORMAT_GR88;
+ case VA_FOURCC_I420:
+ case VA_FOURCC_YV12:
+ case VA_FOURCC_YV16:
+ return DRM_FORMAT_R8;
+ case VA_FOURCC_P010:
+ return DRM_FORMAT_GR1616;
+ case VA_FOURCC_I010:
+ return DRM_FORMAT_R16;
+ }
+ }
+ return 0;
+}
+
+static uint32_t drm_format_of_composite_object(uint32_t fourcc)
+{
+ switch (fourcc) {
+ case VA_FOURCC_NV12:
+ return DRM_FORMAT_NV12;
+ case VA_FOURCC_I420:
+ return DRM_FORMAT_YUV420;
+ case VA_FOURCC_YV12:
+ return DRM_FORMAT_YVU420;
+ case VA_FOURCC_YV16:
+ return DRM_FORMAT_YVU422;
+ case VA_FOURCC_YUY2:
+ return DRM_FORMAT_YUYV;
+ case VA_FOURCC_UYVY:
+ return DRM_FORMAT_UYVY;
+ case VA_FOURCC_Y800:
+ return DRM_FORMAT_R8;
+
+ case VA_FOURCC_P010:
+ case VA_FOURCC_I010:
+ // These currently have no composite DRM format - they are usable
+ // only as separate planes.
+ return 0;
+
+ case VA_FOURCC_RGBA:
+ return DRM_FORMAT_ABGR8888;
+ case VA_FOURCC_RGBX:
+ return DRM_FORMAT_XBGR8888;
+ case VA_FOURCC_BGRA:
+ return DRM_FORMAT_ARGB8888;
+ case VA_FOURCC_BGRX:
+ return DRM_FORMAT_XRGB8888;
+ case VA_FOURCC_ARGB:
+ return DRM_FORMAT_BGRA8888;
+ case VA_FOURCC_ABGR:
+ return DRM_FORMAT_RGBA8888;
+ }
+ return 0;
+}
+
+static VAStatus
+i965_ExportSurfaceHandle(VADriverContextP ctx, VASurfaceID surface_id,
+ uint32_t mem_type, uint32_t flags,
+ void *descriptor)
+{
+ struct i965_driver_data *const i965 = i965_driver_data(ctx);
+ struct object_surface *obj_surface = SURFACE(surface_id);
+ const i965_fourcc_info *info;
+ VADRMPRIMESurfaceDescriptor *desc;
+ unsigned int tiling, swizzle;
+ uint32_t formats[4], pitch, height, offset;
+ int fd, p;
+ int composite_object =
+ flags & VA_EXPORT_SURFACE_COMPOSED_LAYERS;
+
+ if (!obj_surface || !obj_surface->bo)
+ return VA_STATUS_ERROR_INVALID_SURFACE;
+
+ if (mem_type != VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2) {
+ i965_log_info(ctx, "vaExportSurfaceHandle: memory type %08x "
+ "is not supported.\n", mem_type);
+ return VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE;
+ }
+
+ info = get_fourcc_info(obj_surface->fourcc);
+ if (!info)
+ return VA_STATUS_ERROR_INVALID_SURFACE;
+ if (composite_object) {
+ formats[0] =
+ drm_format_of_composite_object(obj_surface->fourcc);
+ if (!formats[0]) {
+ i965_log_info(ctx, "vaExportSurfaceHandle: fourcc %08x "
+ "is not supported for export as a composite "
+ "object.\n", obj_surface->fourcc);
+ return VA_STATUS_ERROR_INVALID_SURFACE;
+ }
+ } else {
+ for (p = 0; p < info->num_planes; p++) {
+ formats[p] =
+ drm_format_of_separate_plane(obj_surface->fourcc, p);
+ if (!formats[p]) {
+ i965_log_info(ctx, "vaExportSurfaceHandle: fourcc %08x "
+ "is not supported for export as separate "
+ "planes.\n", obj_surface->fourcc);
+ return VA_STATUS_ERROR_INVALID_SURFACE;
+ }
+ }
+ }
+
+ if (drm_intel_bo_gem_export_to_prime(obj_surface->bo, &fd))
+ return VA_STATUS_ERROR_INVALID_SURFACE;
+
+ if (drm_intel_bo_get_tiling(obj_surface->bo, &tiling, &swizzle))
+ tiling = I915_TILING_NONE;
+
+ desc = descriptor;
+
+ desc->fourcc = obj_surface->fourcc;
+ desc->width = obj_surface->orig_width;
+ desc->height = obj_surface->orig_height;
+
+ desc->num_objects = 1;
+ desc->objects[0].fd = fd;
+ desc->objects[0].size = obj_surface->size;
+ switch (tiling) {
+ case I915_TILING_X:
+ desc->objects[0].drm_format_modifier = I915_FORMAT_MOD_X_TILED;
+ break;
+ case I915_TILING_Y:
+ desc->objects[0].drm_format_modifier = I915_FORMAT_MOD_Y_TILED;
+ break;
+ case I915_TILING_NONE:
+ default:
+ desc->objects[0].drm_format_modifier = DRM_FORMAT_MOD_NONE;
+ }
+
+ if (composite_object) {
+ desc->num_layers = 1;
+
+ desc->layers[0].drm_format = formats[0];
+ desc->layers[0].num_planes = info->num_planes;
+
+ offset = 0;
+ for (p = 0; p < info->num_planes; p++) {
+ desc->layers[0].object_index[p] = 0;
+
+ if (p == 0) {
+ pitch = obj_surface->width;
+ height = obj_surface->height;
+ } else {
+ pitch = obj_surface->cb_cr_pitch;
+ height = obj_surface->cb_cr_height;
+ }
+
+ desc->layers[0].offset[p] = offset;
+ desc->layers[0].pitch[p] = pitch;
+
+ offset += pitch * height;
+ }
+ } else {
+ desc->num_layers = info->num_planes;
+
+ offset = 0;
+ for (p = 0; p < info->num_planes; p++) {
+ desc->layers[p].drm_format = formats[p];
+ desc->layers[p].num_planes = 1;
+
+ desc->layers[p].object_index[0] = 0;
+
+ if (p == 0) {
+ pitch = obj_surface->width;
+ height = obj_surface->height;
+ } else {
+ pitch = obj_surface->cb_cr_pitch;
+ height = obj_surface->cb_cr_height;
+ }
+
+ desc->layers[p].offset[0] = offset;
+ desc->layers[p].pitch[0] = pitch;
+
+ offset += pitch * height;
+ }
+ }
+
+ return VA_STATUS_SUCCESS;
+}
+
static int
i965_os_has_ring_support(VADriverContextP ctx,
int ring)
return VA_STATUS_SUCCESS;
}
+void i965_log_error(VADriverContextP ctx, const char *format, ...)
+{
+ va_list vl;
+
+ va_start(vl, format);
+
+ if (!ctx->error_callback) {
+ // No error callback: this is a error message which should be
+ // user-visible, so print it to stderr instead.
+ vfprintf(stderr, format, vl);
+ } else {
+ // Put the message on the stack. If it overruns the size of the
+ // then it will just be truncated - callers shouldn't be sending
+ // messages which are too long.
+ char tmp[1024];
+ int ret;
+ ret = vsnprintf(tmp, sizeof(tmp), format, vl);
+ if (ret > 0)
+ ctx->error_callback(ctx, tmp);
+ }
+
+ va_end(vl);
+}
+
+void i965_log_info(VADriverContextP ctx, const char *format, ...)
+{
+ va_list vl;
+
+ va_start(vl, format);
+
+ if (!ctx->info_callback) {
+ // No info callback: this message is only useful for developers,
+ // so just discard it.
+ } else {
+ // Put the message on the stack. If it overruns the size of the
+ // then it will just be truncated - callers shouldn't be sending
+ // messages which are too long.
+ char tmp[1024];
+ int ret;
+ ret = vsnprintf(tmp, sizeof(tmp), format, vl);
+ if (ret > 0)
+ ctx->info_callback(ctx, tmp);
+ }
+
+ va_end(vl);
+}
+
extern struct hw_codec_info *i965_get_codec_info(int devid);
static bool
if (INTEL_DRIVER_PRE_VERSION > 0) {
ret = snprintf(&i965->va_vendor[len], sizeof(i965->va_vendor) - len,
".pre%d", INTEL_DRIVER_PRE_VERSION);
- if (ret < 0 || ret >= sizeof(i965->va_vendor))
+ if (ret < 0 || ret >= (sizeof(i965->va_vendor) - len))
goto error;
len += ret;
ret = snprintf(&i965->va_vendor[len], sizeof(i965->va_vendor) - len,
" (%s)", INTEL_DRIVER_GIT_VERSION);
- if (ret < 0 || ret >= sizeof(i965->va_vendor))
+ if (ret < 0 || ret >= (sizeof(i965->va_vendor) - len))
goto error;
len += ret;
}
vtable->vaAcquireBufferHandle = i965_AcquireBufferHandle;
vtable->vaReleaseBufferHandle = i965_ReleaseBufferHandle;
+ /* 1.0.0 */
+ vtable->vaExportSurfaceHandle = i965_ExportSurfaceHandle;
+
vtable_vpp->vaQueryVideoProcFilters = i965_QueryVideoProcFilters;
vtable_vpp->vaQueryVideoProcFilterCaps = i965_QueryVideoProcFilterCaps;
vtable_vpp->vaQueryVideoProcPipelineCaps = i965_QueryVideoProcPipelineCaps;