favilla/
frame_data.rs

1use crate::vk_engine::VulkanEngine;
2use ash::{vk, Device};
3
4/// Helper struct holding a command pool and per-frame data: semaphores, fences and command buffers.
5pub struct FrameDataManager {
6    pub frame_data: Vec<PerFrameData>,
7    pub command_pool: vk::CommandPool,
8}
9
10impl FrameDataManager {
11    /// Creates a new FrameDataManager, including command pool and synchronistation primitives per
12    /// in-flight frame.
13    /// # Safety
14    /// Must be able to create command buffers, fences and semaphores.
15    pub unsafe fn new(vk_engine: &VulkanEngine) -> Self {
16        let pool_create_info = vk::CommandPoolCreateInfo::builder()
17            .flags(
18                vk::CommandPoolCreateFlags::RESET_COMMAND_BUFFER
19                    | vk::CommandPoolCreateFlags::TRANSIENT,
20            )
21            .queue_family_index(vk_engine.queue_family_index);
22        let pool = vk_engine
23            .device
24            .create_command_pool(&pool_create_info, None)
25            .unwrap();
26
27        let command_buffer_allocate_info = vk::CommandBufferAllocateInfo::builder()
28            .command_buffer_count(vk_engine.num_frames)
29            .command_pool(pool)
30            .level(vk::CommandBufferLevel::PRIMARY);
31
32        let command_buffers_per_frame = vk_engine
33            .device
34            .allocate_command_buffers(&command_buffer_allocate_info)
35            .unwrap();
36
37        let semaphore_create_info = vk::SemaphoreCreateInfo::default();
38
39        let mut image_acquired_semaphores = vec![];
40        let mut render_complete_semaphores = vec![];
41        let mut frame_fences = vec![];
42
43        for _ in 0..vk_engine.num_frames {
44            let image_acquired_semaphore = vk_engine
45                .device
46                .create_semaphore(&semaphore_create_info, None)
47                .unwrap();
48            image_acquired_semaphores.push(image_acquired_semaphore);
49            let render_complete_semaphore = vk_engine
50                .device
51                .create_semaphore(&semaphore_create_info, None)
52                .unwrap();
53            render_complete_semaphores.push(render_complete_semaphore);
54
55            let fence_info = vk::FenceCreateInfo {
56                flags: vk::FenceCreateFlags::SIGNALED,
57                ..Default::default()
58            };
59            let fence = vk_engine.device.create_fence(&fence_info, None).unwrap();
60            frame_fences.push(fence);
61        }
62        let per_frame_data = (0..vk_engine.num_frames as usize)
63            .map(|i| PerFrameData {
64                image_acquired_semaphore: image_acquired_semaphores[i],
65                render_complete_semaphore: render_complete_semaphores[i],
66                frame_fence: frame_fences[i],
67                command_buffer: command_buffers_per_frame[i],
68            })
69            .collect();
70
71        Self {
72            frame_data: per_frame_data,
73            command_pool: pool,
74        }
75    }
76
77    /// Frees all resources held by `self`.
78    /// # Safety
79    /// Resources must not be used anymore.
80    pub unsafe fn destroy(&mut self, device: &Device) {
81        device.destroy_command_pool(self.command_pool, None);
82        for frame_data in &mut self.frame_data {
83            frame_data.destroy(device);
84        }
85    }
86}
87
88/// Data held by `FrameDataManager`.
89pub struct PerFrameData {
90    pub frame_fence: vk::Fence,
91    pub command_buffer: vk::CommandBuffer,
92    pub image_acquired_semaphore: vk::Semaphore,
93    pub render_complete_semaphore: vk::Semaphore,
94}
95
96impl PerFrameData {
97    /// Frees all resources held by `self`.
98    /// # Safety
99    /// Resources must not be used anymore.
100    pub unsafe fn destroy(&mut self, device: &Device) {
101        device.destroy_semaphore(self.image_acquired_semaphore, None);
102        device.destroy_semaphore(self.render_complete_semaphore, None);
103        device.destroy_fence(self.frame_fence, None);
104    }
105}