diff --git a/src/vulkan/utils/layers.rs b/src/vulkan/utils/layers.rs index 9a6fa2e..0c82dc2 100644 --- a/src/vulkan/utils/layers.rs +++ b/src/vulkan/utils/layers.rs @@ -1,17 +1,29 @@ use std::ffi::CString; +pub enum LayersSelector<'a> { + Nothing, + SpecificLayers(Vec<&'a str>), + All +} + pub fn use_layers( entry: &ash::Entry, - layers_to_select: Vec<&str>, + selector: LayersSelector, ) -> Vec { - let layers_available = get_layers_available(entry); - - let selected_layers = select_layers(&layers_available, &layers_to_select); - - selected_layers + let layers_available = get_layers_available(entry) .iter() - .map(|sl| CString::new(sl.clone().as_bytes()).unwrap()) - .collect::>() + .filter_map(|layer| { + layer.layer_name_as_c_str() + .and_then(|layer_name| Ok(CString::from(layer_name))) + .ok() + }) + .collect::>(); + + match selector { + LayersSelector::Nothing => Vec::new(), + LayersSelector::SpecificLayers(layers) => select_layers(&layers_available, &layers), + LayersSelector::All => layers_available, + } } fn get_layers_available(entry: &ash::Entry) -> Vec { @@ -19,20 +31,21 @@ fn get_layers_available(entry: &ash::Entry) -> Vec { } fn select_layers( - layers_available: &[ash::vk::LayerProperties], + layers_available: &Vec, layers_to_select: &[&str], -) -> Vec { - layers_available +) -> Vec { + layers_to_select .iter() - .filter_map(|l| { - let layer_name = l - .layer_name_as_c_str() - .unwrap_or_default() - .to_string_lossy(); - layers_to_select - .iter() - .find(|&&ln| ln == layer_name) - .map(|_| layer_name.into_owned()) + .filter_map(|layer_name| { + if layers_available.iter().any(|layer_available| { + layer_available.to_str() + .and_then(|layer_available| Ok(layer_available.eq(*layer_name))) + .unwrap_or(false) + }) { + CString::new(*layer_name).ok() + } else { + None + } }) - .collect() + .collect::>() } diff --git a/src/vulkan/utils/mod.rs b/src/vulkan/utils/mod.rs index 39400d8..e5f7be3 100644 --- a/src/vulkan/utils/mod.rs +++ b/src/vulkan/utils/mod.rs @@ -1,5 +1,5 @@ mod layers; -pub use layers::use_layers; +pub use layers::{use_layers, LayersSelector}; pub fn print_version(version: u32) -> String { format!( diff --git a/src/vulkan/vk_instance.rs b/src/vulkan/vk_instance.rs index b949812..cf1c8d5 100644 --- a/src/vulkan/vk_instance.rs +++ b/src/vulkan/vk_instance.rs @@ -3,7 +3,7 @@ use std::fmt::{Display, Formatter}; use ash::{Instance, vk, Entry}; use ash::khr::surface; use winit::raw_window_handle::{HasDisplayHandle, HasWindowHandle}; -use crate::vulkan::utils::use_layers; +use crate::vulkan::utils::{use_layers, LayersSelector}; use crate::vulkan::vk_surface::VkSurface; use crate::vulkan::VkPhysicalDevice; @@ -19,11 +19,15 @@ impl VkInstance { 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 = use_layers( + &entry, + LayersSelector::SpecificLayers(vec![ + "VK_LAYER_KHRONOS_validation", + "VK_LAYER_MANGOHUD_overlay_x86_64", + "VK_LAYER_NV_optimus" + ]) + ); + log::info!("{:?}", layers); let layers_raw = layers.iter().map(|s| s.as_ptr()).collect::>(); // App Info