backend, allocator: Fix mGPU backend + allocator swapchain combos (#159)

This commit is contained in:
Lee Bousfield 2025-03-16 16:52:24 -05:00 committed by GitHub
parent bea48d0bbe
commit b058847592
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 24 additions and 5 deletions

View file

@ -1,6 +1,7 @@
#pragma once
#include <hyprutils/memory/SharedPtr.hpp>
#include <hyprutils/memory/WeakPtr.hpp>
#include <hyprutils/signal/Signal.hpp>
#include <vector>
#include <functional>
@ -79,6 +80,7 @@ namespace Aquamarine {
virtual Hyprutils::Memory::CSharedPointer<IAllocator> preferredAllocator() = 0;
virtual std::vector<SDRMFormat> getRenderableFormats(); // empty = use getRenderFormats
virtual std::vector<Hyprutils::Memory::CSharedPointer<IAllocator>> getAllocators() = 0;
virtual Hyprutils::Memory::CWeakPointer<IBackendImplementation> getPrimary() = 0;
};
class CBackend {

View file

@ -369,6 +369,7 @@ namespace Aquamarine {
virtual Hyprutils::Memory::CSharedPointer<IAllocator> preferredAllocator();
virtual std::vector<SDRMFormat> getRenderableFormats();
virtual std::vector<Hyprutils::Memory::CSharedPointer<IAllocator>> getAllocators();
virtual Hyprutils::Memory::CWeakPointer<IBackendImplementation> getPrimary();
Hyprutils::Memory::CWeakPointer<CDRMBackend> self;

View file

@ -49,6 +49,7 @@ namespace Aquamarine {
virtual bool createOutput(const std::string& name = "");
virtual Hyprutils::Memory::CSharedPointer<IAllocator> preferredAllocator();
virtual std::vector<Hyprutils::Memory::CSharedPointer<IAllocator>> getAllocators();
virtual Hyprutils::Memory::CWeakPointer<IBackendImplementation> getPrimary();
Hyprutils::Memory::CWeakPointer<CHeadlessBackend> self;

View file

@ -136,6 +136,7 @@ namespace Aquamarine {
virtual bool createOutput(const std::string& name = "");
virtual Hyprutils::Memory::CSharedPointer<IAllocator> preferredAllocator();
virtual std::vector<Hyprutils::Memory::CSharedPointer<IAllocator>> getAllocators();
virtual Hyprutils::Memory::CWeakPointer<IBackendImplementation> getPrimary();
Hyprutils::Memory::CWeakPointer<CWaylandBackend> self;

View file

@ -72,7 +72,7 @@ Aquamarine::CGBMBuffer::CGBMBuffer(const SAllocatorBufferParams& params, Hypruti
const bool CURSOR = params.cursor && params.scanout;
const bool MULTIGPU = params.multigpu && params.scanout;
const bool EXPLICIT_SCANOUT = params.scanout && swapchain->currentOptions().scanoutOutput;
const bool EXPLICIT_SCANOUT = params.scanout && swapchain->currentOptions().scanoutOutput && !params.multigpu;
TRACE(allocator->backend->log(AQ_LOG_TRACE,
std::format("GBM: Allocating a buffer: size {}, format {}, cursor: {}, multigpu: {}, scanout: {}", attrs.size, fourccToName(attrs.format), CURSOR,
@ -153,7 +153,7 @@ Aquamarine::CGBMBuffer::CGBMBuffer(const SAllocatorBufferParams& params, Hypruti
}
uint32_t flags = GBM_BO_USE_RENDERING;
if (params.scanout)
if (params.scanout && !MULTIGPU)
flags |= GBM_BO_USE_SCANOUT;
uint64_t modifier = DRM_FORMAT_MOD_INVALID;
@ -223,7 +223,7 @@ Aquamarine::CGBMBuffer::CGBMBuffer(const SAllocatorBufferParams& params, Hypruti
free(modName);
if (params.scanout && swapchain->backendImpl->type() == AQ_BACKEND_DRM) {
if (params.scanout && !MULTIGPU && swapchain->backendImpl->type() == AQ_BACKEND_DRM) {
// clear the buffer using the DRM renderer to avoid uninitialized mem
auto impl = (CDRMBackend*)swapchain->backendImpl.get();
if (impl->rendererState.renderer)

View file

@ -211,6 +211,10 @@ std::vector<SP<IAllocator>> Aquamarine::CHeadlessBackend::getAllocators() {
return {backend->primaryAllocator};
}
Hyprutils::Memory::CWeakPointer<IBackendImplementation> Aquamarine::CHeadlessBackend::getPrimary() {
return {};
}
bool Aquamarine::CHeadlessBackend::CTimer::expired() {
return std::chrono::steady_clock::now() > when;
}

View file

@ -447,6 +447,10 @@ std::vector<SP<IAllocator>> Aquamarine::CWaylandBackend::getAllocators() {
return {backend->primaryAllocator};
}
Hyprutils::Memory::CWeakPointer<IBackendImplementation> Aquamarine::CWaylandBackend::getPrimary() {
return {};
}
Aquamarine::CWaylandOutput::CWaylandOutput(const std::string& name_, Hyprutils::Memory::CWeakPointer<CWaylandBackend> backend_) : backend(backend_) {
name = name_;

View file

@ -993,7 +993,8 @@ void Aquamarine::CDRMBackend::onReady() {
backend->log(AQ_LOG_DEBUG, std::format("drm: onReady: connector {} has output name {}", c->id, c->output->name));
// swapchain has to be created here because allocator is absent in connect if not ready
c->output->swapchain = CSwapchain::create(backend->primaryAllocator, self.lock());
auto primaryBackend = primary ? primary : self;
c->output->swapchain = CSwapchain::create(backend->primaryAllocator, primaryBackend.lock());
c->output->swapchain->reconfigure(SSwapchainOptions{.length = 0, .scanout = true, .multigpu = !!primary, .scanoutOutput = c->output}); // mark the swapchain for scanout
c->output->needsFrame = true;
@ -1073,6 +1074,10 @@ std::vector<SP<IAllocator>> Aquamarine::CDRMBackend::getAllocators() {
return {backend->primaryAllocator, dumbAllocator};
}
Hyprutils::Memory::CWeakPointer<IBackendImplementation> Aquamarine::CDRMBackend::getPrimary() {
return primary;
}
bool Aquamarine::SDRMPlane::init(drmModePlane* plane) {
id = plane->plane_id;
@ -1467,7 +1472,8 @@ void Aquamarine::SDRMConnector::connect(drmModeConnector* connector) {
if (!backend->backend->ready)
return;
output->swapchain = CSwapchain::create(backend->backend->primaryAllocator, backend->self.lock());
auto primaryBackend = backend->primary ? backend->primary : backend;
output->swapchain = CSwapchain::create(backend->backend->primaryAllocator, primaryBackend.lock());
output->swapchain->reconfigure(SSwapchainOptions{.length = 0, .scanout = true, .multigpu = !!backend->primary, .scanoutOutput = output}); // mark the swapchain for scanout
output->needsFrame = true;
backend->backend->events.newOutput.emit(SP<IOutput>(output));