* [FFmpeg-devel] [PATCH] Miscellaneous Vulkan cleanups (PR #21323)
@ 2025-12-30 19:18 bcheng via ffmpeg-devel
0 siblings, 0 replies; only message in thread
From: bcheng via ffmpeg-devel @ 2025-12-30 19:18 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: bcheng
PR #21323 opened by bcheng
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/21323
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/21323.patch
Gets rid of some validation issues, and removes the useless ycbcr sampler entirely.
>From e41e21a1ec42a30f2d97a1a1c092797d4f9328b4 Mon Sep 17 00:00:00 2001
From: Benjamin Cheng <benjamin.cheng@amd.com>
Date: Tue, 30 Dec 2025 14:15:43 -0500
Subject: [PATCH 1/4] avutil/hwcontext_vulkan: Limit usages for lone DPBs
Lone DPBs will only be requested when the implementation requires
a separate DPB. These images are never given out, and are never used for
anything other than a DPB. Also most implementations requiring these
won't support any other usages on DPBs, so limiting the usages would fix
some validation errors.
---
libavutil/hwcontext_vulkan.c | 59 +++++++++++++++++++-----------------
1 file changed, 31 insertions(+), 28 deletions(-)
diff --git a/libavutil/hwcontext_vulkan.c b/libavutil/hwcontext_vulkan.c
index aa5f72e7f2..182eabceb0 100644
--- a/libavutil/hwcontext_vulkan.c
+++ b/libavutil/hwcontext_vulkan.c
@@ -2957,6 +2957,9 @@ static int vulkan_frames_init(AVHWFramesContext *hwfc)
const struct FFVkFormatEntry *fmt;
int disable_multiplane = p->disable_multiplane ||
(hwctx->flags & AV_VK_FRAME_FLAG_DISABLE_MULTIPLANE);
+ int is_lone_dpb = ((hwctx->usage & VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR) ||
+ ((hwctx->usage & VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR) &&
+ !(hwctx->usage & VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR)));
/* Defaults */
if (!hwctx->nb_layers)
@@ -3009,37 +3012,37 @@ static int vulkan_frames_init(AVHWFramesContext *hwfc)
return err;
}
- /* Image usage flags */
- hwctx->usage |= supported_usage & (VK_IMAGE_USAGE_TRANSFER_DST_BIT |
- VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
- VK_IMAGE_USAGE_STORAGE_BIT |
- VK_IMAGE_USAGE_SAMPLED_BIT);
+ /* Lone DPB images do not need additional flags. */
+ if (!is_lone_dpb) {
+ /* Image usage flags */
+ hwctx->usage |= supported_usage & (VK_IMAGE_USAGE_TRANSFER_DST_BIT |
+ VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
+ VK_IMAGE_USAGE_STORAGE_BIT |
+ VK_IMAGE_USAGE_SAMPLED_BIT);
- if (p->vkctx.extensions & FF_VK_EXT_HOST_IMAGE_COPY &&
- !(p->dprops.driverID == VK_DRIVER_ID_NVIDIA_PROPRIETARY) &&
- !(p->dprops.driverID == VK_DRIVER_ID_MOLTENVK))
- hwctx->usage |= supported_usage & VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT;
+ if (p->vkctx.extensions & FF_VK_EXT_HOST_IMAGE_COPY &&
+ !(p->dprops.driverID == VK_DRIVER_ID_NVIDIA_PROPRIETARY) &&
+ !(p->dprops.driverID == VK_DRIVER_ID_MOLTENVK))
+ hwctx->usage |= supported_usage & VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT;
- /* Enables encoding of images, if supported by format and extensions */
- if ((supported_usage & VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR) &&
- (p->vkctx.extensions & (FF_VK_EXT_VIDEO_ENCODE_QUEUE |
- FF_VK_EXT_VIDEO_MAINTENANCE_1)))
- hwctx->usage |= VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR;
+ /* Enables encoding of images, if supported by format and extensions */
+ if ((supported_usage & VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR) &&
+ (p->vkctx.extensions & (FF_VK_EXT_VIDEO_ENCODE_QUEUE |
+ FF_VK_EXT_VIDEO_MAINTENANCE_1)))
+ hwctx->usage |= VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR;
- /* Image creation flags.
- * Only fill them in automatically if the image is not going to be used as
- * a DPB-only image, and we have SAMPLED/STORAGE bits set. */
- if (!hwctx->img_flags) {
- int is_lone_dpb = ((hwctx->usage & VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR) ||
- ((hwctx->usage & VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR) &&
- !(hwctx->usage & VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR)));
- int sampleable = hwctx->usage & (VK_IMAGE_USAGE_SAMPLED_BIT |
- VK_IMAGE_USAGE_STORAGE_BIT);
- hwctx->img_flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
- if (sampleable && !is_lone_dpb) {
- hwctx->img_flags |= VK_IMAGE_CREATE_ALIAS_BIT;
- if ((fmt->vk_planes > 1) && (hwctx->format[0] == fmt->vkf))
- hwctx->img_flags |= VK_IMAGE_CREATE_EXTENDED_USAGE_BIT;
+ /* Image creation flags.
+ * Only fill them in automatically if the image is not going to be used as
+ * a DPB-only image, and we have SAMPLED/STORAGE bits set. */
+ if (!hwctx->img_flags) {
+ int sampleable = hwctx->usage & (VK_IMAGE_USAGE_SAMPLED_BIT |
+ VK_IMAGE_USAGE_STORAGE_BIT);
+ hwctx->img_flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
+ if (sampleable) {
+ hwctx->img_flags |= VK_IMAGE_CREATE_ALIAS_BIT;
+ if ((fmt->vk_planes > 1) && (hwctx->format[0] == fmt->vkf))
+ hwctx->img_flags |= VK_IMAGE_CREATE_EXTENDED_USAGE_BIT;
+ }
}
}
--
2.49.1
>From 24db09a881c9e0eb5b36dcf693c6ac17e9d56be8 Mon Sep 17 00:00:00 2001
From: Benjamin Cheng <benjamin.cheng@amd.com>
Date: Tue, 30 Dec 2025 11:47:46 -0500
Subject: [PATCH 2/4] lavc/vulkan_video: Restrict usages for image views
These image views are used only internally for video coding, so they do
not need all the usages of the image it's created from.
---
libavcodec/vulkan_decode.c | 8 +++++---
libavcodec/vulkan_encode.c | 6 +++---
libavcodec/vulkan_video.c | 9 ++++++++-
libavcodec/vulkan_video.h | 2 +-
4 files changed, 17 insertions(+), 8 deletions(-)
diff --git a/libavcodec/vulkan_decode.c b/libavcodec/vulkan_decode.c
index de786ad808..31ed14f517 100644
--- a/libavcodec/vulkan_decode.c
+++ b/libavcodec/vulkan_decode.c
@@ -217,7 +217,7 @@ int ff_vk_decode_prepare_frame(FFVulkanDecodeContext *dec, AVFrame *pic,
err = ff_vk_create_view(&ctx->s, &ctx->common,
&vkpic->view.ref[0], &vkpic->view.aspect_ref[0],
(AVVkFrame *)vkpic->dpb_frame->data[0],
- dpb_hwfc->format[0], !is_current);
+ dpb_hwfc->format[0], VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR);
if (err < 0)
return err;
@@ -231,7 +231,9 @@ int ff_vk_decode_prepare_frame(FFVulkanDecodeContext *dec, AVFrame *pic,
err = ff_vk_create_view(&ctx->s, &ctx->common,
&vkpic->view.out[0], &vkpic->view.aspect[0],
(AVVkFrame *)pic->data[0],
- hwfc->format[0], !is_current);
+ hwfc->format[0],
+ VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR |
+ (!is_current ? VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR : 0));
if (err < 0)
return err;
@@ -1404,7 +1406,7 @@ int ff_vk_decode_init(AVCodecContext *avctx)
&ctx->common.layered_view,
&ctx->common.layered_aspect,
(AVVkFrame *)ctx->common.layered_frame->data[0],
- s->hwfc->format[0], 1);
+ s->hwfc->format[0], VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR);
if (err < 0)
goto fail;
}
diff --git a/libavcodec/vulkan_encode.c b/libavcodec/vulkan_encode.c
index 7b534ffa30..c820b63666 100644
--- a/libavcodec/vulkan_encode.c
+++ b/libavcodec/vulkan_encode.c
@@ -71,7 +71,7 @@ static int vulkan_encode_init(AVCodecContext *avctx, FFHWBaseEncodePicture *pic)
/* Input image view */
err = ff_vk_create_view(&ctx->s, &ctx->common,
&vp->in.view, &vp->in.aspect,
- vkf, vkfc->format[0], 0);
+ vkf, vkfc->format[0], VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR);
if (err < 0)
return err;
@@ -81,7 +81,7 @@ static int vulkan_encode_init(AVCodecContext *avctx, FFHWBaseEncodePicture *pic)
AVVkFrame *rvkf = (AVVkFrame *)rf->data[0];
err = ff_vk_create_view(&ctx->s, &ctx->common,
&vp->dpb.view, &vp->dpb.aspect,
- rvkf, ctx->pic_format, 1);
+ rvkf, ctx->pic_format, VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR);
if (err < 0)
return err;
} else {
@@ -635,7 +635,7 @@ static int vulkan_encode_create_dpb(AVCodecContext *avctx, FFVulkanEncodeContext
&ctx->common.layered_view,
&ctx->common.layered_aspect,
(AVVkFrame *)ctx->common.layered_frame->data[0],
- hwfc->format[0], 1);
+ hwfc->format[0], VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR);
if (err < 0)
return err;
diff --git a/libavcodec/vulkan_video.c b/libavcodec/vulkan_video.c
index d73479d14d..8bc3e9b907 100644
--- a/libavcodec/vulkan_video.c
+++ b/libavcodec/vulkan_video.c
@@ -290,14 +290,21 @@ StdVideoAV1Profile ff_vk_av1_profile_to_vk(int profile)
int ff_vk_create_view(FFVulkanContext *s, FFVkVideoCommon *common,
VkImageView *view, VkImageAspectFlags *aspect,
- AVVkFrame *src, VkFormat vkf, int is_dpb)
+ AVVkFrame *src, VkFormat vkf, VkImageUsageFlags usage)
{
VkResult ret;
FFVulkanFunctions *vk = &s->vkfn;
VkImageAspectFlags aspect_mask = ff_vk_aspect_bits_from_vkfmt(vkf);
+ int is_dpb = usage & (VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR |
+ VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR);
+ VkImageViewUsageCreateInfo usage_create_info = {
+ .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO,
+ .usage = usage,
+ };
VkSamplerYcbcrConversionInfo yuv_sampler_info = {
.sType = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO,
+ .pNext = &usage_create_info,
.conversion = common->yuv_sampler,
};
VkImageViewCreateInfo img_view_create_info = {
diff --git a/libavcodec/vulkan_video.h b/libavcodec/vulkan_video.h
index 1b29f7adc7..14168b7cc8 100644
--- a/libavcodec/vulkan_video.h
+++ b/libavcodec/vulkan_video.h
@@ -85,7 +85,7 @@ StdVideoAV1Profile ff_vk_av1_profile_to_vk(int profile);
*/
int ff_vk_create_view(FFVulkanContext *s, FFVkVideoCommon *common,
VkImageView *view, VkImageAspectFlags *aspect,
- AVVkFrame *src, VkFormat vkf, int is_dpb);
+ AVVkFrame *src, VkFormat vkf, VkImageUsageFlags flags);
/**
* Initialize video session, allocating and binding necessary memory.
--
2.49.1
>From 2a0671f28ec67ce844bbeb9769ebb7967a9bdeb6 Mon Sep 17 00:00:00 2001
From: Benjamin Cheng <benjamin.cheng@amd.com>
Date: Tue, 30 Dec 2025 14:11:52 -0500
Subject: [PATCH 3/4] lavc/vulkan_video: Drop sampler
With the limiting of video usages on the image views, we no longer need
a yuv sampler, since no multi-plane image will be created with the
SAMPLED usage bit.
---
libavcodec/vulkan_decode.c | 3 +--
libavcodec/vulkan_video.c | 32 +-------------------------------
libavcodec/vulkan_video.h | 2 --
3 files changed, 2 insertions(+), 35 deletions(-)
diff --git a/libavcodec/vulkan_decode.c b/libavcodec/vulkan_decode.c
index 31ed14f517..eb76d5b052 100644
--- a/libavcodec/vulkan_decode.c
+++ b/libavcodec/vulkan_decode.c
@@ -1385,8 +1385,7 @@ int ff_vk_decode_init(AVCodecContext *avctx)
VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR);
dpb_hwfc->format[0] = s->hwfc->format[0];
dpb_hwfc->tiling = VK_IMAGE_TILING_OPTIMAL;
- dpb_hwfc->usage = VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR |
- VK_IMAGE_USAGE_SAMPLED_BIT; /* Shuts validator up. */
+ dpb_hwfc->usage = VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR;
if (ctx->common.layered_dpb)
dpb_hwfc->nb_layers = ctx->caps.maxDpbSlots;
diff --git a/libavcodec/vulkan_video.c b/libavcodec/vulkan_video.c
index 8bc3e9b907..9645a2de67 100644
--- a/libavcodec/vulkan_video.c
+++ b/libavcodec/vulkan_video.c
@@ -302,14 +302,9 @@ int ff_vk_create_view(FFVulkanContext *s, FFVkVideoCommon *common,
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO,
.usage = usage,
};
- VkSamplerYcbcrConversionInfo yuv_sampler_info = {
- .sType = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO,
- .pNext = &usage_create_info,
- .conversion = common->yuv_sampler,
- };
VkImageViewCreateInfo img_view_create_info = {
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
- .pNext = &yuv_sampler_info,
+ .pNext = &usage_create_info,
.viewType = common->layered_dpb && is_dpb ?
VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D,
.format = vkf,
@@ -365,12 +360,6 @@ av_cold void ff_vk_video_common_uninit(FFVulkanContext *s,
av_frame_free(&common->layered_frame);
av_buffer_unref(&common->dpb_hwfc_ref);
-
- if (common->yuv_sampler) {
- vk->DestroySamplerYcbcrConversion(s->hwctx->act_dev, common->yuv_sampler,
- s->hwctx->alloc);
- common->yuv_sampler = VK_NULL_HANDLE;
- }
}
av_cold int ff_vk_video_common_init(AVCodecContext *avctx, FFVulkanContext *s,
@@ -383,25 +372,6 @@ av_cold int ff_vk_video_common_init(AVCodecContext *avctx, FFVulkanContext *s,
VkVideoSessionMemoryRequirementsKHR *mem = NULL;
VkBindVideoSessionMemoryInfoKHR *bind_mem = NULL;
- int cxpos = 0, cypos = 0;
- VkSamplerYcbcrConversionCreateInfo yuv_sampler_info = {
- .sType = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO,
- .components = ff_comp_identity_map,
- .ycbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY,
- .ycbcrRange = avctx->color_range == AVCOL_RANGE_MPEG, /* Ignored */
- .format = session_create->pictureFormat,
- };
-
- /* Create identity YUV sampler
- * (VkImageViews of YUV image formats require it, even if it does nothing) */
- av_chroma_location_enum_to_pos(&cxpos, &cypos, avctx->chroma_sample_location);
- yuv_sampler_info.xChromaOffset = cxpos >> 7;
- yuv_sampler_info.yChromaOffset = cypos >> 7;
- ret = vk->CreateSamplerYcbcrConversion(s->hwctx->act_dev, &yuv_sampler_info,
- s->hwctx->alloc, &common->yuv_sampler);
- if (ret != VK_SUCCESS)
- return AVERROR_EXTERNAL;
-
/* Create session */
ret = vk->CreateVideoSessionKHR(s->hwctx->act_dev, session_create,
s->hwctx->alloc, &common->session);
diff --git a/libavcodec/vulkan_video.h b/libavcodec/vulkan_video.h
index 14168b7cc8..d63bfae3fc 100644
--- a/libavcodec/vulkan_video.h
+++ b/libavcodec/vulkan_video.h
@@ -34,8 +34,6 @@ typedef struct FFVkVideoSession {
VkDeviceMemory *mem;
uint32_t nb_mem;
- VkSamplerYcbcrConversion yuv_sampler;
-
AVBufferRef *dpb_hwfc_ref;
int layered_dpb;
AVFrame *layered_frame;
--
2.49.1
>From e27ba4f25978e8931d8e5475ada7ce701c99ba6a Mon Sep 17 00:00:00 2001
From: Benjamin Cheng <benjamin.cheng@amd.com>
Date: Tue, 30 Dec 2025 12:01:19 -0500
Subject: [PATCH 4/4] hwcontext_vulkan: Remove unnecessary validation filters
With the latest changes, I can no longer get these to show up.
---
libavutil/hwcontext_vulkan.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/libavutil/hwcontext_vulkan.c b/libavutil/hwcontext_vulkan.c
index 182eabceb0..2011cdec79 100644
--- a/libavutil/hwcontext_vulkan.c
+++ b/libavutil/hwcontext_vulkan.c
@@ -733,8 +733,6 @@ static VkBool32 VKAPI_CALL vk_dbg_callback(VkDebugUtilsMessageSeverityFlagBitsEX
switch (data->messageIdNumber) {
case 0x086974c1: /* BestPractices-vkCreateCommandPool-command-buffer-reset */
case 0xfd92477a: /* BestPractices-vkAllocateMemory-small-allocation */
- case 0x618ab1e7: /* VUID-VkImageViewCreateInfo-usage-02275 */
- case 0x30f4ac70: /* VUID-VkImageCreateInfo-pNext-06811 */
return VK_FALSE;
default:
break;
--
2.49.1
_______________________________________________
ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org
To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2025-12-30 19:19 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-12-30 19:18 [FFmpeg-devel] [PATCH] Miscellaneous Vulkan cleanups (PR #21323) bcheng via ffmpeg-devel
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
This inbox may be cloned and mirrored by anyone:
git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git
# If you have public-inbox 1.1+ installed, you may
# initialize and index your mirror using the following commands:
public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
ffmpegdev@gitmailbox.com
public-inbox-index ffmpegdev
Example config snippet for mirrors.
AGPL code for this site: git clone https://public-inbox.org/public-inbox.git