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