全局公开 Vulkan 的函数指针是个好主意吗?

Is it a good idea to expose Vulkan's function pointers globally?

我刚刚在运行时第一次加载了一个共享库。我目前正在做的是创建一个显式上下文,其中加载了所有函数指针。

在 C++ 中大致如下所示

auto entry = load_vk(..);
auto instance = entry.CreateInstance(...);
VkInstancePointer vk = load_vk_static_fn(instance);
vk.CreateDevice(...);

问题是我不确定它的生命周期。我需要跨不同的线程访问 vk,所以我目前将它包装在 shared_ptr<VkInstancePointer> 中。我也在析构函数中卸载库。

我遇到的问题是我想让 vulkan api 更方便一点,这样我就可以写

physical_device.create_logical_device(...);

但这意味着 physical_device 需要包含 shared_ptr<VkInstancePointer>。这意味着很多东西都会有原子计数器增量的额外开销。

我想知道是否可以全局加载 vulkan 函数指针?

load_entry();
auto instance = CreateInstance();
load_instance_fp(instance);
auto device = CreateDevice(..);

我通常从不使用全局变量,但在这里似乎很有意义。

我是否想在某个时候卸载 Vulkan 库?

Vulkan中有两种函数指针:实例函数指针和设备函数指针。

通过vkGetInstanceProcAddr 检索实例函数指针。此函数可以检索与设备无关的函数的函数指针。也就是说,对于处理 creating/managing/destroying 设备的函数,而不是直接与设备对话的函数(即:任何采用 VkDeviceVkQueueVkCommandBuffer 的函数).

但它也可以检索与设备本身对话的函数的指针。这些函数可以与 任何 Vulkan 设备通信,无论它是在检索函数指针之前还是之后创建的。

相比之下,vkGetDeviceProcAddr 获取 device 函数指针。这些函数指针是特定于设备的;它们不能用于不同于它们创建时使用的设备。

因此您可以创建全局函数指针,可以从任何线程使用它来与任何设备通信。但它们必须是实例函数指针。

或者您可以让 Vulkan SDK 完成它的工作并为您处理所有这些。

Do I ever want to unload the Vulkan library at some point?

我不知道你想要这样做的原因。用户通常无法在不重启机器的情况下安装新版本的驱动级系统,如 Vulkan。即使可以,您的代码也不知道如何处理它的新内容,因为您的代码是针对较低版本编写的。