vulkan: vkGetDeviceQueue2 returns VK_NULL_HANDLE on older AMD drivers, first vkQueueSubmit aborts
What happens
Since the queue handle refactor (vulkan: Refactor vk_queue to use per-instance mutexes and unique handles, llama.cpp #23570, ggml commit 3ca9985), ggml_vk_create_queue fetches every queue through vkGetDeviceQueue2:
h->queue = device->device.getQueue2(queue_info2);Some older drivers return VK_NULL_HANDLE from vkGetDeviceQueue2 even for queues they created. The first vkQueueSubmit then fails and the process aborts:
ERROR: vkQueueSubmit: Invalid queue [VUID-vkQueueSubmit-queue-parameter](exit code 0xC0000409 on Windows). Present in v0.22.0 and on master as of 2026-08-30 (d471637). ggml 0.16 used getQueue and worked on the same machine.
Reproduction
AMD Ryzen 5 4500U with Radeon Graphics, Windows 11, AMD driver 27.20.11044.7 (Vulkan 1.2.133, driverVersion 0x800089). Loader 1.3.300.
A minimal program that creates a device with one compute queue (no flags) and fetches it both ways:
device "AMD Radeon(TM) Graphics" api 1.2.133 driver 0x800089
family 0: count 1 flags GRAPHICS | COMPUTE | TRANSFER | SPARSE_BINDING
family 1: count 2 flags COMPUTE | TRANSFER | SPARSE_BINDING
family 2: count 1 flags TRANSFER | SPARSE_BINDING
family 0: vkGetDeviceQueue -> 0x1f87fb67bc0 vkGetDeviceQueue2 -> 0x0
empty vkQueueSubmit on queue from vkGetDeviceQueue: SUCCESSAny ggml Vulkan workload on this machine (here a whisper large-v3-turbo encode) reproduces the abort; GGML_VK_VISIBLE_DEVICES=99 (CPU only) works.
Suggested fix
When has_internally_synchronized_queues is false the queue was created without flags, so vkGetDeviceQueue names the same queue. A null check is enough:
h->queue = device->device.getQueue2(queue_info2);
if (!h->queue) {
// Some older drivers (e.g. AMD 20.x on Windows, Vulkan 1.2.133) return a null
// handle from vkGetDeviceQueue2 even for queues they created.
h->queue = device->device.getQueue(queue_family_index, queue_index);
}We are shipping this as a local patch on top of v0.22.0 (vibe-transcribe/sona#50); the standalone test above shows vkGetDeviceQueue returns a working queue on that device, and I will report back once the patched build has run there. Happy to open a PR here or on llama.cpp, whichever you prefer.
Source: ggml-org/ggml