History

vulkan: enable encoding of images if video_maintenance1 is enabled

Vulkan encoding was designed in a very... consolidated way. You had to know the exact codec and profile that the image was going to eventually be encoded as at... image creation time. Unfortunately, as good as our code is, glimpsing into the exact future isn't what its capable of. video_maintenance1 removed that requirement, which only then made encoding images practically possible.

Lynne committed 2 years ago

Commit 18d964f1 parent 46c13833 files · +67 −12Browse files

Unified · Split

3 files
  1. libavcodec/vulkan_decode.c +10 −0
  2. libavfilter/vulkan_filter.c +29 −12
  3. libavutil/hwcontext_vulkan.c +28 −0
libavcodec/vulkan_decode.c+10−0
@@ -934,6 +934,10 @@ static int vulkan_decode_get_profile(AVCodecContext *avctx, AVBufferRef *frames_ · 933 unmodified lines
934 VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR |934 VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR |
935 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |935 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
936 VK_IMAGE_USAGE_SAMPLED_BIT;936 VK_IMAGE_USAGE_SAMPLED_BIT;
937
938 if (ctx->s.extensions & (FF_VK_EXT_VIDEO_ENCODE_QUEUE |
939 FF_VK_EXT_VIDEO_MAINTENANCE_1))
940 fmt_info.imageUsage |= VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR;
937 }941 }
938 942
939 /* Get the format of the images necessary */943 /* Get the format of the images necessary */
@@ -1023,6 +1027,7 @@ int ff_vk_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx) · 83 unmodified lines
1023 AVVulkanFramesContext *hwfc = frames_ctx->hwctx;1027 AVVulkanFramesContext *hwfc = frames_ctx->hwctx;
1024 FFVulkanDecodeContext *dec = avctx->internal->hwaccel_priv_data;1028 FFVulkanDecodeContext *dec = avctx->internal->hwaccel_priv_data;
1025 FFVulkanDecodeProfileData *prof;1029 FFVulkanDecodeProfileData *prof;
1030 FFVulkanDecodeShared *ctx;
1026 1031
1027 frames_ctx->sw_format = AV_PIX_FMT_NONE;1032 frames_ctx->sw_format = AV_PIX_FMT_NONE;
1028 1033
@@ -1059,6 +1064,11 @@ int ff_vk_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx) · 30 unmodified lines
1059 if (!dec->dedicated_dpb)1064 if (!dec->dedicated_dpb)
1060 hwfc->usage |= VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR;1065 hwfc->usage |= VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR;
1061 1066
1067 ctx = dec->shared_ctx;
1068 if (ctx->s.extensions & (FF_VK_EXT_VIDEO_ENCODE_QUEUE |
1069 FF_VK_EXT_VIDEO_MAINTENANCE_1))
1070 hwfc->usage |= VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR;
1071
1062 return err;1072 return err;
1063}1073}
1064 1074
libavfilter/vulkan_filter.c+29−12
@@ -37,6 +37,7 @@ int ff_vk_filter_init_context(AVFilterContext *avctx, FFVulkanContext *s, · 36 unmodified lines
37 if (frames_ref) {37 if (frames_ref) {
38 int no_storage = 0;38 int no_storage = 0;
39 FFVulkanFunctions *vk;39 FFVulkanFunctions *vk;
40 VkImageUsageFlagBits usage_req;
40 const VkFormat *sub = av_vkfmt_from_pixfmt(sw_format);41 const VkFormat *sub = av_vkfmt_from_pixfmt(sw_format);
41 42
42 frames_ctx = (AVHWFramesContext *)frames_ref->data;43 frames_ctx = (AVHWFramesContext *)frames_ref->data;
@@ -57,18 +58,41 @@ int ff_vk_filter_init_context(AVFilterContext *avctx, FFVulkanContext *s, · 14 unmodified lines
57 if (vk_frames->tiling != VK_IMAGE_TILING_OPTIMAL)58 if (vk_frames->tiling != VK_IMAGE_TILING_OPTIMAL)
58 goto skip;59 goto skip;
59 60
60 /* Usage mismatch */
61 if ((vk_frames->usage & (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT)) !=
62 (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT))
63 goto skip;
64
65 s->extensions = ff_vk_extensions_to_mask(vk_dev->enabled_dev_extensions,61 s->extensions = ff_vk_extensions_to_mask(vk_dev->enabled_dev_extensions,
66 vk_dev->nb_enabled_dev_extensions);62 vk_dev->nb_enabled_dev_extensions);
63
64 /* More advanced format checks */
67 err = ff_vk_load_functions(device_ctx, &s->vkfn, s->extensions, 1, 1);65 err = ff_vk_load_functions(device_ctx, &s->vkfn, s->extensions, 1, 1);
68 if (err < 0)66 if (err < 0)
69 return err;67 return err;
70 vk = &s->vkfn;68 vk = &s->vkfn;
71 69
70 /* Usage mismatch */
71 usage_req = VK_IMAGE_USAGE_SAMPLED_BIT |
72 VK_IMAGE_USAGE_STORAGE_BIT;
73
74 /* If format supports hardware encoding, make sure
75 * the context includes it. */
76 if (vk_frames->format[1] == VK_FORMAT_UNDEFINED &&
77 (s->extensions & (FF_VK_EXT_VIDEO_ENCODE_QUEUE |
78 FF_VK_EXT_VIDEO_MAINTENANCE_1))) {
79 VkFormatProperties3 fprops = {
80 .sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3,
81 };
82 VkFormatProperties2 prop = {
83 .sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2,
84 .pNext = &fprops,
85 };
86 vk->GetPhysicalDeviceFormatProperties2(vk_dev->phys_dev,
87 vk_frames->format[0],
88 &prop);
89 if (fprops.optimalTilingFeatures & VK_FORMAT_FEATURE_2_VIDEO_ENCODE_INPUT_BIT_KHR)
90 usage_req |= VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR;
91 }
92
93 if ((vk_frames->usage & usage_req) != usage_req)
94 goto skip;
95
72 /* Check if the subformats can do storage */96 /* Check if the subformats can do storage */
73 for (int i = 0; sub[i] != VK_FORMAT_UNDEFINED; i++) {97 for (int i = 0; sub[i] != VK_FORMAT_UNDEFINED; i++) {
74 VkFormatProperties2 prop = {98 VkFormatProperties2 prop = {
@@ -113,13 +137,6 @@ skip: · 38 unmodified lines
113 frames_ctx->width = width;137 frames_ctx->width = width;
114 frames_ctx->height = height;138 frames_ctx->height = height;
115 139
116 vk_frames = frames_ctx->hwctx;
117 vk_frames->tiling = VK_IMAGE_TILING_OPTIMAL;
118 vk_frames->usage = VK_IMAGE_USAGE_SAMPLED_BIT |
119 VK_IMAGE_USAGE_STORAGE_BIT |
120 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
121 VK_IMAGE_USAGE_TRANSFER_DST_BIT;
122
123 err = av_hwframe_ctx_init(frames_ref);140 err = av_hwframe_ctx_init(frames_ref);
124 if (err < 0) {141 if (err < 0) {
125 av_buffer_unref(&frames_ref);142 av_buffer_unref(&frames_ref);
libavutil/hwcontext_vulkan.c+28−0
@@ -2632,6 +2632,12 @@ static int vulkan_frames_init(AVHWFramesContext *hwfc) · 2631 unmodified lines
2632 VK_BUFFER_USAGE_TRANSFER_SRC_BIT |2632 VK_BUFFER_USAGE_TRANSFER_SRC_BIT |
2633 VK_IMAGE_USAGE_STORAGE_BIT |2633 VK_IMAGE_USAGE_STORAGE_BIT |
2634 VK_IMAGE_USAGE_SAMPLED_BIT);2634 VK_IMAGE_USAGE_SAMPLED_BIT);
2635
2636 /* Enables encoding of images, if supported by format and extensions */
2637 if ((supported_usage & VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR) &&
2638 (p->vkctx.extensions & (FF_VK_EXT_VIDEO_ENCODE_QUEUE |
2639 FF_VK_EXT_VIDEO_MAINTENANCE_1)))
2640 hwctx->usage |= VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR;
2635 }2641 }
2636 2642
2637 /* Image creation flags.2643 /* Image creation flags.
@@ -2650,6 +2656,28 @@ static int vulkan_frames_init(AVHWFramesContext *hwfc) · 12 unmodified lines
2650 }2656 }
2651 }2657 }
2652 2658
2659 /* If the image has an ENCODE_SRC usage, and the maintenance1
2660 * extension is supported, check if it has a profile list.
2661 * If there's no profile list, or it has no encode operations,
2662 * then allow creating the image with no specific profile. */
2663 if ((hwctx->usage & VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR) &&
2664 p->video_maint_1_features.videoMaintenance1) {
2665 const VkVideoProfileListInfoKHR *pl;
2666 pl = ff_vk_find_struct(hwctx->create_pnext, VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR);
2667 if (!pl) {
2668 hwctx->img_flags |= VK_IMAGE_CREATE_VIDEO_PROFILE_INDEPENDENT_BIT_KHR;
2669 } else {
2670 uint32_t i;
2671 for (i = 0; i < pl->profileCount; i++) {
2672 /* Video ops start at exactly 0x00010000 */
2673 if (pl->pProfiles[i].videoCodecOperation & 0xFFFF0000)
2674 break;
2675 }
2676 if (i == pl->profileCount)
2677 hwctx->img_flags |= VK_IMAGE_CREATE_VIDEO_PROFILE_INDEPENDENT_BIT_KHR;
2678 }
2679 }
2680
2653 if (!hwctx->lock_frame)2681 if (!hwctx->lock_frame)
2654 hwctx->lock_frame = lock_frame;2682 hwctx->lock_frame = lock_frame;
2655 2683

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t