| Message ID | 20260616-ipu3-libipa-rework-v1-6-d4448b54f1d8@ideasonboard.com |
|---|---|
| State | Superseded |
| Headers | show |
| Series |
|
| Related | show |
Quoting Daniel Scally (2026-06-16 07:41:40) > 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. I'm curious that we're handling gamma in a tone mapping block, but that's where it was so lets not change that in this patch anyway. > > Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com> > --- > 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 <cmath> > #include <string.h> > > +#include <libcamera/base/span.h> > + > /** > * \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<uint16_t *>( > + __builtin_assume_aligned(params->acc_param.gamma.gc_lut.lut, 16)); > + Span<uint16_t> 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; Sooooooo good to drop all this. > - > - 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<double>(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 <libipa/gamma.h> > + > #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<kNumLutNodes, UQ<0, 13>> gammaAlgo_; Well, that all looks pretty clean to me. Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> > }; > > } /* 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 > - * <linux/intel-ipu3.h> 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 <libipa/awb.h> > #include <libipa/ccm.h> > #include <libipa/fc_queue.h> > +#include <libipa/gamma.h> > > 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 { > > -- > 2.43.0 >
Hi Dan On Tue, Jun 16, 2026 at 07:41:40AM +0100, Daniel Scally wrote: > 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 <dan.scally@ideasonboard.com> > --- > 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 <cmath> > #include <string.h> Please check if headers inclusion has to be adjusted here and in the header Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com> > > +#include <libcamera/base/span.h> > + > /** > * \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<uint16_t *>( > + __builtin_assume_aligned(params->acc_param.gamma.gc_lut.lut, 16)); > + Span<uint16_t> 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<double>(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 <libipa/gamma.h> > + > #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<kNumLutNodes, UQ<0, 13>> 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 > - * <linux/intel-ipu3.h> 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 <libipa/awb.h> > #include <libipa/ccm.h> > #include <libipa/fc_queue.h> > +#include <libipa/gamma.h> > > 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 { > > -- > 2.43.0 >
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 <cmath> #include <string.h> +#include <libcamera/base/span.h> + /** * \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<uint16_t *>( + __builtin_assume_aligned(params->acc_param.gamma.gc_lut.lut, 16)); + Span<uint16_t> 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<double>(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 <libipa/gamma.h> + #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<kNumLutNodes, UQ<0, 13>> 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 - * <linux/intel-ipu3.h> 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 <libipa/awb.h> #include <libipa/ccm.h> #include <libipa/fc_queue.h> +#include <libipa/gamma.h> 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 {
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 <dan.scally@ideasonboard.com> --- 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(-)