handmade.network » Forums » Work-in-Progress » vkbind - Single file Vulkan API loader
mackron
David Reid
7 posts
#16692 vkbind - Single file Vulkan API loader
2 weeks, 3 days ago Edited by David Reid on Nov. 3, 2018, 11:03 a.m. Reason: Initial post

In case anybody's interested, I've been hacking away on a simple API loader for Vulkan. I've called it vkbind, and you can find it on GitHub over here: https://github.com/dr-soft/vkbind. It's the same kind of thing as GLEW, if you remember that.

It's single file and includes the Vulkan headers (including the platform-specific stuff) which is all auto-generated from vk.xml so there's no need to download any SDKs or anything. It's also all linked at run time, so no need to link to anything either. It's pretty simple - it just loads "vulkan-1.dll", etc. and calls dlsym() on it basically.

I've not yet tested on anything other than Windows. Would be interested in some feedback!

Example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
#define VKBIND_IMPLEMENTATION
#include "vkbind.h"

int main()
{
    VkResult result = vkbInit(NULL);
    if (result != VK_SUCCESS) {
        printf("Failed to initialize vkbind.");
        return -1;
    }

    // Do stuff here.

    vkbUninit();
    return 0;
}


Or if your platform does not statically expose all APIs:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#define VKBIND_IMPLEMENTATION
#include "vkbind.h"

int main()
{
    VkbAPI api;
    VkResult result = vkbInit(&api);
    if (result != VK_SUCCESS) {
        printf("Failed to initialize vkbind.");
        return -1;
    }
    
    // ... Create your Vulkan instance here (vkCreateInstance) ...

    result = vkbInitInstanceAPI(instance, &api);
    if (result != VK_SUCCESS) {
        printf("Failed to initialize instance API.");
        return -2;
    }

    result = vkbBindAPI(&api);  // <-- Optional. Can call APIs directly like api.vkDestroyInstance().
    if (result != VK_SUCCESS) {
        printf("Failed to bind instance API.");
        return -3;
    }

    // Do stuff here.

    vkbUninit();
    return 0;
}


I'm also working on some examples which are in the vkbind repository (there's only one there at the moment). Something that I find annoying is how existing examples are so hard to read because they're wrapped in classes, call out to functions in other source files, etc. My examples are flat and simple. I'm hoping to add more examples to the repository soon-ish.
albatros
14 posts

None

#16693 vkbind - Single file Vulkan API loader
2 weeks, 3 days ago

This looks great. :)

*Silently lurks in wait of a linux version*

None
ratchetfreak
413 posts
#16694 vkbind - Single file Vulkan API loader
2 weeks, 2 days ago

albatros
This looks great. :)

*Silently lurks in wait of a linux version*


It's already linux compatible, using dlsym on linux and GetProcAddress on win32

Though one note to make, the vulkan loader dll/dynamic lib only exposes the "core extensions" which is the the wsi extensions and a few bug fix extensions.

All the rest are never exposed directly by the dll and dlsym/GetProcAddress will fail on them. Instead you need to use vkGetInstanceProcAddress for the other extension functions.
mackron
David Reid
7 posts
#16695 vkbind - Single file Vulkan API loader
2 weeks, 2 days ago

I just pushed a fix for the Linux and GCC builds. It was not looking for vulkan.so.1 which was causing some problems. Also had a compiler error due to size_t not being defined.

With the dlsym stuff, the most robust way to do it is to use vkbInitInstanceAPI() like in the second example in my original post which should grab your extension functions. You can also manually call vkGetInstanceProcAddr() if that's your preference.