gfx_hal/memory.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
//! Types to describe the properties of memory allocated for graphics resources.
use crate::{buffer, image, queue, Backend};
use std::ops::Range;
bitflags!(
/// Memory property flags.
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Properties: u16 {
/// Device local memory on the GPU.
const DEVICE_LOCAL = 0x1;
/// Host visible memory can be accessed by the CPU.
///
/// Backends must provide at least one cpu visible memory.
const CPU_VISIBLE = 0x2;
/// CPU-GPU coherent.
///
/// Non-coherent memory requires explicit flushing.
const COHERENT = 0x4;
/// Cached memory by the CPU
const CPU_CACHED = 0x8;
/// Memory that may be lazily allocated as needed on the GPU
/// and *must not* be visible to the CPU.
const LAZILY_ALLOCATED = 0x10;
}
);
bitflags!(
/// Memory heap flags.
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct HeapFlags: u16 {
/// Device local memory on the GPU.
const DEVICE_LOCAL = 0x1;
}
);
bitflags!(
/// Barrier dependency flags.
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Dependencies: u32 {
/// Specifies the memory dependency to be framebuffer-local.
const BY_REGION = 0x1;
///
const VIEW_LOCAL = 0x2;
///
const DEVICE_GROUP = 0x4;
}
);
// DOC TODO: Could be better, but I don't know how to do this without
// trying to explain the whole synchronization model.
/// A [memory barrier](https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#synchronization-memory-barriers)
/// type for either buffers or images.
#[allow(missing_docs)]
#[derive(Clone, Debug)]
pub enum Barrier<'a, B: Backend> {
/// Applies the given access flags to all buffers in the range.
AllBuffers(Range<buffer::Access>),
/// Applies the given access flags to all images in the range.
AllImages(Range<image::Access>),
/// A memory barrier that defines access to a buffer.
Buffer {
/// The access flags controlling the buffer.
states: Range<buffer::State>,
/// The buffer the barrier controls.
target: &'a B::Buffer,
/// Subrange of the buffer the barrier applies to.
range: buffer::SubRange,
/// The source and destination Queue family IDs, for a [queue family ownership transfer](https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#synchronization-queue-transfers)
/// Can be `None` to indicate no ownership transfer.
families: Option<Range<queue::QueueFamilyId>>,
},
/// A memory barrier that defines access to (a subset of) an image.
Image {
/// The access flags controlling the image.
states: Range<image::State>,
/// The image the barrier controls.
target: &'a B::Image,
/// A `SubresourceRange` that defines which section of an image the barrier applies to.
range: image::SubresourceRange,
/// The source and destination Queue family IDs, for a [queue family ownership transfer](https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#synchronization-queue-transfers)
/// Can be `None` to indicate no ownership transfer.
families: Option<Range<queue::QueueFamilyId>>,
},
}
impl<'a, B: Backend> Barrier<'a, B> {
/// Create a barrier for the whole buffer between the given states.
pub fn whole_buffer(target: &'a B::Buffer, states: Range<buffer::State>) -> Self {
Barrier::Buffer {
states,
target,
families: None,
range: buffer::SubRange::WHOLE,
}
}
}
/// Memory requirements for a certain resource (buffer/image).
#[derive(Clone, Copy, Debug)]
pub struct Requirements {
/// Size in the memory.
pub size: u64,
/// Memory alignment.
pub alignment: u64,
/// Supported memory types.
pub type_mask: u32,
}
/// A linear segment within a memory block.
#[derive(Clone, Debug, Default, Hash, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Segment {
/// Offset to the segment.
pub offset: u64,
/// Size of the segment, or None if unbound.
pub size: Option<u64>,
}
impl Segment {
/// All the memory available.
pub const ALL: Self = Segment {
offset: 0,
size: None,
};
}
/// Defines a single memory bind region.
///
/// This is used in the [`bind_sparse`][queue::Queue::bind_sparse] method to define a physical
/// store region for a buffer.
#[derive(Debug)]
pub struct SparseBind<M> {
/// Offset into the (virtual) resource.
pub resource_offset: u64,
/// Size of the memory region to be bound.
pub size: u64,
/// Memory that the physical store is bound to, and the offset into the resource of the binding.
///
/// Using `None` will unbind this range. Reading or writing to an unbound range is undefined
/// behaviour in some older hardware.
pub memory: Option<(M, u64)>,
}
/// Defines a single image memory bind region.
///
/// This is used in the [`bind_sparse`][queue::Queue::bind_sparse] method to define a physical
/// store region for a buffer.
#[derive(Debug)]
pub struct SparseImageBind<M> {
/// Image aspect and region of interest in the image.
pub subresource: image::Subresource,
/// Coordinates of the first texel in the (virtual) image subresource to bind.
pub offset: image::Offset,
/// Extent of the (virtual) image subresource region to be bound.
pub extent: image::Extent,
/// Memory that the physical store is bound to, and the offset into the resource of the binding.
///
/// Using `None` will unbind this range. Reading or writing to an unbound range is undefined
/// behaviour in some older hardware.
pub memory: Option<(M, u64)>,
}
bitflags!(
/// Sparse flags for creating images and buffers.
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct SparseFlags: u32 {
/// Specifies the view will be backed using sparse memory binding.
const SPARSE_BINDING = 0x0000_0001;
/// Specifies the view can be partially backed with sparse memory binding.
/// Must have `SPARSE_BINDING` enabled.
const SPARSE_RESIDENCY = 0x0000_0002;
/// Specifies the view will be backed using sparse memory binding with memory bindings that
/// might alias other data. Must have `SPARSE_BINDING` enabled.
const SPARSE_ALIASED = 0x0000_0004;
}
);