Skip to content

[Impeller] Allow sampling textures with manually-uploaded mip levels#187729

Merged
auto-submit[bot] merged 17 commits into
flutter:masterfrom
bdero:bdero/impeller-mipmap-sampling
Jun 11, 2026
Merged

[Impeller] Allow sampling textures with manually-uploaded mip levels#187729
auto-submit[bot] merged 17 commits into
flutter:masterfrom
bdero:bdero/impeller-mipmap-sampling

Conversation

@bdero

@bdero bdero commented Jun 9, 2026

Copy link
Copy Markdown
Member

Removes the bind-time NeedsMipmapGeneration() check in the Metal and OpenGL ES backends, which rejected sampling any mip_count > 1 texture whose mips were uploaded by hand (Texture.overwrite(mipLevel:)) rather than produced by the GenerateMipmap blit.

Why remove it:

  • It's inconsistent across backends. Vulkan has no equivalent, and the Metal check is already skipped on iOS, so manually-mipped textures already sample fine there; only desktop Metal and GLES failed.
  • Makes stuff like prefiltered IBL atlases & compressed-texture mip chains impossible.

The mipmap_generated_/NeedsMipmapGeneration() state tracking is kept, the Gaussian blur and render-target mip generation still read it; only the bind-time validation is removed.

Adds the CanSampleManuallyMippedTexture render golden.

Pre-launch Checklist

Remove the bind-time NeedsMipmapGeneration() check from the Metal and OpenGL
ES backends. It rejected sampling any texture whose mip chain was uploaded via
Texture::overwrite(mipLevel:) (rather than the GenerateMipmap blit) by
returning false at bind, so the texture was never bound.

The check was inconsistent: Vulkan has no equivalent and the Metal check was
already skipped on iOS. The mipmap_generated_ flag stays, since the 2D
renderer's Gaussian blur and render-target mip generation still read it; only
the redundant bind-time validation is removed. The 2D renderer generates mips
before sampling by construction and never tripped the check, so this only
unblocks external HAL consumers (Flutter GPU) sampling manually-mipped
textures such as prefiltered IBL atlases and compressed-texture mip chains.
@flutter-dashboard flutter-dashboard Bot added the CICD Run CI/CD label Jun 9, 2026
@github-actions github-actions Bot added engine flutter/engine related. See also e: labels. e: impeller Impeller rendering backend issues and features requests labels Jun 9, 2026
CanSampleManuallyMippedTexture populates a mip_count=2 texture's base level by
hand (via SetContents, no GenerateMipmap blit) and samples it at an explicit
LOD of 0 through the mipmaps shader. It exercises the bind-time mipmap
validation removed in the previous commit: before that change the bind failed
on desktop Metal and OpenGL ES, so the golden would have been blank.
@github-actions github-actions Bot removed the CICD Run CI/CD label Jun 9, 2026
@bdero bdero requested a review from gaaclarke June 9, 2026 12:28
@bdero bdero marked this pull request as ready for review June 9, 2026 12:34

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

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 removes bind-time mipmap validation checks from the OpenGL ES and Metal backends, allowing textures with manually populated mip chains to be sampled. A new golden test is added to verify this behavior. Feedback suggests initializing the entire mip chain in the test by populating the second mip level to prevent potential driver-specific completeness issues.

Comment thread engine/src/flutter/impeller/renderer/renderer_golden_unittests.cc
Upload the second mip level by hand via a blit copy so the texture is
mipmap-complete on backends that require it (OpenGL ES samples a mipmapped
texture as incomplete otherwise). The blit copy does not set mipmap_generated_,
so NeedsMipmapGeneration() stays true and the test still exercises the
removed bind-time check.
@flutter-dashboard flutter-dashboard Bot added the CICD Run CI/CD label Jun 9, 2026
@bdero bdero added CICD Run CI/CD and removed CICD Run CI/CD labels Jun 9, 2026
@fluttergithubbot

Copy link
Copy Markdown
Contributor

An existing Git SHA, e28d997e1d2cee36b1077d4f2361edfdc7264ea0, was detected, and no actions were taken.

To re-trigger presubmits after closing or re-opeing a PR, or pushing a HEAD commit (i.e. with --force) that already was pushed before, push a blank commit (git commit --allow-empty -m "Trigger Build") or rebase to continue.

