全局加载 Vulkan 函数
Loading Vulkan functions globally
随着 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.h
头文件中声明了函数原型,例如:
VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(
const VkInstanceCreateInfo* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkInstance* pInstance);
这可能会阻止我全局加载函数。如果我要定义 VK_NO_PROTOTYPES
,那么这些原型将被跳过,我相信我可以将它们重新声明为 PFN_vkCreateInstance vkCreateInstance = nullptr;
等等。但这是正确的方法吗?
那么,我的问题 - 全局加载 Vulkan 函数的正确方法是什么?
::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
原型消失后,您可以根据 documentation:
全局加载 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;
}
随着 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.h
头文件中声明了函数原型,例如:
VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(
const VkInstanceCreateInfo* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkInstance* pInstance);
这可能会阻止我全局加载函数。如果我要定义 VK_NO_PROTOTYPES
,那么这些原型将被跳过,我相信我可以将它们重新声明为 PFN_vkCreateInstance vkCreateInstance = nullptr;
等等。但这是正确的方法吗?
那么,我的问题 - 全局加载 Vulkan 函数的正确方法是什么?
::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
原型消失后,您可以根据 documentation:
全局加载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;
}