• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 std::ops::BitOr;
11 
12 /// Describes how an image is going to be used. This is **not** just an optimization.
13 ///
14 /// If you try to use an image in a way that you didn't declare, a panic will happen.
15 ///
16 /// If `transient_attachment` is true, then only `color_attachment`, `depth_stencil_attachment`
17 /// and `input_attachment` can be true as well. The rest must be false or an error will be returned
18 /// when creating the image.
19 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
20 pub struct ImageUsage {
21     /// Can be used as a source for transfers. Includes blits.
22     pub transfer_source: bool,
23 
24     /// Can be used as a destination for transfers. Includes blits.
25     pub transfer_destination: bool,
26 
27     /// Can be sampled from a shader.
28     pub sampled: bool,
29 
30     /// Can be used as an image storage in a shader.
31     pub storage: bool,
32 
33     /// Can be attached as a color attachment to a framebuffer.
34     pub color_attachment: bool,
35 
36     /// Can be attached as a depth, stencil or depth-stencil attachment to a framebuffer.
37     pub depth_stencil_attachment: bool,
38 
39     /// Indicates that this image will only ever be used as a temporary framebuffer attachment.
40     /// As soon as you leave a render pass, the content of transient images becomes undefined.
41     ///
42     /// This is a hint to the Vulkan implementation that it may not need allocate any memory for
43     /// this image if the image can live entirely in some cache.
44     pub transient_attachment: bool,
45 
46     /// Can be used as an input attachment. In other words, you can draw to it in a subpass then
47     /// read from it in a following pass.
48     pub input_attachment: bool,
49 }
50 
51 impl ImageUsage {
52     /// Builds a `ImageUsage` with all values set to true. Note that using the returned value will
53     /// produce an error because of `transient_attachment` being true.
54     #[inline]
all() -> ImageUsage55     pub fn all() -> ImageUsage {
56         ImageUsage {
57             transfer_source: true,
58             transfer_destination: true,
59             sampled: true,
60             storage: true,
61             color_attachment: true,
62             depth_stencil_attachment: true,
63             transient_attachment: true,
64             input_attachment: true,
65         }
66     }
67 
68     /// Builds a `ImageUsage` with all values set to false. Useful as a default value.
69     ///
70     /// # Example
71     ///
72     /// ```rust
73     /// use vulkano::image::ImageUsage as ImageUsage;
74     ///
75     /// let _usage = ImageUsage {
76     ///     transfer_destination: true,
77     ///     sampled: true,
78     ///     .. ImageUsage::none()
79     /// };
80     /// ```
81     #[inline]
none() -> ImageUsage82     pub fn none() -> ImageUsage {
83         ImageUsage {
84             transfer_source: false,
85             transfer_destination: false,
86             sampled: false,
87             storage: false,
88             color_attachment: false,
89             depth_stencil_attachment: false,
90             transient_attachment: false,
91             input_attachment: false,
92         }
93     }
94 
95     /// Builds a ImageUsage with color_attachment set to true and the rest to false.
96     #[inline]
color_attachment() -> ImageUsage97     pub fn color_attachment() -> ImageUsage {
98         ImageUsage {
99             transfer_source: false,
100             transfer_destination: false,
101             sampled: false,
102             storage: false,
103             color_attachment: true,
104             depth_stencil_attachment: false,
105             transient_attachment: false,
106             input_attachment: false,
107         }
108     }
109 
110     /// Builds a ImageUsage with depth_stencil_attachment set to true and the rest to false.
111     #[inline]
depth_stencil_attachment() -> ImageUsage112     pub fn depth_stencil_attachment() -> ImageUsage {
113         ImageUsage {
114             transfer_source: false,
115             transfer_destination: false,
116             sampled: false,
117             storage: false,
118             color_attachment: false,
119             depth_stencil_attachment: true,
120             transient_attachment: false,
121             input_attachment: false,
122         }
123     }
124 
125     /// Builds a ImageUsage with color_attachment and transient_attachment set to true and the rest to false.
126     #[inline]
transient_color_attachment() -> ImageUsage127     pub fn transient_color_attachment() -> ImageUsage {
128         ImageUsage {
129             transfer_source: false,
130             transfer_destination: false,
131             sampled: false,
132             storage: false,
133             color_attachment: true,
134             depth_stencil_attachment: false,
135             transient_attachment: true,
136             input_attachment: false,
137         }
138     }
139 
140     /// Builds a ImageUsage with depth_stencil_attachment and transient_attachment set to true and the rest to false.
141     #[inline]
transient_depth_stencil_attachment() -> ImageUsage142     pub fn transient_depth_stencil_attachment() -> ImageUsage {
143         ImageUsage {
144             transfer_source: false,
145             transfer_destination: false,
146             sampled: false,
147             storage: false,
148             color_attachment: false,
149             depth_stencil_attachment: true,
150             transient_attachment: true,
151             input_attachment: false,
152         }
153     }
154 }
155 
156 impl From<ImageUsage> for ash::vk::ImageUsageFlags {
157     #[inline]
from(val: ImageUsage) -> Self158     fn from(val: ImageUsage) -> Self {
159         let mut result = ash::vk::ImageUsageFlags::empty();
160         if val.transfer_source {
161             result |= ash::vk::ImageUsageFlags::TRANSFER_SRC;
162         }
163         if val.transfer_destination {
164             result |= ash::vk::ImageUsageFlags::TRANSFER_DST;
165         }
166         if val.sampled {
167             result |= ash::vk::ImageUsageFlags::SAMPLED;
168         }
169         if val.storage {
170             result |= ash::vk::ImageUsageFlags::STORAGE;
171         }
172         if val.color_attachment {
173             result |= ash::vk::ImageUsageFlags::COLOR_ATTACHMENT;
174         }
175         if val.depth_stencil_attachment {
176             result |= ash::vk::ImageUsageFlags::DEPTH_STENCIL_ATTACHMENT;
177         }
178         if val.transient_attachment {
179             result |= ash::vk::ImageUsageFlags::TRANSIENT_ATTACHMENT;
180         }
181         if val.input_attachment {
182             result |= ash::vk::ImageUsageFlags::INPUT_ATTACHMENT;
183         }
184         result
185     }
186 }
187 
188 impl From<ash::vk::ImageUsageFlags> for ImageUsage {
189     #[inline]
from(val: ash::vk::ImageUsageFlags) -> ImageUsage190     fn from(val: ash::vk::ImageUsageFlags) -> ImageUsage {
191         ImageUsage {
192             transfer_source: !(val & ash::vk::ImageUsageFlags::TRANSFER_SRC).is_empty(),
193             transfer_destination: !(val & ash::vk::ImageUsageFlags::TRANSFER_DST).is_empty(),
194             sampled: !(val & ash::vk::ImageUsageFlags::SAMPLED).is_empty(),
195             storage: !(val & ash::vk::ImageUsageFlags::STORAGE).is_empty(),
196             color_attachment: !(val & ash::vk::ImageUsageFlags::COLOR_ATTACHMENT).is_empty(),
197             depth_stencil_attachment: !(val & ash::vk::ImageUsageFlags::DEPTH_STENCIL_ATTACHMENT)
198                 .is_empty(),
199             transient_attachment: !(val & ash::vk::ImageUsageFlags::TRANSIENT_ATTACHMENT)
200                 .is_empty(),
201             input_attachment: !(val & ash::vk::ImageUsageFlags::INPUT_ATTACHMENT).is_empty(),
202         }
203     }
204 }
205 
206 impl BitOr for ImageUsage {
207     type Output = Self;
208 
209     #[inline]
bitor(self, rhs: Self) -> Self210     fn bitor(self, rhs: Self) -> Self {
211         ImageUsage {
212             transfer_source: self.transfer_source || rhs.transfer_source,
213             transfer_destination: self.transfer_destination || rhs.transfer_destination,
214             sampled: self.sampled || rhs.sampled,
215             storage: self.storage || rhs.storage,
216             color_attachment: self.color_attachment || rhs.color_attachment,
217             depth_stencil_attachment: self.depth_stencil_attachment || rhs.depth_stencil_attachment,
218             transient_attachment: self.transient_attachment || rhs.transient_attachment,
219             input_attachment: self.input_attachment || rhs.input_attachment,
220         }
221     }
222 }
223