demo_vk/graphics/vulkan/context/instance/
mod.rs1mod debug;
2
3use {
4 crate::{graphics::vulkan::raii, unwrap_here},
5 anyhow::{Context, Result},
6 ash::vk,
7 std::{ffi::CStr, sync::Arc},
8 winit::{raw_window_handle::HasDisplayHandle, window::Window},
9};
10
11const VK_EXT_DEBUG_UTILS: &CStr = c"VK_EXT_debug_utils";
12
13pub struct Instance {
20 pub ash: Arc<raii::Instance>,
21 extensions: Vec<String>,
22 _debug_utils: Option<Arc<raii::DebugUtils>>,
23}
24
25impl Instance {
26 pub fn for_window(
28 app_name: impl AsRef<str>,
29 window: &Window,
30 ) -> Result<Self> {
31 let extensions = ash_window::enumerate_required_extensions(
32 window
33 .display_handle()
34 .with_context(|| "Unable to fetch display handle!")?
35 .as_raw(),
36 )?;
37 Self::new(app_name, extensions)
38 }
39
40 pub fn new(
42 app_name: impl AsRef<str>,
43 extensions: &[*const i8],
44 ) -> Result<Self> {
45 let ptrs = {
46 let mut ptrs = extensions.to_vec();
47 if cfg!(debug_assertions) {
48 ptrs.push(VK_EXT_DEBUG_UTILS.as_ptr());
49 }
50 ptrs
51 };
52
53 let app_name_c = std::ffi::CString::new(app_name.as_ref()).unwrap();
54 let engine_name = std::ffi::CString::new("N/A").unwrap();
55 let application_info = vk::ApplicationInfo {
56 p_application_name: app_name_c.as_ptr(),
57 application_version: vk::make_api_version(0, 1, 0, 0),
58 p_engine_name: engine_name.as_ptr(),
59 engine_version: vk::make_api_version(0, 1, 0, 0),
60 api_version: vk::make_api_version(0, 1, 3, 0),
61 ..Default::default()
62 };
63 let create_info = vk::InstanceCreateInfo {
64 p_application_info: &application_info,
65 enabled_extension_count: ptrs.len() as u32,
66 pp_enabled_extension_names: ptrs.as_ptr(),
67 ..Default::default()
68 };
69
70 let ash = unwrap_here!(
71 "Create Vulkan instance",
72 raii::Instance::new(&create_info)
73 );
74
75 let debug_utils = unwrap_here!(
76 "Setup debug logging.",
77 debug::setup_debug_logging(ash.clone())
78 );
79
80 Ok(Self {
81 ash,
82 extensions: ptrs
83 .iter()
84 .map(|&ptr| {
85 unsafe { CStr::from_ptr(ptr) }.to_string_lossy().to_string()
86 })
87 .collect(),
88 _debug_utils: debug_utils,
89 })
90 }
91}
92
93impl std::fmt::Debug for Instance {
94 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
95 f.debug_struct("Instance")
96 .field("extensions", &self.extensions)
97 .field("ash", &self.ash)
98 .finish()
99 }
100}
101
102impl std::ops::Deref for Instance {
103 type Target = ash::Instance;
104
105 fn deref(&self) -> &Self::Target {
106 &self.ash.raw
107 }
108}