vulkan.hpp 扩展的唯一句柄

vulkan.hpp unique handles for extensions

我正在尝试为 vk::DebugUtilsMessengerEXT 对象创建一个唯一句柄。

为此,我将 VkCreateDebugUtilsMessenger() 加载到一个函数指针中,然后调用它来创建纯 C 结构,然后我通过

将其变成一个唯一的 vulkan.hpp 对象

vk::UniqueDebugUtilsMessengerEXT(messenger, instance);

问题由此开始。这种对象隐含地调用析构函数,也就是说它会在变量离开作用域时尝试调用vkDestroyDebugUtilsMessengerEXT。但是这个函数不能加载到一个同名的指针中。

即定义函数指针为vkDestroyDebugUtilsMessengerEXT

然后设置为

vkDestroyDebugUtilsMessengerEXT = (PFN_vkDestroyDebugUtilsMessengerEXT) instance.getProcAddr(
        "vkDestroyDebugUtilsMessengerEXT");

当我重新定义符号时会导致编译错误。

error: ‘void (* vkDestroyDebugUtilsMessengerEXT)(VkInstance, VkDebugUtilsMessengerEXT, VkAllocationCallbacks)’ redeclared as different kind of symbol

但是不定义它会导致 linker 错误,因为 linker 无法找到 link 的符号以防止破坏唯一句柄。

/usr/bin/ld: obj/Debug/main.o: in function `vk::DispatchLoaderStatic::vkDestroyDebugUtilsMessengerEXT(VkInstance_T*, VkDebugUtilsMessengerEXT_T*, VkAllocationCallbacks const*) const':
/home/kronos/Desktop/Vulkan/Generated/../libraries/vulkansdk-linux/1.1.97.0/x86_64/include/vulkan/vulkan.hpp:1770: undefined reference to `vkDestroyDebugUtilsMessengerEXT'

我该如何解决这个问题?我如何公开该符号以允许编译?

我找到了解决方案。

定义一个与请求函数同名的函数并调用其中的指针允许编译和链接。

本质上:

void (*vkDestroyDebugUtilsMessenger)(VkInstance instance, VkDebugUtilsMessengerEXT debugMessenger, const VkAllocationCallbacks* pAllocator);
void vkDestroyDebugUtilsMessengerEXT(VkInstance instance, VkDebugUtilsMessengerEXT debugMessenger, const VkAllocationCallbacks* pAllocator)
{
    vkDestroyDebugUtilsMessenger(instance, debugMessenger, pAllocator);
}

创建链接和编译所需的符号并:

vkDestroyDebugUtilsMessenger =
        (PFN_vkDestroyDebugUtilsMessengerEXT) vkGetInstanceProcAddr(
            instance, "vkDestroyDebugUtilsMessengerEXT");

将正确初始化指针。

除了上面的答案,还不如像下面的代码:

using unique_debug_utils_messenger_ext = UniqueHandle<DebugUtilsMessengerEXT, DispatchLoaderDynamic>;
...
UniqueInstance instance_{nullptr};
UniqueDevice device_;
unique_debug_utils_messenger_ext debug_messenger_;
DebugUtilsMessengerCreateInfoEXT debug_messenger_create_info;
DispatchLoaderDynamic dispatch_loader_dynamic_;
...
dispatch_loader_dynamic_ = {*instance_, *device_};
debug_messenger_ = instance_->createDebugUtilsMessengerEXTUnique(
            debug_messenger_create_info,
            nullptr,
            dispatch_loader_dynamic_);

该代码使您仍然可以使用智能指针功能。 vulkan.hpp.

中的 DispatchLoaderDynamic 实现中提供了更多详细信息