vulk_ext/vkx/
instance.rs

1use super::*;
2
3#[derive(Debug)]
4pub struct InstanceCreateInfo<'a> {
5    pub application_name: &'a str,
6    pub engine_name: &'a str,
7    pub validation_layers: bool,
8}
9
10impl Default for InstanceCreateInfo<'_> {
11    fn default() -> Self {
12        Self {
13            application_name: "vulk",
14            engine_name: "vulk",
15            validation_layers: true,
16        }
17    }
18}
19
20pub struct Instance {
21    _init: vulk::Init,
22    instance: vulk::Instance,
23    debug_utils: Option<DebugUtils>,
24    validation_layers: bool,
25}
26
27impl std::fmt::Debug for Instance {
28    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
29        f.debug_struct("Instance")
30            .field("_init", &"Init {..}")
31            .field("instance", &"Instance {..}")
32            .field("debug_utils", &self.debug_utils)
33            .field("validation_layers", &self.validation_layers)
34            .finish()
35    }
36}
37
38impl Instance {
39    pub unsafe fn create(create_info: &InstanceCreateInfo<'_>) -> Result<Self> {
40        // Vulk.
41        let init = vulk::Init::load().context("Initializing Vulk")?;
42
43        // Instance-specific debug messenger.
44        let debug_utils_messenger_create_info_ext =
45            debug_utils::debug_utils_messenger_create_info_ext();
46
47        // Validation features.
48        let enabled_validation_features = [
49            vk::ValidationFeatureEnableEXT::BestPracticesEXT,
50            vk::ValidationFeatureEnableEXT::SynchronizationValidationEXT,
51        ];
52        let validation_features_ext = vk::ValidationFeaturesEXT {
53            s_type: vk::StructureType::ValidationFeaturesEXT,
54            p_next: addr_of!(debug_utils_messenger_create_info_ext).cast(),
55            enabled_validation_feature_count: enabled_validation_features.len() as _,
56            p_enabled_validation_features: enabled_validation_features.as_ptr(),
57            disabled_validation_feature_count: 0,
58            p_disabled_validation_features: null(),
59        };
60
61        // Extensions.
62        let mut enabled_extension_names = vec![];
63        enabled_extension_names.extend_from_slice(&vulk::REQUIRED_INSTANCE_EXTENSIONS);
64        if create_info.validation_layers {
65            enabled_extension_names.extend_from_slice(&vulk::DEBUGGING_INSTANCE_EXTENSIONS);
66        }
67        if cfg!(windows) {
68            enabled_extension_names.extend_from_slice(&vulk::WIN32_INSTANCE_EXTENSIONS);
69        }
70
71        // Layers.
72        let mut enabled_layer_names = vec![];
73        if create_info.validation_layers {
74            enabled_layer_names.push(b"VK_LAYER_KHRONOS_validation\0".as_ptr().cast());
75        }
76
77        // Instance.
78        let application_name = std::ffi::CString::new(create_info.application_name)?;
79        let engine_name = std::ffi::CString::new(create_info.engine_name)?;
80        let instance = init.create_instance(&vk::InstanceCreateInfo {
81            s_type: vk::StructureType::InstanceCreateInfo,
82            p_next: addr_of!(validation_features_ext).cast(),
83            flags: vk::InstanceCreateFlags::empty(),
84            p_application_info: &vk::ApplicationInfo {
85                s_type: vk::StructureType::ApplicationInfo,
86                p_next: null(),
87                p_application_name: application_name.as_ptr(),
88                application_version: 1,
89                p_engine_name: engine_name.as_ptr(),
90                engine_version: 1,
91                api_version: vulk::REQUIRED_VULKAN_VERSION,
92            },
93            enabled_layer_count: enabled_layer_names.len() as _,
94            pp_enabled_layer_names: enabled_layer_names.as_ptr(),
95            enabled_extension_count: enabled_extension_names.len() as _,
96            pp_enabled_extension_names: enabled_extension_names.as_ptr(),
97        })?;
98        let instance = vulk::Instance::load(&init, instance)?;
99
100        // Debug utils.
101        let debug_utils = if create_info.validation_layers {
102            Some(debug_utils::DebugUtils::create(&instance)?)
103        } else {
104            None
105        };
106
107        Ok(Self {
108            _init: init,
109            instance,
110            debug_utils,
111            validation_layers: create_info.validation_layers,
112        })
113    }
114
115    pub unsafe fn destroy(self) {
116        if let Some(debug_utils) = self.debug_utils {
117            debug_utils.destroy(&self.instance);
118        }
119        self.instance.destroy_instance();
120    }
121
122    #[must_use]
123    pub fn validation_layers(&self) -> bool {
124        self.validation_layers
125    }
126}
127
128impl std::ops::Deref for Instance {
129    type Target = vulk::Instance;
130
131    fn deref(&self) -> &Self::Target {
132        &self.instance
133    }
134}