Skip to content

Clamp the discarded select arm's index in prefix-sum lookups - #1817

Open
lexoliu wants to merge 1 commit into
linebender:mainfrom
lexoliu:fix-select-index-underflow
Open

Clamp the discarded select arm's index in prefix-sum lookups#1817
lexoliu wants to merge 1 commit into
linebender:mainfrom
lexoliu:fix-select-index-underflow

Conversation

@lexoliu

@lexoliu lexoliu commented Aug 13, 2026

Copy link
Copy Markdown

Fixes #1816.

Several prefix-sum lookups have the shape
select(default, sh_array[ix - 1u], ix > 0u). Both arms of select are
evaluated, so lanes with ix == 0 compute sh_array[0u - 1u] before
discarding it. Mali lowers workgroup arrays to ordinary memory, so the
underflowed index becomes a wild address and the driver reports a device loss;
on a Pixel 9 Pro (Immortalis-G715, Android 16) any scene containing a path
lost the device on the first frame. The shaders run unchecked since #1093, so
there is no bounds check to mask it.

This clamps the index in the discarded arm, sh_array[max(ix, 1u) - 1u],
which changes nothing when ix > 0 and keeps the dead access in bounds when
ix == 0. Six sites: one each in tile_alloc and backdrop_dyn, two in
coarse (these four fault on the device), and two in fine which have the
same pattern but didn't fault in my scenes.

Verified on the Pixel 9 Pro with fully unchecked shaders: the scenes that
previously lost the device render correctly. vello_tests passes on Metal, so
the selected values are unchanged. An explicit if would avoid the dual
evaluation altogether; I kept the clamp since it's the smallest diff and it's
what I tested on hardware, but happy to change the shape.

Copilot AI lite review requested due to automatic review settings August 13, 2026 03:16
Both arms of a select are evaluated, so lookups of the form
select(default, sh_array[ix - 1u], ix > 0u) compute sh_array[0u - 1u] on
lanes where ix == 0. Mali lowers workgroup arrays to ordinary memory, so
the underflowed index becomes a wild address and the driver reports a
device loss; on a Pixel 9 Pro (Immortalis-G715, Android 16) any scene
containing a path lost the device on the first frame. The shaders run
unchecked since linebender#1093, so no bounds check masks it.

Clamping the index in the discarded arm changes nothing when ix > 0 and
keeps the dead access in bounds when ix == 0. tile_alloc, backdrop_dyn
and coarse fault on the device; the two fine.wgsl sites share the pattern
and are fixed for consistency.
@lexoliu
lexoliu force-pushed the fix-select-index-underflow branch from a302016 to 5e5f538 Compare August 13, 2026 03:17

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Fixes a Vulkan device-loss on Mali GPUs caused by underflowed workgroup-array indexing in the discarded arm of WGSL select expressions used for prefix-sum lookups.

Changes:

  • Clamp the index used in the non-selected select arm (max(ix, 1u) - 1u) across six prefix-sum lookup sites to prevent underflow on ix == 0.
  • Update the Unreleased changelog with a note about the Mali device-loss fix.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
vello_shaders/shader/tile_alloc.wgsl Clamp discarded-arm prefix-sum index to avoid - 1u underflow.
vello_shaders/shader/coarse.wgsl Clamp discarded-arm prefix-sum indices in two prefix-sum lookups.
vello_shaders/shader/backdrop_dyn.wgsl Clamp discarded-arm prefix-sum index in row prefix-sum lookup.
vello_shaders/shader/fine.wgsl Clamp discarded-arm prefix-sum indices in two prefix-sum lookups.
CHANGELOG.md Add Unreleased entry describing the Mali device-loss fix.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread CHANGELOG.md Outdated
### Fixed

- Rendering scenes whose binning requires more than 256 bins. ([#1700][] by [@b0nes164][])
- Prefix-sum lookups no longer index workgroup arrays with an underflowed index in the discarded arm of a `select`, which caused a device loss on Mali GPUs for any scene containing a path. ([#XXXX][] by [@lexoliu][])
lexoliu added a commit to water-rs/waterui that referenced this pull request Aug 13, 2026
Points vello at lexoliu/vello#fix-select-index-underflow (upstream PR
linebender/vello#1817): the discarded arm of a select computed an
underflowed workgroup-array index and Mali page-faults on it, losing the
Vulkan device for any scene containing a path. Drop this patch when a
vello release containing the fix ships.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Device lost on Mali (Pixel 9) for any scene containing a path

2 participants