blob: 7566012df70c874e4c3fbc51f5954afed4d00231 [file] [log] [blame]
// Copyright (c) 2016 The vulkano developers
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>,
// 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<BufferUsage> 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,
}
}
}