stride3d/stride · error · InvalidOperationException

Software rendering requested but no CPU Vulkan device…

Error message

Software rendering requested but no CPU Vulkan device (Lavapipe) found

What it means

PickPhysicalDevice throws this when softwareRendering was requested but the best-scoring device is not a CPU device (score < 3 means no Lavapipe/CPU device was found). The harness explicitly asked for software rendering — e.g. for deterministic CI behavior — and the environment cannot satisfy it.

Solutions

  1. Install Lavapipe (mesa-vulkan-drivers on Linux) so a CPU Vulkan device exists
  2. Ensure the Lavapipe .icd.json is listed in VK_ICD_FILENAMES/VK_DRIVER_FILES and is being loaded
  3. Disable softwareRendering to allow using the real GPU device instead
  4. Verify with vulkaninfo that a device with type CPU appears

Example fix

// before
var ok = FrameRenderer.TryRender(softwareRendering: true);
// after
if (!FrameRenderer.CpuDeviceAvailable)
{
    Assert.Skip("Lavapipe not installed; cannot force software rendering");
    return;
}
var ok = FrameRenderer.TryRender(softwareRendering: true);
Defensive patterns

Strategy: fallback

Validate before calling

bool CpuDeviceAvailable(VkPhysicalDevice d) { api.vkGetPhysicalDeviceProperties(d, out var p); return p.DeviceType == VkPhysicalDeviceType.Cpu; }

Try / catch

try { EnsureSharedContext(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("Lavapipe"))
{
    Assert.Skip("Software rendering requested but no CPU Vulkan device");
}

Prevention

When it happens

Trigger: Calling the FrameRenderer with softwareRendering = true while only GPU devices (or no usable devices) are present; forcing the software path via env/flag on a machine with only hardware ICDs.

Common situations: CI configured for Lavapipe but mesa-vulkan-drivers not installed; a GPU is present so the harness finds it but software mode demands a CPU device; mixed environments where Lavapipe ICD json is missing from VK_ICD_FILENAMES.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/b76fe5752f466cbb. Report an issue: GitHub.

Appendix: source

Thrown at sources/shaders/Stride.Shaders.Tests/FrameRenderer.Vulkan.cs:178

            var isCpu = properties.deviceType == VkPhysicalDeviceType.Cpu;
            var score = softwareRendering
                ? (isCpu ? 3 : 0)
                : properties.deviceType switch
                {
                    VkPhysicalDeviceType.DiscreteGpu => 3,
                    VkPhysicalDeviceType.IntegratedGpu => 2,
                    _ => 1,
                };
            if (score > bestScore)
            {
                bestScore = score;
                best = i;
            }
        }
        if (best < 0)
            throw new InvalidOperationException("No Vulkan 1.2+ physical device");
        if (softwareRendering && bestScore < 3)
            throw new InvalidOperationException("Software rendering requested but no CPU Vulkan device (Lavapipe) found");
        physicalDevice = devices[best];
    }

    private static void CreateDevice()
    {
        uint familyCount = 0;
        instanceApi.vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &familyCount, null);
        var families = new VkQueueFamilyProperties[familyCount];
        fixed (VkQueueFamilyProperties* familiesPtr = families)
            instanceApi.vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &familyCount, familiesPtr);
        queueFamily = uint.MaxValue;
        for (uint i = 0; i < familyCount; i++)
        {
            if ((families[i].queueFlags & (VkQueueFlags.Graphics | VkQueueFlags.Compute)) == (VkQueueFlags.Graphics | VkQueueFlags.Compute))
            {
                queueFamily = i;
                break;
            }

View on GitHub (pinned to 96fad776d2)