demo_vk/graphics/vulkan/raii/
instance_extensions.rs1use {
4 crate::{graphics::vulkan::raii, trace},
5 anyhow::{bail, Result},
6 ash::vk::{self, Handle},
7 std::sync::Arc,
8};
9
10macro_rules! instance_extension {
11 (
12 $name: ident,
13 $ext_type: ty,
14 $raw_type: ty,
15 $destroy: ident
16 ) => {
17 pub struct $name {
22 pub ext: $ext_type,
23 pub raw: $raw_type,
24 pub ash: Arc<raii::Instance>,
25 }
26
27 impl std::fmt::Debug for $name {
28 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
29 f.debug_struct(stringify!($name))
30 .field("ext", &"<extension loader>")
31 .field("raw", &self.raw)
32 .field("ash", &self.ash)
33 .finish()
34 }
35 }
36
37 impl std::ops::Deref for $name {
38 type Target = $raw_type;
39
40 fn deref(&self) -> &Self::Target {
41 &self.raw
42 }
43 }
44
45 impl Drop for $name {
46 fn drop(&mut self) {
47 unsafe { self.ext.$destroy(self.raw, None) }
48 }
49 }
50 };
51}
52
53instance_extension!(
54 DebugUtils,
55 ash::ext::debug_utils::Instance,
56 vk::DebugUtilsMessengerEXT,
57 destroy_debug_utils_messenger
58);
59
60impl DebugUtils {
61 pub fn new(
62 ash: Arc<raii::Instance>,
63 create_info: &vk::DebugUtilsMessengerCreateInfoEXT,
64 ) -> Result<Arc<Self>> {
65 let ext = ash::ext::debug_utils::Instance::new(&ash.entry, &ash);
66 let raw =
67 unsafe { ext.create_debug_utils_messenger(create_info, None)? };
68 Ok(Arc::new(Self { ext, raw, ash }))
69 }
70}
71
72instance_extension!(
73 Surface,
74 ash::khr::surface::Instance,
75 vk::SurfaceKHR,
76 destroy_surface
77);
78
79impl Surface {
80 pub fn new(
81 ash: Arc<raii::Instance>,
82 raw: vk::SurfaceKHR,
83 ) -> Result<Arc<Self>> {
84 let ext = ash::khr::surface::Instance::new(&ash.entry, &ash);
85 Ok(Arc::new(Self { raw, ext, ash }))
86 }
87
88 pub fn for_window(
89 ash: Arc<raii::Instance>,
90 window: &glfw::Window,
91 ) -> Result<Arc<Self>> {
92 let handle = unsafe {
93 let mut surface: std::mem::MaybeUninit<vk::SurfaceKHR> =
94 std::mem::MaybeUninit::uninit();
95 let result = window.create_window_surface(
96 ash.raw.handle().as_raw() as _,
97 std::ptr::null(),
98 surface.as_mut_ptr() as _,
99 );
100 if result != vk::Result::SUCCESS.as_raw() {
101 bail!(trace!("Unable to create Vulkan window surface!")());
102 }
103 surface.assume_init()
104 };
105 Self::new(ash, handle)
106 }
107}