Skip to content

[Impeller] framebuffer_blend.frag checks supports_decal > 1 instead of > 0.0, always taking the software decal fallback #196266

Closed

Description

@zanderso

Description

In engine/src/flutter/impeller/entity/shaders/blending/framebuffer_blend.frag, the supports_decal specialization constant (layout(constant_id = 1) const float supports_decal = 1;) is specialized in ContentContext to 0.0 or 1.0 based
on Capabilities::SupportsDecalSamplerAddressMode().

However, Sample() in framebuffer_blend.frag checks if (supports_decal > 1) instead of if (supports_decal > 0.0):

vec4 Sample(sampler2D texture_sampler, vec2 texture_coords) {
  if (supports_decal > 1) {
    return texture(texture_sampler, texture_coords);
  }
  return IPSampleDecal(texture_sampler, texture_coords);
}

(Compare with advanced_blend.frag, porter_duff_blend.frag, and vertices_uber.glsl, which all check if (supports_decal > 0.0).)

Impact

Because supports_decal is at most 1.0, supports_decal > 1 always evaluates to false, causing framebuffer_blend.frag to unconditionally fall back to IPSampleDecal(texture_sampler, texture_coords) even when hardware SamplerAddressMode::kDecal is supported and configured on the sampler:

  1. Unnecessary shader work: Every fragment executes the software [0, 1) UV bounds check in IPSampleDecal.
  2. Unintended -0.475 mip bias: IPSampleDecal samples with kDefaultMipBias (-0.475). When drawing a downscaled mipmapped image (FilterQuality.medium/DlImageSampling::kMipmapLinear) with an advanced blend mode on a device that supports both framebuffer fetch and hardware decal addressing, the -0.475 LOD bias shifts mip selection toward a higher-resolution mip level than intended.

Expected Behavior

framebuffer_blend.frag should check if (supports_decal > 0.0) so that it samples texture(texture_sampler, texture_coords) directly when hardware decal addressing is supported.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions