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