rafx_api/
swapchain.rs

1#[cfg(feature = "rafx-dx12")]
2use crate::dx12::RafxSwapchainDx12;
3#[cfg(any(
4    feature = "rafx-empty",
5    not(any(
6        feature = "rafx-dx12",
7        feature = "rafx-metal",
8        feature = "rafx-vulkan",
9        feature = "rafx-gles2",
10        feature = "rafx-gles3"
11    ))
12))]
13use crate::empty::RafxSwapchainEmpty;
14#[cfg(feature = "rafx-gles2")]
15use crate::gles2::RafxSwapchainGles2;
16#[cfg(feature = "rafx-gles3")]
17use crate::gles3::RafxSwapchainGles3;
18#[cfg(feature = "rafx-metal")]
19use crate::metal::RafxSwapchainMetal;
20#[cfg(feature = "rafx-vulkan")]
21use crate::vulkan::RafxSwapchainVulkan;
22use crate::{
23    RafxFence, RafxFormat, RafxResult, RafxSemaphore, RafxSwapchainColorSpace, RafxSwapchainDef,
24    RafxSwapchainImage,
25};
26
27/// A set of images that act as a "backbuffer" of a window.
28pub enum RafxSwapchain {
29    #[cfg(feature = "rafx-dx12")]
30    Dx12(RafxSwapchainDx12),
31    #[cfg(feature = "rafx-vulkan")]
32    Vk(RafxSwapchainVulkan),
33    #[cfg(feature = "rafx-metal")]
34    Metal(RafxSwapchainMetal),
35    #[cfg(feature = "rafx-gles2")]
36    Gles2(RafxSwapchainGles2),
37    #[cfg(feature = "rafx-gles3")]
38    Gles3(RafxSwapchainGles3),
39    #[cfg(any(
40        feature = "rafx-empty",
41        not(any(
42            feature = "rafx-dx12",
43            feature = "rafx-metal",
44            feature = "rafx-vulkan",
45            feature = "rafx-gles2",
46            feature = "rafx-gles3"
47        ))
48    ))]
49    Empty(RafxSwapchainEmpty),
50}
51
52impl RafxSwapchain {
53    /// Get the number of images in the swapchain. This is important to know because it indicates
54    /// how many frames may be "in-flight" at a time - which affects how long a resource may be
55    /// "in-use" after a command buffere referencing it has been submitted
56    pub fn image_count(&self) -> usize {
57        match self {
58            #[cfg(feature = "rafx-dx12")]
59            RafxSwapchain::Dx12(inner) => inner.image_count(),
60            #[cfg(feature = "rafx-vulkan")]
61            RafxSwapchain::Vk(inner) => inner.image_count(),
62            #[cfg(feature = "rafx-metal")]
63            RafxSwapchain::Metal(inner) => inner.image_count(),
64            #[cfg(feature = "rafx-gles2")]
65            RafxSwapchain::Gles2(inner) => inner.image_count(),
66            #[cfg(feature = "rafx-gles3")]
67            RafxSwapchain::Gles3(inner) => inner.image_count(),
68            #[cfg(any(
69                feature = "rafx-empty",
70                not(any(
71                    feature = "rafx-dx12",
72                    feature = "rafx-metal",
73                    feature = "rafx-vulkan",
74                    feature = "rafx-gles2",
75                    feature = "rafx-gles3"
76                ))
77            ))]
78            RafxSwapchain::Empty(inner) => inner.image_count(),
79        }
80    }
81
82    /// Get the format of the images used in the swapchain
83    pub fn format(&self) -> RafxFormat {
84        match self {
85            #[cfg(feature = "rafx-dx12")]
86            RafxSwapchain::Dx12(inner) => inner.format(),
87            #[cfg(feature = "rafx-vulkan")]
88            RafxSwapchain::Vk(inner) => inner.format(),
89            #[cfg(feature = "rafx-metal")]
90            RafxSwapchain::Metal(inner) => inner.format(),
91            #[cfg(feature = "rafx-gles2")]
92            RafxSwapchain::Gles2(inner) => inner.format(),
93            #[cfg(feature = "rafx-gles3")]
94            RafxSwapchain::Gles3(inner) => inner.format(),
95            #[cfg(any(
96                feature = "rafx-empty",
97                not(any(
98                    feature = "rafx-dx12",
99                    feature = "rafx-metal",
100                    feature = "rafx-vulkan",
101                    feature = "rafx-gles2",
102                    feature = "rafx-gles3"
103                ))
104            ))]
105            RafxSwapchain::Empty(inner) => inner.format(),
106        }
107    }
108
109    /// Get the color space of the images used in the swapchain
110    pub fn color_space(&self) -> RafxSwapchainColorSpace {
111        match self {
112            #[cfg(feature = "rafx-dx12")]
113            RafxSwapchain::Dx12(inner) => inner.color_space(),
114            #[cfg(feature = "rafx-vulkan")]
115            RafxSwapchain::Vk(inner) => inner.color_space(),
116            #[cfg(feature = "rafx-metal")]
117            RafxSwapchain::Metal(inner) => inner.color_space(),
118            #[cfg(feature = "rafx-gles2")]
119            RafxSwapchain::Gles2(inner) => inner.color_space(),
120            #[cfg(feature = "rafx-gles3")]
121            RafxSwapchain::Gles3(inner) => inner.color_space(),
122            #[cfg(any(
123                feature = "rafx-empty",
124                not(any(
125                    feature = "rafx-dx12",
126                    feature = "rafx-metal",
127                    feature = "rafx-vulkan",
128                    feature = "rafx-gles2",
129                    feature = "rafx-gles3"
130                ))
131            ))]
132            RafxSwapchain::Empty(inner) => inner.color_space(),
133        }
134    }
135
136    /// Return the metadata used to create the swapchain
137    pub fn swapchain_def(&self) -> &RafxSwapchainDef {
138        match self {
139            #[cfg(feature = "rafx-dx12")]
140            RafxSwapchain::Dx12(inner) => inner.swapchain_def(),
141            #[cfg(feature = "rafx-vulkan")]
142            RafxSwapchain::Vk(inner) => inner.swapchain_def(),
143            #[cfg(feature = "rafx-metal")]
144            RafxSwapchain::Metal(inner) => inner.swapchain_def(),
145            #[cfg(feature = "rafx-gles2")]
146            RafxSwapchain::Gles2(inner) => inner.swapchain_def(),
147            #[cfg(feature = "rafx-gles3")]
148            RafxSwapchain::Gles3(inner) => inner.swapchain_def(),
149            #[cfg(any(
150                feature = "rafx-empty",
151                not(any(
152                    feature = "rafx-dx12",
153                    feature = "rafx-metal",
154                    feature = "rafx-vulkan",
155                    feature = "rafx-gles2",
156                    feature = "rafx-gles3"
157                ))
158            ))]
159            RafxSwapchain::Empty(inner) => inner.swapchain_def(),
160        }
161    }
162
163    /// Acquire the next image. The given fence will be signaled when it is available
164    ///
165    /// This is the same as `acquire_next_image_semaphore` except that it signals a fence.
166    pub fn acquire_next_image_fence(
167        &mut self,
168        fence: &RafxFence,
169    ) -> RafxResult<RafxSwapchainImage> {
170        match self {
171            #[cfg(feature = "rafx-dx12")]
172            RafxSwapchain::Dx12(inner) => {
173                inner.acquire_next_image_fence(fence.dx12_fence().unwrap())
174            }
175            #[cfg(feature = "rafx-vulkan")]
176            RafxSwapchain::Vk(inner) => inner.acquire_next_image_fence(fence.vk_fence().unwrap()),
177            #[cfg(feature = "rafx-metal")]
178            RafxSwapchain::Metal(inner) => {
179                inner.acquire_next_image_fence(fence.metal_fence().unwrap())
180            }
181            #[cfg(feature = "rafx-gles2")]
182            RafxSwapchain::Gles2(inner) => {
183                inner.acquire_next_image_fence(fence.gles2_fence().unwrap())
184            }
185            #[cfg(feature = "rafx-gles3")]
186            RafxSwapchain::Gles3(inner) => {
187                inner.acquire_next_image_fence(fence.gles3_fence().unwrap())
188            }
189            #[cfg(any(
190                feature = "rafx-empty",
191                not(any(
192                    feature = "rafx-dx12",
193                    feature = "rafx-metal",
194                    feature = "rafx-vulkan",
195                    feature = "rafx-gles2",
196                    feature = "rafx-gles3"
197                ))
198            ))]
199            RafxSwapchain::Empty(inner) => {
200                inner.acquire_next_image_fence(fence.empty_fence().unwrap())
201            }
202        }
203    }
204
205    /// Acquire the next image. The given semaphore will be signaled when it is available
206    ///
207    /// This is the same as `acquire_next_image_fence` except that it signals a semaphore.
208    pub fn acquire_next_image_semaphore(
209        &mut self,
210        semaphore: &RafxSemaphore,
211    ) -> RafxResult<RafxSwapchainImage> {
212        match self {
213            #[cfg(feature = "rafx-dx12")]
214            RafxSwapchain::Dx12(inner) => {
215                inner.acquire_next_image_semaphore(semaphore.dx12_semaphore().unwrap())
216            }
217            #[cfg(feature = "rafx-vulkan")]
218            RafxSwapchain::Vk(inner) => {
219                inner.acquire_next_image_semaphore(semaphore.vk_semaphore().unwrap())
220            }
221            #[cfg(feature = "rafx-metal")]
222            RafxSwapchain::Metal(inner) => {
223                inner.acquire_next_image_semaphore(semaphore.metal_semaphore().unwrap())
224            }
225            #[cfg(feature = "rafx-gles2")]
226            RafxSwapchain::Gles2(inner) => {
227                inner.acquire_next_image_semaphore(semaphore.gles2_semaphore().unwrap())
228            }
229            #[cfg(feature = "rafx-gles3")]
230            RafxSwapchain::Gles3(inner) => {
231                inner.acquire_next_image_semaphore(semaphore.gles3_semaphore().unwrap())
232            }
233            #[cfg(any(
234                feature = "rafx-empty",
235                not(any(
236                    feature = "rafx-dx12",
237                    feature = "rafx-metal",
238                    feature = "rafx-vulkan",
239                    feature = "rafx-gles2",
240                    feature = "rafx-gles3"
241                ))
242            ))]
243            RafxSwapchain::Empty(inner) => {
244                inner.acquire_next_image_semaphore(semaphore.empty_semaphore().unwrap())
245            }
246        }
247    }
248
249    /// Rebuild the swapchain. This is most commonly called when a window is resized.
250    pub fn rebuild(
251        &mut self,
252        swapchain_def: &RafxSwapchainDef,
253    ) -> RafxResult<()> {
254        match self {
255            #[cfg(feature = "rafx-dx12")]
256            RafxSwapchain::Dx12(inner) => inner.rebuild(swapchain_def),
257            #[cfg(feature = "rafx-vulkan")]
258            RafxSwapchain::Vk(inner) => inner.rebuild(swapchain_def),
259            #[cfg(feature = "rafx-metal")]
260            RafxSwapchain::Metal(inner) => inner.rebuild(swapchain_def),
261            #[cfg(feature = "rafx-gles2")]
262            RafxSwapchain::Gles2(inner) => inner.rebuild(swapchain_def),
263            #[cfg(feature = "rafx-gles3")]
264            RafxSwapchain::Gles3(inner) => inner.rebuild(swapchain_def),
265            #[cfg(any(
266                feature = "rafx-empty",
267                not(any(
268                    feature = "rafx-dx12",
269                    feature = "rafx-metal",
270                    feature = "rafx-vulkan",
271                    feature = "rafx-gles2",
272                    feature = "rafx-gles3"
273                ))
274            ))]
275            RafxSwapchain::Empty(inner) => inner.rebuild(swapchain_def),
276        }
277    }
278
279    /// Get the underlying dx12 API object. This provides access to any internally created
280    /// vulkan objects.
281    #[cfg(feature = "rafx-dx12")]
282    pub fn dx12_swapchain(&self) -> Option<&RafxSwapchainDx12> {
283        match self {
284            #[cfg(feature = "rafx-dx12")]
285            RafxSwapchain::Dx12(inner) => Some(inner),
286            #[cfg(feature = "rafx-vulkan")]
287            RafxSwapchain::Vk(_) => None,
288            #[cfg(feature = "rafx-metal")]
289            RafxSwapchain::Metal(_) => None,
290            #[cfg(feature = "rafx-gles2")]
291            RafxSwapchain::Gles2(_) => None,
292            #[cfg(feature = "rafx-gles3")]
293            RafxSwapchain::Gles3(_) => None,
294            #[cfg(any(
295                feature = "rafx-empty",
296                not(any(
297                    feature = "rafx-dx12",
298                    feature = "rafx-metal",
299                    feature = "rafx-vulkan",
300                    feature = "rafx-gles2",
301                    feature = "rafx-gles3"
302                ))
303            ))]
304            RafxSwapchain::Empty(_) => None,
305        }
306    }
307
308    /// Get the underlying vulkan API object. This provides access to any internally created
309    /// vulkan objects.
310    #[cfg(feature = "rafx-vulkan")]
311    pub fn vk_swapchain(&self) -> Option<&RafxSwapchainVulkan> {
312        match self {
313            #[cfg(feature = "rafx-dx12")]
314            RafxSwapchain::Dx12(_) => None,
315            #[cfg(feature = "rafx-vulkan")]
316            RafxSwapchain::Vk(inner) => Some(inner),
317            #[cfg(feature = "rafx-metal")]
318            RafxSwapchain::Metal(_) => None,
319            #[cfg(feature = "rafx-gles2")]
320            RafxSwapchain::Gles2(_) => None,
321            #[cfg(feature = "rafx-gles3")]
322            RafxSwapchain::Gles3(_) => None,
323            #[cfg(any(
324                feature = "rafx-empty",
325                not(any(
326                    feature = "rafx-dx12",
327                    feature = "rafx-metal",
328                    feature = "rafx-vulkan",
329                    feature = "rafx-gles2",
330                    feature = "rafx-gles3"
331                ))
332            ))]
333            RafxSwapchain::Empty(_) => None,
334        }
335    }
336
337    /// Get the underlying metal API object. This provides access to any internally created
338    /// metal objects.
339    #[cfg(feature = "rafx-metal")]
340    pub fn metal_swapchain(&self) -> Option<&RafxSwapchainMetal> {
341        match self {
342            #[cfg(feature = "rafx-dx12")]
343            RafxSwapchain::Dx12(_) => None,
344            #[cfg(feature = "rafx-vulkan")]
345            RafxSwapchain::Vk(_) => None,
346            #[cfg(feature = "rafx-metal")]
347            RafxSwapchain::Metal(inner) => Some(inner),
348            #[cfg(feature = "rafx-gles2")]
349            RafxSwapchain::Gles2(_) => None,
350            #[cfg(feature = "rafx-gles3")]
351            RafxSwapchain::Gles3(_) => None,
352            #[cfg(any(
353                feature = "rafx-empty",
354                not(any(
355                    feature = "rafx-dx12",
356                    feature = "rafx-metal",
357                    feature = "rafx-vulkan",
358                    feature = "rafx-gles2",
359                    feature = "rafx-gles3"
360                ))
361            ))]
362            RafxSwapchain::Empty(_) => None,
363        }
364    }
365
366    /// Get the underlying gl API object. This provides access to any internally created
367    /// metal objects.
368    #[cfg(feature = "rafx-gles2")]
369    pub fn gles2_swapchain(&self) -> Option<&RafxSwapchainGles2> {
370        match self {
371            #[cfg(feature = "rafx-dx12")]
372            RafxSwapchain::Dx12(_) => None,
373            #[cfg(feature = "rafx-vulkan")]
374            RafxSwapchain::Vk(_) => None,
375            #[cfg(feature = "rafx-metal")]
376            RafxSwapchain::Metal(_) => None,
377            #[cfg(feature = "rafx-gles2")]
378            RafxSwapchain::Gles2(inner) => Some(inner),
379            #[cfg(feature = "rafx-gles3")]
380            RafxSwapchain::Gles3(_) => None,
381            #[cfg(any(
382                feature = "rafx-empty",
383                not(any(
384                    feature = "rafx-dx12",
385                    feature = "rafx-metal",
386                    feature = "rafx-vulkan",
387                    feature = "rafx-gles2",
388                    feature = "rafx-gles3"
389                ))
390            ))]
391            RafxSwapchain::Empty(_) => None,
392        }
393    }
394
395    /// Get the underlying gl API object. This provides access to any internally created
396    /// metal objects.
397    #[cfg(feature = "rafx-gles3")]
398    pub fn gles3_swapchain(&self) -> Option<&RafxSwapchainGles3> {
399        match self {
400            #[cfg(feature = "rafx-dx12")]
401            RafxSwapchain::Dx12(_) => None,
402            #[cfg(feature = "rafx-vulkan")]
403            RafxSwapchain::Vk(_) => None,
404            #[cfg(feature = "rafx-metal")]
405            RafxSwapchain::Metal(_) => None,
406            #[cfg(feature = "rafx-gles2")]
407            RafxSwapchain::Gles2(_) => None,
408            #[cfg(feature = "rafx-gles3")]
409            RafxSwapchain::Gles3(inner) => Some(inner),
410            #[cfg(any(
411                feature = "rafx-empty",
412                not(any(
413                    feature = "rafx-dx12",
414                    feature = "rafx-metal",
415                    feature = "rafx-vulkan",
416                    feature = "rafx-gles2",
417                    feature = "rafx-gles3"
418                ))
419            ))]
420            RafxSwapchain::Empty(_) => None,
421        }
422    }
423
424    /// Get the underlying metal API object. This provides access to any internally created
425    /// metal objects.
426    #[cfg(any(
427        feature = "rafx-empty",
428        not(any(
429            feature = "rafx-dx12",
430            feature = "rafx-metal",
431            feature = "rafx-vulkan",
432            feature = "rafx-gles2",
433            feature = "rafx-gles3"
434        ))
435    ))]
436    pub fn empty_swapchain(&self) -> Option<&RafxSwapchainEmpty> {
437        match self {
438            #[cfg(feature = "rafx-dx12")]
439            RafxSwapchain::Dx12(_) => None,
440            #[cfg(feature = "rafx-vulkan")]
441            RafxSwapchain::Vk(_) => None,
442            #[cfg(feature = "rafx-metal")]
443            RafxSwapchain::Metal(_) => None,
444            #[cfg(feature = "rafx-gles2")]
445            RafxSwapchain::Gles2(_) => None,
446            #[cfg(feature = "rafx-gles3")]
447            RafxSwapchain::Gles3(_) => None,
448            #[cfg(any(
449                feature = "rafx-empty",
450                not(any(
451                    feature = "rafx-dx12",
452                    feature = "rafx-metal",
453                    feature = "rafx-vulkan",
454                    feature = "rafx-gles2",
455                    feature = "rafx-gles3"
456                ))
457            ))]
458            RafxSwapchain::Empty(inner) => Some(inner),
459        }
460    }
461}