Rework how data is internally stored

This commit is contained in:
hodasemi 2023-12-01 14:36:38 +01:00
parent 469328b934
commit c297325c37
6 changed files with 346 additions and 133 deletions

View file

@ -20,6 +20,7 @@ paste = "1.0.14"
serde = "1.0.192"
serde_json = "1.0.108"
ringbuf = "0.3.3"
lazy_static = "1.4.0"
[profile.release-lto]
inherits = "release"

View file

@ -5,13 +5,39 @@ use std::{
fs::{self, File, OpenOptions},
io::Write,
path::Path,
sync::{RwLock, RwLockReadGuard, RwLockWriteGuard},
};
use lazy_static::lazy_static;
use overlay::{Overlay, OverlayConfig};
static mut LOG_ENABLED: bool = true;
static mut LOG_FILE: String = String::new();
static mut OVERLAY: Overlay = Overlay::new();
lazy_static! {
static ref OVERLAY: RwLock<Overlay> = RwLock::new(Overlay::new());
}
pub(crate) fn overlay() -> RwLockReadGuard<'static, Overlay> {
match OVERLAY.try_read() {
Ok(overlay) => overlay,
Err(_) => {
write_log!("failed to get read handle from OVERLAY");
write_log!(std::backtrace::Backtrace::force_capture());
panic!();
}
}
}
pub(crate) fn overlay_mut() -> RwLockWriteGuard<'static, Overlay> {
match OVERLAY.try_write() {
Ok(overlay) => overlay,
Err(_) => {
write_log!("failed to get write handle from OVERLAY");
write_log!(std::backtrace::Backtrace::force_capture());
panic!();
}
}
}
pub(crate) fn logging() -> bool {
unsafe { LOG_ENABLED }
@ -96,7 +122,11 @@ pub fn check_logging(home: &str) {
LOG_FILE = format!("{}/rf2_vk_hud.log", home);
}
if let Err(_) = File::create(unsafe { &LOG_FILE }) {}
if let Err(_) = OpenOptions::new()
.append(true)
.create(true)
.open(unsafe { &LOG_FILE })
{}
write_log!(" ==================================================================");
write_log!(" ======================= New Negotiation ==========================");

View file

@ -12,8 +12,7 @@ mod rfactor_data;
use anyhow::Result;
use assetpath::AssetPath;
use std::{
cell::RefCell,
rc::Rc,
collections::HashMap,
sync::{Arc, Mutex},
};
use ui::{guihandler::guihandler::Font, prelude::*};
@ -62,28 +61,38 @@ impl OverlayConfig {
}
}
#[derive(Debug)]
pub struct InstanceCollection {
pub instance: Arc<Instance>,
pub physical_devices: Vec<VkPhysicalDevice>,
pub device_collection: HashMap<VkDevice, DeviceCollection>,
}
#[derive(Debug)]
pub struct DeviceCollection {
pub device: Arc<Device>,
pub queues: HashMap<VkQueue, Arc<Mutex<Queue>>>,
pub swapchains: HashMap<VkSwapchainKHR, Arc<Swapchain>>,
}
pub struct Overlay {
config: OverlayConfig,
instance: Option<Arc<Instance>>,
device: Option<Arc<Device>>,
queue: Option<Arc<Mutex<Queue>>>,
pub(crate) instances: HashMap<VkInstance, InstanceCollection>,
rendering: Option<Rendering>,
gui_handler: Option<Arc<GuiHandler>>,
ui_elements: Vec<Rc<RefCell<dyn UiOverlay>>>,
ui_elements: Vec<Arc<Mutex<dyn UiOverlay>>>,
rfactor_data: Option<RFactorData>,
}
impl Overlay {
pub const fn new() -> Self {
pub fn new() -> Self {
Self {
config: OverlayConfig::new(),
instance: None,
device: None,
queue: None,
instances: HashMap::new(),
rendering: None,
gui_handler: None,
ui_elements: Vec::new(),
@ -96,28 +105,132 @@ impl Overlay {
self.config = config;
}
pub fn set_instance(&mut self, instance: Arc<Instance>) {
self.instance = Some(instance);
pub fn add_instance(&mut self, instance: Arc<Instance>) {
let physical_devices = match instance.enumerate_physical_devices() {
Ok(devices) => devices,
Err(err) => {
write_log!(format!("failed to enumerate physical devices {err:?}"));
panic!();
}
};
self.instances.insert(
instance.vk_handle(),
InstanceCollection {
instance,
physical_devices,
device_collection: HashMap::new(),
},
);
}
pub fn instance(&self) -> Arc<Instance> {
self.instance.as_ref().unwrap().clone()
pub fn remove_instance(&mut self, handle: VkInstance) {
self.instances.remove(&handle);
}
pub fn instance_by_physical_device(&self, physical_device: VkPhysicalDevice) -> Arc<Instance> {
match self
.instances
.values()
.find(|collection| {
collection
.physical_devices
.iter()
.find(|&&phys_dev| phys_dev == physical_device)
.is_some()
})
.map(|collection| &collection.instance)
{
Some(instance) => instance.clone(),
None => {
write_log!(format!(
"failed to find instance with physical device ({physical_device:?})"
));
panic!();
}
}
}
pub fn set_device(&mut self, device: Arc<Device>) {
self.device = Some(device);
if let Some(instance_collection) = self
.instances
.get_mut(&device.physical_device().instance().vk_handle())
{
instance_collection.device_collection.insert(
device.vk_handle(),
DeviceCollection {
device,
queues: HashMap::new(),
swapchains: HashMap::new(),
},
);
}
}
pub fn device(&self) -> Arc<Device> {
self.device.as_ref().unwrap().clone()
fn device_collection(&self, device: VkDevice) -> &DeviceCollection {
for instance_collection in self.instances.values() {
if let Some(device_collection) = instance_collection.device_collection.get(&device) {
return device_collection;
}
}
write_log!(format!("device ({device:?}) not found"));
panic!();
}
fn device_collection_mut(&mut self, device: &Arc<Device>) -> &mut DeviceCollection {
if let Some(instance_collection) = self
.instances
.get_mut(&device.physical_device().instance().vk_handle())
{
if let Some(device_collection) = instance_collection
.device_collection
.get_mut(&device.vk_handle())
{
return device_collection;
}
}
write_log!(format!("device ({device:?}) not found"));
panic!();
}
pub fn device(&self, handle: VkDevice) -> Arc<Device> {
self.device_collection(handle).device.clone()
}
pub fn set_queue(&mut self, queue: Arc<Mutex<Queue>>) {
self.queue = Some(queue);
let handle = queue.lock().unwrap().vk_handle();
let device = queue.lock().unwrap().device().clone();
self.device_collection_mut(&device)
.queues
.insert(handle, queue);
}
pub fn queue(&self) -> Arc<Mutex<Queue>> {
self.queue.as_ref().unwrap().clone()
pub fn queue(&self, device: VkDevice, queue: VkQueue) -> Arc<Mutex<Queue>> {
match self.device_collection(device).queues.get(&queue) {
Some(queue) => queue.clone(),
None => {
write_log!(format!("queue ({queue:?} not found)"));
panic!();
}
}
}
pub fn device_queue(&self, device: VkDevice) -> Arc<Mutex<Queue>> {
self.device_collection(device)
.queues
.values()
.next()
.expect(&format!("no queue for device ({device:?}) present"))
.clone()
}
pub fn insert_swapchain(&mut self, swapchain: Arc<Swapchain>) {
self.device_collection_mut(swapchain.device())
.swapchains
.insert(swapchain.vk_handle(), swapchain);
}
pub fn swapchain(&self, swapchain: VkSwapchainKHR) -> Option<&Arc<Swapchain>> {
@ -130,14 +243,32 @@ impl Overlay {
}
}
pub fn create_rendering(&mut self, swapchain: Arc<Swapchain>) -> Result<()> {
pub fn create_rendering(&mut self, device: VkDevice) -> Result<()> {
write_log!("-> create rendering: start");
self.rendering = None;
write_log!("-> create rendering: old cleared");
let mut rendering = Rendering::new(self.queue(), swapchain.clone())?;
let device_collection = self.device_collection(device);
let device = &device_collection.device.clone();
let queue = match device_collection.queues.values().next() {
Some(queue) => queue.clone(),
None => {
write_log!(format!("failed to find queue"));
panic!();
}
};
let swapchain = match device_collection.swapchains.values().next() {
Some(swapchain) => swapchain.clone(),
None => {
write_log!(format!("failed to find swapchain"));
panic!();
}
};
let mut rendering = Rendering::new(queue.clone(), swapchain.clone())?;
write_log!("-> create rendering: new created");
@ -152,78 +283,80 @@ impl Overlay {
// provide trait required by GuiHandler
let ctx = Arc::new(ContextImpl::new(
self.device(),
self.queue(),
swapchain,
device.clone(),
queue.clone(),
swapchain.clone(),
rendering.images().clone(),
));
write_log!("create rendering: context created");
// create GuiHandler
let gui_handler = GuiHandler::new(create_info, &(ctx as Arc<dyn ContextInterface>))?;
write_log!("GuiHandler successfully created");
write_log!("create rendering: GuiHandler successfully created");
// create ui elements
// create watermark
if self.config.ui_config.enable_watermark {
let watermark = Rc::new(RefCell::new(Watermark::new(&gui_handler)?));
let watermark = Arc::new(Mutex::new(Watermark::new(&gui_handler)?));
self.ui_elements.push(watermark);
write_log!("Watermark successfully created");
write_log!("create rendering: Watermark successfully created");
}
// create radar
if self.config.ui_config.enable_radar {
let radar = Rc::new(RefCell::new(Radar::new(
let radar = Arc::new(Mutex::new(Radar::new(
self.config.radar_config,
self.device(),
self.queue(),
device.clone(),
queue.clone(),
&rendering,
)?));
rendering.add_render_callback({
let radar = radar.clone();
move |index| radar.borrow().render(index)
move |index| radar.lock().unwrap().render(index)
});
self.ui_elements.push(radar);
write_log!("Radar successfully created");
write_log!("create rendering: Radar successfully created");
}
// create pedals
if self.config.ui_config.enable_pedals {
let pedals = Rc::new(RefCell::new(Pedals::new(
let pedals = Arc::new(Mutex::new(Pedals::new(
&gui_handler,
self.device(),
self.queue(),
device.clone(),
queue.clone(),
)?));
self.ui_elements.push(pedals.clone());
rendering.add_render_callback(move |_| pedals.borrow().render());
rendering.add_render_callback(move |_| pedals.lock().unwrap().render());
write_log!("Pedals successfully created");
write_log!("create rendering: Pedals successfully created");
}
// create leaderboard
if self.config.ui_config.enable_leaderboard {
let leaderboard = Rc::new(RefCell::new(LeaderBoard::new(
let leaderboard = Arc::new(Mutex::new(LeaderBoard::new(
&gui_handler,
self.config.leader_board_config,
)?));
self.ui_elements.push(leaderboard);
write_log!("Leader Board successfully created");
write_log!("create rendering: Leader Board successfully created");
}
// add rendering callbacks
rendering.add_render_callback({
let gui_handler = gui_handler.clone();
let device = self.device();
let queue = self.queue();
let device = device.clone();
let queue = queue.clone();
move |index| {
let command_buffer =
@ -242,7 +375,7 @@ impl Overlay {
}
});
write_log!("render callbacks added");
write_log!("create rendering: render callbacks added");
self.rendering = Some(rendering);
self.gui_handler = Some(gui_handler);

View file

@ -14,7 +14,7 @@ pub struct Rendering {
queue: Arc<Mutex<Queue>>,
render_callbacks: Vec<Box<dyn Fn(u32) -> Result<Arc<CommandBuffer>>>>,
render_callbacks: Vec<Box<dyn Fn(u32) -> Result<Arc<CommandBuffer>> + Send + Sync>>,
}
impl Rendering {
@ -60,7 +60,7 @@ impl Rendering {
pub fn add_render_callback<F>(&mut self, f: F)
where
F: Fn(u32) -> Result<Arc<CommandBuffer>> + 'static,
F: Fn(u32) -> Result<Arc<CommandBuffer>> + Send + Sync + 'static,
{
self.render_callbacks.push(Box::new(f));
}

View file

@ -2,8 +2,7 @@ use anyhow::Result;
use rfactor_sm_reader::*;
use std::{
cell::RefCell,
rc::Rc,
sync::{Arc, Mutex},
time::{Duration, Instant},
};
@ -11,7 +10,7 @@ use crate::write_log;
use super::UiOverlay;
pub trait DataReceiver {
pub trait DataReceiver: Send + Sync {
fn game_phase_change(&mut self, phase: GamePhase) -> Result<()>;
fn update_for_phase(&self, phase: GamePhase) -> bool;
@ -67,7 +66,7 @@ pub struct RFactorData {
player_id: Option<i32>,
previous_game_phase: GamePhase,
receivers: Vec<Rc<RefCell<dyn UiOverlay>>>,
receivers: Vec<Arc<Mutex<dyn UiOverlay>>>,
}
impl RFactorData {
@ -89,7 +88,7 @@ impl RFactorData {
})
}
pub fn add_receiver(&mut self, receiver: Rc<RefCell<dyn UiOverlay>>) {
pub fn add_receiver(&mut self, receiver: Arc<Mutex<dyn UiOverlay>>) {
self.receivers.push(receiver);
}
@ -131,7 +130,8 @@ impl RFactorData {
for receiver in self.receivers.iter() {
receiver
.borrow_mut()
.lock()
.unwrap()
.game_phase_change(self.previous_game_phase)?;
}
}
@ -140,7 +140,7 @@ impl RFactorData {
}
for receiver in self.receivers.iter() {
let mut rec_mut = receiver.borrow_mut();
let mut rec_mut = receiver.lock().unwrap();
if rec_mut.update_for_phase(self.previous_game_phase) {
rec_mut.scoring_update(self.previous_game_phase, &vehicle_scorings)?;
@ -156,7 +156,8 @@ impl RFactorData {
for receiver in self.receivers.iter() {
receiver
.borrow_mut()
.lock()
.unwrap()
.game_phase_change(self.previous_game_phase)?;
}
}
@ -170,7 +171,7 @@ impl RFactorData {
write_log!("new telemetry update");
for receiver in self.receivers.iter() {
let mut rec_mut = receiver.borrow_mut();
let mut rec_mut = receiver.lock().unwrap();
if rec_mut.update_for_phase(self.previous_game_phase) {
rec_mut.telemetry_update(self.player_id, &telemetries)?;

View file

@ -13,7 +13,7 @@ use std::{ffi::c_void, mem, os::raw::c_char, ptr};
static mut ACQUIRE_NEXT_IMAGE: PFN_vkAcquireNextImageKHR =
unsafe { mem::transmute(vkVoidFunction as *const c_void) };
use crate::{get_config, logging, write_log, OVERLAY};
use crate::{get_config, logging, overlay, overlay_mut, write_log};
#[no_mangle]
#[allow(non_snake_case)]
@ -24,9 +24,7 @@ pub(crate) extern "C" fn vkNegotiateLoaderLayerInterfaceVersion(
check_logging(&home);
unsafe {
OVERLAY.set_config(get_config(&home));
}
overlay_mut().set_config(get_config(&home));
unsafe {
*pVersionStruct = VkNegotiateLayerInterface {
@ -202,7 +200,7 @@ pub(crate) extern "system" fn create_instance(
}
};
OVERLAY.set_instance(ins);
overlay_mut().add_instance(ins);
}
write_log!("-> created local instance handle");
@ -222,6 +220,7 @@ pub(crate) extern "system" fn destroy_instance(
unsafe {
if let Some(vk_fn) = vk_handles().handle("vkDestroyInstance") {
let destroy_instance: PFN_vkDestroyInstance = mem::transmute(vk_fn);
overlay_mut().remove_instance(instance);
destroy_instance(instance, allocator);
}
@ -278,7 +277,9 @@ pub(crate) extern "system" fn create_device(
};
};
let pdev = match PhysicalDevice::from_raw(unsafe { OVERLAY.instance() }, physical_device) {
let instance = overlay().instance_by_physical_device(physical_device);
let pdev = match PhysicalDevice::from_raw(instance, physical_device) {
Ok(pdev) => pdev,
Err(err) => {
write_log!(format!("failed creating physical device: {:?}", err));
@ -332,10 +333,8 @@ pub(crate) extern "system" fn create_device(
write_log!("got queue from device");
unsafe {
OVERLAY.set_device(device);
OVERLAY.set_queue(queue);
}
overlay_mut().set_device(device.clone());
overlay_mut().set_queue(queue);
VK_SUCCESS
}
@ -378,11 +377,42 @@ pub(crate) extern "system" fn create_swapchain(
*p_swapchain
}));
let swapchain = unsafe { Swapchain::from_raw(OVERLAY.device(), &*create_info, *p_swapchain) };
overlay_mut().insert_swapchain(unsafe {
Swapchain::from_raw(overlay().device(_device), &*create_info, *p_swapchain)
});
{
let instances = &overlay().instances;
write_log!(format!("number of instances: {}", instances.len()));
for instance_collection in instances.values() {
write_log!(format!(
"\tnumber of physical devices: {}",
instance_collection.physical_devices.len()
));
write_log!(format!(
"\tnumber of devices: {}",
instance_collection.device_collection.len()
));
for device_collection in instance_collection.device_collection.values() {
write_log!(format!(
"\t\tnumber of queues: {}",
device_collection.queues.len()
));
write_log!(format!(
"\t\tnumber of swapchains: {}",
device_collection.swapchains.len()
));
}
}
}
write_log!("-> created Arc<Swapchain>");
if let Err(err) = unsafe { OVERLAY.create_rendering(swapchain) } {
if let Err(err) = overlay_mut().create_rendering(_device) {
write_log!(format!("create overlay rendering struct failed: {:?}", err));
return VK_ERROR_INITIALIZATION_FAILED;
}
@ -400,84 +430,96 @@ pub(crate) extern "system" fn acquire_next_image(
fence: VkFence,
image_index: *mut u32,
) -> VkResult {
unsafe {
match OVERLAY.swapchain(swapchain) {
Some(sc) => {
let device = OVERLAY.device();
// unsafe {
// match OVERLAY.swapchain(swapchain) {
// Some(sc) => {
// let device = OVERLAY.device();
let res = device.acquire_next_image(
sc.vk_handle(),
timeout,
Some(semaphore),
Some(fence),
);
// let res = device.acquire_next_image(
// sc.vk_handle(),
// timeout,
// Some(semaphore),
// Some(fence),
// );
write_log!(format!(
"acquire (swapchain: {:?}) res: {:?}",
sc.vk_handle(),
res
));
// write_log!(format!(
// "acquire (swapchain: {:?}) res: {:?}",
// sc.vk_handle(),
// res
// ));
match res {
Ok(res) => match res {
OutOfDate::Ok(index) => {
sc.set_image_index(index);
VK_SUCCESS
}
OutOfDate::OutOfDate => VK_ERROR_OUT_OF_DATE_KHR,
OutOfDate::TimeOut => VK_TIMEOUT,
},
Err(err) => {
write_log!(format!("failed acquiring next image {:?}", err));
VK_ERROR_DEVICE_LOST
}
}
}
None => {
write_log!("acquired other swapchain image");
ACQUIRE_NEXT_IMAGE(device, swapchain, timeout, semaphore, fence, image_index)
}
}
// match res {
// Ok(res) => match res {
// OutOfDate::Ok(index) => {
// sc.set_image_index(index);
// *image_index = index;
// VK_SUCCESS
// }
// OutOfDate::OutOfDate => VK_ERROR_OUT_OF_DATE_KHR,
// OutOfDate::TimeOut => VK_TIMEOUT,
// },
// Err(err) => {
// write_log!(format!("failed acquiring next image {:?}", err));
// VK_ERROR_DEVICE_LOST
// }
// }
// }
// None => {
// write_log!("acquired other swapchain image");
// ACQUIRE_NEXT_IMAGE(device, swapchain, timeout, semaphore, fence, image_index)
// }
// }
// }
let res =
unsafe { ACQUIRE_NEXT_IMAGE(device, swapchain, timeout, semaphore, fence, image_index) };
if res != VK_SUCCESS {
write_log!(" ================== vulkan layer acquire next image ==================");
write_log!(format!("image index: {}", unsafe { *image_index }));
write_log!(format!("result: {:?}", VkResult::from(res)));
}
res
}
pub(crate) extern "system" fn present_queue(
queue: VkQueue,
present_info: *const VkPresentInfoKHR,
) -> VkResult {
if logging() {
write_log!(" ================== vulkan layer queue present ==================");
write_log!(format!("iq: {:?}, cq: {:?}", queue, unsafe {
OVERLAY.queue().lock().unwrap().vk_handle()
}));
unsafe {
let swapchains = std::slice::from_raw_parts(
(*present_info).pSwapchains,
(*present_info).swapchainCount as usize,
);
// if logging() {
// write_log!(" ================== vulkan layer queue present ==================");
// write_log!(format!("iq: {:?}, cq: {:?}", queue, unsafe {
// OVERLAY.queue().lock().unwrap().vk_handle()
// }));
// unsafe {
// let swapchains = std::slice::from_raw_parts(
// (*present_info).pSwapchains,
// (*present_info).swapchainCount as usize,
// );
write_log!(format!("present {} swapchain(s)", swapchains.len()));
// write_log!(format!("present {} swapchain(s)", swapchains.len()));
for swapchain in swapchains {
write_log!(format!("present swapchain: {:?}", swapchain));
// for swapchain in swapchains {
// write_log!(format!("present swapchain: {:?}", swapchain));
if let Some(swch) = OVERLAY.swapchain(*swapchain) {
write_log!(format!(
" -> internal swapchain found! ({:?})",
swch.vk_handle()
));
}
}
}
}
// if let Some(swch) = OVERLAY.swapchain(*swapchain) {
// write_log!(format!(
// " -> internal swapchain found! ({:?})",
// swch.vk_handle()
// ));
// }
// }
// }
// }
match unsafe { OVERLAY.render() } {
Ok(_) => (),
Err(err) => {
write_log!(format!("overlay rendering failed: {:?}", err));
return VK_ERROR_DEVICE_LOST;
}
};
// match unsafe { OVERLAY.render() } {
// Ok(_) => (),
// Err(err) => {
// write_log!(format!("overlay rendering failed: {:?}", err));
// return VK_ERROR_DEVICE_LOST;
// }
// };
let pfn: PFN_vkQueuePresentKHR = match vk_handles().handle("vkQueuePresentKHR") {
Some(pfn) => unsafe { mem::transmute(pfn) },
@ -487,5 +529,11 @@ pub(crate) extern "system" fn present_queue(
}
};
pfn(queue, present_info)
let res = pfn(queue, present_info);
if res != VK_SUCCESS {
write_log!(format!("queue present failed: {:?}", VkResult::from(res)));
}
res
}