[Impeller] Canonicalize uniform block instance names for the GL backends#186394
Conversation
There was a problem hiding this comment.
Code Review
This pull request implements uniform block instance name canonicalization for OpenGL targets within the Impeller compiler. By renaming non-conforming instance variables to a canonical form, it ensures that uniform block members are correctly resolved on backends that use case- and underscore-insensitive matching. The changes include a new normalization helper function, the integration of the canonicalization logic into the compiler workflow, and a corresponding unit test. Feedback was provided regarding the use of std::toupper, suggesting a locale-independent implementation to avoid potential inconsistencies and undefined behavior.
OpenGL targets older than #version 140 (the kOpenGLES ESSL 1.00 output
and the kOpenGLDesktop GLSL 1.20 output) have no uniform buffer objects,
so SPIRV-Cross lowers `uniform Block { ... } instance;` to
`struct Block { ... }; uniform Block instance;`, and the driver reports
the members as `instance.member`. BufferBindingsGLES resolves those
members by the *block* name carried in shader reflection (and exposed to
Flutter GPU callers as e.g. getUniformSlot("Block")), reaching them
through a case-insensitive, underscore-insensitive normalization. That
match only succeeds when the instance name normalizes to the block name.
Impeller's own shaders follow the `uniform XInfo { ... } x_info;`
convention and satisfy it, but a caller-authored Flutter GPU shader
bundle need not (e.g. `uniform ToonInfo { ... } toon;`), in which case
every member of the block resolves to GL location -1 and is silently
skipped; the shader then reads zeros for all of those uniforms.
Rewrite any non-conforming uniform block instance variable to a
canonical, collision-free form (`_<BlockName>`, which reduces to the
block name under the same normalization and cannot collide with the
struct type) before SPIRV-Cross emits the source for those backends.
Conforming instance names (the engine's `x_info` convention) are left
unchanged, so existing engine shaders are unaffected, and shader
reflection (which keys on the block name) is untouched. No shader bundle
or runtime stage format change.
Fixes flutter#186393.
Replace `std::toupper` in StripUnderscoresAndUpper with an inline ASCII fold. GLSL identifiers are ASCII, so this is correct, and it avoids the locale dependence (and the signed-`char` UB) of the C `toupper`. Drop the now-unused `<cctype>` include.
The doc comments on `StripUnderscoresAndUpper` and `CanonicalizeUniformBlockInstanceNamesForGL`, and the test rationale and failure messages in `UniformBlockInstanceNameCanonicalizedForGL`, all restate context that already lives in flutter#186393. Replaced each with a short version that names the rule, points at the issue for the deeper explanation, and lets the code speak for itself. No behavior change.
3095642 to
c5815a1
Compare
gaaclarke
left a comment
There was a problem hiding this comment.
Code looks good, can we get an integration test for this in fragment_shader_test.dart?
…tion Per @gaaclarke's review on PR flutter#186394, add an end-to-end test that exercises the canonicalization landed for flutter#186393. A new fragment shader fixture (`flutter_gpu_unlit_alt_instance.frag`) declares `uniform ColorParams { vec4 base_color; } params;`. The instance name `params` does not normalize to the block name `ColorParams` under `BufferBindingsGLES`'s case- and underscore-insensitive match, so on the OpenGL ES backend without canonicalization every member of this block would silently bind to GL location `-1`. The shader is wired into `test.shaderbundle` as `UnlitFragmentAltInstance`. The new test in `gpu_test.dart` builds a pipeline with `UnlitVertex` + `UnlitFragmentAltInstance`, binds the fragment block via `getUniformSlot('ColorParams')` with red, renders the triangle, adds it to Skia Gold, and also pixel-checks the center of the rendered triangle programmatically. If the canonicalization regresses, the GLES backend reads zero for `base_color`, the fragment output is fully transparent black, and the programmatic pixel check fails locally without depending on the Skia Gold baseline. Verified locally: passes on `flutter_tester_opengles` (SwANGLE) and `flutter_tester` (Metal); `analyze.sh` clean. The test lands in `gpu_test.dart` rather than `fragment_shader_test.dart` because the bug only affects Flutter GPU shader bundles. RuntimeEffect shaders (`FragmentProgram` / `ui.FragmentShader`) flatten their uniforms to individual top-level declarations on the GLES backend, so the `uniform Block { ... } instance;` lowering this PR canonicalizes is not reachable from `fragment_shader_test.dart`.
|
Added a test to |
|
autosubmit label was removed for flutter/flutter/186394, because - The status or check suite Linux windows_android_aot_engine has failed. Please fix the issues identified (or deflake) before re-applying this label.
|
|
autosubmit label was removed for flutter/flutter/186394, because - The status or check suite Linux windows_host_engine has failed. Please fix the issues identified (or deflake) before re-applying this label.
|
|
Golden file changes have been found for this pull request. Click here to view and triage (e.g. because this is an intentional change). If you are still iterating on this change and are not ready to resolve the images on the Flutter Gold dashboard, consider marking this PR as a draft pull request above. You will still be able to view image results on the dashboard, commenting will be silenced, and the check will not try to resolve itself until marked ready for review. For more guidance, visit Writing a golden file test for Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing. |
|
Looks like I'll need your help to accept the new golden generated by the test @gaaclarke |
|
thanks! |
flutter/flutter@1ceffd1...3598686 2026-05-17 engine-flutter-autoroll@skia.org Roll Fuchsia Linux SDK from G9xv1qcMhvXOy-9pk... to 5Ki-dBY4SpWdQMF_3... (flutter/flutter#186636) 2026-05-17 bdero@google.com [Impeller] Canonicalize uniform block instance names for the GL backends (flutter/flutter#186394) 2026-05-16 srawlins@google.com [widgets] Use super parameters in missed spots (flutter/flutter#186198) 2026-05-16 120367427+master-wayne7@users.noreply.github.com refactor: Remove material imports from Widget tests (flutter/flutter#185078) 2026-05-16 137456488+flutter-pub-roller-bot@users.noreply.github.com Roll pub packages (flutter/flutter#186602) 2026-05-16 chris@bracken.jp [gn] Fix typo in comment (flutter/flutter#186549) 2026-05-16 engine-flutter-autoroll@skia.org Roll Fuchsia Linux SDK from y6uQHA5xUN83IF395... to G9xv1qcMhvXOy-9pk... (flutter/flutter#186599) 2026-05-15 30870216+gaaclarke@users.noreply.github.com Removes bringup from passing macos/sdf tests (flutter/flutter#186527) 2026-05-15 mdebbar@google.com [web] Fix several WebParagraph bugs (flutter/flutter#186403) 2026-05-15 alex.medinsh@gmail.com Display the team ID and name when selecting a signing certificate (flutter/flutter#184665) 2026-05-15 chris@bracken.jp [iOS] Improve documentation on FlutterVSyncClient and FlutterDisplayLink (flutter/flutter#186456) 2026-05-15 jason-simmons@users.noreply.github.com Increase the run time of text field integration tests to 10 seconds (flutter/flutter#186475) 2026-05-15 155553833+MatejLNCD@users.noreply.github.com Fix web-server hot restart/reload not applying changes for entrypoints outside lib (flutter/flutter#183838) 2026-05-15 1063596+reidbaker@users.noreply.github.com Update dart_skills_lint dependency to e449787 and optimize skills validation test (flutter/flutter#186528) 2026-05-15 engine-flutter-autoroll@skia.org Roll Packages from 2ec2236 to 32c84d6 (3 revisions) (flutter/flutter#186583) 2026-05-15 53112208+BilalRehman08@users.noreply.github.com Dispose TextEditingController in IndexedStack example (flutter/flutter#186375) 2026-05-15 34465683+rkishan516@users.noreply.github.com refactor: update filename for sliver semantic widget (flutter/flutter#185917) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-packages Please CC bmparr@google.com,stuartmorgan@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
…r#11724) flutter/flutter@1ceffd1...3598686 2026-05-17 engine-flutter-autoroll@skia.org Roll Fuchsia Linux SDK from G9xv1qcMhvXOy-9pk... to 5Ki-dBY4SpWdQMF_3... (flutter/flutter#186636) 2026-05-17 bdero@google.com [Impeller] Canonicalize uniform block instance names for the GL backends (flutter/flutter#186394) 2026-05-16 srawlins@google.com [widgets] Use super parameters in missed spots (flutter/flutter#186198) 2026-05-16 120367427+master-wayne7@users.noreply.github.com refactor: Remove material imports from Widget tests (flutter/flutter#185078) 2026-05-16 137456488+flutter-pub-roller-bot@users.noreply.github.com Roll pub packages (flutter/flutter#186602) 2026-05-16 chris@bracken.jp [gn] Fix typo in comment (flutter/flutter#186549) 2026-05-16 engine-flutter-autoroll@skia.org Roll Fuchsia Linux SDK from y6uQHA5xUN83IF395... to G9xv1qcMhvXOy-9pk... (flutter/flutter#186599) 2026-05-15 30870216+gaaclarke@users.noreply.github.com Removes bringup from passing macos/sdf tests (flutter/flutter#186527) 2026-05-15 mdebbar@google.com [web] Fix several WebParagraph bugs (flutter/flutter#186403) 2026-05-15 alex.medinsh@gmail.com Display the team ID and name when selecting a signing certificate (flutter/flutter#184665) 2026-05-15 chris@bracken.jp [iOS] Improve documentation on FlutterVSyncClient and FlutterDisplayLink (flutter/flutter#186456) 2026-05-15 jason-simmons@users.noreply.github.com Increase the run time of text field integration tests to 10 seconds (flutter/flutter#186475) 2026-05-15 155553833+MatejLNCD@users.noreply.github.com Fix web-server hot restart/reload not applying changes for entrypoints outside lib (flutter/flutter#183838) 2026-05-15 1063596+reidbaker@users.noreply.github.com Update dart_skills_lint dependency to e449787 and optimize skills validation test (flutter/flutter#186528) 2026-05-15 engine-flutter-autoroll@skia.org Roll Packages from 2ec2236 to 32c84d6 (3 revisions) (flutter/flutter#186583) 2026-05-15 53112208+BilalRehman08@users.noreply.github.com Dispose TextEditingController in IndexedStack example (flutter/flutter#186375) 2026-05-15 34465683+rkishan516@users.noreply.github.com refactor: update filename for sliver semantic widget (flutter/flutter#185917) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-packages Please CC bmparr@google.com,stuartmorgan@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
Fixes #186393.
On pre-
#version 140GL targets (kOpenGLES,kOpenGLDesktop), SPIRV-Cross lowersuniform Block { ... } instance;tostruct Block { ... }; uniform Block instance;and the driver reports members asinstance.member.BufferBindingsGLESlooks them up by the block name modulo a case- and underscore-insensitive match, so a non-conforming instance name (e.g.uniform ToonInfo { ... } toon;) silently binds every member to GL location-1.This PR makes
impellercrewrite non-conforming instance names to_<BlockName>(which reduces to the block name under the same fold) before emitting GLSL for those targets. Conforming instance names (XInfo/x_info) are left alone; shader reflection (keyed on the block name) is untouched; no shader bundle / runtime stage format change. Vulkan and Metal are unaffected (they bind by descriptor index).Verified on a Pixel 10 Pro: the broken shader from the linked issue now renders identically to Vulkan / Metal. New compiler unit test (
UniformBlockInstanceNameCanonicalizedForGL) compilesmat2_test.frag(uniform Params { ... } uParams;) for the GL targets and asserts the emitted source uses_Params.rather thanuParams..Pre-launch Checklist
///).This change was developed with AI assistance; I have reviewed and take responsibility for it.