| // 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::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 struct ExtensionProperties { |
| /// The name of the extension. |
| pub extension_name: String, |
| |
| /// The version of the extension. |
| pub spec_version: u32, |
| } |
| |
| impl From<ash::vk::ExtensionProperties> for ExtensionProperties { |
| #[inline] |
| 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, |
| } |
| } |
| } |
| |
| /// An error that can happen when enabling an extension on an instance or device. |
| #[derive(Clone, Copy, Debug)] |
| pub struct ExtensionRestrictionError { |
| /// The extension in question. |
| pub extension: &'static str, |
| /// The restriction that was not met. |
| pub restriction: ExtensionRestriction, |
| } |
| |
| impl Error for ExtensionRestrictionError {} |
| |
| impl Display for ExtensionRestrictionError { |
| fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> { |
| write!( |
| f, |
| "a restriction for the extension {} was not met: {}", |
| self.extension, self.restriction, |
| ) |
| } |
| } |
| |
| #[derive(Clone, Copy, Debug)] |
| pub enum ExtensionRestriction { |
| /// Not supported by the loader or physical device. |
| NotSupported, |
| /// 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 Display for ExtensionRestriction { |
| fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> { |
| match *self { |
| ExtensionRestriction::NotSupported => { |
| write!(f, "not supported by the loader or physical device") |
| } |
| ExtensionRestriction::RequiredIfSupported => { |
| 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!(f, "requires device extension {} to be disabled", ext) |
| } |
| } |
| } |
| } |