call flush_mapped_ranges when unmapping write-mapped buffers

I'm not sure how things worked without this.
This commit is contained in:
teoxoy 2024-08-07 18:15:43 +02:00 committed by Erich Gubler
parent 94f54b3dc8
commit 5617f0fd17
5 changed files with 31 additions and 16 deletions

View File

@ -2418,7 +2418,9 @@ impl Global {
Ok((ptr, range_size))
}
resource::BufferMapState::Active {
ref ptr, ref range, ..
ref mapping,
ref range,
..
} => {
if offset < range.start {
return Err(BufferAccessError::OutOfBoundsUnderrun {
@ -2437,7 +2439,7 @@ impl Global {
let relative_offset = (offset - range.start) as isize;
unsafe {
Ok((
NonNull::new_unchecked(ptr.as_ptr().offset(relative_offset)),
NonNull::new_unchecked(mapping.ptr.as_ptr().offset(relative_offset)),
range_size,
))
}

View File

@ -391,10 +391,10 @@ impl<A: HalApi> LifetimeTracker<A> {
host,
snatch_guard,
) {
Ok(ptr) => {
Ok(mapping) => {
*buffer.map_state.lock() = resource::BufferMapState::Active {
ptr,
range: pending_mapping.range.start..pending_mapping.range.start + size,
mapping,
range: pending_mapping.range.clone(),
host,
};
Ok(())
@ -406,7 +406,10 @@ impl<A: HalApi> LifetimeTracker<A> {
}
} else {
*buffer.map_state.lock() = resource::BufferMapState::Active {
ptr: std::ptr::NonNull::dangling(),
mapping: hal::BufferMapping {
ptr: std::ptr::NonNull::dangling(),
is_coherent: true,
},
range: pending_mapping.range,
host: pending_mapping.op.host,
};

View File

@ -18,7 +18,7 @@ use std::os::raw::c_char;
use thiserror::Error;
use wgt::{BufferAddress, DeviceLostReason, TextureFormat};
use std::{iter, num::NonZeroU32, ptr};
use std::{iter, num::NonZeroU32};
pub mod any_device;
pub(crate) mod bgl;
@ -307,7 +307,7 @@ fn map_buffer<A: HalApi>(
size: BufferAddress,
kind: HostMap,
snatch_guard: &SnatchGuard,
) -> Result<ptr::NonNull<u8>, BufferAccessError> {
) -> Result<hal::BufferMapping, BufferAccessError> {
let raw_buffer = buffer.try_raw(snatch_guard)?;
let mapping = unsafe {
raw.map_buffer(raw_buffer, offset..offset + size)
@ -360,7 +360,7 @@ fn map_buffer<A: HalApi>(
}
}
Ok(mapping.ptr)
Ok(mapping)
}
#[derive(Clone, Debug)]

View File

@ -611,8 +611,11 @@ impl<A: HalApi> Device<A> {
} else if desc.usage.contains(wgt::BufferUsages::MAP_WRITE) {
// buffer is mappable, so we are just doing that at start
let map_size = buffer.size;
let ptr = if map_size == 0 {
std::ptr::NonNull::dangling()
let mapping = if map_size == 0 {
hal::BufferMapping {
ptr: std::ptr::NonNull::dangling(),
is_coherent: true,
}
} else {
let snatch_guard: SnatchGuard = self.snatchable_lock.read();
map_buffer(
@ -625,7 +628,7 @@ impl<A: HalApi> Device<A> {
)?
};
*buffer.map_state.lock() = resource::BufferMapState::Active {
ptr,
mapping,
range: 0..map_size,
host: HostMap::Write,
};

View File

@ -229,7 +229,7 @@ pub(crate) enum BufferMapState<A: HalApi> {
Waiting(BufferPendingMapping<A>),
/// Mapped
Active {
ptr: NonNull<u8>,
mapping: hal::BufferMapping,
range: hal::MemoryRange,
host: HostMap,
},
@ -669,13 +669,18 @@ impl<A: HalApi> Buffer<A> {
BufferMapState::Waiting(pending) => {
return Ok(Some((pending.op, Err(BufferAccessError::MapAborted))));
}
BufferMapState::Active { ptr, range, host } => {
BufferMapState::Active {
mapping,
range,
host,
} => {
#[allow(clippy::collapsible_if)]
if host == HostMap::Write {
#[cfg(feature = "trace")]
if let Some(ref mut trace) = *device.trace.lock() {
let size = range.end - range.start;
let data = trace.make_binary("bin", unsafe {
std::slice::from_raw_parts(ptr.as_ptr(), size as usize)
std::slice::from_raw_parts(mapping.ptr.as_ptr(), size as usize)
});
trace.add(trace::Action::WriteBuffer {
id: buffer_id,
@ -684,7 +689,9 @@ impl<A: HalApi> Buffer<A> {
queued: false,
});
}
let _ = (ptr, range);
if !mapping.is_coherent {
unsafe { device.raw().flush_mapped_ranges(raw_buf, iter::once(range)) };
}
}
unsafe { device.raw().unmap_buffer(raw_buf) };
}