[v6,06/24] libcamera: shaders: Extend debayer shaders to apply RGB gain values on output
diff mbox series

Message ID 20251202134544.662446-7-bryan.odonoghue@linaro.org
State New
Headers show
Series
  • Add GLES 2.0 GPUISP to libcamera
Related show

Commit Message

Bryan O'Donoghue Dec. 2, 2025, 1:45 p.m. UTC
Extend out the bayer fragment shaders to take 3 x 256 byte inputs as
textures from the CPU.

We then use an index to the table to recover the colour-corrected values
provided by the SoftIPA thread.

Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
---
 src/libcamera/shaders/bayer_1x_packed.frag | 45 +++++++++++++++++++
 src/libcamera/shaders/bayer_unpacked.frag  | 51 +++++++++++++++++++++-
 2 files changed, 95 insertions(+), 1 deletion(-)

Patch
diff mbox series

diff --git a/src/libcamera/shaders/bayer_1x_packed.frag b/src/libcamera/shaders/bayer_1x_packed.frag
index 19b13ad08..171a928c2 100644
--- a/src/libcamera/shaders/bayer_1x_packed.frag
+++ b/src/libcamera/shaders/bayer_1x_packed.frag
@@ -65,6 +65,7 @@  uniform vec2 tex_step;
 uniform vec2 tex_bayer_first_red;
 
 uniform sampler2D tex_y;
+uniform mat3 ccm;
 
 void main(void)
 {
@@ -212,5 +213,49 @@  void main(void)
 			vec3(patterns.y, C, patterns.x) :
 			vec3(patterns.wz, C));
 
+	/*
+	 *   CCM is a 3x3 in the format
+	 *
+	 *   +--------------+----------------+---------------+
+	 *   | RedRedGain   | RedGreenGain   | RedBlueGain   |
+	 *   +--------------+----------------+---------------+
+	 *   | GreenRedGain | GreenGreenGain | GreenBlueGain |
+	 *   +--------------+----------------+---------------+
+	 *   | BlueRedGain  |  BlueGreenGain | BlueBlueGain  |
+	 *   +--------------+----------------+---------------+
+	 *
+	 *   Rout = RedRedGain * Rin + RedGreenGain * Gin + RedBlueGain * Bin
+	 *   Gout = GreenRedGain * Rin + GreenGreenGain * Gin + GreenBlueGain * Bin
+	 *   Bout = BlueRedGain * Rin + BlueGreenGain * Gin + BlueBlueGain * Bin
+	 *
+	 *   We upload to the GPU without transposition glUniformMatrix3f(.., .., GL_FALSE, ccm);
+	 *
+	 *   CPU
+	 *   float ccm [] = {
+	 *             RedRedGain,   RedGreenGain,   RedBlueGain,
+	 *             GreenRedGain, GreenGreenGain, GreenBlueGain,
+	 *             BlueRedGain,  BlueGreenGain,  BlueBlueGain,
+	 *   };
+	 *
+	 *   GPU
+	 *   ccm = {
+	 *             RedRedGain,   GreenRedGain,   BlueRedGain,
+	 *             RedGreenGain, GreenGreenGain, BlueGreenGain,
+	 *             RedBlueGain,  GreenBlueGain,  BlueBlueGain,
+	 *   }
+	 *
+	 *   However the indexing for the mat data-type is column major hence
+	 *   ccm[0][0] = RedRedGain, ccm[0][1] = RedGreenGain, ccm[0][2] = RedBlueGain
+	 *
+	 */
+	float rin, gin, bin;
+	rin = rgb.r;
+	gin = rgb.g;
+	bin = rgb.b;
+
+	rgb.r = (rin * ccm[0][0]) + (gin * ccm[0][1]) + (bin * ccm[0][2]);
+	rgb.g = (rin * ccm[1][0]) + (gin * ccm[1][1]) + (bin * ccm[1][2]);
+	rgb.b = (rin * ccm[2][0]) + (gin * ccm[2][1]) + (bin * ccm[2][2]);
+
 	gl_FragColor = vec4(rgb, 1.0);
 }
diff --git a/src/libcamera/shaders/bayer_unpacked.frag b/src/libcamera/shaders/bayer_unpacked.frag
index aa7a1b004..c41d72f4f 100644
--- a/src/libcamera/shaders/bayer_unpacked.frag
+++ b/src/libcamera/shaders/bayer_unpacked.frag
@@ -24,8 +24,11 @@  uniform sampler2D       tex_y;
 varying vec4            center;
 varying vec4            yCoord;
 varying vec4            xCoord;
+uniform mat3            ccm;
 
 void main(void) {
+    vec3 rgb;
+
     #define fetch(x, y) texture2D(tex_y, vec2(x, y)).r
 
     float C = texture2D(tex_y, center.xy).r; // ( 0, 0)
@@ -97,11 +100,57 @@  void main(void) {
     PATTERN.xw  += kB.xw * B;
     PATTERN.xz  += kF.xz * F;
 
-    gl_FragColor.rgb = (alternate.y == 0.0) ?
+    rgb =  (alternate.y == 0.0) ?
         ((alternate.x == 0.0) ?
             vec3(C, PATTERN.xy) :
             vec3(PATTERN.z, C, PATTERN.w)) :
         ((alternate.x == 0.0) ?
             vec3(PATTERN.w, C, PATTERN.z) :
             vec3(PATTERN.yx, C));
+
+    /*
+     *   CCM is a 3x3 in the format
+     *
+     *   +--------------+----------------+---------------+
+     *   | RedRedGain   | RedGreenGain   | RedBlueGain   |
+     *   +--------------+----------------+---------------+
+     *   | GreenRedGain | GreenGreenGain | GreenBlueGain |
+     *   +--------------+----------------+---------------+
+     *   | BlueRedGain  |  BlueGreenGain | BlueBlueGain  |
+     *   +--------------+----------------+---------------+
+     *
+     *   Rout = RedRedGain * Rin + RedGreenGain * Gin + RedBlueGain * Bin
+     *   Gout = GreenRedGain * Rin + GreenGreenGain * Gin + GreenBlueGain * Bin
+     *   Bout = BlueRedGain * Rin + BlueGreenGain * Gin + BlueBlueGain * Bin
+     *
+     *   We upload to the GPU without transposition glUniformMatrix3f(.., .., GL_FALSE, ccm);
+     *
+     *   CPU
+     *   float ccm [] = {
+     *             RedRedGain,   RedGreenGain,   RedBlueGain,
+     *             GreenRedGain, GreenGreenGain, GreenBlueGain,
+     *             BlueRedGain,  BlueGreenGain,  BlueBlueGain,
+     *   };
+     *
+     *   GPU
+     *   ccm = {
+     *             RedRedGain,   GreenRedGain,   BlueRedGain,
+     *             RedGreenGain, GreenGreenGain, BlueGreenGain,
+     *             RedBlueGain,  GreenBlueGain,  BlueBlueGain,
+     *   }
+     *
+     *   However the indexing for the mat data-type is column major hence
+     *   ccm[0][0] = RedRedGain, ccm[0][1] = RedGreenGain, ccm[0][2] = RedBlueGain
+     *
+     */
+    float rin, gin, bin;
+    rin = rgb.r;
+    gin = rgb.g;
+    bin = rgb.b;
+
+    rgb.r = (rin * ccm[0][0]) + (gin * ccm[0][1]) + (bin * ccm[0][2]);
+    rgb.g = (rin * ccm[1][0]) + (gin * ccm[1][1]) + (bin * ccm[1][2]);
+    rgb.b = (rin * ccm[2][0]) + (gin * ccm[2][1]) + (bin * ccm[2][2]);
+
+    gl_FragColor.rgb = rgb;
 }