forked from quickshell/quickshell
wayland/screencopy: use all dmabuf planes and modifiers in egl image
Fixes black texture on nvidia
This commit is contained in:
parent
bf235d3d4d
commit
abd9a3c5f8
1 changed files with 72 additions and 6 deletions
|
@ -6,6 +6,7 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <EGL/egl.h>
|
#include <EGL/egl.h>
|
||||||
#include <EGL/eglext.h>
|
#include <EGL/eglext.h>
|
||||||
|
@ -555,23 +556,88 @@ WlBufferQSGTexture* WlDmaBuffer::createQsgTexture(QQuickWindow* window) const {
|
||||||
|
|
||||||
auto* display = qEglContext->display();
|
auto* display = qEglContext->display();
|
||||||
|
|
||||||
|
// Ref https://github.com/hyprwm/hyprlock/blob/da1d076d849fc0f298c1d287bddd04802bf7d0f9/src/renderer/Screencopy.cpp#L194
|
||||||
|
struct AttribNameSet {
|
||||||
|
EGLAttrib fd;
|
||||||
|
EGLAttrib offset;
|
||||||
|
EGLAttrib pitch;
|
||||||
|
EGLAttrib modlo;
|
||||||
|
EGLAttrib modhi;
|
||||||
|
};
|
||||||
|
|
||||||
|
static auto attribNames = std::array<AttribNameSet, 4> {
|
||||||
|
AttribNameSet {
|
||||||
|
.fd = EGL_DMA_BUF_PLANE0_FD_EXT,
|
||||||
|
.offset = EGL_DMA_BUF_PLANE0_OFFSET_EXT,
|
||||||
|
.pitch = EGL_DMA_BUF_PLANE0_PITCH_EXT,
|
||||||
|
.modlo = EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT,
|
||||||
|
.modhi = EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT
|
||||||
|
},
|
||||||
|
AttribNameSet {
|
||||||
|
.fd = EGL_DMA_BUF_PLANE1_FD_EXT,
|
||||||
|
.offset = EGL_DMA_BUF_PLANE1_OFFSET_EXT,
|
||||||
|
.pitch = EGL_DMA_BUF_PLANE1_PITCH_EXT,
|
||||||
|
.modlo = EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT,
|
||||||
|
.modhi = EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT
|
||||||
|
},
|
||||||
|
AttribNameSet {
|
||||||
|
.fd = EGL_DMA_BUF_PLANE2_FD_EXT,
|
||||||
|
.offset = EGL_DMA_BUF_PLANE2_OFFSET_EXT,
|
||||||
|
.pitch = EGL_DMA_BUF_PLANE2_PITCH_EXT,
|
||||||
|
.modlo = EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT,
|
||||||
|
.modhi = EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT
|
||||||
|
},
|
||||||
|
AttribNameSet {
|
||||||
|
.fd = EGL_DMA_BUF_PLANE3_FD_EXT,
|
||||||
|
.offset = EGL_DMA_BUF_PLANE3_OFFSET_EXT,
|
||||||
|
.pitch = EGL_DMA_BUF_PLANE3_PITCH_EXT,
|
||||||
|
.modlo = EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT,
|
||||||
|
.modhi = EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
auto attribs = std::array<EGLAttrib, 6 * 2 + 1> {
|
auto attribs = std::vector<EGLAttrib> {
|
||||||
EGL_WIDTH, this->width,
|
EGL_WIDTH, this->width,
|
||||||
EGL_HEIGHT, this->height,
|
EGL_HEIGHT, this->height,
|
||||||
EGL_LINUX_DRM_FOURCC_EXT, this->format,
|
EGL_LINUX_DRM_FOURCC_EXT, this->format,
|
||||||
EGL_DMA_BUF_PLANE0_FD_EXT, this->planes[0].fd, // NOLINT
|
|
||||||
EGL_DMA_BUF_PLANE0_OFFSET_EXT, this->planes[0].offset, // NOLINT
|
|
||||||
EGL_DMA_BUF_PLANE0_PITCH_EXT, this->planes[0].stride, // NOLINT
|
|
||||||
EGL_NONE
|
|
||||||
};
|
};
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
|
if (this->planeCount > 4) {
|
||||||
|
qFatal(logDmabuf) << "Could not create EGL attrib array with more than 4 planes. Count:"
|
||||||
|
<< this->planeCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto i = 0; i != this->planeCount; i++) {
|
||||||
|
const auto& names = attribNames[i];
|
||||||
|
const auto& plane = this->planes[i]; // NOLINT
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
attribs.insert(attribs.end(), {
|
||||||
|
names.fd, plane.fd,
|
||||||
|
names.offset, plane.offset,
|
||||||
|
names.pitch, plane.stride,
|
||||||
|
});
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
if (this->modifier != DRM_FORMAT_MOD_INVALID) {
|
||||||
|
attribs.insert(attribs.end(), {
|
||||||
|
names.modlo, static_cast<EGLAttrib>(this->modifier & 0xFFFFFFFF),
|
||||||
|
names.modhi, static_cast<EGLAttrib>(this->modifier >> 32),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// clang-format on
|
||||||
|
}
|
||||||
|
|
||||||
|
attribs.emplace_back(EGL_NONE);
|
||||||
|
|
||||||
auto* eglImage =
|
auto* eglImage =
|
||||||
eglCreateImage(display, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, nullptr, attribs.data());
|
eglCreateImage(display, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, nullptr, attribs.data());
|
||||||
|
|
||||||
if (eglImage == EGL_NO_IMAGE) {
|
if (eglImage == EGL_NO_IMAGE) {
|
||||||
qFatal() << "failed to make egl image" << eglGetError();
|
qFatal() << "Failed to create egl image" << eglGetError();
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue