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::RequiresOneOf; 11 use bytemuck::cast_slice; 12 use std::{ 13 error::Error, 14 fmt::{Display, Error as FmtError, Formatter}, 15 }; 16 17 /// Properties of an extension in the loader or a physical device. 18 #[derive(Clone, Debug)] 19 pub struct ExtensionProperties { 20 /// The name of the extension. 21 pub extension_name: String, 22 23 /// The version of the extension. 24 pub spec_version: u32, 25 } 26 27 impl From<ash::vk::ExtensionProperties> for ExtensionProperties { 28 #[inline] from(val: ash::vk::ExtensionProperties) -> Self29 fn from(val: ash::vk::ExtensionProperties) -> Self { 30 Self { 31 extension_name: { 32 let bytes = cast_slice(val.extension_name.as_slice()); 33 let end = bytes.iter().position(|&b| b == 0).unwrap_or(bytes.len()); 34 String::from_utf8_lossy(&bytes[0..end]).into() 35 }, 36 spec_version: val.spec_version, 37 } 38 } 39 } 40 41 /// An error that can happen when enabling an extension on an instance or device. 42 #[derive(Clone, Copy, Debug)] 43 pub struct ExtensionRestrictionError { 44 /// The extension in question. 45 pub extension: &'static str, 46 /// The restriction that was not met. 47 pub restriction: ExtensionRestriction, 48 } 49 50 impl Error for ExtensionRestrictionError {} 51 52 impl Display for ExtensionRestrictionError { fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError>53 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> { 54 write!( 55 f, 56 "a restriction for the extension {} was not met: {}", 57 self.extension, self.restriction, 58 ) 59 } 60 } 61 62 #[derive(Clone, Copy, Debug)] 63 pub enum ExtensionRestriction { 64 /// Not supported by the loader or physical device. 65 NotSupported, 66 /// Required to be enabled by the physical device. 67 RequiredIfSupported, 68 /// Requires one of the following. 69 Requires(RequiresOneOf), 70 /// Requires a device extension to be disabled. 71 ConflictsDeviceExtension(&'static str), 72 } 73 74 impl Display for ExtensionRestriction { fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError>75 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> { 76 match *self { 77 ExtensionRestriction::NotSupported => { 78 write!(f, "not supported by the loader or physical device") 79 } 80 ExtensionRestriction::RequiredIfSupported => { 81 write!(f, "required to be enabled by the physical device") 82 } 83 ExtensionRestriction::Requires(requires) => { 84 if requires.len() > 1 { 85 write!(f, "requires one of: {}", requires) 86 } else { 87 write!(f, "requires: {}", requires) 88 } 89 } 90 ExtensionRestriction::ConflictsDeviceExtension(ext) => { 91 write!(f, "requires device extension {} to be disabled", ext) 92 } 93 } 94 } 95 } 96