mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-22 06:44:14 +00:00
buffer_map_async should use offset + size (#5185)
This commit is contained in:
parent
990324fc33
commit
3028972817
@ -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,
|
||||||
|
@ -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(
|
||||||
|
@ -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);
|
||||||
|
@ -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")
|
||||||
|
Loading…
Reference in New Issue
Block a user