From 45bea6dab2530a4d6b6ef2275ae37c0241853504 Mon Sep 17 00:00:00 2001 From: vaxerski Date: Fri, 12 Jul 2024 17:20:08 +0200 Subject: [PATCH] drm/renderer: support external rendering --- src/allocator/GBM.cpp | 3 +- src/backend/drm/Renderer.cpp | 60 +++++++++++++++++++++++------------- src/backend/drm/Renderer.hpp | 4 +-- 3 files changed, 42 insertions(+), 25 deletions(-) diff --git a/src/allocator/GBM.cpp b/src/allocator/GBM.cpp index 6bc01fb..90396ce 100644 --- a/src/allocator/GBM.cpp +++ b/src/allocator/GBM.cpp @@ -53,8 +53,7 @@ static SDRMFormat guessFormatFrom(std::vector formats, bool cursor) } Aquamarine::CGBMBuffer::CGBMBuffer(const SAllocatorBufferParams& params, Hyprutils::Memory::CWeakPointer allocator_, - Hyprutils::Memory::CSharedPointer swapchain) : - allocator(allocator_) { + Hyprutils::Memory::CSharedPointer swapchain) : allocator(allocator_) { if (!allocator) return; diff --git a/src/backend/drm/Renderer.cpp b/src/backend/drm/Renderer.cpp index 9f24876..1d20e16 100644 --- a/src/backend/drm/Renderer.cpp +++ b/src/backend/drm/Renderer.cpp @@ -83,6 +83,16 @@ void main() { gl_FragColor = texture2D(tex, v_texcoord); })#"; +inline const std::string FRAG_SRC_EXT = R"#( +#extension GL_OES_EGL_image_external : require +precision highp float; +varying vec2 v_texcoord; // is in 0-1 +uniform samplerExternalOES texture0; + +void main() { + gl_FragColor = texture2D(texture0, v_texcoord); +})#"; + // ------------------- gbm stuff static int openRenderNode(int drmFd) { @@ -150,19 +160,12 @@ std::optional>> CDRMRenderer::getModsForFo egl.eglQueryDmaBufModifiersEXT(egl.display, format, len, mods.data(), external.data(), &len); std::vector> result; - bool linearIsExternal = false; for (size_t i = 0; i < mods.size(); ++i) { - if (external.at(i)) { - if (mods.at(i) == DRM_FORMAT_MOD_LINEAR) - linearIsExternal = true; - } - result.push_back({mods.at(i), external.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) - result.push_back({DRM_FORMAT_MOD_LINEAR, false}); + if (std::find(mods.begin(), mods.end(), DRM_FORMAT_MOD_LINEAR) == mods.end() && mods.size() == 0) + result.push_back({DRM_FORMAT_MOD_LINEAR, true}); return result; } @@ -209,7 +212,7 @@ bool CDRMRenderer::initDRMFormats() { TRACE(backend->log(AQ_LOG_TRACE, std::format("EGL: GPU Supports Format {} (0x{:x})", fourccToName((uint32_t)fmt), fmt))); for (auto& [mod, external] : mods) { auto modName = drmGetFormatModifierName(mod); - TRACE(backend->log(AQ_LOG_TRACE, std::format("EGL: | with modifier 0x{:x}: {}", mod, modName ? modName : "?unknown?"))); + TRACE(backend->log(AQ_LOG_TRACE, std::format("EGL: | {}with modifier 0x{:x}: {}", (external ? "external only " : ""), mod, modName ? modName : "?unknown?"))); free(modName); } } @@ -368,6 +371,17 @@ SP CDRMRenderer::attempt(int drmfd, SP backend_) { renderer->gl.shader.texAttrib = glGetAttribLocation(renderer->gl.shader.program, "texcoord"); renderer->gl.shader.tex = glGetUniformLocation(renderer->gl.shader.program, "tex"); + renderer->gl.shaderExt.program = createProgram(VERT_SRC, FRAG_SRC_EXT); + if (renderer->gl.shaderExt.program == 0) { + backend_->log(AQ_LOG_ERROR, "CDRMRenderer: fail, shaderExt failed"); + return nullptr; + } + + renderer->gl.shaderExt.proj = glGetUniformLocation(renderer->gl.shaderExt.program, "proj"); + renderer->gl.shaderExt.posAttrib = glGetAttribLocation(renderer->gl.shaderExt.program, "pos"); + renderer->gl.shaderExt.texAttrib = glGetAttribLocation(renderer->gl.shaderExt.program, "texcoord"); + renderer->gl.shaderExt.tex = glGetUniformLocation(renderer->gl.shaderExt.program, "tex"); + renderer->restoreEGL(); backend_->log(AQ_LOG_DEBUG, "CDRMRenderer: success"); @@ -533,7 +547,9 @@ bool CDRMRenderer::blit(SP from, SP to) { } } - TRACE(backend->log(AQ_LOG_TRACE, std::format("EGL (blit): fromTex id {}, image 0x{:x}", fromTex.texid, (uintptr_t)fromTex.image))); + TRACE(backend->log(AQ_LOG_TRACE, + std::format("EGL (blit): fromTex id {}, image 0x{:x}, target {}", fromTex.texid, (uintptr_t)fromTex.image, + fromTex.target == GL_TEXTURE_2D ? "GL_TEXTURE_2D" : "GL_TEXTURE_EXTERNAL_OES"))); // then, get a rbo from our to buffer // if it has an attachment, use that @@ -568,7 +584,7 @@ bool CDRMRenderer::blit(SP from, SP to) { GLCALL(glGenRenderbuffers(1, &rboID)); GLCALL(glBindRenderbuffer(GL_RENDERBUFFER, rboID)); - egl.glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, (GLeglImageOES)rboImage); + GLCALL(egl.glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, (GLeglImageOES)rboImage)); GLCALL(glBindRenderbuffer(GL_RENDERBUFFER, 0)); GLCALL(glGenFramebuffers(1, &fboID)); @@ -608,6 +624,8 @@ bool CDRMRenderer::blit(SP from, SP to) { float monitorProj[9]; matrixIdentity(base); + auto& SHADER = fromTex.target == GL_TEXTURE_2D ? gl.shader : gl.shaderExt; + // KMS uses flipped y, we have to do FLIPPED_180 matrixTranslate(base, toDma.size.x / 2.0, toDma.size.y / 2.0); matrixTransform(base, HYPRUTILS_TRANSFORM_FLIPPED_180); @@ -628,25 +646,25 @@ bool CDRMRenderer::blit(SP from, SP to) { GLCALL(glTexParameteri(fromTex.target, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); GLCALL(glTexParameteri(fromTex.target, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); - GLCALL(glUseProgram(gl.shader.program)); + GLCALL(glUseProgram(SHADER.program)); GLCALL(glDisable(GL_BLEND)); GLCALL(glDisable(GL_SCISSOR_TEST)); matrixTranspose(glMtx, glMtx); - GLCALL(glUniformMatrix3fv(gl.shader.proj, 1, GL_FALSE, glMtx)); + GLCALL(glUniformMatrix3fv(SHADER.proj, 1, GL_FALSE, glMtx)); - GLCALL(glUniform1i(gl.shader.tex, 0)); + GLCALL(glUniform1i(SHADER.tex, 0)); - GLCALL(glVertexAttribPointer(gl.shader.posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts)); - GLCALL(glVertexAttribPointer(gl.shader.texAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts)); + GLCALL(glVertexAttribPointer(SHADER.posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts)); + GLCALL(glVertexAttribPointer(SHADER.texAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts)); - GLCALL(glEnableVertexAttribArray(gl.shader.posAttrib)); - GLCALL(glEnableVertexAttribArray(gl.shader.texAttrib)); + GLCALL(glEnableVertexAttribArray(SHADER.posAttrib)); + GLCALL(glEnableVertexAttribArray(SHADER.texAttrib)); GLCALL(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); - GLCALL(glDisableVertexAttribArray(gl.shader.posAttrib)); - GLCALL(glDisableVertexAttribArray(gl.shader.texAttrib)); + GLCALL(glDisableVertexAttribArray(SHADER.posAttrib)); + GLCALL(glDisableVertexAttribArray(SHADER.texAttrib)); GLCALL(glBindTexture(fromTex.target, 0)); diff --git a/src/backend/drm/Renderer.hpp b/src/backend/drm/Renderer.hpp index 692d224..c3b6e40 100644 --- a/src/backend/drm/Renderer.hpp +++ b/src/backend/drm/Renderer.hpp @@ -43,10 +43,10 @@ namespace Aquamarine { void onBufferAttachmentDrop(CDRMRendererBufferAttachment* attachment); struct { - struct { + struct SShader { GLuint program = 0; GLint proj = -1, tex = -1, posAttrib = -1, texAttrib = -1; - } shader; + } shader, shaderExt; } gl; struct {