use crate::allocator::Kind;
pub trait MemoryUsage: std::fmt::Debug {
fn properties_required(&self) -> gfx_hal::memory::Properties;
fn memory_fitness(&self, properties: gfx_hal::memory::Properties) -> u32;
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)
}
}
#[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,
}
}
}
#[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,
}
}
}
#[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,
}
}
}
#[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,
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum MemoryUsageValue {
Data,
Dynamic,
Upload,
Download,
}
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),
}
}
}