demo_vk/graphics/vulkan/raii/
device_extensions.rs

1//! RAII wrappers for Vulkan objects that extend the Vulkan device.
2
3use {
4    crate::{graphics::vulkan::raii, trace},
5    anyhow::{Context, Result},
6    ash::vk,
7    std::sync::Arc,
8};
9
10macro_rules! device_extension {
11    (
12        $name: ident,
13        $ext_type: ty,
14        $raw_type: ty,
15        $destroy: ident
16    ) => {
17        /// RAII wrapper that destroys itself when Dropped.
18        ///
19        /// The owner is responsible for dropping Vulkan resources in the
20        /// correct order.
21        pub struct $name {
22            pub ext: $ext_type,
23            pub raw: $raw_type,
24            pub device: Arc<raii::Device>,
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("device", &self.device)
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
53device_extension!(
54    Swapchain,
55    ash::khr::swapchain::Device,
56    vk::SwapchainKHR,
57    destroy_swapchain
58);
59
60impl Swapchain {
61    pub fn new(
62        device: Arc<raii::Device>,
63        create_info: &vk::SwapchainCreateInfoKHR,
64    ) -> Result<Arc<Self>> {
65        let ext = ash::khr::swapchain::Device::new(&device.ash, &device);
66        let raw = unsafe {
67            ext.create_swapchain(create_info, None)
68                .with_context(trace!("Error while creating swapchain!"))?
69        };
70        Ok(Arc::new(Self { ext, raw, device }))
71    }
72}