Compare commits
	
		
			No commits in common. "a6d89fb2e571df50fedffab4bc56e64dedc610c1" and "956fdd180ff19091f1d6bf9a7b5fae9df4c7689f" have entirely different histories.
		
	
	
		
			a6d89fb2e5
			...
			956fdd180f
		
	
		|  | @ -1,6 +1,9 @@ | |||
| use std::collections::HashSet; | ||||
| 
 | ||||
| use crate::gfx::{BulkBufferBuilder, Context}; | ||||
| use crate::{ | ||||
|     gfx::{BulkBufferBuilder, Context}, | ||||
|     math, | ||||
| }; | ||||
| 
 | ||||
| #[derive(Debug, Clone, Copy, PartialEq)] | ||||
| pub enum BrickgridFlag { | ||||
|  | @ -75,15 +78,9 @@ impl Brickgrid { | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub fn get_buffer(&self) -> &wgpu::Buffer { | ||||
|         &self.buffer | ||||
|     } | ||||
| 
 | ||||
|     pub fn get_upload_buffer(&self) -> &wgpu::Buffer { | ||||
|         &self.upload_buffer | ||||
|     } | ||||
| 
 | ||||
|     /// Panics if index out of range
 | ||||
|     /// Panics if position maps to out of range index
 | ||||
|     // pub fn set(&mut self, pos: glam::UVec3, value: BrickgridElement) -> BrickgridElement {
 | ||||
|     //      let index = math::to_1d_index(pos, self.dimensions);
 | ||||
|     pub fn set(&mut self, index: usize, value: BrickgridElement) -> BrickgridElement { | ||||
|         let current = self.data[index]; | ||||
|         self.data[index] = value; | ||||
|  | @ -91,7 +88,9 @@ impl Brickgrid { | |||
|         current | ||||
|     } | ||||
| 
 | ||||
|     /// Panics if index out of range
 | ||||
|     /// Panics if position maps to out of range index
 | ||||
|     // pub fn get(&mut self, pos: glam::UVec3) -> BrickgridElement {
 | ||||
|     //     let index = math::to_1d_index(pos, self.dimensions);
 | ||||
|     pub fn get(&mut self, index: usize) -> BrickgridElement { | ||||
|         self.data[index] | ||||
|     } | ||||
|  | @ -129,4 +128,12 @@ impl Brickgrid { | |||
|             ); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub fn get_buffer(&self) -> &wgpu::Buffer { | ||||
|         &self.buffer | ||||
|     } | ||||
| 
 | ||||
|     pub fn get_upload_buffer(&self) -> &wgpu::Buffer { | ||||
|         &self.upload_buffer | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -6,7 +6,7 @@ use crate::{ | |||
| 
 | ||||
| use super::{ | ||||
|     brickgrid::{Brickgrid, BrickgridElement, BrickgridFlag}, | ||||
|     brickmap_cache::BrickmapCache, | ||||
|     brickmap_cache::{BrickmapCache, BrickmapCacheEntry}, | ||||
|     shading_table::ShadingTableAllocator, | ||||
| }; | ||||
| 
 | ||||
|  | @ -166,63 +166,69 @@ impl BrickmapManager { | |||
|         let grid_pos = grid_pos.as_ivec3(); | ||||
|         let (bitmask_data, albedo_data) = super::util::cull_interior_voxels(world, grid_pos); | ||||
| 
 | ||||
|         let mut brickgrid_element = BrickgridElement::default(); | ||||
|         // If there's no voxel colour data post-culling it means the brickmap is
 | ||||
|         // empty. We don't need to upload it, just mark the relevant brickgrid entry.
 | ||||
|         if albedo_data.is_empty() { | ||||
|             if let Some(entry) = self.update_brickgrid_element(grid_idx, 0) { | ||||
|                 // TODO: We need to actually remove the cache entry lmao
 | ||||
|                 // The brickgrid element had a brickmap entry so we need to unload it's
 | ||||
|                 // shading data
 | ||||
|                 if let Err(e) = self | ||||
|                     .shading_table_allocator | ||||
|                     .try_dealloc(entry.shading_table_offset) | ||||
|                 { | ||||
|                     log::warn!("{}", e) | ||||
|                 } | ||||
|             } | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         // We have voxel data so we have a brickmap to upload
 | ||||
|         if !albedo_data.is_empty() { | ||||
|             let shading_idx = self | ||||
|         // Update the shading table
 | ||||
|         let shading_idx = self | ||||
|             .shading_table_allocator | ||||
|             .try_alloc(albedo_data.len() as u32) | ||||
|             .unwrap() as usize; | ||||
| 
 | ||||
|         if let Some(entry) = | ||||
|             self.brickmap_cache | ||||
|                 .add_entry(grid_idx, shading_idx as u32, bitmask_data, albedo_data) | ||||
|         { | ||||
|             self.update_brickgrid_element(entry.grid_idx, 1); | ||||
|         } | ||||
| 
 | ||||
|         // Update the brickgrid index
 | ||||
|         if let Some(old_entry) = self.update_brickgrid_element( | ||||
|             grid_idx, | ||||
|             super::util::to_brickgrid_element( | ||||
|                 self.brickmap_cache.index as u32, | ||||
|                 BrickgridFlag::Loaded, | ||||
|             ), | ||||
|         ) { | ||||
|             // TODO: We need to actually remove the cache entry lmao
 | ||||
|             // The brickgrid element had a brickmap entry so we need to unload it's
 | ||||
|             // shading data
 | ||||
|             if let Err(e) = self | ||||
|                 .shading_table_allocator | ||||
|                 .try_alloc(albedo_data.len() as u32) | ||||
|                 .unwrap() as usize; | ||||
| 
 | ||||
|             if let Some(entry) = self.brickmap_cache.add_entry( | ||||
|                 grid_idx, | ||||
|                 shading_idx as u32, | ||||
|                 bitmask_data, | ||||
|                 albedo_data, | ||||
|             ) { | ||||
|                 // An entry got removed so we need to deallocate it's shading table elements
 | ||||
|                 // and mark the relevant brickgrid as unloaded
 | ||||
|                 if let Err(e) = self | ||||
|                     .shading_table_allocator | ||||
|                     .try_dealloc(entry.shading_table_offset) | ||||
|                 { | ||||
|                     log::warn!("{}", e) | ||||
|                 } | ||||
|                 self.brickgrid.set( | ||||
|                     entry.grid_idx, | ||||
|                     BrickgridElement::new(0, BrickgridFlag::Unloaded), | ||||
|                 ); | ||||
|             } | ||||
| 
 | ||||
|             brickgrid_element = | ||||
|                 BrickgridElement::new(self.brickmap_cache.index, BrickgridFlag::Loaded); | ||||
|         } | ||||
| 
 | ||||
|         let old = self.brickgrid.set(grid_idx, brickgrid_element); | ||||
|         if old.get_flag() == BrickgridFlag::Loaded { | ||||
|             // The brickgrid element was previously loaded so we need to unload any of
 | ||||
|             // the data that was associated with it
 | ||||
|             if let Some(entry) = self.brickmap_cache.remove_entry(old.get_pointer()) { | ||||
|                 if entry.grid_idx != grid_idx { | ||||
|                     log::error!( | ||||
|                         "Mismatch between brickgrid index and brickmap grid index: {} vs {}", | ||||
|                         grid_idx, | ||||
|                         entry.grid_idx | ||||
|                     ); | ||||
|                 } | ||||
| 
 | ||||
|                 // We need to deallocate the removed entries shading table elements
 | ||||
|                 if let Err(e) = self | ||||
|                     .shading_table_allocator | ||||
|                     .try_dealloc(entry.shading_table_offset) | ||||
|                 { | ||||
|                     log::warn!("{}", e) | ||||
|                 } | ||||
|                 .try_dealloc(old_entry.shading_table_offset) | ||||
|             { | ||||
|                 log::warn!("{}", e) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn update_brickgrid_element(&mut self, index: usize, data: u32) -> Option<BrickmapCacheEntry> { | ||||
|         let mut brickmap_cache_entry = None; | ||||
|         let current = self.brickgrid.get(index); | ||||
|         if current.get_flag() == BrickgridFlag::Loaded { | ||||
|             let cache_index = current.get_pointer(); | ||||
|             brickmap_cache_entry = self.brickmap_cache.get_entry(cache_index); | ||||
|         } | ||||
| 
 | ||||
|         // We're safe to overwrite the CPU brickgrid and mark for GPU upload now
 | ||||
|         self.brickgrid.set(index, BrickgridElement(data)); | ||||
|         brickmap_cache_entry | ||||
|     } | ||||
| 
 | ||||
|     fn upload_unpack_buffers(&mut self, context: &gfx::Context) { | ||||
|         self.brickgrid.upload(context); | ||||
|         self.brickmap_cache.upload(context); | ||||
|  |  | |||
|  | @ -1,5 +1,7 @@ | |||
| use crate::voxel::world::{Voxel, WorldManager}; | ||||
| 
 | ||||
| use super::brickgrid::BrickgridFlag; | ||||
| 
 | ||||
| pub fn cull_interior_voxels( | ||||
|     world: &mut WorldManager, | ||||
|     grid_pos: glam::IVec3, | ||||
|  | @ -101,6 +103,10 @@ pub fn cull_interior_voxels( | |||
|     (bitmask_data, albedo_data) | ||||
| } | ||||
| 
 | ||||
| pub fn to_brickgrid_element(brickmap_cache_idx: u32, flags: BrickgridFlag) -> u32 { | ||||
|     (brickmap_cache_idx << 8) + flags as u32 | ||||
| } | ||||
| 
 | ||||
| pub fn grid_pos_to_world_pos( | ||||
|     world: &mut WorldManager, | ||||
|     grid_pos: glam::IVec3, | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue