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 // TODO(lucacasonato): error handling
let maybe_err = gfx_select!(buffer => instance.buffer_map_async( let maybe_err = gfx_select!(buffer => instance.buffer_map_async(
buffer, buffer,
offset..(offset + size), offset,
Some(size),
wgpu_core::resource::BufferMapOperation { wgpu_core::resource::BufferMapOperation {
host: match mode { host: match mode {
1 => wgpu_core::device::HostMap::Read, 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); let buffer = wgc::id::Id::zip(expect.buffer.index, expect.buffer.epoch, backend);
wgc::gfx_select!(device_id => global.buffer_map_async( wgc::gfx_select!(device_id => global.buffer_map_async(
buffer, buffer,
expect.offset .. expect.offset+expect.data.len() as wgt::BufferAddress, expect.offset,
Some(expect.data.len() as u64),
wgc::resource::BufferMapOperation { wgc::resource::BufferMapOperation {
host: wgc::device::HostMap::Read, host: wgc::device::HostMap::Read,
callback: Some(wgc::resource::BufferMapCallback::from_rust( callback: Some(wgc::resource::BufferMapCallback::from_rust(

View File

@ -26,9 +26,7 @@ use wgt::{BufferAddress, TextureFormat};
use std::{ use std::{
borrow::Cow, borrow::Cow,
iter, iter, ptr,
ops::Range,
ptr,
sync::{atomic::Ordering, Arc}, sync::{atomic::Ordering, Arc},
}; };
@ -2336,15 +2334,18 @@ impl Global {
pub fn buffer_map_async<A: HalApi>( pub fn buffer_map_async<A: HalApi>(
&self, &self,
buffer_id: id::BufferId, buffer_id: id::BufferId,
range: Range<BufferAddress>, offset: BufferAddress,
size: Option<BufferAddress>,
op: BufferMapOperation, op: BufferMapOperation,
) -> BufferAccessResult { ) -> 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 // 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 // defer the error callback if it needs to be called immediately (typically when running
// into errors). // 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() { if let Some(callback) = operation.callback.take() {
callback.call(Err(err.clone())); callback.call(Err(err.clone()));
} }
@ -2360,7 +2361,8 @@ impl Global {
fn buffer_map_async_inner<A: HalApi>( fn buffer_map_async_inner<A: HalApi>(
&self, &self,
buffer_id: id::BufferId, buffer_id: id::BufferId,
range: Range<BufferAddress>, offset: BufferAddress,
size: Option<BufferAddress>,
op: BufferMapOperation, op: BufferMapOperation,
) -> Result<(), (BufferMapOperation, BufferAccessError)> { ) -> Result<(), (BufferMapOperation, BufferAccessError)> {
profiling::scope!("Buffer::map_async"); profiling::scope!("Buffer::map_async");
@ -2372,22 +2374,43 @@ impl Global {
HostMap::Write => (wgt::BufferUsages::MAP_WRITE, hal::BufferUses::MAP_WRITE), 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 = {
let buffer = hub let buffer = hub.buffers.get(buffer_id);
.buffers
.get(buffer_id)
.map_err(|_| BufferAccessError::Invalid);
let buffer = match buffer { let buffer = match buffer {
Ok(b) => b, Ok(b) => b,
Err(e) => { Err(_) => {
return Err((op, e)); 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; let device = &buffer.device;
if !device.is_valid() { 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(); let map_state = &mut *buffer.map_state.lock();
*map_state = match *map_state { *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(); let mut trackers = buffer.device.as_ref().trackers.lock();
trackers.buffers.set_single(&buffer, internal_use); 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(()) => (), Ok(()) => (),
Err(cause) => { Err(cause) => {
self.handle_error_nolabel(&buffer_data.error_sink, cause, "Buffer::map_async") self.handle_error_nolabel(&buffer_data.error_sink, cause, "Buffer::map_async")