Shared texture-backed element storage for instanced geometry.
Per-element data lives in an RGBA32F element texture (gsplats:
4 texels/splat; points: 3 texels/point; lines: 6 texels/segment —
layout authority in ./element-texture-layout) sampled by the vertex
shader via texelFetch. The only per-instance data is the ordering
pair aSortedIndex / aSortedIndexB (Uint32), which maps the draw
slot to a storage slot so draw order can be permuted without
rewriting element data (depth-sorting plan,
docs/guides/specs/GSPLAT_DEPTH_SORTING_SPEC.md §4/§8). The pair is
DOUBLE-BUFFERED — a new ordering streams into the inactive buffer and
the uSortedIndexSlot uniform flips on completion (spec §2.1 tier 3),
so no frame ever samples a half-applied permutation.
Texture lifetime = geometry lifetime: attachElementStorage
registers a dispose listener on the geometry, so every dispose
site (pool evictors, pool.dispose(), the fallback rebuild swap)
frees the texture with the geometry — no site-by-site bookkeeping.
Shared texture-backed element storage for instanced geometry.
Per-element data lives in an RGBA32F element texture (gsplats: 4 texels/splat; points: 3 texels/point; lines: 6 texels/segment — layout authority in
./element-texture-layout) sampled by the vertex shader viatexelFetch. The only per-instance data is the ordering pairaSortedIndex/aSortedIndexB(Uint32), which maps the draw slot to a storage slot so draw order can be permuted without rewriting element data (depth-sorting plan,docs/guides/specs/GSPLAT_DEPTH_SORTING_SPEC.md§4/§8). The pair is DOUBLE-BUFFERED — a new ordering streams into the inactive buffer and theuSortedIndexSlotuniform flips on completion (spec §2.1 tier 3), so no frame ever samples a half-applied permutation.Texture lifetime = geometry lifetime:
attachElementStorageregisters adisposelistener on the geometry, so every dispose site (pool evictors,pool.dispose(), the fallback rebuild swap) frees the texture with the geometry — no site-by-site bookkeeping.