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