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>
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::newdrops itslimits: UiLimitsparameter, andUiLimitsis 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_INDEXINGplus twomax_binding_array_*limits. After:Features::empty()(theDeviceDescriptordefault) and onlymax_buffer_sizeset, which was never about the binding array.TextureHandlehas noprimitive()method any more; a caller outsideirisshouldn't have been calling it (it fed the old renderer's internals), but if something did: useimage_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.GlyphPrimitivehas 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)— onelayer(the shared atlas array's layer) instead of aview_idx/sampler_idxpair, 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_withinandTextures::addkeep their signatures. What changed underneath is that each standalone image now gets its ownwgpu::BindGroupand draw call instead of a slot in the shared array — invisible from the widget API, visible only inUiRenderNode's internals and iniris's device requirements.