Split brickmap cache to it's own struct
This commit is contained in:
parent
66f44c5461
commit
8e08506e6c
|
@ -51,9 +51,7 @@ pub struct BrickmapManager {
|
||||||
state_buffer: wgpu::Buffer,
|
state_buffer: wgpu::Buffer,
|
||||||
brickgrid: Vec<u32>,
|
brickgrid: Vec<u32>,
|
||||||
brickgrid_buffer: wgpu::Buffer,
|
brickgrid_buffer: wgpu::Buffer,
|
||||||
brickmap_cache_map: Vec<Option<BrickmapCacheEntry>>,
|
brickmap_cache: BrickmapCache,
|
||||||
brickmap_cache_idx: usize,
|
|
||||||
brickmap_buffer: wgpu::Buffer,
|
|
||||||
shading_table_buffer: wgpu::Buffer,
|
shading_table_buffer: wgpu::Buffer,
|
||||||
shading_table_allocator: ShadingTableAllocator,
|
shading_table_allocator: ShadingTableAllocator,
|
||||||
feedback_buffer: wgpu::Buffer,
|
feedback_buffer: wgpu::Buffer,
|
||||||
|
@ -84,8 +82,7 @@ impl BrickmapManager {
|
||||||
let brickgrid =
|
let brickgrid =
|
||||||
vec![1u32; (brickgrid_dims.x * brickgrid_dims.y * brickgrid_dims.z) as usize];
|
vec![1u32; (brickgrid_dims.x * brickgrid_dims.y * brickgrid_dims.z) as usize];
|
||||||
|
|
||||||
let brickmap_cache = vec![Brickmap::default(); brickmap_cache_size];
|
let brickmap_cache = BrickmapCache::new(context, brickmap_cache_size);
|
||||||
let brickmap_cache_map = vec![None; brickmap_cache.capacity()];
|
|
||||||
|
|
||||||
let shading_table_allocator = ShadingTableAllocator::new(4, shading_table_bucket_size);
|
let shading_table_allocator = ShadingTableAllocator::new(4, shading_table_bucket_size);
|
||||||
let shading_table = vec![0u32; shading_table_allocator.total_elements as usize];
|
let shading_table = vec![0u32; shading_table_allocator.total_elements as usize];
|
||||||
|
@ -106,7 +103,6 @@ impl BrickmapManager {
|
||||||
.with_init_buffer_bm("Brick World State", &[state_uniform])
|
.with_init_buffer_bm("Brick World State", &[state_uniform])
|
||||||
.set_usage(wgpu::BufferUsages::STORAGE | wgpu::BufferUsages::COPY_DST)
|
.set_usage(wgpu::BufferUsages::STORAGE | wgpu::BufferUsages::COPY_DST)
|
||||||
.with_init_buffer_bm("Brickgrid", &brickgrid)
|
.with_init_buffer_bm("Brickgrid", &brickgrid)
|
||||||
.with_init_buffer_bm("Brickmap Cache", &brickmap_cache)
|
|
||||||
.with_init_buffer_bm("Shading Table", &shading_table)
|
.with_init_buffer_bm("Shading Table", &shading_table)
|
||||||
.with_init_buffer_bm("Brickgrid Unpack", &brickgrid_upload_data)
|
.with_init_buffer_bm("Brickgrid Unpack", &brickgrid_upload_data)
|
||||||
.with_init_buffer_bm("Brickmap Unpack", &brickmap_upload_data)
|
.with_init_buffer_bm("Brickmap Unpack", &brickmap_upload_data)
|
||||||
|
@ -123,8 +119,7 @@ impl BrickmapManager {
|
||||||
Self {
|
Self {
|
||||||
state_uniform,
|
state_uniform,
|
||||||
brickgrid,
|
brickgrid,
|
||||||
brickmap_cache_map,
|
brickmap_cache,
|
||||||
brickmap_cache_idx: 0,
|
|
||||||
shading_table_allocator,
|
shading_table_allocator,
|
||||||
unpack_max_count: max_uploaded_brickmaps as usize,
|
unpack_max_count: max_uploaded_brickmaps as usize,
|
||||||
brickgrid_staged,
|
brickgrid_staged,
|
||||||
|
@ -132,7 +127,6 @@ impl BrickmapManager {
|
||||||
|
|
||||||
state_buffer: buffers.remove(0),
|
state_buffer: buffers.remove(0),
|
||||||
brickgrid_buffer: buffers.remove(0),
|
brickgrid_buffer: buffers.remove(0),
|
||||||
brickmap_buffer: buffers.remove(0),
|
|
||||||
shading_table_buffer: buffers.remove(0),
|
shading_table_buffer: buffers.remove(0),
|
||||||
brickgrid_unpack_buffer: buffers.remove(0),
|
brickgrid_unpack_buffer: buffers.remove(0),
|
||||||
brickmap_unpack_buffer: buffers.remove(0),
|
brickmap_unpack_buffer: buffers.remove(0),
|
||||||
|
@ -150,7 +144,7 @@ impl BrickmapManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_brickmap_buffer(&self) -> &wgpu::Buffer {
|
pub fn get_brickmap_buffer(&self) -> &wgpu::Buffer {
|
||||||
&self.brickmap_buffer
|
&self.brickmap_cache.buffer
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_shading_buffer(&self) -> &wgpu::Buffer {
|
pub fn get_shading_buffer(&self) -> &wgpu::Buffer {
|
||||||
|
@ -198,8 +192,7 @@ impl BrickmapManager {
|
||||||
// TODO: Why do we call this here rather than doing it outside of here?
|
// TODO: Why do we call this here rather than doing it outside of here?
|
||||||
self.upload_unpack_buffers(context);
|
self.upload_unpack_buffers(context);
|
||||||
|
|
||||||
// TODO: This is inaccurate if we've looped
|
log::info!("Num loaded brickmaps: {}", self.brickmap_cache.num_loaded);
|
||||||
log::info!("Num loaded brickmaps: {}", self.brickmap_cache_idx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_request(&mut self, world: &mut WorldManager, data: &[u32]) {
|
fn handle_request(&mut self, world: &mut WorldManager, data: &[u32]) {
|
||||||
|
@ -224,30 +217,24 @@ impl BrickmapManager {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the brickgrid index
|
|
||||||
self.update_brickgrid_element(
|
|
||||||
grid_idx,
|
|
||||||
Self::to_brickgrid_element(self.brickmap_cache_idx as u32, BrickgridFlag::Loaded),
|
|
||||||
);
|
|
||||||
|
|
||||||
// If there's already something in the cache spot we want to write to, we
|
|
||||||
// need to unload it.
|
|
||||||
if self.brickmap_cache_map[self.brickmap_cache_idx].is_some() {
|
|
||||||
let entry = self.brickmap_cache_map[self.brickmap_cache_idx].unwrap();
|
|
||||||
self.update_brickgrid_element(entry.grid_idx, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the shading table
|
// Update the shading table
|
||||||
let shading_idx = self
|
let shading_idx = self
|
||||||
.shading_table_allocator
|
.shading_table_allocator
|
||||||
.try_alloc(albedo_data.len() as u32)
|
.try_alloc(albedo_data.len() as u32)
|
||||||
.unwrap() as usize;
|
.unwrap() as usize;
|
||||||
|
|
||||||
// We're all good to overwrite the cache map entry now :)
|
if let Some(entry) = self.brickmap_cache.add_entry(grid_idx, shading_idx as u32) {
|
||||||
self.brickmap_cache_map[self.brickmap_cache_idx] = Some(BrickmapCacheEntry {
|
// TODO: Currently this is broken!!
|
||||||
|
// We removed the entry, then when updating the brickgrid we go and remove the NEW entry!!!
|
||||||
|
// Need to think about this
|
||||||
|
self.update_brickgrid_element(entry.grid_idx, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the brickgrid index
|
||||||
|
self.update_brickgrid_element(
|
||||||
grid_idx,
|
grid_idx,
|
||||||
shading_table_offset: shading_idx as u32,
|
Self::to_brickgrid_element(self.brickmap_cache.index as u32, BrickgridFlag::Loaded),
|
||||||
});
|
);
|
||||||
|
|
||||||
// Update the brickmap
|
// Update the brickmap
|
||||||
let brickmap = Brickmap {
|
let brickmap = Brickmap {
|
||||||
|
@ -261,13 +248,12 @@ impl BrickmapManager {
|
||||||
shading_elements[..shading_element_count].copy_from_slice(&albedo_data);
|
shading_elements[..shading_element_count].copy_from_slice(&albedo_data);
|
||||||
|
|
||||||
let staged_brickmap = BrickmapUnpackElement {
|
let staged_brickmap = BrickmapUnpackElement {
|
||||||
cache_idx: self.brickmap_cache_idx as u32,
|
cache_idx: self.brickmap_cache.index as u32,
|
||||||
brickmap,
|
brickmap,
|
||||||
shading_element_count: shading_element_count as u32,
|
shading_element_count: shading_element_count as u32,
|
||||||
shading_elements,
|
shading_elements,
|
||||||
};
|
};
|
||||||
self.brickmap_staged.push(staged_brickmap);
|
self.brickmap_staged.push(staged_brickmap);
|
||||||
self.brickmap_cache_idx = (self.brickmap_cache_idx + 1) % self.brickmap_cache_map.len();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_brickgrid_element(&mut self, index: usize, data: u32) {
|
fn update_brickgrid_element(&mut self, index: usize, data: u32) {
|
||||||
|
@ -276,8 +262,7 @@ impl BrickmapManager {
|
||||||
// is marked as None.
|
// is marked as None.
|
||||||
if (self.brickgrid[index] & 0xF) == 4 {
|
if (self.brickgrid[index] & 0xF) == 4 {
|
||||||
let brickmap_idx = (self.brickgrid[index] >> 8) as usize;
|
let brickmap_idx = (self.brickgrid[index] >> 8) as usize;
|
||||||
let cache_map_entry = self.brickmap_cache_map[brickmap_idx];
|
match self.brickmap_cache.remove_entry(brickmap_idx) {
|
||||||
match cache_map_entry {
|
|
||||||
Some(entry) => {
|
Some(entry) => {
|
||||||
match self
|
match self
|
||||||
.shading_table_allocator
|
.shading_table_allocator
|
||||||
|
@ -286,7 +271,6 @@ impl BrickmapManager {
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
Err(e) => log::warn!("{}", e),
|
Err(e) => log::warn!("{}", e),
|
||||||
}
|
}
|
||||||
self.brickmap_cache_map[brickmap_idx] = None;
|
|
||||||
}
|
}
|
||||||
None => log::warn!("Expected brickmap cache entry, found None!"),
|
None => log::warn!("Expected brickmap cache entry, found None!"),
|
||||||
}
|
}
|
||||||
|
@ -471,3 +455,68 @@ impl BrickmapManager {
|
||||||
(chunk_pos.as_ivec3(), block_pos.as_uvec3())
|
(chunk_pos.as_ivec3(), block_pos.as_uvec3())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct BrickmapCache {
|
||||||
|
buffer: wgpu::Buffer,
|
||||||
|
cache: Vec<Option<BrickmapCacheEntry>>,
|
||||||
|
index: usize,
|
||||||
|
num_loaded: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BrickmapCache {
|
||||||
|
fn new(context: &gfx::Context, size: usize) -> Self {
|
||||||
|
let buffer_data = vec![Brickmap::default(); size];
|
||||||
|
let buffer = gfx::BulkBufferBuilder::new()
|
||||||
|
.set_usage(wgpu::BufferUsages::STORAGE | wgpu::BufferUsages::COPY_DST)
|
||||||
|
.with_init_buffer_bm("Brickmap Cache", &buffer_data)
|
||||||
|
.build(context)
|
||||||
|
.remove(0);
|
||||||
|
|
||||||
|
Self {
|
||||||
|
buffer,
|
||||||
|
cache: vec![None; size],
|
||||||
|
index: 0,
|
||||||
|
num_loaded: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Adds a brickmap entry and returns the entry that was overwritten.
|
||||||
|
fn add_entry(
|
||||||
|
&mut self,
|
||||||
|
grid_idx: usize,
|
||||||
|
shading_table_offset: u32,
|
||||||
|
) -> Option<BrickmapCacheEntry> {
|
||||||
|
// We do this first because we want this to be the index of the most recently added entry
|
||||||
|
// This has the side effect of meaning that on the first loop through the cache the first
|
||||||
|
// entry is empty, but it's fine.
|
||||||
|
self.index = (self.index + 1) % self.cache.len();
|
||||||
|
|
||||||
|
let existing_entry = self.cache[self.index];
|
||||||
|
if existing_entry.is_none() {
|
||||||
|
self.num_loaded += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.cache[self.index] = Some(BrickmapCacheEntry {
|
||||||
|
grid_idx,
|
||||||
|
shading_table_offset,
|
||||||
|
});
|
||||||
|
|
||||||
|
existing_entry
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Remove an entry from the cache and return it
|
||||||
|
fn remove_entry(&mut self, index: usize) -> Option<BrickmapCacheEntry> {
|
||||||
|
let entry = self.cache[index];
|
||||||
|
if entry.is_some() {
|
||||||
|
self.cache[index] = None;
|
||||||
|
self.num_loaded -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
entry
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_entry(&self, index: usize) -> Option<BrickmapCacheEntry> {
|
||||||
|
self.cache[index]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue