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;
|
2016-12-28 20:20:12 +11:00
|
|
|
use ::RawPtr;
|
2016-12-30 16:19:47 +11:00
|
|
|
use std::marker::PhantomData;
|
2017-01-05 19:03:37 +11:00
|
|
|
use version::{FunctionPointers, V1_0, InstanceLoader, EntryLoader};
|
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,
|
2017-01-05 04:46:00 +11:00
|
|
|
entry_fn: V::EntryFp,
|
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-05 19:03:37 +11:00
|
|
|
|
|
|
|
#[allow(non_camel_case_types)]
|
2017-01-05 18:48:18 +11:00
|
|
|
pub trait EntryV1_0 {
|
|
|
|
type Fp: FunctionPointers;
|
2017-01-05 05:09:27 +11:00
|
|
|
fn fp_v1_0(&self) -> &vk::EntryFnV1_0;
|
|
|
|
fn static_fn(&self) -> &vk::StaticFn;
|
2017-01-05 18:48:18 +11:00
|
|
|
|
|
|
|
fn create_instance(&self,
|
|
|
|
create_info: &vk::InstanceCreateInfo,
|
|
|
|
allocation_callbacks: Option<&vk::AllocationCallbacks>)
|
|
|
|
-> Result<Instance<Self::Fp>, InstanceError> {
|
|
|
|
unsafe {
|
|
|
|
let mut instance: vk::Instance = mem::uninitialized();
|
|
|
|
let err_code = self.fp_v1_0().create_instance(create_info,
|
|
|
|
allocation_callbacks.as_raw_ptr(),
|
|
|
|
&mut instance);
|
|
|
|
if err_code != vk::Result::Success {
|
|
|
|
return Err(InstanceError::VkError(err_code));
|
|
|
|
}
|
|
|
|
let instance_fp = <<Self as EntryV1_0>::Fp as FunctionPointers>::InstanceFp::load(&self.static_fn(), instance).map_err(|err| InstanceError::LoadError(err))?;
|
|
|
|
Ok(Instance::from_raw(instance, instance_fp))
|
|
|
|
}
|
|
|
|
}
|
2017-01-05 18:40:22 +11:00
|
|
|
|
2017-01-05 05:09:27 +11:00
|
|
|
fn enumerate_instance_layer_properties(&self) -> VkResult<Vec<vk::LayerProperties>> {
|
|
|
|
unsafe {
|
|
|
|
let mut num = 0;
|
|
|
|
self.fp_v1_0().enumerate_instance_layer_properties(&mut num, ptr::null_mut());
|
|
|
|
|
|
|
|
let mut v = Vec::with_capacity(num as usize);
|
2017-01-05 18:48:18 +11:00
|
|
|
let err_code = self.fp_v1_0()
|
2017-01-05 05:09:27 +11:00
|
|
|
.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),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-01-05 18:48:18 +11:00
|
|
|
fn enumerate_instance_extension_properties(&self) -> VkResult<Vec<vk::ExtensionProperties>> {
|
2017-01-05 05:09:27 +11:00
|
|
|
unsafe {
|
|
|
|
let mut num = 0;
|
2017-01-05 18:48:18 +11:00
|
|
|
self.fp_v1_0()
|
2017-01-05 05:09:27 +11:00
|
|
|
.enumerate_instance_extension_properties(ptr::null(), &mut num, ptr::null_mut());
|
|
|
|
let mut data = Vec::with_capacity(num as usize);
|
2017-01-05 18:48:18 +11:00
|
|
|
let err_code = self.fp_v1_0()
|
2017-01-05 05:09:27 +11:00
|
|
|
.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),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn get_instance_proc_addr(&self,
|
2017-01-05 18:48:18 +11:00
|
|
|
instance: vk::Instance,
|
|
|
|
p_name: *const vk::c_char)
|
|
|
|
-> vk::PFN_vkVoidFunction {
|
2017-01-05 05:09:27 +11:00
|
|
|
unsafe { self.static_fn().get_instance_proc_addr(instance, p_name) }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-01-05 18:48:18 +11:00
|
|
|
impl EntryV1_0 for Entry<V1_0> {
|
|
|
|
type Fp = V1_0;
|
|
|
|
fn fp_v1_0(&self) -> &vk::EntryFnV1_0 {
|
2017-01-05 05:09:27 +11:00
|
|
|
self.entry_fn.fp_v1_0()
|
|
|
|
}
|
2017-01-05 18:48:18 +11:00
|
|
|
fn static_fn(&self) -> &vk::StaticFn {
|
2017-01-05 05:09:27 +11:00
|
|
|
&self.static_fn
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-01-01 18:09:51 +11:00
|
|
|
impl<V: FunctionPointers> Entry<V> {
|
2017-01-01 18:56:38 +11:00
|
|
|
pub fn new() -> 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
|
|
|
}?;
|
2017-01-05 19:03:37 +11:00
|
|
|
let entry_fn = unsafe {
|
|
|
|
V::EntryFp::load(&static_fn).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
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|