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