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