rFactor2_vk_hud/src/overlay/rendering.rs
2023-01-20 08:14:51 +01:00

91 lines
2.2 KiB
Rust

use anyhow::Result;
use vulkan_rs::prelude::*;
use std::{
sync::{Arc, Mutex},
time::Duration,
};
use crate::write_log;
pub struct Rendering {
swapchain: Arc<Swapchain>,
images: Vec<Arc<Image>>,
queue: Arc<Mutex<Queue>>,
render_callbacks: Vec<Box<dyn Fn(u32) -> Result<Arc<CommandBuffer>>>>,
}
impl Rendering {
pub fn new(queue: Arc<Mutex<Queue>>, swapchain: Arc<Swapchain>) -> Result<Self> {
crate::write_log!("-> Rendering ctor: begin");
let vk_images = swapchain.vk_images()?;
write_log!(format!(
"-> Rendering ctor: vk images ({})",
vk_images.len()
));
let images = match swapchain.wrap_images(&vk_images, &queue, true) {
Ok(images) => images,
Err(err) => {
write_log!(format!("-> Rendering ctor: failed wrapper: {:?}", err));
return Err(err);
}
};
write_log!("-> Rendering ctor: wrapped images");
write_log!(format!(
"-> Rendering swapchain extents ({}, {})",
swapchain.width(),
swapchain.height(),
));
Ok(Self {
swapchain,
images,
queue,
render_callbacks: Vec::new(),
})
}
pub fn swapchain(&self) -> &Arc<Swapchain> {
&self.swapchain
}
pub fn add_render_callback<F>(&mut self, f: F)
where
F: Fn(u32) -> Result<Arc<CommandBuffer>> + 'static,
{
self.render_callbacks.push(Box::new(f));
}
pub fn render(&self) -> Result<()> {
let image_index = self.swapchain.current_index();
let command_buffers: Vec<Arc<CommandBuffer>> = self
.render_callbacks
.iter()
.map(|c| c(image_index))
.collect::<Result<Vec<Arc<CommandBuffer>>>>()?;
write_log!(format!(
"submitting {} commandbuffer(s)",
command_buffers.len()
));
let queue = self.queue.lock().unwrap();
queue.minimal_submit(Duration::from_secs(10), &command_buffers)?;
Ok(())
}
pub fn images(&self) -> &Vec<Arc<Image>> {
&self.images
}
}