Skip to content

Conversation

@StrideStudios
Copy link

Added the optional ability to compile VkBootstrap as a shared library

Before this, if the VkInstance was split between two different shared libraries, it would crash since the vulkan_functions singleton would be created twice (once per dll). This fixes it by exporting it within a shared library.

option(VK_BOOTSTRAP_SHARED "Compile Vk Bootstrap as a Shared Library" OFF)

Shared Library is Opt in, and otherwise it will compile as static with minimal changes to code.

#if !defined(VK_SHARED)
#define VK_API
#else
#if defined(__GNUC__) || defined(__GNUG__) || defined(__clang__)
#define VK_API __attribute__((visibility("default")))
#elif defined(_MSC_VER)
#define VK_API __declspec(dllexport)
#else
#define VK_API
#endif
#endif

If Static, the VK_API expands to nothing, so most lines are unaffected.

// Export Singleton so it works with shared libraries
VK_API class VulkanFunctions& vulkan_functions();

This is the only line different when compiled as a static library, but it functions the same as it did before.

  • All Tests pass
  • Compiled with MSVC in personal project, and singleton issue was fixed

- Fixes vulkan_functions singleton when linked, as it would crash beforehand (since a non-exported singleton is created once per dll)
Copy link
Owner

@charles-lunarg charles-lunarg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm hesitant to take this PR because it doesn't try to solve the underlying problem, rather it just makes it possible for users to work around it.

The problem is the use of static variables to store the vulkan dynamic library and loaded function pointers. Making vk-bootstrap a shared library solves it by making the static variables available to the entire process, instead of each linked instance of vk-bootstrap having its own private static variable. Hence, the root of the problem is the use of static variables which silently require that vk-bootstrap not be shared between shared libraries and with the executable.

So, in an effort to combat the root problem, I have created a PR #441 which refactors the implementation details to store & pass the necessary function pointers inside of the vkb types directly. Now passing between shared libraries and the executable is no problem as the required context is passed alongside it.

I hope the solution satisfies your needs.

I am still open to compiling vk-bootstrap as a shared library, but I'd rather it be on the merits of shared libraries than to fix a bug.

@StrideStudios
Copy link
Author

Vk-bootstrap really wouldn't benefit much from being a shared library, since in a project with shared libraries it most of time only needs to be privately included in one or two, as is the case with my project. It is absolutely the better option to have the functions as members of the instance, for example, especially since the functions are set upon the instance being built.

On the other hand, it wouldn't be much of a drawback to be a shared library either, since the biggest drawback is slightly slow function calls (which wouldn't matter much because it is on startup).

@charles-lunarg
Copy link
Owner

I started making a bunch of comments of stuff to change, would you rather I go and commit it directly to cut out you having to make a bunch of nitpick kinda changes?

@StrideStudios
Copy link
Author

It would be fine for you to commit directly. I appreciate how much effort you are putting into this!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants