Add options for selecting adapter by name and forcing fallback (#19921)

Adds support for:
- `WGPU_ADAPTER_NAME` which will attempt to select a specific adapter
with a given name.
- `WGPU_FORCE_FALLBACK_ADAPTER` which will force fallback to a fallback
(software) renderer, if available.

The first has higher specificity than the second.
This commit is contained in:
charlotte 🌸 2025-07-03 15:26:34 -07:00 committed by GitHub
parent 6e918f56d8
commit 852fb84aa2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 50 additions and 6 deletions

View File

@ -399,10 +399,19 @@ impl Plugin for RenderPlugin {
} }
}); });
let force_fallback_adapter = std::env::var("WGPU_FORCE_FALLBACK_ADAPTER")
.map_or(settings.force_fallback_adapter, |v| {
!(v.is_empty() || v == "0" || v == "false")
});
let desired_adapter_name = std::env::var("WGPU_ADAPTER_NAME")
.as_deref()
.map_or(settings.adapter_name.clone(), |x| Some(x.to_lowercase()));
let request_adapter_options = wgpu::RequestAdapterOptions { let request_adapter_options = wgpu::RequestAdapterOptions {
power_preference: settings.power_preference, power_preference: settings.power_preference,
compatible_surface: surface.as_ref(), compatible_surface: surface.as_ref(),
..Default::default() force_fallback_adapter,
}; };
let (device, queue, adapter_info, render_adapter) = let (device, queue, adapter_info, render_adapter) =
@ -410,6 +419,7 @@ impl Plugin for RenderPlugin {
&instance, &instance,
&settings, &settings,
&request_adapter_options, &request_adapter_options,
desired_adapter_name,
) )
.await; .await;
debug!("Configured wgpu adapter Limits: {:#?}", device.limits()); debug!("Configured wgpu adapter Limits: {:#?}", device.limits());

View File

@ -7,7 +7,7 @@ use bevy_tasks::ComputeTaskPool;
use bevy_utils::WgpuWrapper; use bevy_utils::WgpuWrapper;
pub use graph_runner::*; pub use graph_runner::*;
pub use render_device::*; pub use render_device::*;
use tracing::{error, info, info_span, warn}; use tracing::{debug, error, info, info_span, trace, warn};
use crate::{ use crate::{
diagnostic::{internal::DiagnosticsRecorder, RecordDiagnostics}, diagnostic::{internal::DiagnosticsRecorder, RecordDiagnostics},
@ -151,12 +151,40 @@ pub async fn initialize_renderer(
instance: &Instance, instance: &Instance,
options: &WgpuSettings, options: &WgpuSettings,
request_adapter_options: &RequestAdapterOptions<'_, '_>, request_adapter_options: &RequestAdapterOptions<'_, '_>,
desired_adapter_name: Option<String>,
) -> (RenderDevice, RenderQueue, RenderAdapterInfo, RenderAdapter) { ) -> (RenderDevice, RenderQueue, RenderAdapterInfo, RenderAdapter) {
let adapter = instance let mut selected_adapter = None;
.request_adapter(request_adapter_options) if let Some(adapter_name) = &desired_adapter_name {
.await debug!("Searching for adapter with name: {}", adapter_name);
.expect(GPU_NOT_FOUND_ERROR_MESSAGE); for adapter in instance.enumerate_adapters(options.backends.expect(
"The `backends` field of `WgpuSettings` must be set to use a specific adapter.",
)) {
trace!("Checking adapter: {:?}", adapter.get_info());
let info = adapter.get_info();
if let Some(surface) = request_adapter_options.compatible_surface {
if !adapter.is_surface_supported(surface) {
continue;
}
}
if info
.name
.to_lowercase()
.contains(&adapter_name.to_lowercase())
{
selected_adapter = Some(adapter);
break;
}
}
} else {
debug!(
"Searching for adapter with options: {:?}",
request_adapter_options
);
selected_adapter = instance.request_adapter(request_adapter_options).await.ok();
};
let adapter = selected_adapter.expect(GPU_NOT_FOUND_ERROR_MESSAGE);
let adapter_info = adapter.get_info(); let adapter_info = adapter.get_info();
info!("{:?}", adapter_info); info!("{:?}", adapter_info);

View File

@ -53,6 +53,10 @@ pub struct WgpuSettings {
pub instance_flags: InstanceFlags, pub instance_flags: InstanceFlags,
/// This hints to the WGPU device about the preferred memory allocation strategy. /// This hints to the WGPU device about the preferred memory allocation strategy.
pub memory_hints: MemoryHints, pub memory_hints: MemoryHints,
/// If true, will force wgpu to use a software renderer, if available.
pub force_fallback_adapter: bool,
/// The name of the adapter to use.
pub adapter_name: Option<String>,
} }
impl Default for WgpuSettings { impl Default for WgpuSettings {
@ -136,6 +140,8 @@ impl Default for WgpuSettings {
gles3_minor_version, gles3_minor_version,
instance_flags, instance_flags,
memory_hints: MemoryHints::default(), memory_hints: MemoryHints::default(),
force_fallback_adapter: false,
adapter_name: None,
} }
} }
} }