ludic/changes/model-release.md
Orkuncakilkaya e634177ca4 feat(render3d): 23.4 - model_release, shared textures counted, and scatter layers sized to what they hold
- model_release(model) frees each primitive's mesh, and each texture once no other model uses it:
  the glTF texture cache counts the primitives using each texture (a path loaded again, and a LOD
  chain borrowing its LOD0's material, each take a reference); the last one frees the texture and
  forgets it along with any remembered material naming it, so a later load is a fresh one
- a scatter layer's instance and sort arrays start at 256 and double as layer_add or a stream
  fills them, to the layer's cap, instead of the whole cap up front (0.4 GB in Maroon Lake)
- gvk_tex_read's copy struct comes from the scratch ring
- examples/rendering/release.ludic holds it (RELEASE OK on Vulkan and OpenGL), in the suite

smooth renders pixel-identical before and after (max |d| 0). ludic-dev test 306/306.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 23:34:14 +03:00

791 B

bump: minor type: feature A loaded model can be let go of: model_release(model). Its meshes are freed at once, and each texture once no other model uses it - the glTF loader shares textures between models (one path loaded once, a LOD chain borrowing its LOD0's material), so every cached texture now counts the primitives using it, and the last one frees it and forgets it, with any remembered material that named it. A game can unload a species' kit or a map's models when nothing of them is left, and loading one again afterwards is a fresh load. A scatter layer takes room for what it holds instead of its whole capacity up front (it doubles as it fills, to its cap), which in Maroon Lake was 0.4 GB of never-filled instance arrays. examples/rendering/release.ludic is the check.