ash/src/entry.rs

160 lines
5.6 KiB
Rust
Raw Normal View History

2016-12-10 05:25:48 +11:00
use prelude::*;
2016-12-09 11:55:29 +11:00
use std::mem;
use std::ptr;
2016-12-10 06:15:59 +11:00
use vk;
2017-01-01 18:09:51 +11:00
use instance::Instance;
2016-12-09 11:55:29 +11:00
use shared_library::dynamic_library::DynamicLibrary;
use std::path::Path;
use ::RawPtr;
2016-12-30 16:19:47 +11:00
use std::marker::PhantomData;
2017-01-01 18:09:51 +11:00
use version::{FunctionPointers, V1_0, InstanceFpV1_0, InstanceLoader};
2016-12-24 09:22:21 +11:00
2016-12-09 11:55:29 +11:00
#[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")
}
2016-12-24 09:22:21 +11:00
lazy_static!{
static ref VK_LIB: Result<DynamicLibrary, String> = DynamicLibrary::open(Some(get_path()));
}
2016-12-29 17:08:50 +11:00
#[derive(Clone)]
2017-01-01 18:09:51 +11:00
pub struct Entry<V: FunctionPointers> {
2016-12-24 15:57:44 +11:00
static_fn: vk::StaticFn,
entry_fn: vk::EntryFn,
2017-01-01 18:09:51 +11:00
_v: PhantomData<V>,
2016-12-09 11:55:29 +11:00
}
#[derive(Debug)]
pub enum LoadingError {
2016-12-29 15:03:12 +11:00
LibraryLoadError(String),
EntryLoadError(Vec<&'static str>),
StaticLoadError(Vec<&'static str>),
2016-12-09 11:55:29 +11:00
}
2016-12-10 05:25:48 +11:00
#[derive(Debug)]
pub enum InstanceError {
2016-12-29 15:03:12 +11:00
LoadError(Vec<&'static str>),
2016-12-10 05:25:48 +11:00
VkError(vk::Result),
}
2017-01-01 18:09:51 +11:00
pub trait EntryExt {
fn load_vulkan<V: FunctionPointers>() -> Result<Entry<V>, LoadingError> {
let static_fn = match *VK_LIB {
Ok(ref lib) => {
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))?;
Ok(static_fn)
}
Err(ref err) => Err(LoadingError::LibraryLoadError(err.clone())),
}?;
let entry_fn = vk::EntryFn::load(|name| unsafe {
mem::transmute(static_fn.get_instance_proc_addr(vk::Instance::null(), name.as_ptr()))
}).map_err(|err| LoadingError::EntryLoadError(err))?;
Ok(Entry {
static_fn: static_fn,
entry_fn: entry_fn,
_v: PhantomData,
})
}
}
impl<V: FunctionPointers> EntryExt for Entry<V> {}
impl Entry<V1_0> {}
impl<V: FunctionPointers> Entry<V> {
2016-12-30 16:19:47 +11:00
pub fn create_instance(&self,
create_info: &vk::InstanceCreateInfo,
allocation_callbacks: Option<&vk::AllocationCallbacks>)
2017-01-01 18:09:51 +11:00
-> Result<Instance<V>, InstanceError> {
2016-12-30 16:19:47 +11:00
unsafe {
let mut instance: vk::Instance = mem::uninitialized();
let err_code = self.entry_fn.create_instance(create_info,
allocation_callbacks.as_raw_ptr(),
&mut instance);
if err_code != vk::Result::Success {
return Err(InstanceError::VkError(err_code));
}
2017-01-01 18:09:51 +11:00
let instance_fp = V::InstanceFp::load(&self.static_fn, instance).map_err(|err| InstanceError::LoadError(err))?;
Ok(Instance::from_raw(instance, instance_fp))
2016-12-30 16:19:47 +11:00
}
}
pub fn load_vulkan() -> Result<Entry<V>, LoadingError> {
2016-12-24 09:22:21 +11:00
let static_fn = match *VK_LIB {
Ok(ref lib) => {
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))?;
Ok(static_fn)
}
2016-12-29 15:03:12 +11:00
Err(ref err) => Err(LoadingError::LibraryLoadError(err.clone())),
2016-12-24 09:22:21 +11:00
}?;
2016-12-10 05:25:48 +11:00
let entry_fn = vk::EntryFn::load(|name| unsafe {
mem::transmute(static_fn.get_instance_proc_addr(vk::Instance::null(), name.as_ptr()))
2016-12-10 05:25:48 +11:00
}).map_err(|err| LoadingError::EntryLoadError(err))?;
2016-12-09 11:55:29 +11:00
Ok(Entry {
static_fn: static_fn,
entry_fn: entry_fn,
2017-01-01 18:09:51 +11:00
_v: PhantomData,
2016-12-09 11:55:29 +11:00
})
}
2016-12-10 05:25:48 +11:00
pub fn enumerate_instance_layer_properties(&self) -> VkResult<Vec<vk::LayerProperties>> {
2016-12-09 11:55:29 +11:00
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),
}
}
}
2016-12-10 05:25:48 +11:00
pub fn enumerate_instance_extension_properties(&self)
-> VkResult<Vec<vk::ExtensionProperties>> {
2016-12-09 11:55:29 +11:00
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),
}
}
}
pub fn get_instance_proc_addr(&self,
instance: vk::Instance,
p_name: *const vk::c_char)
-> vk::PFN_vkVoidFunction {
unsafe { self.static_fn.get_instance_proc_addr(instance, p_name) }
}
2016-12-09 11:55:29 +11:00
}