buffer_map_async should use offset + size (#5185)

This commit is contained in:
andristarr 2024-02-09 09:48:00 +01:00 committed by GitHub
parent 990324fc33
commit 3028972817
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 48 additions and 25 deletions

View File

@ -98,7 +98,8 @@ pub async fn op_webgpu_buffer_get_map_async(
// TODO(lucacasonato): error handling
let maybe_err = gfx_select!(buffer => instance.buffer_map_async(
buffer,
offset..(offset + size),
offset,
Some(size),
wgpu_core::resource::BufferMapOperation {
host: match mode {
1 => wgpu_core::device::HostMap::Read,

View File

@ -131,7 +131,8 @@ impl Test<'_> {
let buffer = wgc::id::Id::zip(expect.buffer.index, expect.buffer.epoch, backend);
wgc::gfx_select!(device_id => global.buffer_map_async(
buffer,
expect.offset .. expect.offset+expect.data.len() as wgt::BufferAddress,
expect.offset,
Some(expect.data.len() as u64),
wgc::resource::BufferMapOperation {
host: wgc::device::HostMap::Read,
callback: Some(wgc::resource::BufferMapCallback::from_rust(

View File

@ -26,9 +26,7 @@ use wgt::{BufferAddress, TextureFormat};
use std::{
borrow::Cow,
iter,
ops::Range,
ptr,
iter, ptr,
sync::{atomic::Ordering, Arc},
};
@ -2336,15 +2334,18 @@ impl Global {
pub fn buffer_map_async<A: HalApi>(
&self,
buffer_id: id::BufferId,
range: Range<BufferAddress>,
offset: BufferAddress,
size: Option<BufferAddress>,
op: BufferMapOperation,
) -> BufferAccessResult {
api_log!("Buffer::map_async {buffer_id:?} range {range:?} op: {op:?}");
api_log!("Buffer::map_async {buffer_id:?} offset {offset:?} size {size:?} op: {op:?}");
// User callbacks must not be called while holding buffer_map_async_inner's locks, so we
// defer the error callback if it needs to be called immediately (typically when running
// into errors).
if let Err((mut operation, err)) = self.buffer_map_async_inner::<A>(buffer_id, range, op) {
if let Err((mut operation, err)) =
self.buffer_map_async_inner::<A>(buffer_id, offset, size, op)
{
if let Some(callback) = operation.callback.take() {
callback.call(Err(err.clone()));
}
@ -2360,7 +2361,8 @@ impl Global {
fn buffer_map_async_inner<A: HalApi>(
&self,
buffer_id: id::BufferId,
range: Range<BufferAddress>,
offset: BufferAddress,
size: Option<BufferAddress>,
op: BufferMapOperation,
) -> Result<(), (BufferMapOperation, BufferAccessError)> {
profiling::scope!("Buffer::map_async");
@ -2372,22 +2374,43 @@ impl Global {
HostMap::Write => (wgt::BufferUsages::MAP_WRITE, hal::BufferUses::MAP_WRITE),
};
if range.start % wgt::MAP_ALIGNMENT != 0 || range.end % wgt::COPY_BUFFER_ALIGNMENT != 0 {
return Err((op, BufferAccessError::UnalignedRange));
}
let buffer = {
let buffer = hub
.buffers
.get(buffer_id)
.map_err(|_| BufferAccessError::Invalid);
let buffer = hub.buffers.get(buffer_id);
let buffer = match buffer {
Ok(b) => b,
Err(e) => {
return Err((op, e));
Err(_) => {
return Err((op, BufferAccessError::Invalid));
}
};
{
let snatch_guard = buffer.device.snatchable_lock.read();
if buffer.is_destroyed(&snatch_guard) {
return Err((op, BufferAccessError::Destroyed));
}
}
let range_size = if let Some(size) = size {
size
} else if offset > buffer.size {
0
} else {
buffer.size - offset
};
if offset % wgt::MAP_ALIGNMENT != 0 {
return Err((op, BufferAccessError::UnalignedOffset { offset }));
}
if range_size % wgt::COPY_BUFFER_ALIGNMENT != 0 {
return Err((op, BufferAccessError::UnalignedRangeSize { range_size }));
}
let range = offset..(offset + range_size);
if range.start % wgt::MAP_ALIGNMENT != 0 || range.end % wgt::COPY_BUFFER_ALIGNMENT != 0
{
return Err((op, BufferAccessError::UnalignedRange));
}
let device = &buffer.device;
if !device.is_valid() {
@ -2417,11 +2440,6 @@ impl Global {
));
}
let snatch_guard = device.snatchable_lock.read();
if buffer.is_destroyed(&snatch_guard) {
return Err((op, BufferAccessError::Destroyed));
}
{
let map_state = &mut *buffer.map_state.lock();
*map_state = match *map_state {
@ -2442,6 +2460,8 @@ impl Global {
};
}
let snatch_guard = buffer.device.snatchable_lock.read();
{
let mut trackers = buffer.device.as_ref().trackers.lock();
trackers.buffers.set_single(&buffer, internal_use);

View File

@ -1453,7 +1453,8 @@ impl crate::Context for ContextWgpuCore {
))),
};
match wgc::gfx_select!(buffer => self.0.buffer_map_async(*buffer, range, operation)) {
match wgc::gfx_select!(buffer => self.0.buffer_map_async(*buffer, range.start, Some(range.end-range.start), operation))
{
Ok(()) => (),
Err(cause) => {
self.handle_error_nolabel(&buffer_data.error_sink, cause, "Buffer::map_async")