Skip to content

fix(cpu): detect both V-Cache services, not just the Win32 one - #73

Merged
carterscode merged 2 commits into
mainfrom
fix/vcache-driver-detection
Aug 8, 2026
Merged

fix(cpu): detect both V-Cache services, not just the Win32 one#73
carterscode merged 2 commits into
mainfrom
fix/vcache-driver-detection

Conversation

@carterscode

Copy link
Copy Markdown
Owner

Follow-up to #72. The panel still reported "not found" on a 9950X3D that has the stack.

Root cause

ServiceController.GetServices() returns Win32 services only. AMD installs the optimizer as an INF driver package that registers two entries:

Key Type Seen by GetServices()
amd3dvcache kernel driver
amd3dvcacheSvc Win32 (type 16)

A machine carrying only the driver — or whose helper a different chipset package registers differently — looked like it had no routing stack at all.

Detection now enumerates HKLM\SYSTEM\CurrentControlSet\Services, which holds every service type, and reports the strongest signal found.

On the dev machine this changes the result from Idle to Running — the kernel driver was present and running the whole time, invisible to the old code.

Also fixed

  • Indirect display names. INF-installed services store DisplayName as @oem46.inf,%amd3dvcacheSvc.DisplayName%;AMD 3D V-Cache Performance Optimizer Service. CleanDisplayName resolves the readable fallback instead of printing the raw form, and returns null rather than showing an unresolved indirect string.
  • NotInstalled no longer doubles as "the read failed". New Unreadable state. Both mean "can't confirm", but only one justifies telling the user to go install something — the summary asserted "isn't installed" in both cases.
  • Panel wording. Names the real package (AMD Chipset Software, whose component is listed as "AMD 3D V-Cache Performance Optimizer Driver"), drops literal asterisks that were rendering as *chipset* in the UI, and frames the service as needed only on the CPPC=Driver path — on the recommended CPPC=Cache path it isn't a dependency at all, so leading with it as a missing requirement was misleading.

Testing

770 stable / 752 beta pass. Verified against this machine's real registry: the detector now resolves amd3dvcache / "AMD 3D V-Cache Performance Optimizer Kernel Driver" as Running.

The dual-CCD panel still cannot be rendered on the dev machine (single-CCD 9850X3D), so the rendered result needs eyes on the 9950X3D.

Post-Deploy Monitoring & Validation

  • Healthy: the panel names a service (amd3dvcache or amd3dvcacheSvc) instead of "not installed".
  • Failure: still "not installed" where Get-ChildItem 'HKLM:\SYSTEM\CurrentControlSet\Services' | ? PSChildName -match '3dvcache' returns rows — that would mean the matcher is too narrow.
  • Rollback: revert; read-only detection change, no persisted state touched.
  • Owner/window: first launch on the reporter's 9950X3D.

Code review: skipped (no Tier 1 tool available to the agent; Tier 2 criteria not met — one service file, one UI method, tests).

carterscode and others added 2 commits August 7, 2026 19:38
…ooked at one

Still reported "not found" on a 9950X3D with the stack present.

ServiceController.GetServices() returns Win32 services only. AMD installs this as
an INF driver package that registers two entries: a kernel driver named
"amd3dvcache" and a user-mode helper named "amd3dvcacheSvc". A machine carrying
only the driver -- or whose helper is registered differently by another chipset
package version -- looked to the app like it had no routing stack at all.

Detection now enumerates HKLM\SYSTEM\CurrentControlSet\Services, which holds
every service type, and reports the strongest signal found. On this machine that
changes the result from Idle (the Win32 helper, stopped) to Running (the kernel
driver, which was there the whole time and invisible to the old code).

INF-installed services store DisplayName as an indirect string
("@oem46.inf,%amd3dvcacheSvc.DisplayName%;AMD 3D V-Cache Performance Optimizer
Service"). CleanDisplayName resolves the readable fallback rather than printing
the raw form, and returns null when it cannot.

NotInstalled no longer doubles as "the read failed". Absence and unreadability
both mean "can't confirm", but only one justifies telling the user to install
something, and the summary asserted "isn't installed" in both cases.

Panel wording: the row now names the actual package ("AMD Chipset Software",
which lists the component as "AMD 3D V-Cache Performance Optimizer Driver")
rather than saying "chipset driver", drops the literal asterisks that were
rendering as *chipset* in the UI, and frames the service as needed only on the
CPPC=Driver path -- on the recommended CPPC=Cache path it is not a dependency at
all, so leading with it as a missing requirement was misleading.

770 stable / 752 beta tests pass.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
On the branch before merging, so the section exists before the tag is pushed --
release.yml silently falls back to [Unreleased] otherwise.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Comment on lines +124 to +128
catch
{
// Read failed -- say so rather than reporting absence we did not observe.
return new CcdServiceInfo(CcdServiceState.Unreadable, null, null);
}
using var sc = new System.ServiceProcess.ServiceController(serviceName);
return sc.Status == System.ServiceProcess.ServiceControllerStatus.Running;
}
catch { return false; }
@carterscode
carterscode merged commit 80f6d36 into main Aug 8, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants