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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -16,14 +16,14 @@ impl XlibSurface {
pub fn new<E: EntryV1_0, I: InstanceV1_0>( pub fn new<E: EntryV1_0, I: InstanceV1_0>(
entry: &E, entry: &E,
instance: &I, instance: &I,
) -> Result<XlibSurface, Vec<&'static str>> { ) -> XlibSurface {
let surface_fn = vk::KhrXlibSurfaceFn::load(|name| unsafe { let surface_fn = vk::KhrXlibSurfaceFn::load(|name| unsafe {
mem::transmute(entry.get_instance_proc_addr(instance.handle(), name.as_ptr())) mem::transmute(entry.get_instance_proc_addr(instance.handle(), name.as_ptr()))
})?; });
Ok(XlibSurface { XlibSurface {
handle: instance.handle(), handle: instance.handle(),
xlib_surface_fn: surface_fn, xlib_surface_fn: surface_fn,
}) }
} }
pub fn name() -> &'static CStr { 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( let device_fn = <<Self as InstanceV1_0>::Fp as FunctionPointers>::DeviceFp::load(
self.fp_v1_0(), self.fp_v1_0(),
device, device,
).map_err(|err| DeviceError::LoadError(err))?; );
Ok(Device::from_raw(device, device_fn)) 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 { fn fp_v1_0(&self) -> &vk::EntryFnV1_0 {
&self.entry_fn &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| { let entry_fn = vk::EntryFnV1_0::load(|name| {
mem::transmute(static_fn.get_instance_proc_addr(vk::Instance::null(), name.as_ptr())) 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 { pub trait EntryLoader: Sized {
fn fp_v1_0(&self) -> &vk::EntryFnV1_0; 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)] #[allow(non_camel_case_types)]
@ -61,18 +61,18 @@ impl EntryLoader for EntryFpV1_1 {
fn fp_v1_0(&self) -> &vk::EntryFnV1_0 { fn fp_v1_0(&self) -> &vk::EntryFnV1_0 {
&self.entry_fn_1_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| { let entry_fn_1_0 = vk::EntryFnV1_0::load(|name| {
mem::transmute(static_fn.get_instance_proc_addr(vk::Instance::null(), name.as_ptr())) mem::transmute(static_fn.get_instance_proc_addr(vk::Instance::null(), name.as_ptr()))
})?; });
let entry_fn_1_1 = vk::EntryFnV1_1::load(|name| { let entry_fn_1_1 = vk::EntryFnV1_1::load(|name| {
mem::transmute(static_fn.get_instance_proc_addr(vk::Instance::null(), name.as_ptr())) 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_0,
entry_fn_1_1, entry_fn_1_1,
}) }
} }
} }
@ -80,7 +80,7 @@ pub trait InstanceLoader: Sized {
unsafe fn load( unsafe fn load(
static_fn: &vk::StaticFn, static_fn: &vk::StaticFn,
instance: vk::Instance, instance: vk::Instance,
) -> Result<Self, Vec<&'static str>>; ) -> Self;
} }
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
@ -93,13 +93,13 @@ impl InstanceLoader for InstanceFpV1_0 {
unsafe fn load( unsafe fn load(
static_fn: &vk::StaticFn, static_fn: &vk::StaticFn,
instance: vk::Instance, instance: vk::Instance,
) -> Result<Self, Vec<&'static str>> { ) -> Self {
let instance_fn = vk::InstanceFnV1_0::load(|name| { let instance_fn = vk::InstanceFnV1_0::load(|name| {
mem::transmute(static_fn.get_instance_proc_addr(instance, name.as_ptr())) mem::transmute(static_fn.get_instance_proc_addr(instance, name.as_ptr()))
})?; });
Ok(InstanceFpV1_0 { InstanceFpV1_0 {
instance_fn: instance_fn, instance_fn: instance_fn,
}) }
} }
} }
@ -114,18 +114,18 @@ impl InstanceLoader for InstanceFpV1_1 {
unsafe fn load( unsafe fn load(
static_fn: &vk::StaticFn, static_fn: &vk::StaticFn,
instance: vk::Instance, instance: vk::Instance,
) -> Result<Self, Vec<&'static str>> { ) -> Self {
let instance_fn_1_0 = vk::InstanceFnV1_0::load(|name| { let instance_fn_1_0 = vk::InstanceFnV1_0::load(|name| {
mem::transmute(static_fn.get_instance_proc_addr(instance, name.as_ptr())) mem::transmute(static_fn.get_instance_proc_addr(instance, name.as_ptr()))
})?; });
let instance_fn_1_1 = vk::InstanceFnV1_1::load(|name| { let instance_fn_1_1 = vk::InstanceFnV1_1::load(|name| {
mem::transmute(static_fn.get_instance_proc_addr(instance, name.as_ptr())) mem::transmute(static_fn.get_instance_proc_addr(instance, name.as_ptr()))
})?; });
Ok(InstanceFpV1_1 { InstanceFpV1_1 {
instance_fn_1_0, instance_fn_1_0,
instance_fn_1_1, instance_fn_1_1,
}) }
} }
} }
@ -133,7 +133,7 @@ pub trait DeviceLoader: Sized {
unsafe fn load( unsafe fn load(
instance_fn: &vk::InstanceFnV1_0, instance_fn: &vk::InstanceFnV1_0,
device: vk::Device, device: vk::Device,
) -> Result<Self, Vec<&'static str>>; ) -> Self;
} }
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
@ -146,13 +146,13 @@ impl DeviceLoader for DeviceFpV1_0 {
unsafe fn load( unsafe fn load(
instance_fn: &vk::InstanceFnV1_0, instance_fn: &vk::InstanceFnV1_0,
device: vk::Device, device: vk::Device,
) -> Result<Self, Vec<&'static str>> { ) -> Self {
let device_fn = vk::DeviceFnV1_0::load(|name| { let device_fn = vk::DeviceFnV1_0::load(|name| {
mem::transmute(instance_fn.get_device_proc_addr(device, name.as_ptr())) mem::transmute(instance_fn.get_device_proc_addr(device, name.as_ptr()))
})?; });
Ok(DeviceFpV1_0 { DeviceFpV1_0 {
device_fn: device_fn, device_fn: device_fn,
}) }
} }
} }
@ -167,16 +167,16 @@ impl DeviceLoader for DeviceFpV1_1 {
unsafe fn load( unsafe fn load(
instance_fn: &vk::InstanceFnV1_0, instance_fn: &vk::InstanceFnV1_0,
device: vk::Device, device: vk::Device,
) -> Result<Self, Vec<&'static str>> { ) -> Self {
let device_fn_1_0 = vk::DeviceFnV1_0::load(|name| { let device_fn_1_0 = vk::DeviceFnV1_0::load(|name| {
mem::transmute(instance_fn.get_device_proc_addr(device, name.as_ptr())) mem::transmute(instance_fn.get_device_proc_addr(device, name.as_ptr()))
})?; });
let device_fn_1_1 = vk::DeviceFnV1_1::load(|name| { let device_fn_1_1 = vk::DeviceFnV1_1::load(|name| {
mem::transmute(instance_fn.get_device_proc_addr(device, name.as_ptr())) mem::transmute(instance_fn.get_device_proc_addr(device, name.as_ptr()))
})?; });
Ok(DeviceFpV1_1 { DeviceFpV1_1 {
device_fn_1_0, device_fn_1_0,
device_fn_1_1, 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, dpy: x11_display as *mut vk::Display,
}; };
let xlib_surface_loader = 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) 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, hwnd: hwnd as *const c_void,
}; };
let win32_surface_loader = 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) win32_surface_loader.create_win32_surface_khr(&win32_create_info, None)
} }
@ -314,7 +314,7 @@ impl ExampleBase {
p_user_data: ptr::null_mut(), p_user_data: ptr::null_mut(),
}; };
let debug_report_loader = 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 let debug_call_back = debug_report_loader
.create_debug_report_callback_ext(&debug_info, None) .create_debug_report_callback_ext(&debug_info, None)
.unwrap(); .unwrap();
@ -323,7 +323,7 @@ impl ExampleBase {
.enumerate_physical_devices() .enumerate_physical_devices()
.expect("Physical device error"); .expect("Physical device error");
let surface_loader = let surface_loader =
Surface::new(&entry, &instance).expect("Unable to load the Surface extension"); Surface::new(&entry, &instance);
let (pdevice, queue_family_index) = pdevices let (pdevice, queue_family_index) = pdevices
.iter() .iter()
.map(|pdevice| { .map(|pdevice| {
@ -425,7 +425,7 @@ impl ExampleBase {
.find(|&mode| mode == vk::PresentModeKHR::MAILBOX) .find(|&mode| mode == vk::PresentModeKHR::MAILBOX)
.unwrap_or(vk::PresentModeKHR::FIFO); .unwrap_or(vk::PresentModeKHR::FIFO);
let swapchain_loader = let swapchain_loader =
Swapchain::new(&instance, &device).expect("Unable to load swapchain"); Swapchain::new(&instance, &device);
let swapchain_create_info = vk::SwapchainCreateInfoKHR { let swapchain_create_info = vk::SwapchainCreateInfoKHR {
s_type: vk::StructureType::SWAPCHAIN_CREATE_INFO_KHR, s_type: vk::StructureType::SWAPCHAIN_CREATE_INFO_KHR,
p_next: ptr::null(), 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 { fn generate_function_pointers(ident: Ident, commands: &[&vkxml::Command]) -> quote::Tokens {
let names: Vec<_> = commands.iter().map(|cmd| cmd.command_ident()).collect(); let names: Vec<_> = commands.iter().map(|cmd| cmd.command_ident()).collect();
let names_ref = &names; let names_ref = &names;
let names_ref1 = &names;
let names_ref2 = &names;
let names_ref3 = &names;
let raw_names: Vec<_> = commands let raw_names: Vec<_> = commands
.iter() .iter()
.map(|cmd| Ident::from(cmd.name.as_str())) .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,)* #(#inner_params_iter,)*
} }
}).collect(); }).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 expanded_params_ref = &expanded_params;
let return_types: Vec<_> = commands let return_types: Vec<_> = commands
@ -753,31 +767,28 @@ fn generate_function_pointers(ident: Ident, commands: &[&vkxml::Command]) -> quo
} }
} }
impl #ident { 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 where F: FnMut(&::std::ffi::CStr) -> *const c_void
{ {
let mut _err_str = Vec::new(); #ident {
let s = #ident {
#( #(
#names_ref: unsafe { #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 raw_name = stringify!(#raw_names_ref);
let cname = ::std::ffi::CString::new(raw_name).unwrap(); let cname = ::std::ffi::CString::new(raw_name).unwrap();
let val = _f(&cname); let val = _f(&cname);
if val.is_null(){ if val.is_null(){
_err_str.push(raw_name); #names_ref3
}
::std::mem::transmute(val)
},
)*
};
if _err_str.is_empty() {
Ok(s)
} }
else{ else{
Err(_err_str) ::std::mem::transmute(val)
}
},
)*
} }
} }
#( #(
pub unsafe fn #names_ref(&self, #expanded_params_ref) -> #return_types_ref { pub unsafe fn #names_ref(&self, #expanded_params_ref) -> #return_types_ref {