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>
This commit is contained in:
parent
70a92a8862
commit
e634177ca4
10 changed files with 189 additions and 7 deletions
|
|
@ -608,6 +608,13 @@ function headless_case(path: pointer, exp: pointer, label: pointer) -> void {
|
|||
let got = capture_line(`{out} < /dev/null`)
|
||||
if got == exp { ok(label) } else { bad2(label, `got [{got}] want [{exp}]`) }
|
||||
}
|
||||
# a program built headless whose verdict is one of its lines (the renderer logs before it)
|
||||
function headless_line_case(path: pointer, exp: pointer, label: pointer) -> void {
|
||||
let out = `{tmp_dir()}/h_{flat(path)}`
|
||||
if not shq(`bin/ludicc --headless examples/{path}.ludic -o {out} > {out}.log 2>&1`) { bad2(label, capture_line(`grep -i error {out}.log | head -1`)); return }
|
||||
let got = capture_line(`{out} < /dev/null 2>&1 | grep -c '^{exp}$'`)
|
||||
if got == "1" { ok(label) } else { bad2(label, capture_line(`{out} < /dev/null 2>&1 | grep -i fail | head -1`)) }
|
||||
}
|
||||
# ludic migrate state and components: the header names what every member needs, a field read in a
|
||||
# member is not edited, a module named like a package keeps a state of its own, and the program
|
||||
# runs as it did
|
||||
|
|
@ -1045,6 +1052,7 @@ function cmd_dev_test() -> int {
|
|||
reject_case("rejected/state_component_ro", "look is read-only here (look: Look)", "a component's state is read-only unless its header says mut")
|
||||
controller_case("state/component", "", " #10 big 10 1", "component.ludic (0.S: a component's header names its states; its getters, functions and events take them and the template never sees them)")
|
||||
headless_case("rendering/ui_render3d", "ok", "ui_render3d.ludic (ludic.ui's render3d backend builds against the renderer)")
|
||||
headless_line_case("rendering/release", "RELEASE OK", "release.ludic (model_release: meshes go, a shared texture stays until its last user goes)")
|
||||
migrate_component_case()
|
||||
migrate_foreign_case()
|
||||
reject_case("rejected/runtime_type_clash", "PadButton is the runtime's enum", "a program's type named like one of the runtime's is refused")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue