// Copyright (c) 2016 The vulkano developers // Licensed under the Apache License, Version 2.0 // or the MIT // license , // at your option. All files in the project carrying such // notice may not be copied, modified, or distributed except // according to those terms. use std::ops::BitOr; /// Describes how a buffer is going to be used. This is **not** just an optimization. /// /// If you try to use a buffer in a way that you didn't declare, a panic will happen. /// /// Some methods are provided to build `BufferUsage` structs for some common situations. However /// there is no restriction in the combination of BufferUsages that can be enabled. #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub struct BufferUsage { pub transfer_source: bool, pub transfer_destination: bool, pub uniform_texel_buffer: bool, pub storage_texel_buffer: bool, pub uniform_buffer: bool, pub storage_buffer: bool, pub index_buffer: bool, pub vertex_buffer: bool, pub indirect_buffer: bool, /// Requires the `buffer_device_address` feature. If that feature is not enabled, this will /// be silently ignored. pub device_address: bool, } impl BufferUsage { /// Builds a `BufferUsage` with all values set to false. #[inline] pub const fn none() -> BufferUsage { BufferUsage { transfer_source: false, transfer_destination: false, uniform_texel_buffer: false, storage_texel_buffer: false, uniform_buffer: false, storage_buffer: false, index_buffer: false, vertex_buffer: false, indirect_buffer: false, device_address: false, } } /// Builds a `BufferUsage` with all values set to true. Can be used for quick prototyping. #[inline] pub const fn all() -> BufferUsage { BufferUsage { transfer_source: true, transfer_destination: true, uniform_texel_buffer: true, storage_texel_buffer: true, uniform_buffer: true, storage_buffer: true, index_buffer: true, vertex_buffer: true, indirect_buffer: true, device_address: true, } } /// Builds a `BufferUsage` with `transfer_source` set to true and the rest to false. #[inline] pub const fn transfer_source() -> BufferUsage { BufferUsage { transfer_source: true, ..BufferUsage::none() } } /// Builds a `BufferUsage` with `transfer_destination` set to true and the rest to false. #[inline] pub const fn transfer_destination() -> BufferUsage { BufferUsage { transfer_destination: true, ..BufferUsage::none() } } /// Builds a `BufferUsage` with `vertex_buffer` set to true and the rest to false. #[inline] pub const fn vertex_buffer() -> BufferUsage { BufferUsage { vertex_buffer: true, ..BufferUsage::none() } } /// Builds a `BufferUsage` with `vertex_buffer` and `transfer_destination` set to true and the rest /// to false. #[inline] pub const fn vertex_buffer_transfer_destination() -> BufferUsage { BufferUsage { vertex_buffer: true, transfer_destination: true, ..BufferUsage::none() } } /// Builds a `BufferUsage` with `index_buffer` set to true and the rest to false. #[inline] pub const fn index_buffer() -> BufferUsage { BufferUsage { index_buffer: true, ..BufferUsage::none() } } /// Builds a `BufferUsage` with `index_buffer` and `transfer_destination` set to true and the rest to false. #[inline] pub const fn index_buffer_transfer_destination() -> BufferUsage { BufferUsage { index_buffer: true, transfer_destination: true, ..BufferUsage::none() } } /// Builds a `BufferUsage` with `uniform_buffer` set to true and the rest to false. #[inline] pub const fn uniform_buffer() -> BufferUsage { BufferUsage { uniform_buffer: true, ..BufferUsage::none() } } /// Builds a `BufferUsage` with `uniform_buffer` and `transfer_destination` set to true and the rest /// to false. #[inline] pub const fn uniform_buffer_transfer_destination() -> BufferUsage { BufferUsage { uniform_buffer: true, transfer_destination: true, ..BufferUsage::none() } } /// Builds a `BufferUsage` with `indirect_buffer` set to true and the rest to false. #[inline] pub const fn indirect_buffer() -> BufferUsage { BufferUsage { indirect_buffer: true, ..BufferUsage::none() } } /// Builds a `BufferUsage` with `indirect_buffer` and `transfer_destination` set to true and the rest /// to false. #[inline] pub const fn indirect_buffer_transfer_destination() -> BufferUsage { BufferUsage { indirect_buffer: true, transfer_destination: true, ..BufferUsage::none() } } /// Builds a `BufferUsage` with `device_address` set to true and the rest to false. #[inline] pub const fn device_address() -> BufferUsage { BufferUsage { device_address: true, ..BufferUsage::none() } } } impl From for ash::vk::BufferUsageFlags { fn from(val: BufferUsage) -> Self { let mut result = ash::vk::BufferUsageFlags::empty(); if val.transfer_source { result |= ash::vk::BufferUsageFlags::TRANSFER_SRC; } if val.transfer_destination { result |= ash::vk::BufferUsageFlags::TRANSFER_DST; } if val.uniform_texel_buffer { result |= ash::vk::BufferUsageFlags::UNIFORM_TEXEL_BUFFER; } if val.storage_texel_buffer { result |= ash::vk::BufferUsageFlags::STORAGE_TEXEL_BUFFER; } if val.uniform_buffer { result |= ash::vk::BufferUsageFlags::UNIFORM_BUFFER; } if val.storage_buffer { result |= ash::vk::BufferUsageFlags::STORAGE_BUFFER; } if val.index_buffer { result |= ash::vk::BufferUsageFlags::INDEX_BUFFER; } if val.vertex_buffer { result |= ash::vk::BufferUsageFlags::VERTEX_BUFFER; } if val.indirect_buffer { result |= ash::vk::BufferUsageFlags::INDIRECT_BUFFER; } if val.device_address { result |= ash::vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS; } result } } impl BitOr for BufferUsage { type Output = Self; #[inline] fn bitor(self, rhs: Self) -> Self { BufferUsage { transfer_source: self.transfer_source || rhs.transfer_source, transfer_destination: self.transfer_destination || rhs.transfer_destination, uniform_texel_buffer: self.uniform_texel_buffer || rhs.uniform_texel_buffer, storage_texel_buffer: self.storage_texel_buffer || rhs.storage_texel_buffer, uniform_buffer: self.uniform_buffer || rhs.uniform_buffer, storage_buffer: self.storage_buffer || rhs.storage_buffer, index_buffer: self.index_buffer || rhs.index_buffer, vertex_buffer: self.vertex_buffer || rhs.vertex_buffer, indirect_buffer: self.indirect_buffer || rhs.indirect_buffer, device_address: self.device_address || rhs.device_address, } } }