1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
use prelude::*; use std::mem; use std::ptr; use vk; use instance::Instance; use shared_library::dynamic_library::DynamicLibrary; use std::path::Path; #[cfg(windows)] fn get_path() -> &'static Path { Path::new("vulkan-1.dll") } #[cfg(all(unix, not(target_os = "android")))] fn get_path() -> &'static Path { Path::new("libvulkan.so.1") } #[cfg(target_os = "android")] fn get_path() -> &'static Path { Path::new("libvulkan.so") } pub struct Entry { lib: DynamicLibrary, pub static_fn: vk::StaticFn, pub entry_fn: vk::EntryFn, } #[derive(Debug)] pub enum LoadingError { LibraryLoadFailure(String), StaticLoadError(String), EntryLoadError(String), } #[derive(Debug)] pub enum InstanceError { LoadError(String), VkError(vk::Result), } impl Entry { pub fn load_vulkan_path(path: &Path) -> Result<Entry, LoadingError> { let lib = DynamicLibrary::open(Some(path)).map_err(|err| LoadingError::LibraryLoadFailure(err))?; let static_fn = vk::StaticFn::load(|name| unsafe { let name = name.to_str().unwrap(); let f = match lib.symbol(name) { Ok(s) => s, Err(_) => ptr::null(), }; f }).map_err(|err| LoadingError::StaticLoadError(err))?; let entry_fn = vk::EntryFn::load(|name| unsafe { mem::transmute(static_fn.get_instance_proc_addr(ptr::null_mut(), name.as_ptr())) }).map_err(|err| LoadingError::EntryLoadError(err))?; Ok(Entry { lib: lib, static_fn: static_fn, entry_fn: entry_fn, }) } pub fn load_vulkan() -> Result<Entry, LoadingError> { Entry::load_vulkan_path(get_path()) } pub fn create_instance(&self, create_info: &vk::InstanceCreateInfo) -> Result<Instance, InstanceError> { unsafe { let mut instance: vk::Instance = mem::uninitialized(); let err_code = self.entry_fn.create_instance(create_info, ptr::null(), &mut instance); if err_code != vk::Result::Success { return Err(InstanceError::VkError(err_code)); } let instance_fn = vk::InstanceFn::load(|name| { mem::transmute(self.static_fn.get_instance_proc_addr(instance, name.as_ptr())) }).map_err(|err| InstanceError::LoadError(err))?; Ok(Instance::from_raw(instance, instance_fn)) } } pub fn enumerate_instance_layer_properties(&self) -> VkResult<Vec<vk::LayerProperties>> { unsafe { let mut num = 0; self.entry_fn.enumerate_instance_layer_properties(&mut num, ptr::null_mut()); let mut v = Vec::with_capacity(num as usize); let err_code = self.entry_fn .enumerate_instance_layer_properties(&mut num, v.as_mut_ptr()); v.set_len(num as usize); match err_code { vk::Result::Success => Ok(v), _ => Err(err_code), } } } pub fn enumerate_instance_extension_properties(&self) -> VkResult<Vec<vk::ExtensionProperties>> { unsafe { let mut num = 0; self.entry_fn .enumerate_instance_extension_properties(ptr::null(), &mut num, ptr::null_mut()); let mut data = Vec::with_capacity(num as usize); let err_code = self.entry_fn .enumerate_instance_extension_properties(ptr::null(), &mut num, data.as_mut_ptr()); data.set_len(num as usize); match err_code { vk::Result::Success => Ok(data), _ => Err(err_code), } } } }