vulkan-test/src/init/debug_messenger.cpp
2024-11-18 19:34:19 -05:00

97 lines
3.3 KiB
C++

#include <fmt/color.h>
#include <fmt/format.h>
#include "debug_messenger.hpp"
fn DebugMessenger::create(const vk::Instance& instance, Config config)
-> std::expected<vk::UniqueDebugUtilsMessengerEXT, std::string> {
#ifdef NDEBUG
return nullptr;
#else
try {
vk::DebugUtilsMessengerCreateInfoEXT createInfo {
.messageSeverity = config.severity_flags,
.messageType = config.type_flags,
.pfnUserCallback = debugCallback,
.pUserData = &config,
};
return instance.createDebugUtilsMessengerEXTUnique(createInfo);
} catch (const vk::SystemError& e) {
return std::unexpected(fmt::format("Failed to create debug messenger: {}", e.what()));
}
#endif
}
VKAPI_ATTR VkBool32 VKAPI_CALL DebugMessenger::debugCallback(
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
VkDebugUtilsMessageTypeFlagsEXT messageType,
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
void* pUserData
) {
const auto* config = static_cast<const Config*>(pUserData);
Message msg { .message = pCallbackData->pMessage,
.severity = static_cast<vk::DebugUtilsMessageSeverityFlagBitsEXT>(messageSeverity),
.type = static_cast<vk::DebugUtilsMessageTypeFlagsEXT>(messageType),
.function_name = pCallbackData->pMessageIdName
? std::optional<std::string_view>(pCallbackData->pMessageIdName)
: std::nullopt,
.id = pCallbackData->messageIdNumber };
const auto formattedMessage = formatMessage(msg);
if (config && config->use_stderr_for_errors &&
(messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT)) {
fmt::println(stderr, "{}", formattedMessage);
} else {
fmt::println("{}", formattedMessage);
}
return VK_FALSE;
}
fn DebugMessenger::formatMessage(const Message& msg) -> std::string {
// Color based on severity
fmt::color textColor = fmt::color::white;
std::string_view severityText;
switch (msg.severity) {
case vk::DebugUtilsMessageSeverityFlagBitsEXT::eVerbose:
textColor = fmt::color::light_blue;
severityText = "VERBOSE";
break;
case vk::DebugUtilsMessageSeverityFlagBitsEXT::eInfo:
textColor = fmt::color::white;
severityText = "INFO";
break;
case vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning:
textColor = fmt::color::yellow;
severityText = "WARNING";
break;
case vk::DebugUtilsMessageSeverityFlagBitsEXT::eError:
textColor = fmt::color::red;
severityText = "ERROR";
break;
}
// Build message type string
std::string typeStr;
if (msg.type & vk::DebugUtilsMessageTypeFlagBitsEXT::eGeneral)
typeStr += "GENERAL ";
if (msg.type & vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation)
typeStr += "VALIDATION ";
if (msg.type & vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance)
typeStr += "PERFORMANCE ";
// Format the message with color and structure
return fmt::format(
fmt::emphasis::bold | fg(textColor),
"[{}] {} {}{}: {}",
severityText,
typeStr,
msg.function_name.has_value() ? fmt::format("in {} ", *msg.function_name) : "",
msg.id,
msg.message
);
}