143 lines
4.2 KiB
C++
143 lines
4.2 KiB
C++
#pragma once
|
|
|
|
#include <memory/pointer_types/null_on_move.hpp>
|
|
#include <renderer/vk/context/instance.hpp>
|
|
#include <renderer/vk/vulkan.hpp>
|
|
|
|
namespace lt::renderer::vk {
|
|
|
|
class Messenger
|
|
{
|
|
public:
|
|
// NOLINTNEXTLINE(performance-enum-size)
|
|
enum Severity : decltype(std::to_underlying(
|
|
VK_DEBUG_UTILS_MESSAGE_SEVERITY_FLAG_BITS_MAX_ENUM_EXT
|
|
))
|
|
{
|
|
verbose = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT,
|
|
info = VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT,
|
|
warning = VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT,
|
|
error = VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT,
|
|
|
|
all_severity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT
|
|
| VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT
|
|
| VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT
|
|
| VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT,
|
|
};
|
|
|
|
// NOLINTNEXTLINE(performance-enum-size)
|
|
enum Type : decltype(std::to_underlying(VK_DEBUG_UTILS_MESSAGE_TYPE_FLAG_BITS_MAX_ENUM_EXT))
|
|
{
|
|
general = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT,
|
|
validation = VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT,
|
|
performance = VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT,
|
|
|
|
// address_binding = VK_DEBUG_UTILS_MESSAGE_TYPE_DEVICE_ADDRESS_BINDING_BIT_EXT,
|
|
|
|
/** @note: does not include address binding yet. */
|
|
all_type = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT
|
|
| VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT
|
|
| VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT,
|
|
};
|
|
|
|
using CallbackData_T = const VkDebugUtilsMessengerCallbackDataEXT *;
|
|
|
|
using Callback_T = std::function<void(
|
|
Severity message_severity,
|
|
Type message_type,
|
|
CallbackData_T vulkan_data,
|
|
void *user_data
|
|
)>;
|
|
|
|
struct CreateInfo
|
|
{
|
|
Severity severity;
|
|
|
|
Type type;
|
|
|
|
Callback_T callback;
|
|
|
|
void *user_data;
|
|
};
|
|
|
|
explicit Messenger(CreateInfo info)
|
|
: m_callback(std::move(info.callback))
|
|
, m_user_data(info.user_data)
|
|
{
|
|
ensure(m_callback, "Failed to initialize vk::Messenger: null callback");
|
|
ensure(info.severity != Severity {}, "Failed to initialize vk::Messenger: null severity");
|
|
ensure(info.type != Type {}, "Failed to initialize vk::Messenger: null type");
|
|
|
|
// Instance may not be initialized yet
|
|
// Making it get initialized inside a call to vk_create_debug_messenger
|
|
// Which would invoke a nullptr...
|
|
if (!vk_create_debug_messenger)
|
|
{
|
|
Instance::get();
|
|
}
|
|
|
|
const auto vulkan_info = VkDebugUtilsMessengerCreateInfoEXT {
|
|
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,
|
|
.messageSeverity = info.severity,
|
|
.messageType = info.type,
|
|
.pfnUserCallback = &validation_layers_callback,
|
|
.pUserData = this,
|
|
};
|
|
|
|
ensure(
|
|
!vk_create_debug_messenger(Instance::get(), &vulkan_info, nullptr, &m_debug_messenger),
|
|
"Failed to create vulkan debug utils messenger"
|
|
);
|
|
}
|
|
|
|
~Messenger()
|
|
{
|
|
vk_destroy_debug_messenger(Instance::get(), m_debug_messenger, nullptr);
|
|
}
|
|
|
|
Messenger(Messenger &&) = default;
|
|
|
|
Messenger(const Messenger &) = delete;
|
|
|
|
auto operator=(Messenger &&) -> Messenger & = default;
|
|
|
|
auto operator=(const Messenger &) const -> Messenger & = delete;
|
|
|
|
|
|
private:
|
|
static auto validation_layers_callback(
|
|
VkDebugUtilsMessageSeverityFlagBitsEXT const message_severity,
|
|
VkDebugUtilsMessageTypeFlagsEXT const message_type,
|
|
VkDebugUtilsMessengerCallbackDataEXT const *const callback_data,
|
|
void *const vulkan_user_data
|
|
) -> VkBool32
|
|
{
|
|
auto *messenger = (Messenger *)vulkan_user_data; // NOLINT
|
|
ensure(messenger, "Null vulkan_user_data received in messenger callback");
|
|
|
|
messenger->validation_layers_callback_impl(message_severity, message_type, callback_data);
|
|
return VK_FALSE;
|
|
}
|
|
|
|
void validation_layers_callback_impl(
|
|
VkDebugUtilsMessageSeverityFlagBitsEXT message_severity,
|
|
VkDebugUtilsMessageTypeFlagsEXT message_type,
|
|
const VkDebugUtilsMessengerCallbackDataEXT *callback_data
|
|
)
|
|
{
|
|
m_callback(
|
|
static_cast<Severity>(message_severity),
|
|
static_cast<Type>(message_type),
|
|
callback_data,
|
|
m_user_data
|
|
);
|
|
}
|
|
|
|
memory::NullOnMove<VkDebugUtilsMessengerEXT> m_debug_messenger = VK_NULL_HANDLE;
|
|
|
|
Callback_T m_callback;
|
|
|
|
void *m_user_data;
|
|
};
|
|
|
|
} // namespace lt::renderer::vk
|