Skip to content

Optimize visible brush geometry memory allocation - #109

Open
Aciz wants to merge 3 commits into
etfdevs:masterfrom
Aciz:optimize-tcvis-mem-alloc
Open

Optimize visible brush geometry memory allocation#109
Aciz wants to merge 3 commits into
etfdevs:masterfrom
Aciz:optimize-tcvis-mem-alloc

Conversation

@Aciz

@Aciz Aciz commented Aug 25, 2026

Copy link
Copy Markdown
Collaborator
  • Replace the fixed MAX_FACE_VERTS vertex buffer pre-allocated for every face of every visible brush with lazily allocated, growable buffers (start at 8 verts, double, capped at MAX_FACE_VERTS). Faces that end up with few or no verts no longer waste the full 64-vert allocation. This nets roughly 10x memory savings on average.
  • Replace the per-brush memory allocation module with an arena allocator. Cuts down the amount of malloc() calls from potentially hundreds of thousands to few dozen. Previously, win32 heap allocator could choke on this, making some maps unplayable (very extreme cases with > 50k generated brushes)
  • Add tcVisMemInfo command to display the status of the arena.

Replace the fixed 'MAX_FACE_VERTS' vertex buffer pre-allocated for every
face of every visible brush with lazily allocated, growable buffers
(start at 8 verts, double, capped at 'MAX_FACE_VERTS'). Faces that end up
with few or no verts no longer waste the full 64-vert allocation.

On average, this is roughly 10x less memory allocated for the visible
brushes, tested ~15 maps of various sizes and complexities.
@Aciz
Aciz marked this pull request as draft August 25, 2026 18:17
Aciz added 2 commits August 25, 2026 21:52
Replace the per-brush malloc()/realloc() calls (node, faces array, and
per-face vert growth) with a module-local bump allocator. Data is
rebuilt on map load and lives until the next one; whole structure is
bulk-freed with a single arena reset.

Blocks are never moved, so the pointers held across frames for drawing
remain valid. Per-face verts keep the lazy doubling growth (8 -> 16 ->
32 -> 64, capped at MAX_FACE_VERTS) via arena alloc + copy, preserving
the memory reduction from the previous commit.

This cuts down the total amount of malloc() calls on the entire thing
from potentially hundreds of thousands to few dozen in extreme cases.
Previously, the amount of calls to malloc() could choke the heap
allocator on win32, making some maps unplayable (very extreme cases with
over 50k generated visible brushes).
Prints out the allocated arena size, as well as memory used by per-brush
type.
@Aciz
Aciz marked this pull request as ready for review August 25, 2026 19:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant