From patchwork Tue Jun 16 06:41:40 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dan Scally X-Patchwork-Id: 26897 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 B7531C3302 for ; Tue, 16 Jun 2026 06:42:03 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 04BC9625BB; Tue, 16 Jun 2026 08:41:57 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="ZUfdUrd9"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 1C73A623F5 for ; Tue, 16 Jun 2026 08:41:50 +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 D21F1166C; Tue, 16 Jun 2026 08:41:16 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1781592076; bh=sAflhLA91ZjuiM83DPI+H8xZ3xvJUxxNg+0tqw96N5M=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=ZUfdUrd9oFWfUSr4MI91v6GdZCDN6ziOlm8x6yTRNDkHfKICw06pDc6TS9C3TxaQX I/hU8wKcybDMLdWIjJmNO0pW+hgkW/C2p7UAMSVoxtefqiAKyXiXcB6Ao6MLue7HHh nldDOAR80qqpSet+myYzqmUCsNuTPeJ3+R8g+QYY= From: Daniel Scally Date: Tue, 16 Jun 2026 07:41:40 +0100 Subject: [PATCH 06/10] ipa: ipu3: ToneMapping: Convert to use GammaAlgorithm MIME-Version: 1.0 Message-Id: <20260616-ipu3-libipa-rework-v1-6-d4448b54f1d8@ideasonboard.com> References: <20260616-ipu3-libipa-rework-v1-0-d4448b54f1d8@ideasonboard.com> In-Reply-To: <20260616-ipu3-libipa-rework-v1-0-d4448b54f1d8@ideasonboard.com> To: libcamera-devel@lists.libcamera.org Cc: Daniel Scally X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=8324; i=dan.scally@ideasonboard.com; h=from:subject:message-id; bh=sAflhLA91ZjuiM83DPI+H8xZ3xvJUxxNg+0tqw96N5M=; b=owEBbQKS/ZANAwAKAchJV3psRXUyAcsmYgBqMPAqlYyVaISm7jnN4T8x7D5FpCb1feWMutMc6 LyakDfa1wKJAjMEAAEKAB0WIQQqyuwyDnZdb+mxmm/ISVd6bEV1MgUCajDwKgAKCRDISVd6bEV1 MsJTEACzBdHozM3of4+7cgyMiKcNqtMN/VaaVWVEFBNoD5aKHXr+mD8lQUWY9aif1r2d9X/tfQ9 gj1mZ2hgG3Xy7mktf2WsuWnXBBCby+geD5uss/oBhroTb44l86KYRE5PHwd38Dx+N92Byfzmjis JizN5VEoNFL2hrxq//tejm5PTPG3YTkp0E248as4hG5rHCIGVplHfKnkxX9Hp0d6mFORDvG6Drf QvYlOyPgoHokWsq4pEXIKJPGRqs1NMSqnnKkKlIOj0HIBLcJpxzU4gGnrRDSCoLmzStPxk9CpPT M/vyPvvgAJtzi2FvfdzAD6+tSt592mcdHbMYA3c6QTrVc5G96KEjfmEdn3NNbE6j/7jQu14NePB VlYw4AF/+R+y6rNZ8bb5/QV5o//gVG1G+RH6DCcYhkZ/GjAm/zZ6gkQX4IUftGH6ZrlMsEvgfXV UEbaa0fDshO6kQXRlsR/ZumnzgaMfM75H/ZhWaHtdPLT7sqIS0XNOStQWUiflKR6lQTljEMO0zz owCie7q+eWopWaaWGj54LlX3aqiv/mT+t9CliUZxGCwxbXVQ1YCvnH2PPIecD9Q3bybV5OZ06G2 dViyDO84SIU+i9qtdYacsfmqzZaSD/bNinpUHO1gEI5OzraI/s2KnxvHsvUh+JR3IUNo37y3q6o 6lzD2W9Blc+PQvA== 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. Signed-off-by: Daniel Scally --- src/ipa/ipu3/algorithms/tone_mapping.cpp | 73 +++++++++++++++++--------------- src/ipa/ipu3/algorithms/tone_mapping.h | 9 +++- src/ipa/ipu3/ipa_context.cpp | 24 +++++------ src/ipa/ipu3/ipa_context.h | 8 ++-- 4 files changed, 60 insertions(+), 54 deletions(-) diff --git a/src/ipa/ipu3/algorithms/tone_mapping.cpp b/src/ipa/ipu3/algorithms/tone_mapping.cpp index 160338c139448cc9a0bc1fe2400c335a96f68f73..2bc29bb9124dd8bd327ca3064b52c55637f56e7b 100644 --- a/src/ipa/ipu3/algorithms/tone_mapping.cpp +++ b/src/ipa/ipu3/algorithms/tone_mapping.cpp @@ -10,6 +10,8 @@ #include #include +#include + /** * \file tone_mapping.h */ @@ -27,10 +29,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 +50,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 +77,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)); + Span lut {lutData, kNumLutNodes}; + + gammaAlgo_.prepare(frameContext.gamma, lut); /* Enable the custom gamma table. */ params->use.acc_gamma = 1; @@ -84,33 +109,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..db351a32b4383c4d607a2d6ee6a8fa3994a1d436 100644 --- a/src/ipa/ipu3/algorithms/tone_mapping.h +++ b/src/ipa/ipu3/algorithms/tone_mapping.h @@ -7,6 +7,8 @@ #pragma once +#include + #include "algorithm.h" namespace libcamera { @@ -18,7 +20,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 +33,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 dc43bc0877ed5c2e7287414e12667374f5ee1c80..7152d070d3ab1bc463fdaad437d5e1c1b87ce25c 100644 --- a/src/ipa/ipu3/ipa_context.cpp +++ b/src/ipa/ipu3/ipa_context.cpp @@ -119,6 +119,11 @@ namespace libcamera::ipa::ipu3 { * \brief Active colour Correction Matrix parameters for the IPA */ +/** + * \var IPAActiveState::gamma + * \brief Active gamma correction parameters for the IPA + */ + /** * \var IPASessionConfiguration::sensor * \brief Sensor-specific configuration of the IPA @@ -154,20 +159,6 @@ namespace libcamera::ipa::ipu3 { * The gain should be adapted to the sensor specific gain code before applying. */ -/** - * \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. - */ - /** * \struct IPAFrameContext * \brief IPU3-specific FrameContext @@ -192,4 +183,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 be626d30d966b1bdaa322e5154f95f745f799976..1eaaac82da0e3ad5bed0749c39d9dad8c585cab0 100644 --- a/src/ipa/ipu3/ipa_context.h +++ b/src/ipa/ipu3/ipa_context.h @@ -18,6 +18,7 @@ #include #include #include +#include namespace libcamera { @@ -66,11 +67,7 @@ struct IPAActiveState { 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 { @@ -81,6 +78,7 @@ struct IPAFrameContext : public FrameContext { ipa::awb::FrameContext awb; ipa::ccm::FrameContext ccm; + ipa::gamma::FrameContext gamma; }; struct IPAContext {