aboutsummaryrefslogtreecommitdiff
path: root/src/extensions.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/extensions.rs')
-rw-r--r--src/extensions.rs256
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) ());