| // Copyright (c) 2016 The vulkano developers |
| // Licensed under the Apache License, Version 2.0 |
| // <LICENSE-APACHE or |
| // https://www.apache.org/licenses/LICENSE-2.0> or the MIT |
| // license <LICENSE-MIT or https://opensource.org/licenses/MIT>, |
| // at your option. All files in the project carrying such |
| // notice may not be copied, modified, or distributed except |
| // according to those terms. |
| |
| use crate::{descriptor_set::layout::DescriptorType, macros::vulkan_enum}; |
| |
| vulkan_enum! { |
| #[non_exhaustive] |
| |
| /// In-memory layout of the pixel data of an image. |
| /// |
| /// The pixel data of a Vulkan image is arranged in a particular way, which is called its |
| /// *layout*. Each image subresource (mipmap level and array layer) in an image can have a |
| /// different layout, but usually the whole image has its data in the same layout. Layouts are |
| /// abstract in the sense that the user does not know the specific details of each layout; the |
| /// device driver is free to implement each layout in the way it sees fit. |
| /// |
| /// The layout of a newly created image is either `Undefined` or `Preinitialized`. Every |
| /// operation that can be performed on an image is only possible with specific layouts, so |
| /// before the operation is performed, the user must perform a *layout transition* on the |
| /// image. This rearranges the pixel data from one layout into another. Layout transitions are |
| /// performed as part of pipeline barriers in a command buffer. |
| /// |
| /// The `General` layout is compatible with any operation, so layout transitions are never |
| /// needed. However, the other layouts, while more restricted, are usually better optimised for |
| /// a particular type of operation than `General`, so they are usually preferred. |
| /// |
| /// Vulkan does not keep track of layouts itself, so it is the responsibility of the user to |
| /// keep track of this information. When performing a layout transition, the previous layout |
| /// must be specified as well. Some operations allow for different layouts, but require the |
| /// user to specify which one. Vulkano helps with this by providing sensible defaults, |
| /// automatically tracking the layout of each image when creating a command buffer, and adding |
| /// layout transitions where needed. |
| ImageLayout = ImageLayout(i32); |
| |
| /// The layout of the data is unknown, and the image is treated as containing no valid data. |
| /// Transitioning from `Undefined` will discard any existing pixel data. |
| Undefined = UNDEFINED, |
| |
| /// A general-purpose layout that can be used for any operation. Some operations may only allow |
| /// `General`, such as storage images, but many have a more specific layout that is better |
| /// optimized for that purpose. |
| General = GENERAL, |
| |
| /// For a color image used as a color or resolve attachment in a framebuffer. Images that are |
| /// transitioned into this layout must have the `color_attachment` usage enabled. |
| ColorAttachmentOptimal = COLOR_ATTACHMENT_OPTIMAL, |
| |
| /// For a depth/stencil image used as a depth/stencil attachment in a framebuffer. |
| DepthStencilAttachmentOptimal = DEPTH_STENCIL_ATTACHMENT_OPTIMAL, |
| |
| /// For a depth/stencil image used as a read-only depth/stencil attachment in a framebuffer, or |
| /// as a (combined) sampled image or input attachment in a shader. |
| DepthStencilReadOnlyOptimal = DEPTH_STENCIL_READ_ONLY_OPTIMAL, |
| |
| /// For a color image used as a (combined) sampled image or input attachment in a shader. |
| /// Images that are transitioned into this layout must have the `sampled` or `input_attachment` |
| /// usages enabled. |
| ShaderReadOnlyOptimal = SHADER_READ_ONLY_OPTIMAL, |
| |
| /// For operations that transfer data from an image (copy, blit). |
| TransferSrcOptimal = TRANSFER_SRC_OPTIMAL, |
| |
| /// For operations that transfer data to an image (copy, blit, clear). |
| TransferDstOptimal = TRANSFER_DST_OPTIMAL, |
| |
| /// When creating an image, this specifies that the initial data is going to be directly |
| /// written to from the CPU. Unlike `Undefined`, the image is assumed to contain valid data when |
| /// transitioning from this layout. However, this only works right when the image has linear |
| /// tiling, optimal tiling gives undefined results. |
| Preinitialized = PREINITIALIZED, |
| |
| /// A combination of `DepthStencilReadOnlyOptimal` for the depth aspect of the image, |
| /// and `DepthStencilAttachmentOptimal` for the stencil aspect of the image. |
| DepthReadOnlyStencilAttachmentOptimal = DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL { |
| api_version: V1_1, |
| device_extensions: [khr_maintenance2], |
| }, |
| |
| /// A combination of `DepthStencilAttachmentOptimal` for the depth aspect of the image, |
| /// and `DepthStencilReadOnlyOptimal` for the stencil aspect of the image. |
| DepthAttachmentStencilReadOnlyOptimal = DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL { |
| api_version: V1_1, |
| device_extensions: [khr_maintenance2], |
| }, |
| |
| /* TODO: enable |
| // TODO: document |
| DepthAttachmentOptimal = DEPTH_ATTACHMENT_OPTIMAL { |
| api_version: V1_2, |
| device_extensions: [khr_separate_depth_stencil_layouts], |
| },*/ |
| |
| /* TODO: enable |
| // TODO: document |
| DepthReadOnlyOptimal = DEPTH_READ_ONLY_OPTIMAL { |
| api_version: V1_2, |
| device_extensions: [khr_separate_depth_stencil_layouts], |
| },*/ |
| |
| /* TODO: enable |
| // TODO: document |
| StencilAttachmentOptimal = STENCIL_ATTACHMENT_OPTIMAL { |
| api_version: V1_2, |
| device_extensions: [khr_separate_depth_stencil_layouts], |
| },*/ |
| |
| /* TODO: enable |
| // TODO: document |
| StencilReadOnlyOptimal = STENCIL_READ_ONLY_OPTIMAL { |
| api_version: V1_2, |
| device_extensions: [khr_separate_depth_stencil_layouts], |
| },*/ |
| |
| /* TODO: enable |
| // TODO: document |
| ReadOnlyOptimal = READ_ONLY_OPTIMAL { |
| api_version: V1_3, |
| device_extensions: [khr_synchronization2], |
| },*/ |
| |
| /* TODO: enable |
| // TODO: document |
| AttachmentOptimal = ATTACHMENT_OPTIMAL { |
| api_version: V1_3, |
| device_extensions: [khr_synchronization2], |
| },*/ |
| |
| /// The layout of images that are held in a swapchain. Images are in this layout when they are |
| /// acquired from the swapchain, and must be transitioned back into this layout before |
| /// presenting them. |
| PresentSrc = PRESENT_SRC_KHR { |
| device_extensions: [khr_swapchain], |
| }, |
| |
| /* TODO: enable |
| // TODO: document |
| VideoDecodeDst = VIDEO_DECODE_DST_KHR { |
| device_extensions: [khr_video_decode_queue], |
| },*/ |
| |
| /* TODO: enable |
| // TODO: document |
| VideoDecodeSrc = VIDEO_DECODE_SRC_KHR { |
| device_extensions: [khr_video_decode_queue], |
| },*/ |
| |
| /* TODO: enable |
| // TODO: document |
| VideoDecodeDpb = VIDEO_DECODE_DPB_KHR { |
| device_extensions: [khr_video_decode_queue], |
| },*/ |
| |
| /* TODO: enable |
| // TODO: document |
| SharedPresent = SHARED_PRESENT_KHR { |
| device_extensions: [khr_shared_presentable_image], |
| },*/ |
| |
| /* TODO: enable |
| // TODO: document |
| FragmentDensityMapOptimal = FRAGMENT_DENSITY_MAP_OPTIMAL_EXT { |
| device_extensions: [ext_fragment_density_map], |
| },*/ |
| |
| /* TODO: enable |
| // TODO: document |
| FragmentShadingRateAttachmentOptimal = FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR { |
| device_extensions: [khr_fragment_shading_rate], |
| },*/ |
| |
| /* TODO: enable |
| // TODO: document |
| VideoEncodeDst = VIDEO_ENCODE_DST_KHR { |
| device_extensions: [khr_video_encode_queue], |
| },*/ |
| |
| /* TODO: enable |
| // TODO: document |
| VideoEncodeSrc = VIDEO_ENCODE_SRC_KHR { |
| device_extensions: [khr_video_encode_queue], |
| },*/ |
| |
| /* TODO: enable |
| // TODO: document |
| VideoEncodeDpb = VIDEO_ENCODE_DPB_KHR { |
| device_extensions: [khr_video_encode_queue], |
| },*/ |
| |
| /* TODO: enable |
| // TODO: document |
| AttachmentFeedbackLoopOptimal = ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT { |
| device_extensions: [ext_attachment_feedback_loop_layout], |
| },*/ |
| } |
| |
| impl Default for ImageLayout { |
| #[inline] |
| fn default() -> Self { |
| ImageLayout::Undefined |
| } |
| } |
| |
| /// The set of layouts to use for an image when used in descriptor of various kinds. |
| #[derive(Clone, Copy, Debug, PartialEq, Eq)] |
| pub struct ImageDescriptorLayouts { |
| /// The image layout to use in a descriptor as a storage image. |
| pub storage_image: ImageLayout, |
| /// The image layout to use in a descriptor as a combined image sampler. |
| pub combined_image_sampler: ImageLayout, |
| /// The image layout to use in a descriptor as a sampled image. |
| pub sampled_image: ImageLayout, |
| /// The image layout to use in a descriptor as an input attachment. |
| pub input_attachment: ImageLayout, |
| } |
| |
| impl ImageDescriptorLayouts { |
| /// Returns the layout for the given descriptor type. Panics if `descriptor_type` is not an |
| /// image descriptor type. |
| #[inline] |
| pub fn layout_for(&self, descriptor_type: DescriptorType) -> ImageLayout { |
| match descriptor_type { |
| DescriptorType::CombinedImageSampler => self.combined_image_sampler, |
| DescriptorType::SampledImage => self.sampled_image, |
| DescriptorType::StorageImage => self.storage_image, |
| DescriptorType::InputAttachment => self.input_attachment, |
| _ => panic!("{:?} is not an image descriptor type", descriptor_type), |
| } |
| } |
| } |