From 170aa92a03c3ed6996bbb213e1490f7b38079d07 Mon Sep 17 00:00:00 2001 From: maik klein Date: Mon, 28 Nov 2016 21:16:35 +0100 Subject: [PATCH] vk loader rework --- .idea/ashlib.iml | 9 - .idea/compiler.xml | 22 -- .idea/copyright/profiles_settings.xml | 3 - .idea/misc.xml | 55 --- .idea/modules.xml | 8 - .idea/vcs.xml | 6 - .idea/workspace.xml | 499 -------------------------- ash/Cargo.toml | 1 + ash/src/instance.rs | 498 +++++++++++++++---------- ash/src/lib.rs | 15 +- ash/src/load.rs | 118 +++--- examples/Cargo.lock | 1 + examples/src/main.rs | 129 ++----- vk_loader2/src/lib.rs | 21 +- 14 files changed, 435 insertions(+), 950 deletions(-) delete mode 100644 .idea/ashlib.iml delete mode 100644 .idea/compiler.xml delete mode 100644 .idea/copyright/profiles_settings.xml delete mode 100644 .idea/misc.xml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/vcs.xml delete mode 100644 .idea/workspace.xml diff --git a/.idea/ashlib.iml b/.idea/ashlib.iml deleted file mode 100644 index d6ebd48..0000000 --- a/.idea/ashlib.iml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml deleted file mode 100644 index 96cc43e..0000000 --- a/.idea/compiler.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml deleted file mode 100644 index e7bedf3..0000000 --- a/.idea/copyright/profiles_settings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 4b4bb32..0000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,55 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 1350090..0000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 35eb1dd..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml deleted file mode 100644 index f71b70f..0000000 --- a/.idea/workspace.xml +++ /dev/null @@ -1,499 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1471359564698 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/ash/Cargo.toml b/ash/Cargo.toml index bf7fffe..3b0a41c 100644 --- a/ash/Cargo.toml +++ b/ash/Cargo.toml @@ -10,3 +10,4 @@ glfw = "0.9.1" bitflags = "0.7.0" vk_loader = { version = "0.1.0", path = "../vk_loader"} +vk_loader2 = { version = "0.1.0", path = "../vk_loader2"} diff --git a/ash/src/instance.rs b/ash/src/instance.rs index b309d32..14fc17e 100644 --- a/ash/src/instance.rs +++ b/ash/src/instance.rs @@ -6,219 +6,337 @@ use std::error; use std::fmt; use std::mem; use std::sync::Arc; - -use vk_loader as vk; -use feature; -use load; -use fence; -use extensions::*; use std::os::raw::*; use std::cell::Cell; -use surface; -use device::*; +use vk_loader2 as vk; +// use feature; +use load; +// use fence; +// use extensions::*; +// use surface; +// use device::*; -pub struct DebugCallback { - handle: vk::DebugReportCallbackEXT, - f: *mut Fn(String), -} - -#[derive(Clone)] +#[derive(Debug)] pub struct Instance { - pub inner: Arc, + handle: vk::Instance, + instance_fn: vk::InstanceFn, } -pub struct InstanceImpl { - pub instance: vk::Instance, - pub ip: vk::InstancePointers, - callback: Option, -} - -impl Instance{ - pub fn handle(&self) -> usize{ - self.inner.instance - } - - pub fn ip(&self) -> &vk::InstancePointers { - &self.inner.ip - } -} - -unsafe impl Send for Instance {} -unsafe impl Sync for Instance {} - -impl Drop for InstanceImpl { - fn drop(&mut self) { - unsafe { - if let Some(ref callback) = self.callback { - self.ip.DestroyDebugReportCallbackEXT(self.instance, callback.handle, ptr::null()); - Box::from_raw(callback.f); +macro_rules! vk_error( + ($err_name: ident, $($raw_name: ident => $name: ident,)*) => { + #[derive(Debug)] + pub enum $err_name { + $( + $name, + )* + } + impl From for $err_name { + fn from(r: vk::Result) -> $err_name { + match r { + $( + vk::Result::$raw_name => $err_name::$name, + )* + _ => panic!("Missing error case for '{}', please open an issue.", stringify!($err_name)), + } } - self.ip.DestroyInstance(self.instance, ptr::null()); } } -} +); -pub struct ApplicationInfo { - pub name: String, -} +vk_error!( + InstanceError, + ErrorOutOfHostMemory => OutOfHostMemory, + ErrorOutOfDeviceMemory => OutOfDeviceMemory, + ErrorInitializationFailed => InitializationFailed, + ErrorIncompatibleDriver => IncompatibleDriver, +); + +vk_error!( + EnumerateDeviceError, + ErrorOutOfHostMemory => OutOfHostMemory, + ErrorOutOfDeviceMemory => OutOfDeviceMemory, + ErrorInitializationFailed => InitializationFailed, +); impl Instance { - pub fn create_surface(&self, s: &S) -> surface::Surface { - surface::Surface { - instance: self.clone(), - handle: s.create_surface(self), + // FIX: Add loading error + pub fn create_instance>(i: I) -> Result { + let create_info = i.into(); + let static_fn = load::static_fn().unwrap(); + let entry = load::entry_fn(&static_fn); + unsafe { + let mut instance: vk::Instance = mem::uninitialized(); + let err_code = entry.create_instance(&create_info, ptr::null(), &mut instance); + if err_code != vk::Result::Success { + return Err(err_code); + } + let instance_fn = vk::InstanceFn::load(|name| unsafe { + mem::transmute(static_fn.get_instance_proc_addr(instance, name.as_ptr())) + }) + .unwrap(); + Ok(Instance { + handle: instance, + instance_fn: instance_fn, + }) } } - pub fn extenstion_properties() -> InstanceExtension { - let entry_points = load::entry_points().unwrap(); - let extension_props = unsafe { - let mut num = 0; - entry_points.EnumerateInstanceExtensionProperties(ptr::null(), &mut num, ptr::null_mut()); - let mut data = Vec::with_capacity(num as usize); - entry_points.EnumerateInstanceExtensionProperties(ptr::null(), &mut num, data.as_mut_ptr()); - data.set_len(num as usize); - InstanceExtensionProperties { ext_props: data } - }; - extension_props.into() + pub fn enumerate_physical_devices(&self) -> Result, vk::Result> { + unsafe { + let mut num = mem::uninitialized(); + self.instance_fn + .enumerate_physical_devices(self.handle, &mut num, ptr::null_mut()); + let mut physical_devices = Vec::::with_capacity(num as usize); + let err_code = self.instance_fn + .enumerate_physical_devices(self.handle, &mut num, physical_devices.as_mut_ptr()); + physical_devices.set_len(num as usize); + match err_code { + vk::Result::Success => Ok(physical_devices), + _ => Err(err_code), + } + } } - pub fn device_extension_properties(&self, device: vk::PhysicalDevice) -> DeviceExtension { - let extension_props = unsafe { + pub fn enumerate_instance_layer_properties() -> Vec { + let static_fn = load::static_fn().unwrap(); + let entry = load::entry_fn(&static_fn); + unsafe { let mut num = 0; - self.inner.ip - .EnumerateDeviceExtensionProperties(device, ptr::null(), &mut num, ptr::null_mut()); + entry.enumerate_instance_layer_properties(&mut num, ptr::null_mut()); + + let mut v = Vec::with_capacity(num as usize); + entry.enumerate_instance_layer_properties(&mut num, v.as_mut_ptr()); + v.set_len(num as usize); + v + } + } + + pub fn enumerate_device_extension_properties + (&self, + device: vk::PhysicalDevice) + -> Result, vk::Result> { + unsafe { + let mut num = 0; + self.instance_fn + .enumerate_device_extension_properties(device, + ptr::null(), + &mut num, + ptr::null_mut()); let mut data = Vec::with_capacity(num as usize); - self.inner.ip.EnumerateDeviceExtensionProperties(device, + let err_code = self.instance_fn + .enumerate_device_extension_properties(device, ptr::null(), &mut num, data.as_mut_ptr()); data.set_len(num as usize); - DeviceExtensionProperties { ext_props: data } - }; - extension_props.into() - } - - pub fn new(app_info: &ApplicationInfo, - extensions: &InstanceExtension, - f: F) - -> Instance { - let entry_points = load::entry_points().unwrap(); - - unsafe { - let mut num = 0; - entry_points.EnumerateInstanceLayerProperties(&mut num, ptr::null_mut()); - - let mut v = Vec::with_capacity(num as usize); - entry_points.EnumerateInstanceLayerProperties(&mut num, v.as_mut_ptr()); - v.set_len(num as usize); - - for p in v { - // println!("layer {}", CStr::from_ptr(p.layerName.as_ptr()).to_str().unwrap()); + match err_code { + vk::Result::Success => Ok(data), + _ => Err(err_code), } } - let layername = CString::new("VK_LAYER_LUNARG_standard_validation").unwrap(); - let layer = [layername.as_ptr()]; - - let c = CString::new(app_info.name.clone()).unwrap(); - let raw_name = c.as_ptr(); - let appinfo = vk::ApplicationInfo { - pApplicationName: raw_name, - sType: vk::STRUCTURE_TYPE_APPLICATION_INFO, - pNext: ptr::null(), - applicationVersion: 0, - pEngineName: raw_name, - engineVersion: 0, - apiVersion: 0, - }; - - let extension_list = extensions.extension_list(); - let extension_list_raw = - extension_list.iter().map(|extension| extension.as_ptr()).collect::>(); - let create_info = vk::InstanceCreateInfo { - sType: vk::STRUCTURE_TYPE_INSTANCE_CREATE_INFO, - pApplicationInfo: &appinfo, - pNext: ptr::null(), - ppEnabledLayerNames: layer.as_ptr(), - enabledLayerCount: layer.len() as u32, - ppEnabledExtensionNames: extension_list_raw.as_ptr(), - enabledExtensionCount: extension_list_raw.len() as u32, - flags: 0, - }; - - let mut instance: vk::Instance = unsafe { mem::uninitialized() }; - unsafe { - entry_points.CreateInstance(&create_info, ptr::null(), &mut instance); - } - let vk: vk::InstancePointers = { - let f = load::static_functions().unwrap(); - vk::InstancePointers::load(|name| unsafe { - mem::transmute(f.GetInstanceProcAddr(instance, name.as_ptr())) - }) - }; - extern "system" fn debug_callback(flags: vk::DebugReportFlagsEXT, - obj: vk::DebugReportObjectTypeEXT, - u: u64, - u1: usize, - i: i32, - chars: *const c_char, - chars1: *const c_char, - data: *mut c_void) - -> u32 { - unsafe { - let f = &*(data as *mut F); - f(CStr::from_ptr(chars).to_str().unwrap().to_owned()); - f(CStr::from_ptr(chars1).to_str().unwrap().to_owned()); - } - 1 - } - let raw_boxed_f = Box::into_raw(Box::new(f)); - let debug = vk::DebugReportCallbackCreateInfoEXT { - sType: 1000011000, - pNext: ptr::null(), - flags: vk::DEBUG_REPORT_ERROR_BIT_EXT | vk::DEBUG_REPORT_WARNING_BIT_EXT, - pfnCallback: debug_callback::, - pUserData: raw_boxed_f as *mut c_void, - }; - let callback = unsafe { - let mut callback: vk::DebugReportCallbackEXT = mem::uninitialized(); - - assert!(vk.CreateDebugReportCallbackEXT(instance, - &debug, - ptr::null(), - &mut callback) == 0, - "Debug"); - - DebugCallback { - f: raw_boxed_f, - handle: callback, - } - }; - Instance { - inner: Arc::new(InstanceImpl { - ip: vk, - instance: instance, - callback: Some(callback), - }), - } - } - - pub fn get_pysical_devices(&self) -> Vec { - unsafe { - let mut num = 0; - self.inner.ip - .EnumeratePhysicalDevices(self.inner.instance, &mut num, ptr::null_mut()); - let mut physical_devices = Vec::::with_capacity(num as usize); - self.inner.ip - .EnumeratePhysicalDevices(self.inner.instance, &mut num, physical_devices.as_mut_ptr()); - physical_devices.set_len(num as usize); - physical_devices.into_iter() - .map(|handle| { - PhysicalDevice { - instance: self.clone(), - handle: handle, - } - }) - .collect() - } } } +// pub struct DebugCallback { +// handle: vk::DebugReportCallbackEXT, +// f: *mut Fn(String), +// } +// +// #[derive(Clone)] +// pub struct Instance { +// pub inner: Arc, +// } +// +// pub struct InstanceImpl { +// pub instance: vk::Instance, +// pub ip: vk::InstancePointers, +// callback: Option, +// } +// +// impl Instance{ +// pub fn handle(&self) -> usize{ +// self.inner.instance +// } +// +// pub fn ip(&self) -> &vk::InstancePointers { +// &self.inner.ip +// } +// } +// +// unsafe impl Send for Instance {} +// unsafe impl Sync for Instance {} +// +// impl Drop for InstanceImpl { +// fn drop(&mut self) { +// unsafe { +// if let Some(ref callback) = self.callback { +// self.ip.DestroyDebugReportCallbackEXT(self.instance, callback.handle, ptr::null()); +// Box::from_raw(callback.f); +// } +// self.ip.DestroyInstance(self.instance, ptr::null()); +// } +// } +// } +// +// pub struct ApplicationInfo { +// pub name: String, +// } +// +// impl Instance { +// pub fn create_surface(&self, s: &S) -> surface::Surface { +// surface::Surface { +// instance: self.clone(), +// handle: s.create_surface(self), +// } +// } +// +// pub fn extenstion_properties() -> InstanceExtension { +// let entry_points = load::entry_points().unwrap(); +// let extension_props = unsafe { +// let mut num = 0; +// entry_points.EnumerateInstanceExtensionProperties(ptr::null(), &mut num, ptr::null_mut()); +// let mut data = Vec::with_capacity(num as usize); +// entry_points.EnumerateInstanceExtensionProperties(ptr::null(), &mut num, data.as_mut_ptr()); +// data.set_len(num as usize); +// InstanceExtensionProperties { ext_props: data } +// }; +// extension_props.into() +// } +// pub fn device_extension_properties(&self, device: vk::PhysicalDevice) -> DeviceExtension { +// let extension_props = unsafe { +// let mut num = 0; +// self.inner.ip +// .EnumerateDeviceExtensionProperties(device, ptr::null(), &mut num, ptr::null_mut()); +// let mut data = Vec::with_capacity(num as usize); +// self.inner.ip.EnumerateDeviceExtensionProperties(device, +// ptr::null(), +// &mut num, +// data.as_mut_ptr()); +// data.set_len(num as usize); +// DeviceExtensionProperties { ext_props: data } +// }; +// extension_props.into() +// } +// +// pub fn new(app_info: &ApplicationInfo, +// extensions: &InstanceExtension, +// f: F) +// -> Instance { +// let entry_points = load::entry_points().unwrap(); +// +// unsafe { +// let mut num = 0; +// entry_points.EnumerateInstanceLayerProperties(&mut num, ptr::null_mut()); +// +// let mut v = Vec::with_capacity(num as usize); +// entry_points.EnumerateInstanceLayerProperties(&mut num, v.as_mut_ptr()); +// v.set_len(num as usize); +// +// for p in v { +// // println!("layer {}", CStr::from_ptr(p.layerName.as_ptr()).to_str().unwrap()); +// } +// } +// let layername = CString::new("VK_LAYER_LUNARG_standard_validation").unwrap(); +// let layer = [layername.as_ptr()]; +// +// let c = CString::new(app_info.name.clone()).unwrap(); +// let raw_name = c.as_ptr(); +// let appinfo = vk::ApplicationInfo { +// pApplicationName: raw_name, +// sType: vk::STRUCTURE_TYPE_APPLICATION_INFO, +// pNext: ptr::null(), +// applicationVersion: 0, +// pEngineName: raw_name, +// engineVersion: 0, +// apiVersion: 0, +// }; +// +// let extension_list = extensions.extension_list(); +// let extension_list_raw = +// extension_list.iter().map(|extension| extension.as_ptr()).collect::>(); +// let create_info = vk::InstanceCreateInfo { +// sType: vk::STRUCTURE_TYPE_INSTANCE_CREATE_INFO, +// pApplicationInfo: &appinfo, +// pNext: ptr::null(), +// ppEnabledLayerNames: layer.as_ptr(), +// enabledLayerCount: layer.len() as u32, +// ppEnabledExtensionNames: extension_list_raw.as_ptr(), +// enabledExtensionCount: extension_list_raw.len() as u32, +// flags: 0, +// }; +// +// let mut instance: vk::Instance = unsafe { mem::uninitialized() }; +// unsafe { +// entry_points.CreateInstance(&create_info, ptr::null(), &mut instance); +// } +// let vk: vk::InstancePointers = { +// let f = load::static_functions().unwrap(); +// vk::InstancePointers::load(|name| unsafe { +// mem::transmute(f.GetInstanceProcAddr(instance, name.as_ptr())) +// }) +// }; +// extern "system" fn debug_callback(flags: vk::DebugReportFlagsEXT, +// obj: vk::DebugReportObjectTypeEXT, +// u: u64, +// u1: usize, +// i: i32, +// chars: *const c_char, +// chars1: *const c_char, +// data: *mut c_void) +// -> u32 { +// unsafe { +// let f = &*(data as *mut F); +// f(CStr::from_ptr(chars).to_str().unwrap().to_owned()); +// f(CStr::from_ptr(chars1).to_str().unwrap().to_owned()); +// } +// 1 +// } +// let raw_boxed_f = Box::into_raw(Box::new(f)); +// let debug = vk::DebugReportCallbackCreateInfoEXT { +// sType: 1000011000, +// pNext: ptr::null(), +// flags: vk::DEBUG_REPORT_ERROR_BIT_EXT | vk::DEBUG_REPORT_WARNING_BIT_EXT, +// pfnCallback: debug_callback::, +// pUserData: raw_boxed_f as *mut c_void, +// }; +// let callback = unsafe { +// let mut callback: vk::DebugReportCallbackEXT = mem::uninitialized(); +// +// assert!(vk.CreateDebugReportCallbackEXT(instance, +// &debug, +// ptr::null(), +// &mut callback) == 0, +// "Debug"); +// +// DebugCallback { +// f: raw_boxed_f, +// handle: callback, +// } +// }; +// Instance { +// inner: Arc::new(InstanceImpl { +// ip: vk, +// instance: instance, +// callback: Some(callback), +// }), +// } +// } +// +// pub fn get_pysical_devices(&self) -> Vec { +// unsafe { +// let mut num = 0; +// self.inner.ip +// .EnumeratePhysicalDevices(self.inner.instance, &mut num, ptr::null_mut()); +// let mut physical_devices = Vec::::with_capacity(num as usize); +// self.inner.ip +// .EnumeratePhysicalDevices(self.inner.instance, &mut num, physical_devices.as_mut_ptr()); +// physical_devices.set_len(num as usize); +// physical_devices.into_iter() +// .map(|handle| { +// PhysicalDevice { +// instance: self.clone(), +// handle: handle, +// } +// }) +// .collect() +// } +// } +// } diff --git a/ash/src/lib.rs b/ash/src/lib.rs index 18c181c..f502f4a 100644 --- a/ash/src/lib.rs +++ b/ash/src/lib.rs @@ -2,16 +2,17 @@ extern crate lazy_static; extern crate shared_library; extern crate vk_loader; +extern crate vk_loader2; extern crate glfw; #[macro_use] extern crate bitflags; pub mod load; -pub mod extensions; -pub mod surface; +//pub mod extensions; +//pub mod surface; pub mod instance; -pub mod feature; -pub mod device; -pub mod commandpool; -pub mod fence; -pub mod buffer; +//pub mod feature; +//pub mod device; +//pub mod commandpool; +//pub mod fence; +//pub mod buffer; diff --git a/ash/src/load.rs b/ash/src/load.rs index cabebf4..c8200f9 100644 --- a/ash/src/load.rs +++ b/ash/src/load.rs @@ -14,7 +14,7 @@ use std::path::Path; use std::ptr; use shared_library; -use vk_loader as vk; +use vk_loader2 as vk; lazy_static! { pub static ref VK_LIB: Result = { @@ -26,59 +26,81 @@ lazy_static! { .map_err(|err| LoadingError::LibraryLoadFailure(err)) }; - static ref VK_STATIC: Result = { - match *VK_LIB { - Ok(ref lib) => { - let mut err = None; - let result = vk::Static::load(|name| unsafe { - let name = name.to_str().unwrap(); - match lib.symbol(name) { - Ok(s) => s, - Err(_) => { // TODO: return error? - err = Some(LoadingError::MissingEntryPoint(name.to_owned())); - ptr::null() - } - } - }); - - if let Some(err) = err { - Err(err) - } else { - Ok(result) - } - }, - Err(ref err) => Err(err.clone()), - } - }; - - static ref VK_ENTRY: Result = { - match *VK_STATIC { - Ok(ref lib) => { - // At this point we assume that if one of the functions fails to load, it is an - // implementation bug and not a real-life situation that could be handled by - // an error. - Ok(vk::EntryPoints::load(|name| unsafe { - mem::transmute(lib.GetInstanceProcAddr(0, name.as_ptr())) - })) - }, - Err(ref err) => Err(err.clone()), - } - }; +// static ref VK_STATIC: Result = { +// match *VK_LIB { +// Ok(ref lib) => { +// let mut err = None; +// let result = vk::Static::load(|name| unsafe { +// let name = name.to_str().unwrap(); +// match lib.symbol(name) { +// Ok(s) => s, +// Err(_) => { // TODO: return error? +// err = Some(LoadingError::MissingEntryPoint(name.to_owned())); +// ptr::null() +// } +// } +// }); +// +// if let Some(err) = err { +// Err(err) +// } else { +// Ok(result) +// } +// }, +// Err(ref err) => Err(err.clone()), +// } +// }; +// +// static ref VK_ENTRY: Result = { +// match *VK_STATIC { +// Ok(ref lib) => { +// // At this point we assume that if one of the functions fails to load, it is an +// // implementation bug and not a real-life situation that could be handled by +// // an error. +// Ok(vk::EntryPoints::load(|name| unsafe { +// mem::transmute(lib.GetInstanceProcAddr(0, name.as_ptr())) +// })) +// }, +// Err(ref err) => Err(err.clone()), +// } +// }; } /// Returns the collection of static functions from the Vulkan loader, or an error if failed to /// open the loader. -pub fn static_functions() -> Result<&'static vk::Static, LoadingError> { - VK_STATIC.as_ref().map_err(|err| err.clone()) +// pub fn static_functions() -> Result<&'static vk::Static, LoadingError> { +// VK_STATIC.as_ref().map_err(|err| err.clone()) +// } + +pub fn static_fn() -> Result { + let r = match *VK_LIB { + Ok(ref lib) => { + vk::Static::load(|name| unsafe { + let name = name.to_str().unwrap(); + match lib.symbol(name) { + Ok(s) => s, + Err(_) => ptr::null(), + } + }) + } + Err(ref err) => return Err("Foo".to_string()), + }; + Ok(r.unwrap()) +} +pub fn entry_fn(static_fn: &vk::Static) -> vk::EntryFn { + let entry = vk::EntryFn::load(|name| unsafe { + mem::transmute(static_fn.get_instance_proc_addr(ptr::null_mut(), name.as_ptr())) + }); + entry.unwrap() } -/// Returns the collection of Vulkan entry points from the Vulkan loader, or an error if failed to -/// open the loader. -pub fn entry_points() -> Result<&'static vk::EntryPoints, LoadingError> { - VK_ENTRY.as_ref().map_err(|err| err.clone()) -} - -/// Error that can happen when loading the Vulkan loader. +/// // Returns the collection of Vulkan entry points from the Vulkan loader, or an error if failed to +/// // open the loader. +/// pub fn entry_points() -> Result<&'static vk::EntryPoints, LoadingError> { +/// VK_ENTRY.as_ref().map_err(|err| err.clone()) +/// } +/// +/// // Error that can happen when loading the Vulkan loader. #[derive(Debug, Clone)] pub enum LoadingError { /// Failed to load the Vulkan shared library. diff --git a/examples/Cargo.lock b/examples/Cargo.lock index 95eabc1..8b0276a 100644 --- a/examples/Cargo.lock +++ b/examples/Cargo.lock @@ -19,6 +19,7 @@ dependencies = [ "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "shared_library 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "vk_loader 0.1.0", + "vk_loader2 0.1.0", ] [[package]] diff --git a/examples/src/main.rs b/examples/src/main.rs index f627dac..5d8c841 100644 --- a/examples/src/main.rs +++ b/examples/src/main.rs @@ -5,42 +5,16 @@ extern crate ash; extern crate vk_loader2 as vk; extern crate glfw; +use ash::instance::Instance; use std::ptr; use std::ffi::{CStr, CString}; use std::mem; - -fn main(){ - - let vkstatic = match *ash::load::VK_LIB { - Ok(ref lib) => { - let mut err = None; - let result = vk::Static::load(|name| unsafe { - let name = name.to_str().unwrap(); - match lib.symbol(name) { - Ok(s) => s, - Err(_) => { // TODO: return error? - err = Some(ash::load::LoadingError::MissingEntryPoint("".to_owned())); - ptr::null() - } - } - }); - if let Some(err) = err { - Err(err) - } else { - Ok(result) - } - }, - Err(ref err) => Err(err.clone()), - }.unwrap(); - - let entry = vk::EntryFn::load(|name| unsafe { - mem::transmute(vkstatic.get_instance_proc_addr(ptr::null_mut(), name.as_ptr())) - - }); - println!("{:?}", entry); +fn main() { let app_name = CString::new("TEST").unwrap(); let raw_name = app_name.as_ptr(); + let lunarg_layer = CString::new("VK_LAYER_LUNARG_standard_validation").unwrap(); + let layers = [lunarg_layer.as_ptr()]; let appinfo = vk::ApplicationInfo { p_application_name: raw_name, s_type: vk::StructureType::ApplicationInfo, @@ -51,87 +25,44 @@ fn main(){ api_version: 0, }; let create_info = vk::InstanceCreateInfo { - s_type: vk::StructureType::ApplicationInfo, + s_type: vk::StructureType::InstanceCreateInfo, p_application_info: &appinfo, p_next: ptr::null(), - pp_enabled_layer_names: ptr::null(), - enabled_layer_count: 0, + pp_enabled_layer_names: layers.as_ptr(), + enabled_layer_count: layers.len() as u32, pp_enabled_extension_names: ptr::null(), enabled_extension_count: 0, flags: 0, }; - let mut instance: vk::Instance = unsafe { mem::uninitialized() }; + let instance = Instance::create_instance(create_info).expect("Instance creation error"); println!("{:?}", instance); - unsafe { - let i = entry.create_instance(&create_info, ptr::null(), &mut instance); - println!("{:?}", i); - - } -// let r1 = vk::load_with(|name| unsafe { -// let cs = CString::new(name).unwrap(); -// mem::transmute(vk::get_instance_proc_addr(ptr::null_mut(), cs.as_ptr())) -// }); -// let app_name = CString::new("TEST").unwrap(); -// let raw_name = app_name.as_ptr(); -// let appinfo = vk::ApplicationInfo { -// p_application_name: raw_name, -// s_type: vk::StructureType::ApplicationInfo, -// p_next: ptr::null(), -// application_version: 0, -// p_engine_name: raw_name, -// engine_version: 0, -// api_version: 0, -// }; -// let create_info = vk::InstanceCreateInfo { -// s_type: vk::StructureType::ApplicationInfo, -// p_application_info: &appinfo, -// p_next: ptr::null(), -// pp_enabled_layer_names: ptr::null(), -// enabled_layer_count: 0, -// pp_enabled_extension_names: ptr::null(), -// enabled_extension_count: 0, -// flags: 0, -// }; -// let mut instance: vk::Instance = unsafe { mem::uninitialized() }; -// println!("{:?}", instance); -// unsafe { -// let i = vk::create_instance(&create_info, ptr::null(), &mut instance); -// println!("{:?}", i); -// -// } -// println!("{:?}", instance); -// let r2 = vk::load_with(|name| unsafe { -// let cs = CString::new(name).unwrap(); -// mem::transmute(vk::get_instance_proc_addr(instance, cs.as_ptr())) -// }); -// println!("{:?}", r2); -// let r3 = vk::load_with(|name| unsafe { -// let cs = CString::new(name).unwrap(); -// mem::transmute(vk::get_instance_proc_addr(ptr::null_mut(), cs.as_ptr())) -// }); -// println!("{:?}", r3); + let pdevices = instance.enumerate_physical_devices().expect("Physical device error"); + println!("{:?}", pdevices); + let ext_props = instance.enumerate_device_extension_properties(pdevices[0]) + .expect("Enumerate device error"); + println!("{:?}", ext_props); } -//use ash::instance::*; -//use vk_loader as vk; -//use ash::extensions::*; -//use glfw::*; -//use std::sync::Arc; -//use std::thread; -//use ash::device::*; -//use ash::surface; -//use ash::commandpool; -//use std::cell::RefCell; -//use std::marker; -//use std::ptr; -//use ash::device; -//fn handle_window_event(window: &mut glfw::Window, event: glfw::WindowEvent) { +// use ash::instance::*; +// use vk_loader as vk; +// use ash::extensions::*; +// use glfw::*; +// use std::sync::Arc; +// use std::thread; +// use ash::device::*; +// use ash::surface; +// use ash::commandpool; +// use std::cell::RefCell; +// use std::marker; +// use std::ptr; +// use ash::device; +// fn handle_window_event(window: &mut glfw::Window, event: glfw::WindowEvent) { // match event { // glfw::WindowEvent::Key(Key::Escape, _, Action::Press, _) => window.set_should_close(true), // _ => {} // } -//} +// } // -//fn main() { +// fn main() { // let mut glfw = glfw::init(glfw::FAIL_ON_ERRORS).unwrap(); // // let (mut window, events) = glfw.create_window(1920, @@ -347,4 +278,4 @@ fn main(){ // // handle_window_event(&mut window, event); // // } // // } -//} +// } diff --git a/vk_loader2/src/lib.rs b/vk_loader2/src/lib.rs index b6b36d9..0d2faa6 100644 --- a/vk_loader2/src/lib.rs +++ b/vk_loader2/src/lib.rs @@ -3109,6 +3109,7 @@ pub type PFN_vkVoidFunction = unsafe extern "system" fn( ); } +//FIX: Need better error handling for extensions macro_rules! vk_functions { ($struct_name: ident, $($raw_name: expr, $name: ident ($($param_name: ident: $param: ty),*,) -> $ret: ty;)+) => { pub struct $struct_name{ @@ -3116,27 +3117,37 @@ macro_rules! vk_functions { $name: extern "system" fn ($($param_name: $param),*) -> $ret, )+ } + + unsafe impl Send for $struct_name {} + unsafe impl Sync for $struct_name {} + impl $struct_name { - pub fn load(mut f: F) -> $struct_name + pub fn load(mut f: F) -> ::std::result::Result<$struct_name, String> where F: FnMut(&::std::ffi::CStr) -> *const c_void { use std::ffi::{CString, CStr}; use std::mem; - $struct_name { + let s = $struct_name { $( $name: unsafe { extern "system" fn $name($(_: $param),*) { panic!("function pointer `{}` not loaded", stringify!($name)) } let cname = CString::new($raw_name).unwrap(); let val = f(&cname); - if val.is_null() { mem::transmute($name as *const ()) } else { mem::transmute(val) } + //if val.is_null() { mem::transmute($name as *const ()) } else { mem::transmute(val) } + //if val.is_null(){ + // return ::std::result::Result::Err($raw_name.to_string()); + //} + mem::transmute(val) }, )+ - } + }; + ::std::result::Result::Ok(s) } $( #[inline] pub unsafe fn $name(&self $(, $param_name: $param)*) -> $ret { let fp = self.$name; + assert!(!(self.$name as *const c_void).is_null(), "{} not loaded!.", stringify!($raw_name)); fp($($param_name),*) } )+ @@ -3147,6 +3158,7 @@ macro_rules! vk_functions { writeln!(fmt, stringify!($struct_name)); $( write!(fmt, $raw_name); + write!(fmt," is loaded = {:?}", !(self.$name as *const c_void).is_null()); writeln!(fmt, ", "); )+ write!(fmt, "") @@ -3235,6 +3247,7 @@ vk_functions!{ vk_functions!{ InstanceFn, + "vkDestroyInstance", destroy_instance( instance: Instance, p_allocator: *const AllocationCallbacks,