vulkano/examples/debug/main.rs

158 lines
6.3 KiB
Rust

use vulkano::{
device::{
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
},
instance::{
debug::{
DebugUtilsMessageSeverity, DebugUtilsMessageType, DebugUtilsMessenger,
DebugUtilsMessengerCallback, DebugUtilsMessengerCreateInfo,
},
Instance, InstanceCreateFlags, InstanceCreateInfo, InstanceExtensions,
},
VulkanLibrary,
};
fn main() {
// Vulkano Debugging Example Code
//
// This example code will demonstrate using the debug functions of the Vulkano API.
//
// 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
// this example. First, enable debugging using this extension: `VK_EXT_debug_utils`.
let extensions = InstanceExtensions {
ext_debug_utils: true,
..InstanceExtensions::empty()
};
let library = VulkanLibrary::new().unwrap();
// 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.
//
// 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.
//
// 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
// 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:");
let layers = library.layer_properties().unwrap();
for l in layers {
println!("\t{}", l.name());
}
// NOTE: To simplify the example code we won't verify these layer(s) are actually in the layers
// list.
let layers = vec!["VK_LAYER_KHRONOS_validation".to_owned()];
// Important: pass the extension(s) and layer(s) when creating the vulkano instance.
let instance = Instance::new(
library,
InstanceCreateInfo {
flags: InstanceCreateFlags::ENUMERATE_PORTABILITY,
enabled_layers: layers,
enabled_extensions: extensions,
..Default::default()
},
)
.expect("failed to create Vulkan instance");
// 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.
let _debug_callback = unsafe {
DebugUtilsMessenger::new(
instance.clone(),
DebugUtilsMessengerCreateInfo {
message_severity: DebugUtilsMessageSeverity::ERROR
| DebugUtilsMessageSeverity::WARNING
| DebugUtilsMessageSeverity::INFO
| DebugUtilsMessageSeverity::VERBOSE,
message_type: DebugUtilsMessageType::GENERAL
| DebugUtilsMessageType::VALIDATION
| DebugUtilsMessageType::PERFORMANCE,
..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");
};
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");
};
println!(
"{} {} {}: {}",
callback_data.message_id_name.unwrap_or("unknown"),
ty,
severity,
callback_data.message
);
},
))
},
)
}
.ok();
// Create Vulkan objects in the same way as the other examples.
let device_extensions = DeviceExtensions {
..DeviceExtensions::empty()
};
let (physical_device, queue_family_index) = instance
.enumerate_physical_devices()
.unwrap()
.filter(|p| p.supported_extensions().contains(&device_extensions))
.map(|p| {
(!p.queue_family_properties().is_empty())
.then_some((p, 0))
.expect("couldn't find a queue family")
})
.min_by_key(|(p, _)| match p.properties().device_type {
PhysicalDeviceType::DiscreteGpu => 0,
PhysicalDeviceType::IntegratedGpu => 1,
PhysicalDeviceType::VirtualGpu => 2,
PhysicalDeviceType::Cpu => 3,
PhysicalDeviceType::Other => 4,
_ => 5,
})
.expect("no device available");
let (_device, _queues) = Device::new(
physical_device,
DeviceCreateInfo {
enabled_extensions: device_extensions,
queue_create_infos: vec![QueueCreateInfo {
queue_family_index,
..Default::default()
}],
..Default::default()
},
)
.expect("failed to create device");
// (At this point you should see a bunch of messages printed to the terminal window -
// have fun debugging!)
}