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.
This commit is contained in:
Tom Englund 2026-02-21 21:27:59 +01:00 committed by GitHub
parent a20142bcce
commit 9f59ed7868
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 29 additions and 2 deletions

20
src/helpers/Drm.cpp Normal file
View file

@ -0,0 +1,20 @@
#include <xf86drm.h>
#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;
}

5
src/helpers/Drm.hpp Normal file
View file

@ -0,0 +1,5 @@
#pragma once
namespace DRM {
bool sameGpu(int fd1, int fd2);
}

View file

@ -32,6 +32,7 @@
#include "time/Time.hpp"
#include "../desktop/view/LayerSurface.hpp"
#include "../desktop/state/FocusState.hpp"
#include "Drm.hpp"
#include <aquamarine/output/Output.hpp>
#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()) {

View file

@ -17,6 +17,7 @@
#include "../desktop/state/FocusState.hpp"
#include "SeatManager.hpp"
#include "../helpers/time/Time.hpp"
#include "../helpers/Drm.hpp"
#include <cstring>
#include <gbm.h>
#include <cairo/cairo.h>
@ -440,7 +441,7 @@ SP<Aquamarine::IBuffer> CPointerManager::renderHWCursorBuffer(SP<CPointerManager
options.length = 2;
options.scanout = true;
options.cursor = true;
options.multigpu = state->monitor->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)