demo_vk/graphics/vulkan/raii/
device.rs

1use {
2    crate::{graphics::vulkan::raii, unwrap_here},
3    anyhow::Result,
4    ash::{
5        ext::debug_utils,
6        vk::{self, Handle},
7    },
8    std::{ffi::CString, sync::Arc},
9};
10
11/// A RAII wrapper for the Vulkan Logical Device.
12pub struct Device {
13    debug_utils: Option<Arc<ash::ext::debug_utils::Device>>,
14    pub raw: ash::Device,
15    pub ash: Arc<raii::Instance>,
16}
17
18impl Device {
19    pub fn new(
20        instance: Arc<raii::Instance>,
21        physical_device: vk::PhysicalDevice,
22        create_info: &vk::DeviceCreateInfo,
23    ) -> Result<Arc<Self>> {
24        let raw = unsafe {
25            instance
26                .raw
27                .create_device(physical_device, create_info, None)?
28        };
29
30        let debug_utils = Self::create_debug_utils(&instance.raw, &raw);
31        if let Some(debug_utils) = debug_utils.as_ref() {
32            let name = CString::new("My Device").unwrap();
33            unsafe {
34                debug_utils.set_debug_utils_object_name(
35                    &vk::DebugUtilsObjectNameInfoEXT {
36                        object_type: vk::ObjectType::DEVICE,
37                        object_handle: raw.handle().as_raw(),
38                        p_object_name: name.as_ptr(),
39                        ..Default::default()
40                    },
41                )?;
42            }
43        }
44        Ok(Arc::new(Self {
45            debug_utils,
46            raw,
47            ash: instance,
48        }))
49    }
50
51    #[cfg(not(debug_assertions))]
52    pub fn set_debug_name(
53        &self,
54        name_info: &vk::DebugUtilsObjectNameInfoEXT,
55    ) -> Result<()> {
56        Ok(())
57    }
58
59    #[cfg(debug_assertions)]
60    pub fn set_debug_name(
61        &self,
62        name_info: &vk::DebugUtilsObjectNameInfoEXT,
63    ) -> Result<()> {
64        unwrap_here!(format!("Set debug name: {:#?}", name_info), unsafe {
65            self.debug_utils
66                .as_ref()
67                .unwrap()
68                .set_debug_utils_object_name(name_info)
69        });
70        Ok(())
71    }
72
73    #[cfg(not(debug_assertions))]
74    fn create_debug_utils(
75        instance: &ash::Instance,
76        device: &ash::Device,
77    ) -> Option<Arc<debug_utils::Device>> {
78        None
79    }
80
81    #[cfg(debug_assertions)]
82    fn create_debug_utils(
83        instance: &ash::Instance,
84        device: &ash::Device,
85    ) -> Option<Arc<debug_utils::Device>> {
86        Some(Arc::new(ash::ext::debug_utils::Device::new(
87            instance, device,
88        )))
89    }
90}
91
92impl Drop for Device {
93    fn drop(&mut self) {
94        unsafe { self.raw.destroy_device(None) }
95    }
96}
97
98impl std::fmt::Debug for Device {
99    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
100        f.debug_struct("Device")
101            .field("raw", &"<raw vulkan device handle>")
102            .field("ash", &self.ash)
103            .finish()
104    }
105}
106
107impl std::ops::Deref for Device {
108    type Target = ash::Device;
109
110    fn deref(&self) -> &Self::Target {
111        &self.raw
112    }
113}