aboutsummaryrefslogtreecommitdiff
path: root/src/instance/extensions.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/instance/extensions.rs')
-rw-r--r--src/instance/extensions.rs153
1 files changed, 153 insertions, 0 deletions
diff --git a/src/instance/extensions.rs b/src/instance/extensions.rs
new file mode 100644
index 0000000..dab0b12
--- /dev/null
+++ b/src/instance/extensions.rs
@@ -0,0 +1,153 @@
+// Copyright (c) 2016 The vulkano developers
+// Licensed under the Apache License, Version 2.0
+// <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT
+// license <LICENSE-MIT or https://opensource.org/licenses/MIT>,
+// at your option. All files in the project carrying such
+// notice may not be copied, modified, or distributed except
+// according to those terms.
+
+use crate::check_errors;
+pub use crate::extensions::{
+ ExtensionRestriction, ExtensionRestrictionError, SupportedExtensionsError,
+};
+use crate::instance::loader;
+use crate::instance::loader::LoadingError;
+use std::ffi::CStr;
+use std::ptr;
+
+macro_rules! instance_extensions {
+ (
+ $($member:ident => {
+ doc: $doc:expr,
+ raw: $raw:expr,
+ requires_core: $requires_core:expr,
+ requires_instance_extensions: [$($requires_instance_extension:ident),*]$(,)?
+ },)*
+ ) => (
+ extensions! {
+ InstanceExtensions,
+ $($member => {
+ doc: $doc,
+ raw: $raw,
+ requires_core: $requires_core,
+ requires_device_extensions: [],
+ requires_instance_extensions: [$($requires_instance_extension),*],
+ },)*
+ }
+
+ impl InstanceExtensions {
+ /// Checks enabled extensions against the instance version and each other.
+ pub(super) fn check_requirements(
+ &self,
+ supported: &InstanceExtensions,
+ api_version: crate::Version,
+ ) -> Result<(), crate::extensions::ExtensionRestrictionError> {
+ $(
+ if self.$member {
+ if !supported.$member {
+ return Err(crate::extensions::ExtensionRestrictionError {
+ extension: stringify!($member),
+ restriction: crate::extensions::ExtensionRestriction::NotSupported,
+ });
+ }
+
+ if api_version < $requires_core {
+ return Err(crate::extensions::ExtensionRestrictionError {
+ extension: stringify!($member),
+ restriction: crate::extensions::ExtensionRestriction::RequiresCore($requires_core),
+ });
+ } else {
+ $(
+ if !self.$requires_instance_extension {
+ return Err(crate::extensions::ExtensionRestrictionError {
+ extension: stringify!($member),
+ restriction: crate::extensions::ExtensionRestriction::RequiresInstanceExtension(stringify!($requires_instance_extension)),
+ });
+ }
+ )*
+ }
+ }
+ )*
+ Ok(())
+ }
+ }
+ );
+}
+
+pub use crate::autogen::InstanceExtensions;
+pub(crate) use instance_extensions;
+
+impl InstanceExtensions {
+ /// See the docs of supported_by_core().
+ pub fn supported_by_core_raw() -> Result<Self, SupportedExtensionsError> {
+ InstanceExtensions::supported_by_core_raw_with_loader(loader::auto_loader()?)
+ }
+
+ /// Returns an `InstanceExtensions` object with extensions supported by the core driver.
+ pub fn supported_by_core() -> Result<Self, LoadingError> {
+ match InstanceExtensions::supported_by_core_raw() {
+ Ok(l) => Ok(l),
+ Err(SupportedExtensionsError::LoadingError(e)) => Err(e),
+ Err(SupportedExtensionsError::OomError(e)) => panic!("{:?}", e),
+ }
+ }
+
+ /// Same as `supported_by_core`, but allows specifying a loader.
+ pub fn supported_by_core_with_loader<L>(
+ ptrs: &loader::FunctionPointers<L>,
+ ) -> Result<Self, LoadingError>
+ where
+ L: loader::Loader,
+ {
+ match InstanceExtensions::supported_by_core_raw_with_loader(ptrs) {
+ Ok(l) => Ok(l),
+ Err(SupportedExtensionsError::LoadingError(e)) => Err(e),
+ Err(SupportedExtensionsError::OomError(e)) => panic!("{:?}", e),
+ }
+ }
+
+ /// See the docs of supported_by_core().
+ pub fn supported_by_core_raw_with_loader<L>(
+ ptrs: &loader::FunctionPointers<L>,
+ ) -> Result<Self, SupportedExtensionsError>
+ where
+ L: loader::Loader,
+ {
+ let fns = ptrs.fns();
+
+ let properties: Vec<ash::vk::ExtensionProperties> = unsafe {
+ let mut num = 0;
+ check_errors(fns.v1_0.enumerate_instance_extension_properties(
+ ptr::null(),
+ &mut num,
+ ptr::null_mut(),
+ ))?;
+
+ let mut properties = Vec::with_capacity(num as usize);
+ check_errors(fns.v1_0.enumerate_instance_extension_properties(
+ ptr::null(),
+ &mut num,
+ properties.as_mut_ptr(),
+ ))?;
+ properties.set_len(num as usize);
+ properties
+ };
+
+ Ok(Self::from(properties.iter().map(|property| unsafe {
+ CStr::from_ptr(property.extension_name.as_ptr())
+ })))
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use crate::instance::InstanceExtensions;
+ use std::ffi::CString;
+
+ #[test]
+ fn empty_extensions() {
+ let i: Vec<CString> = (&InstanceExtensions::none()).into();
+ assert!(i.iter().next().is_none());
+ }
+}