Module: Mesa Branch: main Commit: 5cb46f1ce70a513fd90f676bcfd852667b041f43 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=5cb46f1ce70a513fd90f676bcfd852667b041f43
Author: Dave Airlie <airl...@redhat.com> Date: Thu Mar 9 16:40:48 2023 +1000 vulkan/video: add support for h264 encode to common code This adds support for the h264 encode session and parameter storage. Reviewed-by: Hyunjun Ko <zz...@igalia.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25874> --- src/vulkan/runtime/vk_video.c | 147 +++++++++++++++++++++++++++++++++++++++--- src/vulkan/runtime/vk_video.h | 29 +++++++++ 2 files changed, 168 insertions(+), 8 deletions(-) diff --git a/src/vulkan/runtime/vk_video.c b/src/vulkan/runtime/vk_video.c index 16a684bfcd5..3a7d1528225 100644 --- a/src/vulkan/runtime/vk_video.c +++ b/src/vulkan/runtime/vk_video.c @@ -57,10 +57,34 @@ vk_video_session_init(struct vk_device *device, vid->h265.profile_idc = h265_profile->stdProfileIdc; break; } +#ifdef VK_ENABLE_BETA_EXTENSIONS + case VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_EXT: { + const struct VkVideoEncodeH264ProfileInfoEXT *h264_profile = + vk_find_struct_const(create_info->pVideoProfile->pNext, VIDEO_ENCODE_H264_PROFILE_INFO_EXT); + vid->h264.profile_idc = h264_profile->stdProfileIdc; + break; + } +#endif default: return VK_ERROR_FEATURE_NOT_PRESENT; } +#ifdef VK_ENABLE_BETA_EXTENSIONS + if (vid->op == VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_EXT) { + const struct VkVideoEncodeUsageInfoKHR *encode_usage_profile = + vk_find_struct_const(create_info->pVideoProfile->pNext, VIDEO_ENCODE_USAGE_INFO_KHR); + if (encode_usage_profile) { + vid->enc_usage.video_usage_hints = encode_usage_profile->videoUsageHints; + vid->enc_usage.video_content_hints = encode_usage_profile->videoContentHints; + vid->enc_usage.tuning_mode = encode_usage_profile->tuningMode; + } else { + vid->enc_usage.video_usage_hints = VK_VIDEO_ENCODE_USAGE_DEFAULT_KHR; + vid->enc_usage.video_content_hints = VK_VIDEO_ENCODE_CONTENT_DEFAULT_KHR; + vid->enc_usage.tuning_mode = VK_VIDEO_ENCODE_TUNING_MODE_DEFAULT_KHR; + } + } +#endif + return VK_SUCCESS; } @@ -99,10 +123,15 @@ FIND(StdVideoH265VideoParameterSet, h265_dec, std_vps, vps_video_parameter_set_i FIND(StdVideoH265SequenceParameterSet, h265_dec, std_sps, sps_seq_parameter_set_id) FIND(StdVideoH265PictureParameterSet, h265_dec, std_pps, pps_pic_parameter_set_id) +#ifdef VK_ENABLE_BETA_EXTENSIONS +FIND(StdVideoH264SequenceParameterSet, h264_enc, std_sps, seq_parameter_set_id) +FIND(StdVideoH264PictureParameterSet, h264_enc, std_pps, pic_parameter_set_id) +#endif + static void -init_add_h264_session_parameters(struct vk_video_session_parameters *params, - const struct VkVideoDecodeH264SessionParametersAddInfoKHR *h264_add, - const struct vk_video_session_parameters *templ) +init_add_h264_dec_session_parameters(struct vk_video_session_parameters *params, + const struct VkVideoDecodeH264SessionParametersAddInfoKHR *h264_add, + const struct vk_video_session_parameters *templ) { unsigned i; @@ -129,6 +158,37 @@ init_add_h264_session_parameters(struct vk_video_session_parameters *params, } } +#ifdef VK_ENABLE_BETA_EXTENSIONS +static void +init_add_h264_enc_session_parameters(struct vk_video_session_parameters *params, + const struct VkVideoEncodeH264SessionParametersAddInfoEXT *h264_add, + const struct vk_video_session_parameters *templ) +{ + unsigned i; + if (h264_add) { + for (i = 0; i < h264_add->stdSPSCount; i++) { + add_h264_enc_std_sps(params, &h264_add->pStdSPSs[i], false); + } + } + if (templ) { + for (i = 0; i < templ->h264_dec.std_sps_count; i++) { + add_h264_enc_std_sps(params, &templ->h264_enc.std_sps[i], true); + } + } + + if (h264_add) { + for (i = 0; i < h264_add->stdPPSCount; i++) { + add_h264_enc_std_pps(params, &h264_add->pStdPPSs[i], false); + } + } + if (templ) { + for (i = 0; i < templ->h264_enc.std_pps_count; i++) { + add_h264_enc_std_pps(params, &templ->h264_enc.std_pps[i], true); + } + } +} +#endif + static void init_add_h265_session_parameters(struct vk_video_session_parameters *params, const struct VkVideoDecodeH265SessionParametersAddInfoKHR *h265_add, @@ -200,7 +260,7 @@ vk_video_session_parameters_init(struct vk_device *device, return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); } - init_add_h264_session_parameters(params, h264_create->pParametersAddInfo, templ); + init_add_h264_dec_session_parameters(params, h264_create->pParametersAddInfo, templ); break; } case VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR: { @@ -228,6 +288,29 @@ vk_video_session_parameters_init(struct vk_device *device, init_add_h265_session_parameters(params, h265_create->pParametersAddInfo, templ); break; } +#ifdef VK_ENABLE_BETA_EXTENSIONS + case VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_EXT: { + const struct VkVideoEncodeH264SessionParametersCreateInfoEXT *h264_create = + vk_find_struct_const(create_info->pNext, VIDEO_ENCODE_H264_SESSION_PARAMETERS_CREATE_INFO_EXT); + + params->h264_enc.max_std_sps_count = h264_create->maxStdSPSCount; + params->h264_enc.max_std_pps_count = h264_create->maxStdPPSCount; + + uint32_t sps_size = params->h264_enc.max_std_sps_count * sizeof(StdVideoH264SequenceParameterSet); + uint32_t pps_size = params->h264_enc.max_std_pps_count * sizeof(StdVideoH264PictureParameterSet); + + params->h264_enc.std_sps = vk_alloc(&device->alloc, sps_size, 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + params->h264_enc.std_pps = vk_alloc(&device->alloc, pps_size, 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + if (!params->h264_enc.std_sps || !params->h264_enc.std_pps) { + vk_free(&device->alloc, params->h264_enc.std_sps); + vk_free(&device->alloc, params->h264_enc.std_pps); + return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); + } + + init_add_h264_enc_session_parameters(params, h264_create->pParametersAddInfo, templ); + break; + } +#endif default: unreachable("Unsupported video codec operation"); break; @@ -249,6 +332,12 @@ vk_video_session_parameters_finish(struct vk_device *device, vk_free(&device->alloc, params->h265_dec.std_sps); vk_free(&device->alloc, params->h265_dec.std_pps); break; +#ifdef VK_ENABLE_BETA_EXTENSIONS + case VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_EXT: + vk_free(&device->alloc, params->h264_enc.std_sps); + vk_free(&device->alloc, params->h264_enc.std_pps); + break; +#endif default: break; } @@ -268,8 +357,8 @@ update_sps(struct vk_video_session_parameters *params, } static VkResult -update_h264_session_parameters(struct vk_video_session_parameters *params, - const struct VkVideoDecodeH264SessionParametersAddInfoKHR *h264_add) +update_h264_dec_session_parameters(struct vk_video_session_parameters *params, + const struct VkVideoDecodeH264SessionParametersAddInfoKHR *h264_add) { VkResult result = VK_SUCCESS; @@ -281,6 +370,21 @@ update_h264_session_parameters(struct vk_video_session_parameters *params, return result; } +#ifdef VK_ENABLE_BETA_EXTENSIONS +static VkResult +update_h264_enc_session_parameters(struct vk_video_session_parameters *params, + const struct VkVideoEncodeH264SessionParametersAddInfoEXT *h264_add) +{ + VkResult result = VK_SUCCESS; + result = update_h264_enc_std_sps(params, h264_add->stdSPSCount, h264_add->pStdSPSs); + if (result != VK_SUCCESS) + return result; + + result = update_h264_enc_std_pps(params, h264_add->stdPPSCount, h264_add->pStdPPSs); + return result; +} +#endif + static VkResult update_h265_session_parameters(struct vk_video_session_parameters *params, const struct VkVideoDecodeH265SessionParametersAddInfoKHR *h265_add) @@ -319,7 +423,7 @@ vk_video_session_parameters_update(struct vk_video_session_parameters *params, case VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR: { const struct VkVideoDecodeH264SessionParametersAddInfoKHR *h264_add = vk_find_struct_const(update->pNext, VIDEO_DECODE_H264_SESSION_PARAMETERS_ADD_INFO_KHR); - return update_h264_session_parameters(params, h264_add); + return update_h264_dec_session_parameters(params, h264_add); } case VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR: { const struct VkVideoDecodeH265SessionParametersAddInfoKHR *h265_add = @@ -327,6 +431,13 @@ vk_video_session_parameters_update(struct vk_video_session_parameters *params, return update_h265_session_parameters(params, h265_add); } +#ifdef VK_ENABLE_BETA_EXTENSIONS + case VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_EXT: { + const struct VkVideoEncodeH264SessionParametersAddInfoEXT *h264_add = + vk_find_struct_const(update->pNext, VIDEO_ENCODE_H264_SESSION_PARAMETERS_ADD_INFO_EXT); + return update_h264_enc_session_parameters(params, h264_add); + } +#endif default: unreachable("Unknown codec\n"); } @@ -1001,7 +1112,11 @@ vk_video_get_profile_alignments(const VkVideoProfileListInfoKHR *profile_list, { uint32_t width_align = 1, height_align = 1; for (unsigned i = 0; i < profile_list->profileCount; i++) { - if (profile_list->pProfiles[i].videoCodecOperation == VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR) { + if (profile_list->pProfiles[i].videoCodecOperation == VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR +#ifdef VK_ENABLE_BETA_EXTENSIONS + || profile_list->pProfiles[i].videoCodecOperation == VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_EXT +#endif + ) { width_align = MAX2(width_align, VK_VIDEO_H264_MACROBLOCK_WIDTH); height_align = MAX2(height_align, VK_VIDEO_H264_MACROBLOCK_HEIGHT); } @@ -1013,3 +1128,19 @@ vk_video_get_profile_alignments(const VkVideoProfileListInfoKHR *profile_list, *width_align_out = width_align; *height_align_out = height_align; } + +#ifdef VK_ENABLE_BETA_EXTENSIONS +const StdVideoH264SequenceParameterSet * +vk_video_find_h264_enc_std_sps(const struct vk_video_session_parameters *params, + uint32_t id) +{ + return find_h264_enc_std_sps(params, id); +} + +const StdVideoH264PictureParameterSet * +vk_video_find_h264_enc_std_pps(const struct vk_video_session_parameters *params, + uint32_t id) +{ + return find_h264_enc_std_pps(params, id); +} +#endif diff --git a/src/vulkan/runtime/vk_video.h b/src/vulkan/runtime/vk_video.h index 442c54b34f3..1a24990fdac 100644 --- a/src/vulkan/runtime/vk_video.h +++ b/src/vulkan/runtime/vk_video.h @@ -38,6 +38,13 @@ struct vk_video_session { uint32_t max_dpb_slots; uint32_t max_active_ref_pics; +#ifdef VK_ENABLE_BETA_EXTENSIONS + struct { + VkVideoEncodeUsageFlagsKHR video_usage_hints; + VkVideoEncodeContentFlagsKHR video_content_hints; + VkVideoEncodeTuningModeKHR tuning_mode; + } enc_usage; +#endif union { struct { StdVideoH264ProfileIdc profile_idc; @@ -74,6 +81,18 @@ struct vk_video_session_parameters { uint32_t std_pps_count; StdVideoH265PictureParameterSet *std_pps; } h265_dec; + +#ifdef VK_ENABLE_BETA_EXTENSIONS + struct { + uint32_t max_std_sps_count; + uint32_t max_std_pps_count; + + uint32_t std_sps_count; + StdVideoH264SequenceParameterSet *std_sps; + uint32_t std_pps_count; + StdVideoH264PictureParameterSet *std_pps; + } h264_enc; +#endif }; }; @@ -198,6 +217,16 @@ void vk_fill_video_h265_reference_info(const VkVideoDecodeInfoKHR *frame_info, void vk_video_get_profile_alignments(const VkVideoProfileListInfoKHR *profile_list, uint32_t *width_align_out, uint32_t *height_align_out); + +#ifdef VK_ENABLE_BETA_EXTENSIONS +const StdVideoH264SequenceParameterSet * +vk_video_find_h264_enc_std_sps(const struct vk_video_session_parameters *params, + uint32_t id); +const StdVideoH264PictureParameterSet * +vk_video_find_h264_enc_std_pps(const struct vk_video_session_parameters *params, + uint32_t id); +#endif + #ifdef __cplusplus } #endif