demo_vk/graphics/vulkan/raii/
device_extensions.rs

1//! RAII wrappers for Vulkan objects that extend the Vulkan device.
2
3use {crate::graphics::vulkan::raii, anyhow::Result, ash::vk, std::sync::Arc};
4
5macro_rules! device_extension {
6    (
7        $name: ident,
8        $ext_type: ty,
9        $raw_type: ty,
10        $destroy: ident
11    ) => {
12        /// RAII wrapper that destroys itself when Dropped.
13        ///
14        /// The owner is responsible for dropping Vulkan resources in the
15        /// correct order.
16        pub struct $name {
17            pub ext: $ext_type,
18            pub raw: $raw_type,
19            pub device: Arc<raii::Device>,
20        }
21
22        impl std::fmt::Debug for $name {
23            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
24                f.debug_struct(stringify!($name))
25                    .field("ext", &"<extension loader>")
26                    .field("raw", &self.raw)
27                    .field("device", &self.device)
28                    .finish()
29            }
30        }
31
32        impl std::ops::Deref for $name {
33            type Target = $raw_type;
34
35            fn deref(&self) -> &Self::Target {
36                &self.raw
37            }
38        }
39
40        impl Drop for $name {
41            fn drop(&mut self) {
42                unsafe { self.ext.$destroy(self.raw, None) }
43            }
44        }
45    };
46}
47
48device_extension!(
49    Swapchain,
50    ash::khr::swapchain::Device,
51    vk::SwapchainKHR,
52    destroy_swapchain
53);
54
55impl Swapchain {
56    pub fn new(
57        device: Arc<raii::Device>,
58        create_info: &vk::SwapchainCreateInfoKHR,
59    ) -> Result<Arc<Self>> {
60        let ext = ash::khr::swapchain::Device::new(&device.ash, &device);
61        let raw = unsafe { ext.create_swapchain(create_info, None)? };
62        Ok(Arc::new(Self { ext, raw, device }))
63    }
64}