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

10 lines
791 B
Markdown

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.