gfx_memory/
usage.rs

1//! Defines usage types for memory bocks.
2//! See `Usage` and implementations for details.
3
4use hal::memory as m;
5
6/// Scenarios of how resources use memory.
7#[derive(Debug, Clone, Copy, PartialEq)]
8pub enum MemoryUsage {
9    /// Full speed GPU access.
10    /// Optimal for render targets and persistent resources.
11    /// Avoid memory with host access.
12    Private,
13    /// CPU to GPU data flow with update commands.
14    /// Used for dynamic buffer data, typically constant buffers.
15    /// Host access is guaranteed.
16    /// Prefers memory with fast GPU access.
17    Dynamic {
18        /// Optimize for multiple disjoint small portions to be updated,
19        /// as opposed to big linear chunks of memory.
20        sparse_updates: bool,
21    },
22    /// CPU to GPU data flow with mapping.
23    /// Used for staging data before copying to the `Data` memory.
24    /// Host access is guaranteed.
25    Staging {
26        /// Optimize for reading back from Gpu.
27        read_back: bool,
28    },
29}
30
31impl MemoryUsage {
32    /// Set of required memory properties for this usage.
33    pub fn properties_required(self) -> m::Properties {
34        match self {
35            MemoryUsage::Private => m::Properties::DEVICE_LOCAL,
36            MemoryUsage::Dynamic { .. } | MemoryUsage::Staging { .. } => m::Properties::CPU_VISIBLE,
37        }
38    }
39
40    #[allow(clippy::identity_op)]
41    pub(crate) fn memory_fitness(self, properties: m::Properties) -> u32 {
42        match self {
43            MemoryUsage::Private => {
44                assert!(properties.contains(m::Properties::DEVICE_LOCAL));
45                0 | (!properties.contains(m::Properties::CPU_VISIBLE) as u32) << 3
46                    | (!properties.contains(m::Properties::LAZILY_ALLOCATED) as u32) << 2
47                    | (!properties.contains(m::Properties::CPU_CACHED) as u32) << 1
48                    | (!properties.contains(m::Properties::COHERENT) as u32) << 0
49            }
50            MemoryUsage::Dynamic { sparse_updates } => {
51                assert!(properties.contains(m::Properties::CPU_VISIBLE));
52                assert!(!properties.contains(m::Properties::LAZILY_ALLOCATED));
53                0 | (properties.contains(m::Properties::DEVICE_LOCAL) as u32) << 2
54                    | ((properties.contains(m::Properties::COHERENT) == sparse_updates) as u32) << 1
55                    | (!properties.contains(m::Properties::CPU_CACHED) as u32) << 0
56            }
57            MemoryUsage::Staging { read_back } => {
58                assert!(properties.contains(m::Properties::CPU_VISIBLE));
59                assert!(!properties.contains(m::Properties::LAZILY_ALLOCATED));
60                0 | ((properties.contains(m::Properties::CPU_CACHED) == read_back) as u32) << 1
61                    | (!properties.contains(m::Properties::DEVICE_LOCAL) as u32) << 0
62            }
63        }
64    }
65}