2022-03-06 19:30:49 +00:00
|
|
|
use vulkano::{
|
|
|
|
device::{
|
2022-09-10 06:00:08 +00:00
|
|
|
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
2022-03-06 19:30:49 +00:00
|
|
|
},
|
|
|
|
instance::{
|
2022-04-16 12:54:32 +00:00
|
|
|
debug::{
|
|
|
|
DebugUtilsMessageSeverity, DebugUtilsMessageType, DebugUtilsMessenger,
|
2023-08-05 18:57:37 +00:00
|
|
|
DebugUtilsMessengerCallback, DebugUtilsMessengerCreateInfo,
|
2022-04-16 12:54:32 +00:00
|
|
|
},
|
2023-06-17 20:18:48 +00:00
|
|
|
Instance, InstanceCreateFlags, InstanceCreateInfo, InstanceExtensions,
|
2022-03-06 19:30:49 +00:00
|
|
|
},
|
2022-07-30 06:53:52 +00:00
|
|
|
VulkanLibrary,
|
2022-03-06 19:30:49 +00:00
|
|
|
};
|
2016-08-02 02:56:27 +00:00
|
|
|
|
|
|
|
fn main() {
|
|
|
|
// Vulkano Debugging Example Code
|
|
|
|
//
|
2018-09-02 04:18:22 +00:00
|
|
|
// This example code will demonstrate using the debug functions of the Vulkano API.
|
2016-08-02 02:56:27 +00:00
|
|
|
//
|
|
|
|
// There is documentation here about how to setup debugging:
|
|
|
|
// https://vulkan.lunarg.com/doc/view/1.0.13.0/windows/layers.html
|
|
|
|
//
|
|
|
|
// .. but if you just want a template of code that has everything ready to go then follow
|
2023-03-05 18:56:35 +00:00
|
|
|
// this example. First, enable debugging using this extension: `VK_EXT_debug_utils`.
|
2016-08-02 02:56:27 +00:00
|
|
|
let extensions = InstanceExtensions {
|
2019-10-20 20:26:07 +00:00
|
|
|
ext_debug_utils: true,
|
2022-09-05 20:16:40 +00:00
|
|
|
..InstanceExtensions::empty()
|
2016-08-02 02:56:27 +00:00
|
|
|
};
|
|
|
|
|
2022-07-30 06:53:52 +00:00
|
|
|
let library = VulkanLibrary::new().unwrap();
|
|
|
|
|
2023-03-05 18:56:35 +00:00
|
|
|
// You also need to specify (unless you've used the methods linked above) which debugging
|
|
|
|
// layers your code should use. Each layer is a bunch of checks or messages that provide
|
|
|
|
// information of some sort.
|
2016-08-02 02:56:27 +00:00
|
|
|
//
|
2023-03-05 18:56:35 +00:00
|
|
|
// The main layer you might want is `VK_LAYER_LUNARG_standard_validation`. This includes a
|
|
|
|
// number of the other layers for you and is quite detailed.
|
2016-08-02 02:56:27 +00:00
|
|
|
//
|
2018-09-02 04:18:22 +00:00
|
|
|
// Additional layers can be installed (gpu vendor provided, something you found on GitHub, etc)
|
|
|
|
// and you should verify that list for safety - Vulkano will return an error if you specify
|
2016-08-02 02:56:27 +00:00
|
|
|
// any layers that are not installed on this system. That code to do could look like this:
|
|
|
|
println!("List of Vulkan debugging layers available to use:");
|
2022-08-12 10:18:35 +00:00
|
|
|
let layers = library.layer_properties().unwrap();
|
|
|
|
for l in layers {
|
2016-08-02 02:56:27 +00:00
|
|
|
println!("\t{}", l.name());
|
|
|
|
}
|
|
|
|
|
2023-03-05 18:56:35 +00:00
|
|
|
// NOTE: To simplify the example code we won't verify these layer(s) are actually in the layers
|
|
|
|
// list.
|
2022-02-14 09:32:27 +00:00
|
|
|
let layers = vec!["VK_LAYER_KHRONOS_validation".to_owned()];
|
2016-08-02 02:56:27 +00:00
|
|
|
|
2023-03-05 18:56:35 +00:00
|
|
|
// Important: pass the extension(s) and layer(s) when creating the vulkano instance.
|
2022-07-30 06:53:52 +00:00
|
|
|
let instance = Instance::new(
|
|
|
|
library,
|
|
|
|
InstanceCreateInfo {
|
2023-06-17 20:18:48 +00:00
|
|
|
flags: InstanceCreateFlags::ENUMERATE_PORTABILITY,
|
2022-07-30 06:53:52 +00:00
|
|
|
enabled_layers: layers,
|
2023-06-17 20:18:48 +00:00
|
|
|
enabled_extensions: extensions,
|
2022-07-30 06:53:52 +00:00
|
|
|
..Default::default()
|
|
|
|
},
|
|
|
|
)
|
2022-02-14 09:32:27 +00:00
|
|
|
.expect("failed to create Vulkan instance");
|
2016-08-02 02:56:27 +00:00
|
|
|
|
2023-03-05 18:56:35 +00:00
|
|
|
// After creating the instance we must register the debug callback.
|
|
|
|
//
|
|
|
|
// NOTE: If you let this debug_callback binding fall out of scope then the callback will stop
|
|
|
|
// providing events.
|
2022-04-16 12:54:32 +00:00
|
|
|
let _debug_callback = unsafe {
|
|
|
|
DebugUtilsMessenger::new(
|
|
|
|
instance.clone(),
|
|
|
|
DebugUtilsMessengerCreateInfo {
|
2022-11-05 05:02:28 +00:00
|
|
|
message_severity: DebugUtilsMessageSeverity::ERROR
|
|
|
|
| DebugUtilsMessageSeverity::WARNING
|
|
|
|
| DebugUtilsMessageSeverity::INFO
|
|
|
|
| DebugUtilsMessageSeverity::VERBOSE,
|
|
|
|
message_type: DebugUtilsMessageType::GENERAL
|
|
|
|
| DebugUtilsMessageType::VALIDATION
|
|
|
|
| DebugUtilsMessageType::PERFORMANCE,
|
2023-08-05 18:57:37 +00:00
|
|
|
..DebugUtilsMessengerCreateInfo::user_callback(DebugUtilsMessengerCallback::new(
|
|
|
|
|message_severity, message_type, callback_data| {
|
|
|
|
let severity = if message_severity
|
|
|
|
.intersects(DebugUtilsMessageSeverity::ERROR)
|
|
|
|
{
|
|
|
|
"error"
|
|
|
|
} else if message_severity.intersects(DebugUtilsMessageSeverity::WARNING) {
|
|
|
|
"warning"
|
|
|
|
} else if message_severity.intersects(DebugUtilsMessageSeverity::INFO) {
|
|
|
|
"information"
|
|
|
|
} else if message_severity.intersects(DebugUtilsMessageSeverity::VERBOSE) {
|
|
|
|
"verbose"
|
|
|
|
} else {
|
|
|
|
panic!("no-impl");
|
|
|
|
};
|
2019-10-20 20:26:07 +00:00
|
|
|
|
2023-08-05 18:57:37 +00:00
|
|
|
let ty = if message_type.intersects(DebugUtilsMessageType::GENERAL) {
|
|
|
|
"general"
|
|
|
|
} else if message_type.intersects(DebugUtilsMessageType::VALIDATION) {
|
|
|
|
"validation"
|
|
|
|
} else if message_type.intersects(DebugUtilsMessageType::PERFORMANCE) {
|
|
|
|
"performance"
|
|
|
|
} else {
|
|
|
|
panic!("no-impl");
|
|
|
|
};
|
2019-10-20 20:26:07 +00:00
|
|
|
|
2023-08-05 18:57:37 +00:00
|
|
|
println!(
|
|
|
|
"{} {} {}: {}",
|
|
|
|
callback_data.message_id_name.unwrap_or("unknown"),
|
|
|
|
ty,
|
|
|
|
severity,
|
|
|
|
callback_data.message
|
|
|
|
);
|
|
|
|
},
|
|
|
|
))
|
2022-04-16 12:54:32 +00:00
|
|
|
},
|
|
|
|
)
|
2024-10-23 10:07:00 +00:00
|
|
|
}
|
|
|
|
.ok();
|
2016-08-02 02:56:27 +00:00
|
|
|
|
2023-03-05 18:56:35 +00:00
|
|
|
// Create Vulkan objects in the same way as the other examples.
|
2021-06-28 06:24:44 +00:00
|
|
|
let device_extensions = DeviceExtensions {
|
2022-09-05 20:16:40 +00:00
|
|
|
..DeviceExtensions::empty()
|
2021-06-28 06:24:44 +00:00
|
|
|
};
|
2022-09-10 06:00:08 +00:00
|
|
|
let (physical_device, queue_family_index) = instance
|
|
|
|
.enumerate_physical_devices()
|
|
|
|
.unwrap()
|
|
|
|
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
2022-08-12 10:18:35 +00:00
|
|
|
.map(|p| {
|
2022-09-10 06:00:08 +00:00
|
|
|
(!p.queue_family_properties().is_empty())
|
|
|
|
.then_some((p, 0))
|
2022-08-12 10:18:35 +00:00
|
|
|
.expect("couldn't find a queue family")
|
2021-06-28 06:24:44 +00:00
|
|
|
})
|
2021-08-09 13:44:58 +00:00
|
|
|
.min_by_key(|(p, _)| match p.properties().device_type {
|
2021-06-28 06:24:44 +00:00
|
|
|
PhysicalDeviceType::DiscreteGpu => 0,
|
|
|
|
PhysicalDeviceType::IntegratedGpu => 1,
|
|
|
|
PhysicalDeviceType::VirtualGpu => 2,
|
|
|
|
PhysicalDeviceType::Cpu => 3,
|
|
|
|
PhysicalDeviceType::Other => 4,
|
2022-09-05 20:16:40 +00:00
|
|
|
_ => 5,
|
2021-06-28 06:24:44 +00:00
|
|
|
})
|
2020-05-10 00:36:20 +00:00
|
|
|
.expect("no device available");
|
2021-06-28 06:24:44 +00:00
|
|
|
|
2024-03-13 16:37:28 +00:00
|
|
|
let (_device, _queues) = Device::new(
|
2021-06-28 06:24:44 +00:00
|
|
|
physical_device,
|
2022-02-14 09:32:27 +00:00
|
|
|
DeviceCreateInfo {
|
2022-07-18 13:11:43 +00:00
|
|
|
enabled_extensions: device_extensions,
|
2022-09-10 06:00:08 +00:00
|
|
|
queue_create_infos: vec![QueueCreateInfo {
|
|
|
|
queue_family_index,
|
|
|
|
..Default::default()
|
|
|
|
}],
|
2022-02-14 09:32:27 +00:00
|
|
|
..Default::default()
|
|
|
|
},
|
2020-05-10 00:36:20 +00:00
|
|
|
)
|
|
|
|
.expect("failed to create device");
|
2016-08-02 02:56:27 +00:00
|
|
|
|
2023-03-05 18:56:35 +00:00
|
|
|
// (At this point you should see a bunch of messages printed to the terminal window -
|
|
|
|
// have fun debugging!)
|
2016-08-02 02:56:27 +00:00
|
|
|
}
|