[v2] libcamera: egl: Fix DRM format for GL_RG dmabuf import
diff mbox series

Message ID 20261022232627.15472-1-faizel.kb@gmail.com
State New
Headers show
Series
  • [v2] libcamera: egl: Fix DRM format for GL_RG dmabuf import
Related show

Commit Message

Faizel K B Oct. 22, 2026, 11:26 p.m. UTC
Importing unpacked 10/12-bit Bayer input buffers (e.g. SGBRG10) as
dmabufs always fails with Mesa, and DebayerEGL falls back to mapping
each input buffer and uploading it with glTexImage2D() on every frame:

  INFO Debayer debayer_egl.cpp:523 Importing input DMABuf failed, falling back to upload

The cause is the DRM format used for GL_RG textures. Unpacked Bayer
pixels are 16-bit little-endian words, loaded into a GL_RG texture with
the low byte in .r and the high byte in .g, which the shaders recombine
into a single sample. R and G here are texture channels, not colours.

When importing a dmabuf with EGL_EXT_image_dma_buf_import, the order of
the samples in memory is taken from the DRM fourcc, which describes the
components of a little-endian word from MSB to LSB:

  DRM_FORMAT_RG88  [15:0] R:G 8:8 little endian  -> byte 0 = G, byte 1 = R
  DRM_FORMAT_GR88  [15:0] G:R 8:8 little endian  -> byte 0 = R, byte 1 = G

The import path maps GL_RG to DRM_FORMAT_RG88, which would place the
low byte in .g instead of .r. Mesa has no RG88 entry in its DRI image
format table, so eglCreateImageKHR() fails before this matters.

Map GL_RG to DRM_FORMAT_GR88, which matches the upload path and is
supported by Mesa. 8-bit and CSI-2 packed input (GL_LUMINANCE) is not
affected.

Fixes: 6e23162ddcae ("egl: Add GL format parameter to eGLImage constructor")
Signed-off-by: Faizel K B <faizel.kb@gmail.com>
Reviewed-by: Robert Mader <robert.mader@collabora.com>
Tested-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com> # ipu6 + ov2740
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Tested-by: Milan Zamazal <mzamazal@redhat.com>
---

Notes:
    Changes in v2:
    - Drop "silently" from the commit message
    - Describe the sample order in terms of EGL_EXT_image_dma_buf_import
    - Drop the incorrect claim that the GL_RGBA output path is not
      affected. GL_RGBA will be addressed separately once the discussion
      on the v1 thread concludes
    - Collect tags
    
    v1: https://patchwork.libcamera.org/patch/28535/
    
    Tested on RK3588 (Mali-G610, Panfrost, Mesa 24.3.4) with an IMX415
    sensor (SGBRG10 unpacked, 3864x2192).
    
    Panfrost requires the row stride of linear dmabuf imports to be
    64-byte aligned. The SGBRG10 stride at 3864 pixels is 7728 bytes, so
    the import also needed a local rkcif change to honour the 256-byte
    aligned stride (7936) that DebayerEGL::preferredInputStride() requests.

 src/libcamera/egl.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Comments

Bryan O'Donoghue Oct. 23, 2026, 1:42 a.m. UTC | #1
On 23/10/2026 00:26, Faizel K B wrote:
> Importing unpacked 10/12-bit Bayer input buffers (e.g. SGBRG10) as
> dmabufs always fails with Mesa, and DebayerEGL falls back to mapping
> each input buffer and uploading it with glTexImage2D() on every frame:
> 
>    INFO Debayer debayer_egl.cpp:523 Importing input DMABuf failed, falling back to upload
> 
> The cause is the DRM format used for GL_RG textures. Unpacked Bayer
> pixels are 16-bit little-endian words, loaded into a GL_RG texture with
> the low byte in .r and the high byte in .g, which the shaders recombine
> into a single sample. R and G here are texture channels, not colours.
> 
> When importing a dmabuf with EGL_EXT_image_dma_buf_import, the order of
> the samples in memory is taken from the DRM fourcc, which describes the
> components of a little-endian word from MSB to LSB:
> 
>    DRM_FORMAT_RG88  [15:0] R:G 8:8 little endian  -> byte 0 = G, byte 1 = R
>    DRM_FORMAT_GR88  [15:0] G:R 8:8 little endian  -> byte 0 = R, byte 1 = G
> 
> The import path maps GL_RG to DRM_FORMAT_RG88, which would place the
> low byte in .g instead of .r. Mesa has no RG88 entry in its DRI image
> format table, so eglCreateImageKHR() fails before this matters.
> 
> Map GL_RG to DRM_FORMAT_GR88, which matches the upload path and is
> supported by Mesa. 8-bit and CSI-2 packed input (GL_LUMINANCE) is not
> affected.
> 
> Fixes: 6e23162ddcae ("egl: Add GL format parameter to eGLImage constructor")
> Signed-off-by: Faizel K B <faizel.kb@gmail.com>
> Reviewed-by: Robert Mader <robert.mader@collabora.com>
> Tested-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com> # ipu6 + ov2740
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Tested-by: Milan Zamazal <mzamazal@redhat.com>
> ---
> 
> Notes:
>      Changes in v2:
>      - Drop "silently" from the commit message
>      - Describe the sample order in terms of EGL_EXT_image_dma_buf_import
>      - Drop the incorrect claim that the GL_RGBA output path is not
>        affected. GL_RGBA will be addressed separately once the discussion
>        on the v1 thread concludes
>      - Collect tags
>      
>      v1: https://patchwork.libcamera.org/patch/28535/
>      
>      Tested on RK3588 (Mali-G610, Panfrost, Mesa 24.3.4) with an IMX415
>      sensor (SGBRG10 unpacked, 3864x2192).
>      
>      Panfrost requires the row stride of linear dmabuf imports to be
>      64-byte aligned. The SGBRG10 stride at 3864 pixels is 7728 bytes, so
>      the import also needed a local rkcif change to honour the 256-byte
>      aligned stride (7936) that DebayerEGL::preferredInputStride() requests.
> 
>   src/libcamera/egl.cpp | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/src/libcamera/egl.cpp b/src/libcamera/egl.cpp
> index b3d3b9abb..ff9e54a19 100644
> --- a/src/libcamera/egl.cpp
> +++ b/src/libcamera/egl.cpp
> @@ -184,7 +184,7 @@ int eGL::createDMABufTexture2D(eGLImage &eglImage, int fd, bool output)
>   		drm_format = DRM_FORMAT_R8;
>   		break;
>   	case GL_RG:
> -		drm_format = DRM_FORMAT_RG88;
> +		drm_format = DRM_FORMAT_GR88;
>   		break;
>   	case GL_RGBA:
>   		drm_format = DRM_FORMAT_ARGB8888;
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>

Patch
diff mbox series

diff --git a/src/libcamera/egl.cpp b/src/libcamera/egl.cpp
index b3d3b9abb..ff9e54a19 100644
--- a/src/libcamera/egl.cpp
+++ b/src/libcamera/egl.cpp
@@ -184,7 +184,7 @@  int eGL::createDMABufTexture2D(eGLImage &eglImage, int fd, bool output)
 		drm_format = DRM_FORMAT_R8;
 		break;
 	case GL_RG:
-		drm_format = DRM_FORMAT_RG88;
+		drm_format = DRM_FORMAT_GR88;
 		break;
 	case GL_RGBA:
 		drm_format = DRM_FORMAT_ARGB8888;