From patchwork Mon Sep 14 14:53:47 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dan Scally X-Patchwork-Id: 28294 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 52B53C3352 for ; Mon, 14 Sep 2026 14:54:15 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D606F686D9; Mon, 14 Sep 2026 16:54:10 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="bRPzpiVU"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id A8ED6686C0 for ; Mon, 14 Sep 2026 16:53:57 +0200 (CEST) Received: from [127.0.1.1] (chfd-03-b2-v4wan-176392-cust229.vm15.cable.virginm.net [82.19.20.230]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 912F51CF1; Mon, 14 Sep 2026 16:52:17 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1789397537; bh=dU2mU0Tyw1iA1wTmSQmYyDOv2tLbmfLIuds8oSK3mLI=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=bRPzpiVUaFHbxRyAxfC+OU6etTB/N+fNVhDudmW33qwez5PaxNG3zMduvCh65Mw3x JqI9haEUp94FlMmUV8QZnEG1stlE5WVJY9Qm0GNzIj6h+GOLEP4Di80UzRtGI7lg1z Fe7WeJnlnem2C6NtMyaVb7otAjtVrEpjPHIWAnDQ= From: Daniel Scally Date: Mon, 14 Sep 2026 15:53:47 +0100 Subject: [PATCH v4 07/10] ipa: ipu3: ToneMapping: Convert to use GammaAlgorithm MIME-Version: 1.0 Message-Id: <20260914-ipu3-libipa-rework-v4-7-ff8ee2d3dd24@ideasonboard.com> References: <20260914-ipu3-libipa-rework-v4-0-ff8ee2d3dd24@ideasonboard.com> In-Reply-To: <20260914-ipu3-libipa-rework-v4-0-ff8ee2d3dd24@ideasonboard.com> To: libcamera-devel@lists.libcamera.org Cc: Daniel Scally , Jacopo Mondi , Kieran Bingham X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=8389; i=dan.scally@ideasonboard.com; h=from:subject:message-id; bh=dU2mU0Tyw1iA1wTmSQmYyDOv2tLbmfLIuds8oSK3mLI=; b=owEBbQKS/ZANAwAKAchJV3psRXUyAcsmYgBqqAqBCGFT6f3/wch6BkNEahcZ1TFwZgz9E7VOP e2Whr/NKf2JAjMEAAEKAB0WIQQqyuwyDnZdb+mxmm/ISVd6bEV1MgUCaqgKgQAKCRDISVd6bEV1 MjtzD/9/Zl4ltXQNJBo/VVww1nbqmoTUgsreUXAnsP8aKX/VyrrCXmtRokLuODdeyE9et88B3lD x3yaJBgU+MO6m38mhS/KURazo7GbPEWlKnx/olzg6KVrXuXHxcH7QyEgUtbGb/c4AUIBadGajab CWK7ADQ84+YEHvk4IpLfpb9pTi45GGLep4zt9SjRpGKNjTX23BRxGjyvQ5wQtYJGnM2sedwZhym yQ39D6P8As8HzGAG7AvO7cXRbDjvoFsXwKwP0gcqXZGmNZ03zij+gDr1RL254kqBh/IM8Q99fYX +vcxv8gFXVS/tcbio8BB5N7CPpElD9Ua3PLk6Evb7gPTCuCkieaRvafEcEYqQD60CttTTyk3/uH bd6OIe/4PZvqVSXM0yjXM8BPfthlQlem7+VThqEnCJ0jSiYC5TJRu7Aj5xl5FHyh1v3jcMbZxee 9DfDxdeBFCyFpMvvONlC5hHGU1pxp8Mz0ie6NeaM6H2Nhxs11jLS2k+nYAdpfZxa4TSYg2czxl+ j3WaK/c07lRLQxndWMdXS7maW1JGNXRR6jJ09XTF0VfjqBcc+hpfyYQelQh943JAhTejxsizGH1 7QgFFEgaC8Z0uD3cslFwZupoNm19HN9XaoT9L14xdnNIGtUkd9Se04vdSCvIcwp6DEanVP/RiWi qlqcHylDu5DP/Dg== X-Developer-Key: i=dan.scally@ideasonboard.com; a=openpgp; fpr=EEC699ACA1B7CB5D31330C0BBD501C2A3546CCF6 X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Convert the IPU3 ToneMapping algorithm to use the new GammaAlgorithm base class. This gives us configurable gamma via the tuning files and at runtime using the Gamma control. Reviewed-by: Jacopo Mondi Reviewed-by: Kieran Bingham Signed-off-by: Daniel Scally --- Changes in v4: - Used std::Span in place of libcamera's Span class Changes in v3: - Construct Span with size template param Changes in v2: - Fixed includes - Minor styling changes --- src/ipa/ipu3/algorithms/tone_mapping.cpp | 72 +++++++++++++++++--------------- src/ipa/ipu3/algorithms/tone_mapping.h | 12 +++++- src/ipa/ipu3/ipa_context.cpp | 18 ++++---- src/ipa/ipu3/ipa_context.h | 8 ++-- 4 files changed, 59 insertions(+), 51 deletions(-) diff --git a/src/ipa/ipu3/algorithms/tone_mapping.cpp b/src/ipa/ipu3/algorithms/tone_mapping.cpp index 160338c139448cc9a0bc1fe2400c335a96f68f73..d587dac6612daae33a0d97386f221034c21b4df7 100644 --- a/src/ipa/ipu3/algorithms/tone_mapping.cpp +++ b/src/ipa/ipu3/algorithms/tone_mapping.cpp @@ -8,6 +8,7 @@ #include "tone_mapping.h" #include +#include #include /** @@ -27,10 +28,17 @@ namespace ipa::ipu3::algorithms { */ ToneMapping::ToneMapping() - : gamma_(1.0) { } +/** + * \copydoc libcamera::ipa::Algorithm::init + */ +int ToneMapping::init(IPAContext &context, const ValueNode &tuningData) +{ + return gammaAlgo_.init(context.ctrlMap, tuningData); +} + /** * \brief Configure the tone mapping given a configInfo * \param[in] context The shared IPA context @@ -41,12 +49,21 @@ ToneMapping::ToneMapping() int ToneMapping::configure(IPAContext &context, [[maybe_unused]] const IPAConfigInfo &configInfo) { - /* Initialise tone mapping gamma value. */ - context.activeState.toneMapping.gamma = 0.0; - + gammaAlgo_.configure(context.activeState.gamma); return 0; } +/** + * \copydoc libcamera::ipa::Algorithm::queueRequest + */ +void ToneMapping::queueRequest(IPAContext &context, const uint32_t frame, + IPAFrameContext &frameContext, + const ControlList &controls) +{ + gammaAlgo_.queueRequest(context.activeState.gamma, frame, + frameContext.gamma, controls); +} + /** * \brief Fill in the parameter structure, and enable gamma control * \param[in] context The shared IPA context @@ -59,14 +76,21 @@ int ToneMapping::configure(IPAContext &context, */ void ToneMapping::prepare([[maybe_unused]] IPAContext &context, [[maybe_unused]] const uint32_t frame, - [[maybe_unused]] IPAFrameContext &frameContext, + IPAFrameContext &frameContext, ipu3_uapi_params *params) { - /* Copy the calculated LUT into the parameters buffer. */ - memcpy(params->acc_param.gamma.gc_lut.lut, - context.activeState.toneMapping.gammaCorrection.lut, - IPU3_UAPI_GAMMA_CORR_LUT_ENTRIES * - sizeof(params->acc_param.gamma.gc_lut.lut[0])); + if (!frameContext.gamma.update) + return; + + /* + * Unfortunately necessary given the IPU3's gamma uAPI struct has the + * __packed attribute. + */ + uint16_t *lutData = reinterpret_cast( + __builtin_assume_aligned(params->acc_param.gamma.gc_lut.lut, 16)); + std::span lut{ lutData, kNumLutNodes }; + + gammaAlgo_.prepare(frameContext.gamma, lut); /* Enable the custom gamma table. */ params->use.acc_gamma = 1; @@ -84,33 +108,13 @@ void ToneMapping::prepare([[maybe_unused]] IPAContext &context, * The tone mapping look up table is generated as an inverse power curve from * our gamma setting. */ -void ToneMapping::process(IPAContext &context, [[maybe_unused]] const uint32_t frame, - [[maybe_unused]] IPAFrameContext &frameContext, +void ToneMapping::process([[maybe_unused]] IPAContext &context, + [[maybe_unused]] const uint32_t frame, + IPAFrameContext &frameContext, [[maybe_unused]] const ipu3_uapi_stats_3a *stats, [[maybe_unused]] ControlList &metadata) { - /* - * Hardcode gamma to 1.1 as a default for now. - * - * \todo Expose gamma control setting through the libcamera control API - */ - gamma_ = 1.1; - - if (context.activeState.toneMapping.gamma == gamma_) - return; - - struct ipu3_uapi_gamma_corr_lut &lut = - context.activeState.toneMapping.gammaCorrection; - - for (uint32_t i = 0; i < std::size(lut.lut); i++) { - double j = static_cast(i) / (std::size(lut.lut) - 1); - double gamma = std::pow(j, 1.0 / gamma_); - - /* The output value is expressed on 13 bits. */ - lut.lut[i] = gamma * 8191; - } - - context.activeState.toneMapping.gamma = gamma_; + gammaAlgo_.process(frameContext.gamma, metadata); } REGISTER_IPA_ALGORITHM(ToneMapping, "ToneMapping") diff --git a/src/ipa/ipu3/algorithms/tone_mapping.h b/src/ipa/ipu3/algorithms/tone_mapping.h index b2b380108e014b3d5ee7b93bcdd948dea4d2302d..3437b7fcbbb70c9bbc895b514b354d26c1d707c6 100644 --- a/src/ipa/ipu3/algorithms/tone_mapping.h +++ b/src/ipa/ipu3/algorithms/tone_mapping.h @@ -7,6 +7,11 @@ #pragma once +#include + +#include +#include + #include "algorithm.h" namespace libcamera { @@ -18,7 +23,11 @@ class ToneMapping : public Algorithm public: ToneMapping(); + int init(IPAContext &context, const ValueNode &tuningData) override; int configure(IPAContext &context, const IPAConfigInfo &configInfo) override; + void queueRequest(IPAContext &context, const uint32_t frame, + IPAFrameContext &frameContext, + const ControlList &controls) override; void prepare(IPAContext &context, const uint32_t frame, IPAFrameContext &frameContext, ipu3_uapi_params *params) override; void process(IPAContext &context, const uint32_t frame, @@ -27,7 +36,8 @@ public: ControlList &metadata) override; private: - double gamma_; + static constexpr unsigned int kNumLutNodes = IPU3_UAPI_GAMMA_CORR_LUT_ENTRIES; + GammaAlgorithm> gammaAlgo_; }; } /* namespace ipa::ipu3::algorithms */ diff --git a/src/ipa/ipu3/ipa_context.cpp b/src/ipa/ipu3/ipa_context.cpp index 5f5ac92955869898f072f5228524ca7ec8a02839..02e5f79fa5def888fe3776e5cb002771a497ee41 100644 --- a/src/ipa/ipu3/ipa_context.cpp +++ b/src/ipa/ipu3/ipa_context.cpp @@ -122,17 +122,8 @@ namespace libcamera::ipa::ipu3 { */ /** - * \var IPAActiveState::toneMapping - * \brief Context for ToneMapping and Gamma control - * - * \var IPAActiveState::toneMapping.gamma - * \brief Gamma value for the LUT - * - * \var IPAActiveState::toneMapping.gammaCorrection - * \brief Per-pixel tone mapping implemented as a LUT - * - * The LUT structure is defined by the IPU3 kernel interface. See - * struct ipu3_uapi_gamma_corr_lut for further details. + * \var IPAActiveState::gamma + * \brief Active gamma correction parameters for the IPA */ /** @@ -162,4 +153,9 @@ namespace libcamera::ipa::ipu3 { * \brief Per-frame colour Correction Matrix parameters for the IPA */ +/** + * \var IPAFrameContext::gamma + * \brief Per-frame gamma correction parameters for the IPA + */ + } /* namespace libcamera::ipa::ipu3 */ diff --git a/src/ipa/ipu3/ipa_context.h b/src/ipa/ipu3/ipa_context.h index 5476a8ad0256dbb04d33fcd591b72d4b56a52897..1755fc62a89152470bd059c6eb6b6a366e451ba6 100644 --- a/src/ipa/ipu3/ipa_context.h +++ b/src/ipa/ipu3/ipa_context.h @@ -22,6 +22,7 @@ #include #include #include +#include namespace libcamera { @@ -51,11 +52,7 @@ struct IPAActiveState { agc::ActiveState agc; ipa::awb::ActiveState awb; ipa::ccm::ActiveState ccm; - - struct { - double gamma; - struct ipu3_uapi_gamma_corr_lut gammaCorrection; - } toneMapping; + ipa::gamma::ActiveState gamma; }; struct IPAFrameContext : public FrameContext { @@ -67,6 +64,7 @@ struct IPAFrameContext : public FrameContext { agc::FrameContext agc; ipa::awb::FrameContext awb; ipa::ccm::FrameContext ccm; + ipa::gamma::FrameContext gamma; }; struct IPAContext {