Skip to content

fix(shaders): improve compatibility with older Adreno and Mesa GLSL compilers - #115

Open
mrrobot97 wants to merge 2 commits into
rive-app:mainfrom
mrrobot97:codex/fix-android-adreno-path-shaders
Open

fix(shaders): improve compatibility with older Adreno and Mesa GLSL compilers#115
mrrobot97 wants to merge 2 commits into
rive-app:mainfrom
mrrobot97:codex/fix-android-adreno-path-shaders

Conversation

@mrrobot97

@mrrobot97 mrrobot97 commented Jul 23, 2026

Copy link
Copy Markdown

Summary

This PR contains two independent Android/OpenGL shader compatibility fixes, kept as separate commits:

  1. Adreno path-shader fix
    Emit swizzle_image_buffer_idx only for storage-buffer PLS and clockwise-atomic shader variants. This keeps its unused unsigned shifts out of unrelated path shaders that older Adreno GLSL compilers can silently miscompile.

  2. Mesa minifier fix
    Preserve a token separator when a closing parenthesis is immediately followed by an identifier. This prevents older Mesa preprocessors from merging the final token of a function-like macro expansion with the following identifier.

These fixes address different driver failures and do not depend on device-model checks or runtime allowlists.

Problem 1: silent path-shader miscompile on older Adreno

After the storage-buffer PLS work in 365421d6, swizzle_image_buffer_idx became part of every path shader, even when it was unused.

On Android 8.1 with an Adreno 616, the older GLSL compiler silently miscompiles non-atomic path shaders containing the helper's unused unsigned shifts. Filled and stroked vector paths disappear, while image meshes continue to render.

The regression was bisected to:

  • runtime-v0.1.118: renders correctly
  • runtime-v0.1.119: first broken release
  • first bad commit: 365421d6177757772a911f176241af8ea6d5e64e

The helper is required by PLS_IMPL_STORAGE_BUFFER. Clockwise-atomic variants also contained the previous swizzle helper before that commit. Restricting it to those two configurations restores the previous shader contents for unrelated path variants while preserving its required uses.

Problem 2: macro-token merge on older Mesa

The GLSL minifier previously removed whitespace between a closing parenthesis and a following identifier. That is normally safe because the preprocessor operates on tokens, but Mesa 20.3.4 under virgl can incorrectly merge the final token of a function-like macro expansion with the following identifier.

For example:

#define OUT(TYPE) out TYPE
OUT(vec2)v_position;

A conforming preprocessor treats the declaration as:

out vec2 v_position;

On the affected Mesa compiler, the minified form can instead be interpreted as if it contained vec2v_position, producing an unexpected NEW_IDENTIFIER shader compilation error.

The second commit makes the minifier emit:

OUT(vec2) v_position;

This preserves the intended token boundary. It adds only semantically redundant whitespace for conforming compilers and does not change shader logic.

Reproduction

A small static .riv artboard is sufficient. It should contain:

  • several visible filled or stroked vector paths;
  • optionally, an image mesh alongside those paths to make the failure easier to identify.

A state machine is not required.

With the Rive GPU renderer:

  • on the affected Adreno compiler, image meshes remain visible while some or all vector paths disappear due to a silent shader miscompile;
  • on the affected Mesa/virgl compiler, the generated path shader fails to compile and the rendered artboard is incomplete.

The Android Canvas renderer can be used as a control because it does not use these GLSL path shaders.

The Mesa preprocessing failure can also be reproduced independently with the minimal function-like macro example above; no .riv asset is needed for that compiler-level reproduction.

Validation

  • A/B tested the Adreno fix on Android 8.1 / Adreno 616:
    • the unguarded Rive renderer loses vector paths;
    • the guarded version restores the complete result and matches the Canvas control.
  • Reproduced the Mesa failure on Android 12 / Mesa 20.3.4 / virgl:
    • the old minified shader fails with unexpected NEW_IDENTIFIER;
    • preserving the separator allows the shader to compile and restores the complete artboard.
  • Verified both fixes together against Rive Android 11.7.2 / runtime-v0.1.169.
  • Regenerated the complete shader set (106 generated artifacts).
  • Compiled all 147 SPIR-V shader variants successfully.

Automated visual coverage for the Adreno failure is not practical because it is a silent device-driver miscompile. The Mesa change is isolated to token separation in generated GLSL and does not alter shader semantics.

Some older Adreno GLSL compilers silently miscompile non-atomic path shaders when they contain the unused unsigned shifts in swizzle_image_buffer_idx.

Restrict the helper to storage-buffer PLS and clockwise-atomic variants. This preserves its WebGPU use and the previous atomic shader behavior while keeping it out of unrelated path shaders.
@mrrobot97 mrrobot97 changed the title fix(shaders): avoid unused swizzle helper on older Adreno fix(shaders): improve compatibility with older Adreno and Mesa GLSL compilers Aug 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants