Programming

Fix Vulkan macOS Crash with Silk.NET & MoltenVK

Resolve vkEnumeratePhysicalDevices crash in Silk.NET Vulkan on macOS with MoltenVK. Learn proper setup, extensions, and device enumeration for .NET 8.

1 answer 1 view

.NET 8 Silk.NET Vulkan Crash on macOS: EXC_BAD_ACCESS (SIGSEGV) in vkEnumeratePhysicalDevices with MoltenVK

I’m developing a .NET 8 application on macOS using Silk.NET Vulkan. After adding MoltenVK libraries to the output folder and implementing basic Vulkan code based on a YouTube tutorial, the app crashes during device enumeration.

Debugging shows the crash in MVKInstance::getPhysicalDevices within libvulkan.1.dylib. I suspect it’s due to using the MoltenVK binary instead of ‘original’ NVIDIA/AMD Vulkan libraries (typically for Linux/Windows). Is this the cause, and why?

Crash Report

Crashed Thread:        0  Dispatch queue: com.apple.main-thread

Exception Type:        EXC_BAD_ACCESS (SIGSEGV)
Exception Codes:       KERN_INVALID_ADDRESS at 0x0000000000000b10
...

Thread 0 Crashed::  Dispatch queue: com.apple.main-thread
0   libvulkan.1.dylib                      0x37b481b31 MVKInstance::getPhysicalDevices(unsigned int*, VkPhysicalDevice_T**) + 17
1   libvulkan.1.dylib                      0x37b4684fc vkEnumeratePhysicalDevices + 60
...

(Full stack trace indicates crash at vkEnumeratePhysicalDevices.)

Relevant Code

The crash occurs in selectDevice during EnumeratePhysicalDevices:

csharp
public unsafe class VulkanContext
{
    // ... fields ...

    private static VulkanContext selectDevice(VulkanContext ctx)
    {
        VulkanContext context = ctx;
        uint devicecount = 1;
        PhysicalDevice[] devices = new PhysicalDevice[1];
        ctx.nativeContext.EnumeratePhysicalDevices(ctx.intance, &devicecount, devices);
        // ... rest of method ...
    }

    // Full code including InitVulkanInstance, createLogicalDevice, etc., available above.
}

Key questions:

  • Is MoltenVK incompatible here, or is there a bug in the code (e.g., fixed devicecount=1 without prior enumeration)?
  • How to properly set up Silk.NET Vulkan on macOS with .NET 8?
  • Recommended fixes for physical device enumeration crash?

The vkEnumeratePhysicalDevices crash on macOS with Silk.NET Vulkan and MoltenVK happens because your code hardcodes devicecount to 1 and passes a fixed-size array without first querying the actual device count—this triggers invalid memory access in MVKInstance::getPhysicalDevices. MoltenVK isn’t the culprit; it’s fully compatible as macOS’s Vulkan-on-Metal translator, but requires proper extensions like VK_KHR_portability_subset and the classic two-step enumeration pattern. Fix it by calling vkEnumeratePhysicalDevices twice: once with a null array to get the count, then allocate and populate, plus tweak your instance creation for macOS portability.

Contents

Understanding the Vulkan macOS Crash

You’ve hit a classic Vulkan macOS snag: EXC_BAD_ACCESS (SIGSEGV) right in libvulkan.1.dylib during device enumeration. The stack trace points straight to MVKInstance::getPhysicalDevices, which screams memory violation at address 0x0000000000000b10. This isn’t random—it’s tied to how MoltenVK emulates Vulkan atop Metal on Apple hardware, where physical device reporting differs from native Linux/Windows setups.

Think about it: macOS lacks true Vulkan drivers from NVIDIA or AMD. Instead, MoltenVK steps in, presenting a single emulated device (your Mac’s GPU). But if your code assumes multiple devices or skips the count query, it dereferences junk memory. The Stack Overflow thread on this exact .NET 8 Silk.NET issue nails it: hardcoded arrays without prior enumeration cause the segfault every time.

Real-world example? Games like Dota 2 faced similar MoltenVK crashes on older macOS, fixed by proper config. Your YouTube tutorial likely skipped macOS quirks, assuming desktop Vulkan behavior.

The Root Cause: Bug in Physical Device Enumeration

Zoom into your selectDevice method:

csharp
uint devicecount = 1;
PhysicalDevice[] devices = new PhysicalDevice[1];
ctx.nativeContext.EnumeratePhysicalDevices(ctx.intance, &devicecount, devices);

Boom—devicecount = 1 is arbitrary. Vulkan’s vkEnumeratePhysicalDevices expects a two-pass dance:

  1. Pass null for the array to fetch the real count.
  2. Allocate based on that count.
  3. Call again to fill the array.

Your single call with a tiny, uninitialized array hits MoltenVK’s internals wrong, causing the SIGSEGV. The Elder Scrolls Online forums describe identical KERN_INVALID_ADDRESS errors from null derefs in queue/device ops.

This isn’t Silk.NET-specific; it’s pure Vulkan API misuse. Even native C++ Vulkan Guide tutorials trip on it on M1/M2 Macs, as seen in this Reddit Vulkan post.

Why MoltenVK Works Fine on macOS

MoltenVK translates Vulkan calls to Metal seamlessly—no incompatibility here. It emulates one physical device on macOS (your integrated GPU), but needs explicit flags for “portability.” Without them, enumeration assumes native hardware and crashes.

Key gotchas:

  • Enable VK_KHR_portability_enumeration and VK_KHR_portability_subset.
  • Set instance version to 1.2+.
  • Use VK_MVK_macos_surface for surfaces.

The Silk.NET PR fixing ImGuiVulkan on macOS proves it: add those extensions, link MoltenVK dynamically, and apps run buttery on Apple Silicon. Khronos MoltenVK issues confirm crashes stem from queue family mismatches, not the library itself.

Pro tip: Grab the latest MoltenVK from the Vulkan SDK—older binaries flake on macOS 13+.

Step-by-Step Silk.NET Vulkan Setup for .NET 8 on macOS

Ready to get Silk.NET humming? Here’s your checklist for .NET 8:

  1. Install NuGets:

    dotnet add package Silk.NET.Vulkan
    dotnet add package Silk.NET.Vulkan.Extensions.EXT  // For macOS extras
    

    Per the Silk.NET.Vulkan NuGet page, this bundles bindings; copy libvulkan.1.dylib (MoltenVK) to your output dir.

  2. Download MoltenVK: Vulkan SDK from LunarG includes it. Extract MoltenVKSwift or static lib to your bin folder.

  3. Instance Creation with macOS Extensions:

    csharp
    var createInfo = new InstanceCreateInfo();
    var extensions = new[] { "VK_KHR_surface", "VK_MVK_macos_surface", "VK_KHR_portability_enumeration" };
    createInfo.EnabledExtensionCount = (uint)extensions.Length;
    createInfo.PpEnabledExtensionNames = extensions.AsPtr();
    // Set portability features
    var portabilityFeatures = new PhysicalDevicePortabilitySubsetFeaturesKHR { TriangListWithoutRestart = true };
    

    Silk.NET GLFW Vulkan issue shows v2.20+ needs this exact setup.

  4. Runtime Config: Embed MoltenVK or set DYLD_LIBRARY_PATH to your dylib. For .NET, use <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> in .csproj.

Test on M1+: It flies post-setup.

Fixing the vkEnumeratePhysicalDevices Crash

Rewrite selectDevice properly:

csharp
private static unsafe VulkanContext selectDevice(VulkanContext ctx)
{
    uint deviceCount = 0;
    ctx.nativeContext.EnumeratePhysicalDevices(ctx.instance, &deviceCount, null);  // Step 1: Get count

    if (deviceCount == 0) throw new Exception("No Vulkan devices found!");

    fixed (PhysicalDevice* devices = new PhysicalDevice[deviceCount])
    {
        ctx.nativeContext.EnumeratePhysicalDevices(ctx.instance, &deviceCount, devices);  // Step 2: Populate

        // Pick first (MoltenVK's only device)
        ctx.physicalDevice = devices[0];
    }
    return ctx;
}

This mirrors Vulkan spec and MoltenVK segfault fixes. Also query queue families post-enum to avoid downstream crashes.

For logical device: Limit to one graphics queue—MoltenVK chokes on multiples per family.

Common Pitfalls and Testing Tips

Watch for:

  • App Store/TestFlight crashes: Sandbox kills Metal access; embed MoltenVK dylib, as in Khronos forums.
  • GLFW Vulkan fails in Silk.NET 2.21+: Downgrade or patch extensions.
  • Vulkan errors like missing DLLs? Run vulkaninfo from SDK to validate.

Test: Build, run on clean macOS. Use RenderDoc for capture. If still busted, check Xcode console for MoltenVK logs.

You’ve got this—Vulkan macOS shines once tuned.

Sources

Conclusion

Patch your Silk.NET Vulkan code with two-step vkEnumeratePhysicalDevices, enable MoltenVK portability extensions, and you’re golden on Vulkan macOS—no more SIGSEGV. This setup powers .NET 8 apps reliably on Apple Silicon, unlocking high-perf graphics without native drivers. Deploy confidently; test extensions early to sidestep edge cases.

Authors
Verified by moderation
Moderation
Fix Vulkan macOS Crash with Silk.NET & MoltenVK