device: allow attributes in device_owned_handle types, fix device creation

This commit is contained in:
Janis 2025-01-19 18:45:42 +01:00
parent 0db6b7790d
commit b2730fecbd

View file

@ -1,6 +1,6 @@
use std::{ use std::{
borrow::Cow, borrow::Cow,
collections::{BTreeMap, BTreeSet, HashSet}, collections::{BTreeMap, BTreeSet, HashMap, HashSet},
ffi::{CStr, CString}, ffi::{CStr, CString},
ops::Deref, ops::Deref,
sync::Arc, sync::Arc,
@ -192,11 +192,11 @@ impl<'a> Default for DeviceDesc<'a> {
app_version: Default::default(), app_version: Default::default(),
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
layers: &DEBUG_LAYERS, layers: &DEBUG_LAYERS,
#[cfg(not(debug_assertions))]
layers: &[],
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
layer_settings: Self::debug_layer_settings(), layer_settings: Self::debug_layer_settings(),
#[cfg(not(debug_assertions))] #[cfg(not(debug_assertions))]
layers: &[],
#[cfg(not(debug_assertions))]
layer_settings: &[], layer_settings: &[],
instance_extensions: Default::default(), instance_extensions: Default::default(),
display_handle: Default::default(), display_handle: Default::default(),
@ -509,18 +509,20 @@ impl DeviceBuilder {
let available_extension_names = available_extensions let available_extension_names = available_extensions
.iter() .iter()
.filter_map(|ext| { .filter_map(|ext| {
Some(Extension { Some((
name: ext.extension_name_as_c_str().ok()?.to_str().ok()?, ext.extension_name_as_c_str().ok()?.to_str().ok()?,
version: ext.spec_version, ext.spec_version,
}) ))
}) })
.collect::<HashSet<_>>(); .collect::<HashMap<_, _>>();
let mut out_extensions = Vec::new(); let mut out_extensions = Vec::new();
let mut unsupported_extensions = Vec::new(); let mut unsupported_extensions = Vec::new();
for extension in extensions { for extension in extensions {
if available_extension_names.contains(&extension) { if let Some(available_version) = available_extension_names.get(&extension.name)
&& *available_version >= extension.version
{
out_extensions.push(extension); out_extensions.push(extension);
} else { } else {
unsupported_extensions.push(extension); unsupported_extensions.push(extension);
@ -537,7 +539,10 @@ impl DeviceBuilder {
name: extension.to_str()?, name: extension.to_str()?,
version: 0, version: 0,
}; };
if available_extension_names.contains(&extension) {
if let Some(available_version) = available_extension_names.get(&extension.name)
&& *available_version >= extension.version
{
out_extensions.push(extension); out_extensions.push(extension);
} else { } else {
unsupported_extensions.push(extension); unsupported_extensions.push(extension);
@ -589,7 +594,10 @@ pub struct Device(Arc<DeviceInner>);
pub type WeakDevice = std::sync::Weak<DeviceInner>; pub type WeakDevice = std::sync::Weak<DeviceInner>;
impl Device { impl Device {
pub fn new_from_default_desc(display_handle: Option<RawDisplayHandle>) -> crate::Result<Self> { pub fn new_from_default_desc(
display_handle: Option<RawDisplayHandle>,
with_instance_extensions: &[Extension<'_>],
) -> crate::Result<Self> {
Self::new_from_desc(DeviceDesc { Self::new_from_desc(DeviceDesc {
app_name: Some("Vidya"), app_name: Some("Vidya"),
app_version: vk::make_api_version(0, 0, 1, 0), app_version: vk::make_api_version(0, 0, 1, 0),
@ -634,10 +642,12 @@ impl Device {
khr::spirv_1_4::NAME, khr::spirv_1_4::NAME,
khr::spirv_1_4::SPEC_VERSION, khr::spirv_1_4::SPEC_VERSION,
)]), )]),
instance_extensions: with_instance_extensions,
..Default::default() ..Default::default()
}) })
} }
pub fn new_from_desc(desc: DeviceDesc) -> crate::Result<Self> { pub fn new_from_desc(desc: DeviceDesc) -> crate::Result<Self> {
tracing::debug!("creating new device with: {desc:#?}");
let entry = unsafe { ash::Entry::load()? }; let entry = unsafe { ash::Entry::load()? };
let app_name = desc let app_name = desc
@ -648,27 +658,30 @@ impl Device {
let app_info = vk::ApplicationInfo::default() let app_info = vk::ApplicationInfo::default()
.api_version(desc.features.version) .api_version(desc.features.version)
.application_name(&app_name) .application_name(&app_name)
.engine_name(c"VidyaEngine")
.application_version(desc.app_version) .application_version(desc.app_version)
.engine_name(c"VidyaEngine")
.engine_version(vk::make_api_version(0, 0, 1, 0)); .engine_version(vk::make_api_version(0, 0, 1, 0));
let mut validation_info = let mut validation_info =
vk::LayerSettingsCreateInfoEXT::default().settings(&desc.layer_settings); vk::LayerSettingsCreateInfoEXT::default().settings(&desc.layer_settings);
let extra_layers = (!desc.layer_settings.is_empty()) cfg_if::cfg_if! {
.then_some(Extension { if #[cfg(debug_assertions)] {
name: "VK_EXT_debug_utils", let debug_layers = [Extension {
version: 1,
})
.into_iter()
.chain(
cfg_if::cfg_if! {if #[cfg(debug_assertions)] {
[Extension {
name: "VK_EXT_layer_settings", name: "VK_EXT_layer_settings",
version: 2, version: 2,
}]} else {[]}} }];
.into_iter(), } else {
); let debug_layers = [];
}
};
let extra_instance_extensions = [Extension {
name: "VK_EXT_debug_utils",
version: 1,
}]
.into_iter()
.chain(debug_layers.into_iter());
let layers = DeviceBuilder::get_layers(&entry, desc.layers.into_iter().cloned()).unwrap(); let layers = DeviceBuilder::get_layers(&entry, desc.layers.into_iter().cloned()).unwrap();
@ -678,7 +691,7 @@ impl Device {
desc.instance_extensions desc.instance_extensions
.into_iter() .into_iter()
.cloned() .cloned()
.chain(extra_layers), .chain(extra_instance_extensions),
desc.display_handle, desc.display_handle,
)?; )?;
@ -698,6 +711,10 @@ impl Device {
.enabled_layer_names(&layers.names) .enabled_layer_names(&layers.names)
.push_next(&mut validation_info); .push_next(&mut validation_info);
tracing::debug!(
"Creating instance:\napp_info: {app_info:#?}\ncreate_info: {create_info:#?}"
);
let instance = unsafe { entry.create_instance(&create_info, None)? }; let instance = unsafe { entry.create_instance(&create_info, None)? };
let debug_info = vk::DebugUtilsMessengerCreateInfoEXT::default() let debug_info = vk::DebugUtilsMessengerCreateInfoEXT::default()
@ -962,8 +979,8 @@ impl AsRef<ash::khr::swapchain::Device> for DeviceAndQueues {
#[derive(Clone)] #[derive(Clone)]
pub struct DeviceOwnedDebugObject<T> { pub struct DeviceOwnedDebugObject<T> {
device: Device, pub(crate) device: Device,
object: T, pub(crate) object: T,
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
name: Option<Cow<'static, str>>, name: Option<Cow<'static, str>>,
} }
@ -1034,19 +1051,20 @@ pub trait DeviceOwned<T> {
macro_rules! define_device_owned_handle { macro_rules! define_device_owned_handle {
($(#[$attr:meta])* ($(#[$attr:meta])*
$ty_vis:vis $ty:ident($handle:ty) { $ty_vis:vis $ty:ident($handle:ty) {
$($field_vis:vis $field_name:ident : $field_ty:ty),* $($(#[$field_attr:meta])* $field_vis:vis $field_name:ident : $field_ty:ty),*
$(,)? $(,)?
} $(=> |$this:ident| $dtor:stmt)?) => { } $(=> |$this:ident| $dtor:stmt)?) => {
$(#[$attr])* $(#[$attr])*
$ty_vis struct $ty { $ty_vis struct $ty {
inner: crate::device::DeviceOwnedDebugObject<$handle>, inner: crate::device::DeviceOwnedDebugObject<$handle>,
$( $(
$(#[$field_attr])*
$field_vis $field_name: $field_ty, $field_vis $field_name: $field_ty,
)* )*
} }
impl crate::device::DeviceOwned<$handle> for $ty { impl crate::device::DeviceOwned<$handle> for $ty {
fn device(&self) -> &Device { fn device(&self) -> &crate::device::Device {
self.inner.dev() self.inner.dev()
} }
fn handle(&self) -> $handle { fn handle(&self) -> $handle {