diff --git a/crates/bevy_render/src/view/window/mod.rs b/crates/bevy_render/src/view/window/mod.rs index ddb0f77f98..d184f08e12 100644 --- a/crates/bevy_render/src/view/window/mod.rs +++ b/crates/bevy_render/src/view/window/mod.rs @@ -8,6 +8,8 @@ use crate::{ }; use bevy_app::{App, Plugin}; use bevy_ecs::{entity::EntityHashMap, prelude::*}; +#[cfg(target_os = "linux")] +use bevy_utils::warn_once; use bevy_utils::{default, tracing::debug, HashSet}; use bevy_window::{ CompositeAlphaMode, PresentMode, PrimaryWindow, RawHandleWrapper, Window, WindowClosed, @@ -216,6 +218,9 @@ impl WindowSurfaces { } } +#[cfg(target_os = "linux")] +const NVIDIA_VENDOR_ID: u32 = 0x10DE; + /// (re)configures window surfaces, and obtains a swapchain texture for rendering. /// /// NOTE: `get_current_texture` in `prepare_windows` can take a long time if the GPU workload is @@ -304,19 +309,41 @@ pub fn prepare_windows( }) }; + #[cfg(target_os = "linux")] + let is_nvidia = || { + render_instance + .enumerate_adapters(wgpu::Backends::VULKAN) + .iter() + .any(|adapter| adapter.get_info().vendor & 0xFFFF == NVIDIA_VENDOR_ID) + }; + 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); + match surface.get_current_texture() { + Ok(frame) => window.set_swapchain_texture(frame), + #[cfg(target_os = "linux")] + Err(wgpu::SurfaceError::Outdated) if is_nvidia() => { + warn_once!( + "Couldn't get swap chain texture. This often happens with \ + the NVIDIA drivers on Linux. It can be safely ignored." + ); + } + Err(err) => panic!("Error configuring surface: {err}"), + }; } else { match surface.get_current_texture() { Ok(frame) => { window.set_swapchain_texture(frame); } + #[cfg(target_os = "linux")] + Err(wgpu::SurfaceError::Outdated) if is_nvidia() => { + warn_once!( + "Couldn't get swap chain texture. This often happens with \ + the Nvidia 550 driver. It can be safely ignored." + ); + } Err(wgpu::SurfaceError::Outdated) => { render_device.configure_surface(surface, &surface_data.configuration); let frame = surface