@gaaclarke

Copy link
Copy Markdown
Member

you have to push an empty commit to this to kick the bots. it seems to happen when the cicd label gets confused

@github-actions github-actions Bot removed the CICD Run CI/CD label Jun 9, 2026
@bdero bdero added the CICD Run CI/CD label Jun 9, 2026
@gaaclarke gaaclarke requested review from b-luk and removed request for gaaclarke June 9, 2026 15:44
@gaaclarke

Copy link
Copy Markdown
Member

@b-luk can you give this a review please?

@b-luk b-luk left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally looks good.

The mac_unopt test failure seems like a real failure caused by this change, so we should make sure it gets fixed. https://logs.chromium.org/logs/flutter/buildbucket/cr-buildbucket/8679457603160578785/+/u/test:_Impeller-golden_for_host_release/stdout

The linux_unopt test is just a formatting issue: https://logs.chromium.org/logs/flutter/buildbucket/cr-buildbucket/8679457623519549473/+/u/test:_test:_Check_formatting/stdout.

I want to make sure the golden output is what we expect too. Right now I think those two other failures are blocking golden results from getting created.

VS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));

FS::FragInfo frag_info;
frag_info.lod = 0.0f;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we also have another test to make sure lod = 1 renders as expected? If you add this, we should change it to be something other than all white.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added CanSampleManuallyMippedTextureLod1, which samples the second level at LOD 1, and changed that level to solid orange so it is distinct from the base and from an empty level. Done in 0cdc8e9.

Refactor the manually-mipped golden into a helper parameterized by LOD and add
a second test that samples the hand-uploaded mip level at LOD 1. The second
level is now solid orange rather than white, so it is distinct from the base
and from an empty level. Also wraps the AddCopy call to satisfy clang-format.
@github-actions github-actions Bot removed the CICD Run CI/CD label Jun 9, 2026
@bdero bdero added the CICD Run CI/CD label Jun 9, 2026
@bdero bdero requested a review from b-luk June 9, 2026 19:51
@b-luk

b-luk commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Generally looks good.

The mac_unopt test failure seems like a real failure caused by this change, so we should make sure it gets fixed. https://logs.chromium.org/logs/flutter/buildbucket/cr-buildbucket/8679457603160578785/+/u/test:_Impeller-golden_for_host_release/stdout

The linux_unopt test is just a formatting issue: https://logs.chromium.org/logs/flutter/buildbucket/cr-buildbucket/8679457623519549473/+/u/test:_test:_Check_formatting/stdout.

I want to make sure the golden output is what we expect too. Right now I think those two other failures are blocking golden results from getting created.

The new test on mac_unopt is still failing: https://logs.chromium.org/logs/flutter/buildbucket/cr-buildbucket/8679443838533653025/+/u/test:_Impeller-golden_for_host_release/stdout

[ RUN      ] Play/RendererGoldenTest.CanSampleManuallyMippedTexture/Metal
[FATAL:flutter/impeller/renderer/blit_pass.cc(145)] Impeller validation: Attempted to add a texture blit with out of bounds access.
[ERROR:flutter/fml/backtrace.cc(108)] Caught signal SIGABRT during program execution.
Frame 0: 0x100f10168 fml::LogMessage::~LogMessage()
Frame 1: 0x100f10154 fml::LogMessage::~LogMessage()
Frame 2: 0x100f2ccbc impeller::ImpellerValidationBreak()
Frame 3: 0x100f2cb2c impeller::ValidationLog::~ValidationLog()
Frame 4: 0x1011e8a88 impeller::BlitPass::AddCopy()
Frame 5: 0x100e89adc impeller::testing::DrawManuallyMippedTextureGolden()
Frame 6: 0x10136e560 testing::Test::Run()
Frame 7: 0x10136f700 testing::TestInfo::Run()
Frame 8: 0x101370490 testing::TestSuite::Run()
Frame 9: 0x101380774 testing::internal::UnitTestImpl::RunAllTests()
Frame 10: 0x101380018 testing::UnitTest::Run()
Frame 11: 0x100c9f210 main
Frame 12: 0x19c366b98 start

From asking Gemini about the failure, it says:

