mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-25 16:24:24 +00:00
Remove flume
dependency of wgpu
(#4585)
* Remove `flume` dependency of `wgpu` * Add `Exclusive`
This commit is contained in:
parent
4c5a817071
commit
8998b9de87
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -4013,7 +4013,6 @@ version = "0.18.0"
|
||||
dependencies = [
|
||||
"arrayvec 0.7.4",
|
||||
"cfg-if",
|
||||
"flume",
|
||||
"js-sys",
|
||||
"log",
|
||||
"naga",
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user