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 a buffer is going to be used. This is **not** just an optimization. 13 /// 14 /// If you try to use a buffer in a way that you didn't declare, a panic will happen. 15 /// 16 /// Some methods are provided to build `BufferUsage` structs for some common situations. However 17 /// there is no restriction in the combination of BufferUsages that can be enabled. 18 #[derive(Debug, Copy, Clone, PartialEq, Eq)] 19 pub struct BufferUsage { 20 pub transfer_source: bool, 21 pub transfer_destination: bool, 22 pub uniform_texel_buffer: bool, 23 pub storage_texel_buffer: bool, 24 pub uniform_buffer: bool, 25 pub storage_buffer: bool, 26 pub index_buffer: bool, 27 pub vertex_buffer: bool, 28 pub indirect_buffer: bool, 29 /// Requires the `buffer_device_address` feature. If that feature is not enabled, this will 30 /// be silently ignored. 31 pub device_address: bool, 32 } 33 34 impl BufferUsage { 35 /// Builds a `BufferUsage` with all values set to false. 36 #[inline] none() -> BufferUsage37 pub const fn none() -> BufferUsage { 38 BufferUsage { 39 transfer_source: false, 40 transfer_destination: false, 41 uniform_texel_buffer: false, 42 storage_texel_buffer: false, 43 uniform_buffer: false, 44 storage_buffer: false, 45 index_buffer: false, 46 vertex_buffer: false, 47 indirect_buffer: false, 48 device_address: false, 49 } 50 } 51 52 /// Builds a `BufferUsage` with all values set to true. Can be used for quick prototyping. 53 #[inline] all() -> BufferUsage54 pub const fn all() -> BufferUsage { 55 BufferUsage { 56 transfer_source: true, 57 transfer_destination: true, 58 uniform_texel_buffer: true, 59 storage_texel_buffer: true, 60 uniform_buffer: true, 61 storage_buffer: true, 62 index_buffer: true, 63 vertex_buffer: true, 64 indirect_buffer: true, 65 device_address: true, 66 } 67 } 68 69 /// Builds a `BufferUsage` with `transfer_source` set to true and the rest to false. 70 #[inline] transfer_source() -> BufferUsage71 pub const fn transfer_source() -> BufferUsage { 72 BufferUsage { 73 transfer_source: true, 74 ..BufferUsage::none() 75 } 76 } 77 78 /// Builds a `BufferUsage` with `transfer_destination` set to true and the rest to false. 79 #[inline] transfer_destination() -> BufferUsage80 pub const fn transfer_destination() -> BufferUsage { 81 BufferUsage { 82 transfer_destination: true, 83 ..BufferUsage::none() 84 } 85 } 86 87 /// Builds a `BufferUsage` with `vertex_buffer` set to true and the rest to false. 88 #[inline] vertex_buffer() -> BufferUsage89 pub const fn vertex_buffer() -> BufferUsage { 90 BufferUsage { 91 vertex_buffer: true, 92 ..BufferUsage::none() 93 } 94 } 95 96 /// Builds a `BufferUsage` with `vertex_buffer` and `transfer_destination` set to true and the rest 97 /// to false. 98 #[inline] vertex_buffer_transfer_destination() -> BufferUsage99 pub const fn vertex_buffer_transfer_destination() -> BufferUsage { 100 BufferUsage { 101 vertex_buffer: true, 102 transfer_destination: true, 103 ..BufferUsage::none() 104 } 105 } 106 107 /// Builds a `BufferUsage` with `index_buffer` set to true and the rest to false. 108 #[inline] index_buffer() -> BufferUsage109 pub const fn index_buffer() -> BufferUsage { 110 BufferUsage { 111 index_buffer: true, 112 ..BufferUsage::none() 113 } 114 } 115 116 /// Builds a `BufferUsage` with `index_buffer` and `transfer_destination` set to true and the rest to false. 117 #[inline] index_buffer_transfer_destination() -> BufferUsage118 pub const fn index_buffer_transfer_destination() -> BufferUsage { 119 BufferUsage { 120 index_buffer: true, 121 transfer_destination: true, 122 ..BufferUsage::none() 123 } 124 } 125 126 /// Builds a `BufferUsage` with `uniform_buffer` set to true and the rest to false. 127 #[inline] uniform_buffer() -> BufferUsage128 pub const fn uniform_buffer() -> BufferUsage { 129 BufferUsage { 130 uniform_buffer: true, 131 ..BufferUsage::none() 132 } 133 } 134 135 /// Builds a `BufferUsage` with `uniform_buffer` and `transfer_destination` set to true and the rest 136 /// to false. 137 #[inline] uniform_buffer_transfer_destination() -> BufferUsage138 pub const fn uniform_buffer_transfer_destination() -> BufferUsage { 139 BufferUsage { 140 uniform_buffer: true, 141 transfer_destination: true, 142 ..BufferUsage::none() 143 } 144 } 145 146 /// Builds a `BufferUsage` with `indirect_buffer` set to true and the rest to false. 147 #[inline] indirect_buffer() -> BufferUsage148 pub const fn indirect_buffer() -> BufferUsage { 149 BufferUsage { 150 indirect_buffer: true, 151 ..BufferUsage::none() 152 } 153 } 154 155 /// Builds a `BufferUsage` with `indirect_buffer` and `transfer_destination` set to true and the rest 156 /// to false. 157 #[inline] indirect_buffer_transfer_destination() -> BufferUsage158 pub const fn indirect_buffer_transfer_destination() -> BufferUsage { 159 BufferUsage { 160 indirect_buffer: true, 161 transfer_destination: true, 162 ..BufferUsage::none() 163 } 164 } 165 166 /// Builds a `BufferUsage` with `device_address` set to true and the rest to false. 167 #[inline] device_address() -> BufferUsage168 pub const fn device_address() -> BufferUsage { 169 BufferUsage { 170 device_address: true, 171 ..BufferUsage::none() 172 } 173 } 174 } 175 176 impl From<BufferUsage> for ash::vk::BufferUsageFlags { from(val: BufferUsage) -> Self177 fn from(val: BufferUsage) -> Self { 178 let mut result = ash::vk::BufferUsageFlags::empty(); 179 if val.transfer_source { 180 result |= ash::vk::BufferUsageFlags::TRANSFER_SRC; 181 } 182 if val.transfer_destination { 183 result |= ash::vk::BufferUsageFlags::TRANSFER_DST; 184 } 185 if val.uniform_texel_buffer { 186 result |= ash::vk::BufferUsageFlags::UNIFORM_TEXEL_BUFFER; 187 } 188 if val.storage_texel_buffer { 189 result |= ash::vk::BufferUsageFlags::STORAGE_TEXEL_BUFFER; 190 } 191 if val.uniform_buffer { 192 result |= ash::vk::BufferUsageFlags::UNIFORM_BUFFER; 193 } 194 if val.storage_buffer { 195 result |= ash::vk::BufferUsageFlags::STORAGE_BUFFER; 196 } 197 if val.index_buffer { 198 result |= ash::vk::BufferUsageFlags::INDEX_BUFFER; 199 } 200 if val.vertex_buffer { 201 result |= ash::vk::BufferUsageFlags::VERTEX_BUFFER; 202 } 203 if val.indirect_buffer { 204 result |= ash::vk::BufferUsageFlags::INDIRECT_BUFFER; 205 } 206 if val.device_address { 207 result |= ash::vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS; 208 } 209 result 210 } 211 } 212 213 impl BitOr for BufferUsage { 214 type Output = Self; 215 216 #[inline] bitor(self, rhs: Self) -> Self217 fn bitor(self, rhs: Self) -> Self { 218 BufferUsage { 219 transfer_source: self.transfer_source || rhs.transfer_source, 220 transfer_destination: self.transfer_destination || rhs.transfer_destination, 221 uniform_texel_buffer: self.uniform_texel_buffer || rhs.uniform_texel_buffer, 222 storage_texel_buffer: self.storage_texel_buffer || rhs.storage_texel_buffer, 223 uniform_buffer: self.uniform_buffer || rhs.uniform_buffer, 224 storage_buffer: self.storage_buffer || rhs.storage_buffer, 225 index_buffer: self.index_buffer || rhs.index_buffer, 226 vertex_buffer: self.vertex_buffer || rhs.vertex_buffer, 227 indirect_buffer: self.indirect_buffer || rhs.indirect_buffer, 228 device_address: self.device_address || rhs.device_address, 229 } 230 } 231 } 232