The test failure occurs because BlitPass::AddCopy is called with std::nullopt for the destination region when uploading the 4x4 second mip level (LOD 1). Without an explicit region, Impeller defaults to the texture's full 8x8 base dimensions and calculates an expected copy size of 256 bytes. When it compares this against the 4x4 source buffer's actual size of 64 bytes, the size mismatch triggers a fatal out-of-bounds validation error. This can be resolved by explicitly passing IRect::MakeSize({4, 4}) as the destination region.

If it's not making things up, that seems like a reasonable theory to me.

AddCopy defaults the destination region to the full base size, so uploading the
4x4 second level with no region expected 256 bytes against a 64 byte source and
tripped the bounds validation. Pass an explicit 4x4 destination region.
@github-actions github-actions Bot removed the CICD Run CI/CD label Jun 9, 2026
@bdero bdero added the CICD Run CI/CD label Jun 9, 2026
@bdero

bdero commented Jun 10, 2026

Copy link
Copy Markdown
Member Author

Yes, GLES is pain. GLES 2 leaves GL_TEXTURE_MAX_LEVEL at its default of 1000, which made the partial mip chain mipmap incomplete and sample as black... so 3e6570c clamps it to the texture's declared mip count at bind time. Now let's see those device lab goldens. 🤞

@bdero bdero added CICD Run CI/CD and removed CICD Run CI/CD labels Jun 10, 2026
@b-luk

b-luk commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Looks good to me, as long as the golden tests come back fine.

The linux_fuchsia failure is an unrelated infrastructure issue that is being worked on. Unfortunately it'll block the rest of the CI from running until it gets resolved.

@b-luk

b-luk commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

The linux_fuchsia tests should be fixed by #187813. After that is in master, merge past it and try CI again.

@github-actions github-actions Bot removed the CICD Run CI/CD label Jun 11, 2026
@bdero bdero added the CICD Run CI/CD label Jun 11, 2026
bdero added 2 commits June 11, 2026 12:03
ShaderLibrary.fromAsset is synchronous, so the texture pipeline helper drops
the stray await and matches the unlit helper. Also annotates the non-obvious
locals per specify_nonobvious_local_variable_types and uses var where the type
is obvious.
@github-actions github-actions Bot removed the CICD Run CI/CD label Jun 11, 2026
@bdero bdero added the CICD Run CI/CD label Jun 11, 2026
@flutter-dashboard

Copy link
Copy Markdown

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 package:flutter.

Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing.

Changes reported for pull request #187729 at sha c956ad4

@flutter-dashboard flutter-dashboard Bot added the will affect goldens Changes to golden files label Jun 11, 2026
@bdero

bdero commented Jun 11, 2026

Copy link
Copy Markdown
Member Author

@b-luk the stars have aligned and the goldens are all looking as expected 🙌

@b-luk b-luk left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Thanks for the revisions, Brandon. Sorry about the CI issues.

@bdero bdero added the autosubmit Merge PR when tree becomes green via auto submit App label Jun 11, 2026
@auto-submit auto-submit Bot added this pull request to the merge queue Jun 11, 2026
Merged via the queue into flutter:master with commit 59ab469 Jun 11, 2026
210 of 211 checks passed
@github-project-automation github-project-automation Bot moved this from 🤔 Needs Triage to ✅ Done in Flutter GPU Jun 11, 2026
@flutter-dashboard flutter-dashboard Bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Jun 11, 2026
@bdero bdero deleted the bdero/impeller-mipmap-sampling branch June 12, 2026 00:51
auto-submit Bot pushed a commit to flutter/packages that referenced this pull request Jun 12, 2026
flutter/flutter@8bdce07...b7cb925

