4

随着 Vulkan 的发布,我决定(作为一种爱好)编写一个基于 Vulkan 的 GUI。但是,我目前停留在第一步——加载 Vulkan 函数。我正在使用 Nvidia 的 C++ Vulkan 包装器,据我所知,它需要全局加载 Vulkan 函数。

我可以成功加载本地函数,但是::vkCreateInstance失败了:

void loadInstanceFunctions() {
    PFN_vkCreateInstance vkCreateInstance = (PFN_vkCreateInstance)vkGetInstanceProcAddr(nullptr, "vkCreateInstance"); //works

    ::vkCreateInstance = (PFN_vkCreateInstance)vkGetInstanceProcAddr(nullptr, "vkCreateInstance");  //does not work
}

尝试全局分配新函数指针会给我 2 个编译时错误(使用 VS2015 编译):

  • 表达式必须是可修改的左值。
  • '=':作为左操作数。

vulkan.hheader 中声明了函数原型,例如:

VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(
    const VkInstanceCreateInfo*                 pCreateInfo,
    const VkAllocationCallbacks*                pAllocator,
    VkInstance*                                 pInstance);

这可能会阻止我全局加载函数。如果我要定义VK_NO_PROTOTYPES,那么这些原型将被跳过,我相信我可以重新声明它们PFN_vkCreateInstance vkCreateInstance = nullptr;,依此类推。但这是正确的方法吗?

所以,我的问题 - 全局加载 Vulkan 函数的正确方法是什么?

4

1 回答 1

7
::vkCreateInstance = (PFN_vkCreateInstance)vkGetInstanceProcAddr(nullptr, "vkCreateInstance");  //does not work

您正在尝试将函数指针分配给符号vkCreateInstance,默认情况下,该符号被定义为 vulkan.h 中的原型。

定义VK_NO_PROTOTYPES将预处理所有原型:

#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(
    const VkInstanceCreateInfo*                 pCreateInfo,
    const VkAllocationCallbacks*                pAllocator,
    VkInstance*                                 pInstance);
...
#endif

一旦原型消失,您可以vkCreateInstance根据文档全局加载:

#define VK_NO_PROTOTYPES
#include <vulkan/vulkan.h>

#ifdef __cplusplus
extern "C" {
#endif
VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char *pName);
#ifdef __cplusplus
}
#endif

PFN_vkCreateInstance vkCreateInstance;

int main()
{
        vkCreateInstance = (PFN_vkCreateInstance) vkGetInstanceProcAddr(NULL, "vkCreateInstance");

        return 0;
}
于 2016-03-27T14:11:05.113 回答