[RFC,v5,09/10] libcamera: software_isp: Use LSC type instead of LSC enabled
diff mbox series

Message ID 20260512123619.120068-10-mzamazal@redhat.com
State New
Headers show
Series
  • LSC for SoftISP simple pipeline
Related show

Commit Message

Milan Zamazal May 12, 2026, 12:36 p.m. UTC
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 <mzamazal@redhat.com>
---
 .../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(-)

Patch
diff mbox series

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<LscValueType, kLscGridSize * kLscGridSize * kLscValuesPerCell>;
 	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::soft::IPAProxySoft> ipa_;
 	std::deque<FrameBuffer *> 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 <libcamera/controls.h>
 
 #include "libcamera/internal/matrix.h"
+#include "libcamera/internal/software_isp/debayer_params.h"
 #include "libcamera/internal/vector.h"
 
 #include <libipa/fc_queue.h>
@@ -93,7 +94,7 @@  struct IPAContext {
 	FCQueue<IPAFrameContext> 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<std::reference_wrapper<const StreamConfiguration>> &outputCfgs,
 			      bool ccmEnabled,
-			      bool lscEnabled) = 0;
+			      uint32_t lscType) = 0;
 
 	virtual std::vector<PixelFormat> 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<std::reference_wrapper<const StreamConfiguration>> &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<std::reference_wrapper<const StreamConfiguration>> &outputCfgs,
 		      bool ccmEnabled,
-		      bool lscEnabled) override;
+		      uint32_t lscType) override;
 	Size patternSize(PixelFormat inputFormat) override;
 	std::vector<PixelFormat> formats(PixelFormat input) override;
 	std::tuple<unsigned int, unsigned int>
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<std::reference_wrapper<const StreamConfiguration>> &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 &params)
 	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<std::reference_wrapper<const StreamConfiguration>> &outputCfgs,
 		      bool ccmEnabled,
-		      bool lscEnabled) override;
+		      uint32_t lscType) override;
 
 	Size patternSize(PixelFormat inputFormat) override;
 
@@ -77,9 +77,9 @@  private:
 	std::unique_ptr<eGLImage> eglImageBayerIn_;
 	std::unique_ptr<eGLImage> eglImageBayerOut_;
 
-	/* LSC lookup table */
+	/* Lens shading correction */
+	uint32_t lscType_;
 	std::unique_ptr<eGLImage> 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;