Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make Surface#configure and Surface#get_current_texture non-fatal #6253

Merged
merged 7 commits into from
Dec 7, 2024
Merged
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
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ By @cwfitzgerald in [#6619](https://github.com/gfx-rs/wgpu/pull/6619).

### Render and Compute Passes Now Properly Enforce Their Lifetime

A regression intoduced in 23.0.0 caused lifetimes of render and compute passes to be incorrectly enforced. While this is not
A regression introduced in 23.0.0 caused lifetimes of render and compute passes to be incorrectly enforced. While this is not
a soundness issue, the intent is to move an error from runtime to compile time. This issue has been fixed and restored to the 22.0.0 behavior.

### The `diagnostic(…);` directive is now supported in WGSL
Expand Down Expand Up @@ -134,6 +134,7 @@ By @ErichDonGubler in [#6456](https://github.com/gfx-rs/wgpu/pull/6456), [#6148]
- Make `Surface::as_hal` take an immutable reference to the surface. By @jerzywilczek in [#9999](https://github.com/gfx-rs/wgpu/pull/9999)
- Add actual sample type to `CreateBindGroupError::InvalidTextureSampleType` error message. By @ErichDonGubler in [#6530](https://github.com/gfx-rs/wgpu/pull/6530).
- Improve binding error to give a clearer message when there is a mismatch between resource binding as it is in the shader and as it is in the binding layout. By @eliemichel in [#6553](https://github.com/gfx-rs/wgpu/pull/6553).
- `Surface::configure` and `Surface::get_current_texture` are no longer fatal. By @alokedesai in [#6253](https://github.com/gfx-rs/wgpu/pull/6253)

#### D3D12

Expand Down
1 change: 1 addition & 0 deletions examples/src/framework.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ impl SurfaceWrapper {
// If the surface is outdated, or was lost, reconfigure it.
wgpu::SurfaceError::Outdated
| wgpu::SurfaceError::Lost
| wgpu::SurfaceError::Other
// If OutOfMemory happens, reconfiguring may not help, but we might as well try
| wgpu::SurfaceError::OutOfMemory,
) => {
Expand Down
2 changes: 2 additions & 0 deletions wgpu-types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5642,6 +5642,8 @@ pub enum SurfaceStatus {
Outdated,
/// The surface under the swap chain is lost.
Lost,
/// The surface status is not known since `get_current_texture` previously failed.
Unknown,
}

/// Nanosecond timestamp used by the presentation engine.
Expand Down
1 change: 1 addition & 0 deletions wgpu/src/api/surface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ impl Surface<'_> {
SurfaceStatus::Timeout => return Err(SurfaceError::Timeout),
SurfaceStatus::Outdated => return Err(SurfaceError::Outdated),
SurfaceStatus::Lost => return Err(SurfaceError::Lost),
SurfaceStatus::Unknown => return Err(SurfaceError::Other),
};

let guard = self.config.lock();
Expand Down
3 changes: 3 additions & 0 deletions wgpu/src/api/surface_texture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ pub enum SurfaceError {
Lost,
/// There is no more memory left to allocate a new frame.
OutOfMemory,
/// Acquiring a texture failed with a generic error. Check error callbacks for more information.
Other,
}
static_assertions::assert_impl_all!(SurfaceError: Send, Sync);

Expand All @@ -68,6 +70,7 @@ impl fmt::Display for SurfaceError {
Self::Outdated => "The underlying surface has changed, and therefore the swap chain must be updated",
Self::Lost => "The swap chain has been lost and needs to be recreated",
Self::OutOfMemory => "There is no more memory left to allocate a new frame",
Self::Other => "Acquiring a texture failed with a generic error. Check error callbacks for more information",
})
}
}
Expand Down
41 changes: 29 additions & 12 deletions wgpu/src/backend/wgpu_core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,9 @@ pub struct CoreSurface {
/// Configured device is needed to know which backend
/// code to execute when acquiring a new frame.
configured_device: Mutex<Option<wgc::id::DeviceId>>,
/// The error sink with which to report errors.
/// `None` if the surface has not been configured.
error_sink: Mutex<Option<ErrorSink>>,
}

#[derive(Debug)]
Expand Down Expand Up @@ -827,6 +830,7 @@ impl dispatch::InstanceInterface for ContextWgpuCore {
context: self.clone(),
id,
configured_device: Mutex::default(),
error_sink: Mutex::default(),
}))
}

Expand Down Expand Up @@ -3435,9 +3439,11 @@ impl dispatch::SurfaceInterface for CoreSurface {

let error = self.context.0.surface_configure(self.id, device.id, config);
if let Some(e) = error {
self.context.handle_error_fatal(e, "Surface::configure");
self.context
.handle_error_nolabel(&device.error_sink, e, "Surface::configure");
} else {
*self.configured_device.lock() = Some(device.id);
*self.error_sink.lock() = Some(device.error_sink.clone());
}
}

Expand All @@ -3448,6 +3454,12 @@ impl dispatch::SurfaceInterface for CoreSurface {
crate::SurfaceStatus,
dispatch::DispatchSurfaceOutputDetail,
) {
let output_detail = CoreSurfaceOutputDetail {
context: self.context.clone(),
surface_id: self.id,
}
.into();

match self.context.0.surface_get_current_texture(self.id, None) {
Ok(wgc::present::SurfaceOutput { status, texture_id }) => {
let data = texture_id
Expand All @@ -3458,19 +3470,24 @@ impl dispatch::SurfaceInterface for CoreSurface {
})
.map(Into::into);

(
data,
status,
CoreSurfaceOutputDetail {
context: self.context.clone(),
surface_id: self.id,
(data, status, output_detail)
}
Err(err) => {
let error_sink = self.error_sink.lock();
match error_sink.as_ref() {
Some(error_sink) => {
self.context.handle_error_nolabel(
error_sink,
err,
"Surface::get_current_texture_view",
);
(None, crate::SurfaceStatus::Unknown, output_detail)
}
.into(),
)
None => self
.context
.handle_error_fatal(err, "Surface::get_current_texture_view"),
}
}
Err(err) => self
.context
.handle_error_fatal(err, "Surface::get_current_texture_view"),
}
}
}
Expand Down
Loading