macosrustvulkanash

Creating a Vulkan instance on macOS using Rust + Ash


I am having trouble creating a Vulkan instance in my Rust application.

The Vulkan SDK is installed in /Users/verhage/VulkanSDK.

I exported the required environment variables as per the Ash documentation:

export VULKAN_SDK=$HOME/VulkanSDK/1.3.275.0/macOS
export DYLD_FALLBACK_LIBRARY_PATH=$VULKAN_SDK/lib
export VK_LAYER_PATH=$VULKAN_SDK/share/vulkan/explicit_layer.d
export VK_LAYER_PATH=$VULKAN_SDK/share/vulkan/explicit_layer.d

But then when I do a cargo run I get:

Error: Unable to find a Vulkan driver

Same error as when I do not set any of the environment variables. I also tried to add the environment variables to my run configuration in IntelliJ like this:

enter image description here

But then when I run it I get an even stranger error message:

dyld[26946]: Library not loaded: @rpath/libvulkan.1.dylib
  Referenced from: <D96150F6-E457-355F-B797-E3268BB2412B> /Users/verhage/dev/myapp/target/debug/piston
  Reason: tried: '/Users/verhage/dev/myapp/target/debug/deps/libvulkan.1.dylib' (no such file), '/Users/verhage/dev/myapp/target/debug/libvulkan.1.dylib' (no such file), '/Users/verhage/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/libvulkan.1.dylib' (no such file), '/Users/verhage/.rustup/toolchains/stable-aarch64-apple-darwin/lib/libvulkan.1.dylib' (no such file), '$VULKAN_SDK/lib/libvulkan.1.dylib' (no such file)

I don't get what is going wrong, I double and triple checked all the file paths and they are all there. Also $VULKAN_SDK/lib/libvulkan.1.dylib is exactly where it is expected to be.

This is the code I try to run:

use anyhow::Result;
use ash::{self, vk};

fn main() -> Result<()> {
    let entry = unsafe { ash::Entry::load() }?;
    let application_info = vk::ApplicationInfo::builder().api_version(vk::API_VERSION_1_3);
    let create_info = vk::InstanceCreateInfo::builder().application_info(&application_info);

    let instance = unsafe { entry.create_instance(&create_info, None) }?;
    Ok(())
}

What am I doing wrong?


Solution

  • I figured out what was going on here. On macOS you need to load some specific extensions that are not loaded by default because macOS doesn't have native support for Vulkan.

    Turns out that the environment variables do not matter at all.

    It was all about loading the proper extensions. This is the code with the extensions added:

    use anyhow::Result;
    use ash::{self, vk};
    
    fn main() -> Result<()> {
        let mut extension_names = Vec::new();
        extension_names.push(vk::KhrPortabilityEnumerationFn::name().as_ptr());
        extension_names.push(vk::KhrGetPhysicalDeviceProperties2Fn::name().as_ptr());
    
        let entry = unsafe { ash::Entry::load() }?;
        let application_info = vk::ApplicationInfo::builder().api_version(vk::API_VERSION_1_3);
    
        let create_flags = vk::InstanceCreateFlags::ENUMERATE_PORTABILITY_KHR;
        let create_info = vk::InstanceCreateInfo::builder()
            .application_info(&application_info)
            .enabled_extension_names(&extension_names)
            .flags(create_flags);
    
        let instance = unsafe { entry.create_instance(&create_info, None) }?;
        Ok(())
    }
    

    Now it can find the driver and runs without issues.