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
This commit is contained in:
Xaver Hugl 2022-08-14 19:53:30 +02:00
parent 3ac5116487
commit 6cdb1e6f64
4 changed files with 14 additions and 0 deletions

View file

@ -682,6 +682,11 @@ DrmGpu *DrmBackend::findGpu(dev_t deviceId) const
return it == m_gpus.end() ? nullptr : it->get(); return it == m_gpus.end() ? nullptr : it->get();
} }
size_t DrmBackend::gpuCount() const
{
return m_gpus.size();
}
bool DrmBackend::applyOutputChanges(const OutputConfiguration &config) bool DrmBackend::applyOutputChanges(const OutputConfiguration &config)
{ {
QVector<DrmOutput *> toBeEnabled; QVector<DrmOutput *> toBeEnabled;

View file

@ -68,6 +68,7 @@ public:
DrmGpu *primaryGpu() const; DrmGpu *primaryGpu() const;
DrmGpu *findGpu(dev_t deviceId) const; DrmGpu *findGpu(dev_t deviceId) const;
size_t gpuCount() const;
bool isActive() const; bool isActive() const;

View file

@ -11,6 +11,7 @@
#include "drm_gbm_surface.h" #include "drm_gbm_surface.h"
#include "config-kwin.h" #include "config-kwin.h"
#include "drm_backend.h"
#include "drm_gpu.h" #include "drm_gpu.h"
#include "drm_logging.h" #include "drm_logging.h"
#include "kwineglutils_p.h" #include "kwineglutils_p.h"

View file

@ -143,6 +143,13 @@ bool EglGbmLayer::scanout(SurfaceItem *surfaceItem)
m_dmabufFeedback.scanoutFailed(surface, formats); m_dmabufFeedback.scanoutFailed(surface, formats);
return false; 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); const auto gbmBuffer = GbmBuffer::importBuffer(m_pipeline->gpu(), buffer);
if (!gbmBuffer) { if (!gbmBuffer) {
m_dmabufFeedback.scanoutFailed(surface, formats); m_dmabufFeedback.scanoutFailed(surface, formats);