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

[Merged by Bors] - Ignore Timeout errors on Linux AMD & Intel #5957

Closed
wants to merge 6 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
62 changes: 43 additions & 19 deletions crates/bevy_render/src/view/window.rs
Expand Up @@ -220,32 +220,56 @@ pub fn prepare_windows(
},
};

// Do the initial surface configuration if it hasn't been configured yet. Or if size or
// present mode changed.
let frame = if window_surfaces.configured_windows.insert(window.id)
|| window.size_changed
|| window.present_mode_changed
{
render_device.configure_surface(&surface_data.surface, &surface_configuration);
surface_data
.surface
// A recurring issue is hitting `wgpu::SurfaceError::Timeout` on certain Linux
// mesa driver implementations. This seems to be a quirk of some drivers.
// We'd rather keep panicking when not on Linux mesa, because in those case,
// the `Timeout` is still probably the symptom of a degraded unrecoverable
// application state.
// see https://github.com/bevyengine/bevy/pull/5957
// and https://github.com/gfx-rs/wgpu/issues/1218
#[cfg(target_os = "linux")]
nicopap marked this conversation as resolved.
Show resolved Hide resolved
let may_erroneously_timeout = || {
render_instance
.enumerate_adapters(wgpu::Backends::VULKAN)
.any(|adapter| {
let name = adapter.get_info().name;
name.starts_with("AMD") || name.starts_with("Intel")
})
};

let not_already_configured = window_surfaces.configured_windows.insert(window.id);

let surface = &surface_data.surface;
if not_already_configured || window.size_changed || window.present_mode_changed {
render_device.configure_surface(surface, &surface_configuration);
let frame = surface
.get_current_texture()
.expect("Error configuring surface")
.expect("Error configuring surface");
window.swap_chain_texture = Some(TextureView::from(frame));
} else {
match surface_data.surface.get_current_texture() {
Ok(swap_chain_frame) => swap_chain_frame,
match surface.get_current_texture() {
Ok(frame) => {
window.swap_chain_texture = Some(TextureView::from(frame));
}
Err(wgpu::SurfaceError::Outdated) => {
render_device.configure_surface(&surface_data.surface, &surface_configuration);
surface_data
.surface
render_device.configure_surface(surface, &surface_configuration);
let frame = surface
.get_current_texture()
.expect("Error reconfiguring surface")
.expect("Error reconfiguring surface");
window.swap_chain_texture = Some(TextureView::from(frame));
}
#[cfg(target_os = "linux")]
Err(wgpu::SurfaceError::Timeout) if may_erroneously_timeout() => {
bevy_utils::tracing::trace!(
"Couldn't get swap chain texture. This is probably a quirk \
of your Linux GPU driver, so it can be safely ignored."
);
}
Err(err) => {
panic!("Couldn't get swap chain texture, operation unrecoverable: {err}");
}
err => err.expect("Failed to acquire next swap chain texture!"),
}
};

window.swap_chain_texture = Some(TextureView::from(frame));
window.swap_chain_texture_format = Some(surface_data.format);
}
}