From 6cdb1e6f64c7b81806787670e3ddd3d49d62abc0 Mon Sep 17 00:00:00 2001 From: Xaver Hugl Date: Sun, 14 Aug 2022 19:53:30 +0200 Subject: [PATCH] backends/drm: add stricter checks for direct scanout Buffers with implicit modifiers from another GPU must not be imported, as the layouts may not be compatible. For buffers with incompatible modifiers, direct scanout can also be rejected early, saving some computational power. BUG: 457851 --- src/backends/drm/drm_backend.cpp | 5 +++++ src/backends/drm/drm_backend.h | 1 + src/backends/drm/drm_buffer_gbm.cpp | 1 + src/backends/drm/drm_egl_layer.cpp | 7 +++++++ 4 files changed, 14 insertions(+) diff --git a/src/backends/drm/drm_backend.cpp b/src/backends/drm/drm_backend.cpp index 429ea41855..4118339bdf 100644 --- a/src/backends/drm/drm_backend.cpp +++ b/src/backends/drm/drm_backend.cpp @@ -682,6 +682,11 @@ DrmGpu *DrmBackend::findGpu(dev_t deviceId) const return it == m_gpus.end() ? nullptr : it->get(); } +size_t DrmBackend::gpuCount() const +{ + return m_gpus.size(); +} + bool DrmBackend::applyOutputChanges(const OutputConfiguration &config) { QVector toBeEnabled; diff --git a/src/backends/drm/drm_backend.h b/src/backends/drm/drm_backend.h index 728ea1abee..14edf70184 100644 --- a/src/backends/drm/drm_backend.h +++ b/src/backends/drm/drm_backend.h @@ -68,6 +68,7 @@ public: DrmGpu *primaryGpu() const; DrmGpu *findGpu(dev_t deviceId) const; + size_t gpuCount() const; bool isActive() const; diff --git a/src/backends/drm/drm_buffer_gbm.cpp b/src/backends/drm/drm_buffer_gbm.cpp index 47d67a2423..73a8297251 100644 --- a/src/backends/drm/drm_buffer_gbm.cpp +++ b/src/backends/drm/drm_buffer_gbm.cpp @@ -11,6 +11,7 @@ #include "drm_gbm_surface.h" #include "config-kwin.h" +#include "drm_backend.h" #include "drm_gpu.h" #include "drm_logging.h" #include "kwineglutils_p.h" diff --git a/src/backends/drm/drm_egl_layer.cpp b/src/backends/drm/drm_egl_layer.cpp index 497a0270f3..7ba07fbae5 100644 --- a/src/backends/drm/drm_egl_layer.cpp +++ b/src/backends/drm/drm_egl_layer.cpp @@ -143,6 +143,13 @@ bool EglGbmLayer::scanout(SurfaceItem *surfaceItem) m_dmabufFeedback.scanoutFailed(surface, formats); return false; } + if (buffer->attributes().modifier == DRM_FORMAT_MOD_INVALID && m_pipeline->gpu()->platform()->gpuCount() > 1) { + // importing a buffer from another GPU without an explicit modifier can mess up the buffer format + return false; + } + if (!formats[buffer->format()].contains(buffer->attributes().modifier)) { + return false; + } const auto gbmBuffer = GbmBuffer::importBuffer(m_pipeline->gpu(), buffer); if (!gbmBuffer) { m_dmabufFeedback.scanoutFailed(surface, formats);