From b7d0abb9ed3dd0c1d79dadc33c1d47d6b250711f Mon Sep 17 00:00:00 2001 From: Florian RICHER Date: Sun, 10 Nov 2024 19:10:16 +0100 Subject: [PATCH] Refactor layer selection logic for more flexibility Updated the layer selection logic to utilize an enum, LayersSelector, which supports selecting no layers, specific layers, or all available layers. This refactor enhances code clarity and allows for more flexible layer management. --- src/vulkan/utils/layers.rs | 55 +++++++++++++++++++++++--------------- src/vulkan/utils/mod.rs | 2 +- src/vulkan/vk_instance.rs | 16 ++++++----- 3 files changed, 45 insertions(+), 28 deletions(-) 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