Search code examples
rustvulkandynamic-linking

rust ash (vulkan), how do you load pointers to extension functions?


In C++ I load extension functions like this:

VkResult (*vkCreateDebugUtilsMessengerEXT_NE)(
    VkInstance, const VkDebugUtilsMessengerCreateInfoEXT*,
    const VkAllocationCallbacks*, VkDebugUtilsMessengerEXT*);
VkResult vkCreateDebugUtilsMessengerEXT(VkInstance instance,
    const VkDebugUtilsMessengerCreateInfoEXT* info,
    const VkAllocationCallbacks* callbacks, VkDebugUtilsMessengerEXT* messenger)
{
    return vkCreateDebugUtilsMessengerEXT_NE(instance, info, callbacks, messenger);
}
void LoadeFunctions()
{
    vkCreateDebugUtilsMessengerEXT_NE = (PFN_vkCreateDebugUtilsMessengerEXT) 
    instance.getProcAddr(
        "vkCreateDebugUtilsMessengerEXT");
    Assert(vkCreateDebugUtilsMessengerEXT_NE,
        "Failed to find extension function: vkCreateDebugUtilsMessengerEXT");
}

I am wondering how to accomplish the same in rust using the ash bindings.


Solution

  • Each extension supported by ash is provided by a struct in the ash::extensions module. For instance, VK_EXT_debug_utils is provided by ash::extensions::ext::DebugUtils.

    use ash::{extensions::ext::DebugUtils, Entry, Instance};
    
    unsafe {
        let entry = ash::Entry::load().unwrap();
        let instance = entry.create_instance(/* ... */).unwrap();
    
        // Load `VK_EXT_debug_utils` extension.
        let debug_utils = DebugUtils::new(&entry, &instance);
    
        // Create a debug messenger.
        let debug_messenger = debug_utils
            .create_debug_utils_messenger(/* ... */)
            .unwrap();
    }
    

    Loading an extension loads all the functions associated with that extension.

    You still need to enumerate the available extensions ahead of time, as loading an unsupported extension will not return an error. Instead, calling any functions of that extension will result in a panic at runtime.