From 744a383a52048485445d8b34570dd9b5d3fb28bb Mon Sep 17 00:00:00 2001 From: Vaxry Date: Wed, 24 Jul 2024 21:59:35 +0200 Subject: [PATCH 1/5] gbm: log scanout flag state in trace --- src/allocator/GBM.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/allocator/GBM.cpp b/src/allocator/GBM.cpp index cd2d280..c5056c5 100644 --- a/src/allocator/GBM.cpp +++ b/src/allocator/GBM.cpp @@ -65,7 +65,8 @@ Aquamarine::CGBMBuffer::CGBMBuffer(const SAllocatorBufferParams& params, Hypruti const bool MULTIGPU = params.multigpu && params.scanout; TRACE(allocator->backend->log(AQ_LOG_TRACE, - std::format("GBM: Allocating a buffer: size {}, format {}, cursor: {}, multigpu: {}", attrs.size, fourccToName(attrs.format), CURSOR, MULTIGPU))); + std::format("GBM: Allocating a buffer: size {}, format {}, cursor: {}, multigpu: {}, scanout: {}", attrs.size, fourccToName(attrs.format), CURSOR, + MULTIGPU, params.scanout))); const auto FORMATS = CURSOR ? swapchain->backendImpl->getCursorFormats() : From 353dc1b7299d43f08de44276b93ae32726ff9d70 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Wed, 24 Jul 2024 22:41:58 +0200 Subject: [PATCH 2/5] drm: conform to both renderable and scanoutable formats in scanout buffers fixes #28 --- src/allocator/GBM.cpp | 20 +++++++++++++++++--- src/backend/drm/DRM.cpp | 2 +- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/allocator/GBM.cpp b/src/allocator/GBM.cpp index c5056c5..3f972b4 100644 --- a/src/allocator/GBM.cpp +++ b/src/allocator/GBM.cpp @@ -68,9 +68,8 @@ Aquamarine::CGBMBuffer::CGBMBuffer(const SAllocatorBufferParams& params, Hypruti std::format("GBM: Allocating a buffer: size {}, format {}, cursor: {}, multigpu: {}, scanout: {}", attrs.size, fourccToName(attrs.format), CURSOR, MULTIGPU, params.scanout))); - const auto FORMATS = CURSOR ? - swapchain->backendImpl->getCursorFormats() : - (swapchain->backendImpl->getRenderableFormats().size() == 0 ? swapchain->backendImpl->getRenderFormats() : swapchain->backendImpl->getRenderableFormats()); + const auto FORMATS = CURSOR ? swapchain->backendImpl->getCursorFormats() : swapchain->backendImpl->getRenderFormats(); + const auto RENDERABLE = swapchain->backendImpl->getRenderableFormats(); std::vector explicitModifiers; @@ -95,6 +94,21 @@ Aquamarine::CGBMBuffer::CGBMBuffer(const SAllocatorBufferParams& params, Hypruti if (m == DRM_FORMAT_MOD_INVALID) continue; + if (!RENDERABLE.empty() && params.scanout && !CURSOR && !MULTIGPU) { + // regular scanout plane, check if the format is renderable + auto rformat = std::find_if(RENDERABLE.begin(), RENDERABLE.end(), [f](const auto& e) { return e.drmFormat == f.drmFormat; }); + + if (rformat == RENDERABLE.end()) { + TRACE(allocator->backend->log(AQ_LOG_TRACE, std::format("GBM: Dropping format {} as it's not renderable", fourccToName(f.drmFormat)))); + break; + } + + if (std::find(rformat->modifiers.begin(), rformat->modifiers.end(), m) == rformat->modifiers.end()) { + TRACE(allocator->backend->log(AQ_LOG_TRACE, std::format("GBM: Dropping modifier 0x{:x} as it's not renderable", m))); + continue; + } + } + explicitModifiers.push_back(m); } } diff --git a/src/backend/drm/DRM.cpp b/src/backend/drm/DRM.cpp index 1c21c56..93ba80c 100644 --- a/src/backend/drm/DRM.cpp +++ b/src/backend/drm/DRM.cpp @@ -507,7 +507,7 @@ void Aquamarine::CDRMBackend::buildGlFormats(const std::vector& fmts) if (fmt.external) continue; - if (auto it = std::find_if(result.begin(), result.end(), [fmt] (const auto& e) { return fmt.drmFormat == e.drmFormat; }); it != result.end()) { + if (auto it = std::find_if(result.begin(), result.end(), [fmt](const auto& e) { return fmt.drmFormat == e.drmFormat; }); it != result.end()) { it->modifiers.emplace_back(fmt.modifier); continue; } From 0720a5cbaead5843f584ba9349c6fb64c7f2370c Mon Sep 17 00:00:00 2001 From: UjinT34 <41110182+UjinT34@users.noreply.github.com> Date: Thu, 25 Jul 2024 01:17:48 +0300 Subject: [PATCH 3/5] gbm: Fix cursor bo for nvidia (#29) --- src/allocator/GBM.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/allocator/GBM.cpp b/src/allocator/GBM.cpp index 3f972b4..42666a6 100644 --- a/src/allocator/GBM.cpp +++ b/src/allocator/GBM.cpp @@ -53,7 +53,8 @@ static SDRMFormat guessFormatFrom(std::vector formats, bool cursor) } Aquamarine::CGBMBuffer::CGBMBuffer(const SAllocatorBufferParams& params, Hyprutils::Memory::CWeakPointer allocator_, - Hyprutils::Memory::CSharedPointer swapchain) : allocator(allocator_) { + Hyprutils::Memory::CSharedPointer swapchain) : + allocator(allocator_) { if (!allocator) return; @@ -127,6 +128,8 @@ Aquamarine::CGBMBuffer::CGBMBuffer(const SAllocatorBufferParams& params, Hypruti uint32_t flags = GBM_BO_USE_RENDERING; if (params.scanout) flags |= GBM_BO_USE_SCANOUT; + if (CURSOR) + flags |= GBM_BO_USE_CURSOR; // make implicit fail for nvidia - avoids freezing with incorrect formats for cursor plane if (explicitModifiers.empty()) { allocator->backend->log(AQ_LOG_WARNING, "GBM: Using modifier-less allocation"); @@ -138,6 +141,12 @@ Aquamarine::CGBMBuffer::CGBMBuffer(const SAllocatorBufferParams& params, Hypruti } bo = gbm_bo_create_with_modifiers2(allocator->gbmDevice, attrs.size.x, attrs.size.y, attrs.format, explicitModifiers.data(), explicitModifiers.size(), flags); + if (!bo && CURSOR) { + // allow non-renderable cursor buffer for nvidia + allocator->backend->log(AQ_LOG_ERROR, "GBM: Allocating with modifiers and flags failed, falling back to modifiers without flags"); + bo = gbm_bo_create_with_modifiers(allocator->gbmDevice, attrs.size.x, attrs.size.y, attrs.format, explicitModifiers.data(), explicitModifiers.size()); + } + if (!bo) { allocator->backend->log(AQ_LOG_ERROR, "GBM: Allocating with modifiers failed, falling back to implicit"); bo = gbm_bo_create(allocator->gbmDevice, attrs.size.x, attrs.size.y, attrs.format, flags); From a7d77c60ee5aaa0fef7c4b5c00ff9e8c885c6985 Mon Sep 17 00:00:00 2001 From: moetayuko Date: Fri, 26 Jul 2024 04:41:46 +0800 Subject: [PATCH 4/5] gbm: manually set modifier for implicit bo allocation (#30) Ported from wlroots Fixes https://github.com/hyprwm/Hyprland/issues/7001 --- src/allocator/GBM.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/allocator/GBM.cpp b/src/allocator/GBM.cpp index 42666a6..773fc00 100644 --- a/src/allocator/GBM.cpp +++ b/src/allocator/GBM.cpp @@ -53,8 +53,7 @@ static SDRMFormat guessFormatFrom(std::vector formats, bool cursor) } Aquamarine::CGBMBuffer::CGBMBuffer(const SAllocatorBufferParams& params, Hyprutils::Memory::CWeakPointer allocator_, - Hyprutils::Memory::CSharedPointer swapchain) : - allocator(allocator_) { + Hyprutils::Memory::CSharedPointer swapchain) : allocator(allocator_) { if (!allocator) return; @@ -128,8 +127,6 @@ Aquamarine::CGBMBuffer::CGBMBuffer(const SAllocatorBufferParams& params, Hypruti uint32_t flags = GBM_BO_USE_RENDERING; if (params.scanout) flags |= GBM_BO_USE_SCANOUT; - if (CURSOR) - flags |= GBM_BO_USE_CURSOR; // make implicit fail for nvidia - avoids freezing with incorrect formats for cursor plane if (explicitModifiers.empty()) { allocator->backend->log(AQ_LOG_WARNING, "GBM: Using modifier-less allocation"); @@ -148,7 +145,11 @@ Aquamarine::CGBMBuffer::CGBMBuffer(const SAllocatorBufferParams& params, Hypruti } if (!bo) { - allocator->backend->log(AQ_LOG_ERROR, "GBM: Allocating with modifiers failed, falling back to implicit"); + if (explicitModifiers.size() == 1 && explicitModifiers[0] == DRM_FORMAT_MOD_LINEAR) { + flags |= GBM_BO_USE_LINEAR; + allocator->backend->log(AQ_LOG_ERROR, "GBM: Allocating with modifiers failed, falling back to modifier-less allocation"); + } else + allocator->backend->log(AQ_LOG_ERROR, "GBM: Allocating with modifiers failed, falling back to implicit"); bo = gbm_bo_create(allocator->gbmDevice, attrs.size.x, attrs.size.y, attrs.format, flags); } } @@ -159,7 +160,7 @@ Aquamarine::CGBMBuffer::CGBMBuffer(const SAllocatorBufferParams& params, Hypruti } attrs.planes = gbm_bo_get_plane_count(bo); - attrs.modifier = gbm_bo_get_modifier(bo); + attrs.modifier = (flags & GBM_BO_USE_LINEAR) ? DRM_FORMAT_MOD_LINEAR : gbm_bo_get_modifier(bo); for (size_t i = 0; i < (size_t)attrs.planes; ++i) { attrs.strides.at(i) = gbm_bo_get_stride_for_plane(bo, i); From 0ab8ffa67d95201381c43e44fa67d16e7fa1ef7f Mon Sep 17 00:00:00 2001 From: Ikalco <73481042+ikalco@users.noreply.github.com> Date: Thu, 25 Jul 2024 16:14:05 -0500 Subject: [PATCH 5/5] output: fix destroying wl and headless outputs (#32) --- src/backend/Headless.cpp | 1 + src/backend/Wayland.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/src/backend/Headless.cpp b/src/backend/Headless.cpp index 2c358d4..df4b312 100644 --- a/src/backend/Headless.cpp +++ b/src/backend/Headless.cpp @@ -73,6 +73,7 @@ void Aquamarine::CHeadlessOutput::scheduleFrame(const scheduleFrameReason reason } bool Aquamarine::CHeadlessOutput::destroy() { + events.destroy.emit(); std::erase(backend->outputs, self.lock()); return true; } diff --git a/src/backend/Wayland.cpp b/src/backend/Wayland.cpp index bc2f8d5..bd8fb5b 100644 --- a/src/backend/Wayland.cpp +++ b/src/backend/Wayland.cpp @@ -496,6 +496,7 @@ Aquamarine::CWaylandOutput::CWaylandOutput(const std::string& name_, Hyprutils:: Aquamarine::CWaylandOutput::~CWaylandOutput() { backend->idleCallbacks.clear(); // FIXME: mega hack to avoid a UAF in frame events + events.destroy.emit(); if (waylandState.xdgToplevel) waylandState.xdgToplevel->sendDestroy(); if (waylandState.xdgSurface)