This is an automated email from the git hooks/post-receive script.

Git pushed a commit to branch master
in repository ffmpeg.

The following commit(s) were added to refs/heads/master by this push:
     new 48c613fbed avutil/hwcontext_vulkan: include export handle types in 
host transfer probe
48c613fbed is described below

commit 48c613fbed336a8920a42dda31553d1bdf3cb542
Author:     Kacper Michajłow <[email protected]>
AuthorDate: Wed Aug 19 16:06:33 2026 +0200
Commit:     Kacper Michajłow <[email protected]>
CommitDate: Mon Sep 7 02:34:56 2026 +0200

    avutil/hwcontext_vulkan: include export handle types in host transfer probe
    
    Probe with the same handle types the allocator will use, and require
    a memory type that satisfies the property flags alloc_bind_mem()
    requests instead of only checking for a non-empty mask. Also chain
    VkHostImageCopyDevicePerformanceQueryEXT and keep host transfers only
    when the driver reports optimal device access for the image.
    
    The previous probe was not enough, which was exposed by the blocklist
    removal enabling host transfers on NVIDIA. The same issue already
    existed on AMD, just that not many people test that target.
    
    Fixes: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23612#issuecomment-57871
    
    Signed-off-by: Kacper Michajłow <[email protected]>
---
 libavutil/hwcontext_vulkan.c | 78 ++++++++++++++++++++++++++++++++++----------
 1 file changed, 60 insertions(+), 18 deletions(-)

diff --git a/libavutil/hwcontext_vulkan.c b/libavutil/hwcontext_vulkan.c
index 2e0e526041..525c6a7ab9 100644
--- a/libavutil/hwcontext_vulkan.c
+++ b/libavutil/hwcontext_vulkan.c
@@ -2899,39 +2899,52 @@ static void try_export_flags(AVHWFramesContext *hwfc,
     }
 }
 
