AttrPool keeps buffer; impl MeshPool::flush()

This commit is contained in:
mars 2022-04-18 01:20:50 -06:00
parent e455be548f
commit b4d6d6cba0
2 changed files with 52 additions and 5 deletions

View File

@ -6,6 +6,7 @@ use std::collections::HashMap;
use std::sync::Arc; use std::sync::Arc;
/// An error that can be returned when allocating a mesh. /// An error that can be returned when allocating a mesh.
#[derive(Debug)]
pub enum PoolError { pub enum PoolError {
TooBig, TooBig,
NoMoreRoom, NoMoreRoom,
@ -33,6 +34,7 @@ pub struct AttrLayout {
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
pub struct AttrInfo { pub struct AttrInfo {
pub layout: AttrLayout, pub layout: AttrLayout,
pub usages: wgpu::BufferUsages,
pub default_pool_size: usize, pub default_pool_size: usize,
} }
@ -52,6 +54,9 @@ pub trait Attribute: Sized {
} }
} }
/// The [wgpu::BufferUsages] of this data.
fn get_usages() -> wgpu::BufferUsages;
/// The default size for new pools of this attribute. /// The default size for new pools of this attribute.
/// ///
/// Defaults to 1024 * 1024. (Around one million.) /// Defaults to 1024 * 1024. (Around one million.)
@ -90,9 +95,11 @@ impl AttrStore {
*id *id
} else { } else {
let layout = T::get_layout(); let layout = T::get_layout();
let usages = T::get_usages();
let default_pool_size = T::get_default_pool_size(); let default_pool_size = T::get_default_pool_size();
let info = AttrInfo { let info = AttrInfo {
layout, layout,
usages,
default_pool_size, default_pool_size,
}; };
let id = self.add(info); let id = self.add(info);
@ -137,6 +144,7 @@ pub struct FreeSpace {
/// A single GPU buffer containing linear arrays of attributes. /// A single GPU buffer containing linear arrays of attributes.
pub struct AttrPool { pub struct AttrPool {
buffer: wgpu::Buffer,
id: AttrId, id: AttrId,
pool_id: usize, pool_id: usize,
layout: AttrLayout, layout: AttrLayout,
@ -152,11 +160,20 @@ impl PartialEq for AttrPool {
} }
impl AttrPool { impl AttrPool {
pub fn new(id: AttrId, pool_id: usize, info: AttrInfo) -> Self { pub fn new(device: &wgpu::Device, id: AttrId, pool_id: usize, info: AttrInfo) -> Self {
let layout = info.layout; let layout = info.layout;
let size = info.default_pool_size; let size = info.default_pool_size;
// TODO debug strings for attributes + pools + buffers
let buffer = device.create_buffer(&wgpu::BufferDescriptor {
label: None,
usage: wgpu::BufferUsages::COPY_DST | info.usages,
mapped_at_creation: false,
size: (size * layout.size) as wgpu::BufferAddress,
});
Self { Self {
buffer,
id, id,
pool_id, pool_id,
layout, layout,
@ -290,6 +307,15 @@ impl AttrPool {
let alloc = self.allocs.get(key).ok_or(PoolError::InvalidIndex)?; let alloc = self.allocs.get(key).ok_or(PoolError::InvalidIndex)?;
Ok(alloc.offset) Ok(alloc.offset)
} }
/// Gets a [CopyDest] for an allocation, by key.
pub fn get_copy_dest(&self, key: usize) -> Result<CopyDest, PoolError> {
let offset = self.get_offset(key)?;
Ok(CopyDest {
buffer: &self.buffer,
offset,
})
}
} }
/// The number of attributes a mesh can have before they're moved to the heap. /// The number of attributes a mesh can have before they're moved to the heap.
@ -382,7 +408,7 @@ impl MeshPool {
None => return Err(PoolError::AttrUnregistered), None => return Err(PoolError::AttrUnregistered),
}; };
let pool = AttrPool::new(id, 0, *info); let pool = AttrPool::new(&self.device, id, 0, *info);
self.pools.insert(id, vec![pool]); self.pools.insert(id, vec![pool]);
self.pools.get_mut(&id).unwrap() self.pools.get_mut(&id).unwrap()
} }
@ -417,6 +443,23 @@ impl MeshPool {
Ok(handle) Ok(handle)
} }
pub fn flush(&mut self, commands: &mut wgpu::CommandEncoder) {
let get_dst = |target: &AttrAllocKey| {
self.pools
.get(&target.attr)
.unwrap()
.get(target.pool)
.unwrap()
.get_copy_dest(target.alloc)
.unwrap()
};
// TODO: keep track of loaded/unloaded meshes
let on_complete = |target| {};
self.staging.flush(commands, get_dst, on_complete);
}
pub fn iter_meshes<T, I, F>( pub fn iter_meshes<T, I, F>(
&self, &self,
layout: MeshLayoutId, layout: MeshLayoutId,

View File

@ -28,10 +28,10 @@ impl<T: Clone> StagingPool<T> {
} }
} }
pub fn flush( pub fn flush<'a>(
&mut self, &mut self,
cmd: &mut wgpu::CommandEncoder, cmd: &mut wgpu::CommandEncoder,
get_dst: impl Fn(&T) -> CopyDest<'_>, get_dst: impl Fn(&T) -> CopyDest<'a>,
on_complete: impl Fn(T), on_complete: impl Fn(T),
) { ) {
if self.spillover.is_empty() { if self.spillover.is_empty() {
@ -115,7 +115,11 @@ impl<T: Clone> CopyBuffer<T> {
if dst_size >= size { if dst_size >= size {
dst[0..size].copy_from_slice(&data); dst[0..size].copy_from_slice(&data);
let info = CopyInfo { target, offset, size }; let info = CopyInfo {
target,
offset,
size,
};
(info, None) (info, None)
} else { } else {
let remainder = data.split_off(dst_size); let remainder = data.split_off(dst_size);