From 720fd5f4e12aec478b059758bd4ff3cbf4a28a3c Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 29 Sep 2023 16:27:13 +0200 Subject: [PATCH] Try other adapters, if one fails to return device --- crates/fj-viewer/src/graphics/device.rs | 43 ++++++++++++++++++++++- crates/fj-viewer/src/graphics/renderer.rs | 26 ++++++++++++-- 2 files changed, 65 insertions(+), 4 deletions(-) diff --git a/crates/fj-viewer/src/graphics/device.rs b/crates/fj-viewer/src/graphics/device.rs index 73b35f053..63d3bee21 100644 --- a/crates/fj-viewer/src/graphics/device.rs +++ b/crates/fj-viewer/src/graphics/device.rs @@ -1,4 +1,4 @@ -use tracing::debug; +use tracing::{debug, error}; #[derive(Debug)] pub struct Device { @@ -27,6 +27,43 @@ impl Device { Ok((device, adapter, features)) } + pub async fn try_from_all_adapters( + instance: &wgpu::Instance, + ) -> Result<(Self, wgpu::Adapter, wgpu::Features), DeviceError> { + let mut all_adapters = + instance.enumerate_adapters(wgpu::Backends::all()); + + let result = loop { + let Some(adapter) = all_adapters.next() else { + debug!("No more adapters to try"); + break None; + }; + + let (device, features) = match Device::new(&adapter).await { + Ok((device, adapter)) => (device, adapter), + Err(err) => { + error!( + "Failed to get device from adapter {:?}: {:?}", + adapter.get_info(), + err, + ); + continue; + } + }; + + break Some((device, adapter, features)); + }; + + for adapter in all_adapters { + debug!( + "Remaining adapter that wasn't tried: {:?}", + adapter.get_info() + ); + } + + result.ok_or(DeviceError::FoundNoWorkingAdapter) + } + pub async fn new( adapter: &wgpu::Adapter, ) -> Result<(Self, wgpu::Features), DeviceError> { @@ -82,4 +119,8 @@ pub enum DeviceError { /// Failed to request device #[error("Failed to request device")] RequestDevice(#[from] wgpu::RequestDeviceError), + + /// Found no working adapter to get a device from + #[error("Found no working adapter to get a device from")] + FoundNoWorkingAdapter, } diff --git a/crates/fj-viewer/src/graphics/renderer.rs b/crates/fj-viewer/src/graphics/renderer.rs index 424017ad1..6f3960db7 100644 --- a/crates/fj-viewer/src/graphics/renderer.rs +++ b/crates/fj-viewer/src/graphics/renderer.rs @@ -1,7 +1,7 @@ use std::{io, mem::size_of, vec}; use thiserror::Error; -use tracing::{debug, trace}; +use tracing::{debug, error, trace}; use wgpu::util::DeviceExt as _; use crate::{ @@ -50,8 +50,28 @@ impl Renderer { debug!("Available adapter: {:?}", adapter.get_info()); } - let (device, adapter, features) = - Device::from_preferred_adapter(&instance, &surface).await?; + let result = Device::from_preferred_adapter(&instance, &surface).await; + let (device, adapter, features) = match result { + Ok((device, adapter, features)) => (device, adapter, features), + Err(_) => { + error!("Failed to acquire device from preferred adapter"); + + match Device::try_from_all_adapters(&instance).await { + Ok((device, adapter, features)) => { + (device, adapter, features) + } + Err(err) => { + error!("Prepend `RUST_LOG=fj_viewer=debug` and re-run"); + error!("Then open an issue and post your output"); + error!( + "https://github.com/hannobraun/fornjot/issues/new" + ); + + return Err(err.into()); + } + } + } + }; let color_format = 'color_format: { let capabilities = surface.get_capabilities(&adapter);