Initialize function pointers to a panicking function if it couldn't be

loaded
This commit is contained in:
Maik Klein 2018-11-03 23:37:20 +01:00
parent dc189a8fc6
commit adf571c95c
19 changed files with 5813 additions and 4322 deletions

View file

@ -37,8 +37,6 @@ pub struct Entry<V: FunctionPointers> {
#[derive(Debug)]
pub enum LoadingError {
LibraryLoadError(String),
EntryLoadError(Vec<&'static str>),
StaticLoadError(Vec<&'static str>),
}
#[derive(Debug)]
@ -87,8 +85,7 @@ pub trait EntryV1_0 {
return Err(InstanceError::VkError(err_code));
}
let instance_fp =
<Self::Fp as FunctionPointers>::InstanceFp::load(&self.static_fn(), instance)
.map_err(InstanceError::LoadError)?;
<Self::Fp as FunctionPointers>::InstanceFp::load(&self.static_fn(), instance);
Ok(Instance::from_raw(instance, instance_fp))
}
@ -176,10 +173,10 @@ impl<V: FunctionPointers> Entry<V> {
let static_fn = vk::StaticFn::load(|name| unsafe {
lib.symbol(&*name.to_string_lossy())
.unwrap_or(ptr::null_mut())
}).map_err(LoadingError::StaticLoadError)?;
});
let entry_fn =
unsafe { V::EntryFp::load(&static_fn) }.map_err(LoadingError::EntryLoadError)?;
unsafe { V::EntryFp::load(&static_fn) };
Ok(Entry {
static_fn,

View file

@ -16,14 +16,14 @@ impl AndroidSurface {
pub fn new<E: EntryV1_0, I: InstanceV1_0>(
entry: &E,
instance: &I,
) -> Result<AndroidSurface, Vec<&'static str>> {
) -> AndroidSurface {
let surface_fn = vk::KhrAndroidSurfaceFn::load(|name| unsafe {
mem::transmute(entry.get_instance_proc_addr(instance.handle(), name.as_ptr()))
})?;
Ok(AndroidSurface {
});
AndroidSurface {
handle: instance.handle(),
android_surface_fn: surface_fn,
})
}
}
pub fn name() -> &'static CStr {

View file

@ -14,13 +14,13 @@ impl DebugMarker {
pub fn new<I: InstanceV1_0, D: DeviceV1_0>(
instance: &I,
device: &D,
) -> Result<DebugMarker, Vec<&'static str>> {
) -> DebugMarker {
let debug_marker_fn = vk::ExtDebugMarkerFn::load(|name| unsafe {
mem::transmute(instance.get_device_proc_addr(device.handle(), name.as_ptr()))
})?;
Ok(DebugMarker {
});
DebugMarker {
debug_marker_fn: debug_marker_fn,
})
}
}
pub fn name() -> &'static CStr {

View file

@ -16,14 +16,14 @@ impl DebugReport {
pub fn new<E: EntryV1_0, I: InstanceV1_0>(
entry: &E,
instance: &I,
) -> Result<DebugReport, Vec<&'static str>> {
) -> DebugReport {
let debug_report_fn = vk::ExtDebugReportFn::load(|name| unsafe {
mem::transmute(entry.get_instance_proc_addr(instance.handle(), name.as_ptr()))
})?;
Ok(DebugReport {
});
DebugReport {
handle: instance.handle(),
debug_report_fn,
})
}
}
pub fn name() -> &'static CStr {

View file

@ -15,14 +15,14 @@ impl DebugUtils {
pub fn new<E: EntryV1_0, I: InstanceV1_0>(
entry: &E,
instance: &I,
) -> Result<DebugUtils, Vec<&'static str>> {
) -> DebugUtils {
let debug_utils_fn = vk::ExtDebugUtilsFn::load(|name| unsafe {
mem::transmute(entry.get_instance_proc_addr(instance.handle(), name.as_ptr()))
})?;
Ok(DebugUtils {
});
DebugUtils {
handle: instance.handle(),
debug_utils_fn,
})
}
}
pub fn name() -> &'static CStr {

View file

@ -16,14 +16,14 @@ impl DisplaySwapchain {
pub fn new<I: InstanceV1_0, D: DeviceV1_0>(
instance: &I,
device: &D,
) -> Result<DisplaySwapchain, Vec<&'static str>> {
) -> DisplaySwapchain {
let swapchain_fn = vk::KhrDisplaySwapchainFn::load(|name| unsafe {
mem::transmute(instance.get_device_proc_addr(device.handle(), name.as_ptr()))
})?;
Ok(DisplaySwapchain {
});
DisplaySwapchain {
handle: device.handle(),
swapchain_fn: swapchain_fn,
})
}
}
pub fn name() -> &'static CStr {

View file

@ -16,14 +16,14 @@ impl IOSSurface {
pub fn new<E: EntryV1_0, I: InstanceV1_0>(
entry: &E,
instance: &I,
) -> Result<IOSSurface, Vec<&'static str>> {
) -> IOSSurface{
let surface_fn = vk::MvkIosSurfaceFn::load(|name| unsafe {
mem::transmute(entry.get_instance_proc_addr(instance.handle(), name.as_ptr()))
})?;
Ok(IOSSurface {
});
IOSSurface {
handle: instance.handle(),
ios_surface_fn: surface_fn,
})
}
}
pub fn name() -> &'static CStr {

View file

@ -16,14 +16,14 @@ impl MacOSSurface {
pub fn new<E: EntryV1_0, I: InstanceV1_0>(
entry: &E,
instance: &I,
) -> Result<MacOSSurface, Vec<&'static str>> {
) -> MacOSSurface {
let surface_fn = vk::MvkMacosSurfaceFn::load(|name| unsafe {
mem::transmute(entry.get_instance_proc_addr(instance.handle(), name.as_ptr()))
})?;
Ok(MacOSSurface {
});
MacOSSurface {
handle: instance.handle(),
macos_surface_fn: surface_fn,
})
}
}
pub fn name() -> &'static CStr {

View file

@ -17,14 +17,14 @@ impl Surface {
pub fn new<E: EntryV1_0, I: InstanceV1_0>(
entry: &E,
instance: &I,
) -> Result<Surface, Vec<&'static str>> {
) -> Surface {
let surface_fn = vk::KhrSurfaceFn::load(|name| unsafe {
mem::transmute(entry.get_instance_proc_addr(instance.handle(), name.as_ptr()))
})?;
Ok(Surface {
});
Surface {
handle: instance.handle(),
surface_fn: surface_fn,
})
}
}
pub fn name() -> &'static CStr {

View file

@ -17,14 +17,14 @@ impl Swapchain {
pub fn new<I: InstanceV1_0, D: DeviceV1_0>(
instance: &I,
device: &D,
) -> Result<Swapchain, Vec<&'static str>> {
) -> Swapchain {
let swapchain_fn = vk::KhrSwapchainFn::load(|name| unsafe {
mem::transmute(instance.get_device_proc_addr(device.handle(), name.as_ptr()))
})?;
Ok(Swapchain {
});
Swapchain {
handle: device.handle(),
swapchain_fn: swapchain_fn,
})
}
}
pub fn name() -> &'static CStr {

View file

@ -16,14 +16,14 @@ impl WaylandSurface {
pub fn new<E: EntryV1_0, I: InstanceV1_0>(
entry: &E,
instance: &I,
) -> Result<WaylandSurface, Vec<&'static str>> {
) -> WaylandSurface {
let surface_fn = vk::KhrWaylandSurfaceFn::load(|name| unsafe {
mem::transmute(entry.get_instance_proc_addr(instance.handle(), name.as_ptr()))
})?;
Ok(WaylandSurface {
});
WaylandSurface {
handle: instance.handle(),
wayland_surface_fn: surface_fn,
})
}
}
pub fn name() -> &'static CStr {

View file

@ -16,14 +16,14 @@ impl Win32Surface {
pub fn new<E: EntryV1_0, I: InstanceV1_0>(
entry: &E,
instance: &I,
) -> Result<Win32Surface, Vec<&'static str>> {
) -> Win32Surface {
let surface_fn = vk::KhrWin32SurfaceFn::load(|name| unsafe {
mem::transmute(entry.get_instance_proc_addr(instance.handle(), name.as_ptr()))
})?;
Ok(Win32Surface {
});
Win32Surface {
handle: instance.handle(),
win32_surface_fn: surface_fn,
})
}
}
pub fn name() -> &'static CStr {

View file

@ -16,14 +16,14 @@ impl XcbSurface {
pub fn new<E: EntryV1_0, I: InstanceV1_0>(
entry: &E,
instance: &I,
) -> Result<XcbSurface, Vec<&'static str>> {
) -> XcbSurface {
let surface_fn = vk::KhrXcbSurfaceFn::load(|name| unsafe {
mem::transmute(entry.get_instance_proc_addr(instance.handle(), name.as_ptr()))
})?;
Ok(XcbSurface {
});
XcbSurface {
handle: instance.handle(),
xcb_surface_fn: surface_fn,
})
}
}
pub fn name() -> &'static CStr {

View file

@ -16,14 +16,14 @@ impl XlibSurface {
pub fn new<E: EntryV1_0, I: InstanceV1_0>(
entry: &E,
instance: &I,
) -> Result<XlibSurface, Vec<&'static str>> {
) -> XlibSurface {
let surface_fn = vk::KhrXlibSurfaceFn::load(|name| unsafe {
mem::transmute(entry.get_instance_proc_addr(instance.handle(), name.as_ptr()))
})?;
Ok(XlibSurface {
});
XlibSurface {
handle: instance.handle(),
xlib_surface_fn: surface_fn,
})
}
}
pub fn name() -> &'static CStr {

