summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLizzy Fleckenstein <eliasfleckenstein@web.de>2023-05-15 16:21:58 +0200
committerLizzy Fleckenstein <eliasfleckenstein@web.de>2023-05-15 16:21:58 +0200
commitf1e5cdf25d1fd905fa307232124c361851b51758 (patch)
tree7d7038eb33cc35874a164788021b33c87a1aa928 /src
parent5e6154154c12481a2f3377fa99e6935fef1b952f (diff)
downloadmt_client-f1e5cdf25d1fd905fa307232124c361851b51758.tar.xz
Mulithreaded meshgen
Diffstat (limited to 'src')
-rw-r--r--src/gfx/map.rs61
-rw-r--r--src/gfx/map/mesh.rs27
2 files changed, 45 insertions, 43 deletions
diff --git a/src/gfx/map.rs b/src/gfx/map.rs
index dfc41be..3d49afd 100644
--- a/src/gfx/map.rs
+++ b/src/gfx/map.rs
@@ -9,7 +9,7 @@ use mt_net::{MapBlock, NodeDef};
use serde::{Deserialize, Serialize};
use std::{
collections::HashMap,
- ops::DerefMut,
+ ops::{Deref, DerefMut},
sync::{Arc, Mutex},
};
use wgpu::util::DeviceExt;
@@ -41,7 +41,8 @@ struct AtlasSlice {
cube_tex_coords: [[[f32; 2]; 6]; 6],
}
-struct MeshMakeInfo {
+// data shared with meshgen threads
+struct MeshgenInfo {
// i optimized the shit out of these
textures: Vec<AtlasSlice>,
nodes: [Option<Box<NodeDef>>; u16::MAX as usize + 1],
@@ -54,8 +55,9 @@ pub struct MapRender {
atlas: wgpu::BindGroup,
model: wgpu::BindGroupLayout,
blocks: HashMap<[i16; 3], BlockModel>,
- mesh_make_info: Arc<MeshMakeInfo>,
- mesh_data_buffer: Mutex<usize>,
+ meshgen_info: Arc<MeshgenInfo>,
+ meshgen_threads: Vec<std::thread::JoinHandle<()>>,
+ meshgen_channel: crossbeam_channel::Sender<(Point3<i16>, Box<MapBlock>)>,
queue_consume: MeshQueue,
queue_produce: Arc<Mutex<MeshQueue>>,
}
@@ -191,15 +193,8 @@ impl MapRender {
}
pub fn add_block(&self, pos: Point3<i16>, block: Box<MapBlock>) {
- let (pos, data) = create_mesh(
- &mut self.mesh_data_buffer.lock().unwrap(),
- self.mesh_make_info.clone(),
- &Default::default(),
- pos,
- block,
- );
-
- self.queue_produce.lock().unwrap().insert(pos, data);
+ // FIXME: received mapblocks are propagated twice: network -> gfx -> meshgen
+ self.meshgen_channel.send((pos, block)).ok();
}
pub fn new(state: &mut State, media: &MediaMgr, mut nodes: HashMap<u16, NodeDef>) -> Self {
@@ -354,18 +349,44 @@ impl MapRender {
multiview: None,
});
+ let meshgen_queue = Arc::new(Mutex::new(HashMap::new()));
+ let meshgen_info = Arc::new(MeshgenInfo {
+ nodes: std::array::from_fn(|i| nodes.get(&(i as u16)).cloned().map(Box::new)),
+ textures: atlas_slices,
+ });
+ let mut meshgen_threads = Vec::new();
+ let (meshgen_tx, meshgen_rx) = crossbeam_channel::unbounded();
+
+ // TODO: make this configurable
+ for _ in 0..2 {
+ let input = meshgen_rx.clone();
+ let output = meshgen_queue.clone();
+ let info = meshgen_info.clone();
+ let config = Default::default();
+
+ meshgen_threads.push(std::thread::spawn(move || {
+ let mut buffer_cap = 0;
+ let info = info.deref();
+
+ while let Ok((pos, block)) = input.recv() {
+ let mut data = MeshData::new(buffer_cap);
+ create_mesh(info, &config, pos, block, &mut data);
+ buffer_cap = data.cap();
+ output.lock().unwrap().insert(pos, data);
+ }
+ }));
+ }
+
Self {
pipeline,
- mesh_make_info: Arc::new(MeshMakeInfo {
- nodes: std::array::from_fn(|i| nodes.get(&(i as u16)).cloned().map(Box::new)),
- textures: atlas_slices,
- }),
- mesh_data_buffer: Mutex::new(0),
atlas: atlas_bind_group,
model: model_bind_group_layout,
blocks: HashMap::new(),
- queue_consume: HashMap::new(),
- queue_produce: Arc::new(Mutex::new(HashMap::new())),
+ meshgen_info,
+ meshgen_threads,
+ meshgen_channel: meshgen_tx,
+ queue_consume: HashMap::new(), // store this to keep capacity/allocations around
+ queue_produce: meshgen_queue,
}
}
}
diff --git a/src/gfx/map/mesh.rs b/src/gfx/map/mesh.rs
index 0befb1e..3f8dcbc 100644
--- a/src/gfx/map/mesh.rs
+++ b/src/gfx/map/mesh.rs
@@ -1,8 +1,6 @@
-use super::{LeavesMode, MapRenderSettings, MeshMakeInfo, Vertex, CUBE};
+use super::{LeavesMode, MapRenderSettings, MeshgenInfo, Vertex, CUBE};
use cgmath::Point3;
use mt_net::MapBlock;
-use std::ops::Deref;
-use std::sync::Arc;
#[derive(Clone)]
pub(super) struct MeshData {
@@ -24,15 +22,12 @@ impl MeshData {
}
pub(super) fn create_mesh(
- buffer_cap: &mut usize,
- mkinfo: Arc<MeshMakeInfo>,
+ mkinfo: &MeshgenInfo,
settings: &MapRenderSettings,
pos: Point3<i16>,
block: Box<MapBlock>,
-) -> (Point3<i16>, MeshData) {
- let mkinfo = mkinfo.deref();
- let mut buffer = MeshData::new(*buffer_cap);
-
+ buffer: &mut MeshData,
+) {
for (index, content) in block.param_0.iter().enumerate() {
let def = match &mkinfo.nodes[*content as usize] {
Some(x) => x,
@@ -85,17 +80,6 @@ pub(super) fn create_mesh(
let texture = mkinfo.textures[tile.texture.custom].cube_tex_coords[f];
let mut add_vertex = |vertex: (usize, &([f32; 3], [f32; 2]))| {
- /*println!(
- "{:?} {:?} {:?} {:?}",
- (vertex.1[0], vertex.1[1]),
- (rect[0].start, rect[1].start),
- (rect[0].end, rect[1].end),
- (
- vertex.1[0].lerp(rect[0].start, rect[0].end),
- vertex.1[1].lerp(rect[1].start, rect[1].end)
- )
- );*/
-
buffer.vertices.push(Vertex {
pos: array(|i| pos[i] as f32 - 8.5 + vertex.1 .0[i]),
tex_coords: texture[vertex.0],
@@ -109,9 +93,6 @@ pub(super) fn create_mesh(
}*/
}
}
-
- *buffer_cap = buffer.cap();
- (pos, buffer)
}
#[rustfmt::skip]