Skip to content

Commit

Permalink
Fix crash on Linux Nvidia 550 driver
Browse files Browse the repository at this point in the history
  • Loading branch information
eero-lehtinen committed Mar 17, 2024
1 parent ec3e7af commit 08eb5d9
Showing 1 changed file with 40 additions and 26 deletions.
66 changes: 40 additions & 26 deletions crates/bevy_render/src/view/window/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -304,38 +304,52 @@ pub fn prepare_windows(
})
};

// Nvidia 550.54.14 driver introduced a change, where it returns
// `wgpu::SurfaceError::Outdated` after the window is resized. The
// previous behaviour of returning no error seemed to have been a bug,
// but it didn't affect the application's functionality, so just ignore
// the error if it happens.
#[cfg(target_os = "linux")]
let ignore_outdated = || {
render_instance
.enumerate_adapters(wgpu::Backends::VULKAN)
.iter()
.any(|adapter| {
let info = adapter.get_info();
info.name.starts_with("NVIDIA") && info.driver_info.starts_with("550")
})
};

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

let surface = &surface_data.surface;
if not_already_configured || window.size_changed || window.present_mode_changed {
let frame = surface
.get_current_texture()
.expect("Error configuring surface");
window.set_swapchain_texture(frame);
} else {
match surface.get_current_texture() {
Ok(frame) => {
window.set_swapchain_texture(frame);
}
Err(wgpu::SurfaceError::Outdated) => {
render_device.configure_surface(surface, &surface_data.configuration);
let frame = surface
.get_current_texture()
.expect("Error reconfiguring surface");
window.set_swapchain_texture(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 \
render_device.configure_surface(surface, &surface_data.configuration);
}
match surface.get_current_texture() {
Ok(frame) => {
window.set_swapchain_texture(frame);
}
#[cfg(target_os = "linux")]
Err(wgpu::SurfaceError::Outdated) if ignore_outdated() => {}
Err(wgpu::SurfaceError::Outdated) => {
render_device.configure_surface(surface, &surface_data.configuration);
let frame = surface
.get_current_texture()
.expect("Error reconfiguring surface");
window.set_swapchain_texture(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) => {
panic!("Couldn't get swap chain texture, operation unrecoverable: {err}");
}
}
window.swap_chain_texture_format = Some(surface_data.configuration.format);

if window.screenshot_func.is_some() {
Expand Down

0 comments on commit 08eb5d9

Please sign in to comment.