• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2016 The vulkano developers
2 // Licensed under the Apache License, Version 2.0
3 // <LICENSE-APACHE or
4 // https://www.apache.org/licenses/LICENSE-2.0> or the MIT
5 // license <LICENSE-MIT or https://opensource.org/licenses/MIT>,
6 // at your option. All files in the project carrying such
7 // notice may not be copied, modified, or distributed except
8 // according to those terms.
9 
10 use crate::device::physical::PhysicalDevice;
11 pub use crate::extensions::{
12     ExtensionRestriction, ExtensionRestrictionError, SupportedExtensionsError,
13 };
14 
15 macro_rules! device_extensions {
16     (
17         $($member:ident => {
18             doc: $doc:expr,
19             raw: $raw:expr,
20             requires_core: $requires_core:expr,
21             requires_device_extensions: [$($requires_device_extension:ident),*],
22             requires_instance_extensions: [$($requires_instance_extension:ident),*],
23             required_if_supported: $required_if_supported:expr,
24             conflicts_device_extensions: [$($conflicts_device_extension:ident),*],
25         },)*
26     ) => (
27         extensions! {
28             DeviceExtensions,
29             $( $member => {
30                 doc: $doc,
31                 raw: $raw,
32                 requires_core: $requires_core,
33                 requires_device_extensions: [$($requires_device_extension),*],
34                 requires_instance_extensions: [$($requires_instance_extension),*],
35             },)*
36         }
37 
38         impl DeviceExtensions {
39             /// Checks enabled extensions against the device version, instance extensions and each other.
40             pub(super) fn check_requirements(
41                 &self,
42                 supported: &DeviceExtensions,
43                 api_version: crate::Version,
44                 instance_extensions: &InstanceExtensions,
45             ) -> Result<(), crate::extensions::ExtensionRestrictionError> {
46                 $(
47                     if self.$member {
48                         if !supported.$member {
49                             return Err(crate::extensions::ExtensionRestrictionError {
50                                 extension: stringify!($member),
51                                 restriction: crate::extensions::ExtensionRestriction::NotSupported,
52                             });
53                         }
54 
55                         if api_version < $requires_core {
56                             return Err(crate::extensions::ExtensionRestrictionError {
57                                 extension: stringify!($member),
58                                 restriction: crate::extensions::ExtensionRestriction::RequiresCore($requires_core),
59                             });
60                         }
61 
62                         $(
63                             if !self.$requires_device_extension {
64                                 return Err(crate::extensions::ExtensionRestrictionError {
65                                     extension: stringify!($member),
66                                     restriction: crate::extensions::ExtensionRestriction::RequiresDeviceExtension(stringify!($requires_device_extension)),
67                                 });
68                             }
69                         )*
70 
71                         $(
72                             if !instance_extensions.$requires_instance_extension {
73                                 return Err(crate::extensions::ExtensionRestrictionError {
74                                     extension: stringify!($member),
75                                     restriction: crate::extensions::ExtensionRestriction::RequiresInstanceExtension(stringify!($requires_instance_extension)),
76                                 });
77                             }
78                         )*
79 
80                         $(
81                             if self.$conflicts_device_extension {
82                                 return Err(crate::extensions::ExtensionRestrictionError {
83                                     extension: stringify!($member),
84                                     restriction: crate::extensions::ExtensionRestriction::ConflictsDeviceExtension(stringify!($conflicts_device_extension)),
85                                 });
86                             }
87                         )*
88                     } else {
89                         if $required_if_supported && supported.$member {
90                             return Err(crate::extensions::ExtensionRestrictionError {
91                                 extension: stringify!($member),
92                                 restriction: crate::extensions::ExtensionRestriction::RequiredIfSupported,
93                             });
94                         }
95                     }
96                 )*
97                 Ok(())
98             }
99 
100             pub(crate) fn required_if_supported_extensions() -> Self {
101                 Self {
102                     $(
103                         $member: $required_if_supported,
104                     )*
105                     _unbuildable: crate::extensions::Unbuildable(())
106                 }
107             }
108         }
109    );
110 }
111 
112 pub use crate::autogen::DeviceExtensions;
113 pub(crate) use device_extensions;
114 
115 impl DeviceExtensions {
116     /// See the docs of supported_by_device().
117     #[deprecated(
118         since = "0.25",
119         note = "Use PhysicalDevice::supported_extensions instead"
120     )]
supported_by_device_raw( physical_device: PhysicalDevice, ) -> Result<Self, SupportedExtensionsError>121     pub fn supported_by_device_raw(
122         physical_device: PhysicalDevice,
123     ) -> Result<Self, SupportedExtensionsError> {
124         Ok(*physical_device.supported_extensions())
125     }
126 
127     /// Returns a `DeviceExtensions` object with extensions supported by the `PhysicalDevice`.
128     #[deprecated(
129         since = "0.25",
130         note = "Use PhysicalDevice::supported_extensions instead"
131     )]
supported_by_device(physical_device: PhysicalDevice) -> Self132     pub fn supported_by_device(physical_device: PhysicalDevice) -> Self {
133         *physical_device.supported_extensions()
134     }
135 
136     /// Returns a `DeviceExtensions` object with extensions required as well as supported by the `PhysicalDevice`.
137     /// They are needed to be passed to `Device::new(...)`.
138     #[deprecated(
139         since = "0.25",
140         note = "Use PhysicalDevice::required_extensions instead"
141     )]
required_extensions(physical_device: PhysicalDevice) -> Self142     pub fn required_extensions(physical_device: PhysicalDevice) -> Self {
143         *physical_device.required_extensions()
144     }
145 }
146 
147 /// This helper type can only be instantiated inside this module.
148 /// See `*Extensions::_unbuildable`.
149 #[doc(hidden)]
150 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
151 pub struct Unbuildable(());
152 
153 #[cfg(test)]
154 mod tests {
155     use crate::device::DeviceExtensions;
156     use std::ffi::CString;
157 
158     #[test]
empty_extensions()159     fn empty_extensions() {
160         let d: Vec<CString> = (&DeviceExtensions::none()).into();
161         assert!(d.iter().next().is_none());
162     }
163 
164     #[test]
required_if_supported_extensions()165     fn required_if_supported_extensions() {
166         assert_eq!(
167             DeviceExtensions::required_if_supported_extensions(),
168             DeviceExtensions {
169                 khr_portability_subset: true,
170                 ..DeviceExtensions::none()
171             }
172         )
173     }
174 }
175