Patch Detail
Show a patch.
GET /api/patches/27067/?format=api
{ "id": 27067, "url": "https://patchwork.libcamera.org/api/patches/27067/?format=api", "web_url": "https://patchwork.libcamera.org/patch/27067/", "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": "<20260626-ipu3-libipa-rework-v2-7-41546e23de3e@ideasonboard.com>", "date": "2026-06-26T13:05:54", "name": "[v2,07/12] ipa: ipu3: ToneMapping: Convert to use GammaAlgorithm", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "6193bff0632c6901b3b68bb85929a613e35c7a94", "submitter": { "id": 156, "url": "https://patchwork.libcamera.org/api/people/156/?format=api", "name": "Dan Scally", "email": "dan.scally@ideasonboard.com" }, "delegate": null, "mbox": "https://patchwork.libcamera.org/patch/27067/mbox/", "series": [ { "id": 6022, "url": "https://patchwork.libcamera.org/api/series/6022/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=6022", "date": "2026-06-26T13:05:47", "name": "libipa: Re-work IPU3 IPA to use libipa algorithms", "version": 2, "mbox": "https://patchwork.libcamera.org/series/6022/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/27067/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/27067/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 2683FC3306\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 26 Jun 2026 13:06:22 +0000 (UTC)", "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id E9DD665F13;\n\tFri, 26 Jun 2026 15:06:15 +0200 (CEST)", "from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id BDEF765EE7\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 26 Jun 2026 15:06:06 +0200 (CEST)", "from [127.0.1.1]\n\t(chfd-03-b2-v4wan-176392-cust229.vm15.cable.virginm.net\n\t[82.19.20.230])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id C13AE1AE5;\n\tFri, 26 Jun 2026 15:05:25 +0200 (CEST)" ], "Authentication-Results": "lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"EMMo9yl2\"; dkim-atps=neutral", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1782479125;\n\tbh=MV1OudgVxwqKcw+PZWyvAFv5rAPA2Ey0KE5JXKGr7Os=;\n\th=From:Date:Subject:References:In-Reply-To:To:Cc:From;\n\tb=EMMo9yl2H4szF7oOGBEbJAWatIOJgI5OoNjD6ji9Tu2Ot1mgM24az32wbF6p9R8eH\n\toRV7ehQyROv7wZrT7velWu9ptDbSR9OlfBcVOQW66ObC541b9V+S9h3W7fMJZdKZ2O\n\tPO4g6q3GNPe64tFvm+tvopO8UEFOKL4PRFIdgR2Q=", "From": "Daniel Scally <dan.scally@ideasonboard.com>", "Date": "Fri, 26 Jun 2026 14:05:54 +0100", "Subject": "[PATCH v2 07/12] ipa: ipu3: ToneMapping: Convert to use\n\tGammaAlgorithm", "MIME-Version": "1.0", "Content-Type": "text/plain; charset=\"utf-8\"", "Content-Transfer-Encoding": "7bit", "Message-Id": "<20260626-ipu3-libipa-rework-v2-7-41546e23de3e@ideasonboard.com>", "References": "<20260626-ipu3-libipa-rework-v2-0-41546e23de3e@ideasonboard.com>", "In-Reply-To": "<20260626-ipu3-libipa-rework-v2-0-41546e23de3e@ideasonboard.com>", "To": "libcamera-devel@lists.libcamera.org", "Cc": "Daniel Scally <dan.scally@ideasonboard.com>, \n\tJacopo Mondi <jacopo.mondi@ideasonboard.com>, \n\tKieran Bingham <kieran.bingham@ideasonboard.com>", "X-Mailer": "b4 0.14.2", "X-Developer-Signature": "v=1; a=openpgp-sha256; l=8593;\n\ti=dan.scally@ideasonboard.com; h=from:subject:message-id;\n\tbh=MV1OudgVxwqKcw+PZWyvAFv5rAPA2Ey0KE5JXKGr7Os=;\n\tb=owEBbQKS/ZANAwAKAchJV3psRXUyAcsmYgBqPnk62xG6GoNzv874hDnaI3WUNoRnQZZpoPcc5\n\tX+d3o6QHAyJAjMEAAEKAB0WIQQqyuwyDnZdb+mxmm/ISVd6bEV1MgUCaj55OgAKCRDISVd6bEV1\n\tMkBqD/441lIw/ISxUkps4lFW9fNmRwQ8pOUvU0rMLoFVn10kpKlA9hQ3CZTqPRYGGyvQqQUxy9J\n\tKdbSLZQWkHpi023zK/rv09oNgW16r7KGDBBLOGUOaRErhRS1zRhlZhhZgDCodeJ+FVbcQ8m085W\n\tcQ/B+C1VRNUUK0ZBVSfWKRwgkTyk/sPFWPOY3syoA9Qq3dKZPsizrLRlF15pWB9e4RHl+/MWVhq\n\tacac8/zhcj+4+KOh4LVbte/8Ud0zsOW70lGSoAjoGBlkMSvC/T2Co4PCt1i2ZPnjDDvKdZ3Smpj\n\tpeugQaoPPKTHN+zLu/Pl85DHA0ShZyrJ10omHgTNvjEa2CJtx81gMkYKbfF2BNvF7MtFr0MpHJP\n\tnsAjdVvodALZMJ5ebctPFHQ42eIvOd4ILsFoQeGOXpfT+wINV0mk/Nd7Xa/tsZk6ADrYEi5rgFO\n\tttcqEbQGLI5EVl/QwlPZeuCpzgOioA24WYUz8jVK55fYeerxbvZnQVYrZE9T974hMKug6MzoDGA\n\t2CgTWcHQ8qu7iggg3eGlZbAUgXMZS5oWgJRFCC/Fx6Z4e2zNp/YybzDz50TjFW2rb0+v6qaOo/y\n\t092cY24IvD2bI6jDAN5wcJ9bxAvS6Qbh+dJsQMFlZlyNey5BCbhxHwwdjGosl5yyE+EKd+cdClk\n\tvuBEYB44BQKHzUA==", "X-Developer-Key": "i=dan.scally@ideasonboard.com; a=openpgp;\n\tfpr=EEC699ACA1B7CB5D31330C0BBD501C2A3546CCF6", "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": "Convert the IPU3 ToneMapping algorithm to use the new GammaAlgorithm\nbase class. This gives us configurable gamma via the tuning files and\nat runtime using the Gamma control.\n\nReviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>\nReviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\nSigned-off-by: Daniel Scally <dan.scally@ideasonboard.com>\n---\nChanges in v2:\n\n - Fixed includes\n\t- Minor styling changes\n---\n src/ipa/ipu3/algorithms/tone_mapping.cpp | 73 +++++++++++++++++---------------\n src/ipa/ipu3/algorithms/tone_mapping.h | 12 +++++-\n src/ipa/ipu3/ipa_context.cpp | 24 +++++------\n src/ipa/ipu3/ipa_context.h | 8 ++--\n 4 files changed, 63 insertions(+), 54 deletions(-)", "diff": "diff --git a/src/ipa/ipu3/algorithms/tone_mapping.cpp b/src/ipa/ipu3/algorithms/tone_mapping.cpp\nindex 160338c139448cc9a0bc1fe2400c335a96f68f73..ea17abff8167238dfc5d65f6bb64754e8a7834ef 100644\n--- a/src/ipa/ipu3/algorithms/tone_mapping.cpp\n+++ b/src/ipa/ipu3/algorithms/tone_mapping.cpp\n@@ -10,6 +10,8 @@\n #include <cmath>\n #include <string.h>\n \n+#include <libcamera/base/span.h>\n+\n /**\n * \\file tone_mapping.h\n */\n@@ -27,10 +29,17 @@ namespace ipa::ipu3::algorithms {\n */\n \n ToneMapping::ToneMapping()\n-\t: gamma_(1.0)\n {\n }\n \n+/**\n+ * \\copydoc libcamera::ipa::Algorithm::init\n+ */\n+int ToneMapping::init(IPAContext &context, const ValueNode &tuningData)\n+{\n+\treturn gammaAlgo_.init(context.ctrlMap, tuningData);\n+}\n+\n /**\n * \\brief Configure the tone mapping given a configInfo\n * \\param[in] context The shared IPA context\n@@ -41,12 +50,21 @@ ToneMapping::ToneMapping()\n int ToneMapping::configure(IPAContext &context,\n \t\t\t [[maybe_unused]] const IPAConfigInfo &configInfo)\n {\n-\t/* Initialise tone mapping gamma value. */\n-\tcontext.activeState.toneMapping.gamma = 0.0;\n-\n+\tgammaAlgo_.configure(context.activeState.gamma);\n \treturn 0;\n }\n \n+/**\n+ * \\copydoc libcamera::ipa::Algorithm::queueRequest\n+ */\n+void ToneMapping::queueRequest(IPAContext &context, const uint32_t frame,\n+\t\t\t IPAFrameContext &frameContext,\n+\t\t\t const ControlList &controls)\n+{\n+\tgammaAlgo_.queueRequest(context.activeState.gamma, frame,\n+\t\t\t\tframeContext.gamma, controls);\n+}\n+\n /**\n * \\brief Fill in the parameter structure, and enable gamma control\n * \\param[in] context The shared IPA context\n@@ -59,14 +77,21 @@ int ToneMapping::configure(IPAContext &context,\n */\n void ToneMapping::prepare([[maybe_unused]] IPAContext &context,\n \t\t\t [[maybe_unused]] const uint32_t frame,\n-\t\t\t [[maybe_unused]] IPAFrameContext &frameContext,\n+\t\t\t IPAFrameContext &frameContext,\n \t\t\t ipu3_uapi_params *params)\n {\n-\t/* Copy the calculated LUT into the parameters buffer. */\n-\tmemcpy(params->acc_param.gamma.gc_lut.lut,\n-\t context.activeState.toneMapping.gammaCorrection.lut,\n-\t IPU3_UAPI_GAMMA_CORR_LUT_ENTRIES *\n-\t sizeof(params->acc_param.gamma.gc_lut.lut[0]));\n+\tif (!frameContext.gamma.update)\n+\t\treturn;\n+\n+\t/*\n+\t * Unfortunately necessary given the IPU3's gamma uAPI struct has the\n+\t * __packed attribute.\n+\t */\n+\tuint16_t *lutData = reinterpret_cast<uint16_t *>(\n+\t\t__builtin_assume_aligned(params->acc_param.gamma.gc_lut.lut, 16));\n+\tSpan<uint16_t> lut{ lutData, kNumLutNodes };\n+\n+\tgammaAlgo_.prepare(frameContext.gamma, lut);\n \n \t/* Enable the custom gamma table. */\n \tparams->use.acc_gamma = 1;\n@@ -84,33 +109,13 @@ void ToneMapping::prepare([[maybe_unused]] IPAContext &context,\n * The tone mapping look up table is generated as an inverse power curve from\n * our gamma setting.\n */\n-void ToneMapping::process(IPAContext &context, [[maybe_unused]] const uint32_t frame,\n-\t\t\t [[maybe_unused]] IPAFrameContext &frameContext,\n+void ToneMapping::process([[maybe_unused]] IPAContext &context,\n+\t\t\t [[maybe_unused]] const uint32_t frame,\n+\t\t\t IPAFrameContext &frameContext,\n \t\t\t [[maybe_unused]] const ipu3_uapi_stats_3a *stats,\n \t\t\t [[maybe_unused]] ControlList &metadata)\n {\n-\t/*\n-\t * Hardcode gamma to 1.1 as a default for now.\n-\t *\n-\t * \\todo Expose gamma control setting through the libcamera control API\n-\t */\n-\tgamma_ = 1.1;\n-\n-\tif (context.activeState.toneMapping.gamma == gamma_)\n-\t\treturn;\n-\n-\tstruct ipu3_uapi_gamma_corr_lut &lut =\n-\t\tcontext.activeState.toneMapping.gammaCorrection;\n-\n-\tfor (uint32_t i = 0; i < std::size(lut.lut); i++) {\n-\t\tdouble j = static_cast<double>(i) / (std::size(lut.lut) - 1);\n-\t\tdouble gamma = std::pow(j, 1.0 / gamma_);\n-\n-\t\t/* The output value is expressed on 13 bits. */\n-\t\tlut.lut[i] = gamma * 8191;\n-\t}\n-\n-\tcontext.activeState.toneMapping.gamma = gamma_;\n+\tgammaAlgo_.process(frameContext.gamma, metadata);\n }\n \n REGISTER_IPA_ALGORITHM(ToneMapping, \"ToneMapping\")\ndiff --git a/src/ipa/ipu3/algorithms/tone_mapping.h b/src/ipa/ipu3/algorithms/tone_mapping.h\nindex b2b380108e014b3d5ee7b93bcdd948dea4d2302d..3437b7fcbbb70c9bbc895b514b354d26c1d707c6 100644\n--- a/src/ipa/ipu3/algorithms/tone_mapping.h\n+++ b/src/ipa/ipu3/algorithms/tone_mapping.h\n@@ -7,6 +7,11 @@\n \n #pragma once\n \n+#include <linux/intel-ipu3.h>\n+\n+#include <libipa/fixedpoint.h>\n+#include <libipa/gamma.h>\n+\n #include \"algorithm.h\"\n \n namespace libcamera {\n@@ -18,7 +23,11 @@ class ToneMapping : public Algorithm\n public:\n \tToneMapping();\n \n+\tint init(IPAContext &context, const ValueNode &tuningData) override;\n \tint configure(IPAContext &context, const IPAConfigInfo &configInfo) override;\n+\tvoid queueRequest(IPAContext &context, const uint32_t frame,\n+\t\t\t IPAFrameContext &frameContext,\n+\t\t\t const ControlList &controls) override;\n \tvoid prepare(IPAContext &context, const uint32_t frame,\n \t\t IPAFrameContext &frameContext, ipu3_uapi_params *params) override;\n \tvoid process(IPAContext &context, const uint32_t frame,\n@@ -27,7 +36,8 @@ public:\n \t\t ControlList &metadata) override;\n \n private:\n-\tdouble gamma_;\n+\tstatic constexpr unsigned int kNumLutNodes = IPU3_UAPI_GAMMA_CORR_LUT_ENTRIES;\n+\tGammaAlgorithm<kNumLutNodes, UQ<0, 13>> gammaAlgo_;\n };\n \n } /* namespace ipa::ipu3::algorithms */\ndiff --git a/src/ipa/ipu3/ipa_context.cpp b/src/ipa/ipu3/ipa_context.cpp\nindex 469905a43c4300bfa7a7fee5777f4a51837cf4c6..d3bcd7a81fe010d17d1437bf7f6cedce83a9be5c 100644\n--- a/src/ipa/ipu3/ipa_context.cpp\n+++ b/src/ipa/ipu3/ipa_context.cpp\n@@ -119,6 +119,11 @@ namespace libcamera::ipa::ipu3 {\n * \\brief Active colour Correction Matrix parameters for the IPA\n */\n \n+/**\n+ * \\var IPAActiveState::gamma\n+ * \\brief Active gamma correction parameters for the IPA\n+ */\n+\n /**\n * \\var IPASessionConfiguration::sensor\n * \\brief Sensor-specific configuration of the IPA\n@@ -149,20 +154,6 @@ namespace libcamera::ipa::ipu3 {\n * The gain should be adapted to the sensor specific gain code before applying.\n */\n \n-/**\n- * \\var IPAActiveState::toneMapping\n- * \\brief Context for ToneMapping and Gamma control\n- *\n- * \\var IPAActiveState::toneMapping.gamma\n- * \\brief Gamma value for the LUT\n- *\n- * \\var IPAActiveState::toneMapping.gammaCorrection\n- * \\brief Per-pixel tone mapping implemented as a LUT\n- *\n- * The LUT structure is defined by the IPU3 kernel interface. See\n- * <linux/intel-ipu3.h> struct ipu3_uapi_gamma_corr_lut for further details.\n- */\n-\n /**\n * \\struct IPAFrameContext\n * \\brief IPU3-specific FrameContext\n@@ -187,4 +178,9 @@ namespace libcamera::ipa::ipu3 {\n * \\brief Per-frame colour Correction Matrix parameters for the IPA\n */\n \n+/**\n+ * \\var IPAFrameContext::gamma\n+ * \\brief Per-frame gamma correction parameters for the IPA\n+ */\n+\n } /* namespace libcamera::ipa::ipu3 */\ndiff --git a/src/ipa/ipu3/ipa_context.h b/src/ipa/ipu3/ipa_context.h\nindex 6445db2603645d804b6caa40cde65099c4e57511..ce496ed477f4cbe2653aedada3381258396d92c8 100644\n--- a/src/ipa/ipu3/ipa_context.h\n+++ b/src/ipa/ipu3/ipa_context.h\n@@ -18,6 +18,7 @@\n #include <libipa/awb.h>\n #include <libipa/ccm.h>\n #include <libipa/fc_queue.h>\n+#include <libipa/gamma.h>\n \n namespace libcamera {\n \n@@ -64,11 +65,7 @@ struct IPAActiveState {\n \n \tipa::awb::ActiveState awb;\n \tipa::ccm::ActiveState ccm;\n-\n-\tstruct {\n-\t\tdouble gamma;\n-\t\tstruct ipu3_uapi_gamma_corr_lut gammaCorrection;\n-\t} toneMapping;\n+\tipa::gamma::ActiveState gamma;\n };\n \n struct IPAFrameContext : public FrameContext {\n@@ -79,6 +76,7 @@ struct IPAFrameContext : public FrameContext {\n \n \tipa::awb::FrameContext awb;\n \tipa::ccm::FrameContext ccm;\n+\tipa::gamma::FrameContext gamma;\n };\n \n struct IPAContext {\n", "prefixes": [ "v2", "07/12" ] }