Skip to content

[RFC] Display-menu render-GPU selector for multi-GPU systems #3666

Description

@ten9876

Note on sequencing

Transparency up front: the reference implementation (PR #3656) already exists — it was built during an exploratory session to validate feasibility on real hybrid hardware. Per GOVERNANCE.md this is out of order (RFC should precede the PR). This RFC formalizes the design for maintainer sign-off, and #3656 is explicitly held — it will not merge until this RFC is approved. Filing it now rather than pretending the order was clean.

Problem

On multi-GPU systems — hybrid laptops especially (Intel/AMD iGPU + NVIDIA/AMD dGPU) — AetherSDR's GPU-rendered spectrum/waterfall (QRhiWidget) runs on whichever adapter the OS/compositor picks by default, which is almost always the integrated GPU. There is no in-app way to put the flagship panadapter render path on the discrete GPU.

Today the only related mechanism is the static NvOptimusEnablement = 1 / AmdPowerXpressRequestHighPerformance = 1 export in main.cpp (Windows-only, all-or-nothing, not user-selectable). Linux has nothing. A user who wants the 4090 driving their 4K/8K panadapter has to set PRIME/DRI_PRIME env vars by hand and launch from a terminal — not a flagship experience.

Proposal

A GPU selector in the panadapter Display menu, shown only when more than one GPU is present (so single-GPU users never see it):

  • Enumerates available GPUs (Linux: DRM sysfs vendor/boot_vga; Windows: DXGI EnumAdapters1), plus an "Auto (system default)" entry.
  • The render adapter can't be hot-swapped under a live GL/D3D context, so the choice is persisted and applied on the next launch (with a "Restart to apply" note). Persistence is one nested-JSON Graphics key (Principle V).
  • GpuSelector::applyAtStartup() runs in main() before QApplication and sets the platform-appropriate lever; it honors an explicit user env override and no-ops on Auto / a missing GPU.

Cross-platform impact

Platform Render path Lever set at startup
Linux / Wayland (EGL) Qt EGL NVIDIA → __NV_PRIME_RENDER_OFFLOAD; AMD/Intel → DRI_PRIME=pci-<addr>
Linux / X11 (GLX) Qt GLX NVIDIA → __NV_PRIME_RENDER_OFFLOAD + __GLX_VENDOR_LIBRARY_NAME=nvidia; AMD/Intel → DRI_PRIME=pci-<addr>
Windows Qt D3D11/12 RHI QT_D3D_ADAPTER_INDEX (DXGI adapter index)
macOS Metal Selector hidden (Macs are effectively single-GPU / OS-managed); no-op

Notable interactions to validate:

  • Windows: the existing NvOptimusEnablement export (driver-level dGPU hint) and QT_D3D_ADAPTER_INDEX (RHI adapter) operate at different layers; "Integrated" must actually land on the iGPU — needs hardware confirmation.
  • Linux/Wayland NVIDIA offload requires a healthy driver (a fallen-over dGPU breaks all paths) — out of scope for the app.

Alternatives considered

  1. Keep the Windows-only NvOptimusEnablement export, do nothing on Linux — the status quo: not user-selectable, Windows-only, all-or-nothing. Rejected (the actual gap is Linux + selectability).
  2. .desktop PrefersNonDefaultGPU=true (Linux) — only affects menu launches (not ./AetherSDR from a terminal), GNOME/KDE-specific, and still all-or-nothing. Useful complement, not a substitute.
  3. Live (in-session) GPU switching — not feasible: the RHI context is bound to an adapter at creation; switching means recreating the context. Persist-and-restart is the honest model.
  4. Leave it to users' env vars — works, but it's exactly the non-flagship friction this removes.

Implementation scope (reference: PR #3656)

src/core/GpuSelector.{h,cpp} (enumeration + persistence + startup apply), a Display-menu dropdown in SpectrumOverlayMenu, the main.cpp call before QApplication, CMake (dxgi link on Windows). 6 files, ~370 lines.

Validation status (honest):

  • ✅ NVIDIA offload verified on an Intel iGPU + NVIDIA RTX 4090 laptop under native Wayland (renderD128, nvidia-smi shows AetherSDR as a graphics process).
  • ⚠️ Linux AMD/Intel DRI_PRIME path follows Mesa's documented PCI-tag semantics but is not soaked (no AMD-dGPU box here).
  • ⚠️ Windows QT_D3D_ADAPTER_INDEX is CI-built but needs a Windows hardware tester (incl. the NvOptimusEnablement-vs-Integrated interaction above).

Requesting maintainer approval (and any scope adjustments — e.g. whether to gate non-soaked platform paths behind validation) before merging #3656.

Metadata

Metadata

Assignees

No one assigned

    Labels

    GUIUser interfaceenhancementImprovement to existing featurepriority: lowLow priorityrfcspectrumPanadapter and waterfall

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions