0

I'm reading Vulkan Tutorial and want to use Vulkan C++ binding instead. But error occured when I load vkCreateDebugUtilsMessengerEXT and vkDestroyDebugUtilsMessengerEXT.

Seems like instance.getProcAddr("extension_name") won't really load a function into instance object, so I can't directly invoke, for example, destroyDebugUtilsMessengerEXT by an object of vk::Instance , because vkDestroyDebugUtilsMessengerEXT is an unresolved symbol. The demo of Vulkan sdkcube.cpp manually defines this function, so that the internal invocation of destroyDebugUtilsMessengerEXT can find out a definition of vkDestroyDebugUtilsMessengerEXT. But defining a function with same name of built-in function is definitely weird to me.

Also, I know the below is another way to do the same thing.

// This is the method in Vulkan Tutorial
// https://vulkan-tutorial.com/code/02_validation_layers.cpp
// Make a wrapper
void DestroyDebugUtilsMessengerEXT(VkInstance instance, VkDebugUtilsMessengerEXT debugMessenger, const VkAllocationCallbacks* pAllocator) {
    auto func = (PFN_vkDestroyDebugUtilsMessengerEXT) vkGetInstanceProcAddr(instance, "vkDestroyDebugUtilsMessengerEXT");
    if (func != nullptr) {
        func(instance, debugMessenger, pAllocator);
    }
}

// And call it in cleanup()
DestroyDebugUtilsMessengerEXT(instance, debugMessenger, nullptr);

Could I have a neat way to load those functions without defining a function having same name of built-in or calling them by ugly C style code?

  • 1
    If by "directly invoke", you mean `object.member_function()`... yes, you cannot *dynamically* add members to a type (or object) in C++. There is nothing un-C++-like about using non-member functions to operate on an object. – Nicol Bolas Aug 25 '22 at 16:18
  • You're either going to need a wrapper function or a function pointer which you'll have to check for null yourself. There is no way around that as Vulkan relies on dynamically importing all functions from the ICD. – vandench Aug 25 '22 at 16:57
  • @NicolBolas I'm ok with using non-member function on an object. The weird thing is `vulkan.hpp` provides member functions, like `(create/destroy)DebugUtilsMessengerEXT`, but can not be invoked because its internal function can not be linked. All I want is ensuring if "defining the internal function is exactly what I should do and what I should get used to". Such thing is really unusual to me but is exactly what the official demo shows me. – SynchronizX Aug 26 '22 at 01:59

1 Answers1

0

I have figured out how to dynamically load functions without mixed code style by myself. I couldn't find those corresponding functions because vulkan.hpp is too large and Intellisense in vscode is too slow.

For the case in my question, I should use instance.createDebugUtilsMessengerEXT(vk::DebugUtilsMessengerCreateInfoEXT). The last parameter of this function has a default value which assign a default dynamic loader for it.

Vulkan C++ binding has provided all those stuff as member function. The rule is : the invoking object is always the type of the first parameter of original function. For example, the first parameter of vkDestroyDebugUtilsMessengerEXT is VkInstance, hence the caller object is of type vk::Instance. The first parameter of vkCreateRenderPass is VkDevice, so the caller object is of type vk::Device.

That's all. For a beginner, it's no need to consider too much about loader, the default loader has handled all troubles for us.

One last thing: if Intellisense is too slow/stupid to load correct result, you can search the corresponding wrapper class within vulkan_structs.hpp and vulkan_funcs.hpp. This helped me a lot.