diff options
Diffstat (limited to 'src/extensions.rs')
-rw-r--r-- | src/extensions.rs | 256 |
1 files changed, 40 insertions, 216 deletions
diff --git a/src/extensions.rs b/src/extensions.rs index 822eb67..1e09e8b 100644 --- a/src/extensions.rs +++ b/src/extensions.rs @@ -7,192 +7,33 @@ // notice may not be copied, modified, or distributed except // according to those terms. -use crate::instance::loader::LoadingError; -use crate::Error; -use crate::OomError; -use crate::Version; -use std::error; -use std::fmt; - -macro_rules! extensions { - ( - $sname:ident, - $($member:ident => { - doc: $doc:expr, - raw: $raw:expr, - requires_core: $requires_core:expr, - requires_device_extensions: [$($requires_device_extension:ident),*], - requires_instance_extensions: [$($requires_instance_extension:ident),*]$(,)? - },)* - ) => ( - /// List of extensions that are enabled or available. - #[derive(Copy, Clone, PartialEq, Eq)] - pub struct $sname { - $( - #[doc = $doc] - pub $member: bool, - )* - - /// This field ensures that an instance of this `Extensions` struct - /// can only be created through Vulkano functions and the update - /// syntax. This way, extensions can be added to Vulkano without - /// breaking existing code. - pub _unbuildable: crate::extensions::Unbuildable, - } - - impl $sname { - /// Returns an `Extensions` object with all members set to `false`. - #[inline] - pub const fn none() -> $sname { - $sname { - $($member: false,)* - _unbuildable: crate::extensions::Unbuildable(()) - } - } - - /// Returns true if `self` is a superset of the parameter. - /// - /// That is, for each extension of the parameter that is true, the corresponding value - /// in self is true as well. - pub fn is_superset_of(&self, other: &$sname) -> bool { - $((self.$member == true || other.$member == false))&&+ - } - - /// Returns the union of this list and another list. - #[inline] - pub const fn union(&self, other: &$sname) -> $sname { - $sname { - $( - $member: self.$member || other.$member, - )* - _unbuildable: crate::extensions::Unbuildable(()) - } - } - - /// Returns the intersection of this list and another list. - #[inline] - pub const fn intersection(&self, other: &$sname) -> $sname { - $sname { - $( - $member: self.$member && other.$member, - )* - _unbuildable: crate::extensions::Unbuildable(()) - } - } - - /// Returns the difference of another list from this list. - #[inline] - pub const fn difference(&self, other: &$sname) -> $sname { - $sname { - $( - $member: self.$member && !other.$member, - )* - _unbuildable: crate::extensions::Unbuildable(()) - } - } - } - - impl std::fmt::Debug for $sname { - #[allow(unused_assignments)] - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - write!(f, "[")?; - - let mut first = true; - - $( - if self.$member { - if !first { write!(f, ", ")? } - else { first = false; } - f.write_str(std::str::from_utf8($raw).unwrap())?; - } - )* - - write!(f, "]") - } - } - - impl<'a, I> From<I> for $sname where I: IntoIterator<Item = &'a std::ffi::CStr> { - fn from(names: I) -> Self { - let mut extensions = Self::none(); - for name in names { - match name.to_bytes() { - $( - $raw => { extensions.$member = true; } - )* - _ => (), - } - } - extensions - } - } - - impl<'a> From<&'a $sname> for Vec<std::ffi::CString> { - fn from(x: &'a $sname) -> Self { - let mut data = Self::new(); - $(if x.$member { data.push(std::ffi::CString::new(&$raw[..]).unwrap()); })* - data - } - } - ); -} - -/// Error that can happen when loading the list of layers. +use crate::RequiresOneOf; +use bytemuck::cast_slice; +use std::{ + error::Error, + fmt::{Display, Error as FmtError, Formatter}, +}; + +/// Properties of an extension in the loader or a physical device. #[derive(Clone, Debug)] -pub enum SupportedExtensionsError { - /// Failed to load the Vulkan shared library. - LoadingError(LoadingError), - /// Not enough memory. - OomError(OomError), -} - -impl error::Error for SupportedExtensionsError { - #[inline] - fn source(&self) -> Option<&(dyn error::Error + 'static)> { - match *self { - SupportedExtensionsError::LoadingError(ref err) => Some(err), - SupportedExtensionsError::OomError(ref err) => Some(err), - } - } -} +pub struct ExtensionProperties { + /// The name of the extension. + pub extension_name: String, -impl fmt::Display for SupportedExtensionsError { - #[inline] - fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> { - write!( - fmt, - "{}", - match *self { - SupportedExtensionsError::LoadingError(_) => - "failed to load the Vulkan shared library", - SupportedExtensionsError::OomError(_) => "not enough memory available", - } - ) - } + /// The version of the extension. + pub spec_version: u32, } -impl From<OomError> for SupportedExtensionsError { +impl From<ash::vk::ExtensionProperties> for ExtensionProperties { #[inline] - fn from(err: OomError) -> SupportedExtensionsError { - SupportedExtensionsError::OomError(err) - } -} - -impl From<LoadingError> for SupportedExtensionsError { - #[inline] - fn from(err: LoadingError) -> SupportedExtensionsError { - SupportedExtensionsError::LoadingError(err) - } -} - -impl From<Error> for SupportedExtensionsError { - #[inline] - fn from(err: Error) -> SupportedExtensionsError { - match err { - err @ Error::OutOfHostMemory => SupportedExtensionsError::OomError(OomError::from(err)), - err @ Error::OutOfDeviceMemory => { - SupportedExtensionsError::OomError(OomError::from(err)) - } - _ => panic!("unexpected error: {:?}", err), + fn from(val: ash::vk::ExtensionProperties) -> Self { + Self { + extension_name: { + let bytes = cast_slice(val.extension_name.as_slice()); + let end = bytes.iter().position(|&b| b == 0).unwrap_or(bytes.len()); + String::from_utf8_lossy(&bytes[0..end]).into() + }, + spec_version: val.spec_version, } } } @@ -206,13 +47,12 @@ pub struct ExtensionRestrictionError { pub restriction: ExtensionRestriction, } -impl error::Error for ExtensionRestrictionError {} +impl Error for ExtensionRestrictionError {} -impl fmt::Display for ExtensionRestrictionError { - #[inline] - fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> { +impl Display for ExtensionRestrictionError { + fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> { write!( - fmt, + f, "a restriction for the extension {} was not met: {}", self.extension, self.restriction, ) @@ -223,49 +63,33 @@ impl fmt::Display for ExtensionRestrictionError { pub enum ExtensionRestriction { /// Not supported by the loader or physical device. NotSupported, - /// Requires a minimum Vulkan API version. - RequiresCore(Version), - /// Requires a device extension to be enabled. - RequiresDeviceExtension(&'static str), - /// Requires an instance extension to be enabled. - RequiresInstanceExtension(&'static str), /// Required to be enabled by the physical device. RequiredIfSupported, + /// Requires one of the following. + Requires(RequiresOneOf), /// Requires a device extension to be disabled. ConflictsDeviceExtension(&'static str), } -impl fmt::Display for ExtensionRestriction { - #[inline] - fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> { +impl Display for ExtensionRestriction { + fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> { match *self { ExtensionRestriction::NotSupported => { - write!(fmt, "not supported by the loader or physical device") - } - ExtensionRestriction::RequiresCore(version) => { - write!( - fmt, - "requires Vulkan API version {}.{}", - version.major, version.minor - ) - } - ExtensionRestriction::RequiresDeviceExtension(ext) => { - write!(fmt, "requires device extension {} to be enabled", ext) - } - ExtensionRestriction::RequiresInstanceExtension(ext) => { - write!(fmt, "requires instance extension {} to be enabled", ext) + write!(f, "not supported by the loader or physical device") } ExtensionRestriction::RequiredIfSupported => { - write!(fmt, "required to be enabled by the physical device") + write!(f, "required to be enabled by the physical device") + } + ExtensionRestriction::Requires(requires) => { + if requires.len() > 1 { + write!(f, "requires one of: {}", requires) + } else { + write!(f, "requires: {}", requires) + } } ExtensionRestriction::ConflictsDeviceExtension(ext) => { - write!(fmt, "requires device extension {} to be disabled", ext) + write!(f, "requires device extension {} to be disabled", ext) } } } } - -/// This helper type can only be instantiated inside this module. -#[doc(hidden)] -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub struct Unbuildable(pub(crate) ()); |