| Message ID | 20260126104256.119697-6-rick.w.ten.wolde@gmail.com |
|---|---|
| State | New |
| Headers | show |
| Series |
|
| Related | show |
Hi 2026. 01. 26. 11:42 keltezéssel, Rick ten Wolde írta: > From: Xander Pronk <xander.c.pronk@gmail.com> > > Add support for passing the LSC tables from debayerParams to > the shaders. > > Co-authored-by: Rick ten Wolde <rick_libcamera@wolde.info> > Signed-off-by: Rick ten Wolde <rick_libcamera@wolde.info> > Signed-off-by: Xander Pronk <xander.c.pronk@gmail.com> > --- > src/libcamera/software_isp/debayer_egl.cpp | 21 +++++++++++++++++++++ > src/libcamera/software_isp/debayer_egl.h | 9 +++++++++ > 2 files changed, 30 insertions(+) > > diff --git a/src/libcamera/software_isp/debayer_egl.cpp b/src/libcamera/software_isp/debayer_egl.cpp > index 8e089032..0f36b149 100644 > --- a/src/libcamera/software_isp/debayer_egl.cpp > +++ b/src/libcamera/software_isp/debayer_egl.cpp > @@ -111,6 +111,10 @@ int DebayerEGL::getShaderVariableLocations(void) > textureUniformBayerFirstRed_ = glGetUniformLocation(programId_, "tex_bayer_first_red"); > textureUniformProjMatrix_ = glGetUniformLocation(programId_, "proj_matrix"); > > + textureUniformLSCRed_ = glGetUniformLocation(programId_, "lsc_tex_red"); > + textureUniformLSCGreen_ = glGetUniformLocation(programId_, "lsc_tex_green"); > + textureUniformLSCBlue_ = glGetUniformLocation(programId_, "lsc_tex_blue"); > + > LOG(Debayer, Debug) << "vertexIn " << attributeVertex_ << " textureIn " << attributeTexture_ > << " tex_y " << textureUniformBayerDataIn_ > << " ccm " << ccmUniformDataIn_ > @@ -140,6 +144,9 @@ int DebayerEGL::initBayerShaders(PixelFormat inputFormat, PixelFormat outputForm > /* Specify GL_OES_EGL_image_external */ > egl_.pushEnv(shaderEnv, "#extension GL_OES_EGL_image_external: enable"); > > + /* Always use LSC */ > + egl_.pushEnv(shaderEnv, "#define DO_LSC"); > + > /* > * Tell shaders how to re-order output taking account of how the > * pixels are actually stored by GBM > @@ -349,6 +356,12 @@ int DebayerEGL::configure(const StreamConfiguration &inputCfg, > */ > stats_->setWindow(Rectangle(window_.size())); > > + eglImageLSCLookupRed_ = new eGLImage(20, 20, sizeof(GLubyte), GL_TEXTURE5, 5); > + eglImageLSCLookupGreen_ = new eGLImage(20, 20, sizeof(GLubyte), GL_TEXTURE5, 5); > + eglImageLSCLookupBlue_ = new eGLImage(20, 20, sizeof(GLubyte), GL_TEXTURE5, 5); > + if (!eglImageLSCLookupRed_ || !eglImageLSCLookupGreen_ || !eglImageLSCLookupBlue_) These operator new calls never return nullptr. But see below. > + return -ENOMEM; > + > return 0; > } > > @@ -488,6 +501,14 @@ void DebayerEGL::setShaderVariableValues(DebayerParams ¶ms) > glUniformMatrix3fv(ccmUniformDataIn_, 1, GL_FALSE, ccm); > LOG(Debayer, Debug) << " ccmUniformDataIn_ " << ccmUniformDataIn_ << " data " << params.ccm; > > + egl_.createTexture2D(*eglImageLSCLookupRed_, GL_LUMINANCE, 16, 16, ¶ms.LSC_red, GL_LINEAR); > + egl_.createTexture2D(*eglImageLSCLookupBlue_, GL_LUMINANCE, 16, 16, ¶ms.LSC_green, GL_LINEAR); > + egl_.createTexture2D(*eglImageLSCLookupGreen_, GL_LUMINANCE, 16, 16, ¶ms.LSC_blue, GL_LINEAR); > + > + glUniform1i(textureUniformLSCRed_, eglImageLSCLookupRed_->texture_unit_uniform_id_); > + glUniform1i(textureUniformLSCGreen_, eglImageLSCLookupGreen_->texture_unit_uniform_id_); > + glUniform1i(textureUniformLSCBlue_, eglImageLSCLookupBlue_->texture_unit_uniform_id_); > + > /* > * 0 = Red, 1 = Green, 2 = Blue > */ > diff --git a/src/libcamera/software_isp/debayer_egl.h b/src/libcamera/software_isp/debayer_egl.h > index a5033bc6..61feadab 100644 > --- a/src/libcamera/software_isp/debayer_egl.h > +++ b/src/libcamera/software_isp/debayer_egl.h > @@ -85,6 +85,11 @@ private: > std::unique_ptr<eGLImage> eglImageBayerIn_; > std::unique_ptr<eGLImage> eglImageBayerOut_; > > + /* Pointer to object representing input texture */ > + eGLImage *eglImageLSCLookupRed_; > + eGLImage *eglImageLSCLookupBlue_; > + eGLImage *eglImageLSCLookupGreen_; These need to become `std::optional<eGLImage>` or `std::unique_ptr<>` at least. Please no raw owning raw pointers. Regards, Barnabás Pőcze > + > /* Shader parameters */ > float firstRed_x_; > float firstRed_y_; > @@ -98,6 +103,10 @@ private: > > GLint textureUniformBayerDataIn_; > > + GLint textureUniformLSCRed_; > + GLint textureUniformLSCGreen_; > + GLint textureUniformLSCBlue_; > + > /* Represent per-frame CCM as a uniform vector of floats 3 x 3 */ > GLint ccmUniformDataIn_; >
Hi, thank you for the patches. Rick ten Wolde <rick.w.ten.wolde@gmail.com> writes: > From: Xander Pronk <xander.c.pronk@gmail.com> > > Add support for passing the LSC tables from debayerParams to > the shaders. > > Co-authored-by: Rick ten Wolde <rick_libcamera@wolde.info> > Signed-off-by: Rick ten Wolde <rick_libcamera@wolde.info> > Signed-off-by: Xander Pronk <xander.c.pronk@gmail.com> > --- > src/libcamera/software_isp/debayer_egl.cpp | 21 +++++++++++++++++++++ > src/libcamera/software_isp/debayer_egl.h | 9 +++++++++ > 2 files changed, 30 insertions(+) > > diff --git a/src/libcamera/software_isp/debayer_egl.cpp b/src/libcamera/software_isp/debayer_egl.cpp > index 8e089032..0f36b149 100644 > --- a/src/libcamera/software_isp/debayer_egl.cpp > +++ b/src/libcamera/software_isp/debayer_egl.cpp > @@ -111,6 +111,10 @@ int DebayerEGL::getShaderVariableLocations(void) > textureUniformBayerFirstRed_ = glGetUniformLocation(programId_, "tex_bayer_first_red"); > textureUniformProjMatrix_ = glGetUniformLocation(programId_, "proj_matrix"); > > + textureUniformLSCRed_ = glGetUniformLocation(programId_, "lsc_tex_red"); > + textureUniformLSCGreen_ = glGetUniformLocation(programId_, "lsc_tex_green"); > + textureUniformLSCBlue_ = glGetUniformLocation(programId_, "lsc_tex_blue"); > + > LOG(Debayer, Debug) << "vertexIn " << attributeVertex_ << " textureIn " << attributeTexture_ > << " tex_y " << textureUniformBayerDataIn_ > << " ccm " << ccmUniformDataIn_ > @@ -140,6 +144,9 @@ int DebayerEGL::initBayerShaders(PixelFormat inputFormat, PixelFormat outputForm > /* Specify GL_OES_EGL_image_external */ > egl_.pushEnv(shaderEnv, "#extension GL_OES_EGL_image_external: enable"); > > + /* Always use LSC */ > + egl_.pushEnv(shaderEnv, "#define DO_LSC"); I think this should be conditional. For example, what if LSC algorithm is disabled? Or LSC parameters are not available in the tuning file? > + > /* > * Tell shaders how to re-order output taking account of how the > * pixels are actually stored by GBM > @@ -349,6 +356,12 @@ int DebayerEGL::configure(const StreamConfiguration &inputCfg, > */ > stats_->setWindow(Rectangle(window_.size())); > > + eglImageLSCLookupRed_ = new eGLImage(20, 20, sizeof(GLubyte), GL_TEXTURE5, 5); > + eglImageLSCLookupGreen_ = new eGLImage(20, 20, sizeof(GLubyte), GL_TEXTURE5, 5); > + eglImageLSCLookupBlue_ = new eGLImage(20, 20, sizeof(GLubyte), GL_TEXTURE5, 5); > + if (!eglImageLSCLookupRed_ || !eglImageLSCLookupGreen_ || !eglImageLSCLookupBlue_) > + return -ENOMEM; > + > return 0; > } > > @@ -488,6 +501,14 @@ void DebayerEGL::setShaderVariableValues(DebayerParams ¶ms) > glUniformMatrix3fv(ccmUniformDataIn_, 1, GL_FALSE, ccm); > LOG(Debayer, Debug) << " ccmUniformDataIn_ " << ccmUniformDataIn_ << " data " << params.ccm; > > + egl_.createTexture2D(*eglImageLSCLookupRed_, GL_LUMINANCE, 16, 16, ¶ms.LSC_red, GL_LINEAR); > + egl_.createTexture2D(*eglImageLSCLookupBlue_, GL_LUMINANCE, 16, 16, ¶ms.LSC_green, GL_LINEAR); > + egl_.createTexture2D(*eglImageLSCLookupGreen_, GL_LUMINANCE, 16, 16, ¶ms.LSC_blue, GL_LINEAR); > + > + glUniform1i(textureUniformLSCRed_, eglImageLSCLookupRed_->texture_unit_uniform_id_); > + glUniform1i(textureUniformLSCGreen_, eglImageLSCLookupGreen_->texture_unit_uniform_id_); > + glUniform1i(textureUniformLSCBlue_, eglImageLSCLookupBlue_->texture_unit_uniform_id_); > + > /* > * 0 = Red, 1 = Green, 2 = Blue > */ > diff --git a/src/libcamera/software_isp/debayer_egl.h b/src/libcamera/software_isp/debayer_egl.h > index a5033bc6..61feadab 100644 > --- a/src/libcamera/software_isp/debayer_egl.h > +++ b/src/libcamera/software_isp/debayer_egl.h > @@ -85,6 +85,11 @@ private: > std::unique_ptr<eGLImage> eglImageBayerIn_; > std::unique_ptr<eGLImage> eglImageBayerOut_; > > + /* Pointer to object representing input texture */ > + eGLImage *eglImageLSCLookupRed_; > + eGLImage *eglImageLSCLookupBlue_; > + eGLImage *eglImageLSCLookupGreen_; > + > /* Shader parameters */ > float firstRed_x_; > float firstRed_y_; > @@ -98,6 +103,10 @@ private: > > GLint textureUniformBayerDataIn_; > > + GLint textureUniformLSCRed_; > + GLint textureUniformLSCGreen_; > + GLint textureUniformLSCBlue_; > + > /* Represent per-frame CCM as a uniform vector of floats 3 x 3 */ > GLint ccmUniformDataIn_;
On 26/01/2026 10:42, Rick ten Wolde wrote: > From: Xander Pronk <xander.c.pronk@gmail.com> > > Add support for passing the LSC tables from debayerParams to > the shaders. > > Co-authored-by: Rick ten Wolde <rick_libcamera@wolde.info> > Signed-off-by: Rick ten Wolde <rick_libcamera@wolde.info> > Signed-off-by: Xander Pronk <xander.c.pronk@gmail.com> > --- > src/libcamera/software_isp/debayer_egl.cpp | 21 +++++++++++++++++++++ > src/libcamera/software_isp/debayer_egl.h | 9 +++++++++ > 2 files changed, 30 insertions(+) > > diff --git a/src/libcamera/software_isp/debayer_egl.cpp b/src/libcamera/software_isp/debayer_egl.cpp > index 8e089032..0f36b149 100644 > --- a/src/libcamera/software_isp/debayer_egl.cpp > +++ b/src/libcamera/software_isp/debayer_egl.cpp > @@ -111,6 +111,10 @@ int DebayerEGL::getShaderVariableLocations(void) > textureUniformBayerFirstRed_ = glGetUniformLocation(programId_, "tex_bayer_first_red"); > textureUniformProjMatrix_ = glGetUniformLocation(programId_, "proj_matrix"); > > + textureUniformLSCRed_ = glGetUniformLocation(programId_, "lsc_tex_red"); > + textureUniformLSCGreen_ = glGetUniformLocation(programId_, "lsc_tex_green"); > + textureUniformLSCBlue_ = glGetUniformLocation(programId_, "lsc_tex_blue"); > + > LOG(Debayer, Debug) << "vertexIn " << attributeVertex_ << " textureIn " << attributeTexture_ > << " tex_y " << textureUniformBayerDataIn_ > << " ccm " << ccmUniformDataIn_ > @@ -140,6 +144,9 @@ int DebayerEGL::initBayerShaders(PixelFormat inputFormat, PixelFormat outputForm > /* Specify GL_OES_EGL_image_external */ > egl_.pushEnv(shaderEnv, "#extension GL_OES_EGL_image_external: enable"); > > + /* Always use LSC */ > + egl_.pushEnv(shaderEnv, "#define DO_LSC"); > + If you are always doing LSC there's not much point in having it controlled by define. You also need to update qcam -> src/apps/qcam/viewfinder_gl.cpp What happens if I don't have LSC data though ? > /* > * Tell shaders how to re-order output taking account of how the > * pixels are actually stored by GBM > @@ -349,6 +356,12 @@ int DebayerEGL::configure(const StreamConfiguration &inputCfg, > */ > stats_->setWindow(Rectangle(window_.size())); > > + eglImageLSCLookupRed_ = new eGLImage(20, 20, sizeof(GLubyte), GL_TEXTURE5, 5); > + eglImageLSCLookupGreen_ = new eGLImage(20, 20, sizeof(GLubyte), GL_TEXTURE5, 5); > + eglImageLSCLookupBlue_ = new eGLImage(20, 20, sizeof(GLubyte), GL_TEXTURE5, 5); I think this should be be GL_TEXTURE2, 2) GL_TEXTURE3, 3) and GL_TEXTURE4, 4) respectively. In the sampler only one texture can be active with one texture unit at any one time. So the only texture you are really using in the fragment shader is the last bound shader. That's why for these tables, we use a different texture unit for each R, G and B channel. https://gitlab.freedesktop.org/camera/libcamera-softisp/-/blob/v0.5.2-gpuisp-v5a/src/libcamera/software_isp/debayer_egl.cpp?ref_type=heads#L394 Prompt Gemini: "can i create multiple textures on the same texture unit" Ans: "In OpenGL, you can technically bind multiple textures to the same texture unit, but only one can be active and usable by a sampler at any given time. To use multiple textures in a single shader pass, you must bind each texture to a different texture unit (e.g., GL_TEXTURE0, GL_TEXTURE1)" https://www.google.com/search?client=firefox-b-d&q=can+i+create+multiple+textures+on+the+same+texture+unit&zx=1770218257332&no_sw_cr=1#fpstate=ive&vld=cid:763327a7,vid:9cP1w2ykaYc,st:351 > + if (!eglImageLSCLookupRed_ || !eglImageLSCLookupGreen_ || !eglImageLSCLookupBlue_) > + return -ENOMEM; > + > return 0; > } > > @@ -488,6 +501,14 @@ void DebayerEGL::setShaderVariableValues(DebayerParams ¶ms) > glUniformMatrix3fv(ccmUniformDataIn_, 1, GL_FALSE, ccm); > LOG(Debayer, Debug) << " ccmUniformDataIn_ " << ccmUniformDataIn_ << " data " << params.ccm; > > + egl_.createTexture2D(*eglImageLSCLookupRed_, GL_LUMINANCE, 16, 16, ¶ms.LSC_red, GL_LINEAR); > + egl_.createTexture2D(*eglImageLSCLookupBlue_, GL_LUMINANCE, 16, 16, ¶ms.LSC_green, GL_LINEAR); > + egl_.createTexture2D(*eglImageLSCLookupGreen_, GL_LUMINANCE, 16, 16, ¶ms.LSC_blue, GL_LINEAR); > + > + glUniform1i(textureUniformLSCRed_, eglImageLSCLookupRed_->texture_unit_uniform_id_); > + glUniform1i(textureUniformLSCGreen_, eglImageLSCLookupGreen_->texture_unit_uniform_id_); > + glUniform1i(textureUniformLSCBlue_, eglImageLSCLookupBlue_->texture_unit_uniform_id_); > + > /* > * 0 = Red, 1 = Green, 2 = Blue > */ > diff --git a/src/libcamera/software_isp/debayer_egl.h b/src/libcamera/software_isp/debayer_egl.h > index a5033bc6..61feadab 100644 > --- a/src/libcamera/software_isp/debayer_egl.h > +++ b/src/libcamera/software_isp/debayer_egl.h > @@ -85,6 +85,11 @@ private: > std::unique_ptr<eGLImage> eglImageBayerIn_; > std::unique_ptr<eGLImage> eglImageBayerOut_; > > + /* Pointer to object representing input texture */ > + eGLImage *eglImageLSCLookupRed_; > + eGLImage *eglImageLSCLookupBlue_; > + eGLImage *eglImageLSCLookupGreen_; > + > /* Shader parameters */ > float firstRed_x_; > float firstRed_y_; > @@ -98,6 +103,10 @@ private: > > GLint textureUniformBayerDataIn_; > > + GLint textureUniformLSCRed_; > + GLint textureUniformLSCGreen_; > + GLint textureUniformLSCBlue_; > + > /* Represent per-frame CCM as a uniform vector of floats 3 x 3 */ > GLint ccmUniformDataIn_; > > -- > 2.51.0 >
diff --git a/src/libcamera/software_isp/debayer_egl.cpp b/src/libcamera/software_isp/debayer_egl.cpp index 8e089032..0f36b149 100644 --- a/src/libcamera/software_isp/debayer_egl.cpp +++ b/src/libcamera/software_isp/debayer_egl.cpp @@ -111,6 +111,10 @@ int DebayerEGL::getShaderVariableLocations(void) textureUniformBayerFirstRed_ = glGetUniformLocation(programId_, "tex_bayer_first_red"); textureUniformProjMatrix_ = glGetUniformLocation(programId_, "proj_matrix"); + textureUniformLSCRed_ = glGetUniformLocation(programId_, "lsc_tex_red"); + textureUniformLSCGreen_ = glGetUniformLocation(programId_, "lsc_tex_green"); + textureUniformLSCBlue_ = glGetUniformLocation(programId_, "lsc_tex_blue"); + LOG(Debayer, Debug) << "vertexIn " << attributeVertex_ << " textureIn " << attributeTexture_ << " tex_y " << textureUniformBayerDataIn_ << " ccm " << ccmUniformDataIn_ @@ -140,6 +144,9 @@ int DebayerEGL::initBayerShaders(PixelFormat inputFormat, PixelFormat outputForm /* Specify GL_OES_EGL_image_external */ egl_.pushEnv(shaderEnv, "#extension GL_OES_EGL_image_external: enable"); + /* Always use LSC */ + egl_.pushEnv(shaderEnv, "#define DO_LSC"); + /* * Tell shaders how to re-order output taking account of how the * pixels are actually stored by GBM @@ -349,6 +356,12 @@ int DebayerEGL::configure(const StreamConfiguration &inputCfg, */ stats_->setWindow(Rectangle(window_.size())); + eglImageLSCLookupRed_ = new eGLImage(20, 20, sizeof(GLubyte), GL_TEXTURE5, 5); + eglImageLSCLookupGreen_ = new eGLImage(20, 20, sizeof(GLubyte), GL_TEXTURE5, 5); + eglImageLSCLookupBlue_ = new eGLImage(20, 20, sizeof(GLubyte), GL_TEXTURE5, 5); + if (!eglImageLSCLookupRed_ || !eglImageLSCLookupGreen_ || !eglImageLSCLookupBlue_) + return -ENOMEM; + return 0; } @@ -488,6 +501,14 @@ void DebayerEGL::setShaderVariableValues(DebayerParams ¶ms) glUniformMatrix3fv(ccmUniformDataIn_, 1, GL_FALSE, ccm); LOG(Debayer, Debug) << " ccmUniformDataIn_ " << ccmUniformDataIn_ << " data " << params.ccm; + egl_.createTexture2D(*eglImageLSCLookupRed_, GL_LUMINANCE, 16, 16, ¶ms.LSC_red, GL_LINEAR); + egl_.createTexture2D(*eglImageLSCLookupBlue_, GL_LUMINANCE, 16, 16, ¶ms.LSC_green, GL_LINEAR); + egl_.createTexture2D(*eglImageLSCLookupGreen_, GL_LUMINANCE, 16, 16, ¶ms.LSC_blue, GL_LINEAR); + + glUniform1i(textureUniformLSCRed_, eglImageLSCLookupRed_->texture_unit_uniform_id_); + glUniform1i(textureUniformLSCGreen_, eglImageLSCLookupGreen_->texture_unit_uniform_id_); + glUniform1i(textureUniformLSCBlue_, eglImageLSCLookupBlue_->texture_unit_uniform_id_); + /* * 0 = Red, 1 = Green, 2 = Blue */ diff --git a/src/libcamera/software_isp/debayer_egl.h b/src/libcamera/software_isp/debayer_egl.h index a5033bc6..61feadab 100644 --- a/src/libcamera/software_isp/debayer_egl.h +++ b/src/libcamera/software_isp/debayer_egl.h @@ -85,6 +85,11 @@ private: std::unique_ptr<eGLImage> eglImageBayerIn_; std::unique_ptr<eGLImage> eglImageBayerOut_; + /* Pointer to object representing input texture */ + eGLImage *eglImageLSCLookupRed_; + eGLImage *eglImageLSCLookupBlue_; + eGLImage *eglImageLSCLookupGreen_; + /* Shader parameters */ float firstRed_x_; float firstRed_y_; @@ -98,6 +103,10 @@ private: GLint textureUniformBayerDataIn_; + GLint textureUniformLSCRed_; + GLint textureUniformLSCGreen_; + GLint textureUniformLSCBlue_; + /* Represent per-frame CCM as a uniform vector of floats 3 x 3 */ GLint ccmUniformDataIn_;