# bugreports.qt.io issue draft **Project**: QtBase **Component**: OpenGL **Affects Version/s**: 6.5, 6.6, 6.7, 6.8, 6.9, 6.10, 6.11, 6.12-dev **Severity**: Significant — affects every Qt 6 GLES3 client on Mali-class hardware **Type**: Bug --- ## Summary `QOpenGLTextureGlyphCache`, `QRhiGles2::toGlTextureFormat` (`RED_OR_ALPHA8` case), and `QOpenGLTextureUploader` (`Format_Alpha8` and `Format_Grayscale8` cases) all hard-code `GL_ALPHA` (and `GL_LUMINANCE`) as the `glTexImage2D` `internalFormat` when qtbase is configured with `QT_CONFIG(opengles2)` (true on every aarch64 Linux distribution shipping Qt 6). `GL_ALPHA` was deprecated as a valid `glTexImage2D` `internalFormat` in OpenGL ES 3.0 (ES 3.0 spec, section 3.8.3, table 3.13 — only sized internal formats remain). On Mali-class GPUs (mesa panfrost / panthor) under Wayland, KWin requests an OpenGL ES 3.2 context. Qt's text-glyph cache upload path then runs the `#else` branch with `GL_ALPHA`, mesa returns `GL_INVALID_VALUE`, the texture allocation never succeeds, and every subsequent `glTexSubImage2D` to that texture errors at level 0. KWin's `glDebugMessageCallback` fills the journal with: ``` kwin_wayland: 0x4: GL_INVALID_VALUE in glTexImage2D(internalFormat=GL_ALPHA) kwin_wayland: 0x4: GL_INVALID_OPERATION in glTexSubImage2D(invalid texture level 0) × N ``` …on every text-glyph cache invalidation, every frame, indefinitely. ## Reproduce - Hardware: any Mali-G31 / G52 / G57 / G610 with mesa panfrost or panthor on Linux (RK3399 / RK3566 / RK3588 board, Pinebook Pro, PineTab2, CoolPi 4 etc.). - Software stack: KDE Plasma 6.x Wayland + Qt 6.x built against this hardware (any Arch Linux ARM, Debian arm64, Ubuntu arm64 with Plasma). - Trigger: open any Qt 6 application that renders text and watch `journalctl --user -u plasma-kwin_wayland.service` (or equivalent) for the `glTexImage2D(internalFormat=GL_ALPHA)` line. Examples that trigger reliably: - `kate` opening any text file - `dolphin` listing a directory - any system tray icon update - any window decoration title-bar redraw ## Root cause Three sites in qtbase 6.x: 1. `src/opengl/qopengltextureglyphcache.cpp:111-117` — `createTextureData()` hard-codes `internalFormat = GL_ALPHA` in the `QT_CONFIG(opengles2)` branch. 2. `src/opengl/qopengltextureglyphcache.cpp:213-217` — `load_glyph_image_to_texture()` matching path on glyph reupload. 3. `src/gui/rhi/qrhigles2.cpp:1373-1378` — `QRhiGles2::toGlTextureFormat` `RED_OR_ALPHA8` case is gated only on `caps.coreProfile`, missing the ES≥3 disjunct. 4. `src/opengl/qopengltextureuploader.cpp:253-275` — `Format_Alpha8` and `Format_Grayscale8` short-circuit on `context->isOpenGLES()` before reaching the existing `TextureSwizzle` fallback. ## Fix Three patches (attached as a series), one per file. Each adds a runtime predicate (variations on `caps.gles && caps.ctxMajor >= 3` or `ctx->format().majorVersion() >= 3`) so: - desktop GL Core profile → `GL_R8` + `GL_RED` (existing behavior) - desktop GL Compat profile → `GL_ALPHA` (existing behavior) - **OpenGL ES 3.x → `GL_R8` + `GL_RED`** (new behavior; spec-clean) - OpenGL ES 2.x → `GL_ALPHA` (preserved) Memory layout, swizzle, and shader behavior identical to the existing core-profile path. No new dependencies. ~9 net lines added across three files. ## Validation Tested on PineTab2 (RK3566 / Mali-G52 / mainline kernel 6.19.10 / panfrost mesa 26.0.5 / KDE Plasma 6.6.4 Wayland / Qt 6.11.0 patched). Before the patches: constant journal stream of `GL_INVALID_VALUE` during normal desktop interaction. After the patches: zero `GL_INVALID_VALUE` in a fresh-session journal, including under heavy text-rendering load. Patch series and end-to-end validation context maintained at https://github.com/marfrit/fourier under `qt6-base-fourier/`. ## Patch series (Three patches will be uploaded in Gerrit format as a single series with a common Change-Id thread.) 1. `[PATCH 1/3] QOpenGLTextureGlyphCache: pick GL_R8 on OpenGL ES 3.x` 2. `[PATCH 2/3] QRhiGles2: use GL_R8 for RED_OR_ALPHA8 on OpenGL ES 3.x` 3. `[PATCH 3/3] QOpenGLTextureUploader: route ES 3.x through TextureSwizzle path` --- # Gerrit submission notes (Per Qt's contribution workflow — https://wiki.qt.io/Qt_Contribution_Guidelines) ## Account setup (one-time) 1. Create account at https://account.qt.io 2. Sign Qt's CLA (electronic, takes 5 minutes) 3. Configure SSH key at https://codereview.qt-project.org 4. Install `git-review`: `pacman -S git-review` (Arch) or `pip install git-review` ## Per-patch commit-message trailers Each patch needs Qt-style trailers below the `Signed-off-by`: ``` Bug: QTBUG-XXXXX Pick-to: 6.10 6.9 6.8 6.7 6.6 6.5 Change-Id: ``` `Bug:` is the issue number from bugreports.qt.io (the issue above, once filed). `Pick-to:` requests cherry-picks to LTS branches — this fix should backport cleanly to 6.5 (the oldest currently- supported Qt 6 LTS). `Change-Id:` is auto-generated by `git-review`'s commit-msg hook on first push. ## Push to Gerrit ```sh cd qtbase # Apply our 3 patches with `git am`, then: git review master # pushes branch to refs/for/dev ``` ## Reviewers to add - Eskil Abrahamsen Blomfeldt — primary glyph-cache reviewer - Laszlo Agocs — RHI reviewer - Volker Hilsheimer — QtGui maintainer