@@ -546,6 +546,9 @@ void ViewFinderGL::doRender()
/* Stride of the first plane, in pixels. */
unsigned int stridePixels;
+ /* Whether the raw Bayer format is unpacked. */
+ bool unpacked = false;
+
/* Identity CCM */
float ccm[] = { 1.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f,
@@ -763,6 +766,8 @@ void ViewFinderGL::doRender()
case libcamera::formats::SGBRG8:
case libcamera::formats::SGRBG8:
case libcamera::formats::SRGGB8:
+ unpacked = true;
+ [[fallthrough]];
case libcamera::formats::SBGGR10_CSI2P:
case libcamera::formats::SGBRG10_CSI2P:
case libcamera::formats::SGRBG10_CSI2P:
@@ -798,10 +803,10 @@ void ViewFinderGL::doRender()
1.0f / (size_.height() - 1));
/*
- * The stride is already taken into account in the shaders, set
- * the generic stride factor to 1.0.
+ * The packed shaders handle the stride themselves through
+ * tex_step; only the unpacked shaders need the stride factor.
*/
- stridePixels = size_.width();
+ stridePixels = unpacked ? stride_ : size_.width();
/* Colour Correction Matrix */
shaderProgram_.setUniformValue(ccmUniformDataIn_, qCcmMat);
The unpacked Bayer formats upload the frame to a GL_LUMINANCE texture whose width is the stride, but compute the generic stride factor from stridePixels = width, yielding 1.0. The bayer_unpacked shaders then stretch the full stride width across the image width whenever stride != width. Commit 5b609e7a44f1 ("libcamera: shaders: Fix input sampling when width != stride") makes the equivalent correction for the software ISP GPU debayer path. Compute the stride factor from the texture width for the unpacked formats. The packed formats keep stridePixels = width: their fragment shader samples in byte units and handles the stride via tex_step. Compile-tested only. No 8-bit Bayer source was available to exercise qcam's unpacked raw path. Assisted by Claude Code (claude-fable-5). Signed-off-by: Christian Murphy <christian@themurphys.eu> --- src/apps/qcam/viewfinder_gl.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)