summaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2025-01-27 01:47:54 +0100
committermetamuffin <metamuffin@disroot.org>2025-01-27 01:47:54 +0100
commit3cc7df2954a6f1d69922ba1a4c0129db73a09327 (patch)
treedb30c0af70dc5ea68586072f3da0b1a21723dbf4 /client
parent724e6e4d97f608282e891742565b1036f3e970d5 (diff)
downloadweareserver-3cc7df2954a6f1d69922ba1a4c0129db73a09327.tar
weareserver-3cc7df2954a6f1d69922ba1a4c0129db73a09327.tar.bz2
weareserver-3cc7df2954a6f1d69922ba1a4c0129db73a09327.tar.zst
parallel texture loading which deadlocks wgpu -_-
Diffstat (limited to 'client')
-rw-r--r--client/Cargo.toml5
-rw-r--r--client/src/main.rs20
-rw-r--r--client/src/render/scene/textures.rs84
3 files changed, 73 insertions, 36 deletions
diff --git a/client/Cargo.toml b/client/Cargo.toml
index 762e711..4a22bf6 100644
--- a/client/Cargo.toml
+++ b/client/Cargo.toml
@@ -23,3 +23,8 @@ bytemuck = "1.21.0"
xdg = "2.5.2"
nnnoiseless = "0.5.1"
humansize = "2.1.3"
+rayon = "1.10.0"
+parking_lot = "0.12.3"
+
+[features]
+deadlock_detection = ["parking_lot/deadlock_detection"]
diff --git a/client/src/main.rs b/client/src/main.rs
index e5141c7..804ab44 100644
--- a/client/src/main.rs
+++ b/client/src/main.rs
@@ -46,6 +46,9 @@ fn main() -> Result<()> {
env_logger::init_from_env("LOG");
let args = Args::parse();
+ #[cfg(feature = "deadlock_detection")]
+ std::thread::spawn(deadlock_task);
+
info!("connecting...");
let mut sock = TcpStream::connect(args.address)?;
Packet::Connect(random()).write(&mut sock)?;
@@ -56,3 +59,20 @@ fn main() -> Result<()> {
Ok(())
}
+
+#[cfg(feature = "deadlock_detection")]
+fn deadlock_task() {
+ let deadlocks = loop {
+ std::thread::sleep(std::time::Duration::from_secs(1));
+ let deadlocks = parking_lot::deadlock::check_deadlock();
+ if !deadlocks.is_empty() {
+ break deadlocks;
+ }
+ };
+ for threads in &deadlocks {
+ for t in threads {
+ println!("thread {:#?}", t.thread_id());
+ println!("{:#?}", t.backtrace());
+ }
+ }
+}
diff --git a/client/src/render/scene/textures.rs b/client/src/render/scene/textures.rs
index c385be2..2da84be 100644
--- a/client/src/render/scene/textures.rs
+++ b/client/src/render/scene/textures.rs
@@ -18,7 +18,12 @@ use super::{GraphicsConfig, ScenePreparer, TextureIdentityKind};
use anyhow::Result;
use image::ImageReader;
use log::debug;
-use std::{io::Cursor, sync::Arc, time::Instant};
+use rayon::iter::{IntoParallelIterator, ParallelIterator};
+use std::{
+ io::Cursor,
+ sync::{Arc, atomic::AtomicUsize},
+ time::Instant,
+};
use wgpu::{
AddressMode, BindGroup, BindGroupDescriptor, BindGroupEntry, BindGroupLayout, BindingResource,
Color, ColorTargetState, ColorWrites, CommandEncoderDescriptor, Device, Extent3d, FilterMode,
@@ -99,42 +104,49 @@ impl ScenePreparer {
self.placeholder_textures.insert(kind, tex_bg, 4);
*num_done += 1;
}
- for spec in self.textures.needed() {
- let start = Instant::now();
- let format = if spec.linear {
- TextureFormat::Rgba8Unorm
- } else {
- TextureFormat::Rgba8UnormSrgb
- };
- if let Some(mipgen) = self.mip_generation_pipelines.try_get(format) {
- if let Some(buf) = self.downloader.try_get(spec.data.clone())? {
- let image = ImageReader::new(Cursor::new(buf.0)).with_guessed_format()?;
- let image = image.decode()?;
- let dims = (image.width(), image.height());
- let image = image.into_rgba8();
- let image = image.into_vec();
- let tex_bg = create_texture(
- &self.device,
- &self.queue,
- &self.layouts.texture,
- &image,
- dims.0,
- dims.1,
- format,
- Some(&mipgen),
- &self.config.read().unwrap().clone(),
- );
- self.textures.insert(spec, tex_bg, image.len());
- debug!(
- "texture created (res={}x{}, took {:?})",
- dims.0,
- dims.1,
- start.elapsed()
- );
- *num_done += 1;
+
+ let numdone = AtomicUsize::new(0);
+ self.textures
+ .needed()
+ .into_par_iter()
+ .try_for_each(|spec| {
+ let start = Instant::now();
+ let format = if spec.linear {
+ TextureFormat::Rgba8Unorm
+ } else {
+ TextureFormat::Rgba8UnormSrgb
+ };
+ if let Some(mipgen) = self.mip_generation_pipelines.try_get(format) {
+ if let Some(buf) = self.downloader.try_get(spec.data.clone())? {
+ let image = ImageReader::new(Cursor::new(buf.0)).with_guessed_format()?;
+ let image = image.decode()?;
+ let dims = (image.width(), image.height());
+ let image = image.into_rgba8();
+ let image = image.into_vec();
+ let tex_bg = create_texture(
+ &self.device,
+ &self.queue,
+ &self.layouts.texture,
+ &image,
+ dims.0,
+ dims.1,
+ format,
+ Some(&mipgen),
+ &self.config.read().unwrap().clone(),
+ );
+ self.textures.insert(spec, tex_bg, image.len());
+ debug!(
+ "texture created (res={}x{}, took {:?})",
+ dims.0,
+ dims.1,
+ start.elapsed()
+ );
+ numdone.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
+ }
}
- }
- }
+ Ok::<(), anyhow::Error>(())
+ })?;
+ *num_done += numdone.load(std::sync::atomic::Ordering::Relaxed);
Ok(())
}
}