-
-
Notifications
You must be signed in to change notification settings - Fork 70
Description
Summary
On a dual-AMD system (RDNA4 + Polaris), an output connected to the secondary AMD GPU (RX 480) stays black when another AMD GPU (RX 9070) is the primary DRM device.
Aquamarine detects the connector, creates an output and renderer, and Hyprland assigns a workspace, but the frame commit fails with:
EGL (verifyDestinationDMABUF): FAIL, format is external-onlyEGL (blit): failed to blit: destination dmabuf unsupporteddrm: Backend requires blit, but blit failedCouldn't commit output named DP-4
If I reverse the AQ_DRM_DEVICES order so that the RX 480 becomes the primary DRM GPU, all monitors (including DP-4) work fine. So this seems to be a multi-GPU blit/DMABUF issue between two AMD GPUs, not a configuration or EDID problem.
Environment
- OS: NixOS 25.11 (unstable)
- Kernel:
6.17.9-cachyos - GPUs:
03:00.0AMD Radeon RX 9070 XT (Navi 48) – intended primary / main GPU09:00.0AMD Radeon RX 480 (Ellesmere/Polaris10) – secondary, DP-4 monitor attached0b:00.0AMD RX 580 – bound tovfio-pci(not used by Aquamarine)0c:00.0NVIDIA RTX 2080 – bound tovfio-pci(not used by Aquamarine)
- Mesa:
25.3.0
(fromOpenGL version string: 4.6 (Compatibility Profile) Mesa 25.3.0) - Hyprland: from NixOS
nixpkgshyprlandpackage (unstable channel)-
Hyprland --version:Hyprland 0.52.1 built from branch unknown at commit unknown unknown (unknown). Date: unknown Tag: unknown, commits: 0 Libraries: Hyprgraphics: built against 0.4.0, system has unknown Hyprutils: built against 0.10.2, system has unknown Hyprcursor: built against 0.1.13, system has unknown Hyprlang: built against 0.6.6, system has unknown Aquamarine: built against 0.9.5, system has unknown
-
Aquamarine is whatever version Hyprland 0.52.1 in nixpkgs is built against (Hyprland reports built against 0.9.5 above).
Configuration relevant to Aquamarine / DRM
I use udev rules to create stable symlinks for the two AMD GPUs:
services.udev.extraRules = ''
# RX 9070 XT: 03:00.0 -> /dev/dri/gpu-9070
SUBSYSTEM=="drm", KERNEL=="card*", SUBSYSTEMS=="pci", \
KERNELS=="0000:03:00.0", SYMLINK+="dri/gpu-9070"
# RX 480: 09:00.0 -> /dev/dri/gpu-480
SUBSYSTEM=="drm", KERNEL=="card*", SUBSYSTEMS=="pci", \
KERNELS=="0000:09:00.0", SYMLINK+="dri/gpu-480"
'';Environment variables (set via NixOS):
environment.sessionVariables = {
# Failing setup (bug present):
# AQ_DRM_DEVICES = "/dev/dri/gpu-9070:/dev/dri/gpu-480";
# Working setup (used for comparison and daily use):
# AQ_DRM_DEVICES = "/dev/dri/gpu-480:/dev/dri/gpu-9070";
LIBVA_DRIVER_NAME = "radeonsi";
VDPAU_DRIVER = "radeonsi";
AMD_VULKAN_ICD = "RADV";
};Hyprland config (relevant bits):
debug {
full_cm_proto = true
disable_logs = false
}
cursor {
no_hardware_cursors = true
}
# Aquamarine-related envs in hyprland.conf
env = AQ_NO_MODIFIERS,1
env = AQ_MGPU_NO_EXPLICIT,1I start the debug session from a TTY like this:
HYPRLAND_TRACE=1 AQ_TRACE=1 Hyprlandand collect the log from $XDG_RUNTIME_DIR/hypr/<instance>/hyprland.log.
Reproduction steps
-
Boot into NixOS with both GPUs active:
- RX 9070: primary GPU, several monitors attached (DP-1, DP-2, DP-3, HDMI-A-1)
- RX 480: one monitor attached on DP-4 (1680×1050)
-
Set environment (either via NixOS config or temporarily in the TTY):
export AQ_DRM_DEVICES=/dev/dri/gpu-9070:/dev/dri/gpu-480 export AQ_NO_MODIFIERS=1 export AQ_MGPU_NO_EXPLICIT=1
-
Start Hyprland from a TTY with tracing enabled:
HYPRLAND_TRACE=1 AQ_TRACE=1 Hyprland
-
Hyprland/Aquamarine start correctly, all monitors on RX 9070 work.
-
The DP-4 monitor on RX 480:
- wakes up (no “no signal” OSD),
- is reported by
hyprctl monitorsas an active monitor with workspace and correct mode (1680×[1050@59.95Hz](mailto:1050@59.95Hz)), - but stays completely black (no background, no cursor, no windows).
-
Check
hyprland.log– see error lines shown below.
Now change the environment to:
export AQ_DRM_DEVICES=/dev/dri/gpu-480:/dev/dri/gpu-9070and restart Hyprland.
With RX 480 as first/primary and RX 9070 second, all outputs including DP-4 work perfectly, with the same hardware and Hyprland config.
Expected behavior
With:
AQ_DRM_DEVICES=/dev/dri/gpu-9070:/dev/dri/gpu-480I expect:
-
Primary DRM GPU: RX 9070
-
Secondary DRM GPU: RX 480
-
Both GPUs usable by Aquamarine, including:
- All monitors on RX 9070 working
- Monitor on RX 480 (DP-4) also showing the compositor output (desktop, cursor, windows), like it does when RX 480 is primary.
In other words: cross-GPU blitting from the primary GPU’s renderer to the secondary GPU’s scanout should succeed, or at least degrade gracefully, not result in a black screen.
Actual behavior
With AQ_DRM_DEVICES=/dev/dri/gpu-9070:/dev/dri/gpu-480:
-
Aquamarine detects RX 9070 as primary DRM GPU:
[LOG] [AQ] drm: gpu /dev/dri/card1 becomes primary drm -
It then detects and initializes DP-4 on RX 480:
[LOG] [AQ] drm: Basic init pass for gpu /dev/dri/card0 [LOG] [AQ] drm: Scanning connector id 92 [LOG] [AQ] drm: Initializing connector id 92 [LOG] [AQ] drm: Connector gets name DP-4 ... [LOG] [AQ] drm: Connector DP-4 connected [LOG] [AQ] drm: Connecting connector DP-4, CRTC ID 75 [LOG] [AQ] drm: Dumping detected modes: [LOG] [AQ] drm: Mode 0: 1680x1050@59.95Hz (preferred) ... [LOG] [AQ] drm: Description Acer Technologies P223W LAW0C0158610 (DP-4) -
Aquamarine creates a renderer on RX 480:
[LOG] [AQ] CDRMRenderer(drm): Using device /dev/dri/card0 [LOG] [AQ] Creating CDRMRenderer on gpu /dev/dri/renderD129 [LOG] [AQ] Renderer: AMD Radeon RX 480 Graphics (radeonsi, polaris10, ...)
Then the multi-GPU blit path kicks in and fails:
[LOG] [AQ] drm: Modesetting DP-4 with 1680x1050@59.95Hz
[TRACE] [AQ] drm: Committed a buffer, updating state
[TRACE] [AQ] drm: Backend requires blit, blitting
[WARN] [AQ] GBM: Using modifier-less allocation
[LOG] [AQ] GBM: Allocated a new buffer ... modifier 72057594037927935 aka INVALID
...
[ERR] [AQ] EGL (verifyDestinationDMABUF): FAIL, format is external-only
[ERR] [AQ] EGL (blit): failed to blit: destination dmabuf unsupported
[ERR] [AQ] drm: Backend requires blit, but blit failed
[ERR] Couldn't commit output named DP-4
[LOG] Monitor DP-4 -> destroyed all render data
Result:
-
DP-4 remains black, even though:
- The monitor is considered connected and active by DRM,
- Hyprland lists it as an active monitor with a workspace.
With the reversed order:
AQ_DRM_DEVICES=/dev/dri/gpu-480:/dev/dri/gpu-9070the above error path does not trigger and DP-4 works as expected.
Additional context
-
This is not a simple EDID/CRTC issue:
- The connector modes and EDID for DP-4 look correct.
- The same monitor and cable work fine when the RX 480 is first in
AQ_DRM_DEVICES.
-
The issue only appears when:
- The primary DRM GPU is RX 9070,
- The secondary DRM GPU is RX 480,
- And DP-4 is connected to RX 480.
-
Other GPUs (RX 580, RTX 2080) are bound to
vfio-pciand should be ignored by Aquamarine.
From my reading of the log, the core bug seems to be that the destination DMABUF for the secondary GPU’s output is marked “external-only” and Aquamarine aborts the blit instead of using a compatible intermediate buffer or a safer fallback path, which results in the output being unusable even though it’s otherwise properly detected and modeset.
I’m happy to test patches or additional debug instrumentation if that helps.