[{"id":39076,"web_url":"https://patchwork.libcamera.org/comment/39076/","msgid":"<bfe75abb-ab24-41cb-9386-5835da8a0911@ideasonboard.com>","date":"2026-06-15T14:29:44","subject":"Re: [PATCH 03/11] softisp: Split AWB from Combined Matrix","submitter":{"id":216,"url":"https://patchwork.libcamera.org/api/people/216/","name":"Barnabás Pőcze","email":"barnabas.pocze@ideasonboard.com"},"content":"Hi\n\n2026. 06. 15. 16:05 keltezéssel, Jacopo Mondi írta:\n> From: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> \n> Move the AWB gains out of the combined matrix and pass\n> them directly to the EGL shaders.\n\nIt would be nice to have some explanation as to why\nthis is desirable/needed, what issue it solves (if any), etc.\n\n\n> \n> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>\n> ---\n>   src/ipa/simple/algorithms/awb.cpp          | 16 +++-------------\n>   src/ipa/simple/ipa_context.h               |  5 +----\n>   src/libcamera/shaders/bayer_1x_packed.frag |  4 ++++\n>   src/libcamera/shaders/bayer_unpacked.frag  |  4 ++++\n>   src/libcamera/software_isp/debayer_egl.cpp |  5 +++++\n>   src/libcamera/software_isp/debayer_egl.h   |  3 +++\n>   6 files changed, 20 insertions(+), 17 deletions(-)\n> \n> diff --git a/src/ipa/simple/algorithms/awb.cpp b/src/ipa/simple/algorithms/awb.cpp\n> index f5c88ea6f896..05155c83d172 100644\n> --- a/src/ipa/simple/algorithms/awb.cpp\n> +++ b/src/ipa/simple/algorithms/awb.cpp\n> @@ -38,15 +38,8 @@ void Awb::prepare(IPAContext &context,\n>   \t\t  DebayerParams *params)\n>   {\n>   \tauto &gains = context.activeState.awb.gains;\n> -\tMatrix<float, 3, 3> gainMatrix = { { gains.r(), 0, 0,\n> -\t\t\t\t\t     0, gains.g(), 0,\n> -\t\t\t\t\t     0, 0, gains.b() } };\n> -\tcontext.activeState.combinedMatrix =\n> -\t\tgainMatrix * context.activeState.combinedMatrix;\n> -\n> -\tframeContext.gains.red = gains.r();\n> -\tframeContext.gains.blue = gains.b();\n>   \n> +\tframeContext.gains = gains;\n>   \tparams->gains = gains;\n>   }\n>   \n> @@ -59,11 +52,8 @@ void Awb::process(IPAContext &context,\n>   \tconst SwIspStats::Histogram &histogram = stats->yHistogram;\n>   \tconst uint8_t blackLevel = context.activeState.blc.level;\n>   \n> -\tconst float mdGains[] = {\n> -\t\tstatic_cast<float>(frameContext.gains.red),\n> -\t\tstatic_cast<float>(frameContext.gains.blue)\n> -\t};\n> -\tmetadata.set(controls::ColourGains, mdGains);\n> +\tmetadata.set(controls::ColourGains, { frameContext.gains.r(),\n> +\t\t\t\t\t      frameContext.gains.b() });\n>   \n>   \tif (!stats->valid)\n>   \t\treturn;\n> diff --git a/src/ipa/simple/ipa_context.h b/src/ipa/simple/ipa_context.h\n> index 34f7403a41d6..8ccfacb46a59 100644\n> --- a/src/ipa/simple/ipa_context.h\n> +++ b/src/ipa/simple/ipa_context.h\n> @@ -71,10 +71,7 @@ struct IPAFrameContext : public FrameContext {\n>   \t\tdouble gain;\n>   \t} sensor;\n>   \n> -\tstruct {\n> -\t\tdouble red;\n> -\t\tdouble blue;\n> -\t} gains;\n> +\tRGB<float> gains;\n>   \n>   \tfloat gamma;\n>   \tstd::optional<float> contrast;\n> diff --git a/src/libcamera/shaders/bayer_1x_packed.frag b/src/libcamera/shaders/bayer_1x_packed.frag\n> index 23747f78a631..9a1992e219dd 100644\n> --- a/src/libcamera/shaders/bayer_1x_packed.frag\n> +++ b/src/libcamera/shaders/bayer_1x_packed.frag\n> @@ -65,6 +65,7 @@ uniform vec2 tex_step;\n>   uniform vec2 tex_bayer_first_red;\n>   \n>   uniform sampler2D tex_y;\n> +uniform vec3 awb;\n>   uniform mat3 ccm;\n>   uniform vec3 blacklevel;\n>   uniform float gamma;\n> @@ -227,6 +228,9 @@ void main(void)\n>   \n>   \trgb = rgb - blacklevel;\n>   \n> +\t/* Apply AWB gains, and saturate each channel at sensor range */\n> +\trgb = clamp(rgb * awb, vec3(0.0), vec3(1.0) - blacklevel);\n> +\n>   \t/*\n>   \t *   CCM is a 3x3 in the format\n>   \t *\n> diff --git a/src/libcamera/shaders/bayer_unpacked.frag b/src/libcamera/shaders/bayer_unpacked.frag\n> index 1b85196ae161..2def33c82c8e 100644\n> --- a/src/libcamera/shaders/bayer_unpacked.frag\n> +++ b/src/libcamera/shaders/bayer_unpacked.frag\n> @@ -24,6 +24,7 @@ uniform sampler2D       tex_y;\n>   varying vec4            center;\n>   varying vec4            yCoord;\n>   varying vec4            xCoord;\n> +uniform vec3            awb;\n>   uniform mat3            ccm;\n>   uniform vec3            blacklevel;\n>   uniform float           gamma;\n> @@ -130,6 +131,9 @@ void main(void) {\n>   \n>       rgb = rgb - blacklevel;\n>   \n> +    /* Apply AWB gains, and saturate each channel at sensor range */\n> +    rgb = clamp(rgb * awb, vec3(0.0), vec3(1.0) - blacklevel);\n> +\n>       /*\n>        *   CCM is a 3x3 in the format\n>        *\n> diff --git a/src/libcamera/software_isp/debayer_egl.cpp b/src/libcamera/software_isp/debayer_egl.cpp\n> index fd8de3942aa3..227f698a1fac 100644\n> --- a/src/libcamera/software_isp/debayer_egl.cpp\n> +++ b/src/libcamera/software_isp/debayer_egl.cpp\n> @@ -115,6 +115,7 @@ int DebayerEGL::getShaderVariableLocations(void)\n>   \tattributeTexture_ = glGetAttribLocation(programId_, \"textureIn\");\n>   \n>   \ttextureUniformBayerDataIn_ = glGetUniformLocation(programId_, \"tex_y\");\n> +\tawbUniformDataIn_ = glGetUniformLocation(programId_, \"awb\");\n>   \tccmUniformDataIn_ = glGetUniformLocation(programId_, \"ccm\");\n>   \tblackLevelUniformDataIn_ = glGetUniformLocation(programId_, \"blacklevel\");\n>   \tgammaUniformDataIn_ = glGetUniformLocation(programId_, \"gamma\");\n> @@ -128,6 +129,7 @@ int DebayerEGL::getShaderVariableLocations(void)\n>   \n>   \tLOG(Debayer, Debug) << \"vertexIn \" << attributeVertex_ << \" textureIn \" << attributeTexture_\n>   \t\t\t    << \" tex_y \" << textureUniformBayerDataIn_\n> +\t\t\t    << \" awb \" << awbUniformDataIn_\n>   \t\t\t    << \" ccm \" << ccmUniformDataIn_\n>   \t\t\t    << \" blacklevel \" << blackLevelUniformDataIn_\n>   \t\t\t    << \" gamma \" << gammaUniformDataIn_\n> @@ -502,6 +504,9 @@ void DebayerEGL::setShaderVariableValues(const DebayerParams &params)\n>   \tglUniform3f(blackLevelUniformDataIn_, params.blackLevel[0], params.blackLevel[1], params.blackLevel[2]);\n>   \tLOG(Debayer, Debug) << \" blackLevelUniformDataIn_ \" << blackLevelUniformDataIn_ << \" data \" << params.blackLevel;\n>   \n> +\tglUniform3f(awbUniformDataIn_, params.gains[0], params.gains[1], params.gains[2]);\n> +\tLOG(Debayer, Debug) << \" awbUniformDataIn_ \" << awbUniformDataIn_ << \" data \" << params.gains;\n> +\n>   \t/*\n>   \t * Gamma\n>   \t */\n> diff --git a/src/libcamera/software_isp/debayer_egl.h b/src/libcamera/software_isp/debayer_egl.h\n> index 943410fdd1fc..43038b45a109 100644\n> --- a/src/libcamera/software_isp/debayer_egl.h\n> +++ b/src/libcamera/software_isp/debayer_egl.h\n> @@ -90,6 +90,9 @@ private:\n>   \n>   \tGLint textureUniformBayerDataIn_;\n>   \n> +\t/* Per-frame AWB gains */\n> +\tGLint awbUniformDataIn_;\n> +\n>   \t/* Represent per-frame CCM as a uniform vector of floats 3 x 3 */\n>   \tGLint ccmUniformDataIn_;\n>   \n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 58D77C328C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 15 Jun 2026 14:29:51 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 3770B623E6;\n\tMon, 15 Jun 2026 16:29:50 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 0E0D9623E1\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 15 Jun 2026 16:29:49 +0200 (CEST)","from [192.168.33.26] (185.221.142.169.nat.pool.zt.hu\n\t[185.221.142.169])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id A6D85227;\n\tMon, 15 Jun 2026 16:29:15 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"fGtGTWKf\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1781533755;\n\tbh=R5Bu0+c4rTRgkV2GU3KnBiUxgMfYThszFOoW0LW/lNA=;\n\th=Date:Subject:To:References:From:In-Reply-To:From;\n\tb=fGtGTWKflg0eYpcBdiHRrgccLo19OS5VTtKYwIO8Q1UVkN/joKlXCalvuxmQg5+Wh\n\t+G1RFulOvL1H5dsSDy09Nt4TDYUH4ruytrmj4wYriAYvoO395ESMpjjcjx3z07327G\n\tsQnTIjeyYCaQMGO7T5MQWxlXbScJNls7QyO75bjY=","Message-ID":"<bfe75abb-ab24-41cb-9386-5835da8a0911@ideasonboard.com>","Date":"Mon, 15 Jun 2026 16:29:44 +0200","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH 03/11] softisp: Split AWB from Combined Matrix","To":"Jacopo Mondi <jacopo.mondi@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org,\n\tKieran Bingham <kieran.bingham@ideasonboard.com>","References":"<20260615-libipa-algorithms-v1-0-e949c937422e@ideasonboard.com>\n\t<20260615-libipa-algorithms-v1-3-e949c937422e@ideasonboard.com>","From":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>","Content-Language":"en-US, hu-HU","In-Reply-To":"<20260615-libipa-algorithms-v1-3-e949c937422e@ideasonboard.com>","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"8bit","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]