egl: fixup format modifier lookups with implicit modifiers

ref #6485
This commit is contained in:
Vaxry 2024-06-14 21:59:21 +02:00
parent 12ce06f39b
commit 2f278dc883
3 changed files with 27 additions and 13 deletions

View file

@ -24,8 +24,8 @@ inline const std::vector<SPixelFormat> GLES3_FORMATS = {
.bytesPerBlock = 4, .bytesPerBlock = 4,
}, },
{ {
.drmFormat = DRM_FORMAT_XRGB8888, .drmFormat = DRM_FORMAT_XRGB8888,
.flipRB = true, .flipRB = true,
#ifndef GLES2 #ifndef GLES2
.glFormat = GL_RGBA, .glFormat = GL_RGBA,
#else #else

View file

@ -79,20 +79,20 @@ CHyprOpenGLImpl::CHyprOpenGLImpl() {
m_tGlobalTimer.reset(); m_tGlobalTimer.reset();
} }
std::vector<uint64_t> CHyprOpenGLImpl::getModsForFormat(EGLint format) { std::optional<std::vector<uint64_t>> CHyprOpenGLImpl::getModsForFormat(EGLint format) {
// TODO: return std::expected when clang supports it // TODO: return std::expected when clang supports it
if (!m_sExts.EXT_image_dma_buf_import_modifiers) if (!m_sExts.EXT_image_dma_buf_import_modifiers)
return {}; return std::nullopt;
EGLint len = 0; EGLint len = 0;
if (!m_sProc.eglQueryDmaBufModifiersEXT(wlr_egl_get_display(g_pCompositor->m_sWLREGL), format, 0, nullptr, nullptr, &len)) { if (!m_sProc.eglQueryDmaBufModifiersEXT(wlr_egl_get_display(g_pCompositor->m_sWLREGL), format, 0, nullptr, nullptr, &len)) {
Debug::log(ERR, "EGL: Failed to query mods"); Debug::log(ERR, "EGL: Failed to query mods");
return {}; return std::nullopt;
} }
if (len <= 0) if (len <= 0)
return {DRM_FORMAT_MOD_LINEAR, DRM_FORMAT_MOD_INVALID}; // assume the driver can do linear and implicit. return std::vector<uint64_t>{};
std::vector<uint64_t> mods; std::vector<uint64_t> mods;
std::vector<EGLBoolean> external; std::vector<EGLBoolean> external;
@ -103,13 +103,21 @@ std::vector<uint64_t> CHyprOpenGLImpl::getModsForFormat(EGLint format) {
m_sProc.eglQueryDmaBufModifiersEXT(wlr_egl_get_display(g_pCompositor->m_sWLREGL), format, len, mods.data(), external.data(), &len); m_sProc.eglQueryDmaBufModifiersEXT(wlr_egl_get_display(g_pCompositor->m_sWLREGL), format, len, mods.data(), external.data(), &len);
std::vector<uint64_t> result; std::vector<uint64_t> result;
bool linearIsExternal = false;
for (size_t i = 0; i < mods.size(); ++i) { for (size_t i = 0; i < mods.size(); ++i) {
if (external.at(i)) if (external.at(i)) {
if (mods.at(i) == DRM_FORMAT_MOD_LINEAR)
linearIsExternal = true;
continue; continue;
}
result.push_back(mods.at(i)); result.push_back(mods.at(i));
} }
// if the driver doesn't mark linear as external, add it. It's allowed unless the driver says otherwise. (e.g. nvidia)
if (!linearIsExternal && std::find(mods.begin(), mods.end(), DRM_FORMAT_MOD_LINEAR) == mods.end() && mods.size() == 0)
mods.push_back(DRM_FORMAT_MOD_LINEAR);
return result; return result;
} }
@ -147,15 +155,19 @@ void CHyprOpenGLImpl::initDRMFormats() {
for (auto& fmt : formats) { for (auto& fmt : formats) {
std::vector<uint64_t> mods; std::vector<uint64_t> mods;
if (!DISABLE_MODS) if (!DISABLE_MODS) {
mods = getModsForFormat(fmt); auto ret = getModsForFormat(fmt);
else if (!ret.has_value())
continue;
mods = *ret;
} else
mods = {DRM_FORMAT_MOD_LINEAR}; mods = {DRM_FORMAT_MOD_LINEAR};
m_bHasModifiers = m_bHasModifiers || mods.size() > 0; m_bHasModifiers = m_bHasModifiers || mods.size() > 0;
if (mods.size() == 0) // EGL can always do implicit modifiers.
continue; mods.push_back(DRM_FORMAT_MOD_INVALID);
dmaFormats.push_back(SDRMFormat{ dmaFormats.push_back(SDRMFormat{
.format = fmt, .format = fmt,

View file

@ -238,7 +238,9 @@ class CHyprOpenGLImpl {
void createBGTextureForMonitor(CMonitor*); void createBGTextureForMonitor(CMonitor*);
void initShaders(); void initShaders();
void initDRMFormats(); void initDRMFormats();
std::vector<uint64_t> getModsForFormat(EGLint format);
//
std::optional<std::vector<uint64_t>> getModsForFormat(EGLint format);
// returns the out FB, can be either Mirror or MirrorSwap // returns the out FB, can be either Mirror or MirrorSwap
CFramebuffer* blurMainFramebufferWithDamage(float a, CRegion* damage); CFramebuffer* blurMainFramebufferWithDamage(float a, CRegion* damage);