diff options
author | tcmal <me@aria.rip> | 2024-08-25 17:44:22 +0100 |
---|---|---|
committer | tcmal <me@aria.rip> | 2024-08-25 17:44:22 +0100 |
commit | d7d0f0277c437004ed476393542da39c84c5cf9f (patch) | |
tree | 65c369e00fc1416c74019fde4456b0bf90d3067c /rendy-memory/src/usage.rs | |
parent | 10b3d4ac59e826b31d2114999e31893390acfb9c (diff) |
chore(render): update hal and fix some errors
Diffstat (limited to 'rendy-memory/src/usage.rs')
-rw-r--r-- | rendy-memory/src/usage.rs | 210 |
1 files changed, 210 insertions, 0 deletions
diff --git a/rendy-memory/src/usage.rs b/rendy-memory/src/usage.rs new file mode 100644 index 0000000..a9a4012 --- /dev/null +++ b/rendy-memory/src/usage.rs @@ -0,0 +1,210 @@ +//! Defines usage types for memory bocks. +//! See `Usage` and implementations for details. + +use crate::allocator::Kind; + +/// Memory usage trait. +pub trait MemoryUsage: std::fmt::Debug { + /// Get set of properties required for the usage. + fn properties_required(&self) -> gfx_hal::memory::Properties; + + /// Get comparable fitness value for memory properties. + /// + /// # Panics + /// + /// This function will panic if properties set doesn't contain required properties. + fn memory_fitness(&self, properties: gfx_hal::memory::Properties) -> u32; + + /// Get comparable fitness value for memory allocator. + fn allocator_fitness(&self, kind: Kind) -> u32; +} + +impl<T> MemoryUsage for T +where + T: std::ops::Deref + std::fmt::Debug, + T::Target: MemoryUsage, +{ + fn properties_required(&self) -> gfx_hal::memory::Properties { + (&**self).properties_required() + } + fn memory_fitness(&self, properties: gfx_hal::memory::Properties) -> u32 { + (&**self).memory_fitness(properties) + } + fn allocator_fitness(&self, kind: Kind) -> u32 { + (&**self).allocator_fitness(kind) + } +} + +/// Full speed GPU access. +/// Optimal for render targets and persistent resources. +/// Avoid memory with host access. +#[derive(Clone, Copy, Debug)] +pub struct Data; + +impl MemoryUsage for Data { + fn properties_required(&self) -> gfx_hal::memory::Properties { + gfx_hal::memory::Properties::DEVICE_LOCAL + } + + #[inline] + fn memory_fitness(&self, properties: gfx_hal::memory::Properties) -> u32 { + assert!(properties.contains(gfx_hal::memory::Properties::DEVICE_LOCAL)); + 0 | ((!properties.contains(gfx_hal::memory::Properties::CPU_VISIBLE)) as u32) << 3 + | ((!properties.contains(gfx_hal::memory::Properties::LAZILY_ALLOCATED)) as u32) << 2 + | ((!properties.contains(gfx_hal::memory::Properties::CPU_CACHED)) as u32) << 1 + | ((!properties.contains(gfx_hal::memory::Properties::COHERENT)) as u32) << 0 + } + + fn allocator_fitness(&self, kind: Kind) -> u32 { + match kind { + Kind::Dedicated => 1, + Kind::Dynamic => 2, + Kind::Linear => 0, + } + } +} + +/// CPU to GPU data flow with update commands. +/// Used for dynamic buffer data, typically constant buffers. +/// Host access is guaranteed. +/// Prefers memory with fast GPU access. +#[derive(Clone, Copy, Debug)] +pub struct Dynamic; + +impl MemoryUsage for Dynamic { + fn properties_required(&self) -> gfx_hal::memory::Properties { + gfx_hal::memory::Properties::CPU_VISIBLE + } + + #[inline] + fn memory_fitness(&self, properties: gfx_hal::memory::Properties) -> u32 { + assert!(properties.contains(gfx_hal::memory::Properties::CPU_VISIBLE)); + assert!(!properties.contains(gfx_hal::memory::Properties::LAZILY_ALLOCATED)); + + 0 | (properties.contains(gfx_hal::memory::Properties::DEVICE_LOCAL) as u32) << 2 + | (properties.contains(gfx_hal::memory::Properties::COHERENT) as u32) << 1 + | ((!properties.contains(gfx_hal::memory::Properties::CPU_CACHED)) as u32) << 0 + } + + fn allocator_fitness(&self, kind: Kind) -> u32 { + match kind { + Kind::Dedicated => 1, + Kind::Dynamic => 2, + Kind::Linear => 0, + } + } +} + +/// CPU to GPU data flow with mapping. +/// Used for staging data before copying to the `Data` memory. +/// Host access is guaranteed. +#[derive(Clone, Copy, Debug)] +pub struct Upload; + +impl MemoryUsage for Upload { + fn properties_required(&self) -> gfx_hal::memory::Properties { + gfx_hal::memory::Properties::CPU_VISIBLE + } + + #[inline] + fn memory_fitness(&self, properties: gfx_hal::memory::Properties) -> u32 { + assert!(properties.contains(gfx_hal::memory::Properties::CPU_VISIBLE)); + assert!(!properties.contains(gfx_hal::memory::Properties::LAZILY_ALLOCATED)); + + 0 | ((!properties.contains(gfx_hal::memory::Properties::DEVICE_LOCAL)) as u32) << 2 + | (properties.contains(gfx_hal::memory::Properties::COHERENT) as u32) << 1 + | ((!properties.contains(gfx_hal::memory::Properties::CPU_CACHED)) as u32) << 0 + } + + fn allocator_fitness(&self, kind: Kind) -> u32 { + match kind { + Kind::Dedicated => 0, + Kind::Dynamic => 1, + Kind::Linear => 2, + } + } +} + +/// GPU to CPU data flow with mapping. +/// Used for copying data from `Data` memory to be read by the host. +/// Host access is guaranteed. +#[derive(Clone, Copy, Debug)] +pub struct Download; + +impl MemoryUsage for Download { + fn properties_required(&self) -> gfx_hal::memory::Properties { + gfx_hal::memory::Properties::CPU_VISIBLE + } + + #[inline] + fn memory_fitness(&self, properties: gfx_hal::memory::Properties) -> u32 { + assert!(properties.contains(gfx_hal::memory::Properties::CPU_VISIBLE)); + assert!(!properties.contains(gfx_hal::memory::Properties::LAZILY_ALLOCATED)); + + 0 | ((!properties.contains(gfx_hal::memory::Properties::DEVICE_LOCAL)) as u32) << 2 + | (properties.contains(gfx_hal::memory::Properties::CPU_CACHED) as u32) << 1 + | (properties.contains(gfx_hal::memory::Properties::COHERENT) as u32) << 0 + } + + fn allocator_fitness(&self, kind: Kind) -> u32 { + match kind { + Kind::Dedicated => 0, + Kind::Dynamic => 1, + Kind::Linear => 2, + } + } +} + +/// Well-known memory usage types. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum MemoryUsageValue { + /// See [`Data`] + /// + /// [`Data`]: struct.Data.html + Data, + + /// See [`Dynamic`] + /// + /// [`Dynamic`]: struct.Dynamic.html + Dynamic, + + /// See [`Upload`] + /// + /// [`Upload`]: struct.Upload.html + Upload, + + /// See [`Download`] + /// + /// [`Download`]: struct.Download.html + Download, +} + +/// Memory usage trait. +impl MemoryUsage for MemoryUsageValue { + fn properties_required(&self) -> gfx_hal::memory::Properties { + match self { + MemoryUsageValue::Data => Data.properties_required(), + MemoryUsageValue::Dynamic => Dynamic.properties_required(), + MemoryUsageValue::Upload => Upload.properties_required(), + MemoryUsageValue::Download => Download.properties_required(), + } + } + + fn memory_fitness(&self, properties: gfx_hal::memory::Properties) -> u32 { + match self { + MemoryUsageValue::Data => Data.memory_fitness(properties), + MemoryUsageValue::Dynamic => Dynamic.memory_fitness(properties), + MemoryUsageValue::Upload => Upload.memory_fitness(properties), + MemoryUsageValue::Download => Download.memory_fitness(properties), + } + } + + fn allocator_fitness(&self, kind: Kind) -> u32 { + match self { + MemoryUsageValue::Data => Data.allocator_fitness(kind), + MemoryUsageValue::Dynamic => Dynamic.allocator_fitness(kind), + MemoryUsageValue::Upload => Upload.allocator_fitness(kind), + MemoryUsageValue::Download => Download.allocator_fitness(kind), + } + } +} |