simplify BufferMapCallback by removing its C variant

This commit is contained in:
teoxoy 2024-11-25 13:34:35 +01:00 committed by Teodor Tanasoaia
parent 8e4622b399
commit 13fbf30813
6 changed files with 21 additions and 137 deletions

View File

@ -108,7 +108,7 @@ pub async fn op_webgpu_buffer_get_map_async(
2 => wgpu_core::device::HostMap::Write,
_ => unreachable!(),
},
callback: Some(wgpu_core::resource::BufferMapCallback::from_rust(callback)),
callback: Some(callback),
},
)
.err();

View File

@ -144,9 +144,7 @@ impl Test<'_> {
Some(expect.data.len() as u64),
wgc::resource::BufferMapOperation {
host: wgc::device::HostMap::Read,
callback: Some(wgc::resource::BufferMapCallback::from_rust(Box::new(
map_callback,
))),
callback: Some(Box::new(map_callback)),
},
)
.unwrap();

View File

@ -2170,7 +2170,7 @@ impl Global {
Ok(submission_index) => Ok(submission_index),
Err((mut operation, err)) => {
if let Some(callback) = operation.callback.take() {
callback.call(Err(err.clone()));
callback(Err(err.clone()));
}
log::error!("Buffer::map_async error: {err}");
Err(err)

View File

@ -176,7 +176,7 @@ impl UserClosures {
// a on_submitted_work_done callback to be fired before the on_submitted_work_done callback.
for (mut operation, status) in self.mappings {
if let Some(callback) = operation.callback.take() {
callback.call(status);
callback(status);
}
}
for closure in self.submissions {

View File

@ -188,36 +188,6 @@ macro_rules! impl_trackable {
};
}
/// The status code provided to the buffer mapping callback.
///
/// This is very similar to `BufferAccessResult`, except that this is FFI-friendly.
#[repr(C)]
#[derive(Debug)]
pub enum BufferMapAsyncStatus {
/// The Buffer is successfully mapped, `get_mapped_range` can be called.
///
/// All other variants of this enum represent failures to map the buffer.
Success,
/// The buffer is already mapped.
///
/// While this is treated as an error, it does not prevent mapped range from being accessed.
AlreadyMapped,
/// Mapping was already requested.
MapAlreadyPending,
/// An unknown error.
Error,
/// The context is Lost.
ContextLost,
/// The buffer is in an invalid state.
Invalid,
/// The range isn't fully contained in the buffer.
InvalidRange,
/// The range isn't properly aligned.
InvalidAlignment,
/// Incompatible usage flags.
InvalidUsageFlags,
}
#[derive(Debug)]
pub(crate) enum BufferMapState {
/// Mapped at creation.
@ -239,107 +209,25 @@ unsafe impl Send for BufferMapState {}
#[cfg(send_sync)]
unsafe impl Sync for BufferMapState {}
#[repr(C)]
pub struct BufferMapCallbackC {
pub callback: unsafe extern "C" fn(status: BufferMapAsyncStatus, user_data: *mut u8),
pub user_data: *mut u8,
}
#[cfg(send_sync)]
unsafe impl Send for BufferMapCallbackC {}
#[derive(Debug)]
pub struct BufferMapCallback {
// We wrap this so creating the enum in the C variant can be unsafe,
// allowing our call function to be safe.
inner: BufferMapCallbackInner,
}
#[cfg(send_sync)]
type BufferMapCallbackCallback = Box<dyn FnOnce(BufferAccessResult) + Send + 'static>;
pub type BufferMapCallback = Box<dyn FnOnce(BufferAccessResult) + Send + 'static>;
#[cfg(not(send_sync))]
type BufferMapCallbackCallback = Box<dyn FnOnce(BufferAccessResult) + 'static>;
pub type BufferMapCallback = Box<dyn FnOnce(BufferAccessResult) + 'static>;
enum BufferMapCallbackInner {
Rust { callback: BufferMapCallbackCallback },
C { inner: BufferMapCallbackC },
}
impl Debug for BufferMapCallbackInner {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match *self {
BufferMapCallbackInner::Rust { callback: _ } => f.debug_struct("Rust").finish(),
BufferMapCallbackInner::C { inner: _ } => f.debug_struct("C").finish(),
}
}
}
impl BufferMapCallback {
pub fn from_rust(callback: BufferMapCallbackCallback) -> Self {
Self {
inner: BufferMapCallbackInner::Rust { callback },
}
}
/// # Safety
///
/// - The callback pointer must be valid to call with the provided user_data
/// pointer.
///
/// - Both pointers must point to valid memory until the callback is
/// invoked, which may happen at an unspecified time.
pub unsafe fn from_c(inner: BufferMapCallbackC) -> Self {
Self {
inner: BufferMapCallbackInner::C { inner },
}
}
pub(crate) fn call(self, result: BufferAccessResult) {
match self.inner {
BufferMapCallbackInner::Rust { callback } => {
callback(result);
}
// SAFETY: the contract of the call to from_c says that this unsafe is sound.
BufferMapCallbackInner::C { inner } => unsafe {
let status = match result {
Ok(_) => BufferMapAsyncStatus::Success,
Err(BufferAccessError::Device(_)) => BufferMapAsyncStatus::ContextLost,
Err(BufferAccessError::InvalidResource(_))
| Err(BufferAccessError::DestroyedResource(_)) => BufferMapAsyncStatus::Invalid,
Err(BufferAccessError::AlreadyMapped) => BufferMapAsyncStatus::AlreadyMapped,
Err(BufferAccessError::MapAlreadyPending) => {
BufferMapAsyncStatus::MapAlreadyPending
}
Err(BufferAccessError::MissingBufferUsage(_)) => {
BufferMapAsyncStatus::InvalidUsageFlags
}
Err(BufferAccessError::UnalignedRange)
| Err(BufferAccessError::UnalignedRangeSize { .. })
| Err(BufferAccessError::UnalignedOffset { .. }) => {
BufferMapAsyncStatus::InvalidAlignment
}
Err(BufferAccessError::OutOfBoundsUnderrun { .. })
| Err(BufferAccessError::OutOfBoundsOverrun { .. })
| Err(BufferAccessError::NegativeRange { .. }) => {
BufferMapAsyncStatus::InvalidRange
}
Err(BufferAccessError::Failed)
| Err(BufferAccessError::NotMapped)
| Err(BufferAccessError::MapAborted) => BufferMapAsyncStatus::Error,
};
(inner.callback)(status, inner.user_data);
},
}
}
}
#[derive(Debug)]
pub struct BufferMapOperation {
pub host: HostMap,
pub callback: Option<BufferMapCallback>,
}
impl Debug for BufferMapOperation {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("BufferMapOperation")
.field("host", &self.host)
.field("callback", &self.callback.as_ref().map(|_| "?"))
.finish()
}
}
#[derive(Clone, Debug, Error)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[non_exhaustive]
@ -637,7 +525,7 @@ impl Buffer {
// We can safely unwrap below since we just set the `map_state` to `BufferMapState::Waiting`.
let (mut operation, status) = self.map(&device.snatchable_lock.read()).unwrap();
if let Some(callback) = operation.callback.take() {
callback.call(status);
callback(status);
}
0
};
@ -711,7 +599,7 @@ impl Buffer {
buffer_id,
)? {
if let Some(callback) = operation.callback.take() {
callback.call(status);
callback(status);
}
}

View File

@ -1406,12 +1406,10 @@ impl crate::Context for ContextWgpuCore {
MapMode::Read => wgc::device::HostMap::Read,
MapMode::Write => wgc::device::HostMap::Write,
},
callback: Some(wgc::resource::BufferMapCallback::from_rust(Box::new(
|status| {
let res = status.map_err(|_| crate::BufferAsyncError);
callback(res);
},
))),
callback: Some(Box::new(|status| {
let res = status.map_err(|_| crate::BufferAsyncError);
callback(res);
})),
};
match self.0.buffer_map_async(