Windows: compile DirectX 12 shaders with FXC, never a stray dxcompiler.dll (#339, #354)

wgpu's default DX12 compiler (Auto) loads the first dxcompiler.dll on the
DLL search path. GridCraft ships none, so another program's copy is used;
without a matching dxil.dll its 'DXIL signing library not found' warning
fails wgpu's internal compute pipelines, the device is lost and the app
exits before the first frame. Pin FXC (part of Windows) unless
WGPU_DX12_COMPILER asks for another compiler.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
vangel76 2026-10-11 21:02:20 +02:00
parent ce0483fc17
commit 806a39a514
4 changed files with 51 additions and 4 deletions

View File

@ -242,6 +242,11 @@ the first renderer fails to start, it tries the other one once. The log file rec
(lines starting with `graphics:`). `WGPU_BACKEND` still overrides it (and then nothing else is
tried), e.g. `$env:WGPU_BACKEND = "gl"` or `"dx12"`.
DirectX 12 shaders are compiled with FXC, which is part of Windows, so no `dxcompiler.dll` or
`dxil.dll` is needed, and a copy another program put on `PATH` can no longer stop the app at start
("Parent device is lost", #339). `$env:WGPU_DX12_COMPILER = "dxc"` (or `"auto"`) selects wgpu's DXC
handling again for troubleshooting.
### macOS
| Build | File | Notes |

View File

@ -132,6 +132,7 @@ Ranked; estimates in Opus 5.5 agent-hours. Detail and the full beta-gate list in
| Date | What landed |
|---|---|
| 2026-10-11 | Windows: DirectX 12 shaders compile with FXC, so a missing or stray `dxcompiler.dll` no longer stops the app at start (#339, #354) |
| 2026-10-11 | Legacy Excel 97-2003 `.xls` (BIFF8) import with formulas, number formats, merges, sizes and names (#121) |
| 2026-10-11 | XLSX pass-through: custom XML, external links, connections, query tables, printer settings, form/ActiveX controls and OLE objects are kept on save (#330, #324) |
| 2026-10-11 | Data › Forecast › Forecast Sheet: a new sheet with the history, FORECAST.ETS forecast, confidence bounds, statistics and a chart (#322) |

View File

@ -3,11 +3,15 @@
//! Vulkan is never initialized unless `WGPU_BACKEND` asks for it: enumerating Vulkan adapters
//! crashes inside Intel's `igvk64.dll` on some UHD Graphics drivers (#120), and that access
//! violation happens in the driver, where no Rust error handling can catch it.
//!
//! DirectX 12 shaders are compiled with FXC (`d3dcompiler_47.dll`, part of Windows), never with
//! whichever `dxcompiler.dll` the DLL search path happens to find (#339, #354): see
//! [`dx12_compiler`].
use eframe::{
NativeOptions,
egui_wgpu::WgpuSetup,
wgpu::{Backends, DeviceType},
wgpu::{Backends, DeviceType, Dx12Compiler},
};
/// What the start-up probe learned about one DirectX 12 adapter.
@ -59,9 +63,24 @@ pub fn fallback_backends(backend_override: Option<Backends>, first: Backends) ->
(!rest.is_empty()).then_some(rest)
}
/// Restricts the wgpu instance eframe creates to `backends`.
/// The DirectX 12 shader compiler: `env_choice` (normally `Dx12Compiler::from_env()`, i.e.
/// `WGPU_DX12_COMPILER`, for troubleshooting) or else FXC.
///
/// wgpu's default (`Auto`) loads the first `dxcompiler.dll` on the DLL search path. GridCraft ships
/// none, so that is another program's copy (a Windows SDK, an Edge or WebView folder, anything on
/// `PATH`). Without a matching `dxil.dll` beside it, DXC prints "DXIL signing library not found",
/// wgpu treats that warning as a compile error, its internal compute pipelines fail, the device is
/// lost and the app quits before the first frame ("Parent device is lost"). FXC is part of Windows
/// and needs no extra DLL; egui's shaders don't need anything newer.
pub fn dx12_compiler(env_choice: Option<Dx12Compiler>) -> Dx12Compiler {
env_choice.unwrap_or(Dx12Compiler::Fxc)
}
/// Restricts the wgpu instance eframe creates to `backends`, and pins its DirectX 12 shader
/// compiler ([`dx12_compiler`]).
pub fn configure_backends(options: &mut NativeOptions, backends: Backends) {
if let WgpuSetup::CreateNew(create) = &mut options.wgpu_options.wgpu_setup {
create.instance_descriptor.backend_options.dx12.shader_compiler = dx12_compiler(Dx12Compiler::from_env());
// eframe's default includes Vulkan and GL. Creating the GL backend can crash inside AMD's
// atio6axx.dll, and enumerating Vulkan adapters inside Intel's igvk64.dll (#120), before
// adapter selection or any Rust error handling runs, so the window never appears.
@ -189,4 +208,25 @@ mod tests {
// Both were already tried: nothing left to fall back to.
assert_eq!(fallback_backends(None, Backends::DX12 | Backends::GL), None);
}
#[test]
fn dx12_compiles_shaders_with_fxc_unless_asked() {
// #339, #354: wgpu's `Auto` would load a stray dxcompiler.dll and lose the device.
assert!(matches!(dx12_compiler(None), Dx12Compiler::Fxc));
assert!(matches!(dx12_compiler(Some(Dx12Compiler::Auto)), Dx12Compiler::Auto));
assert!(matches!(dx12_compiler(Some(Dx12Compiler::default_dynamic_dxc())), Dx12Compiler::DynamicDxc { .. }));
// eframe's own default is `Auto`; the configured instance (first start and retry) uses FXC.
let WgpuSetup::CreateNew(eframe_default) = NativeOptions::default().wgpu_options.wgpu_setup else {
panic!("default native options must create a wgpu instance");
};
if Dx12Compiler::from_env().is_none() {
assert!(matches!(eframe_default.instance_descriptor.backend_options.dx12.shader_compiler, Dx12Compiler::Auto));
let mut options = NativeOptions::default();
configure_backends(&mut options, Backends::DX12);
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));
}
}
}

View File

@ -1,6 +1,6 @@
# Hardware parity
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-11 · **Change:** trivial (Windows renderer fallback, #120) · **Target:** Microsoft Excel (Microsoft 365), Excel for Mac 16.113.4
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-11 · **Change:** trivial (Windows DirectX 12 shaders with FXC, #339) · **Target:** Microsoft Excel (Microsoft 365), Excel for Mac 16.113.4
The hardware Excel uses, per platform, against GridCraft. Part of
[target-app-parity.md](target-app-parity.md). **Hardware: ~40% ready, 25–40 h** (estimated).
@ -8,7 +8,7 @@ The hardware Excel uses, per platform, against GridCraft. Part of
| Hardware feature | Excel | GridCraft (macOS · Windows · Linux · BSD · web) | Gap and estimate |
|---|---|---|---|
| Multi-core recalculation | Multi-threaded recalculation on all cores (Windows and Mac), configurable thread count | Single-threaded everywhere (no threading in `crates/calc`) | Parallel recalc of independent dependency chains on native builds; WASM stays single-threaded or uses workers later: 12–18 h |
| GPU rendering of the grid and charts | DirectX / Metal accelerated drawing | wgpu: Metal · DirectX 12 (default since 10-08; OpenGL when DirectX 12 has no GPU driver or fails to start; Vulkan only on request, so the Intel UHD `igvk64.dll` crash (#120) can't happen) · Vulkan/GL · Vulkan/GL · WebGPU or WebGL2 | At parity in kind. Driver problems: screen flashing on Windows 11 (#76): 2–4 h |
| GPU rendering of the grid and charts | DirectX / Metal accelerated drawing | wgpu: Metal · DirectX 12 (default since 10-08; OpenGL when DirectX 12 has no GPU driver or fails to start; Vulkan only on request, so the Intel UHD `igvk64.dll` crash (#120) can't happen; shaders compiled with FXC, so no DXC runtime is needed, #339) · Vulkan/GL · Vulkan/GL · WebGPU or WebGL2 | At parity in kind. Driver problems: screen flashing on Windows 11 (#76): 2–4 h |
| Pen and touch (Draw tab) | Pen pressure and tilt, eraser end, touch mode, Ink to Shape, ink replay | Pen, highlighter, eraser, Ink to Shape with mouse/pen input; **no pressure or tilt**, no touch mode | Pressure-sensitive strokes where winit reports force; touch-friendly ribbon spacing: 4–6 h |
| Trackpad and mouse | Smooth scrolling, pinch zoom, horizontal scroll, Magic Mouse | Smooth scrolling and zoom via egui | Verify pinch zoom on each platform: 1–2 h |
| Multiple windows and monitors | One window per workbook, New Window for the same workbook, per-monitor DPI | One window; multiple workbooks switch inside it (#162; PR #171) | Native window per workbook, New Window, Arrange All across monitors: 6–8 h |
@ -20,5 +20,6 @@ The hardware Excel uses, per platform, against GridCraft. Part of
| Date | Change | Summary |
|---|---|---|
| 2026-10-11 | trivial | Windows: DirectX 12 shaders compiled with FXC, no DXC runtime needed (#339, #354) |
| 2026-10-11 | trivial | Windows: OpenGL fallback when DirectX 12 has no GPU or fails to start; Vulkan never by default (#120) |
| 2026-10-10 | major | Created: single-threaded calc, wgpu rendering, no pen pressure, single window |