Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ By @beholdnec in [#8505](https://github.com/gfx-rs/wgpu/pull/8505).
- Increase recursion limits to please `-Znext-solver`. By @nazar-pc in [#9609](https://github.com/gfx-rs/wgpu/pull/9609)
- Stencil clear and reference values are now truncated to 8 bits. By @beicause in [#9607](https://github.com/gfx-rs/wgpu/pull/9607).
- Fixed missing initialization of other aspects when writing to a single aspect of a multi-aspect texture. By @andyleiserson in [#9626](https://github.com/gfx-rs/wgpu/pull/9626).
- Fix process abort when a `SurfaceTexture` is dropped during panic unwind between `get_current_texture` and `Queue::present`. The acquired texture reference is now released without calling HAL discard. By @hack3rmann in [#9678](https://github.com/gfx-rs/wgpu/pull/9678).

#### naga

Expand Down
3 changes: 2 additions & 1 deletion player/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,8 @@ impl Player {
}
Action::ConfigureSurface { .. }
| Action::Present(_)
| Action::DiscardSurfaceTexture(_) => {
| Action::DiscardSurfaceTexture(_)
| Action::ReleaseSurfaceTexture(_) => {
panic!("Unexpected Surface action: winit feature is not enabled")
}
Action::CreateBuffer(id, desc) => {
Expand Down
1 change: 1 addition & 0 deletions wgpu-core/src/device/trace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ pub enum Action<'a, R: ReferenceType> {
},
Present(R::Surface),
DiscardSurfaceTexture(R::Surface),
ReleaseSurfaceTexture(R::Surface),
CreateBindGroupLayout(
PointerId<markers::BindGroupLayout>,
crate::binding_model::BindGroupLayoutDescriptor<'a>,
Expand Down
1 change: 1 addition & 0 deletions wgpu-core/src/device/trace/record.rs
Original file line number Diff line number Diff line change
Expand Up @@ -905,6 +905,7 @@ fn action_to_owned(action: Action<'_, PointerReferences>) -> Action<'static, Poi
A::GetSurfaceTexture { id, parent } => A::GetSurfaceTexture { id, parent },
A::Present(surface) => A::Present(surface),
A::DiscardSurfaceTexture(surface) => A::DiscardSurfaceTexture(surface),
A::ReleaseSurfaceTexture(surface) => A::ReleaseSurfaceTexture(surface),
A::DropBindGroupLayout(layout) => A::DropBindGroupLayout(layout),
A::GetRenderPipelineBindGroupLayout {
id,
Expand Down
35 changes: 35 additions & 0 deletions wgpu-core/src/present.rs
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,28 @@ impl Surface {

Ok(())
}

/// Like `discard`, drops the inner texture reference, but skips the
/// HAL `discard_texture` call. Safe to call during unwinding
pub fn release(&self) -> Result<(), SurfaceError> {
profiling::scope!("Surface::release");

let mut presentation = self.presentation.lock();
let Some(present) = presentation.as_mut() else {
return Err(SurfaceError::NotConfigured);
};

// `texture` is dropped here, decrementing the refcount of
// Arc<SwapchainAcquireSemaphore>. If this was the last Arc, the Texture
// is freed, which drops NativeSurfaceTextureMetadata and
// its Arc<SwapchainAcquireSemaphore>.
_ = present
.acquired_texture
.take()
.ok_or(SurfaceError::NothingToPresent)?;

Ok(())
}
}

impl Global {
Expand Down Expand Up @@ -463,4 +485,17 @@ impl Global {

surface.discard()
}

pub fn surface_texture_release(&self, surface_id: id::SurfaceId) -> Result<(), SurfaceError> {
let surface = self.surfaces.get(surface_id);

#[cfg(feature = "trace")]
if let Some(present) = surface.presentation.lock().as_ref() {
if let Some(ref mut trace) = *present.device.trace.lock() {
trace.add(Action::ReleaseSurfaceTexture(surface.to_trace()));
}
}

surface.release()
}
}
11 changes: 9 additions & 2 deletions wgpu/src/api/surface_texture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,15 @@ impl SurfaceTexture {

impl Drop for SurfaceTexture {
fn drop(&mut self) {
if !self.presented && !thread_panicking() {
self.detail.texture_discard();
if !self.presented {
if thread_panicking() {
// Best effort: release reference to `SwapchainAcquireSemaphore`
// This fixes <https://github.com/gfx-rs/wgpu/issues/8243>
// `Trying to destroy a SwapchainAcquireSemaphore that is still in use by a SurfaceTexture`
self.detail.texture_release();
} else {
self.detail.texture_discard();
}
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions wgpu/src/backend/webgpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4028,6 +4028,10 @@ impl dispatch::SurfaceOutputDetailInterface for WebSurfaceOutputDetail {
fn texture_discard(&self) {
// Can't really discard the texture on the web.
}

fn texture_release(&self) {
// Can't really discard the texture on the web, so there's no point of releasing too
}
}
impl Drop for WebSurfaceOutputDetail {
fn drop(&mut self) {
Expand Down
10 changes: 10 additions & 0 deletions wgpu/src/backend/wgpu_core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4029,6 +4029,16 @@ impl dispatch::SurfaceOutputDetailInterface for CoreSurfaceOutputDetail {
}
}
}

fn texture_release(&self) {
match self.context.0.surface_texture_release(self.surface_id) {
Ok(_status) => (),
Err(err) => {
self.context
.handle_error_nolabel(&self.error_sink, err, "Surface::release_texture")
}
}
}
}
impl Drop for CoreSurfaceOutputDetail {
fn drop(&mut self) {
Expand Down
1 change: 1 addition & 0 deletions wgpu/src/dispatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,7 @@ pub trait SurfaceInterface: CommonTraits {

pub trait SurfaceOutputDetailInterface: CommonTraits {
fn texture_discard(&self);
fn texture_release(&self);
}

pub trait QueueWriteBufferInterface: CommonTraits {
Expand Down