59 lines
2 KiB
Rust
59 lines
2 KiB
Rust
// 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<vk::Semaphore>,
|
|
/// Semaphores signaled when rendering to a swapchain image is complete.
|
|
pub render_finished: Vec<vk::Semaphore>,
|
|
/// Fences used to synchronize CPU execution with GPU frame completion.
|
|
pub in_flight: Vec<vk::Fence>,
|
|
}
|
|
|
|
/// 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<SyncPrimitives, RendererError> {
|
|
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);
|
|
}
|
|
}
|
|
}
|