[{"id":37647,"web_url":"https://patchwork.libcamera.org/comment/37647/","msgid":"<3bfaf9d5-822d-4353-84cb-4c1726461105@collabora.com>","date":"2026-01-14T11:12:13","subject":"Re: [PATCH] RFC: egl: Implement DMABuf import for input buffers","submitter":{"id":140,"url":"https://patchwork.libcamera.org/api/people/140/","name":"Robert Mader","email":"robert.mader@collabora.com"},"content":"Just a note/reminder from the weekly call:\n\nOn 10.01.26 22:09, Robert Mader wrote:\n> In many cases we can import the GPU-ISP input buffer, a dmabuf from v4l2,\n> directly into EGL instead of mapping and uploading - i.e. copying - it.\n> This reduces memory bandwith usage and can even slightly improve\n> latency.\n> This main reason this doesn't work in many cases is the stride\n> alignment, as GPUs often have stricter requirements (often 128 or even\n> 256 bytes) than hardware ISPs.\n>\n> Thus try to import buffer directly and - if that fails - fall back to\n> the previous upload path. To do so, adjust some function parameters and\n> turn down error messages. Failing imports should come at low cost as\n> drivers know the limitations and can bail out early, without causing\n> additional IO or context switches.\n>\n> In the future we might be able to request buffers with a matching stride\n> from v4l2 drivers in many cases, making direct import the norm instead\n> of a hit-or-miss. An optional kernel API for that exists, but doesn't\n> seem to be implemented by any driver tested so far.\n>\n> Signed-off-by: Robert Mader <robert.mader@collabora.com>\n>\n> ---\n>\n> This patch should be applied on top of\n> https://patchwork.libcamera.org/cover/25706/\n> ---\n>   include/libcamera/internal/egl.h           |  4 +--\n>   src/libcamera/egl.cpp                      | 37 +++++++++++++++++-----\n>   src/libcamera/software_isp/debayer_egl.cpp | 21 ++++++------\n>   src/libcamera/software_isp/debayer_egl.h   |  2 +-\n>   4 files changed, 44 insertions(+), 20 deletions(-)\n>\n> diff --git a/include/libcamera/internal/egl.h b/include/libcamera/internal/egl.h\n> index f007f448a..b61769542 100644\n> --- a/include/libcamera/internal/egl.h\n> +++ b/include/libcamera/internal/egl.h\n> @@ -98,7 +98,7 @@ public:\n>   \n>   \tint initEGLContext(GBM *gbmContext);\n>   \n> -\tint createInputDMABufTexture2D(eGLImage &eglImage, int fd);\n> +\tint createInputDMABufTexture2D(eGLImage &eglImage, int fd, GLint format, uint32_t width, uint32_t height);\n>   \tint createOutputDMABufTexture2D(eGLImage &eglImage, int fd);\n>   \tvoid destroyDMABufTexture(eGLImage &eglImage);\n>   \tvoid createTexture2D(eGLImage &eglImage, GLint format, uint32_t width, uint32_t height, void *data);\n> @@ -131,7 +131,7 @@ private:\n>   \t\t\t  unsigned int shaderDataLen,\n>   \t\t\t  Span<const std::string> shaderEnv);\n>   \n> -\tint createDMABufTexture2D(eGLImage &eglImage, int fd, bool output);\n> +\tint createDMABufTexture2D(eGLImage &eglImage, int fd, uint32_t drm_format, uint32_t width, uint32_t height, bool output);\n>   \n>   \tPFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES;\n>   \tPFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR;\n> diff --git a/src/libcamera/egl.cpp b/src/libcamera/egl.cpp\n> index 0ffd008c7..2853be7c0 100644\n> --- a/src/libcamera/egl.cpp\n> +++ b/src/libcamera/egl.cpp\n> @@ -19,6 +19,7 @@\n>   \n>   #include <libcamera/base/thread.h>\n>   \n> +#include <GLES3/gl32.h>\n>   #include <libdrm/drm_fourcc.h>\n>   \n>   namespace libcamera {\n> @@ -102,6 +103,9 @@ void eGL::syncOutput()\n>    * \\brief Create a DMA-BUF backed 2D texture\n>    * \\param[in,out] eglImage EGL image to associate with the DMA-BUF\n>    * \\param[in] fd DMA-BUF file descriptor\n> + * \\param[in] drm_format the DRM fourcc\n> + * \\param[in] width the buffer width\n> + * \\param[in] height the buffer height\n>    * \\param[in] output If true, create framebuffer for render target\n>    *\n>    * Internal implementation for creating DMA-BUF textures. Creates an EGL\n> @@ -110,7 +114,7 @@ void eGL::syncOutput()\n>    *\n>    * \\return 0 on success, or -ENODEV on failure\n>    */\n> -int eGL::createDMABufTexture2D(eGLImage &eglImage, int fd, bool output)\n> +int eGL::createDMABufTexture2D(eGLImage &eglImage, int fd, uint32_t drm_format, uint32_t width, uint32_t height, bool output)\n>   {\n>   \tint ret = 0;\n>   \n> @@ -118,9 +122,9 @@ int eGL::createDMABufTexture2D(eGLImage &eglImage, int fd, bool output)\n>   \n>   \t// clang-format off\n>   \tEGLint image_attrs[] = {\n> -\t\tEGL_WIDTH, (EGLint)eglImage.width_,\n> -\t\tEGL_HEIGHT, (EGLint)eglImage.height_,\n> -\t\tEGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_ARGB8888,\n> +\t\tEGL_WIDTH, (EGLint)width,\n> +\t\tEGL_HEIGHT, (EGLint)height,\n> +\t\tEGL_LINUX_DRM_FOURCC_EXT, (EGLint)drm_format,\n>   \t\tEGL_DMA_BUF_PLANE0_FD_EXT, fd,\n>   \t\tEGL_DMA_BUF_PLANE0_OFFSET_EXT, 0,\n>   \t\tEGL_DMA_BUF_PLANE0_PITCH_EXT, (EGLint)eglImage.stride_,\n> @@ -135,7 +139,7 @@ int eGL::createDMABufTexture2D(eGLImage &eglImage, int fd, bool output)\n>   \t\t\t\t\t    NULL, image_attrs);\n>   \n>   \tif (eglImage.image_ == EGL_NO_IMAGE_KHR) {\n> -\t\tLOG(eGL, Error) << \"eglCreateImageKHR fail\";\n> +\t\tLOG(eGL, Debug) << \"eglCreateImageKHR fail\";\n>   \t\tret = -ENODEV;\n>   \t\tgoto done;\n>   \t}\n> @@ -176,6 +180,9 @@ done:\n>    * \\brief Create an input DMA-BUF backed texture\n>    * \\param[in,out] eglImage EGL image to associate with the DMA-BUF\n>    * \\param[in] fd DMA-BUF file descriptor\n> + * \\param[in] format the GL format\n> + * \\param[in] width the buffer width\n> + * \\param[in] height the buffer height\n>    *\n>    * Creates an EGL image from a DMA-BUF file descriptor and binds it to\n>    * a 2D texture for use as an input texture in shaders. The texture is\n> @@ -183,11 +190,25 @@ done:\n>    *\n>    * \\return 0 on success, or -ENODEV on failure\n>    */\n> -int eGL::createInputDMABufTexture2D(eGLImage &eglImage, int fd)\n> +int eGL::createInputDMABufTexture2D(eGLImage &eglImage, int fd, GLint format, uint32_t width, uint32_t height)\n>   {\n> +\tEGLint drm_format;\n> +\n>   \tASSERT(tid_ == Thread::currentId());\n>   \n> -\treturn createDMABufTexture2D(eglImage, fd, false);\n> +\tswitch (format) {\n> +\tcase GL_LUMINANCE:\n> +\t\tdrm_format = DRM_FORMAT_R8;\n> +\t\tbreak;\n> +\tcase GL_RG:\n> +\t\tdrm_format = DRM_FORMAT_RG88;\n> +\t\tbreak;\n> +\tdefault:\n> +\t\tLOG(eGL, Error) << \"unhandled GL format\";\n> +\t\treturn -ENODEV;\n> +\t}\n> +\n> +\treturn createDMABufTexture2D(eglImage, fd, drm_format, width, height, false);\n>   }\n>   \n>   /**\n> @@ -206,7 +227,7 @@ int eGL::createOutputDMABufTexture2D(eGLImage &eglImage, int fd)\n>   {\n>   \tASSERT(tid_ == Thread::currentId());\n>   \n> -\treturn createDMABufTexture2D(eglImage, fd, true);\n> +\treturn createDMABufTexture2D(eglImage, fd, DRM_FORMAT_ARGB8888, eglImage.width_, eglImage.height_, true);\n>   }\n>   \n>   /**\n> diff --git a/src/libcamera/software_isp/debayer_egl.cpp b/src/libcamera/software_isp/debayer_egl.cpp\n> index 9693d7252..e6387c851 100644\n> --- a/src/libcamera/software_isp/debayer_egl.cpp\n> +++ b/src/libcamera/software_isp/debayer_egl.cpp\n> @@ -509,13 +509,22 @@ void DebayerEGL::setShaderVariableValues(DebayerParams &params)\n>   \treturn;\n>   }\n>   \n> -int DebayerEGL::debayerGPU(MappedFrameBuffer &in, int out_fd, DebayerParams &params)\n> +int DebayerEGL::debayerGPU(FrameBuffer *input, int out_fd, DebayerParams &params)\n>   {\n>   \t/* eGL context switch */\n>   \tegl_.makeCurrent();\n>   \n>   \t/* Create a standard texture input */\n> -\tegl_.createTexture2D(*eglImageBayerIn_, glFormat_, inputConfig_.stride / bytesPerPixel_, height_, in.planes()[0].data());\n> +\tif (egl_.createInputDMABufTexture2D(*eglImageBayerIn_, input->planes()[0].fd.get(), glFormat_, inputConfig_.stride / bytesPerPixel_, height_) != 0) {\nWe're currently trying the import on every frame instead of remembering \nwhether it failed on previous calls. I'm relatively sure that drivers \nbail fairly early, before doing any syscalls/context switches, if e.g. \nthe stride doesn't match - but then import might still fail later in the \nkernel in certain cases. Remembering that should be pretty straight \nforward, so I should probably just do that.\n> +\t\tMappedFrameBuffer in(input, MappedFrameBuffer::MapFlag::Read);\n> +\t\tif (!in.isValid()) {\n> +\t\t\tLOG(Debayer, Error) << \"mmap-ing buffer(s) failed\";\n> +\t\t\treturn -ENODEV;\n> +\t\t}\n> +\n> +\t\tLOG(Debayer, Debug) << \"Importing input buffer with DMABuf import failed, falling back to upload\";\n> +\t\tegl_.createTexture2D(*eglImageBayerIn_, glFormat_, inputConfig_.stride / bytesPerPixel_, height_, in.planes()[0].data());\n> +\t}\n>   \n>   \t/* Generate the output render framebuffer as render to texture */\n>   \tegl_.createOutputDMABufTexture2D(*eglImageBayerOut_, out_fd);\n> @@ -552,13 +561,7 @@ void DebayerEGL::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output\n>   \tmetadata.sequence = input->metadata().sequence;\n>   \tmetadata.timestamp = input->metadata().timestamp;\n>   \n> -\tMappedFrameBuffer in(input, MappedFrameBuffer::MapFlag::Read);\n> -\tif (!in.isValid()) {\n> -\t\tLOG(Debayer, Error) << \"mmap-ing buffer(s) failed\";\n> -\t\tgoto error;\n> -\t}\n> -\n> -\tif (debayerGPU(in, output->planes()[0].fd.get(), params)) {\n> +\tif (debayerGPU(input, output->planes()[0].fd.get(), params)) {\n>   \t\tLOG(Debayer, Error) << \"debayerGPU failed\";\n>   \t\tgoto error;\n>   \t}\n> diff --git a/src/libcamera/software_isp/debayer_egl.h b/src/libcamera/software_isp/debayer_egl.h\n> index a5033bc63..4b2cf448f 100644\n> --- a/src/libcamera/software_isp/debayer_egl.h\n> +++ b/src/libcamera/software_isp/debayer_egl.h\n> @@ -74,7 +74,7 @@ private:\n>   \tint getShaderVariableLocations();\n>   \tvoid setShaderVariableValues(DebayerParams &params);\n>   \tvoid configureTexture(GLuint &texture);\n> -\tint debayerGPU(MappedFrameBuffer &in, int out_fd, DebayerParams &params);\n> +\tint debayerGPU(FrameBuffer *input, int out_fd, DebayerParams &params);\n>   \n>   \t/* Shader program identifiers */\n>   \tGLuint vertexShaderId_ = 0;","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 40761BDCBF\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 14 Jan 2026 11:12:24 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id CAF2A61FC3;\n\tWed, 14 Jan 2026 12:12:22 +0100 (CET)","from sender4-pp-g120.zoho.com (sender4-pp-g120.zoho.com\n\t[136.143.188.120])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 990A261F9F\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 14 Jan 2026 12:12:21 +0100 (CET)","by mx.zohomail.com with SMTPS id 1768389135755691.3435499177837;\n\tWed, 14 Jan 2026 03:12:15 -0800 (PST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=collabora.com\n\theader.i=robert.mader@collabora.com header.b=\"OknmqbEH\"; \n\tdkim-atps=neutral","ARC-Seal":"i=1; a=rsa-sha256; t=1768389137; cv=none; \n\td=zohomail.com; s=zohoarc; \n\tb=XgpAwfk73YrZQTUetKQdVjhKr6wJDWUSS7Ox85z0C0ZmJxVeqt4HhBYfLCMgcKf6wKE2qdh1OKojpr78iAkP3FYbEJFqYBySP6pFpbQUF1E88ws4M8P1+qRi5uJm0QlNBfWowbUymrXOAavKQHrq2whj5mZp3dPEbJRza3PDBTI=","ARC-Message-Signature":"i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; \n\ts=zohoarc; t=1768389137;\n\th=Content-Type:Content-Transfer-Encoding:Date:Date:From:From:In-Reply-To:MIME-Version:Message-ID:References:Subject:Subject:To:To:Message-Id:Reply-To:Cc;\n\tbh=p2IqlAua13Jtaohqa/BxS8DML8bU7VvHbJKhWlZRD+s=; \n\tb=Dmw+OyWKZ76my6t2nNgdhyx3aoV59mpae+FQXRPhvpkEReTTheQTVVrHw/fQpvXKy6u48Dk+vMK61WmLOxIdMzKmbdv3MZCCPUyLvNupAxycCObMyv0zgtQqJuLIqqjK/1gd2Iuc5hOQeE63koVNHbPtDJDm7hOLwrfPtHPT6VI=","ARC-Authentication-Results":"i=1; mx.zohomail.com;\n\tdkim=pass  header.i=collabora.com;\n\tspf=pass  smtp.mailfrom=robert.mader@collabora.com;\n\tdmarc=pass header.from=<robert.mader@collabora.com>","DKIM-Signature":"v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1768389137;\n\ts=zohomail; d=collabora.com; i=robert.mader@collabora.com;\n\th=Message-ID:Date:Date:MIME-Version:Subject:Subject:To:To:References:From:From:In-Reply-To:Content-Type:Content-Transfer-Encoding:Message-Id:Reply-To:Cc;\n\tbh=p2IqlAua13Jtaohqa/BxS8DML8bU7VvHbJKhWlZRD+s=;\n\tb=OknmqbEHjNBitB0ZOAH7SxzhHZ5PY486KbLg0zbrbTyctLFa6Ul9kSCSKHDhu4LN\n\tuyWf5BNjzenueAMqpRuyfqymw92c9pddF+lsJhJ6X6eHj3jjktgNhVfdC6+a6Sv2rn5\n\t59dNI9fqu/K4Oed9CKCU+g+RHPZD8peLYm1RVHBc=","Message-ID":"<3bfaf9d5-822d-4353-84cb-4c1726461105@collabora.com>","Date":"Wed, 14 Jan 2026 12:12:13 +0100","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH] RFC: egl: Implement DMABuf import for input buffers","To":"libcamera-devel@lists.libcamera.org","References":"<20260110210930.123920-1-robert.mader@collabora.com>","Content-Language":"en-US, de-DE","From":"Robert Mader <robert.mader@collabora.com>","In-Reply-To":"<20260110210930.123920-1-robert.mader@collabora.com>","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"7bit","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":37659,"web_url":"https://patchwork.libcamera.org/comment/37659/","msgid":"<8a11cd1e-a0de-4db8-95bb-bd9f2763ccf7@oss.qualcomm.com>","date":"2026-01-14T15:21:44","subject":"Re: [PATCH] RFC: egl: Implement DMABuf import for input buffers","submitter":{"id":242,"url":"https://patchwork.libcamera.org/api/people/242/","name":"Hans de Goede","email":"johannes.goede@oss.qualcomm.com"},"content":"Hi,\n\nOn 10-Jan-26 22:09, Robert Mader wrote:\n> In many cases we can import the GPU-ISP input buffer, a dmabuf from v4l2,\n> directly into EGL instead of mapping and uploading - i.e. copying - it.\n> This reduces memory bandwith usage and can even slightly improve\n> latency.\n> This main reason this doesn't work in many cases is the stride\n> alignment, as GPUs often have stricter requirements (often 128 or even\n> 256 bytes) than hardware ISPs.\n> \n> Thus try to import buffer directly and - if that fails - fall back to\n> the previous upload path. To do so, adjust some function parameters and\n> turn down error messages. Failing imports should come at low cost as\n> drivers know the limitations and can bail out early, without causing\n> additional IO or context switches.\n> \n> In the future we might be able to request buffers with a matching stride\n> from v4l2 drivers in many cases, making direct import the norm instead\n> of a hit-or-miss. An optional kernel API for that exists, but doesn't\n> seem to be implemented by any driver tested so far.\n> \n> Signed-off-by: Robert Mader <robert.mader@collabora.com>\n\nThanks, I've given this a quick test run and not found any issues:\n\nTested-by: Hans de Goede <johannes.goede@oss.qualcomm.com> # Thinkpad X1 Carbon G13 IPU7 ov08x40\n\nNote it did not seem to make anything faster on this device though,\nso I guess we're hitting the fallback.\n\nRegards,\n\nHans\n\n\n\n> \n> ---\n> \n> This patch should be applied on top of\n> https://patchwork.libcamera.org/cover/25706/\n> ---\n>  include/libcamera/internal/egl.h           |  4 +--\n>  src/libcamera/egl.cpp                      | 37 +++++++++++++++++-----\n>  src/libcamera/software_isp/debayer_egl.cpp | 21 ++++++------\n>  src/libcamera/software_isp/debayer_egl.h   |  2 +-\n>  4 files changed, 44 insertions(+), 20 deletions(-)\n> \n> diff --git a/include/libcamera/internal/egl.h b/include/libcamera/internal/egl.h\n> index f007f448a..b61769542 100644\n> --- a/include/libcamera/internal/egl.h\n> +++ b/include/libcamera/internal/egl.h\n> @@ -98,7 +98,7 @@ public:\n>  \n>  \tint initEGLContext(GBM *gbmContext);\n>  \n> -\tint createInputDMABufTexture2D(eGLImage &eglImage, int fd);\n> +\tint createInputDMABufTexture2D(eGLImage &eglImage, int fd, GLint format, uint32_t width, uint32_t height);\n>  \tint createOutputDMABufTexture2D(eGLImage &eglImage, int fd);\n>  \tvoid destroyDMABufTexture(eGLImage &eglImage);\n>  \tvoid createTexture2D(eGLImage &eglImage, GLint format, uint32_t width, uint32_t height, void *data);\n> @@ -131,7 +131,7 @@ private:\n>  \t\t\t  unsigned int shaderDataLen,\n>  \t\t\t  Span<const std::string> shaderEnv);\n>  \n> -\tint createDMABufTexture2D(eGLImage &eglImage, int fd, bool output);\n> +\tint createDMABufTexture2D(eGLImage &eglImage, int fd, uint32_t drm_format, uint32_t width, uint32_t height, bool output);\n>  \n>  \tPFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES;\n>  \tPFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR;\n> diff --git a/src/libcamera/egl.cpp b/src/libcamera/egl.cpp\n> index 0ffd008c7..2853be7c0 100644\n> --- a/src/libcamera/egl.cpp\n> +++ b/src/libcamera/egl.cpp\n> @@ -19,6 +19,7 @@\n>  \n>  #include <libcamera/base/thread.h>\n>  \n> +#include <GLES3/gl32.h>\n>  #include <libdrm/drm_fourcc.h>\n>  \n>  namespace libcamera {\n> @@ -102,6 +103,9 @@ void eGL::syncOutput()\n>   * \\brief Create a DMA-BUF backed 2D texture\n>   * \\param[in,out] eglImage EGL image to associate with the DMA-BUF\n>   * \\param[in] fd DMA-BUF file descriptor\n> + * \\param[in] drm_format the DRM fourcc\n> + * \\param[in] width the buffer width\n> + * \\param[in] height the buffer height\n>   * \\param[in] output If true, create framebuffer for render target\n>   *\n>   * Internal implementation for creating DMA-BUF textures. Creates an EGL\n> @@ -110,7 +114,7 @@ void eGL::syncOutput()\n>   *\n>   * \\return 0 on success, or -ENODEV on failure\n>   */\n> -int eGL::createDMABufTexture2D(eGLImage &eglImage, int fd, bool output)\n> +int eGL::createDMABufTexture2D(eGLImage &eglImage, int fd, uint32_t drm_format, uint32_t width, uint32_t height, bool output)\n>  {\n>  \tint ret = 0;\n>  \n> @@ -118,9 +122,9 @@ int eGL::createDMABufTexture2D(eGLImage &eglImage, int fd, bool output)\n>  \n>  \t// clang-format off\n>  \tEGLint image_attrs[] = {\n> -\t\tEGL_WIDTH, (EGLint)eglImage.width_,\n> -\t\tEGL_HEIGHT, (EGLint)eglImage.height_,\n> -\t\tEGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_ARGB8888,\n> +\t\tEGL_WIDTH, (EGLint)width,\n> +\t\tEGL_HEIGHT, (EGLint)height,\n> +\t\tEGL_LINUX_DRM_FOURCC_EXT, (EGLint)drm_format,\n>  \t\tEGL_DMA_BUF_PLANE0_FD_EXT, fd,\n>  \t\tEGL_DMA_BUF_PLANE0_OFFSET_EXT, 0,\n>  \t\tEGL_DMA_BUF_PLANE0_PITCH_EXT, (EGLint)eglImage.stride_,\n> @@ -135,7 +139,7 @@ int eGL::createDMABufTexture2D(eGLImage &eglImage, int fd, bool output)\n>  \t\t\t\t\t    NULL, image_attrs);\n>  \n>  \tif (eglImage.image_ == EGL_NO_IMAGE_KHR) {\n> -\t\tLOG(eGL, Error) << \"eglCreateImageKHR fail\";\n> +\t\tLOG(eGL, Debug) << \"eglCreateImageKHR fail\";\n>  \t\tret = -ENODEV;\n>  \t\tgoto done;\n>  \t}\n> @@ -176,6 +180,9 @@ done:\n>   * \\brief Create an input DMA-BUF backed texture\n>   * \\param[in,out] eglImage EGL image to associate with the DMA-BUF\n>   * \\param[in] fd DMA-BUF file descriptor\n> + * \\param[in] format the GL format\n> + * \\param[in] width the buffer width\n> + * \\param[in] height the buffer height\n>   *\n>   * Creates an EGL image from a DMA-BUF file descriptor and binds it to\n>   * a 2D texture for use as an input texture in shaders. The texture is\n> @@ -183,11 +190,25 @@ done:\n>   *\n>   * \\return 0 on success, or -ENODEV on failure\n>   */\n> -int eGL::createInputDMABufTexture2D(eGLImage &eglImage, int fd)\n> +int eGL::createInputDMABufTexture2D(eGLImage &eglImage, int fd, GLint format, uint32_t width, uint32_t height)\n>  {\n> +\tEGLint drm_format;\n> +\n>  \tASSERT(tid_ == Thread::currentId());\n>  \n> -\treturn createDMABufTexture2D(eglImage, fd, false);\n> +\tswitch (format) {\n> +\tcase GL_LUMINANCE:\n> +\t\tdrm_format = DRM_FORMAT_R8;\n> +\t\tbreak;\n> +\tcase GL_RG:\n> +\t\tdrm_format = DRM_FORMAT_RG88;\n> +\t\tbreak;\n> +\tdefault:\n> +\t\tLOG(eGL, Error) << \"unhandled GL format\";\n> +\t\treturn -ENODEV;\n> +\t}\n> +\n> +\treturn createDMABufTexture2D(eglImage, fd, drm_format, width, height, false);\n>  }\n>  \n>  /**\n> @@ -206,7 +227,7 @@ int eGL::createOutputDMABufTexture2D(eGLImage &eglImage, int fd)\n>  {\n>  \tASSERT(tid_ == Thread::currentId());\n>  \n> -\treturn createDMABufTexture2D(eglImage, fd, true);\n> +\treturn createDMABufTexture2D(eglImage, fd, DRM_FORMAT_ARGB8888, eglImage.width_, eglImage.height_, true);\n>  }\n>  \n>  /**\n> diff --git a/src/libcamera/software_isp/debayer_egl.cpp b/src/libcamera/software_isp/debayer_egl.cpp\n> index 9693d7252..e6387c851 100644\n> --- a/src/libcamera/software_isp/debayer_egl.cpp\n> +++ b/src/libcamera/software_isp/debayer_egl.cpp\n> @@ -509,13 +509,22 @@ void DebayerEGL::setShaderVariableValues(DebayerParams &params)\n>  \treturn;\n>  }\n>  \n> -int DebayerEGL::debayerGPU(MappedFrameBuffer &in, int out_fd, DebayerParams &params)\n> +int DebayerEGL::debayerGPU(FrameBuffer *input, int out_fd, DebayerParams &params)\n>  {\n>  \t/* eGL context switch */\n>  \tegl_.makeCurrent();\n>  \n>  \t/* Create a standard texture input */\n> -\tegl_.createTexture2D(*eglImageBayerIn_, glFormat_, inputConfig_.stride / bytesPerPixel_, height_, in.planes()[0].data());\n> +\tif (egl_.createInputDMABufTexture2D(*eglImageBayerIn_, input->planes()[0].fd.get(), glFormat_, inputConfig_.stride / bytesPerPixel_, height_) != 0) {\n> +\t\tMappedFrameBuffer in(input, MappedFrameBuffer::MapFlag::Read);\n> +\t\tif (!in.isValid()) {\n> +\t\t\tLOG(Debayer, Error) << \"mmap-ing buffer(s) failed\";\n> +\t\t\treturn -ENODEV;\n> +\t\t}\n> +\n> +\t\tLOG(Debayer, Debug) << \"Importing input buffer with DMABuf import failed, falling back to upload\";\n> +\t\tegl_.createTexture2D(*eglImageBayerIn_, glFormat_, inputConfig_.stride / bytesPerPixel_, height_, in.planes()[0].data());\n> +\t}\n>  \n>  \t/* Generate the output render framebuffer as render to texture */\n>  \tegl_.createOutputDMABufTexture2D(*eglImageBayerOut_, out_fd);\n> @@ -552,13 +561,7 @@ void DebayerEGL::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output\n>  \tmetadata.sequence = input->metadata().sequence;\n>  \tmetadata.timestamp = input->metadata().timestamp;\n>  \n> -\tMappedFrameBuffer in(input, MappedFrameBuffer::MapFlag::Read);\n> -\tif (!in.isValid()) {\n> -\t\tLOG(Debayer, Error) << \"mmap-ing buffer(s) failed\";\n> -\t\tgoto error;\n> -\t}\n> -\n> -\tif (debayerGPU(in, output->planes()[0].fd.get(), params)) {\n> +\tif (debayerGPU(input, output->planes()[0].fd.get(), params)) {\n>  \t\tLOG(Debayer, Error) << \"debayerGPU failed\";\n>  \t\tgoto error;\n>  \t}\n> diff --git a/src/libcamera/software_isp/debayer_egl.h b/src/libcamera/software_isp/debayer_egl.h\n> index a5033bc63..4b2cf448f 100644\n> --- a/src/libcamera/software_isp/debayer_egl.h\n> +++ b/src/libcamera/software_isp/debayer_egl.h\n> @@ -74,7 +74,7 @@ private:\n>  \tint getShaderVariableLocations();\n>  \tvoid setShaderVariableValues(DebayerParams &params);\n>  \tvoid configureTexture(GLuint &texture);\n> -\tint debayerGPU(MappedFrameBuffer &in, int out_fd, DebayerParams &params);\n> +\tint debayerGPU(FrameBuffer *input, int out_fd, DebayerParams &params);\n>  \n>  \t/* Shader program identifiers */\n>  \tGLuint vertexShaderId_ = 0;","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 09592BDCBF\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 14 Jan 2026 15:21:52 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id B6FE361FC3;\n\tWed, 14 Jan 2026 16:21:51 +0100 (CET)","from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com\n\t[205.220.168.131])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id BC30861F9F\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 14 Jan 2026 16:21:49 +0100 (CET)","from pps.filterd (m0279866.ppops.net [127.0.0.1])\n\tby mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id\n\t60EDnmIc2081707 for <libcamera-devel@lists.libcamera.org>;\n\tWed, 14 Jan 2026 15:21:48 GMT","from mail-qk1-f197.google.com (mail-qk1-f197.google.com\n\t[209.85.222.197])\n\tby mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4bnu58uxx3-1\n\t(version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT)\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 14 Jan 2026 15:21:48 +0000 (GMT)","by mail-qk1-f197.google.com with SMTP id\n\taf79cd13be357-8c38129a433so2312212685a.2\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 14 Jan 2026 07:21:47 -0800 (PST)","from ?IPV6:2001:1c00:c32:7800:5bfa:a036:83f0:f9ec?\n\t(2001-1c00-0c32-7800-5bfa-a036-83f0-f9ec.cable.dynamic.v6.ziggo.nl.\n\t[2001:1c00:c32:7800:5bfa:a036:83f0:f9ec])\n\tby smtp.gmail.com with ESMTPSA id\n\ta640c23a62f3a-b876dd0e9ffsm139718266b.37.2026.01.14.07.21.44\n\t(version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128);\n\tWed, 14 Jan 2026 07:21:45 -0800 (PST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (2048-bit key;\n\tunprotected) header.d=qualcomm.com header.i=@qualcomm.com\n\theader.b=\"Ueq65xwV\"; dkim=pass (2048-bit key;\n\tunprotected) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com\n\theader.b=\"giLfJgYX\"; dkim-atps=neutral","DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h=\n\tcontent-transfer-encoding:content-type:date:from:in-reply-to\n\t:message-id:mime-version:references:subject:to; s=qcppdkim1; bh=\n\tidIMgImW3JCVteJQ9PVwEsadTNKrXQmMUecQIctvK/8=; b=Ueq65xwVXlcMVkCX\n\t2RapQvSKffOCvWzR6OFzqd3bSg461uxhGe/IeEJOT9Qz2VGDyczQ7LeN4EC4vO6x\n\tZnCg98T66ot9fcZkDGiV6KpEwDTmhg5ECj7C1F3pxVEDfjStjHaP2qLiEyqHt31z\n\tnPGoeoEiUAgAy3yg9t4Q9BmX7muYgWpo09EHqqZDNG5FfYVrO6+t5bTTGT3lQwr8\n\tDUJXqlMx6TIUwdySuGor+mJxFebv5om4B43S5wSNk4/0j0I39XmUDhvicfyBEXzn\n\teYWueSmj1gVWmLbr9jwIvjJYW1qb9aubVcMRD2joVYuHEGUg4DYQf9cQwBaOrj1V\n\tPegBBw==","v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=oss.qualcomm.com; s=google; t=1768404107; x=1769008907;\n\tdarn=lists.libcamera.org; \n\th=content-transfer-encoding:in-reply-to:content-language:references\n\t:to:subject:from:user-agent:mime-version:date:message-id:from:to:cc\n\t:subject:date:message-id:reply-to;\n\tbh=idIMgImW3JCVteJQ9PVwEsadTNKrXQmMUecQIctvK/8=;\n\tb=giLfJgYXrdpOuOQsvLuHQvC/qF6FhL7bO/apK1X9F8QOR2idI76q7FcQz7BjgctgO2\n\tDvV9oWNPmiWH9oT4jogkbH6BTia/jxy5+rm/oCcC0YtdOz9vMHrWdsrJWnjSk1d/Jqqe\n\tA4ktR8z27XgJx8/OX+c4SFSmPxuuPx7rFXlLk2LlChlDTzV1mgqbrmXuWKJOZ8k9wjhG\n\tZ1mwtMMKNAGnP5+H2mjb9G1pmrFRB2yXSAk8kbWSzVGpiPgbYsH7Ig5RAwCgwfkDknIK\n\tm2ASVoH/CQwh4O7i4iY1Y8ZxSK9RlbgOF4t/e2gyF1LxhTgqUL5kd84jjS0OM0VLx+m8\n\tWWKA=="],"X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20230601; t=1768404107; x=1769008907;\n\th=content-transfer-encoding:in-reply-to:content-language:references\n\t:to:subject:from:user-agent:mime-version:date:message-id:x-gm-gg\n\t:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to;\n\tbh=idIMgImW3JCVteJQ9PVwEsadTNKrXQmMUecQIctvK/8=;\n\tb=L70Q5YdJEbPKIZAmHedaOjxxctnVXcdX5Rb13ZL+dsubvyoRQbm9CaMs9DGVJGnRGJ\n\tDQ9spJgpznyfnSODK9vUc1BKXGOqYpfAotuus5bPbts3WXW5VQLykcI3KgIiUAffF3dh\n\tywjUk1eky5xgniEaBozuunnUjgF1cBY26bVoH3ctGa+M356m3lXQbgOJLniTfQGMoDY5\n\tHBt8Y/erICmdyU8Yv5L+yiFSIXYG8DGvHzBtuRO2yRVUmvEiCTSfG9zvhgFkOl/kDLAy\n\ts7ijUmUBo+uqFA6HcspzyWwA7fSuBxKHTHrn9sAt2K11AOA52xd/lnN9WCgI4ijBMfQb\n\tenrA==","X-Forwarded-Encrypted":"i=1;\n\tAJvYcCWuiTqSp6kIkMNrfx7qOvHf16pWEaPtg8EM9RwOW7jgLKzTeH3ZdIDsGVyqS8VYkwYz9b7BJ6y/7L90ARBA6jY=@lists.libcamera.org","X-Gm-Message-State":"AOJu0Ywm5m+HgNuzl+LM5cC2wDt8Bgkz09iOO2GQ18YM1CXc6TmdSAn+\n\tqFC3p33dYYijAavoMR6KI5/MeJToLtdiDQ2gikjJGRjzOemaS4zmK6voVpDDEFx0f+tFQ6fW1MY\n\tpTFS/Gbf6iVBxi5PuuI56yCC7VR2acS7O4T2xBvXlwVOVwXzcxGLrdk7CAdUBbVGv3C/RFgNEDW\n\tHnPQWTwGVl","X-Gm-Gg":"AY/fxX6/q57+ve6z2rSakpDTFI5NUS6zbjjeL/WWkMs/psmeRVzGuTkPbaV+rhE1JVX\n\t+kp5nVVYxYTeAAi0mqmAF2A5OXatV5mq967GeIB0n7QqTVzkoN0QhO0Ei20luqL8nI+b5/QP1U9\n\tWkxF2Ki4yEVq2eUEUBk3B6YDPVaN8/vdeNv7qbW9Dj0bU4LxfSKfuSCgIfe2aEfBu4rJqXTVa2h\n\t1n2bPNw2KgmdRO8+jTaS1uo+Otha5+zRyRIGhsFlzfiyFVsn7QK1iv/NMF6JI9EKqC1/Nn9aHjc\n\ted7DFALsQhR7/hI+4joQOiEGFyBDxC5okMo5u4jTquCWnwIUT+PRDFV2UEmZvFG0HpNuIXYrkcq\n\t77C0QazIVpFFHLgD1c4i2p3FP96beKmVdd2pRybtj7Kr7yG3rtB4c7ZpPVmOxxke/HIg9Hk3SrH\n\tSkf3oQkZSbVn4855FaBb0/asY5HOIBTstvE5URvWNaqkdR2T7FZLH5aEII8cfMVCKUYudtbjXgV\n\tDB4","X-Received":["by 2002:a05:620a:3726:b0:8c0:d16b:b09c with SMTP id\n\taf79cd13be357-8c52fbdd39fmr363404985a.58.1768404106524; \n\tWed, 14 Jan 2026 07:21:46 -0800 (PST)","by 2002:a05:620a:3726:b0:8c0:d16b:b09c with SMTP id\n\taf79cd13be357-8c52fbdd39fmr363400085a.58.1768404105834; \n\tWed, 14 Jan 2026 07:21:45 -0800 (PST)"],"Message-ID":"<8a11cd1e-a0de-4db8-95bb-bd9f2763ccf7@oss.qualcomm.com>","Date":"Wed, 14 Jan 2026 16:21:44 +0100","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","From":"johannes.goede@oss.qualcomm.com","Subject":"Re: [PATCH] RFC: egl: Implement DMABuf import for input buffers","To":"Robert Mader <robert.mader@collabora.com>,\n\tlibcamera-devel@lists.libcamera.org","References":"<20260110210930.123920-1-robert.mader@collabora.com>","Content-Language":"en-US, nl","In-Reply-To":"<20260110210930.123920-1-robert.mader@collabora.com>","Content-Type":"text/plain; charset=UTF-8","Content-Transfer-Encoding":"7bit","X-Proofpoint-Spam-Details-Enc":"AW1haW4tMjYwMTE0MDEyOCBTYWx0ZWRfXyGf/J6ca6foc\n\tCCAmTj3wElWe31aMkhr7q2y56pyeVYWQHG5bKPFDdmpuYzNKY7lRx5dpUiUmVGMmAsJvN4chaYR\n\tv3yjjn87/u48KiPkw8hrUFU7Z8zbcG1Lzm2h9Na0LAZqQvRiuaVWA1x3u32WIu71lBxlow39dQ+\n\trg8qJ1rYwd1ME5F5Ay61VyaQTW3aa93+NlQAYXgkEMb5rIa5i2btY6CJHm6LzdzgcHWhDC1g6I9\n\tUKHLUod5sqiJDyt9XV6FNwH3sGqpjHrJ7QXNaXcYi3cRSE3tQ5fhrTvm9aEC/ypp9AZBJGfQqr2\n\tY3KfvUP+e2rxrmzdVzLlsJgCnNBHrf98KiiH6tCv1JWWdyaBoxpRdHulqM3Js10NgaVHBAPDPiy\n\taRq3swj+REcPNn/a+HocN9Z2uCtjv0Opo3WlDJlWF+VMzUnW0xGQN8GehrEjbggBQoF77ec/epH\n\tGNpcMjqifjMLj0l+XhQ==","X-Authority-Analysis":"v=2.4 cv=BZnVE7t2 c=1 sm=1 tr=0 ts=6967b48c cx=c_pps\n\ta=50t2pK5VMbmlHzFWWp8p/g==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10\n\ta=vUbySO9Y5rIA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22\n\ta=YAyIRdgMAAAA:8 a=QX4gbG5DAAAA:8 a=EUspDBNiAAAA:8\n\ta=AvsCf4B-4CM3FxZuHX8A:9\n\ta=QEXdDO2ut3YA:10 a=IoWCM6iH3mJn3m4BftBB:22 a=o1rO4XtwZBNj6n05oSJ_:22\n\ta=AbAUZ8qAyYyZVLSsDulk:22","X-Proofpoint-ORIG-GUID":"LXwx5PdsJuwoa3q8730UYKV2MofGFlMW","X-Proofpoint-GUID":"LXwx5PdsJuwoa3q8730UYKV2MofGFlMW","X-Proofpoint-Virus-Version":"vendor=baseguard\n\tengine=ICAP:2.0.293, Aquarius:18.0.1121, Hydra:6.1.9,\n\tFMLib:17.12.100.49\n\tdefinitions=2026-01-14_04,2026-01-14_01,2025-10-01_01","X-Proofpoint-Spam-Details":"rule=outbound_notspam policy=outbound score=0\n\tsuspectscore=0 impostorscore=0 priorityscore=1501 bulkscore=0\n\tspamscore=0\n\tadultscore=0 malwarescore=0 lowpriorityscore=0 phishscore=0\n\tclxscore=1015\n\tclassifier=typeunknown authscore=0 authtc= authcc= route=outbound\n\tadjust=0\n\treason=mlx scancount=1 engine=8.22.0-2512120000\n\tdefinitions=main-2601140128","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":37663,"web_url":"https://patchwork.libcamera.org/comment/37663/","msgid":"<85fr882m2z.fsf@mzamazal-thinkpadp1gen7.tpbc.csb>","date":"2026-01-14T16:30:44","subject":"Re: [PATCH] RFC: egl: Implement DMABuf import for input buffers","submitter":{"id":177,"url":"https://patchwork.libcamera.org/api/people/177/","name":"Milan Zamazal","email":"mzamazal@redhat.com"},"content":"johannes.goede@oss.qualcomm.com writes:\n\n> Hi,\n>\n> On 10-Jan-26 22:09, Robert Mader wrote:\n>> In many cases we can import the GPU-ISP input buffer, a dmabuf from v4l2,\n>> directly into EGL instead of mapping and uploading - i.e. copying - it.\n>> This reduces memory bandwith usage and can even slightly improve\n>> latency.\n>> This main reason this doesn't work in many cases is the stride\n>> alignment, as GPUs often have stricter requirements (often 128 or even\n>> 256 bytes) than hardware ISPs.\n>> \n>> Thus try to import buffer directly and - if that fails - fall back to\n>> the previous upload path. To do so, adjust some function parameters and\n>> turn down error messages. Failing imports should come at low cost as\n>> drivers know the limitations and can bail out early, without causing\n>> additional IO or context switches.\n>> \n>> In the future we might be able to request buffers with a matching stride\n>> from v4l2 drivers in many cases, making direct import the norm instead\n>> of a hit-or-miss. An optional kernel API for that exists, but doesn't\n>> seem to be implemented by any driver tested so far.\n>> \n>> Signed-off-by: Robert Mader <robert.mader@collabora.com>\n>\n> Thanks, I've given this a quick test run and not found any issues:\n>\n> Tested-by: Hans de Goede <johannes.goede@oss.qualcomm.com> # Thinkpad X1 Carbon G13 IPU7 ov08x40\n>\n> Note it did not seem to make anything faster on this device though,\n> so I guess we're hitting the fallback.\n\nThe same here.\n\nTested-by: Milan Zamazal <mzamazal@redhat.com> # TI AM69\n\n> Regards,\n>\n> Hans\n>\n>\n>\n>> \n>> ---\n>> \n>> This patch should be applied on top of\n>> https://patchwork.libcamera.org/cover/25706/\n>> ---\n>>  include/libcamera/internal/egl.h           |  4 +--\n>>  src/libcamera/egl.cpp                      | 37 +++++++++++++++++-----\n>>  src/libcamera/software_isp/debayer_egl.cpp | 21 ++++++------\n>>  src/libcamera/software_isp/debayer_egl.h   |  2 +-\n>>  4 files changed, 44 insertions(+), 20 deletions(-)\n>> \n>> diff --git a/include/libcamera/internal/egl.h b/include/libcamera/internal/egl.h\n>> index f007f448a..b61769542 100644\n>> --- a/include/libcamera/internal/egl.h\n>> +++ b/include/libcamera/internal/egl.h\n>> @@ -98,7 +98,7 @@ public:\n>>  \n>>  \tint initEGLContext(GBM *gbmContext);\n>>  \n>> -\tint createInputDMABufTexture2D(eGLImage &eglImage, int fd);\n>> +\tint createInputDMABufTexture2D(eGLImage &eglImage, int fd, GLint format, uint32_t width, uint32_t height);\n>>  \tint createOutputDMABufTexture2D(eGLImage &eglImage, int fd);\n>>  \tvoid destroyDMABufTexture(eGLImage &eglImage);\n>>  \tvoid createTexture2D(eGLImage &eglImage, GLint format, uint32_t width, uint32_t height, void *data);\n>> @@ -131,7 +131,7 @@ private:\n>>  \t\t\t  unsigned int shaderDataLen,\n>>  \t\t\t  Span<const std::string> shaderEnv);\n>>  \n>> -\tint createDMABufTexture2D(eGLImage &eglImage, int fd, bool output);\n>> +\tint createDMABufTexture2D(eGLImage &eglImage, int fd, uint32_t drm_format, uint32_t width, uint32_t height, bool output);\n>>  \n>>  \tPFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES;\n>>  \tPFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR;\n>> diff --git a/src/libcamera/egl.cpp b/src/libcamera/egl.cpp\n>> index 0ffd008c7..2853be7c0 100644\n>> --- a/src/libcamera/egl.cpp\n>> +++ b/src/libcamera/egl.cpp\n>> @@ -19,6 +19,7 @@\n>>  \n>>  #include <libcamera/base/thread.h>\n>>  \n>> +#include <GLES3/gl32.h>\n>>  #include <libdrm/drm_fourcc.h>\n>>  \n>>  namespace libcamera {\n>> @@ -102,6 +103,9 @@ void eGL::syncOutput()\n>>   * \\brief Create a DMA-BUF backed 2D texture\n>>   * \\param[in,out] eglImage EGL image to associate with the DMA-BUF\n>>   * \\param[in] fd DMA-BUF file descriptor\n>> + * \\param[in] drm_format the DRM fourcc\n>> + * \\param[in] width the buffer width\n>> + * \\param[in] height the buffer height\n>>   * \\param[in] output If true, create framebuffer for render target\n>>   *\n>>   * Internal implementation for creating DMA-BUF textures. Creates an EGL\n>> @@ -110,7 +114,7 @@ void eGL::syncOutput()\n>>   *\n>>   * \\return 0 on success, or -ENODEV on failure\n>>   */\n>> -int eGL::createDMABufTexture2D(eGLImage &eglImage, int fd, bool output)\n>> +int eGL::createDMABufTexture2D(eGLImage &eglImage, int fd, uint32_t drm_format, uint32_t width, uint32_t height, bool output)\n>>  {\n>>  \tint ret = 0;\n>>  \n>> @@ -118,9 +122,9 @@ int eGL::createDMABufTexture2D(eGLImage &eglImage, int fd, bool output)\n>>  \n>>  \t// clang-format off\n>>  \tEGLint image_attrs[] = {\n>> -\t\tEGL_WIDTH, (EGLint)eglImage.width_,\n>> -\t\tEGL_HEIGHT, (EGLint)eglImage.height_,\n>> -\t\tEGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_ARGB8888,\n>> +\t\tEGL_WIDTH, (EGLint)width,\n>> +\t\tEGL_HEIGHT, (EGLint)height,\n>> +\t\tEGL_LINUX_DRM_FOURCC_EXT, (EGLint)drm_format,\n>>  \t\tEGL_DMA_BUF_PLANE0_FD_EXT, fd,\n>>  \t\tEGL_DMA_BUF_PLANE0_OFFSET_EXT, 0,\n>>  \t\tEGL_DMA_BUF_PLANE0_PITCH_EXT, (EGLint)eglImage.stride_,\n>> @@ -135,7 +139,7 @@ int eGL::createDMABufTexture2D(eGLImage &eglImage, int fd, bool output)\n>>  \t\t\t\t\t    NULL, image_attrs);\n>>  \n>>  \tif (eglImage.image_ == EGL_NO_IMAGE_KHR) {\n>> -\t\tLOG(eGL, Error) << \"eglCreateImageKHR fail\";\n>> +\t\tLOG(eGL, Debug) << \"eglCreateImageKHR fail\";\n>>  \t\tret = -ENODEV;\n>>  \t\tgoto done;\n>>  \t}\n>> @@ -176,6 +180,9 @@ done:\n>>   * \\brief Create an input DMA-BUF backed texture\n>>   * \\param[in,out] eglImage EGL image to associate with the DMA-BUF\n>>   * \\param[in] fd DMA-BUF file descriptor\n>> + * \\param[in] format the GL format\n>> + * \\param[in] width the buffer width\n>> + * \\param[in] height the buffer height\n>>   *\n>>   * Creates an EGL image from a DMA-BUF file descriptor and binds it to\n>>   * a 2D texture for use as an input texture in shaders. The texture is\n>> @@ -183,11 +190,25 @@ done:\n>>   *\n>>   * \\return 0 on success, or -ENODEV on failure\n>>   */\n>> -int eGL::createInputDMABufTexture2D(eGLImage &eglImage, int fd)\n>> +int eGL::createInputDMABufTexture2D(eGLImage &eglImage, int fd, GLint format, uint32_t width, uint32_t height)\n>>  {\n>> +\tEGLint drm_format;\n>> +\n>>  \tASSERT(tid_ == Thread::currentId());\n>>  \n>> -\treturn createDMABufTexture2D(eglImage, fd, false);\n>> +\tswitch (format) {\n>> +\tcase GL_LUMINANCE:\n>> +\t\tdrm_format = DRM_FORMAT_R8;\n>> +\t\tbreak;\n>> +\tcase GL_RG:\n>> +\t\tdrm_format = DRM_FORMAT_RG88;\n>> +\t\tbreak;\n>> +\tdefault:\n>> +\t\tLOG(eGL, Error) << \"unhandled GL format\";\n>> +\t\treturn -ENODEV;\n>> +\t}\n>> +\n>> +\treturn createDMABufTexture2D(eglImage, fd, drm_format, width, height, false);\n>>  }\n>>  \n>>  /**\n>> @@ -206,7 +227,7 @@ int eGL::createOutputDMABufTexture2D(eGLImage &eglImage, int fd)\n>>  {\n>>  \tASSERT(tid_ == Thread::currentId());\n>>  \n>> -\treturn createDMABufTexture2D(eglImage, fd, true);\n>> +\treturn createDMABufTexture2D(eglImage, fd, DRM_FORMAT_ARGB8888, eglImage.width_, eglImage.height_, true);\n>>  }\n>>  \n>>  /**\n>> diff --git a/src/libcamera/software_isp/debayer_egl.cpp b/src/libcamera/software_isp/debayer_egl.cpp\n>> index 9693d7252..e6387c851 100644\n>> --- a/src/libcamera/software_isp/debayer_egl.cpp\n>> +++ b/src/libcamera/software_isp/debayer_egl.cpp\n>> @@ -509,13 +509,22 @@ void DebayerEGL::setShaderVariableValues(DebayerParams &params)\n>>  \treturn;\n>>  }\n>>  \n>> -int DebayerEGL::debayerGPU(MappedFrameBuffer &in, int out_fd, DebayerParams &params)\n>> +int DebayerEGL::debayerGPU(FrameBuffer *input, int out_fd, DebayerParams &params)\n>>  {\n>>  \t/* eGL context switch */\n>>  \tegl_.makeCurrent();\n>>  \n>>  \t/* Create a standard texture input */\n>> -\tegl_.createTexture2D(*eglImageBayerIn_, glFormat_, inputConfig_.stride / bytesPerPixel_, height_, in.planes()[0].data());\n>> +\tif (egl_.createInputDMABufTexture2D(*eglImageBayerIn_, input->planes()[0].fd.get(), glFormat_, inputConfig_.stride / bytesPerPixel_, height_) != 0) {\n>> +\t\tMappedFrameBuffer in(input, MappedFrameBuffer::MapFlag::Read);\n>> +\t\tif (!in.isValid()) {\n>> +\t\t\tLOG(Debayer, Error) << \"mmap-ing buffer(s) failed\";\n>> +\t\t\treturn -ENODEV;\n>> +\t\t}\n>> +\n>> +\t\tLOG(Debayer, Debug) << \"Importing input buffer with DMABuf import failed, falling back to upload\";\n>> +\t\tegl_.createTexture2D(*eglImageBayerIn_, glFormat_, inputConfig_.stride / bytesPerPixel_, height_, in.planes()[0].data());\n>> +\t}\n>>  \n>>  \t/* Generate the output render framebuffer as render to texture */\n>>  \tegl_.createOutputDMABufTexture2D(*eglImageBayerOut_, out_fd);\n>> @@ -552,13 +561,7 @@ void DebayerEGL::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output\n>>  \tmetadata.sequence = input->metadata().sequence;\n>>  \tmetadata.timestamp = input->metadata().timestamp;\n>>  \n>> -\tMappedFrameBuffer in(input, MappedFrameBuffer::MapFlag::Read);\n>> -\tif (!in.isValid()) {\n>> -\t\tLOG(Debayer, Error) << \"mmap-ing buffer(s) failed\";\n>> -\t\tgoto error;\n>> -\t}\n>> -\n>> -\tif (debayerGPU(in, output->planes()[0].fd.get(), params)) {\n>> +\tif (debayerGPU(input, output->planes()[0].fd.get(), params)) {\n>>  \t\tLOG(Debayer, Error) << \"debayerGPU failed\";\n>>  \t\tgoto error;\n>>  \t}\n>> diff --git a/src/libcamera/software_isp/debayer_egl.h b/src/libcamera/software_isp/debayer_egl.h\n>> index a5033bc63..4b2cf448f 100644\n>> --- a/src/libcamera/software_isp/debayer_egl.h\n>> +++ b/src/libcamera/software_isp/debayer_egl.h\n>> @@ -74,7 +74,7 @@ private:\n>>  \tint getShaderVariableLocations();\n>>  \tvoid setShaderVariableValues(DebayerParams &params);\n>>  \tvoid configureTexture(GLuint &texture);\n>> -\tint debayerGPU(MappedFrameBuffer &in, int out_fd, DebayerParams &params);\n>> +\tint debayerGPU(FrameBuffer *input, int out_fd, DebayerParams &params);\n>>  \n>>  \t/* Shader program identifiers */\n>>  \tGLuint vertexShaderId_ = 0;","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 07BD1C3226\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 14 Jan 2026 16:30:53 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id A57A761FC3;\n\tWed, 14 Jan 2026 17:30:52 +0100 (CET)","from us-smtp-delivery-124.mimecast.com\n\t(us-smtp-delivery-124.mimecast.com [170.10.129.124])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 3FC3061F9F\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 14 Jan 2026 17:30:51 +0100 (CET)","from mail-wm1-f72.google.com (mail-wm1-f72.google.com\n\t[209.85.128.72]) by relay.mimecast.com with ESMTP with STARTTLS\n\t(version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id\n\tus-mta-689-NFjLOTdNOO2cW7h7_U2veQ-1; Wed, 14 Jan 2026 11:30:48 -0500","by mail-wm1-f72.google.com with SMTP id\n\t5b1f17b1804b1-4775d8428e8so748335e9.0\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 14 Jan 2026 08:30:47 -0800 (PST)","from mzamazal-thinkpadp1gen7.tpbc.csb\n\t(ip-77-48-47-2.net.vodafone.cz. [77.48.47.2])\n\tby smtp.gmail.com with ESMTPSA id\n\t5b1f17b1804b1-47ee2840b7csm22368985e9.14.2026.01.14.08.30.44\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tWed, 14 Jan 2026 08:30:45 -0800 (PST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=redhat.com header.i=@redhat.com\n\theader.b=\"VQ2kAwOT\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n\ts=mimecast20190719; t=1768408250;\n\th=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n\tto:to:cc:cc:mime-version:mime-version:content-type:content-type:\n\tin-reply-to:in-reply-to:references:references;\n\tbh=VWUJ0nBhZWdnZisz5BbVjDWZtCGQoYjHMPB4nvxflt4=;\n\tb=VQ2kAwOTF2foEKMM1gX2BQ1rM49b4473yuddwH+A8na28zsQpQHxTwlxYAFg/bJdMrOZyU\n\teCRqTrySff5K5W3cMLwG+kxgOR+OhYqV/z9ZlySUk051mJxuRsvWgo7CWh8NgyhhK/emDL\n\tWwV2op6wF7h6yutJ+Fm994yFZLlGmho=","X-MC-Unique":"NFjLOTdNOO2cW7h7_U2veQ-1","X-Mimecast-MFC-AGG-ID":"NFjLOTdNOO2cW7h7_U2veQ_1768408247","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20230601; t=1768408246; x=1769013046;\n\th=mime-version:user-agent:message-id:date:references:in-reply-to\n\t:subject:cc:to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject\n\t:date:message-id:reply-to;\n\tbh=VWUJ0nBhZWdnZisz5BbVjDWZtCGQoYjHMPB4nvxflt4=;\n\tb=Rj6yaLDwBglHtiwVGwVvtnQmAFqEMq5zxSH1rX7ri3wtiV16WNNcujBwIvUTcDulmy\n\tYTiSz1uDkqAIiD9zkF8AjArc+7w4VEptOJOGyoOOghT8AsqqfZ1ilBs34cmjkCBnUAdt\n\tLVtjsC3j3kv4R6DrVGmtsejys9BuR2PQ9TIzerUXQ1dfMl/lVxr9K2FO4FFDWB3MoNpN\n\tkKE9pGN3bA+pffka+4ODIdYcmfTkAjegsdYrubP46y7zvjyWP157QsATow6yHu2tIr9L\n\tqofEZsS1CQ4S1GyKfQPh6xeSmU4umqEux6h/hveXOlbnyIZ5ixVQe+IVMpD3u4UNhDcs\n\trsPw==","X-Forwarded-Encrypted":"i=1;\n\tAJvYcCUXZD9w83G97LsnMcHKtHNt0rlGNP/fA/TjeNkon3d+QC8x6UwfJojPRYYgmlf/WeFp9MSHXaMBru6/V6cTHEs=@lists.libcamera.org","X-Gm-Message-State":"AOJu0YzAqhTwZ9Dy2GO6rEBtrQ4QVjVncgRMMw+o3wqy4FoUBJQOefLd\n\tI/tZFYI40LsWqlQgtr9PXsKhRLQiBDAX3mCgSdpO3Z13jKXybRIineLo6XSr3Eqwy7HxBo9ATSE\n\t7KmwGA6qBahrTkUUuQQLUZGGU576JpmVYAJtUgoh3wqLiV6pZpUkutY5D2t+WliXFIQr/oCGuoF\n\t3WWCghw9vNVOqGQ/lsODuiN1iwOVqazR9GIkE+1S+gVcwF3AfeKIV8SAALFe4=","X-Gm-Gg":"AY/fxX598zZuvyvI93r1TT/5yOJU5IB7Z9VU9qibOWbQh+rep4gZA5271fo+x8VFiO/\n\tMakaegLr624MYsFFNjqtjQ6SkAztM3eIEz/HdAfScQgxrFtSdJwPuDx3XSUXYm4qGJ8MEoZ4yWn\n\t8sVrGJiyLUfNCKJSR9S5DxmpDyfJg93baUj3eQ4xTfZEHApeEKU1vl2kC2gTbgTO8HdtjKQDWah\n\tgNyZMDDC4lxkR5vSCi0x2kbHSPt6eFtyRGhUMr39Cl+qiemDp9Z6+hDVKs/LXQ/CmH/gMMBGs0b\n\ta2NyjgnUU9DHvXpm9KscSAX8h9Ze8TpJUJBaPRK0nIwZ+doAEFT/hu3PPKKq5eNM8shtUWmrcOS\n\tLn5CyNVqlGSShCqiFq2mfx6iHuE01Y9wKRd0cvBc4nIyDsnaI+4vlP7iq/leY9rw=","X-Received":["by 2002:a05:600c:8b58:b0:47e:d943:ec08 with SMTP id\n\t5b1f17b1804b1-47ee483adc2mr29866025e9.28.1768408246350; \n\tWed, 14 Jan 2026 08:30:46 -0800 (PST)","by 2002:a05:600c:8b58:b0:47e:d943:ec08 with SMTP id\n\t5b1f17b1804b1-47ee483adc2mr29865565e9.28.1768408245732; \n\tWed, 14 Jan 2026 08:30:45 -0800 (PST)"],"From":"Milan Zamazal <mzamazal@redhat.com>","To":"Robert Mader <robert.mader@collabora.com>","Cc":"johannes.goede@oss.qualcomm.com,  libcamera-devel@lists.libcamera.org","Subject":"Re: [PATCH] RFC: egl: Implement DMABuf import for input buffers","In-Reply-To":"<8a11cd1e-a0de-4db8-95bb-bd9f2763ccf7@oss.qualcomm.com>\n\t(johannes goede's message of \"Wed, 14 Jan 2026 16:21:44 +0100\")","References":"<20260110210930.123920-1-robert.mader@collabora.com>\n\t<8a11cd1e-a0de-4db8-95bb-bd9f2763ccf7@oss.qualcomm.com>","Date":"Wed, 14 Jan 2026 17:30:44 +0100","Message-ID":"<85fr882m2z.fsf@mzamazal-thinkpadp1gen7.tpbc.csb>","User-Agent":"Gnus/5.13 (Gnus v5.13)","MIME-Version":"1.0","X-Mimecast-Spam-Score":"0","X-Mimecast-MFC-PROC-ID":"nuBs_dz2fw7qQOH5TEdcKJfoZq96VoGfOl2UK3GlHB0_1768408247","X-Mimecast-Originator":"redhat.com","Content-Type":"text/plain","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":37671,"web_url":"https://patchwork.libcamera.org/comment/37671/","msgid":"<25f8b15f-4ac9-4836-8de1-01d7db69388b@ideasonboard.com>","date":"2026-01-15T10:19:02","subject":"Re: [PATCH] RFC: egl: Implement DMABuf import for input buffers","submitter":{"id":216,"url":"https://patchwork.libcamera.org/api/people/216/","name":"Barnabás Pőcze","email":"barnabas.pocze@ideasonboard.com"},"content":"2026. 01. 10. 22:09 keltezéssel, Robert Mader írta:\n> In many cases we can import the GPU-ISP input buffer, a dmabuf from v4l2,\n> directly into EGL instead of mapping and uploading - i.e. copying - it.\n> This reduces memory bandwith usage and can even slightly improve\n> latency.\n> This main reason this doesn't work in many cases is the stride\n> alignment, as GPUs often have stricter requirements (often 128 or even\n> 256 bytes) than hardware ISPs.\n> \n> Thus try to import buffer directly and - if that fails - fall back to\n> the previous upload path. To do so, adjust some function parameters and\n> turn down error messages. Failing imports should come at low cost as\n> drivers know the limitations and can bail out early, without causing\n> additional IO or context switches.\n> \n> In the future we might be able to request buffers with a matching stride\n> from v4l2 drivers in many cases, making direct import the norm instead\n> of a hit-or-miss. An optional kernel API for that exists, but doesn't\n> seem to be implemented by any driver tested so far.\n> \n> Signed-off-by: Robert Mader <robert.mader@collabora.com>\n> \n> ---\n> \n> This patch should be applied on top of\n> https://patchwork.libcamera.org/cover/25706/\n> ---\n>   include/libcamera/internal/egl.h           |  4 +--\n>   src/libcamera/egl.cpp                      | 37 +++++++++++++++++-----\n>   src/libcamera/software_isp/debayer_egl.cpp | 21 ++++++------\n>   src/libcamera/software_isp/debayer_egl.h   |  2 +-\n>   4 files changed, 44 insertions(+), 20 deletions(-)\n> \n> diff --git a/include/libcamera/internal/egl.h b/include/libcamera/internal/egl.h\n> index f007f448a..b61769542 100644\n> --- a/include/libcamera/internal/egl.h\n> +++ b/include/libcamera/internal/egl.h\n> @@ -98,7 +98,7 @@ public:\n>   \n>   \tint initEGLContext(GBM *gbmContext);\n>   \n> -\tint createInputDMABufTexture2D(eGLImage &eglImage, int fd);\n> +\tint createInputDMABufTexture2D(eGLImage &eglImage, int fd, GLint format, uint32_t width, uint32_t height);\n>   \tint createOutputDMABufTexture2D(eGLImage &eglImage, int fd);\n>   \tvoid destroyDMABufTexture(eGLImage &eglImage);\n>   \tvoid createTexture2D(eGLImage &eglImage, GLint format, uint32_t width, uint32_t height, void *data);\n> @@ -131,7 +131,7 @@ private:\n>   \t\t\t  unsigned int shaderDataLen,\n>   \t\t\t  Span<const std::string> shaderEnv);\n>   \n> -\tint createDMABufTexture2D(eGLImage &eglImage, int fd, bool output);\n> +\tint createDMABufTexture2D(eGLImage &eglImage, int fd, uint32_t drm_format, uint32_t width, uint32_t height, bool output);\n>   \n>   \tPFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES;\n>   \tPFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR;\n> diff --git a/src/libcamera/egl.cpp b/src/libcamera/egl.cpp\n> index 0ffd008c7..2853be7c0 100644\n> --- a/src/libcamera/egl.cpp\n> +++ b/src/libcamera/egl.cpp\n> @@ -19,6 +19,7 @@\n>   \n>   #include <libcamera/base/thread.h>\n>   \n> +#include <GLES3/gl32.h>\n>   #include <libdrm/drm_fourcc.h>\n>   \n>   namespace libcamera {\n> @@ -102,6 +103,9 @@ void eGL::syncOutput()\n>    * \\brief Create a DMA-BUF backed 2D texture\n>    * \\param[in,out] eglImage EGL image to associate with the DMA-BUF\n>    * \\param[in] fd DMA-BUF file descriptor\n> + * \\param[in] drm_format the DRM fourcc\n> + * \\param[in] width the buffer width\n> + * \\param[in] height the buffer height\n>    * \\param[in] output If true, create framebuffer for render target\n>    *\n>    * Internal implementation for creating DMA-BUF textures. Creates an EGL\n> @@ -110,7 +114,7 @@ void eGL::syncOutput()\n>    *\n>    * \\return 0 on success, or -ENODEV on failure\n>    */\n> -int eGL::createDMABufTexture2D(eGLImage &eglImage, int fd, bool output)\n> +int eGL::createDMABufTexture2D(eGLImage &eglImage, int fd, uint32_t drm_format, uint32_t width, uint32_t height, bool output)\n>   {\n>   \tint ret = 0;\n>   \n> @@ -118,9 +122,9 @@ int eGL::createDMABufTexture2D(eGLImage &eglImage, int fd, bool output)\n>   \n>   \t// clang-format off\n>   \tEGLint image_attrs[] = {\n> -\t\tEGL_WIDTH, (EGLint)eglImage.width_,\n> -\t\tEGL_HEIGHT, (EGLint)eglImage.height_,\n> -\t\tEGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_ARGB8888,\n> +\t\tEGL_WIDTH, (EGLint)width,\n> +\t\tEGL_HEIGHT, (EGLint)height,\n> +\t\tEGL_LINUX_DRM_FOURCC_EXT, (EGLint)drm_format,\n>   \t\tEGL_DMA_BUF_PLANE0_FD_EXT, fd,\n>   \t\tEGL_DMA_BUF_PLANE0_OFFSET_EXT, 0,\n>   \t\tEGL_DMA_BUF_PLANE0_PITCH_EXT, (EGLint)eglImage.stride_,\n> @@ -135,7 +139,7 @@ int eGL::createDMABufTexture2D(eGLImage &eglImage, int fd, bool output)\n>   \t\t\t\t\t    NULL, image_attrs);\n>   \n>   \tif (eglImage.image_ == EGL_NO_IMAGE_KHR) {\n> -\t\tLOG(eGL, Error) << \"eglCreateImageKHR fail\";\n> +\t\tLOG(eGL, Debug) << \"eglCreateImageKHR fail\";\n>   \t\tret = -ENODEV;\n>   \t\tgoto done;\n>   \t}\n> @@ -176,6 +180,9 @@ done:\n>    * \\brief Create an input DMA-BUF backed texture\n>    * \\param[in,out] eglImage EGL image to associate with the DMA-BUF\n>    * \\param[in] fd DMA-BUF file descriptor\n> + * \\param[in] format the GL format\n> + * \\param[in] width the buffer width\n> + * \\param[in] height the buffer height\n>    *\n>    * Creates an EGL image from a DMA-BUF file descriptor and binds it to\n>    * a 2D texture for use as an input texture in shaders. The texture is\n> @@ -183,11 +190,25 @@ done:\n>    *\n>    * \\return 0 on success, or -ENODEV on failure\n>    */\n> -int eGL::createInputDMABufTexture2D(eGLImage &eglImage, int fd)\n> +int eGL::createInputDMABufTexture2D(eGLImage &eglImage, int fd, GLint format, uint32_t width, uint32_t height)\n>   {\n> +\tEGLint drm_format;\n> +\n>   \tASSERT(tid_ == Thread::currentId());\n>   \n> -\treturn createDMABufTexture2D(eglImage, fd, false);\n> +\tswitch (format) {\n> +\tcase GL_LUMINANCE:\n> +\t\tdrm_format = DRM_FORMAT_R8;\n> +\t\tbreak;\n> +\tcase GL_RG:\n> +\t\tdrm_format = DRM_FORMAT_RG88;\n> +\t\tbreak;\n> +\tdefault:\n> +\t\tLOG(eGL, Error) << \"unhandled GL format\";\n> +\t\treturn -ENODEV;\n> +\t}\n> +\n> +\treturn createDMABufTexture2D(eglImage, fd, drm_format, width, height, false);\n>   }\n>   \n>   /**\n> @@ -206,7 +227,7 @@ int eGL::createOutputDMABufTexture2D(eGLImage &eglImage, int fd)\n>   {\n>   \tASSERT(tid_ == Thread::currentId());\n>   \n> -\treturn createDMABufTexture2D(eglImage, fd, true);\n> +\treturn createDMABufTexture2D(eglImage, fd, DRM_FORMAT_ARGB8888, eglImage.width_, eglImage.height_, true);\n>   }\n>   \n>   /**\n> diff --git a/src/libcamera/software_isp/debayer_egl.cpp b/src/libcamera/software_isp/debayer_egl.cpp\n> index 9693d7252..e6387c851 100644\n> --- a/src/libcamera/software_isp/debayer_egl.cpp\n> +++ b/src/libcamera/software_isp/debayer_egl.cpp\n> @@ -509,13 +509,22 @@ void DebayerEGL::setShaderVariableValues(DebayerParams &params)\n>   \treturn;\n>   }\n>   \n> -int DebayerEGL::debayerGPU(MappedFrameBuffer &in, int out_fd, DebayerParams &params)\n> +int DebayerEGL::debayerGPU(FrameBuffer *input, int out_fd, DebayerParams &params)\n>   {\n>   \t/* eGL context switch */\n>   \tegl_.makeCurrent();\n>   \n>   \t/* Create a standard texture input */\n> -\tegl_.createTexture2D(*eglImageBayerIn_, glFormat_, inputConfig_.stride / bytesPerPixel_, height_, in.planes()[0].data());\n> +\tif (egl_.createInputDMABufTexture2D(*eglImageBayerIn_, input->planes()[0].fd.get(), glFormat_, inputConfig_.stride / bytesPerPixel_, height_) != 0) {\n> +\t\tMappedFrameBuffer in(input, MappedFrameBuffer::MapFlag::Read);\n> +\t\tif (!in.isValid()) {\n> +\t\t\tLOG(Debayer, Error) << \"mmap-ing buffer(s) failed\";\n> +\t\t\treturn -ENODEV;\n> +\t\t}\n> +\n> +\t\tLOG(Debayer, Debug) << \"Importing input buffer with DMABuf import failed, falling back to upload\";\n> +\t\tegl_.createTexture2D(*eglImageBayerIn_, glFormat_, inputConfig_.stride / bytesPerPixel_, height_, in.planes()[0].data());\n> +\t}\n>   \n>   \t/* Generate the output render framebuffer as render to texture */\n>   \tegl_.createOutputDMABufTexture2D(*eglImageBayerOut_, out_fd);\n\nI think I'm a bit confused about this part (existing code as well).\n`createOutputDMABufTexture2D()` unconditionally overwrites the `EGLImageKHR`\nhandle in the `eGLImage::image_`. I traced it with gdb it would appear that\nit is continuously leaking handles. Am I missing something?\n\nAnd of course the same applies to `eglImageBayerIn_` in the introduced, code, no?\n(Although I can't test that part because import fails.)\n\nI have tested:\n\ndiff --git a/src/libcamera/software_isp/debayer_egl.cpp b/src/libcamera/software_isp/debayer_egl.cpp\nindex 3543a678f..9df57d863 100644\n--- a/src/libcamera/software_isp/debayer_egl.cpp\n+++ b/src/libcamera/software_isp/debayer_egl.cpp\n@@ -528,6 +528,9 @@ int DebayerEGL::debayerGPU(FrameBuffer *input, int out_fd, DebayerParams &params\n  \n         /* Generate the output render framebuffer as render to texture */\n         egl_.createOutputDMABufTexture2D(*eglImageBayerOut_, out_fd);\n+       utils::scope_exit outImageGuard([&] {\n+               egl_.destroyDMABufTexture(*eglImageBayerOut_);\n+       });\n  \n         setShaderVariableValues(params);\n         glViewport(0, 0, width_, height_);\n\nand things seem to work, but I'm not sure.\n\nThis also brings us to the question: why aren't `eglImageBayer{In,Out}_` simple local variables?\n\n\nRegards,\nBarnabás Pőcze\n\n> @@ -552,13 +561,7 @@ void DebayerEGL::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output\n>   \tmetadata.sequence = input->metadata().sequence;\n>   \tmetadata.timestamp = input->metadata().timestamp;\n>   \n> -\tMappedFrameBuffer in(input, MappedFrameBuffer::MapFlag::Read);\n> -\tif (!in.isValid()) {\n> -\t\tLOG(Debayer, Error) << \"mmap-ing buffer(s) failed\";\n> -\t\tgoto error;\n> -\t}\n> -\n> -\tif (debayerGPU(in, output->planes()[0].fd.get(), params)) {\n> +\tif (debayerGPU(input, output->planes()[0].fd.get(), params)) {\n>   \t\tLOG(Debayer, Error) << \"debayerGPU failed\";\n>   \t\tgoto error;\n>   \t}\n> diff --git a/src/libcamera/software_isp/debayer_egl.h b/src/libcamera/software_isp/debayer_egl.h\n> index a5033bc63..4b2cf448f 100644\n> --- a/src/libcamera/software_isp/debayer_egl.h\n> +++ b/src/libcamera/software_isp/debayer_egl.h\n> @@ -74,7 +74,7 @@ private:\n>   \tint getShaderVariableLocations();\n>   \tvoid setShaderVariableValues(DebayerParams &params);\n>   \tvoid configureTexture(GLuint &texture);\n> -\tint debayerGPU(MappedFrameBuffer &in, int out_fd, DebayerParams &params);\n> +\tint debayerGPU(FrameBuffer *input, int out_fd, DebayerParams &params);\n>   \n>   \t/* Shader program identifiers */\n>   \tGLuint vertexShaderId_ = 0;","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 15AE9BDCBF\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 15 Jan 2026 10:19:09 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id E21D361FC3;\n\tThu, 15 Jan 2026 11:19:07 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 3ADAC61F61\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 15 Jan 2026 11:19:06 +0100 (CET)","from [192.168.33.20] (185.221.143.114.nat.pool.zt.hu\n\t[185.221.143.114])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id AA1004E1;\n\tThu, 15 Jan 2026 11:18:38 +0100 (CET)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"QuhGGwHa\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1768472318;\n\tbh=7TuonWE4snr62HgdSRzUl2a7LgGHz0kooWS+JOyy41Y=;\n\th=Date:Subject:To:References:From:In-Reply-To:From;\n\tb=QuhGGwHaCOGY6xnE4RnaxPda7Q7KMhDZlqk7/v3l/AaBV58GzxdTALAnMzpz76YFo\n\tSM+1W/EvkSqIxAWz6XWLExQ67zQTexAnpQ7b7wBevCT427OkBPP3iIDQ49DKVB3QrG\n\t5zRY5XHNhSCIeIWaCRcM5uUDbpHQCoaWFCg1K5Qg=","Message-ID":"<25f8b15f-4ac9-4836-8de1-01d7db69388b@ideasonboard.com>","Date":"Thu, 15 Jan 2026 11:19:02 +0100","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH] RFC: egl: Implement DMABuf import for input buffers","To":"Robert Mader <robert.mader@collabora.com>,\n\tlibcamera-devel@lists.libcamera.org","References":"<20260110210930.123920-1-robert.mader@collabora.com>","From":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>","Content-Language":"en-US, hu-HU","In-Reply-To":"<20260110210930.123920-1-robert.mader@collabora.com>","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"8bit","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":37705,"web_url":"https://patchwork.libcamera.org/comment/37705/","msgid":"<7cf5fca6-d495-4a42-96f2-1233be230106@nxsw.ie>","date":"2026-01-16T22:27:39","subject":"Re: [PATCH] RFC: egl: Implement DMABuf import for input buffers","submitter":{"id":226,"url":"https://patchwork.libcamera.org/api/people/226/","name":"Bryan O'Donoghue","email":"bod.linux@nxsw.ie"},"content":"On 15/01/2026 10:19, Barnabás Pőcze wrote:\n> This also brings us to the question: why aren't `eglImageBayer{In,Out}_` simple local variables?\n\nApart from stuffing an object onto the stack, and consuming memory we \ndon't need to for each frame - you also don't want to do glGenTextures() \nand glGenFrameBuffers for each frame for no reason.\n\nDo it once at an init phase and save cycles/memory. IMO members > local \nvariables for this use case.\n\n---\nbod","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id ED77DBDCBF\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 16 Jan 2026 22:27:46 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 2658F61FC4;\n\tFri, 16 Jan 2026 23:27:46 +0100 (CET)","from tor.source.kernel.org (tor.source.kernel.org\n\t[IPv6:2600:3c04:e001:324:0:1991:8:25])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 5635E61FA3\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 16 Jan 2026 23:27:44 +0100 (CET)","from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58])\n\tby tor.source.kernel.org (Postfix) with ESMTP id 33BBB60160;\n\tFri, 16 Jan 2026 22:27:43 +0000 (UTC)","by smtp.kernel.org (Postfix) with ESMTPSA id 170E1C116C6;\n\tFri, 16 Jan 2026 22:27:41 +0000 (UTC)"],"Message-ID":"<7cf5fca6-d495-4a42-96f2-1233be230106@nxsw.ie>","Date":"Fri, 16 Jan 2026 22:27:39 +0000","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH] RFC: egl: Implement DMABuf import for input buffers","To":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>,\n\tRobert Mader <robert.mader@collabora.com>, \n\tlibcamera-devel@lists.libcamera.org","References":"<20260110210930.123920-1-robert.mader@collabora.com>\n\t<zqIuQJUHMPK_IH5FnyURXjnsdebqzfjGeJlc6qJ8oYcQlu-lrsu9bwiOZdgtQEu6uJ0M7XZOz0rpTAtBHRp-OA==@protonmail.internalid>\n\t<25f8b15f-4ac9-4836-8de1-01d7db69388b@ideasonboard.com>","From":"Bryan O'Donoghue <bod.linux@nxsw.ie>","Content-Language":"en-US","In-Reply-To":"<25f8b15f-4ac9-4836-8de1-01d7db69388b@ideasonboard.com>","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"8bit","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":37706,"web_url":"https://patchwork.libcamera.org/comment/37706/","msgid":"<43d08af2-9415-4862-a4bc-8c8bd5a8d622@nxsw.ie>","date":"2026-01-16T22:30:23","subject":"Re: [PATCH] RFC: egl: Implement DMABuf import for input buffers","submitter":{"id":226,"url":"https://patchwork.libcamera.org/api/people/226/","name":"Bryan O'Donoghue","email":"bod.linux@nxsw.ie"},"content":"On 10/01/2026 21:09, Robert Mader wrote:\n>   \t/* Create a standard texture input */\n> -\tegl_.createTexture2D(*eglImageBayerIn_, glFormat_, inputConfig_.stride / bytesPerPixel_, height_, in.planes()[0].data());\n> +\tif (egl_.createInputDMABufTexture2D(*eglImageBayerIn_, input->planes()[0].fd.get(), glFormat_, inputConfig_.stride / bytesPerPixel_, height_) != 0) {\n> +\t\tMappedFrameBuffer in(input, MappedFrameBuffer::MapFlag::Read);\n> +\t\tif (!in.isValid()) {\n> +\t\t\tLOG(Debayer, Error) << \"mmap-ing buffer(s) failed\";\n> +\t\t\treturn -ENODEV;\n> +\t\t}\n> +\n> +\t\tLOG(Debayer, Debug) << \"Importing input buffer with DMABuf import failed, falling back to upload\";\n> +\t\tegl_.createTexture2D(*eglImageBayerIn_, glFormat_, inputConfig_.stride / bytesPerPixel_, height_, in.planes()[0].data());\n> +\t}\n\nI think we should have an overloaded configure() function that passes \ninput and tries this once, setting a flag or hooking a function pointer \nso that we don't run this test again and again for each frame.\n\n---\nbod","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 659F8C3226\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 16 Jan 2026 22:30:32 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 930CC61FB7;\n\tFri, 16 Jan 2026 23:30:31 +0100 (CET)","from sea.source.kernel.org (sea.source.kernel.org\n\t[IPv6:2600:3c0a:e001:78e:0:1991:8:25])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id F031A61FA3\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 16 Jan 2026 23:30:28 +0100 (CET)","from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58])\n\tby sea.source.kernel.org (Postfix) with ESMTP id 4EB264437B;\n\tFri, 16 Jan 2026 22:30:27 +0000 (UTC)","by smtp.kernel.org (Postfix) with ESMTPSA id A8FCDC116C6;\n\tFri, 16 Jan 2026 22:30:26 +0000 (UTC)"],"Message-ID":"<43d08af2-9415-4862-a4bc-8c8bd5a8d622@nxsw.ie>","Date":"Fri, 16 Jan 2026 22:30:23 +0000","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH] RFC: egl: Implement DMABuf import for input buffers","To":"Robert Mader <robert.mader@collabora.com>,\n\tlibcamera-devel@lists.libcamera.org","References":"<ZhjAUOm_CzMW683WbUhjtHWx7e8Ev2AladZLo7hyjhPWqbuu1UD3fJnLxpHcxLdTk8twlLD3h68fq-wJWvNjBg==@protonmail.internalid>\n\t<20260110210930.123920-1-robert.mader@collabora.com>","From":"Bryan O'Donoghue <bod.linux@nxsw.ie>","Content-Language":"en-US","In-Reply-To":"<20260110210930.123920-1-robert.mader@collabora.com>","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"7bit","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":38178,"web_url":"https://patchwork.libcamera.org/comment/38178/","msgid":"<812002d2-71e2-4dc7-96b5-0ca9b9dcdfcd@oss.qualcomm.com>","date":"2026-02-11T15:53:20","subject":"Re: [PATCH] RFC: egl: Implement DMABuf import for input buffers","submitter":{"id":242,"url":"https://patchwork.libcamera.org/api/people/242/","name":"Hans de Goede","email":"johannes.goede@oss.qualcomm.com"},"content":"Hi Robert, et.al,\n\nOn 10-Jan-26 22:09, Robert Mader wrote:\n> In many cases we can import the GPU-ISP input buffer, a dmabuf from v4l2,\n> directly into EGL instead of mapping and uploading - i.e. copying - it.\n> This reduces memory bandwith usage and can even slightly improve\n> latency.\n> This main reason this doesn't work in many cases is the stride\n> alignment, as GPUs often have stricter requirements (often 128 or even\n> 256 bytes) than hardware ISPs.\n> \n> Thus try to import buffer directly and - if that fails - fall back to\n> the previous upload path. To do so, adjust some function parameters and\n> turn down error messages. Failing imports should come at low cost as\n> drivers know the limitations and can bail out early, without causing\n> additional IO or context switches.\n> \n> In the future we might be able to request buffers with a matching stride\n> from v4l2 drivers in many cases, making direct import the norm instead\n> of a hit-or-miss. An optional kernel API for that exists, but doesn't\n> seem to be implemented by any driver tested so far.\n> \n> Signed-off-by: Robert Mader <robert.mader@collabora.com>\n> Tested-by: Hans de Goede <johannes.goede@oss.qualcomm.com> # Thinkpad X1 Carbon G13 IPU7 ov08x40\n> Tested-by: Milan Zamazal <mzamazal@redhat.com> # TI AM69\n\nWhile playing around with this I noticed that the input buf is still\nDMA-synced even when it gets directly imported.\n\nI've come up with the attached patch on top to fix this.\n\nRegards,\n\nHans\n\n\n\n> ---\n> \n> This patch should be applied on top of\n> https://patchwork.libcamera.org/cover/25706/\n> ---\n>  include/libcamera/internal/egl.h           |  4 +--\n>  src/libcamera/egl.cpp                      | 37 +++++++++++++++++-----\n>  src/libcamera/software_isp/debayer_egl.cpp | 21 ++++++------\n>  src/libcamera/software_isp/debayer_egl.h   |  2 +-\n>  4 files changed, 44 insertions(+), 20 deletions(-)\n> \n> diff --git a/include/libcamera/internal/egl.h b/include/libcamera/internal/egl.h\n> index f007f448a..b61769542 100644\n> --- a/include/libcamera/internal/egl.h\n> +++ b/include/libcamera/internal/egl.h\n> @@ -98,7 +98,7 @@ public:\n>  \n>  \tint initEGLContext(GBM *gbmContext);\n>  \n> -\tint createInputDMABufTexture2D(eGLImage &eglImage, int fd);\n> +\tint createInputDMABufTexture2D(eGLImage &eglImage, int fd, GLint format, uint32_t width, uint32_t height);\n>  \tint createOutputDMABufTexture2D(eGLImage &eglImage, int fd);\n>  \tvoid destroyDMABufTexture(eGLImage &eglImage);\n>  \tvoid createTexture2D(eGLImage &eglImage, GLint format, uint32_t width, uint32_t height, void *data);\n> @@ -131,7 +131,7 @@ private:\n>  \t\t\t  unsigned int shaderDataLen,\n>  \t\t\t  Span<const std::string> shaderEnv);\n>  \n> -\tint createDMABufTexture2D(eGLImage &eglImage, int fd, bool output);\n> +\tint createDMABufTexture2D(eGLImage &eglImage, int fd, uint32_t drm_format, uint32_t width, uint32_t height, bool output);\n>  \n>  \tPFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES;\n>  \tPFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR;\n> diff --git a/src/libcamera/egl.cpp b/src/libcamera/egl.cpp\n> index 0ffd008c7..2853be7c0 100644\n> --- a/src/libcamera/egl.cpp\n> +++ b/src/libcamera/egl.cpp\n> @@ -19,6 +19,7 @@\n>  \n>  #include <libcamera/base/thread.h>\n>  \n> +#include <GLES3/gl32.h>\n>  #include <libdrm/drm_fourcc.h>\n>  \n>  namespace libcamera {\n> @@ -102,6 +103,9 @@ void eGL::syncOutput()\n>   * \\brief Create a DMA-BUF backed 2D texture\n>   * \\param[in,out] eglImage EGL image to associate with the DMA-BUF\n>   * \\param[in] fd DMA-BUF file descriptor\n> + * \\param[in] drm_format the DRM fourcc\n> + * \\param[in] width the buffer width\n> + * \\param[in] height the buffer height\n>   * \\param[in] output If true, create framebuffer for render target\n>   *\n>   * Internal implementation for creating DMA-BUF textures. Creates an EGL\n> @@ -110,7 +114,7 @@ void eGL::syncOutput()\n>   *\n>   * \\return 0 on success, or -ENODEV on failure\n>   */\n> -int eGL::createDMABufTexture2D(eGLImage &eglImage, int fd, bool output)\n> +int eGL::createDMABufTexture2D(eGLImage &eglImage, int fd, uint32_t drm_format, uint32_t width, uint32_t height, bool output)\n>  {\n>  \tint ret = 0;\n>  \n> @@ -118,9 +122,9 @@ int eGL::createDMABufTexture2D(eGLImage &eglImage, int fd, bool output)\n>  \n>  \t// clang-format off\n>  \tEGLint image_attrs[] = {\n> -\t\tEGL_WIDTH, (EGLint)eglImage.width_,\n> -\t\tEGL_HEIGHT, (EGLint)eglImage.height_,\n> -\t\tEGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_ARGB8888,\n> +\t\tEGL_WIDTH, (EGLint)width,\n> +\t\tEGL_HEIGHT, (EGLint)height,\n> +\t\tEGL_LINUX_DRM_FOURCC_EXT, (EGLint)drm_format,\n>  \t\tEGL_DMA_BUF_PLANE0_FD_EXT, fd,\n>  \t\tEGL_DMA_BUF_PLANE0_OFFSET_EXT, 0,\n>  \t\tEGL_DMA_BUF_PLANE0_PITCH_EXT, (EGLint)eglImage.stride_,\n> @@ -135,7 +139,7 @@ int eGL::createDMABufTexture2D(eGLImage &eglImage, int fd, bool output)\n>  \t\t\t\t\t    NULL, image_attrs);\n>  \n>  \tif (eglImage.image_ == EGL_NO_IMAGE_KHR) {\n> -\t\tLOG(eGL, Error) << \"eglCreateImageKHR fail\";\n> +\t\tLOG(eGL, Debug) << \"eglCreateImageKHR fail\";\n>  \t\tret = -ENODEV;\n>  \t\tgoto done;\n>  \t}\n> @@ -176,6 +180,9 @@ done:\n>   * \\brief Create an input DMA-BUF backed texture\n>   * \\param[in,out] eglImage EGL image to associate with the DMA-BUF\n>   * \\param[in] fd DMA-BUF file descriptor\n> + * \\param[in] format the GL format\n> + * \\param[in] width the buffer width\n> + * \\param[in] height the buffer height\n>   *\n>   * Creates an EGL image from a DMA-BUF file descriptor and binds it to\n>   * a 2D texture for use as an input texture in shaders. The texture is\n> @@ -183,11 +190,25 @@ done:\n>   *\n>   * \\return 0 on success, or -ENODEV on failure\n>   */\n> -int eGL::createInputDMABufTexture2D(eGLImage &eglImage, int fd)\n> +int eGL::createInputDMABufTexture2D(eGLImage &eglImage, int fd, GLint format, uint32_t width, uint32_t height)\n>  {\n> +\tEGLint drm_format;\n> +\n>  \tASSERT(tid_ == Thread::currentId());\n>  \n> -\treturn createDMABufTexture2D(eglImage, fd, false);\n> +\tswitch (format) {\n> +\tcase GL_LUMINANCE:\n> +\t\tdrm_format = DRM_FORMAT_R8;\n> +\t\tbreak;\n> +\tcase GL_RG:\n> +\t\tdrm_format = DRM_FORMAT_RG88;\n> +\t\tbreak;\n> +\tdefault:\n> +\t\tLOG(eGL, Error) << \"unhandled GL format\";\n> +\t\treturn -ENODEV;\n> +\t}\n> +\n> +\treturn createDMABufTexture2D(eglImage, fd, drm_format, width, height, false);\n>  }\n>  \n>  /**\n> @@ -206,7 +227,7 @@ int eGL::createOutputDMABufTexture2D(eGLImage &eglImage, int fd)\n>  {\n>  \tASSERT(tid_ == Thread::currentId());\n>  \n> -\treturn createDMABufTexture2D(eglImage, fd, true);\n> +\treturn createDMABufTexture2D(eglImage, fd, DRM_FORMAT_ARGB8888, eglImage.width_, eglImage.height_, true);\n>  }\n>  \n>  /**\n> diff --git a/src/libcamera/software_isp/debayer_egl.cpp b/src/libcamera/software_isp/debayer_egl.cpp\n> index 9693d7252..e6387c851 100644\n> --- a/src/libcamera/software_isp/debayer_egl.cpp\n> +++ b/src/libcamera/software_isp/debayer_egl.cpp\n> @@ -509,13 +509,22 @@ void DebayerEGL::setShaderVariableValues(DebayerParams &params)\n>  \treturn;\n>  }\n>  \n> -int DebayerEGL::debayerGPU(MappedFrameBuffer &in, int out_fd, DebayerParams &params)\n> +int DebayerEGL::debayerGPU(FrameBuffer *input, int out_fd, DebayerParams &params)\n>  {\n>  \t/* eGL context switch */\n>  \tegl_.makeCurrent();\n>  \n>  \t/* Create a standard texture input */\n> -\tegl_.createTexture2D(*eglImageBayerIn_, glFormat_, inputConfig_.stride / bytesPerPixel_, height_, in.planes()[0].data());\n> +\tif (egl_.createInputDMABufTexture2D(*eglImageBayerIn_, input->planes()[0].fd.get(), glFormat_, inputConfig_.stride / bytesPerPixel_, height_) != 0) {\n> +\t\tMappedFrameBuffer in(input, MappedFrameBuffer::MapFlag::Read);\n> +\t\tif (!in.isValid()) {\n> +\t\t\tLOG(Debayer, Error) << \"mmap-ing buffer(s) failed\";\n> +\t\t\treturn -ENODEV;\n> +\t\t}\n> +\n> +\t\tLOG(Debayer, Debug) << \"Importing input buffer with DMABuf import failed, falling back to upload\";\n> +\t\tegl_.createTexture2D(*eglImageBayerIn_, glFormat_, inputConfig_.stride / bytesPerPixel_, height_, in.planes()[0].data());\n> +\t}\n>  \n>  \t/* Generate the output render framebuffer as render to texture */\n>  \tegl_.createOutputDMABufTexture2D(*eglImageBayerOut_, out_fd);\n> @@ -552,13 +561,7 @@ void DebayerEGL::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output\n>  \tmetadata.sequence = input->metadata().sequence;\n>  \tmetadata.timestamp = input->metadata().timestamp;\n>  \n> -\tMappedFrameBuffer in(input, MappedFrameBuffer::MapFlag::Read);\n> -\tif (!in.isValid()) {\n> -\t\tLOG(Debayer, Error) << \"mmap-ing buffer(s) failed\";\n> -\t\tgoto error;\n> -\t}\n> -\n> -\tif (debayerGPU(in, output->planes()[0].fd.get(), params)) {\n> +\tif (debayerGPU(input, output->planes()[0].fd.get(), params)) {\n>  \t\tLOG(Debayer, Error) << \"debayerGPU failed\";\n>  \t\tgoto error;\n>  \t}\n> diff --git a/src/libcamera/software_isp/debayer_egl.h b/src/libcamera/software_isp/debayer_egl.h\n> index a5033bc63..4b2cf448f 100644\n> --- a/src/libcamera/software_isp/debayer_egl.h\n> +++ b/src/libcamera/software_isp/debayer_egl.h\n> @@ -74,7 +74,7 @@ private:\n>  \tint getShaderVariableLocations();\n>  \tvoid setShaderVariableValues(DebayerParams &params);\n>  \tvoid configureTexture(GLuint &texture);\n> -\tint debayerGPU(MappedFrameBuffer &in, int out_fd, DebayerParams &params);\n> +\tint debayerGPU(FrameBuffer *input, int out_fd, DebayerParams &params);\n>  \n>  \t/* Shader program identifiers */\n>  \tGLuint vertexShaderId_ = 0;","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 9E422BDE6B\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 11 Feb 2026 15:53:28 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id E08B5621B9;\n\tWed, 11 Feb 2026 16:53:27 +0100 (CET)","from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com\n\t[205.220.168.131])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id C1E2A620C9\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 11 Feb 2026 16:53:25 +0100 (CET)","from pps.filterd (m0279867.ppops.net [127.0.0.1])\n\tby mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id\n\t61BEVJmE1507319 for <libcamera-devel@lists.libcamera.org>;\n\tWed, 11 Feb 2026 15:53:24 GMT","from mail-qk1-f197.google.com (mail-qk1-f197.google.com\n\t[209.85.222.197])\n\tby mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4c8ukt09p2-1\n\t(version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT)\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 11 Feb 2026 15:53:23 +0000 (GMT)","by mail-qk1-f197.google.com with SMTP id\n\taf79cd13be357-8c881d0c617so1528241585a.1\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 11 Feb 2026 07:53:23 -0800 (PST)","from ?IPV6:2001:1c00:c32:7800:5bfa:a036:83f0:f9ec?\n\t(2001-1c00-0c32-7800-5bfa-a036-83f0-f9ec.cable.dynamic.v6.ziggo.nl.\n\t[2001:1c00:c32:7800:5bfa:a036:83f0:f9ec])\n\tby smtp.gmail.com with ESMTPSA id\n\ta640c23a62f3a-b8f6ebd9859sm75256466b.38.2026.02.11.07.53.20\n\t(version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128);\n\tWed, 11 Feb 2026 07:53:21 -0800 (PST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (2048-bit key;\n\tunprotected) header.d=qualcomm.com header.i=@qualcomm.com\n\theader.b=\"XcBg3Ong\"; dkim=pass (2048-bit key;\n\tunprotected) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com\n\theader.b=\"KsTfKq8j\"; dkim-atps=neutral","DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h=\n\tcontent-type:date:from:in-reply-to:message-id:mime-version\n\t:references:subject:to; s=qcppdkim1; bh=/O02aJkOaJGr4kZ/DMG7nHZc\n\tv1dmukpXUnpDr+Vvd6M=; b=XcBg3OngHMrif8jZEnwhTvs6btSD+nOixySK/UcR\n\tLL5+2wT9V0qy36hDgzSk2HUWoj1DxeO+cdmKpCANgOK1TjRB+jValcG373jDkgua\n\tWFRxGKQWQ2rngoXmOCGhPE9qmYiylVPyZJnxiKGg071bazCaK/EixsP55kPX2I7Y\n\tLCjnzXC673I8S1Q+YuYOi0zkkLlNjLgAC6/R9m47kkkGGRXdeTk56lsoHmTAPYJv\n\tJhJHPc53sbJmazenZizWrEH3AMHk+aXmwGKZxQsaTO98eCkrdNpH3E3XXgTYo7PD\n\tfAtX76tm+pH9ZPjYv9WECb82xjEzlQCa2Jrp/5K1jq1tlQ==","v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=oss.qualcomm.com; s=google; t=1770825203; x=1771430003;\n\tdarn=lists.libcamera.org; \n\th=in-reply-to:content-language:from:references:to:subject:user-agent\n\t:mime-version:date:message-id:from:to:cc:subject:date:message-id\n\t:reply-to; bh=/O02aJkOaJGr4kZ/DMG7nHZcv1dmukpXUnpDr+Vvd6M=;\n\tb=KsTfKq8joPbOUBiImzOl1cJqsnLmAeoTmSEEa2xp3611fwIemKeopsrqwzWgn0KG6e\n\t9xjzeQXxg+x6Hkm6O9ahg8hpxwO2BBNhSsUS4fGuRftozdyTNdiNc5duM13GTC3cx6Xb\n\thMyjAlb1Os0EzzNTBymBHUWcL08XqS2Pxm8Txf2nf2RJqU13iB3QbY1DvzfH8zBnQm1Z\n\tnGcfJfHpRATw/xDK5KmC76BRNXlAN7oAxSW8n1oDxIrY+q+4BAr4UHLSlVucFFI2MjoG\n\tkzs3uQdrlkU26PqgxjqZJPxCRyA4YMHhqLlyzvtwP2L5jEX3aQDca4uHVgMTmsyCqnGD\n\tFnCw=="],"X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20230601; t=1770825203; x=1771430003;\n\th=in-reply-to:content-language:from:references:to:subject:user-agent\n\t:mime-version:date:message-id:x-gm-gg:x-gm-message-state:from:to:cc\n\t:subject:date:message-id:reply-to;\n\tbh=/O02aJkOaJGr4kZ/DMG7nHZcv1dmukpXUnpDr+Vvd6M=;\n\tb=Hg+EWDdjF2E3I3Wrf/WrGzMLjBT7Qyr6F+HKFgFomatlnpVeBFEPeWhDxoapNCYv85\n\tix3HgXXcGAgE/s7puUizHmMF9saAVF9Vpy/wejkKvZhoX+ZcEcsvL0iXHz+XcR/0D6HM\n\t9jO/g/B0mgWT7HHBpwEtDugKvSS9pJte9aO0woOUPr9yPMw92/+cj+5wH6TSsnhMX9FX\n\t0OYFUYuSNq+UC4QWcSEsVUuZb/agFTdhRX0O5CybZiQdC6sdxFdK0yIh9k4ts6jmra0d\n\tbjmUSAKVgVHKphvyxxlG7z5zDwLb6E5R81tJKbFmkk/6FWSxjavRFGyC8XSFGaswakc4\n\teJng==","X-Forwarded-Encrypted":"i=1;\n\tAJvYcCWCltCmJEwnmaulJ3srkgAeqmtY27qahsSx9YYX2J24qjVU86+HOs9HhoLbDNgwc8NO9TXS8dzneXFM7HAAGaw=@lists.libcamera.org","X-Gm-Message-State":"AOJu0Yzb9uE7eGJ0YB0FRrLTctuLmL4zog9VOs/CFHbWw66hV93OWzNb\n\txeLY5vTmR7BL8JTgoUNpNX/ihJboUloPuA7PfBoqbwkQztl8blrToimz15bt3Fq+Ug7dh6nAj0x\n\trmhCcsZ/i6R0kf+HpSzGF8tCP/p+7tt4CACXmSj9koo9QpNYbegzqxlbV5TlvzJ1MQPJYWSKdv2\n\tRL","X-Gm-Gg":"AZuq6aI4xRUoAGMm20DjfLEO4vUh3aXAxy/hE+F0Ighw3uezgtDGvCB/TxE8cdF3SYt\n\t23Q6a/FhdgqJ0Iw4by3Zc7inELnliaX/3H1Vf3KGfqKf8AV6Mmu5V88kasKCxqxlnPM0SoVBgth\n\tt+jjEV/Qtjm1hBuxISi8uNN9zZ0MBB+fSrAsumEBEceqEa7l4vez7P9rtDqdwp1GbsNbDZTfbXO\n\t0X8i5WacAEMiUHetHI6gZ+lFhM2VhVOoUxBXnrHKowPkzSBigKVdIoVs7pEYFoV+i7FTh5thbDN\n\tjgWLEm7628GtjZHhBa5h2ra+JCYhWMSIDNuV5kVavM/ZEiRTZkBydVaNJAjm9ckNzTov3UoD7Hv\n\t3lM2kH1tx6VJdHSxRMcVfueGt96h3R3fRUpeFeIAZ0iEkN7IK7jwnG/1AFsrU9LR7A519iY6SGV\n\t61+ElACCJPJ8qDJB0v8DeYmae+MA8W0lAG3TNt6soT6VDMgBEGvsA7B/0XbCkiQ9eEJWCMsi33X\n\tf7N6pOh60ujmj/n","X-Received":["by 2002:a05:620a:7118:b0:883:c768:200a with SMTP id\n\taf79cd13be357-8cb27fb474cmr433542085a.32.1770825202801; \n\tWed, 11 Feb 2026 07:53:22 -0800 (PST)","by 2002:a05:620a:7118:b0:883:c768:200a with SMTP id\n\taf79cd13be357-8cb27fb474cmr433536285a.32.1770825202095; \n\tWed, 11 Feb 2026 07:53:22 -0800 (PST)"],"Content-Type":"multipart/mixed;\n\tboundary=\"------------j1ByiwP00W4i2cRlV3k5y0Fo\"","Message-ID":"<812002d2-71e2-4dc7-96b5-0ca9b9dcdfcd@oss.qualcomm.com>","Date":"Wed, 11 Feb 2026 16:53:20 +0100","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH] RFC: egl: Implement DMABuf import for input buffers","To":"Robert Mader <robert.mader@collabora.com>,\n\tlibcamera-devel@lists.libcamera.org","References":"<20260110210930.123920-1-robert.mader@collabora.com>","From":"Hans de Goede <johannes.goede@oss.qualcomm.com>","Content-Language":"en-US, nl","In-Reply-To":"<20260110210930.123920-1-robert.mader@collabora.com>","X-Proofpoint-Spam-Details-Enc":"AW1haW4tMjYwMjExMDEyMiBTYWx0ZWRfX7zelXL8i6jMW\n\tZn85/NxlmWjIndvDpkzyzYXfNogAnfJhoPHm9qq7CZQwjKRI3kc7D3ZJYXxqEYLHWu8Ppaxj+6e\n\tJfAEFrkeYw4eKp+yZM3sAmnX27AV3fupA514MRWRBXFsczCk/sVPIzLVXLDNJShqgwg00Yfqjv+\n\th3+3rWAQ90mjDD9vjQvVxFjrorCd/CQajXObNkGg+gwoqdfE5cxK2z9HRAf9ybRSju5mLTyOA99\n\tYsNXaZy/2Tnk4BlAmW7XsOoZg3YRl227nAq5H/7bEhp2yiO3ZNaBXgug5/OU5smRqjEo8FgIGEy\n\tg/YFishPvZ6MScrDyBdjXSpInN+WaDv+175D7jRPaLHF32GTPCwLhJCBr/PVIcAyami38rKpoJJ\n\twYBZSLgXUJm4Ziu/ARZbLi7XUbXYRvxhM85Ke5b59lU9BTynZOVJ8bcSbDWXFKkD/H6EIpZtpUP\n\tBFtjlaw7ARvRkYZd32A==","X-Proofpoint-ORIG-GUID":"NntuCi2ULjBjGeXdM4gZMFNkbaggvCUc","X-Authority-Analysis":"v=2.4 cv=INIPywvG c=1 sm=1 tr=0 ts=698ca5f3 cx=c_pps\n\ta=50t2pK5VMbmlHzFWWp8p/g==:117 a=xqWC_Br6kY4A:10 a=HzLeVaNsDn8A:10\n\ta=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=Mpw57Om8IfrbqaoTuvik:22\n\ta=GgsMoib0sEa3-_RKJdDe:22 a=r77TgQKjGQsHNAKrUKIA:9 a=YAyIRdgMAAAA:8\n\ta=QX4gbG5DAAAA:8 a=EUspDBNiAAAA:8 a=20KFwNOVAAAA:8\n\ta=AvsCf4B-4CM3FxZuHX8A:9\n\ta=QEXdDO2ut3YA:10 a=_25ADOayARXy1AnpjksA:9 a=B2y7HmGcmWMA:10\n\ta=IoWCM6iH3mJn3m4BftBB:22 a=o1rO4XtwZBNj6n05oSJ_:22\n\ta=AbAUZ8qAyYyZVLSsDulk:22","X-Proofpoint-GUID":"NntuCi2ULjBjGeXdM4gZMFNkbaggvCUc","X-Proofpoint-Virus-Version":"vendor=baseguard\n\tengine=ICAP:2.0.293, Aquarius:18.0.1121, Hydra:6.1.51,\n\tFMLib:17.12.100.49\n\tdefinitions=2026-02-11_02,2026-02-11_04,2025-10-01_01","X-Proofpoint-Spam-Details":"rule=outbound_notspam policy=outbound score=0\n\tclxscore=1015 impostorscore=0 adultscore=0 priorityscore=1501\n\tspamscore=0\n\tsuspectscore=0 bulkscore=0 lowpriorityscore=0 phishscore=0\n\tmalwarescore=0\n\tclassifier=typeunknown authscore=0 authtc= authcc= route=outbound\n\tadjust=0\n\treason=mlx scancount=1 engine=8.22.0-2601150000\n\tdefinitions=main-2602110122","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]