Skip to content

Commit abd9a3c

Browse files
committed
wayland/screencopy: use all dmabuf planes and modifiers in egl image
Fixes black texture on nvidia
1 parent bf235d3 commit abd9a3c

File tree

1 file changed

+72
-6
lines changed

1 file changed

+72
-6
lines changed

src/wayland/buffer/dmabuf.cpp

Lines changed: 72 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <memory>
77
#include <string>
88
#include <utility>
9+
#include <vector>
910

1011
#include <EGL/egl.h>
1112
#include <EGL/eglext.h>
@@ -555,23 +556,88 @@ WlBufferQSGTexture* WlDmaBuffer::createQsgTexture(QQuickWindow* window) const {
555556

556557
auto* display = qEglContext->display();
557558

559+
// Ref https://github.com/hyprwm/hyprlock/blob/da1d076d849fc0f298c1d287bddd04802bf7d0f9/src/renderer/Screencopy.cpp#L194
560+
struct AttribNameSet {
561+
EGLAttrib fd;
562+
EGLAttrib offset;
563+
EGLAttrib pitch;
564+
EGLAttrib modlo;
565+
EGLAttrib modhi;
566+
};
567+
568+
static auto attribNames = std::array<AttribNameSet, 4> {
569+
AttribNameSet {
570+
.fd = EGL_DMA_BUF_PLANE0_FD_EXT,
571+
.offset = EGL_DMA_BUF_PLANE0_OFFSET_EXT,
572+
.pitch = EGL_DMA_BUF_PLANE0_PITCH_EXT,
573+
.modlo = EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT,
574+
.modhi = EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT
575+
},
576+
AttribNameSet {
577+
.fd = EGL_DMA_BUF_PLANE1_FD_EXT,
578+
.offset = EGL_DMA_BUF_PLANE1_OFFSET_EXT,
579+
.pitch = EGL_DMA_BUF_PLANE1_PITCH_EXT,
580+
.modlo = EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT,
581+
.modhi = EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT
582+
},
583+
AttribNameSet {
584+
.fd = EGL_DMA_BUF_PLANE2_FD_EXT,
585+
.offset = EGL_DMA_BUF_PLANE2_OFFSET_EXT,
586+
.pitch = EGL_DMA_BUF_PLANE2_PITCH_EXT,
587+
.modlo = EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT,
588+
.modhi = EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT
589+
},
590+
AttribNameSet {
591+
.fd = EGL_DMA_BUF_PLANE3_FD_EXT,
592+
.offset = EGL_DMA_BUF_PLANE3_OFFSET_EXT,
593+
.pitch = EGL_DMA_BUF_PLANE3_PITCH_EXT,
594+
.modlo = EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT,
595+
.modhi = EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT
596+
}
597+
};
598+
558599
// clang-format off
559-
auto attribs = std::array<EGLAttrib, 6 * 2 + 1> {
600+
auto attribs = std::vector<EGLAttrib> {
560601
EGL_WIDTH, this->width,
561602
EGL_HEIGHT, this->height,
562603
EGL_LINUX_DRM_FOURCC_EXT, this->format,
563-
EGL_DMA_BUF_PLANE0_FD_EXT, this->planes[0].fd, // NOLINT
564-
EGL_DMA_BUF_PLANE0_OFFSET_EXT, this->planes[0].offset, // NOLINT
565-
EGL_DMA_BUF_PLANE0_PITCH_EXT, this->planes[0].stride, // NOLINT
566-
EGL_NONE
567604
};
568605
// clang-format on
569606

607+
if (this->planeCount > 4) {
608+
qFatal(logDmabuf) << "Could not create EGL attrib array with more than 4 planes. Count:"
609+
<< this->planeCount;
610+
}
611+
612+
for (auto i = 0; i != this->planeCount; i++) {
613+
const auto& names = attribNames[i];
614+
const auto& plane = this->planes[i]; // NOLINT
615+
616+
// clang-format off
617+
attribs.insert(attribs.end(), {
618+
names.fd, plane.fd,
619+
names.offset, plane.offset,
620+
names.pitch, plane.stride,
621+
});
622+
// clang-format on
623+
624+
// clang-format off
625+
if (this->modifier != DRM_FORMAT_MOD_INVALID) {
626+
attribs.insert(attribs.end(), {
627+
names.modlo, static_cast<EGLAttrib>(this->modifier & 0xFFFFFFFF),
628+
names.modhi, static_cast<EGLAttrib>(this->modifier >> 32),
629+
});
630+
}
631+
// clang-format on
632+
}
633+
634+
attribs.emplace_back(EGL_NONE);
635+
570636
auto* eglImage =
571637
eglCreateImage(display, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, nullptr, attribs.data());
572638

573639
if (eglImage == EGL_NO_IMAGE) {
574-
qFatal() << "failed to make egl image" << eglGetError();
640+
qFatal() << "Failed to create egl image" << eglGetError();
575641
return nullptr;
576642
}
577643

0 commit comments

Comments
 (0)