Loading Vulkan functions using vkGetInstanceProcAddress

Hi,

I’m working through the “API Without Secrets” Intel Vulkan tutorial and I am struggling to load Vulkan functions. I tweaked the Window class to work with GLFW (I’m using XCode with OSX), and my very basic app can be found here:

https://github.com/NicLentzos/VulkanLoaderTest

The Example::LoadExportedEntryPoints() and Example::LoadGlobalLevelEntryPoints() functions run without throwing errors, but as soon as I call any Vulkan functions such as vkCreateInstance then XCode throws an error saying that the Vulkan function is undefined e.g.

Undefined symbols for architecture x86_64:

“VulkanApp::vkCreateInstance”, referenced from:
VulkanApp::Example::CreateInstance() in Example.o
ld: symbol(s) not found for architecture x86_64

I’m certain that I’m missing something basic, but have gone over the code a number of times and can’t see anything obvious. The tutorial I’m following is the first one, and can be found here:

Intel Vulkan tutorial 1

Could someone take a quick look to see what I’m missing?

Thanks

Hey there,

Make sure to load the functions using vkGetInstanceProcAddress and then to use the function pointer you created with that. You can’t just load it and then use the normal vkCreateInstance function, since this would be the case for static linkage of vulkan, not dynamic.

Here’s an example of Vulkan debug markers:

// This is the function pointer to vkDebugMarkerSetObjectTagEXT which we will load dynamically
PFN_vkDebugMarkerSetObjectTagEXT meta_vkDebugMarkerSetObjectTagEXT;

// Try to load it
meta_vkDebugMarkerSetObjectTagEXT = reinterpret_cast<PFN_vkDebugMarkerSetObjectTagEXT>(
            vkGetDeviceProcAddr(device, "vkDebugMarkerSetObjectTagEXT"));

if (!meta_vkDebugMarkerSetObjectTagEXT) {
   throw std::runtime_error("Failed to load Vulkan debug marker functions!");
}

// Now we can call meta_vkDebugMarkerSetObjectTagEXT
auto tagInfo = make_info<VkDebugMarkerObjectTagInfoEXT>();
tagInfo.objectType = type;
tagInfo.object = object;
tagInfo.tagName = name;
tagInfo.tagSize = tag_size;
tagInfo.pTag = tag;

if (meta_vkDebugMarkerSetObjectTagEXT(device, &tagInfo) != VK_SUCCESS) {
   throw std::runtime_error("Failed to assign Vulkan debug marker data tag to Vulkan resource!");
}

Vulkan debug markers must be loaded dynamically in any case, since they might not be available on the machine.

Maybe have a look at Vulkan metaloder. It is frequently used for dealing with loading Vulkan stuff dynamically:

I personally would recommend not to use a metaloder for beginning experiments. It has some advantages, but I would focus on Vulkan directly first.

Best regards,
Johannes

Hi, thanks very much for the information and sorry for not replying back sooner. It all works perfectly, and I just stash the load function code in an include file (which has grown considerably). Care needs to be taken to avoid typos :joy:

As you say, it’s much better to try doing everything by hand first as I’m learning lots by making mistakes! I was hoping to teach myself Vulkan during lockdown but I’ve only really got as far as instance rendering - I’m a slow learner. If I can just get a skybox up and running in the next week I’ll be happy. Have a good evening and thanks again for the tips.