1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
use std::{error::Error, ffi::CString};
use ash::{extensions::ext::DebugUtils, vk};
pub(crate) struct DebugLayer {
pub(crate) loader: ash::extensions::ext::DebugUtils,
pub(crate) callback: vk::DebugUtilsMessengerEXT,
}
pub enum DebugOption {
None,
Validation,
Debug,
}
impl DebugOption {
pub(crate) fn cons(
&self
) -> Result<(Vec<CString>, vk::DebugUtilsMessengerCreateInfoEXT), Box<dyn Error>> {
let mut layer_names: Vec<CString> = Vec::new();
match self {
DebugOption::None => {},
DebugOption::Validation => {
layer_names.push(CString::new("VK_LAYER_KHRONOS_validation")?);
},
DebugOption::Debug => {
layer_names.push(CString::new("VK_LAYER_KHRONOS_validation")?);
layer_names.push(CString::new("VK_LAYER_LUNARG_api_dump")?);
},
}
let mut debug_info = vk::DebugUtilsMessengerCreateInfoEXT {
..Default::default()
};
match self {
DebugOption::None => {},
_ => {
debug_info = vk::DebugUtilsMessengerCreateInfoEXT {
message_severity: vk::DebugUtilsMessageSeverityFlagsEXT::WARNING
| vk::DebugUtilsMessageSeverityFlagsEXT::VERBOSE
| vk::DebugUtilsMessageSeverityFlagsEXT::INFO
| vk::DebugUtilsMessageSeverityFlagsEXT::ERROR,
message_type: vk::DebugUtilsMessageTypeFlagsEXT::GENERAL
| vk::DebugUtilsMessageTypeFlagsEXT::PERFORMANCE
| vk::DebugUtilsMessageTypeFlagsEXT::VALIDATION,
pfn_user_callback: Some(DebugLayer::vulkan_debug_utils_callback),
..Default::default()
};
}
}
Ok((layer_names, debug_info))
}
}
impl DebugLayer {
pub(crate) unsafe extern "system" fn vulkan_debug_utils_callback(
message_severity: vk::DebugUtilsMessageSeverityFlagsEXT,
message_type: vk::DebugUtilsMessageTypeFlagsEXT,
p_callback_data: *const vk::DebugUtilsMessengerCallbackDataEXT,
_p_user_data: *mut std::ffi::c_void,
) -> vk::Bool32 {
let message = std::ffi::CStr::from_ptr((*p_callback_data).p_message);
let severity = format!("{:?}", message_severity).to_lowercase();
let ty = format!("{:?}", message_type).to_lowercase();
println!("[Debug][{}][{}] {:?}", severity, ty, message);
vk::FALSE
}
pub(crate) fn new(
option: DebugOption,
info: &vk::DebugUtilsMessengerCreateInfoEXT,
entry: &ash::Entry,
instance: &ash::Instance
) -> Result<Option<DebugLayer>, Box<dyn Error>> {
match option {
DebugOption::None => Ok(None),
_ => {
let loader = DebugUtils::new(entry, instance);
let callback = unsafe { loader.create_debug_utils_messenger(info, None)? };
println!("Debug attached");
Ok(Some(DebugLayer{loader, callback}))
}
}
}
}
impl Drop for DebugLayer {
fn drop(
&mut self
) {
unsafe { self.loader.destroy_debug_utils_messenger(self.callback, None) }
}
}