# How iris renders an unbounded number of images Iris cannot require Vulkan descriptor indexing. The Android Vulkan Profile 2025, covering 80.1% of active Vulkan-capable Android devices as of October 2025, does not require `VK_EXT_descriptor_indexing` or its bindless texture features ([Android Vulkan profiles](https://developer.android.com/ndk/guides/graphics/android-vulkan-profile)). Arm guarantees the extension only on Valhall and fifth-generation GPUs ([Arm Vulkan guidance](https://developer.arm.com/mobile-graphics-and-gaming/vulkan-api-best-practices-on-arm-gpus)). The emulator also rejects wgpu requests for `TEXTURE_BINDING_ARRAY`, `SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING`, and `PARTIALLY_BOUND_BINDING_ARRAY`. Those features therefore must not enter Iris's required device feature set. ## Current design Glyph atlas pages are layers of one `texture_2d_array`. `GpuTextures` doubles the array when it runs out of layers, copies the old layers on the GPU, and rebuilds every bind group that referenced the old view. Page numbers are assigned synchronously by `Textures::add_page` because glyph insertion needs the layer before the renderer processes queued texture updates. Standalone images each own a bind group and are not placed in the glyph array. Each render layer keeps ordinary rect/glyph instances separately from image instances. It draws the ordinary batch once, then binds and draws each standalone image. This removes any fixed image count at the cost of one bind and draw call per visible image, which is the appropriate tradeoff for phone transcripts containing a modest number of screenshots. The masks storage buffer appears in every image bind group. If that buffer or the atlas array is reallocated, all affected bind groups must be rebuilt; retaining a bind group across either reallocation would leave it pointing at the old GPU resource. Texture updates accumulate their rebuild requirement with OR. A patch must never clear a rebuild requested by an earlier push in the same batch. Within a render layer, images are drawn after rects and glyphs. Both primitive lists use `swap_remove`, so no code may infer draw adjacency from arena adjacency after a free. Standalone images currently use `NonFiltering` sampling. Thumbnail scaling and filtering remain image-widget decisions, not texture-storage decisions. ## Verification rig `scripts/rigs/gpu-probe` requests Iris's exact feature and limit set without a window. Run it on the target device when changing renderer requirements. A successful desktop adapter is not evidence that the same feature is available on Android hardware.