use std::ffi::CString; use ash::{Instance, vk, Entry}; use winit::raw_window_handle::{HasDisplayHandle}; use crate::vulkan::utils::use_layers; use crate::vulkan::VkPhysicalDevice; pub struct VkInstance { entry: Entry, handle: Instance, } impl VkInstance { pub fn new(window: &impl HasDisplayHandle) -> Self { let entry = Entry::linked(); // Layers let layers = use_layers(&entry, vec![ "VK_LAYER_KHRONOS_validation", "VK_LAYER_MANGOHUD_overlay_x86_64", "VK_LAYER_NV_optimus" ]); let layers_raw = layers.iter().map(|s| s.as_ptr()).collect::>(); // Extensions let mut extension_names = ash_window::enumerate_required_extensions(window.display_handle().expect("No display handle").as_raw()) .unwrap() .to_vec(); #[cfg(any(target_os = "macos", target_os = "ios"))] { extension_names.push(ash::khr::portability_enumeration::NAME.as_ptr()); // Enabling this extension is a requirement when using `VK_KHR_portability_subset` extension_names.push(ash::khr::get_physical_device_properties2::NAME.as_ptr()); } // App Info let app_name = CString::new("VulkanTriangle").unwrap(); let appinfo = vk::ApplicationInfo::default() .application_name(app_name.as_c_str()) .application_version(0) .engine_name(app_name.as_c_str()) .engine_version(0) .api_version(vk::make_api_version(0, 1, 0, 0)); let create_flags = if cfg!(any(target_os = "macos", target_os = "ios")) { vk::InstanceCreateFlags::ENUMERATE_PORTABILITY_KHR } else { vk::InstanceCreateFlags::default() }; // Instance Info let create_info = vk::InstanceCreateInfo::default() .application_info(&appinfo) .enabled_layer_names(&layers_raw) .enabled_extension_names(&extension_names) .flags(create_flags); let instance: Instance = unsafe { entry .create_instance(&create_info, None) .expect("Instance creation error") }; Self { entry, handle: instance } } pub fn get_physical_devices(&self) -> Vec { let physical_devices = unsafe { self.handle.enumerate_physical_devices() }; physical_devices .unwrap_or_default() .iter().map(|physical_device| VkPhysicalDevice::new(&self.handle, *physical_device)) .collect() } } impl Drop for VkInstance { fn drop(&mut self) { unsafe { self.handle.destroy_instance(None); } } }