Show a patch.

GET /api/patches/26770/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 26770,
    "url": "https://patchwork.libcamera.org/api/patches/26770/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/26770/",
    "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": "<20260518201508.140849-4-robert.mader@collabora.com>",
    "date": "2026-05-18T20:15:07",
    "name": "[v2,3/4] debayer_egl: Implement dmabuf import for input buffers",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": false,
    "hash": "7a775956d781c3086da975c196f40ce82e1d1eb6",
    "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/26770/mbox/",
    "series": [
        {
            "id": 5953,
            "url": "https://patchwork.libcamera.org/api/series/5953/?format=api",
            "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=5953",
            "date": "2026-05-18T20:15:04",
            "name": "software_isp: Implement DMABuf import for input buffers",
            "version": 2,
            "mbox": "https://patchwork.libcamera.org/series/5953/mbox/"
        }
    ],
    "comments": "https://patchwork.libcamera.org/api/patches/26770/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/26770/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 E3CFCC32F4\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 18 May 2026 20:16:20 +0000 (UTC)",
            "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 1B04663030;\n\tMon, 18 May 2026 22:16:20 +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 66AAB62FEC\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 18 May 2026 22:16:17 +0200 (CEST)",
            "by mx.zohomail.com with SMTPS id 1779135373467224.49950436502218; \n\tMon, 18 May 2026 13:16:13 -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=\"PNFt2HX3\"; \n\tdkim-atps=neutral",
        "ARC-Seal": "i=1; a=rsa-sha256; t=1779135374; cv=none; \n\td=zohomail.com; s=zohoarc; \n\tb=BoI6IYUyGmA6C3yKidp4zEIpJ9mn6zjMSTeH3NJ9mQntgPbiRnmLJxU7xUIbkm2hkWAktkMZDgOaUptb/2bk/7Jm0k73vjdQRC58Io+Vo8wk9MdP7Ot7W+mUb32Qv440tqtYhuVsnATLcQZOlV/Iuj669lvy8HegfFR254zmzQk=",
        "ARC-Message-Signature": "i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; \n\ts=zohoarc; t=1779135374;\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=hTPfehAIGuGVuZradoz4Gns7kWlYb3dOc1wahtblfyQ=; \n\tb=btEmtU0AuB3fjHxrO+RdlpqN7+N4PI8Xh9jk167NkIjQDnHgimLk4HOkDB16K35DhRtsP+VbNwa13KOtqUSFY2TWN9VZZF3lFZjtBAnBkKP715MnaH9yOrRPJLPZn7WspPq8z3po0pTny14XsARPJm6vQXXUZQ2gd88483S7/w0=",
        "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=1779135374;\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=hTPfehAIGuGVuZradoz4Gns7kWlYb3dOc1wahtblfyQ=;\n\tb=PNFt2HX3I81vw2CZ6xAa+izmZ7EMbacpYhVl66gu9fDm08yGeYSQYlRSOVK5VSyv\n\tqNaI1SWd8vicAefXC5ElxNp+jx/Ry4wtZJakIrpTFHphAQ+MEH7QtqpeVOH/b/QWToo\n\tvpOnMmzKS+jyqg58pHWJn6XUEIFv7bV1iyyU0Ch8=",
        "From": "Robert Mader <robert.mader@collabora.com>",
        "To": "libcamera-devel@lists.libcamera.org",
        "Cc": "Robert Mader <robert.mader@collabora.com>",
        "Subject": "[PATCH v2 3/4] debayer_egl: Implement dmabuf import for input\n\tbuffers",
        "Date": "Mon, 18 May 2026 22:15:07 +0200",
        "Message-ID": "<20260518201508.140849-4-robert.mader@collabora.com>",
        "X-Mailer": "git-send-email 2.54.0",
        "In-Reply-To": "<20260518201508.140849-1-robert.mader@collabora.com>",
        "References": "<20260518201508.140849-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 | 32 ++++++++++++----------\n src/libcamera/software_isp/debayer_egl.h   |  2 +-\n 2 files changed, 19 insertions(+), 15 deletions(-)",
    "diff": "diff --git a/src/libcamera/software_isp/debayer_egl.cpp b/src/libcamera/software_isp/debayer_egl.cpp\nindex a217e3798..e5a661d2c 100644\n--- a/src/libcamera/software_isp/debayer_egl.cpp\n+++ b/src/libcamera/software_isp/debayer_egl.cpp\n@@ -500,16 +500,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, std::optional<DmaSyncer> *inputBufferDmaSyncer, FrameBuffer *output, const DebayerParams &params)\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+\tif (egl_.createInputDMABufTexture2D(*eglImageBayerIn_, 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\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 +541,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 +559,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..a98a8139a 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 &params);\n-\tint debayerGPU(MappedFrameBuffer &in, int out_fd, const DebayerParams &params);\n+\tint debayerGPU(FrameBuffer *input, std::optional<DmaSyncer> *inputBufferDmaSyncer, FrameBuffer *output, const DebayerParams &params);\n \n \t/* Shader program identifiers */\n \tGLuint vertexShaderId_ = 0;\n",
    "prefixes": [
        "v2",
        "3/4"
    ]
}