dmabuf feedback: limit modifiers to those supported by egl

This commit is contained in:
Xaver Hugl 2021-12-30 17:55:39 +01:00
parent 5a6f1e42c1
commit 0ba2c35e1a
5 changed files with 41 additions and 23 deletions

View file

@ -27,6 +27,7 @@
#include "shadowbuffer.h" #include "shadowbuffer.h"
#include "drm_pipeline.h" #include "drm_pipeline.h"
#include "drm_abstract_output.h" #include "drm_abstract_output.h"
#include "egl_dmabuf.h"
// kwin libs // kwin libs
#include <kwinglplatform.h> #include <kwinglplatform.h>
#include <kwineglimagetexture.h> #include <kwineglimagetexture.h>
@ -659,8 +660,11 @@ bool EglGbmBackend::scanout(AbstractOutput *drmOutput, SurfaceItem *surfaceItem)
// atm no format changes are sent as those might require a modeset // atm no format changes are sent as those might require a modeset
// and thus require more elaborate feedback // and thus require more elaborate feedback
const auto &mods = drmOutput->pipeline()->supportedModifiers(output.current.format.drmFormat); const auto &mods = drmOutput->pipeline()->supportedModifiers(output.current.format.drmFormat);
const auto &supportedModifiers = primaryBackend()->dmabuf()->supportedFormats()[output.current.format.drmFormat];
for (const auto &mod : mods) { for (const auto &mod : mods) {
tranche.formatTable[output.current.format.drmFormat] << mod; if (supportedModifiers.contains(mod)) {
tranche.formatTable[output.current.format.drmFormat] << mod;
}
} }
if (tranche.formatTable.isEmpty()) { if (tranche.formatTable.isEmpty()) {
output.scanoutCandidate->dmabufFeedbackV1()->setTranches({}); output.scanoutCandidate->dmabufFeedbackV1()->setTranches({});

View file

@ -398,4 +398,9 @@ bool AbstractEglBackend::prefer10bpc() const
return false; return false;
} }
EglDmabuf *AbstractEglBackend::dmabuf() const
{
return m_dmaBuf;
}
} }

View file

@ -72,6 +72,7 @@ public:
dev_t deviceId() const; dev_t deviceId() const;
virtual bool prefer10bpc() const; virtual bool prefer10bpc() const;
EglDmabuf *dmabuf() const;
protected: protected:
AbstractEglBackend(dev_t deviceId = 0); AbstractEglBackend(dev_t deviceId = 0);

View file

@ -440,28 +440,31 @@ void EglDmabuf::setSupportedFormatsAndModifiers()
filterFormatsWithMultiplePlanes(formats); filterFormatsWithMultiplePlanes(formats);
auto queryFormats = [&formats, &eglDisplay](int bpc) { for (auto format : qAsConst(formats)) {
QHash<uint32_t, QSet<uint64_t>> set; if (eglQueryDmaBufModifiersEXT != nullptr) {
for (auto format : qAsConst(formats)) { EGLint count = 0;
if (bpc != bpcForFormat(format)) { const EGLBoolean success = eglQueryDmaBufModifiersEXT(eglDisplay, format, 0, nullptr, nullptr, &count);
continue; if (success && count > 0) {
} QVector<uint64_t> modifiers(count);
if (eglQueryDmaBufModifiersEXT != nullptr) { if (eglQueryDmaBufModifiersEXT(eglDisplay, format, count, modifiers.data(), nullptr, &count)) {
EGLint count = 0; QSet<uint64_t> modifiersSet;
const EGLBoolean success = eglQueryDmaBufModifiersEXT(eglDisplay, format, 0, nullptr, nullptr, &count); for (const uint64_t &mod : qAsConst(modifiers)) {
if (success && count > 0) { modifiersSet.insert(mod);
QVector<uint64_t> modifiers(count);
if (eglQueryDmaBufModifiersEXT(eglDisplay, format, count, modifiers.data(), nullptr, &count)) {
QSet<uint64_t> modifiersSet;
for (const uint64_t &mod : qAsConst(modifiers)) {
modifiersSet.insert(mod);
}
set.insert(format, modifiersSet);
continue;
} }
m_supportedFormats.insert(format, modifiersSet);
continue;
} }
} }
set.insert(format, QSet<uint64_t>()); }
m_supportedFormats.insert(format, QSet<uint64_t>());
}
auto filterFormats = [this](int bpc) {
QHash<uint32_t, QSet<uint64_t>> set;
for (auto it = m_supportedFormats.constBegin(); it != m_supportedFormats.constEnd(); it++) {
if (bpcForFormat(it.key()) == bpc) {
set.insert(it.key(), it.value());
}
} }
return set; return set;
}; };
@ -470,18 +473,18 @@ void EglDmabuf::setSupportedFormatsAndModifiers()
tranches.append({ tranches.append({
.device = m_backend->deviceId(), .device = m_backend->deviceId(),
.flags = {}, .flags = {},
.formatTable = queryFormats(10), .formatTable = filterFormats(10),
}); });
} }
tranches.append({ tranches.append({
.device = m_backend->deviceId(), .device = m_backend->deviceId(),
.flags = {}, .flags = {},
.formatTable = queryFormats(8), .formatTable = filterFormats(8),
}); });
tranches.append({ tranches.append({
.device = m_backend->deviceId(), .device = m_backend->deviceId(),
.flags = {}, .flags = {},
.formatTable = queryFormats(-1), .formatTable = filterFormats(-1),
}); });
LinuxDmaBufV1RendererInterface::setSupportedFormatsAndModifiers(tranches); LinuxDmaBufV1RendererInterface::setSupportedFormatsAndModifiers(tranches);
} }

View file

@ -67,6 +67,10 @@ public:
const QSize &size, const QSize &size,
quint32 flags) override; quint32 flags) override;
QHash<uint32_t, QSet<uint64_t>> supportedFormats() const {
return m_supportedFormats;
}
private: private:
EGLImage createImage(const QVector<KWaylandServer::LinuxDmaBufV1Plane> &planes, EGLImage createImage(const QVector<KWaylandServer::LinuxDmaBufV1Plane> &planes,
uint32_t format, uint32_t format,
@ -80,6 +84,7 @@ private:
void setSupportedFormatsAndModifiers(); void setSupportedFormatsAndModifiers();
AbstractEglBackend *m_backend; AbstractEglBackend *m_backend;
QHash<uint32_t, QSet<uint64_t>> m_supportedFormats;
friend class EglDmabufBuffer; friend class EglDmabufBuffer;
}; };