Start on machines with two GPU drivers instead of refusing to launch (#150, #145, #142, #67) - #157
Start on machines with two GPU drivers instead of refusing to launch (#150, #145, #142, #67)#157SwatX18 wants to merge 1 commit into
Conversation
vibranceGUI refuses to start when both an NVIDIA and an AMD driver are installed. It shows a dialog recommending Display Driver Uninstaller and then exits without creating a window. That is wrong for the commonest hybrid desktop there is: an AMD CPU with integrated graphics alongside a discrete NVIDIA card. Both driver DLLs are present, neither should be removed, and the machine has an obvious answer. It is equally wrong for anyone who upgraded cards without scrubbing the old driver. Issues juv#150, juv#145, juv#142 and juv#67 all describe this. The flaw is the test itself. GetAdapter() checks whether driver DLLs exist on disk, which says nothing about whether that GPU is in use. Asking Windows which adapter drives an attached display gives an unambiguous answer on the machine this was developed against: NVIDIA GeForce RTX 5070 Ti DISPLAY1, DISPLAY2, DISPLAY3 (primary) AMD Radeon(TM) Graphics DISPLAY5-9, none attached WMI is not sufficient either - Win32_VideoController reports both adapters as status OK. It is the DISPLAY_DEVICE_ATTACHED_TO_DESKTOP flag from EnumDisplayDevices that discriminates. Three layers, so that most users never see a prompt: 1. Auto-detect the vendor driving an attached display. Exactly one supported vendor attached resolves silently to that vendor. Both, or neither, remains ambiguous rather than guessing. 2. A chooser dialog only when it is genuinely ambiguous. It lists the real adapter names read from the display devices, because a user recognises "NVIDIA GeForce RTX 5070 Ti" while they may not know which chip their laptop has, and preselects whichever drives the primary display. The existing DDU advice is kept but demoted to a link, since it is legitimate for leftover drivers and misleading for hybrid hardware. 3. The choice is persisted to the INI so the question is asked once. It is only consulted when both drivers are still installed, so replacing a card falls back to detection rather than honouring a stale answer. Not regressing a machine that works today Every entry point into the new code sits behind AreBothVendorDriversInstalled(). On a machine with a single driver, EnumDisplayDevices is never called, nothing is logged and the chooser is never constructed. The single-vendor path in GetAdapter() is unchanged. This code runs before the main form exists A throw here means the application never opens at all, which would be worse than the bug being fixed. The display enumeration is wrapped, bounded at 64 devices, and returns an empty list rather than a partial one on either failure path - a half-read enumeration could show one vendor and hide the other, which is worse than admitting ignorance. The chooser's construction is contained, so an unexpected failure degrades to the existing dialog rather than to no window. Vendor names are matched as whole words. "ATI" occurs inside ordinary English words, so a bare substring test classifies "Workstation Virtual Display" and "Cinematic Display Driver" as AMD - turning an honest "cannot tell" into a confident wrong answer in the one branch designed to refuse to guess. Word boundaries are letters rather than letters or digits, so ATI2VGA and AMD780G still match, and every occurrence is examined so a glued match cannot mask a real one. vibrance.GUI.exe --selftest-gpu checks the vendor classification corpus with no GPU, no driver and no disk access, so it can be run on a machine that cannot start the application. It passes 22/22 and fails against a bare substring matcher. Verified On a machine with both drivers installed and only NVIDIA driving the displays, the application now starts with no arguments: title "vibranceGUI (NVIDIA, 2.3.1.1)", status "Running!". Before this change it showed the DDU dialog and exited. Both configurations build clean. Not verified: a genuinely ambiguous machine was not available, so the chooser was exercised with synthetic adapter lists rather than two vendors actually driving attached displays. A single-driver machine could not be tested either, since both drivers are installed on the development machine; that claim rests on the call-site gating described above. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
One thing I noticed after opening this, worth flagging rather than leaving for someone to trip over. The resolution diagnostic this PR adds goes through It can't break startup — every call goes through a Happy to do whichever you prefer: point the new diagnostic at the |
Hi — this fixes the long-standing problem where vibranceGUI refuses to start when both an NVIDIA and an AMD driver are present. It addresses #150, #145, #142 and #67.
The problem
GraphicsAdapterHelper.GetAdapter()returnsAmbiguouswhen bothatiadlxy.dllandnvapi.dllexist in the system folder, andProgram.csthen shows the DDU dialog and exits without creating a window.The check is whether driver DLLs exist on disk, which says nothing about whether that GPU is in use. Both DLLs are present on any machine with an AMD CPU that has integrated graphics plus a discrete NVIDIA card — an extremely common desktop today — and on any machine where an old driver was never scrubbed. In both cases the app won't start, and the advice it gives (remove a driver) is wrong for the first case.
The approach
Asking Windows which adapter drives an attached display gives an unambiguous answer. On my machine:
WMI isn't enough —
Win32_VideoControllerreports both adapters asstatus=OK. It's theDISPLAY_DEVICE_ATTACHED_TO_DESKTOPflag fromEnumDisplayDevicesthat discriminates.Three layers, so most users never see a prompt:
Two things I was careful about
Not regressing machines that work today. Every entry point into the new code sits behind
AreBothVendorDriversInstalled(). On a single-driver machineEnumDisplayDevicesis never called, nothing is logged, and the chooser is never constructed — the single-vendor path inGetAdapter()is unchanged.Not throwing before the main form exists. A throw there means the app never opens, which would be worse than the bug. The enumeration is wrapped, bounded at 64 devices, and returns an empty list rather than a partial one on either failure path — a half-read enumeration could show one vendor and hide the other. The chooser's construction is contained, so an unexpected failure degrades to the existing dialog rather than to no window.
One detail worth flagging: vendor names are matched as whole words.
ATIoccurs inside ordinary English words, so a bare substring test classifies"Workstation Virtual Display"and"Cinematic Display Driver"as AMD — turning an honest "cannot tell" into a confident wrong answer. Boundaries are letters rather than letters-or-digits, soATI2VGAandAMD780Gstill match.vibrance.GUI.exe --selftest-gpuchecks the vendor corpus with no GPU, no driver and no disk access, so it can be run on a machine that can't start the app. It passes 22/22 and fails against a bare substring matcher.Verified
On a machine with both drivers installed and only NVIDIA driving displays, the app now starts with no arguments — title
vibranceGUI (NVIDIA, 2.3.1.1), status "Running!". Before the change it showed the DDU dialog and exited. Both Release and Debug x86 build clean, 0 warnings.Not verified
I don't have a genuinely ambiguous machine — only one vendor drives a display here — so the chooser was exercised with synthetic adapter lists rather than two vendors actually driving attached displays. I also couldn't test a single-driver machine without uninstalling a driver, so that claim rests on the call-site gating described above rather than on a run.
Notes
Branched from
masterand deliberately kept to this one fix — no unrelated changes, andTargetFrameworkVersionis untouched at v4.0. Happy to split it up, drop the persistence or the self-test, or rework anything to fit how you'd prefer it done.Developed with assistance from Claude Code; the commit carries a
Co-Authored-Bytrailer.