From db97342250519c5375bfa1d22bbbcd0feaaf4f81 Mon Sep 17 00:00:00 2001 From: Tom Englund Date: Fri, 18 Jul 2025 21:23:01 +0200 Subject: [PATCH 01/11] syncobj: use rendernode for timelines use rendernode for timelines instead of the drmfd, some devices dont support to use the drmfd for this. --- src/Compositor.cpp | 33 +++++++++++++++++++++------------ src/Compositor.hpp | 17 ++++++++++++----- src/managers/PointerManager.cpp | 2 +- src/protocols/DRMSyncobj.cpp | 10 ++++++++-- src/protocols/LinuxDMABUF.cpp | 2 +- src/protocols/MesaDRM.cpp | 2 +- src/render/OpenGL.cpp | 2 +- src/render/Renderer.cpp | 2 +- 8 files changed, 46 insertions(+), 24 deletions(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index a273304252c..bd035640855 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -169,7 +169,7 @@ void CCompositor::restoreNofile() { } bool CCompositor::supportsDrmSyncobjTimeline() const { - return m_bDrmSyncobjTimelineSupported; + return m_drm.syncobjSupport || m_drmRenderNode.syncObjSupport; } void CCompositor::setMallocThreshold() { @@ -356,19 +356,28 @@ void CCompositor::initServer(std::string socketName, int socketFd) { m_initialized = true; - m_drmFD = m_aqBackend->drmFD(); - Debug::log(LOG, "Running on DRMFD: {}", m_drmFD); + m_drm.fd = m_aqBackend->drmFD(); + Debug::log(LOG, "Running on DRMFD: {}", m_drm.fd); + + m_drmRenderNode.fd = m_aqBackend->drmRenderNodeFD(); + Debug::log(LOG, "Using RENDERNODEFD: {}", m_drmRenderNode.fd); #if defined(__linux__) - if (m_drmFD >= 0) { - uint64_t cap = 0; - int ret = drmGetCap(m_drmFD, DRM_CAP_SYNCOBJ_TIMELINE, &cap); - m_bDrmSyncobjTimelineSupported = (ret == 0 && cap != 0); - Debug::log(LOG, "DRM syncobj timeline support: {}", m_bDrmSyncobjTimelineSupported ? "yes" : "no"); - } else { - m_bDrmSyncobjTimelineSupported = false; - Debug::log(LOG, "DRM syncobj timeline support: no (no DRM FD)"); - } + auto syncObjSupport = [](auto fd) { + if (fd < 0) + return false; + + uint64_t cap = 0; + int ret = drmGetCap(fd, DRM_CAP_SYNCOBJ_TIMELINE, &cap); + return ret == 0 && cap != 0; + }; + + if ((m_drm.syncobjSupport = syncObjSupport(m_drm.fd))) + Debug::log(LOG, "DRM DisplayNode syncobj timeline support: {}", m_drm.syncobjSupport ? "yes" : "no"); + else if ((m_drmRenderNode.syncObjSupport = syncObjSupport(m_drmRenderNode.fd))) + Debug::log(LOG, "DRM RenderNode syncobj timeline support: {}", m_drmRenderNode.syncObjSupport ? "yes" : "no"); + else + Debug::log(LOG, "DRM no syncobj support, disabling explicit sync"); #else Debug::log(LOG, "DRM syncobj timeline support: no (not linux)"); m_bDrmSyncobjTimelineSupported = false; diff --git a/src/Compositor.hpp b/src/Compositor.hpp index 70b18691e69..eddbe677e06 100644 --- a/src/Compositor.hpp +++ b/src/Compositor.hpp @@ -27,9 +27,18 @@ class CCompositor { CCompositor(bool onlyConfig = false); ~CCompositor(); - wl_display* m_wlDisplay = nullptr; - wl_event_loop* m_wlEventLoop = nullptr; - int m_drmFD = -1; + wl_display* m_wlDisplay = nullptr; + wl_event_loop* m_wlEventLoop = nullptr; + struct { + int fd = -1; + bool syncobjSupport = false; + } m_drm; + + struct { + int fd = -1; + bool syncObjSupport = false; + } m_drmRenderNode; + bool m_initialized = false; SP m_aqBackend; @@ -175,8 +184,6 @@ class CCompositor { void removeLockFile(); void setMallocThreshold(); - bool m_bDrmSyncobjTimelineSupported = false; - uint64_t m_hyprlandPID = 0; wl_event_source* m_critSigSource = nullptr; rlimit m_originalNofile = {}; diff --git a/src/managers/PointerManager.cpp b/src/managers/PointerManager.cpp index 318ec343b1f..f563581082a 100644 --- a/src/managers/PointerManager.cpp +++ b/src/managers/PointerManager.cpp @@ -432,7 +432,7 @@ SP CPointerManager::renderHWCursorBuffer(SPmonitor->m_output->getBackend()->preferredAllocator()->drmFD() != g_pCompositor->m_drmFD; + options.multigpu = 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) diff --git a/src/protocols/DRMSyncobj.cpp b/src/protocols/DRMSyncobj.cpp index bedec422e7c..13e6dd000bc 100644 --- a/src/protocols/DRMSyncobj.cpp +++ b/src/protocols/DRMSyncobj.cpp @@ -199,8 +199,14 @@ bool CDRMSyncobjManagerResource::good() { return m_resource->resource(); } -CDRMSyncobjProtocol::CDRMSyncobjProtocol(const wl_interface* iface, const int& ver, const std::string& name) : - IWaylandProtocol(iface, ver, name), m_drmFD(g_pCompositor->m_drmFD) {} +CDRMSyncobjProtocol::CDRMSyncobjProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) { + if (g_pCompositor->m_drm.syncobjSupport) + m_drmFD = g_pCompositor->m_drm.fd; + else if (g_pCompositor->m_drmRenderNode.syncObjSupport) + m_drmFD = g_pCompositor->m_drmRenderNode.fd; + + LOGM(LOG, "CDRMSyncobjProtocol: using fd {}", m_drmFD); +} void CDRMSyncobjProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { const auto& RESOURCE = m_managers.emplace_back(makeUnique(makeUnique(client, ver, id))); diff --git a/src/protocols/LinuxDMABUF.cpp b/src/protocols/LinuxDMABUF.cpp index 24cf2951738..82aa2997377 100644 --- a/src/protocols/LinuxDMABUF.cpp +++ b/src/protocols/LinuxDMABUF.cpp @@ -408,7 +408,7 @@ void CLinuxDMABUFResource::sendMods() { CLinuxDMABufV1Protocol::CLinuxDMABufV1Protocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) { static auto P = g_pHookSystem->hookDynamic("ready", [this](void* self, SCallbackInfo& info, std::any d) { - int rendererFD = g_pCompositor->m_drmFD; + int rendererFD = g_pCompositor->m_drm.fd; auto dev = devIDFromFD(rendererFD); if (!dev.has_value()) { diff --git a/src/protocols/MesaDRM.cpp b/src/protocols/MesaDRM.cpp index 45ee24c51c5..b9189e8edf6 100644 --- a/src/protocols/MesaDRM.cpp +++ b/src/protocols/MesaDRM.cpp @@ -113,7 +113,7 @@ bool CMesaDRMResource::good() { CMesaDRMProtocol::CMesaDRMProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) { drmDevice* dev = nullptr; - int drmFD = g_pCompositor->m_drmFD; + int drmFD = g_pCompositor->m_drm.fd; if (drmGetDevice2(drmFD, 0, &dev) != 0) { LOGM(ERR, "Failed to get device, disabling MesaDRM"); removeGlobal(); diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index 27abe81f077..462459101fb 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -254,7 +254,7 @@ EGLDeviceEXT CHyprOpenGLImpl::eglDeviceFromDRMFD(int drmFD) { return EGL_NO_DEVICE_EXT; } -CHyprOpenGLImpl::CHyprOpenGLImpl() : m_drmFD(g_pCompositor->m_drmFD) { +CHyprOpenGLImpl::CHyprOpenGLImpl() : m_drmFD(g_pCompositor->m_drm.fd) { const std::string EGLEXTENSIONS = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); Debug::log(LOG, "Supported EGL global extensions: ({}) {}", std::ranges::count(EGLEXTENSIONS, ' '), EGLEXTENSIONS); diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index beeb0f5ad67..5879710225d 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -79,7 +79,7 @@ CHyprRenderer::CHyprRenderer() { } else { Debug::log(LOG, "Aq backend has no session, omitting full DRM node checks"); - const auto DRMV = drmGetVersion(g_pCompositor->m_drmFD); + const auto DRMV = drmGetVersion(g_pCompositor->m_drm.fd); if (DRMV) { std::string name = std::string{DRMV->name, DRMV->name_len}; From 88b5f398741f2cdfda275557a25a3765c5112e28 Mon Sep 17 00:00:00 2001 From: Tom Englund Date: Sat, 19 Jul 2025 01:50:40 +0200 Subject: [PATCH 02/11] opengl: use rendernode if available use rendernode if available for CHyprOpenglImpl --- src/render/OpenGL.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index 462459101fb..f4599a84ffc 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -254,7 +254,7 @@ EGLDeviceEXT CHyprOpenGLImpl::eglDeviceFromDRMFD(int drmFD) { return EGL_NO_DEVICE_EXT; } -CHyprOpenGLImpl::CHyprOpenGLImpl() : m_drmFD(g_pCompositor->m_drm.fd) { +CHyprOpenGLImpl::CHyprOpenGLImpl() : m_drmFD(g_pCompositor->m_drmRenderNode.fd >= 0 ? g_pCompositor->m_drmRenderNode.fd : g_pCompositor->m_drm.fd) { const std::string EGLEXTENSIONS = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); Debug::log(LOG, "Supported EGL global extensions: ({}) {}", std::ranges::count(EGLEXTENSIONS, ' '), EGLEXTENSIONS); From be00862370bf102adb8c190eb931e88b8a9c86a1 Mon Sep 17 00:00:00 2001 From: Tom Englund Date: Sat, 19 Jul 2025 19:30:01 +0200 Subject: [PATCH 03/11] MesaDRM: use the m_drmRenderNodeFD if it exist try use the rendernode we got from AQ if it exist. --- src/protocols/MesaDRM.cpp | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/src/protocols/MesaDRM.cpp b/src/protocols/MesaDRM.cpp index b9189e8edf6..789f90b6c8b 100644 --- a/src/protocols/MesaDRM.cpp +++ b/src/protocols/MesaDRM.cpp @@ -113,28 +113,26 @@ bool CMesaDRMResource::good() { CMesaDRMProtocol::CMesaDRMProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) { drmDevice* dev = nullptr; - int drmFD = g_pCompositor->m_drm.fd; + int drmFD = g_pCompositor->m_drmRenderNode.fd >= 0 ? g_pCompositor->m_drmRenderNode.fd : g_pCompositor->m_drm.fd; + if (drmGetDevice2(drmFD, 0, &dev) != 0) { - LOGM(ERR, "Failed to get device, disabling MesaDRM"); + LOGM(ERR, "Failed to get device from fd {}, disabling MesaDRM", drmFD); removeGlobal(); return; } - if (dev->available_nodes & (1 << DRM_NODE_RENDER)) { + if (dev->available_nodes & (1 << DRM_NODE_RENDER) && dev->nodes[DRM_NODE_RENDER]) { m_nodeName = dev->nodes[DRM_NODE_RENDER]; - } else { - ASSERT(dev->available_nodes & (1 << DRM_NODE_PRIMARY)); - - if (!dev->nodes[DRM_NODE_PRIMARY]) { - LOGM(ERR, "No DRM render node available, both render and primary are null, disabling MesaDRM"); - drmFreeDevice(&dev); - removeGlobal(); - return; - } - + } else if (dev->available_nodes & (1 << DRM_NODE_PRIMARY) && dev->nodes[DRM_NODE_PRIMARY]) { LOGM(WARN, "No DRM render node, falling back to primary {}", dev->nodes[DRM_NODE_PRIMARY]); m_nodeName = dev->nodes[DRM_NODE_PRIMARY]; + } else { + LOGM(ERR, "No usable DRM node (render or primary) found, disabling MesaDRM"); + drmFreeDevice(&dev); + removeGlobal(); + return; } + drmFreeDevice(&dev); } From 81316ee3f243f6bdde068683b81726714ca8b12c Mon Sep 17 00:00:00 2001 From: Tom Englund Date: Sun, 10 Aug 2025 20:55:55 +0200 Subject: [PATCH 04/11] linuxdmabuf: use rendernode if available use the rendernode if available already from AQ --- src/protocols/LinuxDMABUF.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/protocols/LinuxDMABUF.cpp b/src/protocols/LinuxDMABUF.cpp index 82aa2997377..c7de03a293a 100644 --- a/src/protocols/LinuxDMABUF.cpp +++ b/src/protocols/LinuxDMABUF.cpp @@ -408,7 +408,7 @@ void CLinuxDMABUFResource::sendMods() { CLinuxDMABufV1Protocol::CLinuxDMABufV1Protocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) { static auto P = g_pHookSystem->hookDynamic("ready", [this](void* self, SCallbackInfo& info, std::any d) { - int rendererFD = g_pCompositor->m_drm.fd; + int rendererFD = g_pCompositor->m_drmRenderNode.fd >= 0 ? g_pCompositor->m_drmRenderNode.fd : g_pCompositor->m_drm.fd; auto dev = devIDFromFD(rendererFD); if (!dev.has_value()) { @@ -467,6 +467,19 @@ CLinuxDMABufV1Protocol::CLinuxDMABufV1Protocol(const wl_interface* iface, const return; } + if (g_pCompositor->m_drmRenderNode.fd >= 0 && rendererFD == g_pCompositor->m_drmRenderNode.fd) { + // Already using the compositor's render node, reuse it. + m_mainDeviceFD = CFileDescriptor{fcntl(g_pCompositor->m_drmRenderNode.fd, F_DUPFD_CLOEXEC, 0)}; + drmFreeDevice(&device); + if (!m_mainDeviceFD.isValid()) { + LOGM(ERR, "failed to open rendernode, disabling linux dmabuf"); + removeGlobal(); + return; + } + + return; // already using rendernode. + } + if (device->available_nodes & (1 << DRM_NODE_RENDER)) { const char* name = device->nodes[DRM_NODE_RENDER]; m_mainDeviceFD = CFileDescriptor{open(name, O_RDWR | O_CLOEXEC)}; From 18a1de9fd3b8029893eb99e414e6b190a7e73fd3 Mon Sep 17 00:00:00 2001 From: Tom Englund Date: Mon, 11 Aug 2025 12:02:17 +0200 Subject: [PATCH 05/11] syncobj: prefer rendernode over displaynode prefer the rendernode over the displaynode, and log a error if attempting to use the protocol without explicit sync support on any of the nodes. --- src/protocols/DRMSyncobj.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/protocols/DRMSyncobj.cpp b/src/protocols/DRMSyncobj.cpp index 13e6dd000bc..0896b904260 100644 --- a/src/protocols/DRMSyncobj.cpp +++ b/src/protocols/DRMSyncobj.cpp @@ -200,10 +200,14 @@ bool CDRMSyncobjManagerResource::good() { } CDRMSyncobjProtocol::CDRMSyncobjProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) { - if (g_pCompositor->m_drm.syncobjSupport) - m_drmFD = g_pCompositor->m_drm.fd; - else if (g_pCompositor->m_drmRenderNode.syncObjSupport) + if (g_pCompositor->m_drmRenderNode.syncObjSupport) m_drmFD = g_pCompositor->m_drmRenderNode.fd; + else if (g_pCompositor->m_drm.syncobjSupport) + m_drmFD = g_pCompositor->m_drm.fd; + else { + LOGM(ERR, "CDRMSyncobjProtocol: no nodes support explicit sync?"); + return; + } LOGM(LOG, "CDRMSyncobjProtocol: using fd {}", m_drmFD); } From 2e0b54e505558779eaf620723b980ae1d32cbb33 Mon Sep 17 00:00:00 2001 From: Tom Englund Date: Fri, 15 Aug 2025 18:46:52 +0200 Subject: [PATCH 06/11] syncobj: check support on both nodes always check support on both nodes always so it can be used later for preferring rendernode if possible in syncobj protocol. --- src/Compositor.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index bd035640855..6cf07bf1873 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -374,9 +374,11 @@ void CCompositor::initServer(std::string socketName, int socketFd) { if ((m_drm.syncobjSupport = syncObjSupport(m_drm.fd))) Debug::log(LOG, "DRM DisplayNode syncobj timeline support: {}", m_drm.syncobjSupport ? "yes" : "no"); - else if ((m_drmRenderNode.syncObjSupport = syncObjSupport(m_drmRenderNode.fd))) + + if ((m_drmRenderNode.syncObjSupport = syncObjSupport(m_drmRenderNode.fd))) Debug::log(LOG, "DRM RenderNode syncobj timeline support: {}", m_drmRenderNode.syncObjSupport ? "yes" : "no"); - else + + if (!m_drm.syncobjSupport && !m_drmRenderNode.syncObjSupport) Debug::log(LOG, "DRM no syncobj support, disabling explicit sync"); #else Debug::log(LOG, "DRM syncobj timeline support: no (not linux)"); From 2664bdc8ad3499a447c63d9b3a44da9621bafc43 Mon Sep 17 00:00:00 2001 From: Tom Englund Date: Fri, 15 Aug 2025 18:53:22 +0200 Subject: [PATCH 07/11] syncobj: remove old var in non linux if else case remove old m_bDrmSyncobjTimelineSupported from non linux if else case that will fail to compile on non linux. the nodes sets support by default to false, and if non linux it wont check for support and set it to true. --- src/Compositor.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 6cf07bf1873..cbb70e2bf80 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -382,7 +382,6 @@ void CCompositor::initServer(std::string socketName, int socketFd) { Debug::log(LOG, "DRM no syncobj support, disabling explicit sync"); #else Debug::log(LOG, "DRM syncobj timeline support: no (not linux)"); - m_bDrmSyncobjTimelineSupported = false; #endif if (!socketName.empty() && socketFd != -1) { From d4472e09aa6686f95bb8044e8ca6dece9e0e4a09 Mon Sep 17 00:00:00 2001 From: Tom Englund Date: Sun, 17 Aug 2025 16:19:45 +0200 Subject: [PATCH 08/11] build: bump aq requirement bump to 0.9.3 where rendernode support got added. --- CMakeLists.txt | 2 +- meson.build | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4d053742b03..643f7dc6a31 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -105,7 +105,7 @@ find_package(Threads REQUIRED) set(GLES_VERSION "GLES3") find_package(OpenGL REQUIRED COMPONENTS ${GLES_VERSION}) -pkg_check_modules(aquamarine_dep REQUIRED IMPORTED_TARGET aquamarine>=0.9.0) +pkg_check_modules(aquamarine_dep REQUIRED IMPORTED_TARGET aquamarine>=0.9.3) pkg_check_modules(hyprlang_dep REQUIRED IMPORTED_TARGET hyprlang>=0.3.2) pkg_check_modules(hyprcursor_dep REQUIRED IMPORTED_TARGET hyprcursor>=0.1.7) pkg_check_modules(hyprutils_dep REQUIRED IMPORTED_TARGET hyprutils>=0.8.2) diff --git a/meson.build b/meson.build index e2b520d37a6..6b04ff9a209 100644 --- a/meson.build +++ b/meson.build @@ -31,7 +31,7 @@ if cpp_compiler.check_header('execinfo.h') add_project_arguments('-DHAS_EXECINFO', language: 'cpp') endif -aquamarine = dependency('aquamarine', version: '>=0.9.0') +aquamarine = dependency('aquamarine', version: '>=0.9.3') hyprcursor = dependency('hyprcursor', version: '>=0.1.7') hyprgraphics = dependency('hyprgraphics', version: '>= 0.1.3') hyprlang = dependency('hyprlang', version: '>= 0.3.2') From 6c18c9c707051a97924847c9418dc3f574bdcbef Mon Sep 17 00:00:00 2001 From: Mihai Fufezan Date: Sun, 17 Aug 2025 18:06:50 +0300 Subject: [PATCH 09/11] flake.lock: update --- flake.lock | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/flake.lock b/flake.lock index 13254efb5ec..75a360636a2 100644 --- a/flake.lock +++ b/flake.lock @@ -16,11 +16,11 @@ ] }, "locked": { - "lastModified": 1753216019, - "narHash": "sha256-zik7WISrR1ks2l6T1MZqZHb/OqroHdJnSnAehkE0kCk=", + "lastModified": 1755458170, + "narHash": "sha256-2bIfLxQQ5QOfpd3wgEbNFnFV13FgvgDiAiynfzSUfaU=", "owner": "hyprwm", "repo": "aquamarine", - "rev": "be166e11d86ba4186db93e10c54a141058bdce49", + "rev": "84d53cadf8b7908c0f697aca46983ac8919939f4", "type": "github" }, "original": { @@ -238,11 +238,11 @@ ] }, "locked": { - "lastModified": 1754481650, - "narHash": "sha256-6u6HdEFJh5gY6VfyMQbhP7zDdVcqOrCDTkbiHJmAtMI=", + "lastModified": 1755416120, + "narHash": "sha256-PosTxeL39YrLvCX5MqqPA6NNWQ4T5ea5K55nmN7ju9Q=", "owner": "hyprwm", "repo": "hyprutils", - "rev": "df6b8820c4a0835d83d0c7c7be86fbc555f1f7fd", + "rev": "e631ea36ddba721eceda69bfee6dd01068416489", "type": "github" }, "original": { @@ -261,11 +261,11 @@ ] }, "locked": { - "lastModified": 1751897909, - "narHash": "sha256-FnhBENxihITZldThvbO7883PdXC/2dzW4eiNvtoV5Ao=", + "lastModified": 1755184602, + "narHash": "sha256-RCBQN8xuADB0LEgaKbfRqwm6CdyopE1xIEhNc67FAbw=", "owner": "hyprwm", "repo": "hyprwayland-scanner", - "rev": "fcca0c61f988a9d092cbb33e906775014c61579d", + "rev": "b3b0f1f40ae09d4447c20608e5a4faf8bf3c492d", "type": "github" }, "original": { @@ -276,11 +276,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1754725699, - "narHash": "sha256-iAcj9T/Y+3DBy2J0N+yF9XQQQ8IEb5swLFzs23CdP88=", + "lastModified": 1755186698, + "narHash": "sha256-wNO3+Ks2jZJ4nTHMuks+cxAiVBGNuEBXsT29Bz6HASo=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "85dbfc7aaf52ecb755f87e577ddbe6dbbdbc1054", + "rev": "fbcf476f790d8a217c3eab4e12033dc4a0f6d23c", "type": "github" }, "original": { @@ -299,11 +299,11 @@ ] }, "locked": { - "lastModified": 1754416808, - "narHash": "sha256-c6yg0EQ9xVESx6HGDOCMcyRSjaTpNJP10ef+6fRcofA=", + "lastModified": 1755446520, + "narHash": "sha256-I0Ok1OGDwc1jPd8cs2VvAYZsHriUVFGIUqW+7uSsOUM=", "owner": "cachix", "repo": "git-hooks.nix", - "rev": "9c52372878df6911f9afc1e2a1391f55e4dfc864", + "rev": "4b04db83821b819bbbe32ed0a025b31e7971f22e", "type": "github" }, "original": { @@ -365,11 +365,11 @@ ] }, "locked": { - "lastModified": 1753633878, - "narHash": "sha256-js2sLRtsOUA/aT10OCDaTjO80yplqwOIaLUqEe0nMx0=", + "lastModified": 1755354946, + "narHash": "sha256-zdov5f/GcoLQc9qYIS1dUTqtJMeDqmBmo59PAxze6e4=", "owner": "hyprwm", "repo": "xdg-desktop-portal-hyprland", - "rev": "371b96bd11ad2006ed4f21229dbd1be69bed3e8a", + "rev": "a10726d6a8d0ef1a0c645378f983b6278c42eaa0", "type": "github" }, "original": { From 40ff3a24b61b124cc91046150fc9639a3ee45c4a Mon Sep 17 00:00:00 2001 From: Tom Englund Date: Tue, 19 Aug 2025 14:58:16 +0200 Subject: [PATCH 10/11] renderer: glfinish on software renderer software renderers apparently bug out on implicit sync, use glfinish as with nvidia case on implicit paths. --- src/render/Renderer.cpp | 12 ++++++++++-- src/render/Renderer.hpp | 2 ++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 5879710225d..cf8ed0bad59 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -69,6 +69,8 @@ CHyprRenderer::CHyprRenderer() { m_nvidia = true; else if (name.contains("i915")) m_intel = true; + else if (name.contains("softpipe") || name.contains("Software Rasterizer") || name.contains("llvmpipe")) + m_software = true; Debug::log(LOG, "DRM driver information: {} v{}.{}.{} from {} description {}", name, DRMV->version_major, DRMV->version_minor, DRMV->version_patchlevel, std::string{DRMV->date, DRMV->date_len}, std::string{DRMV->desc, DRMV->desc_len}); @@ -89,6 +91,8 @@ CHyprRenderer::CHyprRenderer() { m_nvidia = true; else if (name.contains("i915")) m_intel = true; + else if (name.contains("softpipe") || name.contains("Software Rasterizer") || name.contains("llvmpipe")) + m_software = true; Debug::log(LOG, "Primary DRM driver information: {} v{}.{}.{} from {} description {}", name, DRMV->version_major, DRMV->version_minor, DRMV->version_patchlevel, std::string{DRMV->date, DRMV->date_len}, std::string{DRMV->desc, DRMV->desc_len}); @@ -2234,8 +2238,8 @@ void CHyprRenderer::endRender(const std::function& renderingDoneCallback if (!g_pHyprOpenGL->explicitSyncSupported()) { Debug::log(TRACE, "renderer: Explicit sync unsupported, falling back to implicit in endRender"); - // nvidia doesn't have implicit sync, so we have to explicitly wait here - if (isNvidia() && *PNVIDIAANTIFLICKER) + // nvidia doesn't have implicit sync, so we have to explicitly wait here, llvmpipe and other software renderer seems to bug out aswell. + if ((isNvidia() && *PNVIDIAANTIFLICKER) || isSoftware()) glFinish(); else glFlush(); // mark an implicit sync point @@ -2295,6 +2299,10 @@ bool CHyprRenderer::isIntel() { return m_intel; } +bool CHyprRenderer::isSoftware() { + return m_software; +} + bool CHyprRenderer::isMgpu() { return m_mgpu; } diff --git a/src/render/Renderer.hpp b/src/render/Renderer.hpp index a986b63b8e7..b1e514f36a7 100644 --- a/src/render/Renderer.hpp +++ b/src/render/Renderer.hpp @@ -75,6 +75,7 @@ class CHyprRenderer { SP getCurrentRBO(); bool isNvidia(); bool isIntel(); + bool isSoftware(); bool isMgpu(); void makeEGLCurrent(); void unsetEGL(); @@ -143,6 +144,7 @@ class CHyprRenderer { eRenderMode m_renderMode = RENDER_MODE_NORMAL; bool m_nvidia = false; bool m_intel = false; + bool m_software = false; bool m_mgpu = false; struct { From 2673fcedfbdd3010f8366d540e93d8d6d9348379 Mon Sep 17 00:00:00 2001 From: Tom Englund Date: Wed, 20 Aug 2025 04:08:06 +0200 Subject: [PATCH 11/11] flake.lock: update --- flake.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/flake.lock b/flake.lock index 75a360636a2..62d536efd8e 100644 --- a/flake.lock +++ b/flake.lock @@ -16,11 +16,11 @@ ] }, "locked": { - "lastModified": 1755458170, - "narHash": "sha256-2bIfLxQQ5QOfpd3wgEbNFnFV13FgvgDiAiynfzSUfaU=", + "lastModified": 1755632680, + "narHash": "sha256-EjaD8+d7AiAV2fGRN4NTMboWDwk8szDfwbzZ8DL1PhQ=", "owner": "hyprwm", "repo": "aquamarine", - "rev": "84d53cadf8b7908c0f697aca46983ac8919939f4", + "rev": "50637ed23e962f0db294d6b0ef534f37b144644b", "type": "github" }, "original": {