layers/extensions passed to Vulkan::new honored now

also permit extensions to fail being used while still creating a device
This commit is contained in:
Janis 2025-01-01 21:34:18 +01:00
parent a26b0d16db
commit 669a4a0a3f
2 changed files with 49 additions and 35 deletions

View file

@ -27,3 +27,4 @@ egui = { workspace = true , features = ["bytemuck"]}
egui_winit_platform = { workspace = true }
bytemuck = { version = "1.21.0", features = ["derive"] }
indexmap = "2.7.0"
itertools = "0.14.0"

View file

@ -1163,18 +1163,35 @@ impl Vulkan {
let mut validation_info =
vk::LayerSettingsCreateInfoEXT::default().settings(&validation_settings);
let layers = Self::get_layers(&entry, &[Self::VALIDATION_LAYER_NAME]).unwrap();
// optional display handle
let extensions = Self::get_extensions(
let layers = Self::get_layers(
&entry,
&layers,
// &[ash::ext::debug_utils::NAME, ash::ext::layer_settings::NAME],
&[ash::ext::debug_utils::NAME],
display_handle,
instance_layers
.into_iter()
.chain(&[
#[cfg(debug_assertions)]
Self::VALIDATION_LAYER_NAME,
])
.cloned(),
)
.unwrap();
let (extensions, unsupported_extensions) = Self::get_extensions(
&entry,
&layers,
instance_extensions
.into_iter()
.chain([ash::ext::debug_utils::NAME, ash::ext::layer_settings::NAME].iter())
.cloned(),
display_handle,
)?;
if !unsupported_extensions.is_empty() {
tracing::error!(
"extensions were requested but not supported by instance: {:?}",
unsupported_extensions
);
}
let layers = VkNameList::from_strs(&layers);
let extensions = VkNameList::from_strs(&extensions);
@ -1580,38 +1597,35 @@ impl Vulkan {
}
}
/// returns a tuple of supported/enabled extensions and unsupported/requested extensions
fn get_extensions<'a>(
entry: &ash::Entry,
layers: &[&'a CStr],
extensions: &[&'a CStr],
extensions: impl Iterator<Item = &'a CStr> + 'a,
display_handle: Option<RawDisplayHandle>,
) -> core::result::Result<Vec<&'a CStr>, (Vec<&'a CStr>, Vec<&'a CStr>)> {
) -> Result<(Vec<&'a CStr>, Vec<&'a CStr>)> {
unsafe {
let available_extensions = Self::get_available_extensions(entry, layers)
.map_err(|_| (Vec::<&'a CStr>::new(), extensions.to_vec()))?;
let available_extensions = Self::get_available_extensions(entry, layers)?;
let available_extension_names = available_extensions
.iter()
.map(|layer| layer.extension_name_as_c_str())
.collect::<core::result::Result<BTreeSet<_>, _>>()
.map_err(|_| (Vec::<&'a CStr>::new(), extensions.to_vec()))?;
.filter_map(|layer| layer.extension_name_as_c_str().ok())
.collect::<BTreeSet<_>>();
let mut out_extensions = Vec::with_capacity(extensions.len());
let mut unsupported_extensions = Vec::with_capacity(extensions.len());
for &extension in extensions {
if available_extension_names.contains(&extension) {
let mut out_extensions = Vec::new();
let mut unsupported_extensions = Vec::new();
for extension in extensions {
if available_extension_names.contains(extension) {
out_extensions.push(extension);
} else {
unsupported_extensions.push(extension);
}
}
let Ok(required_extension_names) = display_handle
let required_extension_names = display_handle
.map(|display_handle| ash_window::enumerate_required_extensions(display_handle))
.unwrap_or(Ok(&[]))
else {
return Err((out_extensions, unsupported_extensions));
};
.unwrap_or(Ok(&[]))?;
for &extension in required_extension_names {
let extension = core::ffi::CStr::from_ptr(extension);
@ -1622,31 +1636,30 @@ impl Vulkan {
}
}
if !unsupported_extensions.is_empty() {
Err((out_extensions, unsupported_extensions))
} else {
Ok(out_extensions)
}
Ok((out_extensions, unsupported_extensions))
}
}
fn get_layers<'a>(
entry: &ash::Entry,
wants_layers: &[&'a CStr],
wants_layers: impl Iterator<Item = &'a CStr> + 'a,
) -> core::result::Result<Vec<&'a CStr>, (Vec<&'a CStr>, Vec<&'a CStr>)> {
unsafe {
let wants_layers = wants_layers.collect::<Vec<_>>();
let available_layers = entry
.enumerate_instance_layer_properties()
.map_err(|_| (Vec::<&'a CStr>::new(), wants_layers.to_vec()))?;
.map_err(|_| (Vec::<&'a CStr>::new(), wants_layers.clone()))?;
let available_layer_names = available_layers
.iter()
.map(|layer| layer.layer_name_as_c_str())
.collect::<core::result::Result<BTreeSet<_>, _>>()
.map_err(|_| (Vec::<&'a CStr>::new(), wants_layers.to_vec()))?;
.map_err(|_| (Vec::<&'a CStr>::new(), wants_layers.clone()))?;
let mut out_layers = Vec::with_capacity(wants_layers.len());
let mut unsupported_layers = Vec::with_capacity(wants_layers.len());
for &layer in wants_layers {
let mut out_layers = Vec::new();
let mut unsupported_layers = Vec::new();
for layer in wants_layers {
if available_layer_names.contains(&layer) {
out_layers.push(layer);
} else {