Patch Detail
Show a patch.
GET /api/patches/26784/?format=api
{ "id": 26784, "url": "https://patchwork.libcamera.org/api/patches/26784/?format=api", "web_url": "https://patchwork.libcamera.org/patch/26784/", "project": { "id": 1, "url": "https://patchwork.libcamera.org/api/projects/1/?format=api", "name": "libcamera", "link_name": "libcamera", "list_id": "libcamera_core", "list_email": "libcamera-devel@lists.libcamera.org", "web_url": "", "scm_url": "", "webscm_url": "" }, "msgid": "<20260519193907.86812-4-robert.mader@collabora.com>", "date": "2026-05-19T19:39:05", "name": "[v3,3/5] debayer_egl: Implement dmabuf import for input buffers", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": false, "hash": "ece33fbdf2dbc9d846c48ba9e00f18d0541db752", "submitter": { "id": 140, "url": "https://patchwork.libcamera.org/api/people/140/?format=api", "name": "Robert Mader", "email": "robert.mader@collabora.com" }, "delegate": null, "mbox": "https://patchwork.libcamera.org/patch/26784/mbox/", "series": [ { "id": 5957, "url": "https://patchwork.libcamera.org/api/series/5957/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=5957", "date": "2026-05-19T19:39:02", "name": "software_isp: Implement DMABuf import for input buffers", "version": 3, "mbox": "https://patchwork.libcamera.org/series/5957/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/26784/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/26784/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 CAFB6C32F4\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 19 May 2026 19:39:46 +0000 (UTC)", "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id DE5516302C;\n\tTue, 19 May 2026 21:39:45 +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 8B79263035\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 19 May 2026 21:39:41 +0200 (CEST)", "by mx.zohomail.com with SMTPS id 1779219575945619.5835395482512;\n\tTue, 19 May 2026 12:39:35 -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=\"iP7CLjez\"; \n\tdkim-atps=neutral", "ARC-Seal": "i=1; a=rsa-sha256; t=1779219576; cv=none; \n\td=zohomail.com; s=zohoarc; \n\tb=NwzCObXTwmRbLpNkFAGVOP1RsOIjAz+sKDLo3VsOwEZ/EFRXb73Kyee/Pu3jKeCOcfNafoLaCvC8Q+OqraWM7gUOcJCOuSlr7jjVkoQTf4qa3fxg/Cmkn37MbhPqR2Xi4HuBWzBjRpltYzdD3hyoCo+nrD2QLo7ayhC0vZvVtSg=", "ARC-Message-Signature": "i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; \n\ts=zohoarc; t=1779219576;\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=2US6PQNWHOHw1P5M7cN6ib8CWzcdBXpsSJ5Gg/SjQXI=; \n\tb=NcI6+/iR3/tuyNUnIuwzrjI+QW8dpdRC1Sx7/CHQWhvLc25y4YkHhKlMyMROvtcPWIzfnNX4FUllTJUQg28eXPY6/GAwErN/n8aIfWMrvROt6nsjaFHoY0UES94LcuvzzaV8uJP3JEicSOjkoT1n46kTi/KNtov7Rz+BnMJMFgU=", "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=1779219576;\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=2US6PQNWHOHw1P5M7cN6ib8CWzcdBXpsSJ5Gg/SjQXI=;\n\tb=iP7CLjezpTU2DibLL1tassqpVL6TbD+OUCGs1MjC2/pw9BODbLbFy7eP64At8qw0\n\tAzLPwTdU7lIlI/Afv5X0lqyJacUEq0Ic16jhN035kTc7SqCNqO3ZREK72cyXJ1PpMfh\n\tmD4Y3meq+iQrBn6fOUfwBKGy+0eVZIm3PYn99PvQ=", "From": "Robert Mader <robert.mader@collabora.com>", "To": "libcamera-devel@lists.libcamera.org", "Cc": "Robert Mader <robert.mader@collabora.com>", "Subject": "[PATCH v3 3/5] debayer_egl: Implement dmabuf import for input\n\tbuffers", "Date": "Tue, 19 May 2026 21:39:05 +0200", "Message-ID": "<20260519193907.86812-4-robert.mader@collabora.com>", "X-Mailer": "git-send-email 2.54.0", "In-Reply-To": "<20260519193907.86812-1-robert.mader@collabora.com>", "References": "<20260519193907.86812-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 | 40 ++++++++++++++--------\n src/libcamera/software_isp/debayer_egl.h | 4 ++-\n 2 files changed, 28 insertions(+), 16 deletions(-)", "diff": "diff --git a/src/libcamera/software_isp/debayer_egl.cpp b/src/libcamera/software_isp/debayer_egl.cpp\nindex a217e3798..750895d10 100644\n--- a/src/libcamera/software_isp/debayer_egl.cpp\n+++ b/src/libcamera/software_isp/debayer_egl.cpp\n@@ -500,16 +500,32 @@ void DebayerEGL::setShaderVariableValues(const DebayerParams ¶ms)\n \treturn;\n }\n \n-int DebayerEGL::debayerGPU(MappedFrameBuffer &in, int out_fd, const DebayerParams ¶ms)\n+int DebayerEGL::debayerGPU(FrameBuffer *input, std::optional<DmaSyncer> *inputBufferDmaSyncer, FrameBuffer *output, const DebayerParams ¶ms)\n {\n \t/* eGL context switch */\n \tegl_.makeCurrent();\n \n-\t/* Create a standard texture input */\n-\tegl_.createTexture2D(*eglImageBayerIn_, in.planes()[0].data());\n+\t/* Try to create texture for input buffer via dmabuf import */\n+\tif (!dmabuf_import_failed_) {\n+\t\tif (egl_.createInputDMABufTexture2D(*eglImageBayerIn_, input->planes()[0].fd.get()) != 0) {\n+\t\t\tLOG(Debayer, Info) << \"Importing input buffer with DMABuf import failed, falling back to upload\";\n+\t\t\tdmabuf_import_failed_ = true;\n+\t\t}\n+\t}\n+\n+\t/* Otherwise create texture for input buffer via upload from CPU */\n+\tif (dmabuf_import_failed_) {\n+\t\tinputBufferDmaSyncer->emplace(input->planes()[0].fd, DmaSyncer::SyncType::Read);\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_, 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@@ -531,23 +547,15 @@ void DebayerEGL::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output\n {\n \tbench_.startFrame();\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+\tstd::optional<DmaSyncer> inputBufferDmaSyncer;\n \n-\tif (debayerGPU(in, output->planes()[0].fd.get(), params)) {\n+\tif (debayerGPU(input, &inputBufferDmaSyncer, output, params)) {\n \t\tLOG(Debayer, Error) << \"debayerGPU failed\";\n \t\tgoto error;\n \t}\n@@ -557,8 +565,10 @@ 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 (!inputBufferDmaSyncer && (frame % SwStatsCpu::kStatPerNumFrames) == 0)\n+\t\tinputBufferDmaSyncer.emplace(input->planes()[0].fd, DmaSyncer::SyncType::Read);\n \tstats_->processFrame(frame, 0, input);\n-\tdmaSyncers.clear();\n+\tinputBufferDmaSyncer.reset();\n \n \toutputBufferReady.emit(output);\n \tinputBufferReady.emit(input);\ndiff --git a/src/libcamera/software_isp/debayer_egl.h b/src/libcamera/software_isp/debayer_egl.h\nindex 141fb288f..fd8c577d3 100644\n--- a/src/libcamera/software_isp/debayer_egl.h\n+++ b/src/libcamera/software_isp/debayer_egl.h\n@@ -65,7 +65,7 @@ private:\n \tint initBayerShaders(PixelFormat inputFormat, PixelFormat outputFormat);\n \tint getShaderVariableLocations();\n \tvoid setShaderVariableValues(const DebayerParams ¶ms);\n-\tint debayerGPU(MappedFrameBuffer &in, int out_fd, const DebayerParams ¶ms);\n+\tint debayerGPU(FrameBuffer *input, std::optional<DmaSyncer> *inputBufferDmaSyncer, FrameBuffer *output, const DebayerParams ¶ms);\n \n \t/* Shader program identifiers */\n \tGLuint vertexShaderId_ = 0;\n@@ -109,6 +109,8 @@ private:\n \tGLint glFormat_;\n \tunsigned int bytesPerPixel_;\n \tuint32_t shaderStridePixels_;\n+\n+\tbool dmabuf_import_failed_;\n };\n \n } /* namespace libcamera */\n", "prefixes": [ "v3", "3/5" ] }