diff --git a/libavutil/hwcontext_vulkan.c b/libavutil/hwcontext_vulkan.c index dc9d49ccb4..1c298a0b18 100644 --- a/libavutil/hwcontext_vulkan.c +++ b/libavutil/hwcontext_vulkan.c @@ -1418,6 +1418,13 @@ static int setup_queue_families(AVHWDeviceContext *ctx, VkDeviceCreateInfo *cd) VulkanDevicePriv *p = ctx->hwctx; AVVulkanDeviceContext *hwctx = &p->p; FFVulkanFunctions *vk = &p->vkctx.vkfn; + VkPhysicalDeviceDriverProperties dprops = { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES, + }; + VkPhysicalDeviceProperties2 props2 = { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2, + .pNext = &dprops, + }; VkQueueFamilyProperties2 *qf = NULL; VkQueueFamilyVideoPropertiesKHR *qf_vid = NULL; @@ -1471,7 +1478,14 @@ static int setup_queue_families(AVHWDeviceContext *ctx, VkDeviceCreateInfo *cd) hwctx->nb_qf = 0; - /* Pick each queue family to use */ + /* NVIDIA's proprietary drivers have stupid limits, where each queue + * you allocate takes tens of milliseconds, and the more queues you + * allocate, the less you'll have left before initializing a device + * simply fails (112 seems to be the max). GLOBALLY. + * Detect this, and minimize using queues as much as possible. */ + vk->GetPhysicalDeviceProperties2(hwctx->phys_dev, &props2); + + /* Pick each queue family to use. */ #define PICK_QF(type, vid_op) \ do { \ uint32_t i; \ @@ -1495,6 +1509,10 @@ static int setup_queue_families(AVHWDeviceContext *ctx, VkDeviceCreateInfo *cd) if (i == hwctx->nb_qf) { \ hwctx->qf[i].idx = idx; \ hwctx->qf[i].num = qf[idx].queueFamilyProperties.queueCount; \ + if (dprops.driverID == VK_DRIVER_ID_NVIDIA_PROPRIETARY) { \ + if (type == VK_QUEUE_GRAPHICS_BIT) \ + hwctx->qf[i].num = FFMIN(hwctx->qf[i].num, 1); \ + } \ hwctx->qf[i].flags = type; \ hwctx->qf[i].video_caps = vid_op; \ hwctx->nb_qf++; \