1use crate::cleanup::Cleanup;
2use ash::vk;
3
4#[derive(Debug)]
9pub struct CleanupQueue {
10 frame_queue: Vec<QueuedFrame>,
11 current_frame_index: usize,
12}
13
14#[derive(Debug)]
15struct QueuedFrame {
16 buffers: Vec<vk::Buffer>,
17 memory: Vec<vk::DeviceMemory>,
18}
19
20impl CleanupQueue {
21 pub fn new(num_frames: usize) -> Self {
22 Self {
23 frame_queue: (0..num_frames).map(|_| QueuedFrame::new()).collect(),
24 current_frame_index: 0,
25 }
26 }
27
28 fn num_frames(&self) -> usize {
29 self.frame_queue.len()
30 }
31
32 fn get_current_frame_index(&self) -> usize {
33 (self.current_frame_index + self.num_frames() - 1) % self.num_frames()
34 }
35
36 pub fn queue_buffer(&mut self, buffer: vk::Buffer) {
37 let current_frame_index = self.get_current_frame_index();
38 self.frame_queue[current_frame_index].push_buffer(buffer)
39 }
40
41 pub fn queue_memory(&mut self, memory: vk::DeviceMemory) {
42 let current_frame_index = self.get_current_frame_index();
43 self.frame_queue[current_frame_index].push_memory(memory)
44 }
45
46 pub fn queue(&mut self, resource: impl Cleanup) {
47 resource.queue(self);
48 }
49
50 pub unsafe fn tick(&mut self, device: &ash::Device) {
54 let index = self.current_frame_index;
55
56 self.frame_queue[index].destroy(device);
57
58 self.current_frame_index = (self.current_frame_index + 1) % self.num_frames()
59 }
60
61 pub unsafe fn destroy(&mut self, device: &ash::Device) {
65 for frame in &mut self.frame_queue {
66 frame.destroy(device);
67 }
68 }
69}
70
71impl QueuedFrame {
72 fn new() -> Self {
73 Self {
74 buffers: Vec::new(),
75 memory: Vec::new(),
76 }
77 }
78
79 fn push_buffer(&mut self, buffer: vk::Buffer) {
80 self.buffers.push(buffer);
81 }
82
83 fn push_memory(&mut self, memory: vk::DeviceMemory) {
84 self.memory.push(memory);
85 }
86
87 unsafe fn destroy(&mut self, device: &ash::Device) {
88 for buffer in &self.buffers {
89 device.destroy_buffer(*buffer, None);
90 }
91 self.buffers.clear();
92
93 for memory in &self.memory {
94 device.free_memory(*memory, None);
95 }
96 self.memory.clear();
97 }
98}