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 crate::{descriptor_set::layout::DescriptorType, macros::vulkan_enum}; 11 12 vulkan_enum! { 13 #[non_exhaustive] 14 15 /// In-memory layout of the pixel data of an image. 16 /// 17 /// The pixel data of a Vulkan image is arranged in a particular way, which is called its 18 /// *layout*. Each image subresource (mipmap level and array layer) in an image can have a 19 /// different layout, but usually the whole image has its data in the same layout. Layouts are 20 /// abstract in the sense that the user does not know the specific details of each layout; the 21 /// device driver is free to implement each layout in the way it sees fit. 22 /// 23 /// The layout of a newly created image is either `Undefined` or `Preinitialized`. Every 24 /// operation that can be performed on an image is only possible with specific layouts, so 25 /// before the operation is performed, the user must perform a *layout transition* on the 26 /// image. This rearranges the pixel data from one layout into another. Layout transitions are 27 /// performed as part of pipeline barriers in a command buffer. 28 /// 29 /// The `General` layout is compatible with any operation, so layout transitions are never 30 /// needed. However, the other layouts, while more restricted, are usually better optimised for 31 /// a particular type of operation than `General`, so they are usually preferred. 32 /// 33 /// Vulkan does not keep track of layouts itself, so it is the responsibility of the user to 34 /// keep track of this information. When performing a layout transition, the previous layout 35 /// must be specified as well. Some operations allow for different layouts, but require the 36 /// user to specify which one. Vulkano helps with this by providing sensible defaults, 37 /// automatically tracking the layout of each image when creating a command buffer, and adding 38 /// layout transitions where needed. 39 ImageLayout = ImageLayout(i32); 40 41 /// The layout of the data is unknown, and the image is treated as containing no valid data. 42 /// Transitioning from `Undefined` will discard any existing pixel data. 43 Undefined = UNDEFINED, 44 45 /// A general-purpose layout that can be used for any operation. Some operations may only allow 46 /// `General`, such as storage images, but many have a more specific layout that is better 47 /// optimized for that purpose. 48 General = GENERAL, 49 50 /// For a color image used as a color or resolve attachment in a framebuffer. Images that are 51 /// transitioned into this layout must have the `color_attachment` usage enabled. 52 ColorAttachmentOptimal = COLOR_ATTACHMENT_OPTIMAL, 53 54 /// For a depth/stencil image used as a depth/stencil attachment in a framebuffer. 55 DepthStencilAttachmentOptimal = DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 56 57 /// For a depth/stencil image used as a read-only depth/stencil attachment in a framebuffer, or 58 /// as a (combined) sampled image or input attachment in a shader. 59 DepthStencilReadOnlyOptimal = DEPTH_STENCIL_READ_ONLY_OPTIMAL, 60 61 /// For a color image used as a (combined) sampled image or input attachment in a shader. 62 /// Images that are transitioned into this layout must have the `sampled` or `input_attachment` 63 /// usages enabled. 64 ShaderReadOnlyOptimal = SHADER_READ_ONLY_OPTIMAL, 65 66 /// For operations that transfer data from an image (copy, blit). 67 TransferSrcOptimal = TRANSFER_SRC_OPTIMAL, 68 69 /// For operations that transfer data to an image (copy, blit, clear). 70 TransferDstOptimal = TRANSFER_DST_OPTIMAL, 71 72 /// When creating an image, this specifies that the initial data is going to be directly 73 /// written to from the CPU. Unlike `Undefined`, the image is assumed to contain valid data when 74 /// transitioning from this layout. However, this only works right when the image has linear 75 /// tiling, optimal tiling gives undefined results. 76 Preinitialized = PREINITIALIZED, 77 78 /// A combination of `DepthStencilReadOnlyOptimal` for the depth aspect of the image, 79 /// and `DepthStencilAttachmentOptimal` for the stencil aspect of the image. 80 DepthReadOnlyStencilAttachmentOptimal = DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL { 81 api_version: V1_1, 82 device_extensions: [khr_maintenance2], 83 }, 84 85 /// A combination of `DepthStencilAttachmentOptimal` for the depth aspect of the image, 86 /// and `DepthStencilReadOnlyOptimal` for the stencil aspect of the image. 87 DepthAttachmentStencilReadOnlyOptimal = DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL { 88 api_version: V1_1, 89 device_extensions: [khr_maintenance2], 90 }, 91 92 /* TODO: enable 93 // TODO: document 94 DepthAttachmentOptimal = DEPTH_ATTACHMENT_OPTIMAL { 95 api_version: V1_2, 96 device_extensions: [khr_separate_depth_stencil_layouts], 97 },*/ 98 99 /* TODO: enable 100 // TODO: document 101 DepthReadOnlyOptimal = DEPTH_READ_ONLY_OPTIMAL { 102 api_version: V1_2, 103 device_extensions: [khr_separate_depth_stencil_layouts], 104 },*/ 105 106 /* TODO: enable 107 // TODO: document 108 StencilAttachmentOptimal = STENCIL_ATTACHMENT_OPTIMAL { 109 api_version: V1_2, 110 device_extensions: [khr_separate_depth_stencil_layouts], 111 },*/ 112 113 /* TODO: enable 114 // TODO: document 115 StencilReadOnlyOptimal = STENCIL_READ_ONLY_OPTIMAL { 116 api_version: V1_2, 117 device_extensions: [khr_separate_depth_stencil_layouts], 118 },*/ 119 120 /* TODO: enable 121 // TODO: document 122 ReadOnlyOptimal = READ_ONLY_OPTIMAL { 123 api_version: V1_3, 124 device_extensions: [khr_synchronization2], 125 },*/ 126 127 /* TODO: enable 128 // TODO: document 129 AttachmentOptimal = ATTACHMENT_OPTIMAL { 130 api_version: V1_3, 131 device_extensions: [khr_synchronization2], 132 },*/ 133 134 /// The layout of images that are held in a swapchain. Images are in this layout when they are 135 /// acquired from the swapchain, and must be transitioned back into this layout before 136 /// presenting them. 137 PresentSrc = PRESENT_SRC_KHR { 138 device_extensions: [khr_swapchain], 139 }, 140 141 /* TODO: enable 142 // TODO: document 143 VideoDecodeDst = VIDEO_DECODE_DST_KHR { 144 device_extensions: [khr_video_decode_queue], 145 },*/ 146 147 /* TODO: enable 148 // TODO: document 149 VideoDecodeSrc = VIDEO_DECODE_SRC_KHR { 150 device_extensions: [khr_video_decode_queue], 151 },*/ 152 153 /* TODO: enable 154 // TODO: document 155 VideoDecodeDpb = VIDEO_DECODE_DPB_KHR { 156 device_extensions: [khr_video_decode_queue], 157 },*/ 158 159 /* TODO: enable 160 // TODO: document 161 SharedPresent = SHARED_PRESENT_KHR { 162 device_extensions: [khr_shared_presentable_image], 163 },*/ 164 165 /* TODO: enable 166 // TODO: document 167 FragmentDensityMapOptimal = FRAGMENT_DENSITY_MAP_OPTIMAL_EXT { 168 device_extensions: [ext_fragment_density_map], 169 },*/ 170 171 /* TODO: enable 172 // TODO: document 173 FragmentShadingRateAttachmentOptimal = FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR { 174 device_extensions: [khr_fragment_shading_rate], 175 },*/ 176 177 /* TODO: enable 178 // TODO: document 179 VideoEncodeDst = VIDEO_ENCODE_DST_KHR { 180 device_extensions: [khr_video_encode_queue], 181 },*/ 182 183 /* TODO: enable 184 // TODO: document 185 VideoEncodeSrc = VIDEO_ENCODE_SRC_KHR { 186 device_extensions: [khr_video_encode_queue], 187 },*/ 188 189 /* TODO: enable 190 // TODO: document 191 VideoEncodeDpb = VIDEO_ENCODE_DPB_KHR { 192 device_extensions: [khr_video_encode_queue], 193 },*/ 194 195 /* TODO: enable 196 // TODO: document 197 AttachmentFeedbackLoopOptimal = ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT { 198 device_extensions: [ext_attachment_feedback_loop_layout], 199 },*/ 200 } 201 202 impl Default for ImageLayout { 203 #[inline] default() -> Self204 fn default() -> Self { 205 ImageLayout::Undefined 206 } 207 } 208 209 /// The set of layouts to use for an image when used in descriptor of various kinds. 210 #[derive(Clone, Copy, Debug, PartialEq, Eq)] 211 pub struct ImageDescriptorLayouts { 212 /// The image layout to use in a descriptor as a storage image. 213 pub storage_image: ImageLayout, 214 /// The image layout to use in a descriptor as a combined image sampler. 215 pub combined_image_sampler: ImageLayout, 216 /// The image layout to use in a descriptor as a sampled image. 217 pub sampled_image: ImageLayout, 218 /// The image layout to use in a descriptor as an input attachment. 219 pub input_attachment: ImageLayout, 220 } 221 222 impl ImageDescriptorLayouts { 223 /// Returns the layout for the given descriptor type. Panics if `descriptor_type` is not an 224 /// image descriptor type. 225 #[inline] layout_for(&self, descriptor_type: DescriptorType) -> ImageLayout226 pub fn layout_for(&self, descriptor_type: DescriptorType) -> ImageLayout { 227 match descriptor_type { 228 DescriptorType::CombinedImageSampler => self.combined_image_sampler, 229 DescriptorType::SampledImage => self.sampled_image, 230 DescriptorType::StorageImage => self.storage_image, 231 DescriptorType::InputAttachment => self.input_attachment, 232 _ => panic!("{:?} is not an image descriptor type", descriptor_type), 233 } 234 } 235 } 236