// SPDX-License-Identifier: AGPL-3.0-only use crate::error::RendererError; use ash::{Device, vk}; /// Groups all synchronization primitives for the renderer. pub struct SyncPrimitives { /// Semaphores signaled when an image has been acquired from the swapchain and is ready for rendering. pub image_available: Vec, /// Semaphores signaled when rendering to a swapchain image is complete. pub render_finished: Vec, /// Fences used to synchronize CPU execution with GPU frame completion. pub in_flight: Vec, } /// Creates all synchronization primitives for the given number of frames and images. pub fn create_sync_primitives( device: &Device, max_frames_in_flight: usize, image_count: usize, ) -> Result { let semaphore_info = vk::SemaphoreCreateInfo::default(); let fence_info = vk::FenceCreateInfo::default().flags(vk::FenceCreateFlags::SIGNALED); let mut image_available = Vec::with_capacity(max_frames_in_flight); let mut render_finished = Vec::with_capacity(image_count); let mut in_flight = Vec::with_capacity(max_frames_in_flight); for _ in 0..max_frames_in_flight { image_available.push(unsafe { device.create_semaphore(&semaphore_info, None)? }); in_flight.push(unsafe { device.create_fence(&fence_info, None)? }); } for _ in 0..image_count { render_finished.push(unsafe { device.create_semaphore(&semaphore_info, None)? }); } Ok(SyncPrimitives { image_available, render_finished, in_flight, }) } /// Destroys all synchronization primitives. pub unsafe fn destroy_sync_primitives(device: &Device, sync: SyncPrimitives) { unsafe { for semaphore in sync.image_available { device.destroy_semaphore(semaphore, None); } for semaphore in sync.render_finished { device.destroy_semaphore(semaphore, None); } for fence in sync.in_flight { device.destroy_fence(fence, None); } } }