Skip to content

[Impeller] Support compressed texture formats (BC, ETC2, ASTC) with a format capability query #187072

Closed as not planned

Description

@bdero

Use case

Impeller has no compressed texture support today. There are no compressed PixelFormat values, no compressed upload path in any backend, and the descriptor sizing math (BytesPerPixelForPixelFormat, GetByteSizeOfBaseMipLevel, GetBytesPerRow) is per-pixel, which is invalid for block-compressed data.

Compressed textures reduce GPU memory and bandwidth by roughly 4x to 8x and are required for realistic 3D content. Flutter GPU and Flutter Scene cannot expose them (for example glTF textures) until Impeller supports them.

No single compressed format is supported across all platforms, so a runtime capability query is a prerequisite for exposing any of these formats safely.

This is distinct from #170597, which covers runtime lossy compression of regular images. This issue is about block-compressed asset formats (BC, ETC2, ASTC).

Proposal

Add compressed texture support to Impeller, grouped into the same three hardware families that WebGPU exposes as optional features:

  • BC (S3TC, RGTC, BPTC): BC1 to BC7. Desktop GPUs.
  • ETC2 and EAC. Mobile, and any OpenGL ES 3.0 or WebGL2 context.
  • ASTC LDR. Modern mobile and some desktop.

Guided by WebGPU and WebGL, skip these during the initial implementation: PVRTC (deprecated, Apple only, being removed from WebGL), ETC1 (legacy, superseded by ETC2), ASTC HDR, and BC6H HDR. They can be added later behind the same query.

Work items:

  1. Add the compressed PixelFormat values for the three families above.
  2. Make descriptor math block-aware. Add bytes-per-block and block dimensions to formats.h, and update GetByteSizeOfBaseMipLevel and GetBytesPerRow to round to block extents.
  3. Add a compressed upload path: glCompressedTexSubImage2D (GLES), vkCmdCopyBufferToImage with block extents (Vulkan), and replaceRegion with compressed formats (Metal).
  4. Enforce usage restrictions: sample plus copy-destination only. No render target, no storage, no transient storage mode, and no runtime mip generation.
  5. Map the formats in each backend, gated by capability detection: Vulkan feature flags (textureCompressionBC, textureCompressionETC2, textureCompressionASTC_LDR), GLES extension strings, and Metal GPU family checks.

Capability query API

Add to impeller::Capabilities:

enum class TextureCompressionType {
  kBC,    // Desktop. BC1 to BC7.
  kETC2,  // Mobile, GLES3, WebGL2.
  kASTC,  // Modern mobile, some desktop.
};

// True if the device supports a whole compressed family.
virtual bool SupportsTextureCompression(TextureCompressionType type) const = 0;

// Per-format, per-usage query. Covers compressed and uncompressed formats.
virtual bool SupportsTextureFormat(PixelFormat format,
                                   TextureUsage usage) const = 0;

SupportsTextureFormat is the general primitive. SupportsTextureCompression is a convenience for the common "can I use this family at all" check. This mirrors WebGPU, where compression is exposed as three optional device features.

Formats supported almost universally at landing

No single compressed format works everywhere, which is why the query exists. Coverage is near-universal per tier:

  • ETC2 and EAC: guaranteed on OpenGL ES 3.0 and WebGL2, present on all mobile GPUs and Apple Silicon.
  • BC: effectively guaranteed on desktop (Windows, Linux, macOS discrete GPUs) through Vulkan, desktop GL, and Metal.
  • ASTC: modern mobile (Mali, Adreno, Apple A8 and newer).

Together the three families cover essentially every target. A single asset reaches all of them through KTX2 or Basis Universal transcoding at the asset layer, with uncompressed RGBA as the final fallback. See the dependent Flutter GPU issue.

Activity

  1. added
    c: new featureNothing broken; request for a new capability
    engineflutter/engine related. See also e: labels.
    e: impellerImpeller rendering backend issues and features requests
    on May 26, 2026
  2. bdero commented on May 26, 2026

    @bdero
    MemberAuthor

    Duplicate of #148443. Design detail folded into that issue; the dependent Flutter GPU work is tracked in #187073.

  3. github-actions commented on Jul 14, 2026

    @github-actions

    This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

  4. locked as resolved and limited conversation to collaborators on Jul 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    c: new featureNothing broken; request for a new capabilitye: impellerImpeller rendering backend issues and features requestsengineflutter/engine related. See also e: labels.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions