// Copyright (c) 2016 The vulkano developers // Licensed under the Apache License, Version 2.0 // or the MIT // license , // at your option. All files in the project carrying such // notice may not be copied, modified, or distributed except // according to those terms. use super::{ sys::{Image, ImageMemory}, traits::ImageContent, ImageAccess, ImageDescriptorLayouts, ImageInner, ImageLayout, }; use crate::{ device::{Device, DeviceOwned}, swapchain::Swapchain, OomError, }; use std::{ hash::{Hash, Hasher}, sync::Arc, }; /// An image that is part of a swapchain. /// /// Creating a `SwapchainImage` is automatically done when creating a swapchain. /// /// A swapchain image is special in the sense that it can only be used after being acquired by /// calling the `acquire` method on the swapchain. You have no way to know in advance which /// swapchain image is going to be acquired, so you should keep all of them alive. /// /// After a swapchain image has been acquired, you are free to perform all the usual operations /// on it. When you are done you can then *present* the image (by calling the corresponding /// method on the swapchain), which will have the effect of showing the content of the image to /// the screen. Once an image has been presented, it can no longer be used unless it is acquired /// again. #[derive(Debug)] pub struct SwapchainImage { inner: Arc, } impl SwapchainImage { pub(crate) unsafe fn from_handle( handle: ash::vk::Image, swapchain: Arc, image_index: u32, ) -> Result, OomError> { Ok(Arc::new(SwapchainImage { inner: Arc::new(Image::from_swapchain(handle, swapchain, image_index)), })) } /// Returns the swapchain this image belongs to. pub fn swapchain(&self) -> &Arc { match self.inner.memory() { ImageMemory::Swapchain { swapchain, image_index: _, } => swapchain, _ => unreachable!(), } } } unsafe impl DeviceOwned for SwapchainImage { fn device(&self) -> &Arc { self.inner.device() } } unsafe impl ImageAccess for SwapchainImage { fn inner(&self) -> ImageInner<'_> { ImageInner { image: &self.inner, first_layer: 0, num_layers: self.inner.dimensions().array_layers(), first_mipmap_level: 0, num_mipmap_levels: 1, } } fn initial_layout_requirement(&self) -> ImageLayout { ImageLayout::PresentSrc } fn final_layout_requirement(&self) -> ImageLayout { ImageLayout::PresentSrc } fn descriptor_layouts(&self) -> Option { Some(ImageDescriptorLayouts { storage_image: ImageLayout::General, combined_image_sampler: ImageLayout::ShaderReadOnlyOptimal, sampled_image: ImageLayout::ShaderReadOnlyOptimal, input_attachment: ImageLayout::ShaderReadOnlyOptimal, }) } unsafe fn layout_initialized(&self) { match self.inner.memory() { &ImageMemory::Swapchain { ref swapchain, image_index, } => swapchain.image_layout_initialized(image_index), _ => unreachable!(), } } fn is_layout_initialized(&self) -> bool { match self.inner.memory() { &ImageMemory::Swapchain { ref swapchain, image_index, } => swapchain.is_image_layout_initialized(image_index), _ => unreachable!(), } } } unsafe impl

ImageContent

for SwapchainImage { fn matches_format(&self) -> bool { true // FIXME: } } impl PartialEq for SwapchainImage { fn eq(&self, other: &Self) -> bool { self.inner() == other.inner() } } impl Eq for SwapchainImage {} impl Hash for SwapchainImage { fn hash(&self, state: &mut H) { self.inner().hash(state); } }