From 38f7443605560968f4c71cc7dbd8a6e5f0d63bba Mon Sep 17 00:00:00 2001 From: Nathan Adams Date: Tue, 19 Mar 2024 23:07:35 +0100 Subject: [PATCH] desktop: Try each graphics backend one-by-one until we have a result --- desktop/src/gui/controller.rs | 71 +++++++++++++++++++++++------------ 1 file changed, 47 insertions(+), 24 deletions(-) diff --git a/desktop/src/gui/controller.rs b/desktop/src/gui/controller.rs index 1d93fe196..f48dda844 100644 --- a/desktop/src/gui/controller.rs +++ b/desktop/src/gui/controller.rs @@ -48,30 +48,7 @@ impl GuiController { initial_movie_url: Option, no_gui: bool, ) -> anyhow::Result { - let mut backend: wgpu::Backends = preferences.graphics_backends().into(); - if wgpu::Backends::SECONDARY.contains(backend) { - tracing::warn!( - "{} graphics backend support may not be fully supported.", - format_list(&get_backend_names(backend), "and") - ); - } - let mut instance = wgpu::Instance::new(wgpu::InstanceDescriptor { - backends: backend, - flags: wgpu::InstanceFlags::default().with_env(), - ..Default::default() - }); - if instance.enumerate_adapters(backend).is_empty() && backend != wgpu::Backends::all() { - tracing::warn!( - "Graphics backend {} is not available; falling back to any available backend", - format_list(&get_backend_names(backend), "and") - ); - backend = wgpu::Backends::all(); - instance = wgpu::Instance::new(wgpu::InstanceDescriptor { - backends: backend, - flags: wgpu::InstanceFlags::default().with_env(), - ..Default::default() - }); - } + let (instance, backend) = create_wgpu_instance(preferences.graphics_backends().into())?; let surface = unsafe { instance.create_surface_unsafe(wgpu::SurfaceTargetUnsafe::from_window(window.as_ref())?) }?; @@ -361,6 +338,52 @@ impl GuiController { } } +fn create_wgpu_instance( + preferred_backends: wgpu::Backends, +) -> anyhow::Result<(wgpu::Instance, wgpu::Backends)> { + for backend in preferred_backends.iter() { + if let Some(instance) = try_wgpu_backend(backend) { + tracing::info!( + "Using preferred backend {}", + format_list(&get_backend_names(backend), "and") + ); + return Ok((instance, backend)); + } + } + + tracing::warn!( + "Preferred backend(s) of {} not available; falling back to any", + format_list(&get_backend_names(preferred_backends), "or") + ); + + for backend in wgpu::Backends::all() - preferred_backends { + if let Some(instance) = try_wgpu_backend(backend) { + tracing::info!( + "Using fallback backend {}", + format_list(&get_backend_names(backend), "and") + ); + return Ok((instance, backend)); + } + } + + Err(anyhow!( + "No compatible graphics backends of any kind were available" + )) +} + +fn try_wgpu_backend(backend: wgpu::Backends) -> Option { + let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { + backends: backend, + flags: wgpu::InstanceFlags::default().with_env(), + ..Default::default() + }); + if instance.enumerate_adapters(backend).is_empty() { + None + } else { + Some(instance) + } +} + // try to load known unicode supporting fonts to draw cjk characters in egui fn load_system_fonts( font_database: &Database,