1use crate::{command::Fence, factory::Factory};
4
5pub type Fences<B> = smallvec::SmallVec<[Fence<B>; 8]>;
7
8#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
11#[allow(missing_copy_implementations)]
12pub struct Frame {
13 index: u64,
14}
15
16impl Frame {
17 pub fn with_index(index: u64) -> Self {
19 Frame { index }
20 }
21
22 pub fn index(&self) -> u64 {
24 self.index
25 }
26}
27
28#[derive(Debug)]
30#[allow(missing_copy_implementations)]
31pub struct CompleteFrame {
32 index: u64,
33}
34
35impl CompleteFrame {
36 pub fn index(&self) -> u64 {
38 self.index
39 }
40}
41
42#[derive(Clone, Copy, Debug, PartialEq, Eq)]
44pub struct FramesRange {
45 next: u64,
46 complete_upper_bound: u64,
47}
48
49impl FramesRange {
50 pub fn is_complete(&self, frame: Frame) -> bool {
52 self.complete_upper_bound > frame.index
53 }
54
55 pub fn complete(&self, frame: Frame) -> Option<CompleteFrame> {
57 if self.complete_upper_bound > frame.index {
58 Some(CompleteFrame { index: frame.index })
59 } else {
60 None
61 }
62 }
63
64 pub fn next(&self) -> Frame {
66 Frame { index: self.next }
67 }
68}
69
70#[derive(Debug)]
72pub struct Frames<B: rendy_core::hal::Backend> {
73 pending: std::collections::VecDeque<Fences<B>>,
74 next: u64,
75}
76
77impl<B> Frames<B>
78where
79 B: rendy_core::hal::Backend,
80{
81 pub fn new() -> Self {
83 Frames {
84 pending: Default::default(),
85 next: 0,
86 }
87 }
88
89 pub fn next(&self) -> Frame {
91 Frame { index: self.next }
92 }
93
94 pub fn advance(&mut self, fences: Fences<B>) {
97 assert!(fences.iter().all(Fence::is_submitted));
98 self.pending.push_back(fences);
99 self.next += 1;
100 }
101
102 pub fn complete_upper_bound(&self) -> u64 {
105 debug_assert!(self.pending.len() as u64 <= self.next);
106 self.next - self.pending.len() as u64
107 }
108
109 pub fn is_complete(&self, frame: Frame) -> bool {
111 self.complete_upper_bound() > frame.index
112 }
113
114 pub fn complete(&self, frame: Frame) -> Option<CompleteFrame> {
116 if self.complete_upper_bound() > frame.index {
117 Some(CompleteFrame { index: frame.index })
118 } else {
119 None
120 }
121 }
122
123 pub fn wait_complete(
135 &mut self,
136 target: Frame,
137 factory: &Factory<B>,
138 free: impl FnMut(Fences<B>),
139 ) -> CompleteFrame {
140 assert!(target.index <= self.next);
141 if let Some(complete) = self.complete(target) {
142 complete
143 } else {
144 let count = self.pending.len() - (self.next - target.index - 1) as usize;
148 let ready = factory.wait_for_fences(
149 self.pending.iter_mut().take(count).flatten(),
150 rendy_core::hal::device::WaitFor::All,
151 !0,
152 );
153 assert_eq!(ready, Ok(true));
154 self.pending.drain(..count).for_each(free);
155 CompleteFrame {
156 index: target.index,
157 }
158 }
159 }
160
161 pub fn dispose(mut self, factory: &mut Factory<B>) {
163 let ready = factory.wait_for_fences(
164 self.pending.iter_mut().flatten(),
165 rendy_core::hal::device::WaitFor::All,
166 !0,
167 );
168 assert_eq!(ready, Ok(true));
169
170 self.pending
171 .drain(..)
172 .flatten()
173 .for_each(|fence| factory.destroy_fence(fence));
174 }
175
176 pub fn range(&self) -> FramesRange {
179 FramesRange {
180 next: self.next,
181 complete_upper_bound: self.complete_upper_bound(),
182 }
183 }
184}