use anyhow::Result; use vulkan_rs::prelude::*; use std::sync::{Arc, Mutex}; use crate::write_log; pub struct Rendering { swapchain: Arc, images: Vec>, queue: Arc>, signal_semaphore: Arc, render_callbacks: Vec Result> + Send + Sync>>, } impl Rendering { pub fn new(queue: Arc>, swapchain: Arc) -> Result { 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 { signal_semaphore: Semaphore::new(swapchain.device().clone())?, swapchain, images, queue, render_callbacks: Vec::new(), }) } pub fn swapchain(&self) -> &Arc { &self.swapchain } pub fn add_render_callback(&mut self, f: F) where F: Fn(u32) -> Result> + Send + Sync + 'static, { self.render_callbacks.push(Box::new(f)); } pub fn render(&self, wait_semaphores: &[VkSemaphore]) -> Result<&Arc> { let image_index = self.swapchain.current_index(); let command_buffers: Vec> = self .render_callbacks .iter() .map(|c| c(image_index)) .collect::>>>()?; let mut submit = SubmitInfo::default().add_signal_semaphore(&self.signal_semaphore); for command_buffer in command_buffers.iter() { submit = submit.add_command_buffer(command_buffer); } for wait_semaphore in wait_semaphores { submit = submit.add_wait_semaphore_vk(*wait_semaphore); } write_log!(format!( "submitting {} commandbuffer(s)", command_buffers.len() )); write_log!(format!( "submitting {} wait semaphore(s)", wait_semaphores.len() )); self.queue.lock().unwrap().submit(None, &[submit])?; write_log!("submitted layer queue"); Ok(&self.signal_semaphore) } pub fn images(&self) -> &Vec> { &self.images } }