mirror of
https://github.com/storytold/cadcraft.git
synced 2026-10-15 06:46:45 -04:00
Windows: use FXC by default for DirectX 12 startup (#613)
Squash of PR #613 by @PedroGuille. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
b6383b5f3c
commit
ce1cc631d5
2 files changed
+58
-7
No files matched your search
@@ -1,10 +1,14 @@
|
||||
//! Windows graphics instance configuration, applied before wgpu can initialize any driver.
|
||||
|
||||
use eframe::{NativeOptions, egui_wgpu::WgpuSetup, wgpu::Backends};
|
||||
use eframe::{
|
||||
NativeOptions,
|
||||
egui_wgpu::WgpuSetup,
|
||||
wgpu::{Backends, Dx12Compiler},
|
||||
};
|
||||
|
||||
/// Restrict the wgpu instance to DirectX 12 unless `backend_override` (normally
|
||||
/// `Backends::from_env()`, i.e. `WGPU_BACKEND`) names other backends.
|
||||
pub fn configure(options: &mut NativeOptions, backend_override: Option<Backends>) {
|
||||
/// Default to DirectX 12 with FXC before creating the wgpu instance. Explicit
|
||||
/// `WGPU_BACKEND` and `WGPU_DX12_COMPILER` choices, read by the caller, take precedence.
|
||||
pub fn configure(options: &mut NativeOptions, backend_override: Option<Backends>, compiler_override: Option<Dx12Compiler>) {
|
||||
if let WgpuSetup::CreateNew(create) = &mut options.wgpu_options.wgpu_setup {
|
||||
// eframe's default includes GL. Creating that backend can crash inside AMD's
|
||||
// atio6axx.dll before adapter selection or any Rust error handling runs, so the
|
||||
@@ -12,6 +16,15 @@ pub fn configure(options: &mut NativeOptions, backend_override: Option<Backends>
|
||||
// out of the instance avoids it. This matches the verified WGPU_BACKEND=dx12
|
||||
// workaround without mutating process environment variables.
|
||||
create.instance_descriptor.backends = backend_override.unwrap_or(Backends::DX12);
|
||||
// Auto can load another program's dxcompiler.dll without a matching dxil.dll.
|
||||
// That fails wgpu's indirect-validation pipeline and loses the device before
|
||||
// the first frame (issue #608). FXC uses the Windows-provided compiler runtime.
|
||||
create.instance_descriptor.backend_options.dx12.shader_compiler = compiler_override.unwrap_or(Dx12Compiler::Fxc);
|
||||
log::info!(
|
||||
"Windows graphics: backends={:?}, DX12 compiler={:?}",
|
||||
create.instance_descriptor.backends,
|
||||
create.instance_descriptor.backend_options.dx12.shader_compiler
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +34,7 @@ mod tests {
|
||||
|
||||
fn configured_backends(backend_override: Option<Backends>) -> Backends {
|
||||
let mut options = NativeOptions::default();
|
||||
configure(&mut options, backend_override);
|
||||
configure(&mut options, backend_override, None);
|
||||
let WgpuSetup::CreateNew(create) = options.wgpu_options.wgpu_setup else {
|
||||
panic!("default native options must create a wgpu instance");
|
||||
};
|
||||
@@ -38,6 +51,44 @@ mod tests {
|
||||
assert_eq!(configured_backends(None), Backends::DX12);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn windows_default_uses_fxc_instead_of_searching_for_dxc() {
|
||||
let mut options = NativeOptions::default();
|
||||
if let WgpuSetup::CreateNew(create) = &mut options.wgpu_options.wgpu_setup {
|
||||
// Auto can find an unrelated DXC without its matching DXIL runtime (issue #608).
|
||||
create.instance_descriptor.backend_options.dx12.shader_compiler = Dx12Compiler::Auto;
|
||||
}
|
||||
configure(&mut options, None, None);
|
||||
let WgpuSetup::CreateNew(create) = options.wgpu_options.wgpu_setup else {
|
||||
panic!("default native options must create a wgpu instance");
|
||||
};
|
||||
assert!(matches!(create.instance_descriptor.backend_options.dx12.shader_compiler, Dx12Compiler::Fxc));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn explicit_compiler_and_backend_overrides_are_preserved() {
|
||||
let backends = Backends::VULKAN | Backends::DX12;
|
||||
for compiler in
|
||||
[Dx12Compiler::Fxc, Dx12Compiler::Auto, Dx12Compiler::StaticDxc, Dx12Compiler::DynamicDxc { dxc_path: "custom/dxcompiler.dll".into() }]
|
||||
{
|
||||
let mut options = NativeOptions::default();
|
||||
configure(&mut options, Some(backends), Some(compiler.clone()));
|
||||
let WgpuSetup::CreateNew(create) = options.wgpu_options.wgpu_setup else {
|
||||
panic!("default native options must create a wgpu instance");
|
||||
};
|
||||
assert_eq!(create.instance_descriptor.backends, backends);
|
||||
match (compiler, create.instance_descriptor.backend_options.dx12.shader_compiler) {
|
||||
(Dx12Compiler::Fxc, Dx12Compiler::Fxc)
|
||||
| (Dx12Compiler::Auto, Dx12Compiler::Auto)
|
||||
| (Dx12Compiler::StaticDxc, Dx12Compiler::StaticDxc) => {}
|
||||
(Dx12Compiler::DynamicDxc { dxc_path: expected }, Dx12Compiler::DynamicDxc { dxc_path: actual }) => {
|
||||
assert_eq!(actual, expected);
|
||||
}
|
||||
(expected, actual) => panic!("compiler override changed from {expected:?} to {actual:?}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn explicit_backend_override_is_preserved() {
|
||||
for backends in [Backends::VULKAN, Backends::GL, Backends::DX12, Backends::VULKAN | Backends::DX12, Backends::empty()] {
|
||||
|
||||
@@ -237,9 +237,9 @@ fn main() -> eframe::Result {
|
||||
if let Some(icon) = app_icon() {
|
||||
options.viewport = options.viewport.with_icon(icon);
|
||||
}
|
||||
// Before eframe creates the wgpu instance: default Windows to DirectX 12 only (see graphics.rs).
|
||||
// Before eframe creates the wgpu instance: default Windows to DirectX 12 with FXC (see graphics.rs).
|
||||
#[cfg(target_os = "windows")]
|
||||
graphics::configure(&mut options, eframe::wgpu::Backends::from_env());
|
||||
graphics::configure(&mut options, eframe::wgpu::Backends::from_env(), eframe::wgpu::Dx12Compiler::from_env());
|
||||
// winit has no file drag-and-drop on Wayland (only on X11), so dropping files from the file
|
||||
// manager showed a "no" cursor. Run through XWayland when it's there; CADCRAFT_WAYLAND=1
|
||||
// keeps the native Wayland backend.
|
||||
|
||||
Reference in new issue
Block a user