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