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

* Make Surface#configure non-fatal
* Make Surface#get_current_texture non-fatal

---------

Co-authored-by: Andreas Reich <r_andreas2@web.de>
This commit is contained in:
Aloke Desai 2024-12-07 12:13:09 -05:00 committed by GitHub
parent f8b67a752a
commit ebdd958d4b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 39 additions and 14 deletions

View File

@ -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
@ -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

View File

@ -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,
) => {

View File

@ -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.

View File

@ -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();

View File

@ -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);
@ -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",
})
}
}

View File

@ -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)]
@ -827,6 +830,7 @@ impl dispatch::InstanceInterface for ContextWgpuCore {
context: self.clone(),
id,
configured_device: Mutex::default(),
error_sink: Mutex::default(),
}))
}
@ -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());
}
}
@ -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
@ -3458,19 +3470,24 @@ impl dispatch::SurfaceInterface for CoreSurface {
})
.map(Into::into);
(
data,
status,
CoreSurfaceOutputDetail {
context: self.context.clone(),
surface_id: self.id,
}
.into(),
)
(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)
}
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"),
}
}
}