From 07eb70afb131a4450aa01f5b488228c4cce6892b Mon Sep 17 00:00:00 2001 From: Vaxry <43317083+vaxerski@users.noreply.github.com> Date: Wed, 24 Jul 2024 17:41:13 +0100 Subject: [PATCH] gbm: Nvidia fixes for scanout gbm allocation (#27) * nv fixes * fix --- include/aquamarine/backend/Backend.hpp | 1 + include/aquamarine/backend/DRM.hpp | 3 ++ include/aquamarine/backend/Misc.hpp | 6 ++++ src/allocator/GBM.cpp | 4 ++- src/backend/Backend.cpp | 4 +++ src/backend/drm/DRM.cpp | 48 +++++++++++++++++++++++++- src/backend/drm/Renderer.cpp | 4 +-- src/backend/drm/Renderer.hpp | 10 ++---- 8 files changed, 69 insertions(+), 11 deletions(-) diff --git a/include/aquamarine/backend/Backend.hpp b/include/aquamarine/backend/Backend.hpp index 5848722..6e40d62 100644 --- a/include/aquamarine/backend/Backend.hpp +++ b/include/aquamarine/backend/Backend.hpp @@ -77,6 +77,7 @@ namespace Aquamarine { virtual std::vector getCursorFormats() = 0; virtual bool createOutput(const std::string& name = "") = 0; // "" means auto virtual Hyprutils::Memory::CSharedPointer preferredAllocator() = 0; + virtual std::vector getRenderableFormats(); // empty = use getRenderFormats }; class CBackend { diff --git a/include/aquamarine/backend/DRM.hpp b/include/aquamarine/backend/DRM.hpp index 43a6c0b..7bb441d 100644 --- a/include/aquamarine/backend/DRM.hpp +++ b/include/aquamarine/backend/DRM.hpp @@ -342,6 +342,7 @@ namespace Aquamarine { virtual std::vector getCursorFormats(); virtual bool createOutput(const std::string& name = ""); virtual Hyprutils::Memory::CSharedPointer preferredAllocator(); + virtual std::vector getRenderableFormats(); Hyprutils::Memory::CWeakPointer self; @@ -366,6 +367,7 @@ namespace Aquamarine { void scanLeases(); void restoreAfterVT(); void recheckCRTCs(); + void buildGlFormats(const std::vector& fmts); Hyprutils::Memory::CSharedPointer gpu; Hyprutils::Memory::CSharedPointer impl; @@ -383,6 +385,7 @@ namespace Aquamarine { std::vector> planes; std::vector> connectors; std::vector formats; + std::vector glFormats; bool atomic = false; diff --git a/include/aquamarine/backend/Misc.hpp b/include/aquamarine/backend/Misc.hpp index bce8847..0bdd960 100644 --- a/include/aquamarine/backend/Misc.hpp +++ b/include/aquamarine/backend/Misc.hpp @@ -4,6 +4,12 @@ #include namespace Aquamarine { + struct SGLFormat { + uint32_t drmFormat = 0; + uint64_t modifier = 0; + bool external = false; + }; + struct SDRMFormat { uint32_t drmFormat = 0; /* DRM_FORMAT_INVALID */ std::vector modifiers; diff --git a/src/allocator/GBM.cpp b/src/allocator/GBM.cpp index 90396ce..2760ef0 100644 --- a/src/allocator/GBM.cpp +++ b/src/allocator/GBM.cpp @@ -67,7 +67,9 @@ Aquamarine::CGBMBuffer::CGBMBuffer(const SAllocatorBufferParams& params, Hypruti TRACE(allocator->backend->log(AQ_LOG_TRACE, std::format("GBM: Allocating a buffer: size {}, format {}, cursor: {}, multigpu: {}", attrs.size, fourccToName(attrs.format), CURSOR, MULTIGPU))); - const auto FORMATS = CURSOR ? swapchain->backendImpl->getCursorFormats() : swapchain->backendImpl->getRenderFormats(); + const auto FORMATS = CURSOR ? + swapchain->backendImpl->getCursorFormats() : + (swapchain->backendImpl->getRenderableFormats().size() == 0 ? swapchain->backendImpl->getRenderFormats() : swapchain->backendImpl->getRenderableFormats()); std::vector explicitModifiers; diff --git a/src/backend/Backend.cpp b/src/backend/Backend.cpp index 64eb9a0..a6db06a 100644 --- a/src/backend/Backend.cpp +++ b/src/backend/Backend.cpp @@ -328,3 +328,7 @@ int Aquamarine::CBackend::reopenDRMNode(int drmFD, bool allowRenderNode) { return newFD; } + +std::vector Aquamarine::IBackendImplementation::getRenderableFormats() { + return {}; +} diff --git a/src/backend/drm/DRM.cpp b/src/backend/drm/DRM.cpp index d944fc4..d0588a8 100644 --- a/src/backend/drm/DRM.cpp +++ b/src/backend/drm/DRM.cpp @@ -495,9 +495,32 @@ bool Aquamarine::CDRMBackend::initMgpu() { mgpu.renderer->self = mgpu.renderer; + buildGlFormats(mgpu.renderer->formats); + return true; } +void Aquamarine::CDRMBackend::buildGlFormats(const std::vector& fmts) { + std::vector result; + + for (auto& fmt : 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()) { + it->modifiers.emplace_back(fmt.modifier); + continue; + } + + result.emplace_back(SDRMFormat{ + fmt.drmFormat, + {fmt.modifier}, + }); + } + + glFormats = result; +} + void Aquamarine::CDRMBackend::recheckCRTCs() { if (connectors.empty() || crtcs.empty()) return; @@ -802,6 +825,25 @@ bool Aquamarine::CDRMBackend::setCursor(SP buffer, const Hyprutils::Mat void Aquamarine::CDRMBackend::onReady() { backend->log(AQ_LOG_DEBUG, std::format("drm: Connectors size2 {}", connectors.size())); + // init a drm renderer to gather gl formats. + // if we are secondary, initMgpu will have done that + if (!primary) { + auto a = CGBMAllocator::create(backend->reopenDRMNode(gpu->fd), backend); + if (!a) + backend->log(AQ_LOG_ERROR, "drm: onReady: no renderer for gl formats"); + else { + auto r = CDRMRenderer::attempt(a, backend.lock()); + if (!r) + backend->log(AQ_LOG_ERROR, "drm: onReady: no renderer for gl formats"); + else { + TRACE(backend->log(AQ_LOG_TRACE, std::format("drm: onReady: gathered {} gl formats", r->formats.size()))); + buildGlFormats(r->formats); + r.reset(); + a.reset(); + } + } + } + for (auto& c : connectors) { backend->log(AQ_LOG_DEBUG, std::format("drm: onReady: connector {}", c->id)); if (!c->output) @@ -834,6 +876,10 @@ std::vector Aquamarine::CDRMBackend::getRenderFormats() { return {}; } +std::vector Aquamarine::CDRMBackend::getRenderableFormats() { + return glFormats; +} + std::vector Aquamarine::CDRMBackend::getCursorFormats() { for (auto& p : planes) { if (p->type != DRM_PLANE_TYPE_CURSOR) @@ -1346,7 +1392,7 @@ bool Aquamarine::CDRMOutput::commitState(bool onlyTest) { if (!MODE) // modeless commits are invalid return false; - uint32_t flags = 0; + uint32_t flags = 0; if (!onlyTest) { if (NEEDS_RECONFIG) { diff --git a/src/backend/drm/Renderer.cpp b/src/backend/drm/Renderer.cpp index 663a63f..7385d3a 100644 --- a/src/backend/drm/Renderer.cpp +++ b/src/backend/drm/Renderer.cpp @@ -153,7 +153,7 @@ bool CDRMRenderer::initDRMFormats() { TRACE(backend->log(AQ_LOG_TRACE, "EGL: Supported formats:")); - std::vector dmaFormats; + std::vector dmaFormats; for (auto& fmt : formats) { std::vector> mods; @@ -170,7 +170,7 @@ bool CDRMRenderer::initDRMFormats() { mods.push_back({DRM_FORMAT_MOD_INVALID, true}); for (auto& [mod, external] : mods) { - dmaFormats.push_back(GLFormat{ + dmaFormats.push_back(SGLFormat{ .drmFormat = (uint32_t)fmt, .modifier = mod, .external = external, diff --git a/src/backend/drm/Renderer.hpp b/src/backend/drm/Renderer.hpp index 7fe6840..0010ee3 100644 --- a/src/backend/drm/Renderer.hpp +++ b/src/backend/drm/Renderer.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include "FormatUtils.hpp" #include #include #include @@ -19,6 +20,7 @@ namespace Aquamarine { GLuint texid = 0; GLuint target = GL_TEXTURE_2D; }; + class CDRMRendererBufferAttachment : public IAttachment { public: CDRMRendererBufferAttachment(Hyprutils::Memory::CWeakPointer renderer_, Hyprutils::Memory::CSharedPointer buffer, EGLImageKHR image, GLuint fbo_, @@ -78,16 +80,10 @@ namespace Aquamarine { EGLSurface draw = nullptr, read = nullptr; } savedEGLState; - struct GLFormat { - uint32_t drmFormat = 0; - uint64_t modifier = 0; - bool external = false; - }; - SGLTex glTex(Hyprutils::Memory::CSharedPointer buf); Hyprutils::Memory::CWeakPointer self; - std::vector formats; + std::vector formats; private: CDRMRenderer() = default;