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 let init = vulk::Init::load().context("Initializing Vulk")?;
42
43 let debug_utils_messenger_create_info_ext =
45 debug_utils::debug_utils_messenger_create_info_ext();
46
47 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 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 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 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 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}