[plasma/kwin] /: wayland-client: use GpuManager for linux-dmabuf
Xaver Hugl <[email protected]>
| Newsgroups | gmane.comp.kde.cvs |
|---|---|
| Message-ID | <[email protected]> |
Git commit f5aa52f436adbbd0680097ece8fcc6158a7749d6 by Xaver Hugl.
Committed on 16/07/2026 at 18:38.
Pushed by zamundaaa into branch 'master'.
wayland-client: use GpuManager for linux-dmabuf
This simplifies the code and makes it possible to use the devices from each
tranche instead of only the main device.
M +8 -3 autotests/integration/drm_test.cpp
M +1 -4 src/backends/wayland/wayland_backend.cpp
M +11 -40 src/wayland-client/linuxdmabuf.cpp
M +3 -4 src/wayland-client/linuxdmabuf.h
https://invent.kde.org/plasma/kwin/-/commit/f5aa52f436adbbd0680097ece8fcc6158a7749d6
diff --git a/autotests/integration/drm_test.cpp b/autotests/integration/drm_test.cpp
index 3cd1b1ee19e..eef543a9be2 100644
--- a/autotests/integration/drm_test.cpp
+++ b/autotests/integration/drm_test.cpp
@@ -12,6 +12,7 @@
#include "backends/drm/drm_pointer.h"
#include "compositor.h"
#include "core/drmdevice.h"
+#include "core/gpumanager.h"
#include "core/graphicsbuffer.h"
#include "core/outputbackend.h"
#include "core/outputconfiguration.h"
@@ -227,7 +228,7 @@ public:
explicit DmabufWindow(std::function<void(Test::XdgToplevel *toplevel)> setup = [](Test::XdgToplevel *toplevel) { })
: m_surface(Test::createSurface())
, m_shellSurface(Test::createXdgToplevelSurface(m_surface.get(), setup))
- , m_device(DrmDevice::open(Test::linuxDmabuf()->mainDevice()))
+ , m_device(GpuManager::self()->compatibleRenderDevice(Test::linuxDmabuf()->mainDevice()))
, m_surfaceFeedback(Test::linuxDmabuf()->getSurfaceFeedback(*m_surface))
{
connect(m_surfaceFeedback.get(), &WaylandClient::LinuxDmabufFeedbackV1::changed, this, &DmabufWindow::reactToDmabufFeedback);
@@ -261,7 +262,11 @@ public:
if (!tranche.formats.contains(m_buffer->dmabufAttributes()->format)) {
continue;
}
- m_buffer = m_device->allocator()->allocate(GraphicsBufferOptions{
+ auto device = GpuManager::self()->compatibleRenderDevice(tranche.device);
+ if (!device) {
+ continue;
+ }
+ m_buffer = device->allocator()->allocate(GraphicsBufferOptions{
.size = m_buffer->size(),
.format = m_buffer->dmabufAttributes()->format,
.modifiers = tranche.formats[m_buffer->dmabufAttributes()->format],
@@ -291,7 +296,7 @@ public:
std::unique_ptr<KWayland::Client::Surface> m_surface;
std::unique_ptr<Test::XdgToplevel> m_shellSurface;
- std::unique_ptr<DrmDevice> m_device;
+ RenderDevice *m_device = nullptr;
std::unique_ptr<WaylandClient::LinuxDmabufFeedbackV1> m_surfaceFeedback;
GraphicsBufferRef m_buffer;
bool m_needsRealloc = false;
diff --git a/src/backends/wayland/wayland_backend.cpp b/src/backends/wayland/wayland_backend.cpp
index f56e47ff30c..9f4bc4f599d 100644
--- a/src/backends/wayland/wayland_backend.cpp
+++ b/src/backends/wayland/wayland_backend.cpp
@@ -438,10 +438,7 @@ bool WaylandBackend::initialize()
}
if (WaylandClient::LinuxDmabufV1 *dmabuf = m_display->linuxDmabuf()) {
- auto device = DrmDevice::open(dmabuf->mainDevice());
- if (device) {
- m_renderDevice = GpuManager::self()->compatibleRenderDevice(device.get());
- }
+ m_renderDevice = GpuManager::self()->compatibleRenderDevice(dmabuf->mainDevice());
}
createOutputs();
diff --git a/src/wayland-client/linuxdmabuf.cpp b/src/wayland-client/linuxdmabuf.cpp
index 120f1972901..17d3d4e4b68 100644
--- a/src/wayland-client/linuxdmabuf.cpp
+++ b/src/wayland-client/linuxdmabuf.cpp
@@ -4,6 +4,7 @@
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "linuxdmabuf.h"
+#include "core/gpumanager.h"
#include "core/graphicsbuffer.h"
#include "wayland-client/waylandclientlogging.h"
@@ -51,9 +52,9 @@ FormatModifierMap LinuxDmabufFeedbackV1::formats() const
return m_formats;
}
-QByteArray LinuxDmabufFeedbackV1::devicePath() const
+dev_t LinuxDmabufFeedbackV1::mainDevice() const
{
- return m_mainDevice;
+ return m_mainDeviceId;
}
QList<LinuxDmabufFeedbackV1::Tranche> LinuxDmabufFeedbackV1::tranches() const
@@ -80,31 +81,13 @@ void LinuxDmabufFeedbackV1::format_table(void *data, zwp_linux_dmabuf_feedback_v
void LinuxDmabufFeedbackV1::main_device(void *data, zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1, wl_array *deviceId)
{
LinuxDmabufFeedbackV1 *feedback = static_cast<LinuxDmabufFeedbackV1 *>(data);
-
feedback->m_mainDeviceId = deserializeDeviceId(deviceId);
-
- drmDevice *device = nullptr;
- if (drmGetDeviceFromDevId(feedback->m_mainDeviceId, 0, &device) != 0) {
- qCWarning(KWIN_WAYLAND_CLIENT) << "drmGetDeviceFromDevId() failed";
- return;
- }
-
- if (device->available_nodes & (1 << DRM_NODE_RENDER)) {
- feedback->m_mainDevice = QByteArray(device->nodes[DRM_NODE_RENDER]);
- } else if (device->available_nodes & (1 << DRM_NODE_PRIMARY)) {
- // We can't reliably find the render node from the primary node if the display and
- // render devices are split, so just fallback to the primary node.
- feedback->m_mainDevice = QByteArray(device->nodes[DRM_NODE_PRIMARY]);
- }
-
- drmFreeDevice(&device);
}
void LinuxDmabufFeedbackV1::tranche_done(void *data, zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1)
{
LinuxDmabufFeedbackV1 *feedback = static_cast<LinuxDmabufFeedbackV1 *>(data);
- feedback->m_trancheDeviceId = 0;
feedback->m_pendingTranches.push_back(feedback->m_pendingTranche);
feedback->m_pendingTranche = {};
}
@@ -113,7 +96,7 @@ void LinuxDmabufFeedbackV1::tranche_target_device(void *data, zwp_linux_dmabuf_f
{
LinuxDmabufFeedbackV1 *feedback = static_cast<LinuxDmabufFeedbackV1 *>(data);
- feedback->m_trancheDeviceId = deserializeDeviceId(deviceId);
+ feedback->m_pendingTranche.device = deserializeDeviceId(deviceId);
}
void LinuxDmabufFeedbackV1::tranche_formats(void *data, zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1, wl_array *indices)
@@ -124,22 +107,8 @@ void LinuxDmabufFeedbackV1::tranche_formats(void *data, zwp_linux_dmabuf_feedbac
return;
}
- drmDevice *mainDevice = nullptr;
- drmDevice *trancheDevice = nullptr;
- const auto cleanup = qScopeGuard([&]() {
- drmFreeDevice(&mainDevice);
- drmFreeDevice(&trancheDevice);
- });
- if (drmGetDeviceFromDevId(feedback->m_mainDeviceId, 0, &mainDevice) != 0
- || drmGetDeviceFromDevId(feedback->m_trancheDeviceId, 0, &trancheDevice) != 0) {
- qCWarning(KWIN_WAYLAND_CLIENT, "drmGetDeviceFromDevId() failed");
- return;
- }
- if (!drmDevicesEqual(mainDevice, trancheDevice)) {
- // TODO take multi GPU handling into account as well
- qCDebug(KWIN_WAYLAND_CLIENT, "Ignoring tranche from non-main device");
- return;
- }
+ auto main = GpuManager::self()->compatibleRenderDevice(feedback->m_mainDeviceId);
+ auto tranche = GpuManager::self()->compatibleRenderDevice(feedback->m_pendingTranche.device);
struct linux_dmabuf_feedback_v1_table_entry
{
@@ -151,7 +120,9 @@ void LinuxDmabufFeedbackV1::tranche_formats(void *data, zwp_linux_dmabuf_feedbac
const auto entries = static_cast<linux_dmabuf_feedback_v1_table_entry *>(feedback->m_formatTable.data());
for (const uint16_t &index : std::span(static_cast<uint16_t *>(indices->data), indices->size / sizeof(uint16_t))) {
const linux_dmabuf_feedback_v1_table_entry &entry = entries[index];
- feedback->m_formats[entry.format].insert(entry.modifier);
+ if (main == tranche) {
+ feedback->m_formats[entry.format].insert(entry.modifier);
+ }
feedback->m_pendingTranche.formats[entry.format].insert(entry.modifier);
}
}
@@ -185,9 +156,9 @@ zwp_linux_dmabuf_v1 *LinuxDmabufV1::handle() const
return m_dmabuf;
}
-QByteArray LinuxDmabufV1::mainDevice() const
+dev_t LinuxDmabufV1::mainDevice() const
{
- return m_defaultFeedback->devicePath();
+ return m_defaultFeedback->mainDevice();
}
FormatModifierMap LinuxDmabufV1::formats() const
diff --git a/src/wayland-client/linuxdmabuf.h b/src/wayland-client/linuxdmabuf.h
index e0e6ba4a2e1..f1858407aa6 100644
--- a/src/wayland-client/linuxdmabuf.h
+++ b/src/wayland-client/linuxdmabuf.h
@@ -40,10 +40,11 @@ public:
~LinuxDmabufFeedbackV1();
FormatModifierMap formats() const;
- QByteArray devicePath() const;
+ dev_t mainDevice() const;
struct Tranche
{
+ dev_t device;
FormatModifierMap formats;
bool scanout = false;
};
@@ -63,9 +64,7 @@ private:
static void tranche_flags(void *data, zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1, uint32_t flags);
zwp_linux_dmabuf_feedback_v1 *const m_feedback;
- QByteArray m_mainDevice;
dev_t m_mainDeviceId = 0;
- dev_t m_trancheDeviceId = 0;
MemoryMap m_formatTable;
FormatModifierMap m_formats;
QList<Tranche> m_tranches;
@@ -80,7 +79,7 @@ public:
~LinuxDmabufV1();
zwp_linux_dmabuf_v1 *handle() const;
- QByteArray mainDevice() const;
+ dev_t mainDevice() const;
FormatModifierMap formats() const;
/**
* NOTE that it's up to the calling client to take care of the