GPU Device Selection#
Upscayl's upscaling backend (upscayl-bin, a Vulkan-based ncnn binary) independently enumerates all physical Vulkan devices on the host system. By default, when gpuId is null, the backend selects device [0] automatically β typically the first device in the enumeration order . The Electron frontend has no role in device selection; it only passes the -g flag to the backend binary if the user has configured a GPU ID .
How GPU ID is Configured#
GPU selection is user-controlled via the GPU ID field in Settings. The value is persisted in localStorage under the key "gpuId" via a Jotai atom. When non-empty, it is forwarded as -g <gpuId> in the binary arguments for all upscaling modes (single, batch, double-pass) . The sidebar passes null if the field is empty .
Relevant files:
renderer/atoms/user-settings-atom.tsβgpuIdAtomdefinitionrenderer/components/sidebar/settings-tab/input-gpu-id.tsxβ GPU ID UI inputelectron/utils/get-arguments.tsβ-gargument constructionelectron/commands/image-upscayl.tsβ extractsgpuIdfrom IPC payload
Reading the Device Enumeration Log#
On startup, upscayl-bin logs every detected Vulkan physical device, e.g.:
[0 Intel(R) Iris(R) Xe Graphics] queueC=0[1] queueG=0[1] queueT=0[1]
[0 Intel(R) Iris(R) Xe Graphics] bugsbn1=0 bugbilz=0 bugcopc=0 bugihfa=0
[1 Intel(R) Iris(R) Xe Graphics] queueC=0[1] ...
Each device appears twice in the log because the Electron IPC layer duplicates stdout/stderr . The [N] prefix is the device index passed to -g. bugbilz, bugsbn1, etc. are ncnn's internal Vulkan driver bug flags β elevated values (e.g., bugbilz=55 or bugbilz=105) indicate the device has known driver bugs and may produce incorrect results or fail .
SwiftShader / ANGLE β A Common Red Herring#
The System Info block logged by the Electron renderer shows the GPU used by Chromium, not by upscayl-bin. On many Windows systems the Electron GPU reports:
"deviceString": "ANGLE (Google, Vulkan 1.3.0 (SwiftShader Device (Subzero) (0x0000C0DE)), SwiftShader driver-5.0.0)"
This means Chromium itself fell back to a software renderer, which is expected on configurations where hardware-accelerated compositing is unavailable to the renderer process. The actual upscaling GPU is whatever upscayl-bin selects from the Vulkan physical device list β visible only in the backend device enumeration log .
Vulkan Failure Modes#
upscayl-bin failure is signaled via stderr/stdout strings that Electron watches for. If stderr contains "Error" or "failed", the backend process is killed immediately . Common Vulkan errors seen across multiple GPU vendors and Windows versions:
| Error | Code | Typical Cause |
|---|---|---|
vkQueueSubmit failed -4 | VK_ERROR_DEVICE_LOST | Driver crash / GPU timeout, often on integrated or low-VRAM GPUs mid-inference |
vkQueueSubmit failed -3 | VK_ERROR_OUT_OF_DEVICE_MEMORY | VRAM exhaustion, seen on Snapdragon X / Qualcomm Adreno |
vkWaitForFences failed -4 | VK_ERROR_DEVICE_LOST | Device lost before inference begins, common on older NVIDIA cards (GT 710, GT 720, MX230) |
Affected GPU families reported: Intel Iris Xe Graphics , AMD Radeon RX 7700 XT , Qualcomm Adreno X1-45 , NVIDIA GeForce GT 710/720/MX230/MX350, AMD Radeon (RTX 3050 Ti hybrid system) .
Selecting the Correct GPU on Multi-GPU Systems#
On systems with multiple Vulkan-visible devices (common on Windows laptops with both integrated and discrete GPUs), the ncnn backend picks device [0] when no -g flag is set. If that device is unstable, try specifying a different GPU ID in Settings. To identify the correct index, read the device enumeration log and use the 0-based index of the desired device. Comma-separated values (e.g., 0,0) are also accepted and have been tested by community members .
On some systems, Windows exposes the same physical GPU as multiple Vulkan devices (e.g., the native driver + a Microsoft Direct3D12 compatibility layer). The Direct3D12 wrapper entries (e.g., Microsoft Direct3D12 (Qualcomm(R) Adreno(TM) X1-45 GPU)) can appear alongside the native Vulkan device at different indices; the Microsoft Basic Render Driver at device [2] is a pure software fallback and should always be avoided .
Workarounds#
- Set GPU ID explicitly: Enter the 0-based device index from the enumeration log into the GPU ID field in Settings. This forces
-g Nto be passed to the backend. - Reduce tile size: Lowering the tile size reduces peak VRAM usage per tile, which can prevent
VK_ERROR_DEVICE_LOSTon memory-constrained GPUs . - Update GPU drivers:
vkQueueSubmit failed -4has been correlated with driver failures in AMD software notifications . - Avoid the Microsoft Basic Render Driver: If the device list includes a
Microsoft Direct3D12 (Microsoft Basic Render Driver)entry with non-zerobugbilz, do not allow the backend to auto-select it .
No Known Fix (as of 2.15.0)#
There is no automatic device validation or filtering in the current codebase; the backend receives whatever index (or none) the user provides. A community contributor (haxllo) proposed user-friendly error handling for vkWaitForFences failed -4 but cannot submit a PR due to collaborator restrictions on the repository .