Remove flume dependency of wgpu (#4585)

* Remove `flume` dependency of `wgpu`

* Add `Exclusive`
This commit is contained in:
Alphyr 2023-10-27 17:23:39 +02:00 committed by GitHub
parent 4c5a817071
commit 8998b9de87
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 25 additions and 11 deletions

1
Cargo.lock generated
View File

@ -4013,7 +4013,6 @@ version = "0.18.0"
dependencies = [
"arrayvec 0.7.4",
"cfg-if",
"flume",
"js-sys",
"log",
"naga",

View File

@ -103,7 +103,6 @@ optional = true
[dependencies]
arrayvec.workspace = true
cfg-if.workspace = true
flume.workspace = true
log.workspace = true
parking_lot.workspace = true
profiling.workspace = true

View File

@ -3,7 +3,7 @@ use crate::{
BufferViewMut, CommandEncoder, Device, MapMode,
};
use std::fmt;
use std::sync::Arc;
use std::sync::{mpsc, Arc};
struct Chunk {
buffer: Arc<Buffer>,
@ -11,6 +11,23 @@ struct Chunk {
offset: BufferAddress,
}
/// `Sync` wrapper that works by providing only exclusive access.
///
/// See https://doc.rust-lang.org/nightly/std/sync/struct.Exclusive.html
struct Exclusive<T>(T);
unsafe impl<T> Sync for Exclusive<T> {}
impl<T> Exclusive<T> {
fn new(value: T) -> Self {
Self(value)
}
fn get_mut(&mut self) -> &mut T {
&mut self.0
}
}
/// Efficiently performs many buffer writes by sharing and reusing temporary buffers.
///
/// Internally it uses a ring-buffer of staging buffers that are sub-allocated.
@ -36,9 +53,9 @@ pub struct StagingBelt {
/// into `active_chunks`.
free_chunks: Vec<Chunk>,
/// When closed chunks are mapped again, the map callback sends them here.
sender: flume::Sender<Chunk>,
sender: Exclusive<mpsc::Sender<Chunk>>,
/// Free chunks are received here to be put on `self.free_chunks`.
receiver: flume::Receiver<Chunk>,
receiver: Exclusive<mpsc::Receiver<Chunk>>,
}
impl StagingBelt {
@ -53,14 +70,14 @@ impl StagingBelt {
/// (per [`StagingBelt::finish()`]); and
/// * bigger is better, within these bounds.
pub fn new(chunk_size: BufferAddress) -> Self {
let (sender, receiver) = flume::unbounded();
let (sender, receiver) = std::sync::mpsc::channel();
StagingBelt {
chunk_size,
active_chunks: Vec::new(),
closed_chunks: Vec::new(),
free_chunks: Vec::new(),
sender,
receiver,
sender: Exclusive::new(sender),
receiver: Exclusive::new(receiver),
}
}
@ -148,9 +165,8 @@ impl StagingBelt {
pub fn recall(&mut self) {
self.receive_chunks();
let sender = &self.sender;
for chunk in self.closed_chunks.drain(..) {
let sender = sender.clone();
let sender = self.sender.get_mut().clone();
chunk
.buffer
.clone()
@ -164,7 +180,7 @@ impl StagingBelt {
/// Move all chunks that the GPU is done with (and are now mapped again)
/// from `self.receiver` to `self.free_chunks`.
fn receive_chunks(&mut self) {
while let Ok(mut chunk) = self.receiver.try_recv() {
while let Ok(mut chunk) = self.receiver.get_mut().try_recv() {
chunk.offset = 0;
self.free_chunks.push(chunk);
}