Add build-time checks for ImpellerC's SkSL compiler#180861
Conversation
There was a problem hiding this comment.
Code Review
This pull request adds build-time checks for ImpellerC's SkSL compiler. The changes introduce validation in two key areas: first, by enhancing the CompilerSkSL class to detect unsupported array initializers directly from the ParsedIR, providing precise error messages. Second, it adds a post-compilation validation step in the Compiler class, which uses Skia's SkRuntimeEffect to catch a broader range of SkSL invalidities that are harder to detect from the IR, such as array assignments. The changes are accompanied by a comprehensive set of unit tests that cover both successful and failing compilation scenarios, ensuring the new checks work as expected. The implementation is solid and improves the robustness of the SkSL compilation process.
gaaclarke
left a comment
There was a problem hiding this comment.
The approach is looking good to me. The testing is looking good too. My only hangup is making sure we aren't being over prescriptive, I thought going into this it was only array initializers at file scope that was the problem.
| // this. | ||
| auto& block = id.get<SPIRBlock>(); | ||
|
|
||
| // File ane line information for use in the error message. |
There was a problem hiding this comment.
| // File ane line information for use in the error message. | |
| // File and line information for use in the error message. |
| // Check for OpStore instructions that store an array constant. This | ||
| // detects array initializations which use compile-time constants | ||
| // (e.g. `float[2] nums = float[](1.0, 2.0);`). | ||
| auto& store_object_id = ir.ids[ir.spirv[instruction.offset + 1]]; |
There was a problem hiding this comment.
| // next OpLine instruction. | ||
| file = get<SPIRString>(ir.spirv[instruction.offset]).str; | ||
| line = ir.spirv[instruction.offset + 1]; | ||
| } else if (instruction.op == OpStore) { |
There was a problem hiding this comment.
Is the problem limited to arrays at file scope? Will this check catch things in function scope?
There was a problem hiding this comment.
This check catches array initialization at both file and function scope.
The problem isn't limited to array at file scope. The array initializer syntax isn't supported at all in SkSL.
Skia's doc for SkSL gives very little information about what syntax is or isn't supported, and no details on what GLSL version SkSL is based upon.
Older versions of GLSL do not support array initializers:
- The GLSL 1.10 spec in section "4.1.9 Arrays" states: "There is no mechanism for initializing arrays at declaration time from within a shader."
- The GLSL 1.20 spec in section "4.1.9 Arrays" is updated to show array initializer use.
I don't know what specific version of GLSL was used to base SkSL off of, so it's hard to figure out exactly what syntax is supported. From experimenting at https://shaders.skia.org/, all single-line array initialization gives an error. So I assume SkSL is based on an older GLSL version that does not support any array initializers.
|
|
||
| float more_nums[2]; | ||
| // SkSL does not support array assignment. | ||
| more_nums = nums; |
There was a problem hiding this comment.
Same question as above, I thought the problem was just for initializers of uniforms, this is a problem too?
There was a problem hiding this comment.
Yep. From experimenting at https://shaders.skia.org/, this is also unsupported.
| return; | ||
| } | ||
|
|
||
| if (sl_compiler.GetType() == CompilerBackend::Type::kSkSL) { |
There was a problem hiding this comment.
This isn't technically needed right? This is just a backstop for other issues? This sounds good to me.
There was a problem hiding this comment.
It's a backstop to detect any issues which we don't have explicit checks for in spirv_sksl.cc. The array_assignment.frag test case is one such undetected issue which this backstop catches.
Without this, we have the existing behavior of the invalid SkSL triggering a runtime error when the fragment program is loaded. With this backstop, the invalid SkSL triggers an error at build time instead of runtime.
Manual roll requested by [email protected] flutter/flutter@793b0b8...b45a73b 2026-01-13 [email protected] Roll pub packages (flutter/flutter#180900) 2026-01-13 [email protected] Roll Dart SDK from 34318de9874b to ebaf52c13799 (1 revision) (flutter/flutter#180870) 2026-01-13 [email protected] Make sure that an ErrorWidget doesn't crash in 0x0 environment (flutter/flutter#180830) 2026-01-13 [email protected] Make sure that a Banner doesn't crash in 0x0 environment (flutter/flutter#180254) 2026-01-13 [email protected] Adds metal background to engine dart tests (flutter/flutter#180700) 2026-01-13 [email protected] Add TabBar API example for scroll notification integration (flutter/flutter#180728) 2026-01-13 [email protected] Roll Skia from 714d0af2eda7 to 8f3134206e8d (1 revision) (flutter/flutter#180874) 2026-01-13 [email protected] Add build-time checks for ImpellerC's SkSL compiler (flutter/flutter#180861) 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 [email protected],[email protected] 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
Adds build-time checks for ImpellerC's SkSL compiler in two places: - The `CompilerSkSL` class in `spirv_sksl.cc` generates the compiled SkSL from the user's input shader code. It has an existing `detect_unsupported_resources` method which analyzes the generated `ParsedIR` to detect various features that SkSL does not support (e.g. UBOs and SSBOs, push constant blocks, and user specified inputs). This PR adds additional checks to `detect_unsupported_resources` to detect array initialization using array initializers (e.g. `float[](1.0, 2.0)`), which is not supported by SkSL. This specifically addresses flutter#125630. - In the main `Compiler` class in `compiler.cc`, when compiling to SkSL, validate the compiled SkSL by using it to create a `SkRuntimeEffect`. Some invalid SkSL cases, like array assignment (`float[2] float_array = another_float_array;`) are hard to detect from the `ParsedIR`, so `CompilerSkSL` does not attempt to detect these invalid cases. The validation added in `Compiler` will catch all of these cases after SkSL compilation. The error messages produced from this validation are less informative than error messages from `CompilerSkSL`'s checks. It surfaces the error produced by Skia's SkSL parser and outputs the entire generated SkSL file (which can be substantially different from the user's input shader code). Fixes flutter#125630. ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. **Note**: The Flutter team is currently trialing the use of [Gemini Code Assist for GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code). Comments from the `gemini-code-assist` bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
) Manual roll requested by [email protected] flutter/flutter@793b0b8...b45a73b 2026-01-13 [email protected] Roll pub packages (flutter/flutter#180900) 2026-01-13 [email protected] Roll Dart SDK from 34318de9874b to ebaf52c13799 (1 revision) (flutter/flutter#180870) 2026-01-13 [email protected] Make sure that an ErrorWidget doesn't crash in 0x0 environment (flutter/flutter#180830) 2026-01-13 [email protected] Make sure that a Banner doesn't crash in 0x0 environment (flutter/flutter#180254) 2026-01-13 [email protected] Adds metal background to engine dart tests (flutter/flutter#180700) 2026-01-13 [email protected] Add TabBar API example for scroll notification integration (flutter/flutter#180728) 2026-01-13 [email protected] Roll Skia from 714d0af2eda7 to 8f3134206e8d (1 revision) (flutter/flutter#180874) 2026-01-13 [email protected] Add build-time checks for ImpellerC's SkSL compiler (flutter/flutter#180861) 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 [email protected],[email protected] 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
) Manual roll requested by [email protected] flutter/flutter@793b0b8...b45a73b 2026-01-13 [email protected] Roll pub packages (flutter/flutter#180900) 2026-01-13 [email protected] Roll Dart SDK from 34318de9874b to ebaf52c13799 (1 revision) (flutter/flutter#180870) 2026-01-13 [email protected] Make sure that an ErrorWidget doesn't crash in 0x0 environment (flutter/flutter#180830) 2026-01-13 [email protected] Make sure that a Banner doesn't crash in 0x0 environment (flutter/flutter#180254) 2026-01-13 [email protected] Adds metal background to engine dart tests (flutter/flutter#180700) 2026-01-13 [email protected] Add TabBar API example for scroll notification integration (flutter/flutter#180728) 2026-01-13 [email protected] Roll Skia from 714d0af2eda7 to 8f3134206e8d (1 revision) (flutter/flutter#180874) 2026-01-13 [email protected] Add build-time checks for ImpellerC's SkSL compiler (flutter/flutter#180861) 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 [email protected],[email protected] 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
Adds build-time checks for ImpellerC's SkSL compiler in two places:
CompilerSkSLclass inspirv_sksl.ccgenerates the compiled SkSL from the user's input shader code. It has an existingdetect_unsupported_resourcesmethod which analyzes the generatedParsedIRto detect various features that SkSL does not support (e.g. UBOs and SSBOs, push constant blocks, and user specified inputs). This PR adds additional checks todetect_unsupported_resourcesto detect array initialization using array initializers (e.g.float[](1.0, 2.0)), which is not supported by SkSL. This specifically addresses [Impeller] Compiler: GLSL array literals in shaders crash at runtime. #125630.Compilerclass incompiler.cc, when compiling to SkSL, validate the compiled SkSL by using it to create aSkRuntimeEffect. Some invalid SkSL cases, like array assignment (float[2] float_array = another_float_array;) are hard to detect from theParsedIR, soCompilerSkSLdoes not attempt to detect these invalid cases. The validation added inCompilerwill catch all of these cases after SkSL compilation. The error messages produced from this validation are less informative than error messages fromCompilerSkSL's checks. It surfaces the error produced by Skia's SkSL parser and outputs the entire generated SkSL file (which can be substantially different from the user's input shader code).Fixes #125630.
Pre-launch Checklist
///).If you need help, consider asking for advice on the #hackers-new channel on Discord.
Note: The Flutter team is currently trialing the use of Gemini Code Assist for GitHub. Comments from the
gemini-code-assistbot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed.