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:
parent
6e918f56d8
commit
852fb84aa2
@ -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());
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user