Skip to content

Commit

Permalink
Implement volkFinalize function (#153)
Browse files Browse the repository at this point in the history
This is normally not necessary to call if the instance survives until
the application shutdown, but it might be useful in some cases where a
clean and complete instance recreation is needed, or if the application
wants to tear down the Vulkan instance and then create an OpenGL
instance while making sure the Vulkan DLLs are unloaded.
  • Loading branch information
zeux authored Nov 5, 2023
1 parent a03df7a commit 7e0a723
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 0 deletions.
33 changes: 33 additions & 0 deletions volk.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@ extern "C" {
#ifdef _WIN32
__declspec(dllimport) HMODULE __stdcall LoadLibraryA(LPCSTR);
__declspec(dllimport) FARPROC __stdcall GetProcAddress(HMODULE, LPCSTR);
__declspec(dllimport) int __stdcall FreeLibrary(HMODULE);
#endif

static void* loadedModule = NULL;
static VkInstance loadedInstance = VK_NULL_HANDLE;
static VkDevice loadedDevice = VK_NULL_HANDLE;

Expand All @@ -44,6 +46,14 @@ static PFN_vkVoidFunction vkGetDeviceProcAddrStub(void* context, const char* nam
return vkGetDeviceProcAddr((VkDevice)context, name);
}

static PFN_vkVoidFunction nullProcAddrStub(void* context, const char* name)
{
(void)context;
(void)name;

return NULL;
}

VkResult volkInitialize(void)
{
#if defined(_WIN32)
Expand Down Expand Up @@ -73,6 +83,7 @@ VkResult volkInitialize(void)
vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)dlsym(module, "vkGetInstanceProcAddr");
#endif

loadedModule = module;
volkGenLoadLoader(NULL, vkGetInstanceProcAddrStub);

return VK_SUCCESS;
Expand All @@ -82,9 +93,31 @@ void volkInitializeCustom(PFN_vkGetInstanceProcAddr handler)
{
vkGetInstanceProcAddr = handler;

loadedModule = NULL;
volkGenLoadLoader(NULL, vkGetInstanceProcAddrStub);
}

void volkFinalize(void)
{
if (loadedModule)
{
#if defined(_WIN32)
FreeLibrary((HMODULE)loadedModule);
#else
dlclose(loadedModule);
#endif
}

vkGetInstanceProcAddr = NULL;
volkGenLoadLoader(NULL, nullProcAddrStub);
volkGenLoadInstance(NULL, nullProcAddrStub);
volkGenLoadDevice(NULL, nullProcAddrStub);

loadedModule = NULL;
loadedInstance = VK_NULL_HANDLE;
loadedDevice = VK_NULL_HANDLE;
}

uint32_t volkGetInstanceVersion(void)
{
#if defined(VK_VERSION_1_1)
Expand Down
5 changes: 5 additions & 0 deletions volk.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,11 @@ VkResult volkInitialize(void);
*/
void volkInitializeCustom(PFN_vkGetInstanceProcAddr handler);

/**
* Finalize library by unloading Vulkan loader and resetting global symbols to NULL.
*/
void volkFinalize(void);

/**
* Get Vulkan instance version supported by the Vulkan loader, or 0 if Vulkan isn't supported
*
Expand Down

0 comments on commit 7e0a723

Please sign in to comment.