aboutsummaryrefslogtreecommitdiff
path: root/rendy-memory/src/usage.rs
diff options
context:
space:
mode:
authortcmal <me@aria.rip>2024-08-25 17:44:22 +0100
committertcmal <me@aria.rip>2024-08-25 17:44:22 +0100
commitd7d0f0277c437004ed476393542da39c84c5cf9f (patch)
tree65c369e00fc1416c74019fde4456b0bf90d3067c /rendy-memory/src/usage.rs
parent10b3d4ac59e826b31d2114999e31893390acfb9c (diff)
chore(render): update hal and fix some errors
Diffstat (limited to 'rendy-memory/src/usage.rs')
-rw-r--r--rendy-memory/src/usage.rs210
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),
+ }
+ }
+}