use super::*;
#[derive(Debug)]
pub(crate) struct DebugUtils {
debug_utils_messenger: vk::DebugUtilsMessengerEXT,
}
impl DebugUtils {
pub(crate) unsafe fn create(instance: &vulk::Instance) -> Result<Self> {
let debug_utils_messenger_create_info_ext = debug_utils_messenger_create_info_ext();
let debug_utils_messenger = instance
.create_debug_utils_messenger_ext(&raw const debug_utils_messenger_create_info_ext)?;
Ok(Self {
debug_utils_messenger,
})
}
pub(crate) unsafe fn destroy(&self, instance: &vulk::Instance) {
instance.destroy_debug_utils_messenger_ext(self.debug_utils_messenger);
}
}
pub(crate) fn debug_utils_messenger_create_info_ext() -> vk::DebugUtilsMessengerCreateInfoEXT {
let message_severity = vk::DebugUtilsMessageSeverityFlagBitsEXT::VerboseEXT
| vk::DebugUtilsMessageSeverityFlagBitsEXT::InfoEXT
| vk::DebugUtilsMessageSeverityFlagBitsEXT::WarningEXT
| vk::DebugUtilsMessageSeverityFlagBitsEXT::ErrorEXT;
let message_type = vk::DebugUtilsMessageTypeFlagBitsEXT::GeneralEXT
| vk::DebugUtilsMessageTypeFlagBitsEXT::ValidationEXT
| vk::DebugUtilsMessageTypeFlagBitsEXT::PerformanceEXT;
vk::DebugUtilsMessengerCreateInfoEXT {
s_type: vk::StructureType::DebugUtilsMessengerCreateInfoEXT,
p_next: null(),
flags: vk::DebugUtilsMessengerCreateFlagsEXT::empty(),
message_severity,
message_type,
pfn_user_callback: debug_utils_messenger_callback as _,
p_user_data: null_mut(),
}
}
unsafe extern "C" fn debug_utils_messenger_callback(
message_severity: vk::DebugUtilsMessageSeverityFlagBitsEXT,
message_type: vk::DebugUtilsMessageTypeFlagsEXT,
p_callback_data: *const vk::DebugUtilsMessengerCallbackDataEXT,
_user_data: *mut std::ffi::c_void,
) -> vk::Bool32 {
let callback_data = *p_callback_data;
let message_id_name = if callback_data.p_message_id_name.is_null() {
std::borrow::Cow::from("")
} else {
std::ffi::CStr::from_ptr(callback_data.p_message_id_name).to_string_lossy()
};
let message = if callback_data.p_message.is_null() {
std::borrow::Cow::from("")
} else {
std::ffi::CStr::from_ptr(callback_data.p_message).to_string_lossy()
};
let message_id_number: u32 = i32::cast_unsigned(callback_data.message_id_number);
if message_id_name == "Loader Message"
&& !message.starts_with("Loading layer library")
&& (message_severity == vk::DebugUtilsMessageSeverityFlagBitsEXT::InfoEXT
|| message_severity == vk::DebugUtilsMessageSeverityFlagBitsEXT::VerboseEXT)
{
return vk::FALSE;
}
if message_id_name == "UNASSIGNED-BestPractices-vkCreateInstance-specialuse-extension-debugging"
{
return vk::FALSE;
}
if message_id_name == "UNASSIGNED-BestPractices-vkBindBufferMemory-requirements-not-retrieved" {
return vk::FALSE;
}
if message_id_name == "UNASSIGNED-BestPractices-vkBindImageMemory-requirements-not-retrieved" {
return vk::FALSE;
}
if message_id_name == "UNASSIGNED-BestPractices-vkAllocateMemory-small-allocation" {
return vk::FALSE;
}
if message_id_name == "UNASSIGNED-BestPractices-vkBindMemory-small-dedicated-allocation" {
return vk::FALSE;
}
if message_id_name == "UNASSIGNED-BestPractices-pipeline-stage-flags" &&
message.contains("You are using VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT_KHR when vkCmdWriteTimestamp2 is called") {
return vk::FALSE;
}
let level = match message_severity {
vk::DebugUtilsMessageSeverityFlagBitsEXT::VerboseEXT => log::Level::Debug,
vk::DebugUtilsMessageSeverityFlagBitsEXT::InfoEXT => log::Level::Info,
vk::DebugUtilsMessageSeverityFlagBitsEXT::WarningEXT => log::Level::Warn,
vk::DebugUtilsMessageSeverityFlagBitsEXT::ErrorEXT => log::Level::Error,
};
log!(
level,
"message_type={message_type:?}, message_id_name={message_id_name}, message_id_number=0x{message_id_number:08x}, message={message}"
);
vk::FALSE
}