Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 3 additions & 14 deletions wgpu-core/src/device/global.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2064,7 +2064,7 @@ impl Global {
self.hub.queues.remove(queue_id);
}

/// `op.callback` is guaranteed to be called.
/// `op.callback` is always called, even in case of errors.
pub fn buffer_map_async(
&self,
buffer_id: id::BufferId,
Expand All @@ -2077,20 +2077,9 @@ impl Global {

let hub = &self.hub;

let map_result = match hub.buffers.get(buffer_id).get() {
Ok(buffer) => buffer.map_async(offset, size, op),
Err(e) => Err((op, e.into())),
};
let buffer = hub.buffers.get(buffer_id).get()?;

match map_result {
Ok(submission_index) => Ok(submission_index),
Err((mut operation, err)) => {
if let Some(callback) = operation.callback.take() {
callback(Err(err.clone()));
}
Err(err)
}
}
buffer.map_async(offset, size, op)
}

pub fn buffer_get_mapped_range(
Expand Down
5 changes: 4 additions & 1 deletion wgpu-core/src/device/life.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,8 +219,11 @@ impl LifetimeTracker {
});
}

/// Schedule a buffer for mapping.
///
/// The buffer will be added either to a pending submission, or to `self.ready_to_map`.
/// If it is added to a pending submission, returns the index of that submission.
pub(crate) fn map(&mut self, buffer: &Arc<Buffer>) -> Option<SubmissionIndex> {
// Determine which buffers are ready to map, and which must wait for the GPU.
let submission = self
.active
.iter_mut()
Expand Down
43 changes: 41 additions & 2 deletions wgpu-core/src/resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -591,13 +591,52 @@ impl Buffer {
))
}

/// Returns the mapping callback in case of error so that the callback can be fired outside
/// of the locks that are held in this function.
/// Schedule buffer mapping.
///
/// `op.callback` is guaranteed to be called, regardless of the outcome.
pub fn map_async(
self: &Arc<Self>,
offset: wgt::BufferAddress,
size: Option<wgt::BufferAddress>,
op: BufferMapOperation,
) -> Result<SubmissionIndex, BufferAccessError> {
self.try_map_async(offset, size, op)
.map_err(|(mut operation, err)| {
if let Some(callback) = operation.callback.take() {
callback(Err(err.clone()));
}
err
})
}

/// Try to schedule buffer mapping.
///
/// The outcome of this function is one of the following:
/// - If there is a queue, and nothing pending in the queue that uses the
/// buffer in question, the buffer is added to `Queue::ready_to_map`, and
/// will be mapped the next time `Device::maintain` is called. The
/// queue assumes responsibility for calling the callback, and this
/// function returns `Ok(0)`, but the buffer has not yet been mapped.
/// - If there is a queue, and something is pending in the queue that uses
/// the buffer in question, the buffer is scheduled for mapping after that
/// submission completes. The queue assumes responsibility for calling the
/// callback, and this function returns `Ok(index)` with the index of the
/// submission that must complete. The buffer has not yet been mapped.
/// - If there is no queue, the buffer is mapped and the callback is called
/// immediately. The return value is `Ok(0)`.
/// - Regardless of the queue state, if there is an error that terminates
/// the buffer mapping attempt, this function returns the callback along
/// with the error, and the caller is responsible for calling the
/// callback.
///
/// A return value of `Ok(0)` roughly means that no wait is necessary,
/// but it does not necessarily mean that the buffer has already been
/// mapped.
fn try_map_async(
self: &Arc<Self>,
offset: wgt::BufferAddress,
size: Option<wgt::BufferAddress>,
op: BufferMapOperation,
) -> Result<SubmissionIndex, (BufferMapOperation, BufferAccessError)> {
let range_size = if let Some(size) = size {
size
Expand Down