1 // Copyright (c) 2016 The vulkano developers
2 // Licensed under the Apache License, Version 2.0
3 // <LICENSE-APACHE or
4 // https://www.apache.org/licenses/LICENSE-2.0> or the MIT
5 // license <LICENSE-MIT or https://opensource.org/licenses/MIT>,
6 // at your option. All files in the project carrying such
7 // notice may not be copied, modified, or distributed except
8 // according to those terms.
9 
10 use super::{
11     sys::{Image, ImageMemory},
12     traits::ImageContent,
13     ImageAccess, ImageDescriptorLayouts, ImageInner, ImageLayout,
14 };
15 use crate::{
16     device::{Device, DeviceOwned},
17     swapchain::Swapchain,
18     OomError,
19 };
20 use std::{
21     hash::{Hash, Hasher},
22     sync::Arc,
23 };
24 
25 /// An image that is part of a swapchain.
26 ///
27 /// Creating a `SwapchainImage` is automatically done when creating a swapchain.
28 ///
29 /// A swapchain image is special in the sense that it can only be used after being acquired by
30 /// calling the `acquire` method on the swapchain. You have no way to know in advance which
31 /// swapchain image is going to be acquired, so you should keep all of them alive.
32 ///
33 /// After a swapchain image has been acquired, you are free to perform all the usual operations
34 /// on it. When you are done you can then *present* the image (by calling the corresponding
35 /// method on the swapchain), which will have the effect of showing the content of the image to
36 /// the screen. Once an image has been presented, it can no longer be used unless it is acquired
37 /// again.
38 #[derive(Debug)]
39 pub struct SwapchainImage {
40     inner: Arc<Image>,
41 }
42 
43 impl SwapchainImage {
from_handle( handle: ash::vk::Image, swapchain: Arc<Swapchain>, image_index: u32, ) -> Result<Arc<SwapchainImage>, OomError>44     pub(crate) unsafe fn from_handle(
45         handle: ash::vk::Image,
46         swapchain: Arc<Swapchain>,
47         image_index: u32,
48     ) -> Result<Arc<SwapchainImage>, OomError> {
49         Ok(Arc::new(SwapchainImage {
50             inner: Arc::new(Image::from_swapchain(handle, swapchain, image_index)),
51         }))
52     }
53 
54     /// Returns the swapchain this image belongs to.
swapchain(&self) -> &Arc<Swapchain>55     pub fn swapchain(&self) -> &Arc<Swapchain> {
56         match self.inner.memory() {
57             ImageMemory::Swapchain {
58                 swapchain,
59                 image_index: _,
60             } => swapchain,
61             _ => unreachable!(),
62         }
63     }
64 }
65 
66 unsafe impl DeviceOwned for SwapchainImage {
device(&self) -> &Arc<Device>67     fn device(&self) -> &Arc<Device> {
68         self.inner.device()
69     }
70 }
71 
72 unsafe impl ImageAccess for SwapchainImage {
inner(&self) -> ImageInner<'_>73     fn inner(&self) -> ImageInner<'_> {
74         ImageInner {
75             image: &self.inner,
76             first_layer: 0,
77             num_layers: self.inner.dimensions().array_layers(),
78             first_mipmap_level: 0,
79             num_mipmap_levels: 1,
80         }
81     }
82 
initial_layout_requirement(&self) -> ImageLayout83     fn initial_layout_requirement(&self) -> ImageLayout {
84         ImageLayout::PresentSrc
85     }
86 
final_layout_requirement(&self) -> ImageLayout87     fn final_layout_requirement(&self) -> ImageLayout {
88         ImageLayout::PresentSrc
89     }
90 
descriptor_layouts(&self) -> Option<ImageDescriptorLayouts>91     fn descriptor_layouts(&self) -> Option<ImageDescriptorLayouts> {
92         Some(ImageDescriptorLayouts {
93             storage_image: ImageLayout::General,
94             combined_image_sampler: ImageLayout::ShaderReadOnlyOptimal,
95             sampled_image: ImageLayout::ShaderReadOnlyOptimal,
96             input_attachment: ImageLayout::ShaderReadOnlyOptimal,
97         })
98     }
99 
layout_initialized(&self)100     unsafe fn layout_initialized(&self) {
101         match self.inner.memory() {
102             &ImageMemory::Swapchain {
103                 ref swapchain,
104                 image_index,
105             } => swapchain.image_layout_initialized(image_index),
106             _ => unreachable!(),
107         }
108     }
109 
is_layout_initialized(&self) -> bool110     fn is_layout_initialized(&self) -> bool {
111         match self.inner.memory() {
112             &ImageMemory::Swapchain {
113                 ref swapchain,
114                 image_index,
115             } => swapchain.is_image_layout_initialized(image_index),
116             _ => unreachable!(),
117         }
118     }
119 }
120 
121 unsafe impl<P> ImageContent<P> for SwapchainImage {
matches_format(&self) -> bool122     fn matches_format(&self) -> bool {
123         true // FIXME:
124     }
125 }
126 
127 impl PartialEq for SwapchainImage {
eq(&self, other: &Self) -> bool128     fn eq(&self, other: &Self) -> bool {
129         self.inner() == other.inner()
130     }
131 }
132 
133 impl Eq for SwapchainImage {}
134 
135 impl Hash for SwapchainImage {
hash<H: Hasher>(&self, state: &mut H)136     fn hash<H: Hasher>(&self, state: &mut H) {
137         self.inner().hash(state);
138     }
139 }
140