-static AVBufferRef *vulkan_pool_alloc(void *opaque, size_t size)
+/* Computes the external memory handle types for the frame context. */
+static void get_export_handle_types(AVHWFramesContext *hwfc,
+                                    VkExternalMemoryHandleTypeFlags 
*comp_handle_types,
+                                    VkExternalMemoryHandleTypeFlags 
*export_types)
 {
-    int err;
-    AVVkFrame *f;
-    AVBufferRef *avbuf = NULL;
-    AVHWFramesContext *hwfc = opaque;
     VulkanDevicePriv *p = hwfc->device_ctx->hwctx;
-    VulkanFramesPriv *fp = hwfc->hwctx;
-    AVVulkanFramesContext *hwctx = &fp->p;
-    VkExternalMemoryHandleTypeFlags e = 0x0;
-    VkExportMemoryAllocateInfo eminfo[AV_NUM_DATA_POINTERS];
+    av_unused AVVulkanFramesContext *hwctx = &((VulkanFramesPriv 
*)hwfc->hwctx)->p;
 
-    VkExternalMemoryImageCreateInfo eiinfo = {
-        .sType       = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
-        .pNext       = hwctx->create_pnext,
-    };
+    *comp_handle_types = 0x0;
+    *export_types = 0x0;
 
 #ifdef _WIN32
     if (p->vkctx.extensions & FF_VK_EXT_EXTERNAL_WIN32_MEMORY)
-        try_export_flags(hwfc, &eiinfo.handleTypes, &e, IsWindows8OrGreater()
+        try_export_flags(hwfc, comp_handle_types, export_types, 
IsWindows8OrGreater()
                              ? VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
                              : 
VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT);
 #else
     if ((p->vkctx.extensions & FF_VK_EXT_EXTERNAL_FD_MEMORY) &&
         (hwctx->tiling != VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT))
-        try_export_flags(hwfc, &eiinfo.handleTypes, &e,
+        try_export_flags(hwfc, comp_handle_types, export_types,
                          VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT);
 
     if (p->vkctx.extensions & FF_VK_EXT_EXTERNAL_DMABUF_MEMORY &&
         hwctx->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT)
-        try_export_flags(hwfc, &eiinfo.handleTypes, &e,
+        try_export_flags(hwfc, comp_handle_types, export_types,
                          VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT);
 #endif
+}
+
+static AVBufferRef *vulkan_pool_alloc(void *opaque, size_t size)
+{
+    int err;
+    AVVkFrame *f;
+    AVBufferRef *avbuf = NULL;
+    AVHWFramesContext *hwfc = opaque;
+    VulkanFramesPriv *fp = hwfc->hwctx;
+    AVVulkanFramesContext *hwctx = &fp->p;
+    VkExternalMemoryHandleTypeFlags e;
+    VkExportMemoryAllocateInfo eminfo[AV_NUM_DATA_POINTERS];
+
+    VkExternalMemoryImageCreateInfo eiinfo = {
+        .sType       = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
+        .pNext       = hwctx->create_pnext,
+    };
+
+    get_export_handle_types(hwfc, &eiinfo.handleTypes, &e);
 
     for (int i = 0; i < av_pix_fmt_count_planes(hwfc->sw_format); i++) {
         eminfo[i].sType       = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO;
@@ -3078,8 +3091,12 @@ static int vulkan_host_transfer_usable(AVHWFramesContext 
*hwfc)
         /* The driver is free to pick any modifier from the list, so all of
          * them have to be compatible. */
         for (int j = 0; j < nb_mods; j++) {
+            VkHostImageCopyDevicePerformanceQueryEXT perf = {
+                .sType = 
VK_STRUCTURE_TYPE_HOST_IMAGE_COPY_DEVICE_PERFORMANCE_QUERY_EXT,
+            };
             VkImageFormatProperties2 props = {
                 .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
+                .pNext = &perf,
             };
 
             if (has_mods)
@@ -3093,13 +3110,28 @@ static int 
vulkan_host_transfer_usable(AVHWFramesContext *hwfc)
                        pinfo.format, ff_vk_ret2str(ret));
                 return 0;
             }
+
+            if (!perf.optimalDeviceAccess) {
+                av_log(hwfc, AV_LOG_VERBOSE, "Disabling host image transfers: "
+                       "format %i has no optimal device access (identical "
+                       "memory layout: %i)\n",
+                       pinfo.format, perf.identicalMemoryLayout);
+                return 0;
+            }
         }
     }
 
     if (!p->vkctx.host_image_props.identicalMemoryTypeRequirements) {
+        int index;
+        VkExternalMemoryHandleTypeFlags e;
+        VkExternalMemoryImageCreateInfo eiinfo = {
+            .sType       = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
+            .pNext       = hwctx->create_pnext,
+        };
+        get_export_handle_types(hwfc, &eiinfo.handleTypes, &e);
         VkImageCreateInfo create_info = {
             .sType       = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
-            .pNext       = hwctx->create_pnext,
+            .pNext       = eiinfo.handleTypes ? &eiinfo : hwctx->create_pnext,
             .imageType   = VK_IMAGE_TYPE_2D,
             .format      = hwctx->format[0],
             .extent      = { hwfc->width, hwfc->height, 1 },
@@ -3125,7 +3157,17 @@ static int vulkan_host_transfer_usable(AVHWFramesContext 
*hwfc)
         };
 
         vk->GetDeviceImageMemoryRequirements(dev_hwctx->act_dev, &req_info, 
&req);
-        if (!req.memoryRequirements.memoryTypeBits) {
+        /* Check that alloc_bind_mem() will find a compatible memory type. */
+        VkMemoryPropertyFlags req_flags = hwctx->tiling == 
VK_IMAGE_TILING_LINEAR ?
+                                          VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT :
+                                          VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
+        for (index = 0; index < p->mprops.memoryTypeCount; index++) {
+            if (!(req.memoryRequirements.memoryTypeBits & (1U << index)))
+                continue;
+            if ((p->mprops.memoryTypes[index].propertyFlags & req_flags) == 
req_flags)
+                break;
+        }
+        if (index == p->mprops.memoryTypeCount) {
             av_log(hwfc, AV_LOG_VERBOSE, "Disabling host image transfers: "
                    "no compatible memory type\n");
             return 0;

-- 
To stop receiving notification emails like this one, please contact
[email protected].
_______________________________________________
ffmpeg-cvslog mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to