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);