目录
先叨叨
到上篇为止我们已经作了很多事情了。建立了Instance、挑选了物理设备、建立的Device和Queue。
之前做的都是相对简单和线性的工作,只要认真对照说明文档和实例代码基本上不会出现错误。我之前的Leader说过一句话我很认同,程序是调出来的 。
因此为了今后更好的发现和解决程序的问题,需要让Vulkan为我们输出一些内部的Debug信息。本篇就来介绍如何接收Vulkan内部的Debug信息。
git信息
- repository: https://gitee.com/J8_series/easy-car-ui
- tag: 04-05-EnableDebugAndValidation
- url: https://gitee.com/J8_series/easy-car-ui/tree/04-05-EnableDebugAndValidation
关键代码和主要API
VulkanEnv::SetDebugUtilMessenger()
本方法调用vkCreateDebugUtilsMessengerEXT接口创建一个DebugUtilsMessenger,而在DebugUtilsMessenger中可以指定一个回调函数,当Vulkan内参生Debug信息时,便会调用这个回调通知APP。
cpp
void VulkanEnv::SetDebugUtilMessenger()
{
if (false == m_enableDebug)
{
return;
}
//https://registry.khronos.org/vulkan/specs/latest/html/vkspec.html#vkGetInstanceProcAddr
auto func = (PFN_vkCreateDebugUtilsMessengerEXT) vkGetInstanceProcAddr(m_vkInstance, "vkCreateDebugUtilsMessengerEXT");
if (nullptr == func)
{
return;
}
if (func(m_vkInstance, &m_debugUtilsMessengerCreateInfo, nullptr, &m_debugUtilsMessenger) != VK_SUCCESS) {
throw std::runtime_error("failed to set up debug messenger!");
}
}
这里要注意一个问题,我们安装的vulkan的SDK并没有帮助我们实现vkCreateDebugUtilsMessengerEXT接口。因此我们需要自己调用vkGetInstanceProcAddr接口向Vulkan要vkCreateDebugUtilsMessengerEXT的函数地址。如果使用过OpenGL,对这种形式应该不会陌生。
除了DebugUtilsMessenger之外,Vulkan还可以提供DebugReportCallback机制接收Debug信息。 DebugReportCallback通过vkCreateDebugReportCallbackEXT来创建。
VulkanEnv::CreateVkInstance()
通过vkCreateDebugUtilsMessengerEXT的第一个参数是Instance,这也限制了DebugUtilsMessenger必须在创建Instance之后调用。
这会导致一个问题创建Instance时的Debug信息无法获取,解决办法是让VkInstanceCreateInfo的pNext属性,指向一个VkDebugUtilsMessengerCreateInfoEXT对象。
cpp
void VulkanEnv::CreateVkInstance()
{
...
VkInstanceCreateInfo createInfo{};
...
if (true == m_enableDebug)
{
createInfo.pNext = (VkDebugUtilsMessengerCreateInfoEXT*) &m_debugUtilsMessengerCreateInfo;
}
...
}
题外话
创建出来的对象不要忘记在析构函数中释放!