{"id":26599,"url":"https://patchwork.libcamera.org/api/patches/26599/?format=json","web_url":"https://patchwork.libcamera.org/patch/26599/","project":{"id":1,"url":"https://patchwork.libcamera.org/api/projects/1/?format=json","name":"libcamera","link_name":"libcamera","list_id":"libcamera_core","list_email":"libcamera-devel@lists.libcamera.org","web_url":"","scm_url":"","webscm_url":""},"msgid":"<20260503114002.139255-3-robert.mader@collabora.com>","date":"2026-05-03T11:40:01","name":"[2/3] debayer_egl: Implement dmabuf import for input buffers","commit_ref":null,"pull_url":null,"state":"superseded","archived":false,"hash":"294ab9bb7f870292741c37a47a36b932103d3f4e","submitter":{"id":140,"url":"https://patchwork.libcamera.org/api/people/140/?format=json","name":"Robert Mader","email":"robert.mader@collabora.com"},"delegate":null,"mbox":"https://patchwork.libcamera.org/patch/26599/mbox/","series":[{"id":5898,"url":"https://patchwork.libcamera.org/api/series/5898/?format=json","web_url":"https://patchwork.libcamera.org/project/libcamera/list/?series=5898","date":"2026-05-03T11:39:59","name":"software_isp: Implement DMABuf import for input buffers","version":1,"mbox":"https://patchwork.libcamera.org/series/5898/mbox/"}],"comments":"https://patchwork.libcamera.org/api/patches/26599/comments/","check":"pending","checks":"https://patchwork.libcamera.org/api/patches/26599/checks/","tags":{},"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 39A74BE173\n\tfor <parsemail@patchwork.libcamera.org>;\n\tSun,  3 May 2026 11:40:50 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id E36BF62FD3;\n\tSun,  3 May 2026 13:40:49 +0200 (CEST)","from sender4-pp-f112.zoho.com (sender4-pp-f112.zoho.com\n\t[136.143.188.112])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 9CC0962FEA\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSun,  3 May 2026 13:40:46 +0200 (CEST)","by mx.zohomail.com with SMTPS id 1777808440328651.2845930465663;\n\tSun, 3 May 2026 04:40:40 -0700 (PDT)"],"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=\"ec0w3PpG\"; \n\tdkim-atps=neutral","ARC-Seal":"i=1; a=rsa-sha256; t=1777808442; cv=none; \n\td=zohomail.com; s=zohoarc; \n\tb=bDj10qVCTkDdj8JA78yKiyCW7ce+jDGgJqNEUFOxxD5Ge3/UPUVD/Qcoc2vNTwuk9K4mHEvP43uPn21FK1U+mDT30ieqsEOFhDKxbfLAanwyOGMYC866PGDBHj4y012tHttBPfZhq26TRdBt7uOGpvsJuP6absvNCss+vGeYq/M=","ARC-Message-Signature":"i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; \n\ts=zohoarc; t=1777808442;\n\th=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:MIME-Version:Message-ID:References:Subject:Subject:To:To:Message-Id:Reply-To;\n\tbh=i65c0BUiXvt7qykXzHQOd9vKcclacvakhvD8tLa6N/8=; \n\tb=C7iU9Qzw+ejEDCrJvvmVh892T6VvnOQKJej1c/midBOXO8kXwksqZ0QCaESTzgWZwmGmkecFwbe8oG5oCjOADNPMnjnqP7VtInaq58DhXAogRGkadJbjPj/ZGfqIuEjGI51cGthw87K+zw2eb4tu5CC4VB1osn3PfPPO8SOiWm4=","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=1777808442;\n\ts=zohomail; d=collabora.com; i=robert.mader@collabora.com;\n\th=From:From:To:To:Cc:Cc:Subject:Subject:Date:Date:Message-ID:In-Reply-To:References:MIME-Version:Content-Transfer-Encoding:Message-Id:Reply-To;\n\tbh=i65c0BUiXvt7qykXzHQOd9vKcclacvakhvD8tLa6N/8=;\n\tb=ec0w3PpGlbRglsup8i1bqKiLVfKg1O4DhvVDRnwa4X2JIShOUuhWqM9MAFTOSqzI\n\tTUmt7W0alTLKciL9RWrdcyXqUeZgTWfABmhYJmpBYbk1TbYeTP7QbLeA+L9kAmYz4Aj\n\trIJg7H8WIvck01o7OI6ladFwQY6fJfAojHlh+Euw=","From":"Robert Mader <robert.mader@collabora.com>","To":"libcamera-devel@lists.libcamera.org","Cc":"Robert Mader <robert.mader@collabora.com>","Subject":"[PATCH 2/3] debayer_egl: Implement dmabuf import for input buffers","Date":"Sun,  3 May 2026 13:40:01 +0200","Message-ID":"<20260503114002.139255-3-robert.mader@collabora.com>","X-Mailer":"git-send-email 2.54.0","In-Reply-To":"<20260503114002.139255-1-robert.mader@collabora.com>","References":"<20260503114002.139255-1-robert.mader@collabora.com>","MIME-Version":"1.0","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>"},"content":"In many cases we can import the GPU-ISP input buffers, dmabufs from v4l2,\ndirectly into EGL instead of mapping and uploading - i.e. copying - them.\n\nDoing so can have positive effects in multiple areas, including reducing\nmemory bandwidth and CPU usage, as well as avoiding expensive dmabuf syncs\nand syscalls.\n\nThe main reason direct imports may not work are the more demanding stride\nalignment requirements many GPUs have - often 128 or 256 bytes - compared\nto ISPs - apparently often closer to 32 bytes.\n\nThus we first try to import buffers directly and - if that fails - fall back\nto the previous upload path. Failing imports should come at low cost as\ndrivers know the limitations and can bail out early, without causing\nadditional IO or context switches.\n\nIn the future we might be able to request buffers with a matching stride\nfrom v4l2 drivers in many cases, making direct import the norm instead\nof a hit-or-miss. An optional kernel API for that exists, but doesn't\nseem to be implemented by any driver tested so far.\n\nWhile on it, add some minor code adjustments to make it easier to\nfollow.\n\nSigned-off-by: Robert Mader <robert.mader@collabora.com>\n---\n src/libcamera/software_isp/debayer_egl.cpp | 28 ++++++++++++----------\n src/libcamera/software_isp/debayer_egl.h   |  2 +-\n 2 files changed, 17 insertions(+), 13 deletions(-)","diff":"diff --git a/src/libcamera/software_isp/debayer_egl.cpp b/src/libcamera/software_isp/debayer_egl.cpp\nindex 8f0c229fd..624469947 100644\n--- a/src/libcamera/software_isp/debayer_egl.cpp\n+++ b/src/libcamera/software_isp/debayer_egl.cpp\n@@ -495,16 +495,26 @@ void DebayerEGL::setShaderVariableValues(const DebayerParams &params)\n \treturn;\n }\n \n-int DebayerEGL::debayerGPU(MappedFrameBuffer &in, int out_fd, const DebayerParams &params)\n+int DebayerEGL::debayerGPU(FrameBuffer *input, FrameBuffer *output, std::vector<DmaSyncer> &dmaSyncers, const 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_, glFormat_, inputConfig_.stride / bytesPerPixel_, height_, input->planes()[0].fd.get()) != 0) {\n+\t\tLOG(Debayer, Debug) << \"Importing input buffer with DMABuf import failed, falling back to upload\";\n+\n+\t\tdmaSyncBegin(dmaSyncers, input, nullptr);\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+\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+\tegl_.createOutputDMABufTexture2D(*eglImageBayerOut_, output->planes()[0].fd.get());\n \n \tsetShaderVariableValues(params);\n \tglViewport(0, 0, width_, height_);\n@@ -528,21 +538,13 @@ void DebayerEGL::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output\n \n \tstd::vector<DmaSyncer> dmaSyncers;\n \n-\tdmaSyncBegin(dmaSyncers, input, nullptr);\n-\n \t/* Copy metadata from the input buffer */\n \tFrameMetadata &metadata = output->_d()->metadata();\n \tmetadata.status = input->metadata().status;\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, dmaSyncers, params)) {\n \t\tLOG(Debayer, Error) << \"debayerGPU failed\";\n \t\tgoto error;\n \t}\n@@ -552,6 +554,8 @@ void DebayerEGL::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output\n \tmetadata.planes()[0].bytesused = output->planes()[0].length;\n \n \t/* Calculate stats for the whole frame */\n+\tif (dmaSyncers.empty() && (frame % SwStatsCpu::kStatPerNumFrames) == 0)\n+\t    dmaSyncBegin(dmaSyncers, input, nullptr);\n \tstats_->processFrame(frame, 0, input);\n \tdmaSyncers.clear();\n \ndiff --git a/src/libcamera/software_isp/debayer_egl.h b/src/libcamera/software_isp/debayer_egl.h\nindex fcd281f4c..62cb4f7f1 100644\n--- a/src/libcamera/software_isp/debayer_egl.h\n+++ b/src/libcamera/software_isp/debayer_egl.h\n@@ -66,7 +66,7 @@ private:\n \tint initBayerShaders(PixelFormat inputFormat, PixelFormat outputFormat);\n \tint getShaderVariableLocations();\n \tvoid setShaderVariableValues(const DebayerParams &params);\n-\tint debayerGPU(MappedFrameBuffer &in, int out_fd, const DebayerParams &params);\n+\tint debayerGPU(FrameBuffer *input, FrameBuffer *output, std::vector<DmaSyncer> &dmaSyncers, const DebayerParams &params);\n \n \t/* Shader program identifiers */\n \tGLuint vertexShaderId_ = 0;\n","prefixes":["2/3"]}