Skip to content

Commit 8c7bfe7

Browse files
committed
ash runner: split it into different modules
1 parent af24205 commit 8c7bfe7

File tree

5 files changed

+950
-925
lines changed

5 files changed

+950
-925
lines changed

examples/runners/ash/src/device.rs

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
use crate::Options;
2+
use anyhow::{Context, anyhow};
3+
use ash::{ext, khr, vk};
4+
use std::borrow::Cow;
5+
use std::ffi::{CStr, c_char};
6+
use std::ops::Deref;
7+
use std::sync::Arc;
8+
9+
/// Central struct containing the Vulkan instance and device, among others
10+
pub struct MyDevice {
11+
pub entry: ash::Entry,
12+
pub instance: ash::Instance,
13+
pub physical_device: vk::PhysicalDevice,
14+
pub device: ash::Device,
15+
pub main_queue_family: u32,
16+
pub main_queue: vk::Queue,
17+
pub debug_ext_instance: ext::debug_utils::Instance,
18+
pub debug_ext_device: ext::debug_utils::Device,
19+
pub surface_ext: khr::surface::Instance,
20+
pub swapchain_ext: khr::swapchain::Device,
21+
debug_callback: vk::DebugUtilsMessengerEXT,
22+
}
23+
24+
impl Deref for MyDevice {
25+
type Target = ash::Device;
26+
27+
fn deref(&self) -> &Self::Target {
28+
&self.device
29+
}
30+
}
31+
32+
impl MyDevice {
33+
pub fn new(extension_names: &[*const c_char], options: &Options) -> anyhow::Result<Arc<Self>> {
34+
unsafe {
35+
cfg_if::cfg_if! {
36+
if #[cfg(target_os = "macos")] {
37+
let entry = ash_molten::load();
38+
} else {
39+
let entry = ash::Entry::load()?;
40+
}
41+
}
42+
43+
let instance = {
44+
let layer_names: &'static [_] = if options.debug_layer {
45+
const { &[c"VK_LAYER_KHRONOS_validation".as_ptr()] }
46+
} else {
47+
&[]
48+
};
49+
50+
let mut extension_names_raw = extension_names.to_vec();
51+
extension_names_raw.push(ext::debug_utils::NAME.as_ptr());
52+
53+
let app_name = c"VulkanTriangle";
54+
entry
55+
.create_instance(
56+
&vk::InstanceCreateInfo::default()
57+
.application_info(
58+
&vk::ApplicationInfo::default()
59+
.application_name(app_name)
60+
.application_version(0)
61+
.engine_name(app_name)
62+
.engine_version(0)
63+
.api_version(vk::make_api_version(0, 1, 3, 0)),
64+
)
65+
.enabled_layer_names(layer_names)
66+
.enabled_extension_names(&extension_names_raw),
67+
None,
68+
)
69+
.context("create_instance")?
70+
};
71+
72+
let debug_instance = ext::debug_utils::Instance::new(&entry, &instance);
73+
let debug_callback = {
74+
debug_instance.create_debug_utils_messenger(
75+
&vk::DebugUtilsMessengerCreateInfoEXT::default()
76+
.message_severity(
77+
vk::DebugUtilsMessageSeverityFlagsEXT::ERROR
78+
| vk::DebugUtilsMessageSeverityFlagsEXT::WARNING
79+
| vk::DebugUtilsMessageSeverityFlagsEXT::INFO,
80+
)
81+
.message_type(
82+
vk::DebugUtilsMessageTypeFlagsEXT::GENERAL
83+
| vk::DebugUtilsMessageTypeFlagsEXT::VALIDATION
84+
| vk::DebugUtilsMessageTypeFlagsEXT::PERFORMANCE,
85+
)
86+
.pfn_user_callback(Some(vulkan_debug_callback)),
87+
None,
88+
)?
89+
};
90+
91+
let physical_device = {
92+
instance
93+
.enumerate_physical_devices()?
94+
.into_iter()
95+
.min_by_key(|phy| {
96+
match instance.get_physical_device_properties(*phy).device_type {
97+
vk::PhysicalDeviceType::DISCRETE_GPU => 1,
98+
vk::PhysicalDeviceType::VIRTUAL_GPU => 2,
99+
vk::PhysicalDeviceType::INTEGRATED_GPU => 3,
100+
vk::PhysicalDeviceType::CPU => 4,
101+
_ => 5,
102+
}
103+
})
104+
.ok_or(anyhow!("No physical devices available"))?
105+
};
106+
107+
let main_queue_family = {
108+
instance
109+
.get_physical_device_queue_family_properties(physical_device)
110+
.into_iter()
111+
.enumerate()
112+
.find(|(_, prop)| prop.queue_flags.contains(vk::QueueFlags::GRAPHICS))
113+
.ok_or(anyhow!(
114+
"No graphics + compute queues on physical device available"
115+
))?
116+
.0 as u32
117+
};
118+
119+
let device = instance
120+
.create_device(
121+
physical_device,
122+
&vk::DeviceCreateInfo::default()
123+
.push_next(
124+
&mut vk::PhysicalDeviceVulkanMemoryModelFeatures::default()
125+
.vulkan_memory_model(true),
126+
)
127+
.push_next(
128+
&mut vk::PhysicalDeviceVulkan13Features::default()
129+
.synchronization2(true)
130+
.dynamic_rendering(true),
131+
)
132+
.queue_create_infos(&[vk::DeviceQueueCreateInfo::default()
133+
.queue_family_index(main_queue_family)
134+
.queue_priorities(&[1.0])])
135+
.enabled_extension_names(&[
136+
khr::swapchain::NAME.as_ptr(),
137+
khr::shader_non_semantic_info::NAME.as_ptr(),
138+
]),
139+
None,
140+
)
141+
.context("create_device")?;
142+
let main_queue = device.get_device_queue(main_queue_family, 0);
143+
144+
Ok(Arc::new(Self {
145+
debug_ext_device: ext::debug_utils::Device::new(&instance, &device),
146+
surface_ext: khr::surface::Instance::new(&entry, &instance),
147+
swapchain_ext: khr::swapchain::Device::new(&instance, &device),
148+
entry,
149+
instance,
150+
physical_device,
151+
device,
152+
main_queue_family,
153+
main_queue,
154+
debug_ext_instance: debug_instance,
155+
debug_callback,
156+
}))
157+
}
158+
}
159+
}
160+
161+
impl Drop for MyDevice {
162+
fn drop(&mut self) {
163+
unsafe {
164+
self.debug_ext_instance
165+
.destroy_debug_utils_messenger(self.debug_callback, None);
166+
self.device.destroy_device(None);
167+
self.instance.destroy_instance(None);
168+
}
169+
}
170+
}
171+
172+
unsafe extern "system" fn vulkan_debug_callback(
173+
message_severity: vk::DebugUtilsMessageSeverityFlagsEXT,
174+
_message_type: vk::DebugUtilsMessageTypeFlagsEXT,
175+
p_callback_data: *const vk::DebugUtilsMessengerCallbackDataEXT<'_>,
176+
_user_data: *mut std::os::raw::c_void,
177+
) -> vk::Bool32 {
178+
let callback_data = unsafe { *p_callback_data };
179+
let message_id_name = if callback_data.p_message_id_name.is_null() {
180+
Cow::from("")
181+
} else {
182+
unsafe { CStr::from_ptr(callback_data.p_message_id_name).to_string_lossy() }
183+
};
184+
let message = if callback_data.p_message.is_null() {
185+
Cow::from("")
186+
} else {
187+
unsafe { CStr::from_ptr(callback_data.p_message).to_string_lossy() }
188+
};
189+
println!("{message_severity:?}: [{message_id_name}] : {message}");
190+
vk::FALSE
191+
}

0 commit comments

Comments
 (0)