Use VK_EXT_debug_utils instead of deprecated VK_EXT_debug_report for debugging

This commit is contained in:
Sascha Willems 2019-10-18 20:51:46 +02:00
parent 10129ee606
commit b3214c521b
2 changed files with 39 additions and 68 deletions

View file

@ -13,108 +13,79 @@ namespace vks
{ {
namespace debug namespace debug
{ {
PFN_vkCreateDebugReportCallbackEXT CreateDebugReportCallback = VK_NULL_HANDLE; PFN_vkCreateDebugUtilsMessengerEXT vkCreateDebugUtilsMessengerEXT;
PFN_vkDestroyDebugReportCallbackEXT DestroyDebugReportCallback = VK_NULL_HANDLE; PFN_vkDestroyDebugUtilsMessengerEXT vkDestroyDebugUtilsMessengerEXT;
PFN_vkDebugReportMessageEXT dbgBreakCallback = VK_NULL_HANDLE; VkDebugUtilsMessengerEXT debugUtilsMessenger;
VkDebugReportCallbackEXT msgCallback; VKAPI_ATTR VkBool32 VKAPI_CALL debugUtilsMessengerCallback(
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
VKAPI_ATTR VkBool32 VKAPI_CALL messageCallback( VkDebugUtilsMessageTypeFlagsEXT messageType,
VkDebugReportFlagsEXT flags, const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
VkDebugReportObjectTypeEXT objType,
uint64_t srcObject,
size_t location,
int32_t msgCode,
const char* pLayerPrefix,
const char* pMsg,
void* pUserData) void* pUserData)
{ {
// Select prefix depending on flags passed to the callback // Select prefix depending on flags passed to the callback
// Note that multiple flags may be set for a single validation message
std::string prefix(""); std::string prefix("");
// Error that may result in undefined behaviour if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT) {
if (flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) prefix = "VERBOSE: ";
{
prefix += "ERROR:";
};
// Warnings may hint at unexpected / non-spec API usage
if (flags & VK_DEBUG_REPORT_WARNING_BIT_EXT)
{
prefix += "WARNING:";
};
// May indicate sub-optimal usage of the API
if (flags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT)
{
prefix += "PERFORMANCE:";
};
// Informal messages that may become handy during debugging
if (flags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT)
{
prefix += "INFO:";
} }
// Diagnostic info from the Vulkan loader and layers else if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT) {
// Usually not helpful in terms of API usage, but may help to debug layer and loader problems prefix = "INFO: ";
if (flags & VK_DEBUG_REPORT_DEBUG_BIT_EXT)
{
prefix += "DEBUG:";
} }
else if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) {
prefix = "WARNING: ";
}
else if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) {
prefix = "ERROR: ";
}
// Display message to default output (console/logcat) // Display message to default output (console/logcat)
std::stringstream debugMessage; std::stringstream debugMessage;
debugMessage << prefix << " [" << pLayerPrefix << "] Code " << msgCode << " : " << pMsg; debugMessage << prefix << "[" << pCallbackData->messageIdNumber << "][" << pCallbackData->pMessageIdName << "] : " << pCallbackData->pMessage;
#if defined(__ANDROID__) #if defined(__ANDROID__)
if (flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) { if (messageSeverity >= VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) {
LOGE("%s", debugMessage.str().c_str()); LOGE("%s", debugMessage.str().c_str());
} } else {
else {
LOGD("%s", debugMessage.str().c_str()); LOGD("%s", debugMessage.str().c_str());
} }
#else #else
if (flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) { if (messageSeverity >= VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) {
std::cerr << debugMessage.str() << "\n"; std::cerr << debugMessage.str() << "\n";
} } else {
else {
std::cout << debugMessage.str() << "\n"; std::cout << debugMessage.str() << "\n";
} }
fflush(stdout);
#endif #endif
fflush(stdout);
// The return value of this callback controls wether the Vulkan call that caused // The return value of this callback controls wether the Vulkan call that caused the validation message will be aborted or not
// the validation message will be aborted or not // We return VK_FALSE as we DON'T want Vulkan calls that cause a validation message to abort
// We return VK_FALSE as we DON'T want Vulkan calls that cause a validation message // If you instead want to have calls abort, pass in VK_TRUE and the function will return VK_ERROR_VALIDATION_FAILED_EXT
// (and return a VkResult) to abort
// If you instead want to have calls abort, pass in VK_TRUE and the function will
// return VK_ERROR_VALIDATION_FAILED_EXT
return VK_FALSE; return VK_FALSE;
} }
void setupDebugging(VkInstance instance, VkDebugReportFlagsEXT flags, VkDebugReportCallbackEXT callBack) void setupDebugging(VkInstance instance, VkDebugReportFlagsEXT flags, VkDebugReportCallbackEXT callBack)
{ {
CreateDebugReportCallback = reinterpret_cast<PFN_vkCreateDebugReportCallbackEXT>(vkGetInstanceProcAddr(instance, "vkCreateDebugReportCallbackEXT"));
DestroyDebugReportCallback = reinterpret_cast<PFN_vkDestroyDebugReportCallbackEXT>(vkGetInstanceProcAddr(instance, "vkDestroyDebugReportCallbackEXT"));
dbgBreakCallback = reinterpret_cast<PFN_vkDebugReportMessageEXT>(vkGetInstanceProcAddr(instance, "vkDebugReportMessageEXT"));
VkDebugReportCallbackCreateInfoEXT dbgCreateInfo = {}; vkCreateDebugUtilsMessengerEXT = reinterpret_cast<PFN_vkCreateDebugUtilsMessengerEXT>(vkGetInstanceProcAddr(instance, "vkCreateDebugUtilsMessengerEXT"));
dbgCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT; vkDestroyDebugUtilsMessengerEXT = reinterpret_cast<PFN_vkDestroyDebugUtilsMessengerEXT>(vkGetInstanceProcAddr(instance, "vkDestroyDebugUtilsMessengerEXT"));
dbgCreateInfo.pfnCallback = (PFN_vkDebugReportCallbackEXT)messageCallback;
dbgCreateInfo.flags = flags;
VkResult err = CreateDebugReportCallback( VkDebugUtilsMessengerCreateInfoEXT debugUtilsMessengerCI{};
instance, debugUtilsMessengerCI.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
&dbgCreateInfo, debugUtilsMessengerCI.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
nullptr, debugUtilsMessengerCI.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT;
(callBack != VK_NULL_HANDLE) ? &callBack : &msgCallback); debugUtilsMessengerCI.pfnUserCallback = debugUtilsMessengerCallback;
assert(!err); VkResult result = vkCreateDebugUtilsMessengerEXT(instance, &debugUtilsMessengerCI, nullptr, &debugUtilsMessenger);
assert(result == VK_SUCCESS);
} }
void freeDebugCallback(VkInstance instance) void freeDebugCallback(VkInstance instance)
{ {
if (msgCallback != VK_NULL_HANDLE) if (debugUtilsMessenger != VK_NULL_HANDLE)
{ {
DestroyDebugReportCallback(instance, msgCallback, nullptr); vkDestroyDebugUtilsMessengerEXT(instance, debugUtilsMessenger, nullptr);
} }
} }
} }

View file

@ -58,7 +58,7 @@ VkResult VulkanExampleBase::createInstance(bool enableValidation)
{ {
if (settings.validation) if (settings.validation)
{ {
instanceExtensions.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME); instanceExtensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
} }
instanceCreateInfo.enabledExtensionCount = (uint32_t)instanceExtensions.size(); instanceCreateInfo.enabledExtensionCount = (uint32_t)instanceExtensions.size();
instanceCreateInfo.ppEnabledExtensionNames = instanceExtensions.data(); instanceCreateInfo.ppEnabledExtensionNames = instanceExtensions.data();