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;
|
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,
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue