blob: b6d0c44058836d3fa797265014f6c7e77ff59491 [file] [log] [blame]
// 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::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<Self, SupportedExtensionsError> {
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<CString> = (&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()
}
)
}
}