2026-06-12 engine-flutter-autoroll@skia.org Roll Skia from cadbde1ec4b7 to 8c89bf2b0ee3 (5 revisions) (flutter/flutter#187926)
2026-06-12 engine-flutter-autoroll@skia.org Roll Packages from 1b56cde to b78ad83 (5 revisions) (flutter/flutter#187928)
2026-06-12 engine-flutter-autoroll@skia.org Roll Dart SDK from f3441f2067ae to f6c31f4c3a63 (17 revisions) (flutter/flutter#187924)
2026-06-12 engine-flutter-autoroll@skia.org Roll Fuchsia Linux SDK from 2KosSR4ONUjIB7tP_... to A3eaUn9mQ_EkSNxVI... (flutter/flutter#187923)
2026-06-12 engine-flutter-autoroll@skia.org Roll Skia from a2228b926c68 to cadbde1ec4b7 (9 revisions) (flutter/flutter#187921)
2026-06-12 kustermann@google.com Remove dynamic module loading code in flutter web engine (flutter/flutter#187777)
2026-06-12 matt.kosarek@canonical.com Remove EnableTransparentWindowBackground because it did nothing important and because Windows 10 does not support DWMWA_SYSTEMBACKDROP_TYPE (flutter/flutter#187848)
2026-06-12 engine-flutter-autoroll@skia.org Roll Fuchsia Test Scripts from dQ4PjIJB5kZFU8Y32... to EmfiOMUge_nnNS33B... (flutter/flutter#187912)
2026-06-12 mvincentong@gmail.com Clarify RichText selection docs (flutter/flutter#186844)
2026-06-12 1063596+reidbaker@users.noreply.github.com Custom KGP task and migration to AGP api for geting kgp version (flutter/flutter#182788)
2026-06-12 engine-flutter-autoroll@skia.org Roll Skia from f61acb31edf8 to a2228b926c68 (5 revisions) (flutter/flutter#187896)
2026-06-12 bdero@google.com [Flutter GPU] Expose ASTC HDR texture formats (flutter/flutter#187715)
2026-06-12 awolff@google.com Expand coverage of android_hardware_smoke_test. Add image, text, blend mode, and blur tests. (flutter/flutter#187600)
2026-06-11 bdero@google.com [Flutter GPU] Add blit operations (flutter/flutter#187289)
2026-06-11 bkonyi@google.com [flutter_tools] Fix version cache git fallback performance regression (flutter/flutter#187400)
2026-06-11 nshahan@google.com Rewrite `-d web-server` hot reload/restart tests (flutter/flutter#187453)
2026-06-11 bdero@google.com [Impeller] Allow sampling textures with manually-uploaded mip levels (flutter/flutter#187729)
2026-06-11 154381524+flutteractionsbot@users.noreply.github.com Sync CHANGELOG.md from stable (flutter/flutter#187884)
2026-06-11 47866232+chunhtai@users.noreply.github.com iOS a11y sets header trait based on heading level (flutter/flutter#186916)
2026-06-11 engine-flutter-autoroll@skia.org Roll Skia from 9f02102df298 to f61acb31edf8 (19 revisions) (flutter/flutter#187869)
2026-06-11 engine-flutter-autoroll@skia.org Roll ICU from ee5f27adc28b to d578f2e8b7bd (8 revisions) (flutter/flutter#187829)

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 louisehsu@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
via-guy pushed a commit to via-guy/flutter that referenced this pull request Jun 26, 2026
…lutter#187729)

Removes the bind-time `NeedsMipmapGeneration()` check in the Metal and
OpenGL ES backends, which rejected sampling any `mip_count > 1` texture
whose mips were uploaded by hand (`Texture.overwrite(mipLevel:)`) rather
than produced by the `GenerateMipmap` blit.

Why remove it:
- It's inconsistent across backends. Vulkan has no equivalent, and the
Metal check is already skipped on iOS, so manually-mipped textures
already sample fine there; only desktop Metal and GLES failed.
- Makes stuff like prefiltered IBL atlases & compressed-texture mip
chains impossible.

The `mipmap_generated_`/`NeedsMipmapGeneration()` state tracking is
kept, the Gaussian blur and render-target mip generation still read it;
only the bind-time validation is removed.

Adds the `CanSampleManuallyMippedTexture` render golden.

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [AI contribution guidelines] and understand my
responsibilities, or I am not using AI tools.
- [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.

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[AI contribution guidelines]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#ai-contribution-guidelines
[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/
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CICD Run CI/CD e: impeller Impeller rendering backend issues and features requests engine flutter/engine related. See also e: labels. flutter-gpu team-fluttergpu Owned by Flutter GPU team will affect goldens Changes to golden files

Projects

Status: ✅ Done

Development

Successfully merging this pull request may close these issues.

4 participants