forked from 1b-agent/fieldcraft-upstream
gpu: take wgpu's backend options from its environment variables
The adapter selection built its wgpu instance with default backend options, so WGPU_DX12_COMPILER had no effect: on DX12 there was no way to choose between FXC and DXC when measuring them (#561: FXC takes ~8.5 s to create the GPU solver's pipelines and runs it at half of Vulkan's speed, DXC 0.5 s and full speed). The options now come from wgpu's own environment variables. staticdxc is refused with an error: it needs wgpu's static-dxc feature, which FieldCraft does not build, and wgpu would panic on it. Part of #561.
This commit is contained in:
1 parent
60fd0998f5
commit
8cd37e0a68
1 file changed
+30
-1
@@ -8,6 +8,11 @@
|
|||||||
//! Backends are Metal on macOS, DX12 and Vulkan on Windows, Vulkan and GL elsewhere;
|
//! Backends are Metal on macOS, DX12 and Vulkan on Windows, Vulkan and GL elsewhere;
|
||||||
//! `WGPU_BACKEND` narrows them. A discrete GPU outranks an integrated one, then a virtual one,
|
//! `WGPU_BACKEND` narrows them. A discrete GPU outranks an integrated one, then a virtual one,
|
||||||
//! then any other; a CPU device is the software tier.
|
//! then any other; a CPU device is the software tier.
|
||||||
|
//!
|
||||||
|
//! wgpu's backend options follow its environment variables: on DX12, `WGPU_DX12_COMPILER`
|
||||||
|
//! (`fxc` or `dxc`; unset, DXC when `dxcompiler.dll` is on the DLL search path, else FXC, see
|
||||||
|
//! #561). `staticdxc` is refused: it needs wgpu's `static-dxc` feature, which FieldCraft does not
|
||||||
|
//! build, and wgpu would panic on it.
|
||||||
|
|
||||||
use crate::{GpuError, Result};
|
use crate::{GpuError, Result};
|
||||||
|
|
||||||
@@ -100,7 +105,11 @@ pub fn adapter(policy: Policy) -> Result<Option<(wgpu::Adapter, Tier)>> {
|
|||||||
if policy == Policy::Cpu {
|
if policy == Policy::Cpu {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { backends: backends(), ..wgpu::InstanceDescriptor::new_without_display_handle() });
|
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
|
||||||
|
backends: backends(),
|
||||||
|
backend_options: backend_options(wgpu::BackendOptions::from_env_or_default())?,
|
||||||
|
..wgpu::InstanceDescriptor::new_without_display_handle()
|
||||||
|
});
|
||||||
let mut adapters = pollster::block_on(instance.enumerate_adapters(backends()));
|
let mut adapters = pollster::block_on(instance.enumerate_adapters(backends()));
|
||||||
let types: Vec<_> = adapters.iter().map(|a| a.get_info().device_type).collect();
|
let types: Vec<_> = adapters.iter().map(|a| a.get_info().device_type).collect();
|
||||||
let Some(i) = pick(&types, policy)? else { return Ok(None) };
|
let Some(i) = pick(&types, policy)? else { return Ok(None) };
|
||||||
@@ -108,12 +117,32 @@ pub fn adapter(policy: Policy) -> Result<Option<(wgpu::Adapter, Tier)>> {
|
|||||||
Ok((i < adapters.len()).then(|| (adapters.swap_remove(i), tier)))
|
Ok((i < adapters.len()).then(|| (adapters.swap_remove(i), tier)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// `options`, unless they ask for a DX12 compiler this build does not have.
|
||||||
|
fn backend_options(options: wgpu::BackendOptions) -> Result<wgpu::BackendOptions> {
|
||||||
|
if matches!(options.dx12.shader_compiler, wgpu::Dx12Compiler::StaticDxc) {
|
||||||
|
return Err(GpuError::Device("WGPU_DX12_COMPILER=staticdxc is not built in: use dxc with dxcompiler.dll, or fxc".into()));
|
||||||
|
}
|
||||||
|
Ok(options)
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use wgpu::DeviceType::*;
|
use wgpu::DeviceType::*;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn a_dx12_compiler_that_is_not_built_in_is_refused() {
|
||||||
|
let with = |shader_compiler| {
|
||||||
|
let mut o = wgpu::BackendOptions::default();
|
||||||
|
o.dx12.shader_compiler = shader_compiler;
|
||||||
|
backend_options(o)
|
||||||
|
};
|
||||||
|
assert!(with(wgpu::Dx12Compiler::Fxc).is_ok());
|
||||||
|
assert!(with(wgpu::Dx12Compiler::Auto).is_ok());
|
||||||
|
assert!(with(wgpu::Dx12Compiler::StaticDxc).is_err());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn policies_walk_the_tiers() {
|
fn policies_walk_the_tiers() {
|
||||||
assert_eq!(pick(&[Cpu, IntegratedGpu, DiscreteGpu, VirtualGpu], Policy::Auto), Ok(Some(2)));
|
assert_eq!(pick(&[Cpu, IntegratedGpu, DiscreteGpu, VirtualGpu], Policy::Auto), Ok(Some(2)));
|
||||||
|
|||||||
Reference in new issue
Block a user