From patchwork Tue May 12 12:36:13 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 26732 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 5D3B6BDB1C for ; Tue, 12 May 2026 12:37:04 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 02DFC63035; Tue, 12 May 2026 14:37:04 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="HuQqZDHH"; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id ABA6363040 for ; Tue, 12 May 2026 14:37:00 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1778589419; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=4lVwO/cOUEnaMm7csGaMuC3ip1vYDO+wof8lFUK287g=; b=HuQqZDHHWC/Un9BMP5GBq+pFvQOp3oiiFPV12QTDEqs3jdq9F4llSugGTrhg3hPkpCBfUr fszWkovrQz7fEuLgbqSh6pV5feOCM9iJSm9QRTVQ8Va3Dbd0Mg0r4DVtGnBYsFg2w3oLNP 3D7/nRObn3kw60qsrwZutBdyd/m7uE4= Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-398-qbmrZvBQPYSzSMxMBEKtHA-1; Tue, 12 May 2026 08:36:58 -0400 X-MC-Unique: qbmrZvBQPYSzSMxMBEKtHA-1 X-Mimecast-MFC-AGG-ID: qbmrZvBQPYSzSMxMBEKtHA_1778589417 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 2B6AD1800614; Tue, 12 May 2026 12:36:57 +0000 (UTC) Received: from mzamazal-thinkpadp1gen7.tpbc.com (unknown [10.44.50.44]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 1A7C11955D84; Tue, 12 May 2026 12:36:54 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal , Bryan O'Donoghue , Hans de Goede , Laurent Pinchart Subject: [RFC PATCH v5 09/10] libcamera: software_isp: Use LSC type instead of LSC enabled Date: Tue, 12 May 2026 14:36:13 +0200 Message-ID: <20260512123619.120068-10-mzamazal@redhat.com> In-Reply-To: <20260512123619.120068-1-mzamazal@redhat.com> References: <20260512123619.120068-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: _Wh_x4d2_yrc-mAYdlJ2mS7jjUOo8WK9uZEkO8SC6KE_1778589417 X-Mimecast-Originator: redhat.com content-type: text/plain; charset="US-ASCII"; x-default=true 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" With the upcoming introduction of polynomial lens shading correction, let's replace the boolean LSC-enabled flag with an enum / integer indicating the type of the LSC to apply. For the case when LSC is not enabled, LscNone enum value is introduced. The switch passed to the shaders is renamed from APPLY_LSC to APPLY_LSC_TABLE to get ready for other LSC types and other APPLY_LSC_* switches for shaders. Signed-off-by: Milan Zamazal --- .../internal/software_isp/debayer_params.h | 1 + .../internal/software_isp/software_isp.h | 2 +- include/libcamera/ipa/soft.mojom | 2 +- src/ipa/simple/algorithms/lsc.cpp | 2 +- src/ipa/simple/ipa_context.h | 3 ++- src/ipa/simple/soft_simple.cpp | 6 +++--- src/libcamera/shaders/bayer_1x_packed.frag | 4 ++-- src/libcamera/shaders/bayer_unpacked.frag | 4 ++-- src/libcamera/software_isp/debayer.cpp | 2 +- src/libcamera/software_isp/debayer.h | 2 +- src/libcamera/software_isp/debayer_cpu.cpp | 2 +- src/libcamera/software_isp/debayer_cpu.h | 2 +- src/libcamera/software_isp/debayer_egl.cpp | 21 +++++++++++++------ src/libcamera/software_isp/debayer_egl.h | 6 +++--- src/libcamera/software_isp/software_isp.cpp | 4 ++-- 15 files changed, 37 insertions(+), 26 deletions(-) diff --git a/include/libcamera/internal/software_isp/debayer_params.h b/include/libcamera/internal/software_isp/debayer_params.h index 9e6c9ddb8..37fff49a2 100644 --- a/include/libcamera/internal/software_isp/debayer_params.h +++ b/include/libcamera/internal/software_isp/debayer_params.h @@ -35,6 +35,7 @@ struct DebayerParams { using LscLookupTable = std::array; enum LscType : uint32_t { + LscNone, LscTable, }; LscLookupTable lscLut{}; diff --git a/include/libcamera/internal/software_isp/software_isp.h b/include/libcamera/internal/software_isp/software_isp.h index 1e30b2d68..ded0c3917 100644 --- a/include/libcamera/internal/software_isp/software_isp.h +++ b/include/libcamera/internal/software_isp/software_isp.h @@ -99,7 +99,7 @@ private: DebayerParams debayerParams_; DmaBufAllocator dmaHeap_; bool ccmEnabled_; - bool lscEnabled_; + uint32_t lscType_; std::unique_ptr ipa_; std::deque queuedInputBuffers_; diff --git a/include/libcamera/ipa/soft.mojom b/include/libcamera/ipa/soft.mojom index aaefd50c4..e65a6127c 100644 --- a/include/libcamera/ipa/soft.mojom +++ b/include/libcamera/ipa/soft.mojom @@ -20,7 +20,7 @@ interface IPASoftInterface { libcamera.ControlInfoMap sensorControls) => (int32 ret, libcamera.ControlInfoMap ipaControls, - bool ccmEnabled, bool lscEnabled); + bool ccmEnabled, uint32 lscType); start() => (int32 ret); stop(); configure(IPAConfigInfo configInfo) diff --git a/src/ipa/simple/algorithms/lsc.cpp b/src/ipa/simple/algorithms/lsc.cpp index 87023bc9b..ae5179cfc 100644 --- a/src/ipa/simple/algorithms/lsc.cpp +++ b/src/ipa/simple/algorithms/lsc.cpp @@ -36,7 +36,7 @@ int Lsc::init(IPAContext &context, const ValueNode &tuningData) return -EINVAL; } - context.lscEnabled = true; + context.lscType = type_; return 0; } diff --git a/src/ipa/simple/ipa_context.h b/src/ipa/simple/ipa_context.h index d77bbc280..9972efa6d 100644 --- a/src/ipa/simple/ipa_context.h +++ b/src/ipa/simple/ipa_context.h @@ -14,6 +14,7 @@ #include #include "libcamera/internal/matrix.h" +#include "libcamera/internal/software_isp/debayer_params.h" #include "libcamera/internal/vector.h" #include @@ -93,7 +94,7 @@ struct IPAContext { FCQueue frameContexts; ControlInfoMap::Map ctrlMap; bool ccmEnabled = false; - bool lscEnabled = false; + DebayerParams::LscType lscType = DebayerParams::LscNone; }; } /* namespace ipa::soft */ diff --git a/src/ipa/simple/soft_simple.cpp b/src/ipa/simple/soft_simple.cpp index 4c724183a..d3f4a52cc 100644 --- a/src/ipa/simple/soft_simple.cpp +++ b/src/ipa/simple/soft_simple.cpp @@ -58,7 +58,7 @@ public: const ControlInfoMap &sensorControls, ControlInfoMap *ipaControls, bool *ccmEnabled, - bool *lscEnabled) override; + uint32_t *lscType) override; int configure(const IPAConfigInfo &configInfo) override; int start() override; @@ -99,7 +99,7 @@ int IPASoftSimple::init(const IPASettings &settings, const ControlInfoMap &sensorControls, ControlInfoMap *ipaControls, bool *ccmEnabled, - bool *lscEnabled) + uint32_t *lscType) { camHelper_ = CameraSensorHelperFactoryBase::create(settings.sensorModel); if (!camHelper_) { @@ -138,7 +138,7 @@ int IPASoftSimple::init(const IPASettings &settings, return ret; *ccmEnabled = context_.ccmEnabled; - *lscEnabled = context_.lscEnabled; + *lscType = context_.lscType; params_ = nullptr; stats_ = nullptr; diff --git a/src/libcamera/shaders/bayer_1x_packed.frag b/src/libcamera/shaders/bayer_1x_packed.frag index 228c72309..dc2b582f8 100644 --- a/src/libcamera/shaders/bayer_1x_packed.frag +++ b/src/libcamera/shaders/bayer_1x_packed.frag @@ -70,7 +70,7 @@ uniform vec3 blacklevel; uniform float gamma; uniform float contrastExp; -#if defined(APPLY_LSC) +#if defined(APPLY_LSC_TABLE) uniform sampler2D lsc_tex; #endif @@ -231,7 +231,7 @@ void main(void) rgb = rgb - blacklevel; -#if defined(APPLY_LSC) +#if defined(APPLY_LSC_TABLE) rgb = rgb * texture2D(lsc_tex, textureOut).rgb; #endif diff --git a/src/libcamera/shaders/bayer_unpacked.frag b/src/libcamera/shaders/bayer_unpacked.frag index af87bcc0f..df324e6e1 100644 --- a/src/libcamera/shaders/bayer_unpacked.frag +++ b/src/libcamera/shaders/bayer_unpacked.frag @@ -29,7 +29,7 @@ uniform vec3 blacklevel; uniform float gamma; uniform float contrastExp; -#if defined(APPLY_LSC) +#if defined(APPLY_LSC_TABLE) uniform sampler2D lsc_tex; #endif @@ -134,7 +134,7 @@ void main(void) { rgb = rgb - blacklevel; -#if defined(APPLY_LSC) +#if defined(APPLY_LSC_TABLE) rgb = rgb * texture2D(lsc_tex, center.xy).rgb; #endif diff --git a/src/libcamera/software_isp/debayer.cpp b/src/libcamera/software_isp/debayer.cpp index 12c2ec9fd..a77b3c9fc 100644 --- a/src/libcamera/software_isp/debayer.cpp +++ b/src/libcamera/software_isp/debayer.cpp @@ -114,7 +114,7 @@ Debayer::~Debayer() * \param[in] inputCfg The input configuration * \param[in] outputCfgs The output configurations * \param[in] ccmEnabled Whether a color correction matrix is applied - * \param[in] lscEnabled Whether lens shading correction grid is provided + * \param[in] lscType Type of lens shading correction * * \return 0 on success, a negative errno on failure */ diff --git a/src/libcamera/software_isp/debayer.h b/src/libcamera/software_isp/debayer.h index f4e649417..eb3fa7609 100644 --- a/src/libcamera/software_isp/debayer.h +++ b/src/libcamera/software_isp/debayer.h @@ -41,7 +41,7 @@ public: virtual int configure(const StreamConfiguration &inputCfg, const std::vector> &outputCfgs, bool ccmEnabled, - bool lscEnabled) = 0; + uint32_t lscType) = 0; virtual std::vector formats(PixelFormat inputFormat) = 0; diff --git a/src/libcamera/software_isp/debayer_cpu.cpp b/src/libcamera/software_isp/debayer_cpu.cpp index 0a410d03d..14019ff41 100644 --- a/src/libcamera/software_isp/debayer_cpu.cpp +++ b/src/libcamera/software_isp/debayer_cpu.cpp @@ -544,7 +544,7 @@ int DebayerCpu::setDebayerFunctions(PixelFormat inputFormat, int DebayerCpu::configure(const StreamConfiguration &inputCfg, const std::vector> &outputCfgs, bool ccmEnabled, - [[maybe_unused]] bool lscEnabled) + [[maybe_unused]] uint32_t lscType) { if (getInputConfig(inputCfg.pixelFormat, inputConfig_) != 0) return -EINVAL; diff --git a/src/libcamera/software_isp/debayer_cpu.h b/src/libcamera/software_isp/debayer_cpu.h index 6b7d8b677..de8b99b8a 100644 --- a/src/libcamera/software_isp/debayer_cpu.h +++ b/src/libcamera/software_isp/debayer_cpu.h @@ -38,7 +38,7 @@ public: int configure(const StreamConfiguration &inputCfg, const std::vector> &outputCfgs, bool ccmEnabled, - bool lscEnabled) override; + uint32_t lscType) override; Size patternSize(PixelFormat inputFormat) override; std::vector formats(PixelFormat input) override; std::tuple diff --git a/src/libcamera/software_isp/debayer_egl.cpp b/src/libcamera/software_isp/debayer_egl.cpp index 293ec2499..03ec5c5da 100644 --- a/src/libcamera/software_isp/debayer_egl.cpp +++ b/src/libcamera/software_isp/debayer_egl.cpp @@ -147,8 +147,13 @@ int DebayerEGL::initBayerShaders(PixelFormat inputFormat, PixelFormat outputForm /* Specify GL_OES_EGL_image_external */ egl_.pushEnv(shaderEnv, "#extension GL_OES_EGL_image_external: enable"); - if (lscEnabled_) - egl_.pushEnv(shaderEnv, "#define APPLY_LSC"); + switch (lscType_) { + case DebayerParams::LscNone: + break; + case DebayerParams::LscTable: + egl_.pushEnv(shaderEnv, "#define APPLY_LSC_TABLE"); + break; + } /* * Tell shaders how to re-order output taking account of how the pixels @@ -289,7 +294,7 @@ int DebayerEGL::initBayerShaders(PixelFormat inputFormat, PixelFormat outputForm int DebayerEGL::configure(const StreamConfiguration &inputCfg, const std::vector> &outputCfgs, [[maybe_unused]] bool ccmEnabled, - bool lscEnabled) + uint32_t lscType) { if (getInputConfig(inputCfg.pixelFormat, inputConfig_) != 0) return -EINVAL; @@ -306,7 +311,7 @@ int DebayerEGL::configure(const StreamConfiguration &inputCfg, return -EINVAL; } - lscEnabled_ = lscEnabled; + lscType_ = lscType; inputConfig_.stride = inputCfg.stride; inputPixelFormat_ = inputCfg.pixelFormat; @@ -349,7 +354,7 @@ int DebayerEGL::configure(const StreamConfiguration &inputCfg, */ stats_->setWindow(Rectangle(window_.size())); - if (lscEnabled_) { + if (lscType_ == DebayerParams::LscTable) { constexpr unsigned int gridSize = DebayerParams::kLscGridSize; const unsigned int stride = gridSize * DebayerParams::kLscBytesPerCell; eglImageLscLookup_ = @@ -499,11 +504,15 @@ void DebayerEGL::setShaderVariableValues(const DebayerParams ¶ms) glUniformMatrix3fv(ccmUniformDataIn_, 1, GL_FALSE, ccm); LOG(Debayer, Debug) << " ccmUniformDataIn_ " << ccmUniformDataIn_ << " data " << params.combinedMatrix; - if (lscEnabled_) { + switch (lscType_) { + case DebayerParams::LscNone: + break; + case DebayerParams::LscTable: egl_.createTexture2D(*eglImageLscLookup_, GL_RGB16F, GL_RGB, GL_FLOAT, DebayerParams::kLscGridSize, DebayerParams::kLscGridSize, params.lscLut.data(), GL_LINEAR); glUniform1i(textureUniformLsc_, eglImageLscLookup_->texture_unit_uniform_id_); + break; } /* diff --git a/src/libcamera/software_isp/debayer_egl.h b/src/libcamera/software_isp/debayer_egl.h index 85f51cf88..d5cfcad1e 100644 --- a/src/libcamera/software_isp/debayer_egl.h +++ b/src/libcamera/software_isp/debayer_egl.h @@ -45,7 +45,7 @@ public: int configure(const StreamConfiguration &inputCfg, const std::vector> &outputCfgs, bool ccmEnabled, - bool lscEnabled) override; + uint32_t lscType) override; Size patternSize(PixelFormat inputFormat) override; @@ -77,9 +77,9 @@ private: std::unique_ptr eglImageBayerIn_; std::unique_ptr eglImageBayerOut_; - /* LSC lookup table */ + /* Lens shading correction */ + uint32_t lscType_; std::unique_ptr eglImageLscLookup_; - bool lscEnabled_; /* Shader parameters */ float firstRed_x_; diff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp index e35bf10f1..3e59f262c 100644 --- a/src/libcamera/software_isp/software_isp.cpp +++ b/src/libcamera/software_isp/software_isp.cpp @@ -158,7 +158,7 @@ SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor, sensor->controls(), ipaControls, &ccmEnabled_, - &lscEnabled_); + &lscType_); if (ret) { LOG(SoftwareIsp, Error) << "IPA init failed"; debayer_.reset(); @@ -274,7 +274,7 @@ int SoftwareIsp::configure(const StreamConfiguration &inputCfg, if (ret < 0) return ret; - ret = debayer_->configure(inputCfg, outputCfgs, ccmEnabled_, lscEnabled_); + ret = debayer_->configure(inputCfg, outputCfgs, ccmEnabled_, lscType_); if (ret < 0) return ret;