• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use crate::entry::EntryCustom;
2 use crate::entry::MissingEntryPoint;
3 use libloading::Library;
4 use std::error::Error;
5 use std::ffi::OsStr;
6 use std::fmt;
7 use std::ptr;
8 use std::sync::Arc;
9 
10 #[cfg(windows)]
11 const LIB_PATH: &str = "vulkan-1.dll";
12 
13 #[cfg(all(
14     unix,
15     not(any(target_os = "macos", target_os = "ios", target_os = "android"))
16 ))]
17 const LIB_PATH: &str = "libvulkan.so.1";
18 
19 #[cfg(target_os = "android")]
20 const LIB_PATH: &str = "libvulkan.so";
21 
22 #[cfg(any(target_os = "macos", target_os = "ios"))]
23 const LIB_PATH: &str = "libvulkan.dylib";
24 
25 #[derive(Debug)]
26 pub enum LoadingError {
27     LibraryLoadFailure(libloading::Error),
28     MissingEntryPoint(MissingEntryPoint),
29 }
30 
31 impl fmt::Display for LoadingError {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result32     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
33         match self {
34             LoadingError::LibraryLoadFailure(err) => fmt::Display::fmt(err, f),
35             LoadingError::MissingEntryPoint(err) => fmt::Display::fmt(err, f),
36         }
37     }
38 }
39 
40 impl Error for LoadingError {
source(&self) -> Option<&(dyn Error + 'static)>41     fn source(&self) -> Option<&(dyn Error + 'static)> {
42         Some(match self {
43             LoadingError::LibraryLoadFailure(err) => err,
44             LoadingError::MissingEntryPoint(err) => err,
45         })
46     }
47 }
48 
49 impl From<MissingEntryPoint> for LoadingError {
from(err: MissingEntryPoint) -> Self50     fn from(err: MissingEntryPoint) -> Self {
51         LoadingError::MissingEntryPoint(err)
52     }
53 }
54 
55 /// Default function loader
56 pub type Entry = EntryCustom<Arc<Library>>;
57 
58 impl Entry {
59     /// Load default Vulkan library for the current platform
60     ///
61     /// # Safety
62     /// `dlopen`ing native libraries is inherently unsafe. The safety guidelines
63     /// for [`Library::new`] and [`Library::get`] apply here.
64     ///
65     /// ```no_run
66     /// use ash::{vk, Entry};
67     /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
68     /// let entry = unsafe { Entry::new() }?;
69     /// let app_info = vk::ApplicationInfo {
70     ///     api_version: vk::make_api_version(0, 1, 0, 0),
71     ///     ..Default::default()
72     /// };
73     /// let create_info = vk::InstanceCreateInfo {
74     ///     p_application_info: &app_info,
75     ///     ..Default::default()
76     /// };
77     /// let instance = unsafe { entry.create_instance(&create_info, None)? };
78     /// # Ok(()) }
79     /// ```
new() -> Result<Entry, LoadingError>80     pub unsafe fn new() -> Result<Entry, LoadingError> {
81         Self::with_library(LIB_PATH)
82     }
83 
84     /// Load Vulkan library at `path`
85     ///
86     /// # Safety
87     /// `dlopen`ing native libraries is inherently unsafe. The safety guidelines
88     /// for [`Library::new`] and [`Library::get`] apply here.
with_library(path: impl AsRef<OsStr>) -> Result<Entry, LoadingError>89     pub unsafe fn with_library(path: impl AsRef<OsStr>) -> Result<Entry, LoadingError> {
90         let lib = Library::new(path)
91             .map_err(LoadingError::LibraryLoadFailure)
92             .map(Arc::new)?;
93 
94         Ok(Self::new_custom(lib, |vk_lib, name| {
95             vk_lib
96                 .get(name.to_bytes_with_nul())
97                 .map(|symbol| *symbol)
98                 .unwrap_or(ptr::null_mut())
99         })?)
100     }
101 }
102