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
934934 VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR |
935935 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
936936 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;
937941 }
938942
939943 /* 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
10231027 AVVulkanFramesContext *hwfc = frames_ctx->hwctx;
10241028 FFVulkanDecodeContext *dec = avctx->internal->hwaccel_priv_data;
10251029 FFVulkanDecodeProfileData *prof;
1030+ FFVulkanDecodeShared *ctx;
10261031
10271032 frames_ctx->sw_format = AV_PIX_FMT_NONE;
10281033
@@ -1059,6 +1064,11 @@ int ff_vk_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx) · 30 unmodified lines
10591064 if (!dec->dedicated_dpb)
10601065 hwfc->usage |= VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR;
10611066
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+
10621072 return err;
10631073 }
10641074
libavfilter/vulkan_filter.c+29−12
@@ -37,6 +37,7 @@ int ff_vk_filter_init_context(AVFilterContext *avctx, FFVulkanContext *s, · 36 unmodified lines
3737 if (frames_ref) {
3838 int no_storage = 0;
3939 FFVulkanFunctions *vk;
40+ VkImageUsageFlagBits usage_req;
4041 const VkFormat *sub = av_vkfmt_from_pixfmt(sw_format);
4142
4243 frames_ctx = (AVHWFramesContext *)frames_ref->data;
@@ -57,18 +58,41 @@ int ff_vk_filter_init_context(AVFilterContext *avctx, FFVulkanContext *s, · 14 unmodified lines
5758 if (vk_frames->tiling != VK_IMAGE_TILING_OPTIMAL)
5859 goto skip;
5960
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−
6561 s->extensions = ff_vk_extensions_to_mask(vk_dev->enabled_dev_extensions,
6662 vk_dev->nb_enabled_dev_extensions);
63+
64+ /* More advanced format checks */
6765 err = ff_vk_load_functions(device_ctx, &s->vkfn, s->extensions, 1, 1);
6866 if (err < 0)
6967 return err;
7068 vk = &s->vkfn;
7169
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+
7296 /* Check if the subformats can do storage */
7397 for (int i = 0; sub[i] != VK_FORMAT_UNDEFINED; i++) {
7498 VkFormatProperties2 prop = {
@@ -113,13 +137,6 @@ skip: · 38 unmodified lines
113137 frames_ctx->width = width;
114138 frames_ctx->height = height;
115139
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−
123140 err = av_hwframe_ctx_init(frames_ref);
124141 if (err < 0) {
125142 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
26322632 VK_BUFFER_USAGE_TRANSFER_SRC_BIT |
26332633 VK_IMAGE_USAGE_STORAGE_BIT |
26342634 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;
26352641 }
26362642
26372643 /* Image creation flags.
@@ -2650,6 +2656,28 @@ static int vulkan_frames_init(AVHWFramesContext *hwfc) · 12 unmodified lines
26502656 }
26512657 }
26522658
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+
26532681 if (!hwctx->lock_frame)
26542682 hwctx->lock_frame = lock_frame;
26552683

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