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:
parent
a26b0d16db
commit
669a4a0a3f
|
@ -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"
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in a new issue