PR #24970 opened by Kilian (lusoris) URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24970 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24970.patch
On a device with a single queue family, the first barrier on each Vulkan frame becomes an ownership transfer to `VK_QUEUE_FAMILY_IGNORED`, which `VUID-VkImageMemoryBarrier2-image-09118` forbids for an exclusive image. This patch keeps the frame's owning family as the destination in that case, so the barrier performs no transfer. hwcontext_vulkan tracks single-family frames under the real family index, while every filter and codec caller of `ff_vk_frame_barrier()` passes `VK_QUEUE_FAMILY_IGNORED` as the new family. The Khronos validation layer does not flag the barrier itself (reported as https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/13405). Instead, it records a release that is never acquired and reports every later use of the image against the stale layout. Tested on master 538d10d187 with Mesa lavapipe and validation layer 1.4.363, `testsrc2` through `hwupload,<filter>,hwdownload`, 5 frames (rebased onto 7bc3576910 without conflicts; `libavutil/vulkan.o` builds): | Filter | Before | After | | --- | --- | --- | | `gblur_vulkan` | 10 x 09064, 10 x 09059 | none | | `scdet_vulkan` | 10 x 09064, 9 x 09059 | none | A downstream filter whose shader indexes the image array with a literal additionally reports `VUID-vkCmdDispatch-imageLayout-00344` and `VUID-vkCmdDraw-None-09600` before the change; both go to zero with it (checked on the n9.0.2 base). Multi-family devices are unaffected because their frames are `CONCURRENT` and tracked as `IGNORED`. Intel ANV, RADV and the NVIDIA proprietary driver report the same validation output with and without the patch (checked on the n9.0.2 base). `make fate-source` passes. >From 6f8c1d126c56097cfbe97711150eb3e0f19c6a0e Mon Sep 17 00:00:00 2001 From: lusoris <[email protected]> Date: Fri, 9 Oct 2026 02:54:28 +0200 Subject: [PATCH] avutil/vulkan: don't release frames to VK_QUEUE_FAMILY_IGNORED On a device with a single queue family, hwcontext_vulkan creates frames with VK_SHARING_MODE_EXCLUSIVE and tracks them as owned by that family. ff_vk_frame_barrier() copies the tracked family into srcQueueFamilyIndex, while every filter and codec caller passes VK_QUEUE_FAMILY_IGNORED as the new family. The first barrier on such a frame therefore has unequal indices, which the specification treats as a queue family ownership transfer, and its destination is VK_QUEUE_FAMILY_IGNORED, which an exclusive image does not allow (VUID-VkImageMemoryBarrier2-image-09118). The Khronos validation layer accepts the barrier but records it as a release that is never acquired. It does not apply the layout transition and reports every later use of the image against the old layout: VUID-vkCmdDispatch-imageLayout-00344 and VUID-vkCmdDraw-None-09600 for shaders that access the image, and VUID-VkCopyMemoryToImageInfo-dstImageLayout-09059 and VUID-VkCopyImageToMemoryInfo-srcImageLayout-09064 for the host image copies in hwupload and hwdownload. When the caller passes VK_QUEUE_FAMILY_IGNORED and the frame is owned by a concrete queue family, keep that family as the destination. Equal indices perform no transfer, and the tracked owner stays the family that hwcontext_vulkan uses for its own transitions on such devices. Frames on devices with several queue families are tracked as VK_QUEUE_FAMILY_IGNORED and are unaffected, as are frames owned by the external or foreign queue family. Tested with Mesa lavapipe, which has one queue family, and validation layer 1.4.363: gblur_vulkan and scdet_vulkan between hwupload and hwdownload no longer report the four layout errors. Intel ANV, RADV and the NVIDIA proprietary driver report the same messages as before. The validation layer gap is reported as https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/13405. Signed-off-by: lusoris <[email protected]> --- libavutil/vulkan.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/libavutil/vulkan.c b/libavutil/vulkan.c index 3987c33080..7b9c173540 100644 --- a/libavutil/vulkan.c +++ b/libavutil/vulkan.c @@ -2224,6 +2224,7 @@ void ff_vk_frame_barrier(FFVulkanContext *s, FFVkExecContext *e, uint32_t new_qf) { int found = -1; + uint32_t src_qf, dst_qf = new_qf; AVVkFrame *vkf = (AVVkFrame *)pic->data[0]; const int nb_images = ff_vk_count_images(vkf); for (int i = 0; i < e->nb_frame_deps; i++) @@ -2233,6 +2234,21 @@ void ff_vk_frame_barrier(FFVulkanContext *s, FFVkExecContext *e, break; } + src_qf = found >= 0 ? e->queue_family_dst[found] : vkf->queue_family[0]; + + /* Unequal queue family indices define a queue family ownership transfer, + * and an exclusive image can only be transferred to a queue family that + * exists (or to the external or foreign one), never to + * VK_QUEUE_FAMILY_IGNORED (VUID-VkImageMemoryBarrier2-image-09118). + * Frames on a device with a single queue family are tracked as owned by + * that family, so a caller that asks for no particular family keeps the + * current owner: equal indices mean no transfer. */ + if (new_qf == VK_QUEUE_FAMILY_IGNORED && + src_qf != VK_QUEUE_FAMILY_IGNORED && + src_qf != VK_QUEUE_FAMILY_EXTERNAL && + src_qf != VK_QUEUE_FAMILY_FOREIGN_EXT) + dst_qf = src_qf; + /* Earlier submissions are ordered by the frame's semaphore, which makes * their writes available and visible, so only accesses recorded in this * command buffer belong in the source scope. */ @@ -2246,8 +2262,8 @@ void ff_vk_frame_barrier(FFVulkanContext *s, FFVkExecContext *e, .dstAccessMask = new_access, .oldLayout = found >= 0 ? e->layout_dst[found] : vkf->layout[0], .newLayout = new_layout, - .srcQueueFamilyIndex = found >= 0 ? e->queue_family_dst[found] : vkf->queue_family[0], - .dstQueueFamilyIndex = new_qf, + .srcQueueFamilyIndex = src_qf, + .dstQueueFamilyIndex = dst_qf, .image = vkf->img[i], .subresourceRange = (VkImageSubresourceRange) { .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
