Convert QueueWriteBufferView to be lifetime-less (#8161)

This commit is contained in:
Connor Fitzgerald 2025-09-07 03:34:06 -04:00 committed by GitHub
parent 4853133eaa
commit 832609959d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 31 additions and 15 deletions

View File

@ -54,6 +54,7 @@ We have merged the acceleration structure feature into the `RayQuery` feature. T
By @Vecvec in [#7913](https://github.com/gfx-rs/wgpu/pull/7913).
#### New `EXPERIMENTAL_PRECOMPILED_SHADERS` API
We have added `Features::EXPERIMENTAL_PRECOMPILED_SHADERS`, replacing existing passthrough types with a unified `CreateShaderModuleDescriptorPassthrough` which allows passing multiple shader codes for different backends. By @SupaMaggie70Incorporated in [#7834](https://github.com/gfx-rs/wgpu/pull/7834)
Difference for SPIR-V passthrough:
@ -73,6 +74,21 @@ Difference for SPIR-V passthrough:
```
This allows using precompiled shaders without manually checking which backend's code to pass, for example if you have shaders precompiled for both DXIL and SPIR-V.
#### Buffer mapping apis no longer have lifetimes
`Buffer::get_mapped_range()`, `Buffer::get_mapped_range_mut()`, and `Queue::write_buffer_with()` now return guard objects without any lifetimes. This
makes it significantly easier to store these types in structs, which is useful for building utilities that build the contents of a buffer over time.
```diff
- let buffer_mapping_ref: wgpu::BufferView<'_> = buffer.get_mapped_range(..);
- let buffer_mapping_mut: wgpu::BufferViewMut<'_> = buffer.get_mapped_range_mut(..);
- let queue_write_with: wgpu::QueueWriteBufferView<'_> = queue.write_buffer_with(..);
+ let buffer_mapping_ref: wgpu::BufferView = buffer.get_mapped_range(..);
+ let buffer_mapping_mut: wgpu::BufferViewMut = buffer.get_mapped_range_mut(..);
+ let queue_write_with: wgpu::QueueWriteBufferView = queue.write_buffer_with(..);
```
By @sagudev in [#8046](https://github.com/gfx-rs/wgpu/pull/8046) and @cwfitzgerald in [#8070](https://github.com/gfx-rs/wgpu/pull/8161).
#### `EXPERIMENTAL_*` features now require unsafe code to enable
We want to be able to expose potentially experimental features to our users before we have ensured that they are fully sound to use.

View File

@ -58,16 +58,16 @@ static_assertions::assert_impl_all!(PollType: Send, Sync);
/// Reading into this buffer won't yield the contents of the buffer from the
/// GPU and is likely to be slow. Because of this, although [`AsMut`] is
/// implemented for this type, [`AsRef`] is not.
pub struct QueueWriteBufferView<'a> {
queue: &'a Queue,
buffer: &'a Buffer,
pub struct QueueWriteBufferView {
queue: Queue,
buffer: Buffer,
offset: BufferAddress,
inner: dispatch::DispatchQueueWriteBuffer,
}
#[cfg(send_sync)]
static_assertions::assert_impl_all!(QueueWriteBufferView<'_>: Send, Sync);
static_assertions::assert_impl_all!(QueueWriteBufferView: Send, Sync);
impl QueueWriteBufferView<'_> {
impl QueueWriteBufferView {
#[cfg(custom)]
/// Returns custom implementation of QueueWriteBufferView (if custom backend and is internally T)
pub fn as_custom<T: custom::QueueWriteBufferInterface>(&self) -> Option<&T> {
@ -75,7 +75,7 @@ impl QueueWriteBufferView<'_> {
}
}
impl Deref for QueueWriteBufferView<'_> {
impl Deref for QueueWriteBufferView {
type Target = [u8];
fn deref(&self) -> &Self::Target {
@ -84,19 +84,19 @@ impl Deref for QueueWriteBufferView<'_> {
}
}
impl DerefMut for QueueWriteBufferView<'_> {
impl DerefMut for QueueWriteBufferView {
fn deref_mut(&mut self) -> &mut Self::Target {
self.inner.slice_mut()
}
}
impl AsMut<[u8]> for QueueWriteBufferView<'_> {
impl AsMut<[u8]> for QueueWriteBufferView {
fn as_mut(&mut self) -> &mut [u8] {
self.inner.slice_mut()
}
}
impl Drop for QueueWriteBufferView<'_> {
impl Drop for QueueWriteBufferView {
fn drop(&mut self) {
self.queue
.inner
@ -182,19 +182,19 @@ impl Queue {
/// allocations, you might be able to use [`StagingBelt`](crate::util::StagingBelt),
/// or buffers you explicitly create, map, and unmap yourself.
#[must_use]
pub fn write_buffer_with<'a>(
&'a self,
buffer: &'a Buffer,
pub fn write_buffer_with(
&self,
buffer: &Buffer,
offset: BufferAddress,
size: BufferSize,
) -> Option<QueueWriteBufferView<'a>> {
) -> Option<QueueWriteBufferView> {
profiling::scope!("Queue::write_buffer_with");
self.inner
.validate_write_buffer(&buffer.inner, offset, size)?;
let staging_buffer = self.inner.create_staging_buffer(size)?;
Some(QueueWriteBufferView {
queue: self,
buffer,
queue: self.clone(),
buffer: buffer.clone(),
offset,
inner: staging_buffer,
})