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
}
}
#[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();
}
}