Files
ai-app/IRIS.md
T
irisandClaude Sonnet e0a473e090 iris: replace the bindless texture array with an atlas array + per-image bind groups
The old pipeline bound every texture ever drawn (glyph atlas pages and
standalone images alike) in one binding_array<texture_2d<f32>> and asked
every device, unconditionally, for VK_EXT_descriptor_indexing -- which a
real share of Android GPUs lack and which failed outright on the Android
emulator's software Vulkan (see TEXTURES.md's "iris's binding array does
not survive real Android hardware").

Implements TEXTURES.md's "Recommended shape": the glyph atlas is now one
texture_2d_array (a layer per page, grown by doubling + GPU-side
copy_texture_to_texture); a standalone image is its own ordinary Texture
and BindGroup, drawn with its own draw() call from a separate per-layer
instance list; group 2's layout is {atlas array, one image slot, sampler,
masks}. request_device now asks for no features and no binding-array
limits at all, and UiLimits is gone.

Also fixes (by making moot) the changed=false bug the review found, where
a Patch in the same batch could cancel an earlier Push's rebuild signal,
and documents the swap_remove draw-order invariant apply_free already
relied on.

Verified: cargo fmt/build/clippy/test clean in iris/ on the pinned
nightly; minimal and tabs render correctly via run-headless.sh; a
throwaway example confirmed the standalone-image bind-group path renders;
rigs/gpu-probe, updated to the new empty feature/limit set, confirms
request_device succeeds on the ai-app-2 emulator's software Vulkan
(EMU_GPU=software) -- see TEXTURES.md's "Implemented, 2026-09-04" for the
exact command and output. RUST.md's blocking item is resolved.

Co-Authored-By: Claude Sonnet <noreply@anthropic.com>
2026-09-04 22:28:54 -04:00

2.8 KiB

iris: notable public API changes

For Iris to read on her own time. Each entry is a change to iris's public surface that a widget author or app author would notice: a trait method added, removed or re-shaped; a type that callers construct differently; a capability that moved. Small and trivial changes do not go here.

An entry gives the date, what changed, why, and a short before/after where it helps judge the change without the session that made it. Newest first.

2026-09-04: texture pipeline rebuilt off the binding array

Textures/TextureHandle, GlyphPrimitive, and UiRenderNode::new all changed shape. Why: the old pipeline bound every texture ever drawn in one binding_array<texture_2d<f32>> and asked every device, unconditionally, for VK_EXT_descriptor_indexing — a real share of Android GPUs lack it, and it failed outright on the Android emulator's software Vulkan. See TEXTURES.md's "Recommended shape" and "Implemented, 2026-09-04".

  • UiRenderNode::new drops its limits: UiLimits parameter, and UiLimits is gone. Before: UiRenderNode::new(&device, &queue, &config, UiLimits::default()). After: UiRenderNode::new(&device, &queue, &config). Nothing replaces it — there are no more binding-array limits to size.
  • src/default/render.rs's device request asks for no features and no binding-array limits. Before: required_features: Features::TEXTURE_BINDING_ARRAY | Features::PARTIALLY_BOUND_BINDING_ARRAY | Features::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING plus two max_binding_array_* limits. After: Features::empty() (the DeviceDescriptor default) and only max_buffer_size set, which was never about the binding array.
  • TextureHandle has no primitive() method any more; a caller outside iris shouldn't have been calling it (it fed the old renderer's internals), but if something did: use image_index() for a standalone image's bind-group index. There is no equivalent for a page — a page has no bind group of its own now, see below.
  • GlyphPrimitive has no public constructor from a struct literal. Before: GlyphPrimitive { uv_min, uv_max, view_idx, sampler_idx, color, flags }. After: GlyphPrimitive::new(uv_min, uv_max, layer, color, flags) — one layer (the shared atlas array's layer) instead of a view_idx/sampler_idx pair, since a page is now a layer of one array texture rather than its own bound texture.
  • A widget author drawing images is unaffected: Painter::texture/ texture_at/texture_within and Textures::add keep their signatures. What changed underneath is that each standalone image now gets its own wgpu::BindGroup and draw call instead of a slot in the shared array — invisible from the widget API, visible only in UiRenderNode's internals and in iris's device requirements.