Refactor entry with an entry loader

This commit is contained in:
maik klein 2017-01-04 18:46:00 +01:00
parent efd6f906d9
commit 47420b1c1e
3 changed files with 37 additions and 12 deletions

View file

@ -7,7 +7,7 @@ use shared_library::dynamic_library::DynamicLibrary;
use std::path::Path; use std::path::Path;
use ::RawPtr; use ::RawPtr;
use std::marker::PhantomData; use std::marker::PhantomData;
use version::{FunctionPointers, V1_0, InstanceFpV1_0, InstanceLoader}; use version::{FunctionPointers, V1_0, InstanceFpV1_0, InstanceLoader, EntryLoader};
#[cfg(windows)] #[cfg(windows)]
fn get_path() -> &'static Path { fn get_path() -> &'static Path {
@ -31,7 +31,7 @@ lazy_static!{
#[derive(Clone)] #[derive(Clone)]
pub struct Entry<V: FunctionPointers> { pub struct Entry<V: FunctionPointers> {
static_fn: vk::StaticFn, static_fn: vk::StaticFn,
entry_fn: vk::EntryFn, entry_fn: V::EntryFp,
_v: PhantomData<V>, _v: PhantomData<V>,
} }
@ -47,7 +47,6 @@ pub enum InstanceError {
LoadError(Vec<&'static str>), LoadError(Vec<&'static str>),
VkError(vk::Result), VkError(vk::Result),
} }
impl<V: FunctionPointers> Entry<V> { impl<V: FunctionPointers> Entry<V> {
pub fn create_instance(&self, pub fn create_instance(&self,
create_info: &vk::InstanceCreateInfo, create_info: &vk::InstanceCreateInfo,
@ -55,7 +54,8 @@ impl<V: FunctionPointers> Entry<V> {
-> Result<Instance<V>, InstanceError> { -> Result<Instance<V>, InstanceError> {
unsafe { unsafe {
let mut instance: vk::Instance = mem::uninitialized(); let mut instance: vk::Instance = mem::uninitialized();
let err_code = self.entry_fn.create_instance(create_info, let err_code =
self.entry_fn.fp_v1_0().create_instance(create_info,
allocation_callbacks.as_raw_ptr(), allocation_callbacks.as_raw_ptr(),
&mut instance); &mut instance);
if err_code != vk::Result::Success { if err_code != vk::Result::Success {
@ -80,9 +80,7 @@ impl<V: FunctionPointers> Entry<V> {
} }
Err(ref err) => Err(LoadingError::LibraryLoadError(err.clone())), Err(ref err) => Err(LoadingError::LibraryLoadError(err.clone())),
}?; }?;
let entry_fn = vk::EntryFn::load(|name| unsafe { let entry_fn = unsafe { V::EntryFp::load(&static_fn).unwrap() };
mem::transmute(static_fn.get_instance_proc_addr(vk::Instance::null(), name.as_ptr()))
}).map_err(|err| LoadingError::EntryLoadError(err))?;
Ok(Entry { Ok(Entry {
static_fn: static_fn, static_fn: static_fn,
entry_fn: entry_fn, entry_fn: entry_fn,
@ -93,10 +91,11 @@ impl<V: FunctionPointers> Entry<V> {
pub fn enumerate_instance_layer_properties(&self) -> VkResult<Vec<vk::LayerProperties>> { pub fn enumerate_instance_layer_properties(&self) -> VkResult<Vec<vk::LayerProperties>> {
unsafe { unsafe {
let mut num = 0; let mut num = 0;
self.entry_fn.enumerate_instance_layer_properties(&mut num, ptr::null_mut()); self.entry_fn.fp_v1_0().enumerate_instance_layer_properties(&mut num, ptr::null_mut());
let mut v = Vec::with_capacity(num as usize); let mut v = Vec::with_capacity(num as usize);
let err_code = self.entry_fn let err_code = self.entry_fn
.fp_v1_0()
.enumerate_instance_layer_properties(&mut num, v.as_mut_ptr()); .enumerate_instance_layer_properties(&mut num, v.as_mut_ptr());
v.set_len(num as usize); v.set_len(num as usize);
match err_code { match err_code {
@ -111,9 +110,11 @@ impl<V: FunctionPointers> Entry<V> {
unsafe { unsafe {
let mut num = 0; let mut num = 0;
self.entry_fn self.entry_fn
.fp_v1_0()
.enumerate_instance_extension_properties(ptr::null(), &mut num, ptr::null_mut()); .enumerate_instance_extension_properties(ptr::null(), &mut num, ptr::null_mut());
let mut data = Vec::with_capacity(num as usize); let mut data = Vec::with_capacity(num as usize);
let err_code = self.entry_fn let err_code = self.entry_fn
.fp_v1_0()
.enumerate_instance_extension_properties(ptr::null(), &mut num, data.as_mut_ptr()); .enumerate_instance_extension_properties(ptr::null(), &mut num, data.as_mut_ptr());
data.set_len(num as usize); data.set_len(num as usize);
match err_code { match err_code {

View file

@ -5,6 +5,7 @@ use std::mem;
pub trait FunctionPointers { pub trait FunctionPointers {
type InstanceFp: InstanceLoader; type InstanceFp: InstanceLoader;
type DeviceFp: DeviceLoader; type DeviceFp: DeviceLoader;
type EntryFp: EntryLoader;
} }
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
@ -12,6 +13,7 @@ pub struct V1_0;
impl FunctionPointers for V1_0 { impl FunctionPointers for V1_0 {
type InstanceFp = InstanceFpV1_0; type InstanceFp = InstanceFpV1_0;
type DeviceFp = DeviceFpV1_0; type DeviceFp = DeviceFpV1_0;
type EntryFp = EntryFpV1_0;
} }
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
@ -19,6 +21,28 @@ pub struct InstanceFpV1_0 {
pub instance_fn: vk::InstanceFnV1_0, pub instance_fn: vk::InstanceFnV1_0,
} }
#[allow(non_camel_case_types)]
pub struct EntryFpV1_0 {
pub entry_fn: vk::EntryFnV1_0,
}
impl EntryLoader for EntryFpV1_0 {
fn fp_v1_0(&self) -> &vk::EntryFnV1_0 {
&self.entry_fn
}
unsafe fn load(static_fn: &vk::StaticFn) -> Result<Self, Vec<&'static str>> {
let entry_fn = vk::EntryFnV1_0::load(|name| {
mem::transmute(static_fn.get_instance_proc_addr(vk::Instance::null(), name.as_ptr()))
})?;
Ok(EntryFpV1_0 { entry_fn: entry_fn })
}
}
pub trait EntryLoader: Sized {
fn fp_v1_0(&self) -> &vk::EntryFnV1_0;
unsafe fn load(static_fn: &vk::StaticFn) -> Result<Self, Vec<&'static str>>;
}
pub trait InstanceLoader: Sized { pub trait InstanceLoader: Sized {
fn fp_v1_0(&self) -> &vk::InstanceFnV1_0; fn fp_v1_0(&self) -> &vk::InstanceFnV1_0;
unsafe fn load(static_fn: &vk::StaticFn, unsafe fn load(static_fn: &vk::StaticFn,

View file

@ -3711,7 +3711,7 @@ vk_functions!{
} }
vk_functions!{ vk_functions!{
EntryFn, EntryFnV1_0,
"vkCreateInstance", create_instance( "vkCreateInstance", create_instance(
p_create_info: *const InstanceCreateInfo, p_create_info: *const InstanceCreateInfo,
p_allocator: *const AllocationCallbacks, p_allocator: *const AllocationCallbacks,