97 lines
3.3 KiB
C++
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
|
|
);
|
|
}
|