diff --git a/CHANGELOG.md b/CHANGELOG.md index 3cafd06ad..2a13590d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -78,6 +78,8 @@ By @stefnotch in [#5410](https://github.com/gfx-rs/wgpu/pull/5410) #### General +- Added `as_hal` for `Buffer` to access wgpu created buffers form wgpu-hal. By @JasondeWolff in [#5724](https://github.com/gfx-rs/wgpu/pull/5724) + #### Naga - Implement `WGSL`'s `unpack4xI8`,`unpack4xU8`,`pack4xI8` and `pack4xU8`. By @VlaDexa in [#5424](https://github.com/gfx-rs/wgpu/pull/5424) diff --git a/wgpu-core/src/resource.rs b/wgpu-core/src/resource.rs index 67e756c10..9ae275615 100644 --- a/wgpu-core/src/resource.rs +++ b/wgpu-core/src/resource.rs @@ -932,6 +932,28 @@ impl Texture { } impl Global { + /// # Safety + /// + /// - The raw buffer handle must not be manually destroyed + pub unsafe fn buffer_as_hal) -> R, R>( + &self, + id: BufferId, + hal_buffer_callback: F, + ) -> R { + profiling::scope!("Buffer::as_hal"); + + let hub = A::hub(self); + let buffer_opt = { hub.buffers.try_get(id).ok().flatten() }; + let buffer = buffer_opt.as_ref().unwrap(); + + let hal_buffer = { + let snatch_guard = buffer.device.snatchable_lock.read(); + buffer.raw(&snatch_guard) + }; + + hal_buffer_callback(hal_buffer) + } + /// # Safety /// /// - The raw texture handle must not be manually destroyed diff --git a/wgpu/src/backend/wgpu_core.rs b/wgpu/src/backend/wgpu_core.rs index 9b61d9f99..4065a590b 100644 --- a/wgpu/src/backend/wgpu_core.rs +++ b/wgpu/src/backend/wgpu_core.rs @@ -98,6 +98,14 @@ impl ContextWgpuCore { } } + pub unsafe fn buffer_as_hal) -> R, R>( + &self, + id: wgc::id::BufferId, + hal_buffer_callback: F, + ) -> R { + unsafe { self.0.buffer_as_hal::(id, hal_buffer_callback) } + } + pub unsafe fn create_device_from_hal( &self, adapter: &wgc::id::AdapterId, diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index d4085e07a..be80b20cb 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -3547,6 +3547,30 @@ impl Buffer { } } + /// Returns the inner hal Buffer using a callback. The hal buffer will be `None` if the + /// backend type argument does not match with this wgpu Buffer + /// + /// # Safety + /// + /// - The raw handle obtained from the hal Buffer must not be manually destroyed + #[cfg(wgpu_core)] + pub unsafe fn as_hal) -> R, R>( + &self, + hal_buffer_callback: F, + ) -> R { + let id = self.id; + + if let Some(ctx) = self + .context + .as_any() + .downcast_ref::() + { + unsafe { ctx.buffer_as_hal::(id.into(), hal_buffer_callback) } + } else { + hal_buffer_callback(None) + } + } + /// Use only a portion of this Buffer for a given operation. Choosing a range with no end /// will use the rest of the buffer. Using a totally unbounded range will use the entire buffer. pub fn slice>(&self, bounds: S) -> BufferSlice<'_> {