Skip to main content

ursus_core/vulkan/core/
instance.rs

1use ash::vk;
2use raw_window_handle::RawDisplayHandle;
3
4pub struct Instance {
5    pub entry: ash::Entry,
6    pub handle: ash::Instance,
7    pub validation_active: bool,
8    pub debug_utils_active: bool,
9}
10
11impl Instance {
12    pub fn new(display: RawDisplayHandle, validation: bool, debug_labels: bool) -> anyhow::Result<Self> {
13        let entry = unsafe { ash::Entry::load()? };
14
15        let mut extensions = ash_window::enumerate_required_extensions(display)?.to_vec();
16
17        let need_debug_utils = validation || debug_labels;
18        if need_debug_utils {
19            extensions.push(ash::ext::debug_utils::NAME.as_ptr());
20        }
21
22        if validation {
23            extensions.push(ash::ext::debug_utils::NAME.as_ptr());
24        }
25
26        let validation_active = validation && Self::has_validation(&entry);
27        let layers: Vec<*const i8> = if validation_active {
28            log::info!("Validation layers enabled");
29            vec![c"VK_LAYER_KHRONOS_validation".as_ptr()]
30        } else {
31            if validation {
32                log::warn!("VK_LAYER_KHRONOS_validation not found - running without validation");
33            }
34            vec![]
35        };
36
37        let app_name = c"ursus-core";
38        let engine_name = c"ursus-core";
39
40        let app_info = vk::ApplicationInfo::default()
41            .application_name(app_name)
42            .engine_name(engine_name)
43            .api_version(vk::API_VERSION_1_3);
44
45        let create_info = vk::InstanceCreateInfo::default()
46            .application_info(&app_info)
47            .enabled_extension_names(&extensions)
48            .enabled_layer_names(&layers);
49
50        let handle = unsafe { entry.create_instance(&create_info, None)? };
51        log::info!("Vulkan instance created (API 1.3)");
52
53        Ok(Self { entry, handle, validation_active, debug_utils_active: need_debug_utils })
54    }
55
56    fn has_validation(entry: &ash::Entry) -> bool {
57        let Ok(layers) = (unsafe { entry.enumerate_instance_layer_properties() }) else {
58            return false;
59        };
60        layers.iter().any(|l| {
61            let name = unsafe { std::ffi::CStr::from_ptr(l.layer_name.as_ptr()) };
62            name == c"VK_LAYER_KHRONOS_validation"
63        })
64    }
65}
66
67impl Drop for Instance {
68    fn drop(&mut self) {
69        unsafe { self.handle.destroy_instance(None) };
70        log::info!("Vulkan instance уничтожен");
71    }
72}