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 {
power_preference: settings.power_preference,
compatible_surface: surface.as_ref(),
..Default::default()
force_fallback_adapter,
};
let (device, queue, adapter_info, render_adapter) =
@ -410,6 +419,7 @@ impl Plugin for RenderPlugin {
&instance,
&settings,
&request_adapter_options,
desired_adapter_name,
)
.await;
debug!("Configured wgpu adapter Limits: {:#?}", device.limits());

View File

@ -7,7 +7,7 @@ use bevy_tasks::ComputeTaskPool;
use bevy_utils::WgpuWrapper;
pub use graph_runner::*;
pub use render_device::*;
use tracing::{error, info, info_span, warn};
use tracing::{debug, error, info, info_span, trace, warn};
use crate::{
diagnostic::{internal::DiagnosticsRecorder, RecordDiagnostics},
@ -151,12 +151,40 @@ pub async fn initialize_renderer(
instance: &Instance,
options: &WgpuSettings,
request_adapter_options: &RequestAdapterOptions<'_, '_>,
desired_adapter_name: Option<String>,
) -> (RenderDevice, RenderQueue, RenderAdapterInfo, RenderAdapter) {
let adapter = instance
.request_adapter(request_adapter_options)
.await
.expect(GPU_NOT_FOUND_ERROR_MESSAGE);
let mut selected_adapter = None;
if let Some(adapter_name) = &desired_adapter_name {
debug!("Searching for adapter with name: {}", adapter_name);
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();
info!("{:?}", adapter_info);

View File

@ -53,6 +53,10 @@ pub struct WgpuSettings {
pub instance_flags: InstanceFlags,
/// This hints to the WGPU device about the preferred memory allocation strategy.
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 {
@ -136,6 +140,8 @@ impl Default for WgpuSettings {
gles3_minor_version,
instance_flags,
memory_hints: MemoryHints::default(),
force_fallback_adapter: false,
adapter_name: None,
}
}
}