mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-28 11:47:21 -06:00
Windows: after a graphics driver crash, the next start leaves that adapter out
When a graphics driver crashed the process while the window started, as Intel's Direct3D 12 driver (igd12umd64.dll) did on an Intel UHD Graphics 605 (#2243), the next start picked the same adapter again. The restart without a failing adapter and the first-frame watch run inside the process, so the crash ended them along with it. Each start now writes graphics-start.json in the log folder before the graphics start, adds the adapter once one is picked, and clears both when the first frame reaches the screen or the app ends without crashing. A start that finds an earlier start still recorded there leaves that adapter out, as a restart does, logs it and shows a note in the status bar. When the crash came while the adapters were being listed (wgpu's Direct3D 12 backend creates a device on each GPU to list it), the next starts list OpenGL's adapters alone, except on macOS. The adapters stay left out until the app version or the Graphics Processor preference changes, a start shows its first frame on one, or no adapter is left. WGPU_BACKEND and WGPU_ADAPTER_NAME choose regardless of the record. Docs: docs/development.md, docs/target-app-parity.md.
This commit is contained in:
+2
-1
@@ -50,7 +50,7 @@ How the web shell (`apps/vectorcraft-web/src/web.rs`) differs from desktop:
|
||||
The canvas is rasterized on the CPU (`vectorcraft-render`, vello_cpu); the GPU (wgpu, through eframe) only composites the canvas texture and draws the UI, so any GPU that can show the window will do. The desktop app picks the window's adapter itself (`apps/vectorcraft/src/gpu.rs`, eframe's `native_adapter_selector`) and logs every adapter it found and the one it uses.
|
||||
|
||||
- **Order:** adapters that report they can't present to the window are never tried; then the one `WGPU_ADAPTER_NAME` names; hardware before software (llvmpipe, WARP); the native backends (Vulkan, Metal, DX12) before OpenGL; with Automatic, the GPU the Wayland compositor draws with, then the GPU that drives a display, and among those the one that drives the primary display; then the power preference; then a GPU's DX12 adapter before its Vulkan one (Intel's Vulkan driver made the whole window flicker black, #545), keeping the system's order among equals.
|
||||
- **Windows backends:** Direct3D 12, falling back to OpenGL. Vulkan isn't started at all unless `WGPU_BACKEND` asks for it (`WGPU_BACKEND=vulkan`): creating a Vulkan instance loads every installed Vulkan driver into the process, and a faulty one (Intel's `igvk64.dll`, #806) crashed the app before its window appeared.
|
||||
- **Windows backends:** Direct3D 12, falling back to OpenGL. Vulkan isn't started at all unless `WGPU_BACKEND` asks for it (`WGPU_BACKEND=vulkan`): creating a Vulkan instance loads every installed Vulkan driver into the process, and a faulty one (Intel's `igvk64.dll`, #806) crashed the app before its window appeared. After a start that crashed while it listed the Direct3D 12 adapters, later starts list OpenGL's alone (see the crash bullet below).
|
||||
- **The GPU that drives the display.** A GPU without a monitor is the wrong one even when it says it can show the window: on a desktop with a Ryzen's integrated GPU (no monitor) and an NVIDIA card driving both monitors, power saving picked the integrated GPU, Windows had to present every frame across adapters, and the integrated GPU's driver reset under that: the graphics device was lost, or the desktop's compositor went down and every monitor stayed black for minutes (pdfcraft#378). So Automatic asks the system which GPU drives which display and puts that GPU first; the power preference only orders the rest, and decides alone where the system can't say.
|
||||
- **Windows:** `EnumDisplayDevices` (the display devices attached to the desktop, and the primary one), through the `winsafe` crate; the PCI ids in each device id are matched against wgpu's adapters. The registry doesn't tell a user which adapter drives a display, and WMI reports a resolution for a GPU without a monitor, so neither is used.
|
||||
- **Linux:** the connected connectors in `/sys/class/drm` and their cards' PCI ids; a built-in panel (`eDP`, `LVDS`, `DSI`) counts as the primary display.
|
||||
@@ -63,6 +63,7 @@ The canvas is rasterized on the CPU (`vectorcraft-render`, vello_cpu); the GPU (
|
||||
- 0.5.0 saved `powerSaving`, its default, for everyone; it reads as `automatic`.
|
||||
- **If the window fails on its adapter while starting up** (an error from wgpu, or a panic inside wgpu or egui-wgpu during the first frames), the app starts again without that adapter and tries the next one, telling which in the status bar; the run that failed keeps its log as `vectorcraft.1.log`. On Unix the new app replaces the process (an AppImage stays mounted); on Windows it starts beside it. Adapters are told apart by backend and PCI ids, or by name where the backend reports no ids (Metal lists every GPU of a dual-GPU Mac as `0000:0000`, #651). The adapters left out travel in `VECTORCRAFT_GPU_SKIP` (`backend:vendor:device`, such as `Vulkan:1002:164e`), one more on each restart, so the restarts end. When no adapter is left, the app logs why and exits with an error instead of panicking.
|
||||
- **If the window's first frame never reaches the screen** within 20 seconds of the app being created (the files named at the start opened), the adapter counts as hanging and the app starts again without it in the same way (#964: High Performance on a hybrid laptop left the app running in the background with no window and nothing in the log). A window minimized at the start isn't counted. When the processor that hung was chosen in Preferences, the status bar points to Automatic.
|
||||
- **If the app crashes while the window starts**, as when Intel's Direct3D 12 driver (`igd12umd64.dll`) ended 0.9.0 before its window appeared on an Intel UHD Graphics 605 (#2243), no code in the process runs to start it again, so the next start leaves the adapter out. Each start writes `graphics-start.json` in the log folder before the graphics start and adds the adapter once one is picked; when the first frame reaches the screen or the app ends without crashing, the start is cleared from the file. A start that finds an earlier start still recorded there logs the adapter, leaves it out and shows a note in the status bar. When the crash came while the adapters were being listed (wgpu's Direct3D 12 backend creates a device on each GPU to list it), the next start lists OpenGL's adapters alone; on macOS, where wgpu has no OpenGL adapters, it lists them all. Later starts keep leaving them out until the app version or Preferences › Performance › Graphics Processor changes, a start shows its first frame on the adapter that crashed, or no adapter is left that can show the window. `WGPU_BACKEND` and `WGPU_ADAPTER_NAME` choose regardless of the file: a start with `WGPU_BACKEND=dx12` tries Direct3D 12 again, and when its first frame appears, the crash is cleared. A process ended from outside during the start (Task Manager, `kill`) counts as a crash. Runs without preferences (`VECTORCRAFT_NO_PREFS`) record nothing, and a start made while another copy of the app is starting neither reads nor writes the file.
|
||||
- **To recover from a Graphics Processor choice that doesn't work** without editing files: start once with `WGPU_POWER_PREF=low` (or `WGPU_ADAPTER_NAME=…`), which overrides the preference for that start while settings still save, and set Graphics Processor back to Automatic. `VECTORCRAFT_NO_PREFS=1` also starts without it, but saves nothing.
|
||||
- **Environment variables** for when the choice still goes wrong, all read at startup and stronger than the preference:
|
||||
- `WGPU_POWER_PREF`: `low`, `high` or `none` (the system's order).
|
||||
|
||||
Reference in New Issue
Block a user