View file

@ -279,7 +279,7 @@ pub trait InstanceV1_0 {
let device_fn = <<Self as InstanceV1_0>::Fp as FunctionPointers>::DeviceFp::load(
self.fp_v1_0(),
device,
).map_err(|err| DeviceError::LoadError(err))?;
);
Ok(Device::from_raw(device, device_fn))
}

View file

@ -37,17 +37,17 @@ 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>> {
unsafe fn load(static_fn: &vk::StaticFn) -> Self {
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 })
});
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>>;
unsafe fn load(static_fn: &vk::StaticFn) -> Self;
}
#[allow(non_camel_case_types)]
@ -61,18 +61,18 @@ impl EntryLoader for EntryFpV1_1 {
fn fp_v1_0(&self) -> &vk::EntryFnV1_0 {
&self.entry_fn_1_0
}
unsafe fn load(static_fn: &vk::StaticFn) -> Result<Self, Vec<&'static str>> {
unsafe fn load(static_fn: &vk::StaticFn) -> Self {
let entry_fn_1_0 = vk::EntryFnV1_0::load(|name| {
mem::transmute(static_fn.get_instance_proc_addr(vk::Instance::null(), name.as_ptr()))
})?;
});
let entry_fn_1_1 = vk::EntryFnV1_1::load(|name| {
mem::transmute(static_fn.get_instance_proc_addr(vk::Instance::null(), name.as_ptr()))
})?;
});
Ok(EntryFpV1_1 {
EntryFpV1_1 {
entry_fn_1_0,
entry_fn_1_1,
})
}
}
}
@ -80,7 +80,7 @@ pub trait InstanceLoader: Sized {
unsafe fn load(
static_fn: &vk::StaticFn,
instance: vk::Instance,
) -> Result<Self, Vec<&'static str>>;
) -> Self;
}
#[allow(non_camel_case_types)]
@ -93,13 +93,13 @@ impl InstanceLoader for InstanceFpV1_0 {
unsafe fn load(
static_fn: &vk::StaticFn,
instance: vk::Instance,
) -> Result<Self, Vec<&'static str>> {
) -> Self {
let instance_fn = vk::InstanceFnV1_0::load(|name| {
mem::transmute(static_fn.get_instance_proc_addr(instance, name.as_ptr()))
})?;
Ok(InstanceFpV1_0 {
});
InstanceFpV1_0 {
instance_fn: instance_fn,
})
}
}
}
@ -114,18 +114,18 @@ impl InstanceLoader for InstanceFpV1_1 {
unsafe fn load(
static_fn: &vk::StaticFn,
instance: vk::Instance,
) -> Result<Self, Vec<&'static str>> {
) -> Self {
let instance_fn_1_0 = vk::InstanceFnV1_0::load(|name| {
mem::transmute(static_fn.get_instance_proc_addr(instance, name.as_ptr()))
})?;
});
let instance_fn_1_1 = vk::InstanceFnV1_1::load(|name| {
mem::transmute(static_fn.get_instance_proc_addr(instance, name.as_ptr()))
})?;
});
Ok(InstanceFpV1_1 {
InstanceFpV1_1 {
instance_fn_1_0,
instance_fn_1_1,
})
}
}
}
@ -133,7 +133,7 @@ pub trait DeviceLoader: Sized {
unsafe fn load(
instance_fn: &vk::InstanceFnV1_0,
device: vk::Device,
) -> Result<Self, Vec<&'static str>>;
) -> Self;
}
#[allow(non_camel_case_types)]
@ -146,13 +146,13 @@ impl DeviceLoader for DeviceFpV1_0 {
unsafe fn load(
instance_fn: &vk::InstanceFnV1_0,
device: vk::Device,
) -> Result<Self, Vec<&'static str>> {
) -> Self {
let device_fn = vk::DeviceFnV1_0::load(|name| {
mem::transmute(instance_fn.get_device_proc_addr(device, name.as_ptr()))
})?;
Ok(DeviceFpV1_0 {
});
DeviceFpV1_0 {
device_fn: device_fn,
})
}
}
}
@ -167,16 +167,16 @@ impl DeviceLoader for DeviceFpV1_1 {
unsafe fn load(
instance_fn: &vk::InstanceFnV1_0,
device: vk::Device,
) -> Result<Self, Vec<&'static str>> {
) -> Self {
let device_fn_1_0 = vk::DeviceFnV1_0::load(|name| {
mem::transmute(instance_fn.get_device_proc_addr(device, name.as_ptr()))
})?;
});
let device_fn_1_1 = vk::DeviceFnV1_1::load(|name| {
mem::transmute(instance_fn.get_device_proc_addr(device, name.as_ptr()))
})?;
Ok(DeviceFpV1_1 {
});
DeviceFpV1_1 {
device_fn_1_0,
device_fn_1_1,
})
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -107,7 +107,7 @@ unsafe fn create_surface<E: EntryV1_0, I: InstanceV1_0>(
dpy: x11_display as *mut vk::Display,
};
let xlib_surface_loader =
XlibSurface::new(entry, instance).expect("Unable to load xlib surface");
XlibSurface::new(entry, instance);
xlib_surface_loader.create_xlib_surface_khr(&x11_create_info, None)
}
@ -131,7 +131,7 @@ unsafe fn create_surface<E: EntryV1_0, I: InstanceV1_0>(
hwnd: hwnd as *const c_void,
};
let win32_surface_loader =
Win32Surface::new(entry, instance).expect("Unable to load win32 surface");
Win32Surface::new(entry, instance);
win32_surface_loader.create_win32_surface_khr(&win32_create_info, None)
}
@ -314,7 +314,7 @@ impl ExampleBase {
p_user_data: ptr::null_mut(),
};
let debug_report_loader =
DebugReport::new(&entry, &instance).expect("Unable to load debug report");
DebugReport::new(&entry, &instance);
let debug_call_back = debug_report_loader
.create_debug_report_callback_ext(&debug_info, None)
.unwrap();
@ -323,7 +323,7 @@ impl ExampleBase {
.enumerate_physical_devices()
.expect("Physical device error");
let surface_loader =
Surface::new(&entry, &instance).expect("Unable to load the Surface extension");
Surface::new(&entry, &instance);
let (pdevice, queue_family_index) = pdevices
.iter()
.map(|pdevice| {
@ -425,7 +425,7 @@ impl ExampleBase {
.find(|&mode| mode == vk::PresentModeKHR::MAILBOX)
.unwrap_or(vk::PresentModeKHR::FIFO);
let swapchain_loader =
Swapchain::new(&instance, &device).expect("Unable to load swapchain");
Swapchain::new(&instance, &device);
let swapchain_create_info = vk::SwapchainCreateInfoKHR {
s_type: vk::StructureType::SWAPCHAIN_CREATE_INFO_KHR,
p_next: ptr::null(),

View file

@ -687,6 +687,9 @@ pub type CommandMap<'a> = HashMap<vkxml::Identifier, &'a vkxml::Command>;
fn generate_function_pointers(ident: Ident, commands: &[&vkxml::Command]) -> quote::Tokens {
let names: Vec<_> = commands.iter().map(|cmd| cmd.command_ident()).collect();
let names_ref = &names;
let names_ref1 = &names;
let names_ref2 = &names;
let names_ref3 = &names;
let raw_names: Vec<_> = commands
.iter()
.map(|cmd| Ident::from(cmd.name.as_str()))
@ -728,6 +731,17 @@ fn generate_function_pointers(ident: Ident, commands: &[&vkxml::Command]) -> quo
#(#inner_params_iter,)*
}
}).collect();
let expanded_params_unused: Vec<_> = params
.iter()
.map(|inner_params| {
let inner_params_iter = inner_params.iter().map(|&(ref param_name, ref param_ty)| {
let unused_name = Ident::from(format!("_{}", param_name).as_str());
quote!{#unused_name: #param_ty}
});
quote!{
#(#inner_params_iter,)*
}
}).collect();
let expanded_params_ref = &expanded_params;
let return_types: Vec<_> = commands
@ -753,31 +767,28 @@ fn generate_function_pointers(ident: Ident, commands: &[&vkxml::Command]) -> quo
}
}
impl #ident {
pub fn load<F>(mut _f: F) -> ::std::result::Result<Self, Vec<&'static str>>
pub fn load<F>(mut _f: F) -> Self
where F: FnMut(&::std::ffi::CStr) -> *const c_void
{
let mut _err_str = Vec::new();
let s = #ident {
#ident {
#(
#names_ref: unsafe {
extern "system" fn #names_ref1 (#expanded_params_unused) -> #return_types_ref {
panic!("Unable to load {}", stringify!(#names_ref2))
}
let raw_name = stringify!(#raw_names_ref);
let cname = ::std::ffi::CString::new(raw_name).unwrap();
let val = _f(&cname);
if val.is_null(){
_err_str.push(raw_name);
#names_ref3
}
else{
::std::mem::transmute(val)
}
::std::mem::transmute(val)
},
)*
};
if _err_str.is_empty() {
Ok(s)
}
else{
Err(_err_str)
}
}
#(
pub unsafe fn #names_ref(&self, #expanded_params_ref) -> #return_types_ref {