Module: Mesa
Branch: main
Commit: 8dd97080d8c571d8df0bf6eccc152f7d1689727f
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=8dd97080d8c571d8df0bf6eccc152f7d1689727f

Author: Dave Airlie <airl...@redhat.com>
Date:   Tue Jun 20 20:30:22 2023 +1000

vulkan/video: add h265 encode support

This just adds the session and parameter handling for h265 encode.

Reviewed-by: Hyunjun Ko <zz...@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25874>

---

 src/vulkan/runtime/vk_video.c | 141 ++++++++++++++++++++++++++++++++++++++++--
 src/vulkan/runtime/vk_video.h |  23 +++++++
 2 files changed, 159 insertions(+), 5 deletions(-)

diff --git a/src/vulkan/runtime/vk_video.c b/src/vulkan/runtime/vk_video.c
index 3a7d1528225..dd3068ececc 100644
--- a/src/vulkan/runtime/vk_video.c
+++ b/src/vulkan/runtime/vk_video.c
@@ -64,13 +64,20 @@ vk_video_session_init(struct vk_device *device,
       vid->h264.profile_idc = h264_profile->stdProfileIdc;
       break;
    }
+   case VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_EXT: {
+      const struct VkVideoEncodeH265ProfileInfoEXT *h265_profile =
+         vk_find_struct_const(create_info->pVideoProfile->pNext, 
VIDEO_ENCODE_H265_PROFILE_INFO_EXT);
+      vid->h265.profile_idc = h265_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) {
+   if (vid->op == VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_EXT ||
+       vid->op == VK_VIDEO_CODEC_OPERATION_ENCODE_H265_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) {
@@ -126,6 +133,10 @@ FIND(StdVideoH265PictureParameterSet, h265_dec, std_pps, 
pps_pic_parameter_set_i
 #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)
+
+FIND(StdVideoH265VideoParameterSet, h265_enc, std_vps, 
vps_video_parameter_set_id)
+FIND(StdVideoH265SequenceParameterSet, h265_enc, std_sps, 
sps_seq_parameter_set_id)
+FIND(StdVideoH265PictureParameterSet, h265_enc, std_pps, 
pps_pic_parameter_set_id)
 #endif
 
 static void
@@ -190,7 +201,7 @@ init_add_h264_enc_session_parameters(struct 
vk_video_session_parameters *params,
 #endif
 
 static void
-init_add_h265_session_parameters(struct vk_video_session_parameters *params,
+init_add_h265_dec_session_parameters(struct vk_video_session_parameters 
*params,
                                  const struct 
VkVideoDecodeH265SessionParametersAddInfoKHR *h265_add,
                                  const struct vk_video_session_parameters 
*templ)
 {
@@ -229,6 +240,48 @@ init_add_h265_session_parameters(struct 
vk_video_session_parameters *params,
    }
 }
 
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+static void
+init_add_h265_enc_session_parameters(struct vk_video_session_parameters 
*params,
+                                     const struct 
VkVideoEncodeH265SessionParametersAddInfoEXT *h265_add,
+                                     const struct vk_video_session_parameters 
*templ)
+{
+   unsigned i;
+
+   if (h265_add) {
+      for (i = 0; i < h265_add->stdVPSCount; i++) {
+         add_h265_enc_std_vps(params, &h265_add->pStdVPSs[i], false);
+      }
+   }
+   if (templ) {
+      for (i = 0; i < templ->h265_enc.std_vps_count; i++) {
+         add_h265_enc_std_vps(params, &templ->h265_enc.std_vps[i], true);
+      }
+   }
+   if (h265_add) {
+      for (i = 0; i < h265_add->stdSPSCount; i++) {
+         add_h265_enc_std_sps(params, &h265_add->pStdSPSs[i], false);
+      }
+   }
+   if (templ) {
+      for (i = 0; i < templ->h265_enc.std_sps_count; i++) {
+         add_h265_enc_std_sps(params, &templ->h265_enc.std_sps[i], true);
+      }
+   }
+
+   if (h265_add) {
+      for (i = 0; i < h265_add->stdPPSCount; i++) {
+         add_h265_enc_std_pps(params, &h265_add->pStdPPSs[i], false);
+      }
+   }
+   if (templ) {
+      for (i = 0; i < templ->h265_enc.std_pps_count; i++) {
+         add_h265_enc_std_pps(params, &templ->h265_enc.std_pps[i], true);
+      }
+   }
+}
+#endif
+
 VkResult
 vk_video_session_parameters_init(struct vk_device *device,
                                  struct vk_video_session_parameters *params,
@@ -285,7 +338,7 @@ vk_video_session_parameters_init(struct vk_device *device,
          return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
       }
 
-      init_add_h265_session_parameters(params, 
h265_create->pParametersAddInfo, templ);
+      init_add_h265_dec_session_parameters(params, 
h265_create->pParametersAddInfo, templ);
       break;
    }
 #ifdef VK_ENABLE_BETA_EXTENSIONS
@@ -310,6 +363,31 @@ vk_video_session_parameters_init(struct vk_device *device,
       init_add_h264_enc_session_parameters(params, 
h264_create->pParametersAddInfo, templ);
       break;
    }
+   case VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_EXT: {
+      const struct VkVideoEncodeH265SessionParametersCreateInfoEXT 
*h265_create =
+         vk_find_struct_const(create_info->pNext, 
VIDEO_ENCODE_H265_SESSION_PARAMETERS_CREATE_INFO_EXT);
+
+      params->h265_enc.max_std_vps_count = h265_create->maxStdVPSCount;
+      params->h265_enc.max_std_sps_count = h265_create->maxStdSPSCount;
+      params->h265_enc.max_std_pps_count = h265_create->maxStdPPSCount;
+
+      uint32_t vps_size = params->h265_enc.max_std_vps_count * 
sizeof(StdVideoH265VideoParameterSet);
+      uint32_t sps_size = params->h265_enc.max_std_sps_count * 
sizeof(StdVideoH265SequenceParameterSet);
+      uint32_t pps_size = params->h265_enc.max_std_pps_count * 
sizeof(StdVideoH265PictureParameterSet);
+
+      params->h265_enc.std_vps = vk_alloc(&device->alloc, vps_size, 8, 
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+      params->h265_enc.std_sps = vk_alloc(&device->alloc, sps_size, 8, 
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+      params->h265_enc.std_pps = vk_alloc(&device->alloc, pps_size, 8, 
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+      if (!params->h265_enc.std_sps || !params->h265_enc.std_pps || 
!params->h265_enc.std_vps) {
+         vk_free(&device->alloc, params->h265_enc.std_vps);
+         vk_free(&device->alloc, params->h265_enc.std_sps);
+         vk_free(&device->alloc, params->h265_enc.std_pps);
+         return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
+      }
+
+      init_add_h265_enc_session_parameters(params, 
h265_create->pParametersAddInfo, templ);
+      break;
+   }
 #endif
    default:
       unreachable("Unsupported video codec operation");
@@ -337,6 +415,11 @@ vk_video_session_parameters_finish(struct vk_device 
*device,
       vk_free(&device->alloc, params->h264_enc.std_sps);
       vk_free(&device->alloc, params->h264_enc.std_pps);
       break;
+   case VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_EXT:
+      vk_free(&device->alloc, params->h265_enc.std_vps);
+      vk_free(&device->alloc, params->h265_enc.std_sps);
+      vk_free(&device->alloc, params->h265_enc.std_pps);
+      break;
 #endif
    default:
       break;
@@ -373,7 +456,7 @@ update_h264_dec_session_parameters(struct 
vk_video_session_parameters *params,
 #ifdef VK_ENABLE_BETA_EXTENSIONS
 static VkResult
 update_h264_enc_session_parameters(struct vk_video_session_parameters *params,
-                                  const struct 
VkVideoEncodeH264SessionParametersAddInfoEXT *h264_add)
+                                  const struct 
VkVideoEncodeH264SessionParametersAddInfoEXT *h264_add)
 {
    VkResult result = VK_SUCCESS;
    result = update_h264_enc_std_sps(params, h264_add->stdSPSCount, 
h264_add->pStdSPSs);
@@ -383,6 +466,24 @@ update_h264_enc_session_parameters(struct 
vk_video_session_parameters *params,
    result = update_h264_enc_std_pps(params, h264_add->stdPPSCount, 
h264_add->pStdPPSs);
    return result;
 }
+
+static VkResult
+update_h265_enc_session_parameters(struct vk_video_session_parameters *params,
+                                   const struct 
VkVideoEncodeH265SessionParametersAddInfoEXT *h265_add)
+{
+   VkResult result = VK_SUCCESS;
+
+   result = update_h265_enc_std_vps(params, h265_add->stdVPSCount, 
h265_add->pStdVPSs);
+   if (result != VK_SUCCESS)
+      return result;
+
+   result = update_h265_enc_std_sps(params, h265_add->stdSPSCount, 
h265_add->pStdSPSs);
+   if (result != VK_SUCCESS)
+      return result;
+
+   result = update_h265_enc_std_pps(params, h265_add->stdPPSCount, 
h265_add->pStdPPSs);
+   return result;
+}
 #endif
 
 static VkResult
@@ -437,6 +538,11 @@ vk_video_session_parameters_update(struct 
vk_video_session_parameters *params,
         vk_find_struct_const(update->pNext, 
VIDEO_ENCODE_H264_SESSION_PARAMETERS_ADD_INFO_EXT);
       return update_h264_enc_session_parameters(params, h264_add);
    }
+   case VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_EXT: {
+      const struct VkVideoEncodeH265SessionParametersAddInfoEXT *h265_add =
+        vk_find_struct_const(update->pNext, 
VIDEO_ENCODE_H265_SESSION_PARAMETERS_ADD_INFO_EXT);
+      return update_h265_enc_session_parameters(params, h265_add);
+   }
 #endif
    default:
       unreachable("Unknown codec\n");
@@ -1120,7 +1226,11 @@ vk_video_get_profile_alignments(const 
VkVideoProfileListInfoKHR *profile_list,
          width_align = MAX2(width_align, VK_VIDEO_H264_MACROBLOCK_WIDTH);
          height_align = MAX2(height_align, VK_VIDEO_H264_MACROBLOCK_HEIGHT);
       }
-      if (profile_list->pProfiles[i].videoCodecOperation == 
VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR) {
+      if (profile_list->pProfiles[i].videoCodecOperation == 
VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+          || profile_list->pProfiles[i].videoCodecOperation == 
VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_EXT
+#endif
+         ) {
          width_align = MAX2(width_align, VK_VIDEO_H265_CTU_MAX_WIDTH);
          height_align = MAX2(height_align, VK_VIDEO_H265_CTU_MAX_HEIGHT);
       }
@@ -1143,4 +1253,25 @@ vk_video_find_h264_enc_std_pps(const struct 
vk_video_session_parameters *params,
 {
    return find_h264_enc_std_pps(params, id);
 }
+
+const StdVideoH265VideoParameterSet *
+vk_video_find_h265_enc_std_vps(const struct vk_video_session_parameters 
*params,
+                               uint32_t id)
+{
+   return find_h265_enc_std_vps(params, id);
+}
+
+const StdVideoH265SequenceParameterSet *
+vk_video_find_h265_enc_std_sps(const struct vk_video_session_parameters 
*params,
+                               uint32_t id)
+{
+   return find_h265_enc_std_sps(params, id);
+}
+
+const StdVideoH265PictureParameterSet *
+vk_video_find_h265_enc_std_pps(const struct vk_video_session_parameters 
*params,
+                               uint32_t id)
+{
+   return find_h265_enc_std_pps(params, id);
+}
 #endif
diff --git a/src/vulkan/runtime/vk_video.h b/src/vulkan/runtime/vk_video.h
index 1a24990fdac..3f961360e05 100644
--- a/src/vulkan/runtime/vk_video.h
+++ b/src/vulkan/runtime/vk_video.h
@@ -92,6 +92,19 @@ struct vk_video_session_parameters {
          uint32_t std_pps_count;
          StdVideoH264PictureParameterSet *std_pps;
       } h264_enc;
+
+      struct {
+         uint32_t max_std_vps_count;
+         uint32_t max_std_sps_count;
+         uint32_t max_std_pps_count;
+
+         uint32_t std_vps_count;
+         StdVideoH265VideoParameterSet *std_vps;
+         uint32_t std_sps_count;
+         StdVideoH265SequenceParameterSet *std_sps;
+         uint32_t std_pps_count;
+         StdVideoH265PictureParameterSet *std_pps;
+      } h265_enc;
 #endif
    };
 };
@@ -225,6 +238,16 @@ vk_video_find_h264_enc_std_sps(const struct 
vk_video_session_parameters *params,
 const StdVideoH264PictureParameterSet *
 vk_video_find_h264_enc_std_pps(const struct vk_video_session_parameters 
*params,
                                uint32_t id);
+
+const StdVideoH265VideoParameterSet *
+vk_video_find_h265_enc_std_vps(const struct vk_video_session_parameters 
*params,
+                               uint32_t id);
+const StdVideoH265SequenceParameterSet *
+vk_video_find_h265_enc_std_sps(const struct vk_video_session_parameters 
*params,
+                               uint32_t id);
+const StdVideoH265PictureParameterSet *
+vk_video_find_h265_enc_std_pps(const struct vk_video_session_parameters 
*params,
+                               uint32_t id);
 #endif
 
 #ifdef __cplusplus

Reply via email to