use crate::backend::MkGpuBackend;
use crate::buffer::{MkDeviceBuffer, MkBufferUsage};
use crate::memory::MkMemoryType;
use std::collections::VecDeque;
pub struct MkGpuPool<B: MkGpuBackend> {
memory_type: MkMemoryType,
buffer_size: usize,
usage: MkBufferUsage,
free_buffers: VecDeque<B::BufferHandle>,
max_buffers: usize,
}
impl<B: MkGpuBackend> MkGpuPool<B> {
pub fn new(
memory_type: MkMemoryType,
buffer_size: usize,
usage: MkBufferUsage,
max_buffers: usize,
) -> Self {
Self {
memory_type,
buffer_size,
usage,
free_buffers: VecDeque::new(),
max_buffers,
}
}
pub fn acquire(&mut self, backend: &B) -> Result<MkDeviceBuffer<B>, B::Error> {
if let Some(handle) = self.free_buffers.pop_front() {
Ok(MkDeviceBuffer::new(handle, self.buffer_size, self.usage))
} else {
let handle = backend.create_buffer(self.buffer_size, self.usage, self.memory_type)?;
Ok(MkDeviceBuffer::new(handle, self.buffer_size, self.usage))
}
}
pub fn release(&mut self, buffer: MkDeviceBuffer<B>, backend: &B) {
if self.free_buffers.len() < self.max_buffers {
self.free_buffers.push_back(buffer.handle().clone());
} else {
backend.destroy_buffer(buffer.handle());
}
}
pub fn free_count(&self) -> usize {
self.free_buffers.len()
}
pub fn clear(&mut self, backend: &B) {
for handle in self.free_buffers.drain(..) {
backend.destroy_buffer(&handle);
}
}
}