ohm 0.0.0

High performance 2D graphics library
Documentation
//! A dumb allocator making a separate allocation for each resource.

use std::ops::Range;

use gfx_hal::adapter::{MemoryProperties, PhysicalDevice};
use gfx_hal::memory::{Properties, Requirements};
use gfx_hal::{Backend, Device};

use super::{pick_memory_type, Allocation, AllocationError, AllocationSpec, Allocator};

#[derive(derivative::Derivative)]
#[derivative(Debug)]
pub struct PassthroughAllocation<B: Backend> {
    #[derivative(Debug = "ignore")]
    memory: B::Memory,
    size: u64,
    flags: Properties,
    #[derivative(Debug = "ignore")]
    relevant: relevant::Relevant,
}

impl<B: Backend> Allocation<B> for PassthroughAllocation<B> {
    fn memory(&self) -> &B::Memory {
        &self.memory
    }

    fn flags(&self) -> Properties {
        self.flags
    }

    fn range(&self) -> Range<u64> {
        0..self.size
    }
}

/// Dumb allocator making a separate allocation for each resource. Don't use it.
#[derive(Debug)]
pub struct PassthroughAllocator {
    memory_props: MemoryProperties,
}

impl PassthroughAllocator {
    pub fn new<B: Backend>(device: &B::PhysicalDevice) -> PassthroughAllocator {
        PassthroughAllocator {
            memory_props: device.memory_properties(),
        }
    }
}

impl<B: Backend> Allocator<B> for PassthroughAllocator {
    type Allocation = PassthroughAllocation<B>;

    fn alloc(
        &mut self,
        device: &B::Device,
        req: Requirements,
        spec: AllocationSpec,
    ) -> Result<Self::Allocation, AllocationError> {
        let memory_type = pick_memory_type(&self.memory_props, req, spec)?;

        let memory = unsafe { device.allocate_memory(memory_type, req.size)? };
        let flags = self.memory_props.memory_types[memory_type.0].properties;

        Ok(PassthroughAllocation {
            memory,
            flags,
            size: req.size,
            relevant: relevant::Relevant,
        })
    }

    fn free(&mut self, device: &B::Device, allocation: Self::Allocation) {
        unsafe { device.free_memory(allocation.memory) };
        allocation.relevant.dispose();
    }
}