[FFmpeg-devel] [PATCH] avutil/hwcontext_vulkan: disable host transfers if ReBAR is disabled

Lynne dev at lynne.ee
Fri Jun 20 19:30:39 EEST 2025


On 20/06/2025 21:43, Niklas Haas wrote:
> From: Niklas Haas <git at haasn.dev>
> 
> This feature fundamentally relies on host-visible VRAM, which restricts the
> set of available memory types to (typically) host-visible device-local ones.
> 
> When resizable BAR is disabled, this memory type is usually limited to
> e.g. 256 MiB in size, which is just plain insufficient for allocation of
> general purpose GPU images, causing OOM errors on even the simplest of
> commands.
> 
> The easiest solution is to disable host transfers entirely on machines
> without host-addressable VRAM. In theory, we could try and recover the use
> of host transfers for images which are *not* restricted to device-local
> memory types, but this is rarely the case in practice, and the effort
> required would exceed the benefit, especially since ReBAR is a standard
> feature on all platforms recent enough to have Vulkan drivers, and only
> occasionally disabled in the UEFI for by default for some hare-brained
> notion of "backwards compatibiility" with ancient software.
> ---
>   libavutil/hwcontext_vulkan.c | 25 +++++++++++++++++++++----
>   1 file changed, 21 insertions(+), 4 deletions(-)
> 
> diff --git a/libavutil/hwcontext_vulkan.c b/libavutil/hwcontext_vulkan.c
> index edff89af26..b0a765e370 100644
> --- a/libavutil/hwcontext_vulkan.c
> +++ b/libavutil/hwcontext_vulkan.c
> @@ -144,6 +144,9 @@ typedef struct VulkanDevicePriv {
>       /* Disable multiplane images */
>       int disable_multiplane;
>   
> +    /* Disable host image transfer */
> +    int disable_host_transfer;
> +
>       /* Maximum queues */
>       int limit_queues;
>   
> @@ -1694,6 +1697,23 @@ static int vulkan_device_create_internal(AVHWDeviceContext *ctx,
>           goto end;
>       }
>   
> +    /* Get device memory properties */
> +    vk->GetPhysicalDeviceMemoryProperties(hwctx->phys_dev, &p->mprops);
> +    VkDeviceSize max_vram = 0, max_visible_vram = 0;
> +    for (int i = 0; i < p->mprops.memoryTypeCount; i++) {
> +        const VkMemoryType type = p->mprops.memoryTypes[i];
> +        const VkMemoryHeap heap = p->mprops.memoryHeaps[type.heapIndex];
> +        if (!(type.propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT))
> +            continue;
> +        max_vram = FFMAX(max_vram, heap.size);
> +        if (type.propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
> +            max_visible_vram = FFMAX(max_visible_vram, heap.size);
> +    }
> +
> +    /* Only use host image transfers if ReBAR is enabled */
> +    const int has_rebar = max_vram - max_visible_vram < 1024; /* 1 kB tolerance */
> +    p->disable_host_transfer = !has_rebar;
> +
>       /* Get all supported features for the physical device */
>       device_features_init(ctx, &supported_feats);
>       vk->GetPhysicalDeviceFeatures2(hwctx->phys_dev, &supported_feats.device);
> @@ -1990,9 +2010,6 @@ FF_ENABLE_DEPRECATION_WARNINGS
>       if (!hwctx->unlock_queue)
>           hwctx->unlock_queue = unlock_queue;
>   
> -    /* Get device capabilities */
> -    vk->GetPhysicalDeviceMemoryProperties(hwctx->phys_dev, &p->mprops);
> -
>       p->vkctx.device = ctx;
>       p->vkctx.hwctx = hwctx;
>   
> @@ -2835,7 +2852,7 @@ static int vulkan_frames_init(AVHWFramesContext *hwfc)
>                                             VK_IMAGE_USAGE_STORAGE_BIT      |
>                                             VK_IMAGE_USAGE_SAMPLED_BIT);
>   
> -        if (p->vkctx.extensions & FF_VK_EXT_HOST_IMAGE_COPY)
> +        if ((p->vkctx.extensions & FF_VK_EXT_HOST_IMAGE_COPY) && !p->disable_host_transfer)
>               hwctx->usage |= supported_usage & VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT;
>   
>           /* Enables encoding of images, if supported by format and extensions */

LGTM
Thanks


More information about the ffmpeg-devel mailing list