From 9f59ed786856df8a28430e4084491c7e9fa6234f Mon Sep 17 00:00:00 2001 From: Tom Englund Date: Sat, 21 Feb 2026 21:27:59 +0100 Subject: [PATCH] multigpu: fix multi gpu checking (#13277) * multigpu: fix multi gpu checking drmFD() from allocators is not always equal, because we reopen them inside AQ for refcounting, meaning they get duplicated and become their own fds, so checking if fd1 == fd2 ends up wrong. introduce sameGpu in MiscFunctions that checks the actual drmDevice meaning we can now even check if a rendernode is the same gpu as a display node if we want. * multigpu: move sameGpu to DRM namespace move sameGpu out of MiscFunctions to DRM namespace. --- src/helpers/Drm.cpp | 20 ++++++++++++++++++++ src/helpers/Drm.hpp | 5 +++++ src/helpers/Monitor.cpp | 3 ++- src/managers/PointerManager.cpp | 3 ++- 4 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 src/helpers/Drm.cpp create mode 100644 src/helpers/Drm.hpp diff --git a/src/helpers/Drm.cpp b/src/helpers/Drm.cpp new file mode 100644 index 00000000..207b5e3d --- /dev/null +++ b/src/helpers/Drm.cpp @@ -0,0 +1,20 @@ +#include +#include "Drm.hpp" + +bool DRM::sameGpu(int fd1, int fd2) { + drmDevice* devA = nullptr; + drmDevice* devB = nullptr; + + if (drmGetDevice2(fd1, 0, &devA) != 0) + return false; + if (drmGetDevice2(fd2, 0, &devB) != 0) { + drmFreeDevice(&devA); + return false; + } + + bool same = drmDevicesEqual(devA, devB); + + drmFreeDevice(&devA); + drmFreeDevice(&devB); + return same; +} diff --git a/src/helpers/Drm.hpp b/src/helpers/Drm.hpp new file mode 100644 index 00000000..bc56b1ee --- /dev/null +++ b/src/helpers/Drm.hpp @@ -0,0 +1,5 @@ +#pragma once + +namespace DRM { + bool sameGpu(int fd1, int fd2); +} diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp index f03315ca..6cc0087a 100644 --- a/src/helpers/Monitor.cpp +++ b/src/helpers/Monitor.cpp @@ -32,6 +32,7 @@ #include "time/Time.hpp" #include "../desktop/view/LayerSurface.hpp" #include "../desktop/state/FocusState.hpp" +#include "Drm.hpp" #include #include "debug/log/Logger.hpp" #include "debug/HyprNotificationOverlay.hpp" @@ -1895,7 +1896,7 @@ bool CMonitor::attemptDirectScanout() { m_output->state->addDamage(PSURFACE->m_current.accumulateBufferDamage()); // multigpu needs a fence to trigger fence syncing blits and also committing with the recreated dgpu fence - if (m_output->getBackend()->preferredAllocator()->drmFD() != g_pCompositor->m_drm.fd && g_pHyprOpenGL->explicitSyncSupported()) { + if (!DRM::sameGpu(m_output->getBackend()->preferredAllocator()->drmFD(), g_pCompositor->m_drm.fd) && g_pHyprOpenGL->explicitSyncSupported()) { auto sync = CEGLSync::create(); if (sync->fd().isValid()) { diff --git a/src/managers/PointerManager.cpp b/src/managers/PointerManager.cpp index 57e25791..2d752ea7 100644 --- a/src/managers/PointerManager.cpp +++ b/src/managers/PointerManager.cpp @@ -17,6 +17,7 @@ #include "../desktop/state/FocusState.hpp" #include "SeatManager.hpp" #include "../helpers/time/Time.hpp" +#include "../helpers/Drm.hpp" #include #include #include @@ -440,7 +441,7 @@ SP CPointerManager::renderHWCursorBuffer(SPmonitor->m_output->getBackend()->preferredAllocator()->drmFD() != g_pCompositor->m_drm.fd; + options.multigpu = !DRM::sameGpu(state->monitor->m_output->getBackend()->preferredAllocator()->drmFD(), g_pCompositor->m_drm.fd); // We do not set the format (unless shm). If it's unset (DRM_FORMAT_INVALID) then the swapchain will pick for us, // but if it's set, we don't wanna change it. if (shouldUseCpuBuffer)