Create project structure for rendering

This commit is contained in:
hodasemi 2023-01-12 10:10:09 +01:00
parent c1add2e953
commit 5b8be0eb45
3 changed files with 151 additions and 45 deletions

View file

@ -1,6 +1,7 @@
pub mod enums; pub mod enums;
pub mod structs; pub mod structs;
mod overlay;
mod vk_handles; mod vk_handles;
use std::{ use std::{
@ -9,37 +10,27 @@ use std::{
io::Write, io::Write,
mem, mem,
os::raw::c_char, os::raw::c_char,
ptr, ptr, slice,
sync::Arc,
}; };
use enums::*; use enums::*;
use overlay::Overlay;
use structs::*; use structs::*;
use vk_handles::*; use vk_handles::*;
use vulkan_rs::prelude::*; use vulkan_rs::prelude::*;
const LOG_FILE: &'static str = "/home/michael/rf2_vk_hud.log"; const LOG_FILE: &'static str = "/home/michael/rf2_vk_hud.log";
static mut INSTANCE: Option<Arc<Instance>> = None; static mut OVERLAY: Overlay = Overlay::new();
static mut DEVICE: Option<Arc<Device>> = None;
static mut SWAPCHAIN: Option<Arc<Swapchain>> = None;
static mut QUEUE_SUBMIT: PFN_vkQueueSubmit = static mut QUEUE_SUBMIT: PFN_vkQueueSubmit =
unsafe { mem::transmute(vkVoidFunction as *const c_void) }; unsafe { mem::transmute(vkVoidFunction as *const c_void) };
pub fn instance() -> Arc<Instance> {
unsafe { INSTANCE.as_ref().unwrap().clone() }
}
pub fn device() -> Arc<Device> {
unsafe { DEVICE.as_ref().unwrap().clone() }
}
#[no_mangle] #[no_mangle]
#[allow(non_snake_case)] #[allow(non_snake_case)]
pub extern "C" fn vkNegotiateLoaderLayerInterfaceVersion( pub extern "C" fn vkNegotiateLoaderLayerInterfaceVersion(
pVersionStruct: *mut VkNegotiateLayerInterface, pVersionStruct: *mut VkNegotiateLayerInterface,
) -> VkResult { ) -> VkResult {
File::create(LOG_FILE).unwrap(); if let Err(_) = File::create(LOG_FILE) {}
write_log(" =================================================================="); write_log(" ==================================================================");
write_log(" ======================= New Negotiation =========================="); 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 VK_SUCCESS
} }
@ -84,8 +81,6 @@ extern "system" fn get_device_proc_addr(
return func; return func;
} }
// write_log(format!("\trequested fn: {} in device proc addr", s));
// write_log(format!("\t-> not found"));
Functions::Null.convert() Functions::Null.convert()
} }
@ -112,8 +107,6 @@ extern "system" fn get_instance_proc_addr(
return func; return func;
} }
// write_log(format!("\trequested fn: {} in instance proc addr", s));
// write_log(format!("\t-> not found"));
Functions::Null.convert() 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"); write_log("-> created local instance handle");
@ -186,11 +179,12 @@ extern "system" fn destroy_instance(instance: VkInstance, allocator: *const VkAl
write_log(" ================== vulkan layer destroy instance =================="); write_log(" ================== vulkan layer destroy instance ==================");
unsafe { unsafe {
let destroy_instance: PFN_vkDestroyInstance = if let Some(vk_fn) = vk_handles().handle("vkDestroyInstance") {
mem::transmute(vk_handles().handle("vkDestroyInstance").unwrap()); let destroy_instance: PFN_vkDestroyInstance = mem::transmute(vk_fn);
destroy_instance(instance, allocator); destroy_instance(instance, allocator);
} }
}
} }
extern "system" fn create_device( extern "system" fn create_device(
@ -216,10 +210,16 @@ extern "system" fn create_device(
chain_info.advance_layer_info(); chain_info.advance_layer_info();
let result = unsafe { let result = unsafe {
let create_device: PFN_vkCreateDevice = match vk_handles().handle("vkCreateDevice") {
mem::transmute(vk_handles().handle("vkCreateDevice").unwrap()); Some(vk_fn) => {
let create_device: PFN_vkCreateDevice = mem::transmute(vk_fn);
create_device(physical_device, create_info, allocator, device) create_device(physical_device, create_info, allocator, device)
}
None => {
write_log("failed creating device");
return VK_ERROR_INITIALIZATION_FAILED;
}
}
}; };
if result != VK_SUCCESS { if result != VK_SUCCESS {
@ -227,16 +227,29 @@ extern "system" fn create_device(
} }
vk_handles_mut().load_device_functions(unsafe { *device }, proc_addr); vk_handles_mut().load_device_functions(unsafe { *device }, proc_addr);
unsafe { QUEUE_SUBMIT = mem::transmute(vk_handles().handle("vkQueueSubmit").unwrap()) }; unsafe {
QUEUE_SUBMIT = match vk_handles().handle("vkQueueSubmit") {
let pdev = PhysicalDevice::from_raw(instance(), physical_device).unwrap(); 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() }; let ext_names = unsafe { (*create_info).extension_names() };
write_log(format!("{:?}", ext_names)); write_log(format!("{:?}", ext_names));
unsafe { unsafe {
DEVICE = Some( OVERLAY.set_device(
match Device::preinitialized(*device, proc_addr, pdev, &ext_names) { match Device::preinitialized(*device, proc_addr, pdev, &ext_names) {
Ok(dev) => dev, Ok(dev) => dev,
Err(err) => { Err(err) => {
@ -254,11 +267,12 @@ extern "system" fn destroy_device(device: VkDevice, allocator: *const VkAllocati
write_log(" ================== vulkan layer destroy device =================="); write_log(" ================== vulkan layer destroy device ==================");
unsafe { unsafe {
let destroy_device: PFN_vkDestroyDevice = if let Some(vk_fn) = vk_handles().handle("vkDestroyDevice") {
mem::transmute(vk_handles().handle("vkDestroyDevice").unwrap()); let destroy_device: PFN_vkDestroyDevice = mem::transmute(vk_fn);
destroy_device(device, allocator); destroy_device(device, allocator);
} }
}
} }
extern "system" fn create_swapchain( extern "system" fn create_swapchain(
@ -269,10 +283,19 @@ extern "system" fn create_swapchain(
) -> VkResult { ) -> VkResult {
write_log(" ================== vulkan layer create swapchain =================="); 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 { *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 VK_SUCCESS
} }
@ -283,18 +306,33 @@ extern "system" fn submit_queue(
submits: *const VkSubmitInfo, submits: *const VkSubmitInfo,
fence: VkFence, fence: VkFence,
) -> VkResult { ) -> 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) { pub fn write_log(msg: impl ToString) {
let mut file = OpenOptions::new() if let Ok(mut file) = OpenOptions::new().append(true).create(true).open(LOG_FILE) {
.append(true) if let Err(_) = file.write_all(format!("{}\n", msg.to_string()).as_bytes()) {}
.create(true) }
.open(LOG_FILE)
.unwrap();
file.write_all(format!("{}\n", msg.to_string()).as_bytes())
.unwrap();
} }
pub fn get_vk_func(s: &str) -> Option<Functions> { pub fn get_vk_func(s: &str) -> Option<Functions> {

50
src/overlay/mod.rs Normal file
View file

@ -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<Arc<Instance>>,
device: Option<Arc<Device>>,
rendering: Option<Rendering>,
}
impl Overlay {
pub const fn new() -> Self {
Self {
instance: None,
device: None,
rendering: None,
}
}
pub fn set_instance(&mut self, instance: Arc<Instance>) {
self.instance = Some(instance);
}
pub fn instance(&self) -> Arc<Instance> {
self.instance.as_ref().unwrap().clone()
}
pub fn set_device(&mut self, device: Arc<Device>) {
self.device = Some(device);
}
pub fn device(&self) -> Arc<Device> {
self.device.as_ref().unwrap().clone()
}
pub fn create_rendering(&mut self, swapchain: Arc<Swapchain>) -> Result<()> {
self.rendering = Some(Rendering::new(swapchain));
Ok(())
}
pub fn render(&mut self) -> Result<VkSubmitInfo> {
self.rendering.as_mut().unwrap().render()
}
}

18
src/overlay/rendering.rs Normal file
View file

@ -0,0 +1,18 @@
use anyhow::Result;
use vulkan_rs::prelude::*;
use std::sync::Arc;
pub struct Rendering {
swapchain: Arc<Swapchain>,
}
impl Rendering {
pub fn new(swapchain: Arc<Swapchain>) -> Self {
Self { swapchain }
}
pub fn render(&mut self) -> Result<VkSubmitInfo> {
todo!()
}
}