diff --git a/src/lib.rs b/src/lib.rs index 646c3a8..4c19f1f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,7 @@ pub mod enums; pub mod structs; +mod overlay; mod vk_handles; use std::{ @@ -9,37 +10,27 @@ use std::{ io::Write, mem, os::raw::c_char, - ptr, - sync::Arc, + ptr, slice, }; use enums::*; +use overlay::Overlay; use structs::*; use vk_handles::*; use vulkan_rs::prelude::*; const LOG_FILE: &'static str = "/home/michael/rf2_vk_hud.log"; -static mut INSTANCE: Option> = None; -static mut DEVICE: Option> = None; -static mut SWAPCHAIN: Option> = None; +static mut OVERLAY: Overlay = Overlay::new(); static mut QUEUE_SUBMIT: PFN_vkQueueSubmit = unsafe { mem::transmute(vkVoidFunction as *const c_void) }; -pub fn instance() -> Arc { - unsafe { INSTANCE.as_ref().unwrap().clone() } -} - -pub fn device() -> Arc { - unsafe { DEVICE.as_ref().unwrap().clone() } -} - #[no_mangle] #[allow(non_snake_case)] pub extern "C" fn vkNegotiateLoaderLayerInterfaceVersion( pVersionStruct: *mut VkNegotiateLayerInterface, ) -> VkResult { - File::create(LOG_FILE).unwrap(); + if let Err(_) = File::create(LOG_FILE) {} write_log(" =================================================================="); write_log(" ======================= New Negotiation =========================="); @@ -56,7 +47,13 @@ pub extern "C" fn vkNegotiateLoaderLayerInterfaceVersion( } }; - set_vk_handles(VkTypedefHandles::new().unwrap()); + set_vk_handles(match VkTypedefHandles::new() { + Ok(handles) => handles, + Err(err) => { + write_log(format!("failed to load typedef handles {:?}", err)); + return VK_ERROR_INITIALIZATION_FAILED; + } + }); VK_SUCCESS } @@ -84,8 +81,6 @@ extern "system" fn get_device_proc_addr( return func; } - // write_log(format!("\trequested fn: {} in device proc addr", s)); - // write_log(format!("\t-> not found")); Functions::Null.convert() } @@ -112,8 +107,6 @@ extern "system" fn get_instance_proc_addr( return func; } - // write_log(format!("\trequested fn: {} in instance proc addr", s)); - // write_log(format!("\t-> not found")); Functions::Null.convert() } @@ -173,7 +166,7 @@ extern "system" fn create_instance( } }; - INSTANCE = Some(ins); + OVERLAY.set_instance(ins); } write_log("-> created local instance handle"); @@ -186,10 +179,11 @@ extern "system" fn destroy_instance(instance: VkInstance, allocator: *const VkAl write_log(" ================== vulkan layer destroy instance =================="); unsafe { - let destroy_instance: PFN_vkDestroyInstance = - mem::transmute(vk_handles().handle("vkDestroyInstance").unwrap()); + if let Some(vk_fn) = vk_handles().handle("vkDestroyInstance") { + let destroy_instance: PFN_vkDestroyInstance = mem::transmute(vk_fn); - destroy_instance(instance, allocator); + destroy_instance(instance, allocator); + } } } @@ -216,10 +210,16 @@ extern "system" fn create_device( chain_info.advance_layer_info(); let result = unsafe { - let create_device: PFN_vkCreateDevice = - mem::transmute(vk_handles().handle("vkCreateDevice").unwrap()); - - create_device(physical_device, create_info, allocator, device) + match vk_handles().handle("vkCreateDevice") { + Some(vk_fn) => { + let create_device: PFN_vkCreateDevice = mem::transmute(vk_fn); + create_device(physical_device, create_info, allocator, device) + } + None => { + write_log("failed creating device"); + return VK_ERROR_INITIALIZATION_FAILED; + } + } }; if result != VK_SUCCESS { @@ -227,16 +227,29 @@ extern "system" fn create_device( } vk_handles_mut().load_device_functions(unsafe { *device }, proc_addr); - unsafe { QUEUE_SUBMIT = mem::transmute(vk_handles().handle("vkQueueSubmit").unwrap()) }; - - let pdev = PhysicalDevice::from_raw(instance(), physical_device).unwrap(); + unsafe { + QUEUE_SUBMIT = match vk_handles().handle("vkQueueSubmit") { + Some(submit) => mem::transmute(submit), + None => { + write_log("failed querying vkQueueSubmit"); + return VK_ERROR_INITIALIZATION_FAILED; + } + } + }; + let pdev = match PhysicalDevice::from_raw(unsafe { OVERLAY.instance() }, physical_device) { + Ok(pdev) => pdev, + Err(err) => { + write_log(format!("failed creating physical device: {:?}", err)); + return VK_ERROR_INITIALIZATION_FAILED; + } + }; let ext_names = unsafe { (*create_info).extension_names() }; write_log(format!("{:?}", ext_names)); unsafe { - DEVICE = Some( + OVERLAY.set_device( match Device::preinitialized(*device, proc_addr, pdev, &ext_names) { Ok(dev) => dev, Err(err) => { @@ -254,10 +267,11 @@ extern "system" fn destroy_device(device: VkDevice, allocator: *const VkAllocati write_log(" ================== vulkan layer destroy device =================="); unsafe { - let destroy_device: PFN_vkDestroyDevice = - mem::transmute(vk_handles().handle("vkDestroyDevice").unwrap()); + if let Some(vk_fn) = vk_handles().handle("vkDestroyDevice") { + let destroy_device: PFN_vkDestroyDevice = mem::transmute(vk_fn); - destroy_device(device, allocator); + destroy_device(device, allocator); + } } } @@ -269,10 +283,19 @@ extern "system" fn create_swapchain( ) -> VkResult { write_log(" ================== vulkan layer create swapchain =================="); - let swapchain = Swapchain::from_ci(device(), unsafe { &*create_info }).unwrap(); + let swapchain = match unsafe { Swapchain::from_ci(OVERLAY.device(), &*create_info) } { + Ok(swapchain) => swapchain, + Err(err) => { + write_log(format!("create swapchain failed: {:?}", err)); + return VK_ERROR_INITIALIZATION_FAILED; + } + }; unsafe { *p_swapchain = swapchain.vk_handle() }; - unsafe { SWAPCHAIN = Some(swapchain) }; + if let Err(err) = unsafe { OVERLAY.create_rendering(swapchain) } { + write_log(format!("create overlay rendering struct failed: {:?}", err)); + return VK_ERROR_INITIALIZATION_FAILED; + } VK_SUCCESS } @@ -283,18 +306,33 @@ extern "system" fn submit_queue( submits: *const VkSubmitInfo, fence: VkFence, ) -> VkResult { - unsafe { QUEUE_SUBMIT(queue, submit_count, submits, fence) } + // unsafe { return QUEUE_SUBMIT(queue, submit_count, submits, fence): } + + unsafe { + let input_submit_info = slice::from_raw_parts(submits, submit_count as usize); + let overlay_submit = match OVERLAY.render() { + Ok(submit) => submit, + Err(err) => { + write_log(format!("overlay rendering failed: {:?}", err)); + return VK_ERROR_DEVICE_LOST; + } + }; + + let complete_submits = [input_submit_info, &[overlay_submit]].concat(); + + QUEUE_SUBMIT( + queue, + complete_submits.len() as u32, + complete_submits.as_ptr(), + fence, + ) + } } pub fn write_log(msg: impl ToString) { - let mut file = OpenOptions::new() - .append(true) - .create(true) - .open(LOG_FILE) - .unwrap(); - - file.write_all(format!("{}\n", msg.to_string()).as_bytes()) - .unwrap(); + if let Ok(mut file) = OpenOptions::new().append(true).create(true).open(LOG_FILE) { + if let Err(_) = file.write_all(format!("{}\n", msg.to_string()).as_bytes()) {} + } } pub fn get_vk_func(s: &str) -> Option { diff --git a/src/overlay/mod.rs b/src/overlay/mod.rs new file mode 100644 index 0000000..0390178 --- /dev/null +++ b/src/overlay/mod.rs @@ -0,0 +1,50 @@ +use self::rendering::Rendering; + +mod rendering; + +use anyhow::Result; +use std::sync::Arc; +use vulkan_rs::prelude::*; + +#[derive(Default)] +pub struct Overlay { + instance: Option>, + device: Option>, + rendering: Option, +} + +impl Overlay { + pub const fn new() -> Self { + Self { + instance: None, + device: None, + rendering: None, + } + } + + pub fn set_instance(&mut self, instance: Arc) { + self.instance = Some(instance); + } + + pub fn instance(&self) -> Arc { + self.instance.as_ref().unwrap().clone() + } + + pub fn set_device(&mut self, device: Arc) { + self.device = Some(device); + } + + pub fn device(&self) -> Arc { + self.device.as_ref().unwrap().clone() + } + + pub fn create_rendering(&mut self, swapchain: Arc) -> Result<()> { + self.rendering = Some(Rendering::new(swapchain)); + + Ok(()) + } + + pub fn render(&mut self) -> Result { + self.rendering.as_mut().unwrap().render() + } +} diff --git a/src/overlay/rendering.rs b/src/overlay/rendering.rs new file mode 100644 index 0000000..cc369f7 --- /dev/null +++ b/src/overlay/rendering.rs @@ -0,0 +1,18 @@ +use anyhow::Result; +use vulkan_rs::prelude::*; + +use std::sync::Arc; + +pub struct Rendering { + swapchain: Arc, +} + +impl Rendering { + pub fn new(swapchain: Arc) -> Self { + Self { swapchain } + } + + pub fn render(&mut self) -> Result { + todo!() + } +}