Skip to content

Commit

Permalink
StagingBelt: check for free chunks in the receiver as well as `free…
Browse files Browse the repository at this point in the history
…_chunks`.

Previously, chunks would only be taken from the GPU callback receiver
and put on `free_chunks` during `finish()`. So, there might be chunks
that are actually available for use but wouldn't be used.

Now, we consult the receiver whenever we're about to consult the
`free_chunks`, so the reuse of chunks will be as good as possible (given
the application's uses of operations that trigger `map_async` callbacks).
  • Loading branch information
kpreid committed Jul 21, 2022
1 parent 537c6be commit 5065969
Showing 1 changed file with 29 additions and 19 deletions.
48 changes: 29 additions & 19 deletions wgpu/src/util/belt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,23 +73,27 @@ impl StagingBelt {
.position(|chunk| chunk.offset + size.get() <= chunk.size)
{
self.active_chunks.swap_remove(index)
} else if let Some(index) = self
.free_chunks
.iter()
.position(|chunk| size.get() <= chunk.size)
{
self.free_chunks.swap_remove(index)
} else {
let size = self.chunk_size.max(size.get());
Chunk {
buffer: Arc::new(device.create_buffer(&BufferDescriptor {
label: Some("(wgpu internal) StagingBelt staging buffer"),
self.receive_chunks(); // ensure free_chunks is up to date

if let Some(index) = self
.free_chunks
.iter()
.position(|chunk| size.get() <= chunk.size)
{
self.free_chunks.swap_remove(index)
} else {
let size = self.chunk_size.max(size.get());
Chunk {
buffer: Arc::new(device.create_buffer(&BufferDescriptor {
label: Some("(wgpu internal) StagingBelt staging buffer"),
size,
usage: BufferUsages::MAP_WRITE | BufferUsages::COPY_SRC,
mapped_at_creation: true,
})),
size,
usage: BufferUsages::MAP_WRITE | BufferUsages::COPY_SRC,
mapped_at_creation: true,
})),
size,
offset: 0,
offset: 0,
}
}
};

Expand Down Expand Up @@ -121,10 +125,7 @@ impl StagingBelt {
///
/// This has to be called after the command encoders written to `write_buffer` are submitted!
pub fn recall(&mut self) {
while let Ok(mut chunk) = self.receiver.try_recv() {
chunk.offset = 0;
self.free_chunks.push(chunk);
}
self.receive_chunks();

let sender = &self.sender;
for chunk in self.closed_chunks.drain(..) {
Expand All @@ -138,6 +139,15 @@ 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() {
chunk.offset = 0;
self.free_chunks.push(chunk);
}
}
}

impl fmt::Debug for StagingBelt {
Expand Down

0 comments on commit 5065969

Please sign in to comment.