Vulkan 加载 vkCreateDebugReportCallbackEXT
Vulkan load vkCreateDebugReportCallbackEXT
我正在使用 Vulkan 并偶然发现了我的第一个问题。尝试创建调试报告回调时(验证层和调试扩展在我的 intel hd vulkan driver 上可用,至少它是这么说的),它没有告诉我 vkCreateDebugReportCallbackEXT
是一个未解析的符号。当试图获取函数指针时,它告诉我 vkCreateDebugReportCallbackEXT
已经定义。
在 Vulkan 中就是这样 header。我可以设置 VK_NO_PROTOTYPES 但我必须手动加载所有内容。有没有解决的办法?仅仅为函数指针使用不同的名称是行不通的,因为我正在使用 Vulkan-Hpp 而它按原样使用 vkCreateDebugReportCallbackEXT
。
这是一个 driver 错误,告诉我调试扩展可用,但没有?
顺便说一下,我正在使用 VS2015。
感谢您的帮助
这很正常。 vulkan.h
将它们定义为全局函数。但是加载器命令显然 return function pointer.
通常您会使用您喜欢的其他名称。但我也喜欢有规范的名字...
我通过自己 定义 函数(使用 vulkan.h
中的 声明 )来解决它,然后调用加载的指针:
VKAPI_ATTR VkResult VKAPI_CALL vkCommandEXT( /*...*/ ){
return fpCommandEXT( /*...*/ );
}
(无耻的自我推销)像这样:
https://github.com/krOoze/Hello_Triangle/blob/8227220/ErrorHandling.h#L181
我让命令在第一次使用时自动加载——如果你不喜欢那样,在旧的提交中我有更传统的加载器:
https://github.com/krOoze/Hello_Triangle/blob/699ab57/HelloTriangle.cpp#L731
PS:
Khronos 自己刚刚添加了加载程序代码,很好地说明了这一点:
https://github.com/KhronosGroup/Vulkan-Docs/blob/1.0/src/ext_loader/vulkan_ext.c
如果您处理多个 VkInstance
或 VkDevice
,则必须将加载的函数分派到正确的实例或设备。例如,我在这里(可能效率低下)这样做:
https://github.com/krOoze/Hello_Triangle/blob/a691de5/ExtensionLoader.h
我遇到了同样的问题,找不到解决办法所以我这样解决了
(可能是错误的,但我只是想分享一下以防对某人有所帮助):
struct DebugDispatch {
//KHRONOS
PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT = 0;
PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallbackEXT = 0;
//LUNARG
PFN_vkCreateDebugUtilsMessengerEXT vkCreateDebugUtilsMessengerEXT = 0;
PFN_vkDestroyDebugUtilsMessengerEXT vkDestroyDebugUtilsMessengerEXT = 0;
}
VKAPI_ATTR vk::Bool32 VKAPI_CALL debugReportCallback(...){...}
VKAPI_ATTR vk::Bool32 VKAPI_CALL debugUtilsMessengerCallback(...){...}
enum class ValidationFlagsBits : unsigned int {
NONE = 0,
KHRONOS = 1,
LUNARG = 1 << 1
};
typedef vk::Flags<ValidationFlagsBits> ValidationFlags;
void Example(){
...
vk::Instance instance;
instance = vk::createInstance(...);
DebugDispatch debug_dispatch;
vk::DebugReportCallbackEXT debug_report_callback;
vk::DebugUtilsMessengerEXT debug_utils_messenger;
if(validation_flags & ValidationFlagsBits::KHRONOS){
debug_dispatch.vkCreateDebugReportCallbackEXT =
(PFN_vkCreateDebugReportCallbackEXT)instance.getProcAddr("vkCreateDebugReportCallbackEXT");
debug_dispatch.vkDestroyDebugReportCallbackEXT =
(PFN_vkDestroyDebugReportCallbackEXT)instance.getProcAddr("vkDestroyDebugReportCallbackEXT");
vk::DebugUtilsMessengerCreateInfoEXT create_info{};
create_info.messageSeverity = ...;
create_info.messageType = ...;
create_info.pfnUserCallback = reinterpret_cast<PFN_vkDebugUtilsMessengerCallbackEXT>(&debugUtilsMessengerCallback);
debug_utils_messenger = instance.createDebugUtilsMessengerEXT(create_info, nullptr, debug_dispatch);
}
if(validation_flags & ValidationFlagsBits::LUNARG){
debug_dispatch.vkCreateDebugUtilsMessengerEXT =
(PFN_vkCreateDebugUtilsMessengerEXT)instance.getProcAddr("vkCreateDebugUtilsMessengerEXT");
debug_dispatch.vkDestroyDebugUtilsMessengerEXT =
(PFN_vkDestroyDebugUtilsMessengerEXT)instance.getProcAddr("vkDestroyDebugUtilsMessengerEXT");
vk::DebugReportCallbackCreateInfoEXT create_info{};
create_info.flags = ...;
create_info.pfnCallback = reinterpret_cast<PFN_vkDebugReportCallbackEXT>(&debugReportCallback);
debug_report_callback = instance.createDebugReportCallbackEXT(create_info, nullptr, debug_dispatch);
}
...
if(validation_flags & ValidationFlagsBits::KHRONOS){
instance.destroyDebugUtilsMessengerEXT(debug_utils_messenger, nullptr, debug_dispatch);
}
if(validation_flags & ValidationFlagsBits::LUNARG){
instance.destroyDebugReportCallbackEXT(debug_report_callback, nullptr, debug_dispatch);
}
instance.destroy();
}
我正在使用 Vulkan 并偶然发现了我的第一个问题。尝试创建调试报告回调时(验证层和调试扩展在我的 intel hd vulkan driver 上可用,至少它是这么说的),它没有告诉我 vkCreateDebugReportCallbackEXT
是一个未解析的符号。当试图获取函数指针时,它告诉我 vkCreateDebugReportCallbackEXT
已经定义。
在 Vulkan 中就是这样 header。我可以设置 VK_NO_PROTOTYPES 但我必须手动加载所有内容。有没有解决的办法?仅仅为函数指针使用不同的名称是行不通的,因为我正在使用 Vulkan-Hpp 而它按原样使用 vkCreateDebugReportCallbackEXT
。
这是一个 driver 错误,告诉我调试扩展可用,但没有?
顺便说一下,我正在使用 VS2015。
感谢您的帮助
这很正常。 vulkan.h
将它们定义为全局函数。但是加载器命令显然 return function pointer.
通常您会使用您喜欢的其他名称。但我也喜欢有规范的名字...
我通过自己 定义 函数(使用 vulkan.h
中的 声明 )来解决它,然后调用加载的指针:
VKAPI_ATTR VkResult VKAPI_CALL vkCommandEXT( /*...*/ ){
return fpCommandEXT( /*...*/ );
}
(无耻的自我推销)像这样:
https://github.com/krOoze/Hello_Triangle/blob/8227220/ErrorHandling.h#L181
我让命令在第一次使用时自动加载——如果你不喜欢那样,在旧的提交中我有更传统的加载器:
https://github.com/krOoze/Hello_Triangle/blob/699ab57/HelloTriangle.cpp#L731
PS:
Khronos 自己刚刚添加了加载程序代码,很好地说明了这一点:
https://github.com/KhronosGroup/Vulkan-Docs/blob/1.0/src/ext_loader/vulkan_ext.c
如果您处理多个 VkInstance
或 VkDevice
,则必须将加载的函数分派到正确的实例或设备。例如,我在这里(可能效率低下)这样做:
https://github.com/krOoze/Hello_Triangle/blob/a691de5/ExtensionLoader.h
我遇到了同样的问题,找不到解决办法所以我这样解决了 (可能是错误的,但我只是想分享一下以防对某人有所帮助):
struct DebugDispatch {
//KHRONOS
PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT = 0;
PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallbackEXT = 0;
//LUNARG
PFN_vkCreateDebugUtilsMessengerEXT vkCreateDebugUtilsMessengerEXT = 0;
PFN_vkDestroyDebugUtilsMessengerEXT vkDestroyDebugUtilsMessengerEXT = 0;
}
VKAPI_ATTR vk::Bool32 VKAPI_CALL debugReportCallback(...){...}
VKAPI_ATTR vk::Bool32 VKAPI_CALL debugUtilsMessengerCallback(...){...}
enum class ValidationFlagsBits : unsigned int {
NONE = 0,
KHRONOS = 1,
LUNARG = 1 << 1
};
typedef vk::Flags<ValidationFlagsBits> ValidationFlags;
void Example(){
...
vk::Instance instance;
instance = vk::createInstance(...);
DebugDispatch debug_dispatch;
vk::DebugReportCallbackEXT debug_report_callback;
vk::DebugUtilsMessengerEXT debug_utils_messenger;
if(validation_flags & ValidationFlagsBits::KHRONOS){
debug_dispatch.vkCreateDebugReportCallbackEXT =
(PFN_vkCreateDebugReportCallbackEXT)instance.getProcAddr("vkCreateDebugReportCallbackEXT");
debug_dispatch.vkDestroyDebugReportCallbackEXT =
(PFN_vkDestroyDebugReportCallbackEXT)instance.getProcAddr("vkDestroyDebugReportCallbackEXT");
vk::DebugUtilsMessengerCreateInfoEXT create_info{};
create_info.messageSeverity = ...;
create_info.messageType = ...;
create_info.pfnUserCallback = reinterpret_cast<PFN_vkDebugUtilsMessengerCallbackEXT>(&debugUtilsMessengerCallback);
debug_utils_messenger = instance.createDebugUtilsMessengerEXT(create_info, nullptr, debug_dispatch);
}
if(validation_flags & ValidationFlagsBits::LUNARG){
debug_dispatch.vkCreateDebugUtilsMessengerEXT =
(PFN_vkCreateDebugUtilsMessengerEXT)instance.getProcAddr("vkCreateDebugUtilsMessengerEXT");
debug_dispatch.vkDestroyDebugUtilsMessengerEXT =
(PFN_vkDestroyDebugUtilsMessengerEXT)instance.getProcAddr("vkDestroyDebugUtilsMessengerEXT");
vk::DebugReportCallbackCreateInfoEXT create_info{};
create_info.flags = ...;
create_info.pfnCallback = reinterpret_cast<PFN_vkDebugReportCallbackEXT>(&debugReportCallback);
debug_report_callback = instance.createDebugReportCallbackEXT(create_info, nullptr, debug_dispatch);
}
...
if(validation_flags & ValidationFlagsBits::KHRONOS){
instance.destroyDebugUtilsMessengerEXT(debug_utils_messenger, nullptr, debug_dispatch);
}
if(validation_flags & ValidationFlagsBits::LUNARG){
instance.destroyDebugReportCallbackEXT(debug_report_callback, nullptr, debug_dispatch);
}
instance.destroy();
}