// Copyright (c) 2016 The vulkano developers // Licensed under the Apache License, Version 2.0 // or the MIT // license , // 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::device::physical::PhysicalDevice; pub use crate::extensions::{ ExtensionRestriction, ExtensionRestrictionError, SupportedExtensionsError, }; macro_rules! device_extensions { ( $($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),*], required_if_supported: $required_if_supported:expr, conflicts_device_extensions: [$($conflicts_device_extension:ident),*], },)* ) => ( extensions! { DeviceExtensions, $( $member => { doc: $doc, raw: $raw, requires_core: $requires_core, requires_device_extensions: [$($requires_device_extension),*], requires_instance_extensions: [$($requires_instance_extension),*], },)* } impl DeviceExtensions { /// Checks enabled extensions against the device version, instance extensions and each other. pub(super) fn check_requirements( &self, supported: &DeviceExtensions, api_version: crate::Version, instance_extensions: &InstanceExtensions, ) -> 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), }); } $( if !self.$requires_device_extension { return Err(crate::extensions::ExtensionRestrictionError { extension: stringify!($member), restriction: crate::extensions::ExtensionRestriction::RequiresDeviceExtension(stringify!($requires_device_extension)), }); } )* $( if !instance_extensions.$requires_instance_extension { return Err(crate::extensions::ExtensionRestrictionError { extension: stringify!($member), restriction: crate::extensions::ExtensionRestriction::RequiresInstanceExtension(stringify!($requires_instance_extension)), }); } )* $( if self.$conflicts_device_extension { return Err(crate::extensions::ExtensionRestrictionError { extension: stringify!($member), restriction: crate::extensions::ExtensionRestriction::ConflictsDeviceExtension(stringify!($conflicts_device_extension)), }); } )* } else { if $required_if_supported && supported.$member { return Err(crate::extensions::ExtensionRestrictionError { extension: stringify!($member), restriction: crate::extensions::ExtensionRestriction::RequiredIfSupported, }); } } )* Ok(()) } pub(crate) fn required_if_supported_extensions() -> Self { Self { $( $member: $required_if_supported, )* _unbuildable: crate::extensions::Unbuildable(()) } } } ); } pub use crate::autogen::DeviceExtensions; pub(crate) use device_extensions; impl DeviceExtensions { /// See the docs of supported_by_device(). #[deprecated( since = "0.25", note = "Use PhysicalDevice::supported_extensions instead" )] pub fn supported_by_device_raw( physical_device: PhysicalDevice, ) -> Result { Ok(*physical_device.supported_extensions()) } /// Returns a `DeviceExtensions` object with extensions supported by the `PhysicalDevice`. #[deprecated( since = "0.25", note = "Use PhysicalDevice::supported_extensions instead" )] pub fn supported_by_device(physical_device: PhysicalDevice) -> Self { *physical_device.supported_extensions() } /// Returns a `DeviceExtensions` object with extensions required as well as supported by the `PhysicalDevice`. /// They are needed to be passed to `Device::new(...)`. #[deprecated( since = "0.25", note = "Use PhysicalDevice::required_extensions instead" )] pub fn required_extensions(physical_device: PhysicalDevice) -> Self { *physical_device.required_extensions() } } /// This helper type can only be instantiated inside this module. /// See `*Extensions::_unbuildable`. #[doc(hidden)] #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub struct Unbuildable(()); #[cfg(test)] mod tests { use crate::device::DeviceExtensions; use std::ffi::CString; #[test] fn empty_extensions() { let d: Vec = (&DeviceExtensions::none()).into(); assert!(d.iter().next().is_none()); } #[test] fn required_if_supported_extensions() { assert_eq!( DeviceExtensions::required_if_supported_extensions(), DeviceExtensions { khr_portability_subset: true, ..DeviceExtensions::none() } ) } }