-
Notifications
You must be signed in to change notification settings - Fork 29.5k
fixes the vulkan image layout transitions for mipmap generation #173884
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request fixes an issue with Vulkan image layout transitions during mipmap generation. The previous logic could leave some mip levels in an incorrect state. The change replaces a break with a continue in the mipmap generation loop and refactors the layout transitions to be more robust, ensuring all mip levels are correctly transitioned. The overall logic is sound and correctly addresses the bug. I have one suggestion to make a pipeline barrier more precise, which could lead to a minor performance improvement.
engine/src/flutter/impeller/renderer/backend/vulkan/blit_pass_vk.cc
Outdated
Show resolved
Hide resolved
dfd5a8a to
5e2cf63
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fundamentally, I like setting the final layout of all mip levels in one shot. That part lgtm.
But, I don't see how we could ever get into the position where the break trips since we use Size::MipCount. So it's not difficult to imagine why you're having trouble reproducing this with an image in a fixture. That with the possibility of the empty blit is something I am not sure is necessary or sound. Perhaps skipping the blit, doing the transition, then breaking out of the loop after works better.
engine/src/flutter/impeller/renderer/backend/vulkan/blit_pass_vk.h
Outdated
Show resolved
Hide resolved
| if (width <= 1 || height <= 1) { | ||
| break; | ||
| // Continue to make sure everything is placed into eTransferSrcOptimal. | ||
| continue; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have two concerns about this:
- This bit seems defensive coding. How did we even get into this position? We use
Size::MipCountto generate mips sizes and it would be impossible to get into this situation based on how the rest of the subsystems are wired up. - Does
blitImagewhere the sizes are empty cause a validation error? Perhaps skip the blit in case the sizes are empty but still break out of the loop after so additional levels are unaffected.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This bit seems defensive coding. How did we even get into this position? We use Size::MipCount to generate mips sizes and it would be impossible to get into this situation based on how the rest of the subsystems are wired up.
I came at this with the assumption that the original break was meaningful. This PR retains that. We could do some extra investigation to see if it's unnecessary. It seems safer to me to keep it intact since jonah thought it was necessary at some point. It doesn't seem like it will hurt anything (after this change).
Reading the description of Jonah's pr he wasn't so much stopping blits where the sizes is empty, he was blocking things where the blit size is one. It was done here: #165357. Unfortunately the details are a little sparse.
Does blitImage where the sizes are empty cause a validation error? Perhaps skip the blit in case the sizes are empty but still break out of the loop after so additional levels are unaffected.
Probably. The concern behind the suggestion isn't clear to me. The reason there is the continue is that we need a guarentee that we shift the image layouts no matter what.
Is your concern that the branch with the continue is impossible to hit? So you concern is not about a logical problem but one of code clarity? I wonder about that too but I didn't investigate deeply and assumed it was valid since it was already there. Just because I can't get it in testing doesn't mean i can't get it in production because the things that are blocking me in testing are validation layers that don't exist in production. If it isn't hit everything will function correctly anyways. |
|
I was able to from math import log2
for i in range(1,2049):
steps = int(log2(i))
tally = i
result = str(i)
for j in range(1, steps):
tally = tally // 2
result += f' {tally}'
print(result) |
|
Thinking about it more, despite the fact that we can't hit the continue block today, because the code that stops that from happening is so far away. I could easily see us making a change where it was possible again, so this guard is good. |
|
Makes sense. Even if use Size::MipCount, there is nothing preventing an image descriptor with a custom mip count. |
flutter/flutter@c65f01d...da5523a 2025-08-27 dacoharkes@google.com [native assets] Roll dependencies (flutter/flutter#174522) 2025-08-27 engine-flutter-autoroll@skia.org Roll Skia from 8cf2faada2b5 to 7e6da45059c5 (5 revisions) (flutter/flutter#174523) 2025-08-27 43054281+camsim99@users.noreply.github.com [Android] Restrict AOT shared library engine flag to trusted paths (flutter/flutter#173359) 2025-08-27 engine-flutter-autoroll@skia.org Roll Fuchsia Linux SDK from L5zGzsIWIS8N36AFQ... to bHYRvLv2Dg56RWZF2... (flutter/flutter#174518) 2025-08-27 engine-flutter-autoroll@skia.org Roll Packages from 1ef712e to 86fbeec (7 revisions) (flutter/flutter#174521) 2025-08-27 engine-flutter-autoroll@skia.org Roll Skia from 448a0d0e57e3 to 8cf2faada2b5 (1 revision) (flutter/flutter#174510) 2025-08-27 engine-flutter-autoroll@skia.org Roll Skia from 4703976a4dae to 448a0d0e57e3 (3 revisions) (flutter/flutter#174494) 2025-08-27 sokolovskyi.konstantin@gmail.com Fix SliverMainAxisGroup and SliverCrossAxisGroup gestures' local positions. (flutter/flutter#174265) 2025-08-27 robert.ancell@canonical.com Fix lock up when window resized with merged UI and platform threads. (flutter/flutter#172893) 2025-08-27 engine-flutter-autoroll@skia.org Roll Skia from dc2872de506f to 4703976a4dae (1 revision) (flutter/flutter#174489) 2025-08-27 engine-flutter-autoroll@skia.org Roll Dart SDK from db45c0ce46f9 to 89023922f96d (2 revisions) (flutter/flutter#174481) 2025-08-27 32538273+ValentinVignal@users.noreply.github.com Migrate examples and defaults to `WidgetState` (flutter/flutter#174421) 2025-08-27 engine-flutter-autoroll@skia.org Roll Skia from 8e48b9e6d67b to dc2872de506f (7 revisions) (flutter/flutter#174479) 2025-08-27 36861262+QuncCccccc@users.noreply.github.com SnackBar with action no longer auto-dismiss (flutter/flutter#173084) 2025-08-26 engine-flutter-autoroll@skia.org Roll Dart SDK from 9054cd8af73c to db45c0ce46f9 (1 revision) (flutter/flutter#174438) 2025-08-26 engine-flutter-autoroll@skia.org Roll Skia from f941bfab7c09 to 8e48b9e6d67b (4 revisions) (flutter/flutter#174468) 2025-08-26 matanlurey@users.noreply.github.com Fix bug in test_golden_comparator, add an e2e test. (flutter/flutter#174459) 2025-08-26 matt.boetger@gmail.com fix typo in test_profile/README.md (flutter/flutter#174384) 2025-08-26 matanlurey@users.noreply.github.com Remove CP labels on not-merged PRs, and explain why (flutter/flutter#174448) 2025-08-26 1063596+reidbaker@users.noreply.github.com Increase testing coverage and maintainability of android manifest parsing logic (flutter/flutter#174070) 2025-08-26 1961493+harryterkelsen@users.noreply.github.com [web] Add test that pictures are not rasterized when clipped out (flutter/flutter#174452) 2025-08-26 engine-flutter-autoroll@skia.org Roll Skia from 538260c45b4a to f941bfab7c09 (3 revisions) (flutter/flutter#174450) 2025-08-26 30870216+gaaclarke@users.noreply.github.com fixes the vulkan image layout transitions for mipmap generation (flutter/flutter#173884) 2025-08-26 15619084+vashworth@users.noreply.github.com Move flakey iOS tests to bringup (flutter/flutter#174446) 2025-08-26 30870216+gaaclarke@users.noreply.github.com [Impeller] Make sure inline passes always do a clear action. (flutter/flutter#174083) 2025-08-26 engine-flutter-autoroll@skia.org Roll Skia from 21214d63fc40 to 538260c45b4a (2 revisions) (flutter/flutter#174441) 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 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
…ter#173884) Speculative fix for flutter#171252 The image layout transitions were wrong when generating mipmaps where we'd run into `width <= 1 || height <= 1`. Previously the logic would short circuit the process of converting everything from Dst->Src, potentially leaving the mips in a series like [Read, Read, Src, Dst]. Then only the last one would get set to read, so [Read, Read, Src, Read]. Now instead we group transition them all to Dst, then one by one we switch them to src, make sure the last one gets set to src, then group transition them to read. We make sure the loop doesn't break to make sure everything transitions to src. While this fixes a hypothetical bug, I couldn't replicate the bug inside of unit tests because of validations. I couldn't find a mip count / texture size that would allow me to hit the `break` statement that jonah added previously. That doesn't mean it couldn't happen on release builds though. I'm less confident that this fixes the issue after having written the tests. This does reduce the number of barriers though, so that's a win. ## 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
…ter#173884) Speculative fix for flutter#171252 The image layout transitions were wrong when generating mipmaps where we'd run into `width <= 1 || height <= 1`. Previously the logic would short circuit the process of converting everything from Dst->Src, potentially leaving the mips in a series like [Read, Read, Src, Dst]. Then only the last one would get set to read, so [Read, Read, Src, Read]. Now instead we group transition them all to Dst, then one by one we switch them to src, make sure the last one gets set to src, then group transition them to read. We make sure the loop doesn't break to make sure everything transitions to src. While this fixes a hypothetical bug, I couldn't replicate the bug inside of unit tests because of validations. I couldn't find a mip count / texture size that would allow me to hit the `break` statement that jonah added previously. That doesn't mean it couldn't happen on release builds though. I'm less confident that this fixes the issue after having written the tests. This does reduce the number of barriers though, so that's a win. ## 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
…ter#173884) Speculative fix for flutter#171252 The image layout transitions were wrong when generating mipmaps where we'd run into `width <= 1 || height <= 1`. Previously the logic would short circuit the process of converting everything from Dst->Src, potentially leaving the mips in a series like [Read, Read, Src, Dst]. Then only the last one would get set to read, so [Read, Read, Src, Read]. Now instead we group transition them all to Dst, then one by one we switch them to src, make sure the last one gets set to src, then group transition them to read. We make sure the loop doesn't break to make sure everything transitions to src. While this fixes a hypothetical bug, I couldn't replicate the bug inside of unit tests because of validations. I couldn't find a mip count / texture size that would allow me to hit the `break` statement that jonah added previously. That doesn't mean it couldn't happen on release builds though. I'm less confident that this fixes the issue after having written the tests. This does reduce the number of barriers though, so that's a win. ## 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
Speculative fix for #171252
The image layout transitions were wrong when generating mipmaps where we'd run into
width <= 1 || height <= 1. Previously the logic would short circuit the process of converting everything from Dst->Src, potentially leaving the mips in a series like [Read, Read, Src, Dst]. Then only the last one would get set to read, so [Read, Read, Src, Read].Now instead we group transition them all to Dst, then one by one we switch them to src, make sure the last one gets set to src, then group transition them to read. We make sure the loop doesn't break to make sure everything transitions to src.
While this fixes a hypothetical bug, I couldn't replicate the bug inside of unit tests because of validations. I couldn't find a mip count / texture size that would allow me to hit the
breakstatement that jonah added previously. That doesn't mean it couldn't happen on release builds though. I'm less confident that this fixes the issue after having written the tests.This does reduce the number of barriers though, so that's a win.
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.