AttrPool keeps buffer; impl MeshPool::flush()
This commit is contained in:
parent
e455be548f
commit
b4d6d6cba0
47
src/mesh.rs
47
src/mesh.rs
|
@ -6,6 +6,7 @@ use std::collections::HashMap;
|
|||
use std::sync::Arc;
|
||||
|
||||
/// An error that can be returned when allocating a mesh.
|
||||
#[derive(Debug)]
|
||||
pub enum PoolError {
|
||||
TooBig,
|
||||
NoMoreRoom,
|
||||
|
@ -33,6 +34,7 @@ pub struct AttrLayout {
|
|||
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
|
||||
pub struct AttrInfo {
|
||||
pub layout: AttrLayout,
|
||||
pub usages: wgpu::BufferUsages,
|
||||
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.
|
||||
///
|
||||
/// Defaults to 1024 * 1024. (Around one million.)
|
||||
|
@ -90,9 +95,11 @@ impl AttrStore {
|
|||
*id
|
||||
} else {
|
||||
let layout = T::get_layout();
|
||||
let usages = T::get_usages();
|
||||
let default_pool_size = T::get_default_pool_size();
|
||||
let info = AttrInfo {
|
||||
layout,
|
||||
usages,
|
||||
default_pool_size,
|
||||
};
|
||||
let id = self.add(info);
|
||||
|
@ -137,6 +144,7 @@ pub struct FreeSpace {
|
|||
|
||||
/// A single GPU buffer containing linear arrays of attributes.
|
||||
pub struct AttrPool {
|
||||
buffer: wgpu::Buffer,
|
||||
id: AttrId,
|
||||
pool_id: usize,
|
||||
layout: AttrLayout,
|
||||
|
@ -152,11 +160,20 @@ impl PartialEq for 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 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 {
|
||||
buffer,
|
||||
id,
|
||||
pool_id,
|
||||
layout,
|
||||
|
@ -290,6 +307,15 @@ impl AttrPool {
|
|||
let alloc = self.allocs.get(key).ok_or(PoolError::InvalidIndex)?;
|
||||
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.
|
||||
|
@ -382,7 +408,7 @@ impl MeshPool {
|
|||
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.get_mut(&id).unwrap()
|
||||
}
|
||||
|
@ -417,6 +443,23 @@ impl MeshPool {
|
|||
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>(
|
||||
&self,
|
||||
layout: MeshLayoutId,
|
||||
|
|
|
@ -28,10 +28,10 @@ impl<T: Clone> StagingPool<T> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn flush(
|
||||
pub fn flush<'a>(
|
||||
&mut self,
|
||||
cmd: &mut wgpu::CommandEncoder,
|
||||
get_dst: impl Fn(&T) -> CopyDest<'_>,
|
||||
get_dst: impl Fn(&T) -> CopyDest<'a>,
|
||||
on_complete: impl Fn(T),
|
||||
) {
|
||||
if self.spillover.is_empty() {
|
||||
|
@ -115,7 +115,11 @@ impl<T: Clone> CopyBuffer<T> {
|
|||
|
||||
if dst_size >= size {
|
||||
dst[0..size].copy_from_slice(&data);
|
||||
let info = CopyInfo { target, offset, size };
|
||||
let info = CopyInfo {
|
||||
target,
|
||||
offset,
|
||||
size,
|
||||
};
|
||||
(info, None)
|
||||
} else {
|
||||
let remainder = data.split_off(dst_size);
|
||||
|
|
Loading…
Reference in New Issue