Try other adapters, if one fails to return device

This commit is contained in:
Hanno Braun 2023-09-29 16:27:13 +02:00
parent 8e1900679b
commit 720fd5f4e1
2 changed files with 65 additions and 4 deletions

View File

@ -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,
}

View File

@ -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);