{"record":{"id":"4762637449ffc25b","repo":"stride3d/stride","slug":"no-graphics-compute-queue-family","errorCode":null,"errorMessage":"No graphics+compute queue family","messagePattern":"No graphics\\+compute queue family","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"critical","filePath":"sources/shaders/Stride.Shaders.Tests/FrameRenderer.Vulkan.cs","lineNumber":199,"sourceCode":"\n    private static void CreateDevice()\n    {\n        uint familyCount = 0;\n        instanceApi.vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &familyCount, null);\n        var families = new VkQueueFamilyProperties[familyCount];\n        fixed (VkQueueFamilyProperties* familiesPtr = families)\n            instanceApi.vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &familyCount, familiesPtr);\n        queueFamily = uint.MaxValue;\n        for (uint i = 0; i < familyCount; i++)\n        {\n            if ((families[i].queueFlags & (VkQueueFlags.Graphics | VkQueueFlags.Compute)) == (VkQueueFlags.Graphics | VkQueueFlags.Compute))\n            {\n                queueFamily = i;\n                break;\n            }\n        }\n        if (queueFamily == uint.MaxValue)\n            throw new InvalidOperationException(\"No graphics+compute queue family\");\n\n        // The bytecode keeps UserSemantic decorations (SPV_GOOGLE_hlsl_functionality1);\n        // enable the matching extension where the driver wants it declared.\n        uint extensionCount = 0;\n        Check(instanceApi.vkEnumerateDeviceExtensionProperties(physicalDevice, null, &extensionCount, null));\n        var extensions = new VkExtensionProperties[extensionCount];\n        fixed (VkExtensionProperties* extensionsPtr = extensions)\n            Check(instanceApi.vkEnumerateDeviceExtensionProperties(physicalDevice, null, &extensionCount, extensionsPtr));\n        var availableExtensions = new HashSet<string>();\n        for (int i = 0; i < extensions.Length; i++)\n        {\n            fixed (VkExtensionProperties* extensionPtr = &extensions[i])\n                availableExtensions.Add(Marshal.PtrToStringUTF8((nint)extensionPtr->extensionName));\n        }\n        var enabledExtensions = new List<string>();\n        foreach (var wanted in new[] { \"VK_GOOGLE_hlsl_functionality1\", \"VK_GOOGLE_user_type\" })\n        {\n            if (availableExtensions.Contains(wanted))","sourceCodeStart":181,"sourceCodeEnd":217,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/shaders/Stride.Shaders.Tests/FrameRenderer.Vulkan.cs#L181-L217","documentation":"Thrown by CreateDevice during Vulkan physical-device setup when no queue family supports both graphics and compute operations. The renderer requires a single queue family capable of both (it probes vkGetPhysicalDeviceQueueFamilyProperties for combined GRAPHICS|COMPUTE flag bits) and refuses to create a logical device without one. This keeps the pipeline simple by avoiding separate graphics and compute queues.","triggerScenarios":"Calling EnsureSharedContext/CreateDevice on a device whose vkGetPhysicalDeviceQueueFamilyProperties returns no family with both VK_QUEUE_GRAPHICS_BIT and VK_QUEUE_COMPUTE_BIT set, so the loop ends with queueFamily still == uint.MaxValue.","commonSituations":"Running on a compute-only device (e.g. a headless NVIDIA compute GPU, Intel Xe compute-only iGPU) or a minimal display-only device; picking the wrong physicalDevice among multiple devices in a multi-GPU system; running in an emulator or software rasterizer (llvmpipe variants) that exposes no compute support.","solutions":["Select a different physicalDevice that exposes a graphics+compute queue family (iterate vkEnumeratePhysicalDevices and probe each one's queue families before creating the device).","If separate families must be used, extend the probe to allow graphics-only and compute-only families and create two queues instead of one combined queue.","Verify with vkinfo/vulkaninfo that the intended device actually has a queue family with both GRAPHICS and COMPUTE caps; update drivers if a capable device exists but reports none."],"exampleFix":"// before\nvar physicalDevice = physicalDevices.First();\nCreateDevice(physicalDevice);\n// after\nvar physicalDevice = physicalDevices.FirstOrDefault(CapableOfGraphicsCompute)\n    ?? throw new InvalidOperationException(\"No device with graphics+compute queue family\");\nCreateDevice(physicalDevice);\n\nstatic bool CapableOfGraphicsCompute(PhysicalDevice d) { /* probe queue families */ }","handlingStrategy":"validation","validationCode":"uint FindGraphicsComputeFamily(PhysicalDevice physical, GetQueueFamilyPropertiesFn getProps)\n{\n    getProps(physical, out uint count, null);\n    var fams = new VkQueueFamilyProperties[count];\n    getProps(physical, out _, fams);\n    for (uint i = 0; i < count; i++)\n        if ((fams[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) != 0 && (fams[i].queueFlags & VK_QUEUE_COMPUTE_BIT) != 0)\n            return i;\n    return uint.MaxValue; // check before CreateDevice and pick another physical device\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Probe every physical device's queue families during device selection, not just the first one.","Run vulkaninfo in CI to assert test machines expose a graphics+compute-capable device.","Prefer devices known to support compute (discrete GPUs, modern iGPUs) for the test harness."],"tags":["vulkan","gpu","device-initialization"],"backgroundTag":"unsupported-operation","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}