From eea1c3641a2645330940effaeb8bc342601d5978 Mon Sep 17 00:00:00 2001 From: hkmodd <64160552+hkmodd@users.noreply.github.com> Date: Mon, 12 Oct 2026 03:18:12 +0200 Subject: [PATCH] Keep the debug model vertices off the stack rasterizer_debug_model_vertices declares 2048 debug vertices of 64 bytes on the stack. render_model calls it for each part it draws, and the release build inlines it there, so render_model's frame was 136,304 bytes, and the Windows build probed it a page at a time (_chkstk, 33 pages) for every model drawn, although the debug display is off. Its vertices are static now: only the vertices below debug_vertex_count are read, each written when it is added, and the function runs on the render thread only, so nothing it draws changes. Measured on Windows (7800X3D, RTX 4080, release build, vsync off), b30 co-op with 32 times the enemies and a bot, 75 s a run, five runs of each build alternated: render_model's frame is 5,360 bytes (the PDB's S_FRAMEPROC); _chkstk fell from 2.0% to 0.5% of the game thread's samples; fps over windows with 2000 draws a frame or more, origin/main 128, 141, 139, 134, 107 (median 134), this change 140, 139, 144, 141, 132 (median 140). Linux, Android and the web build do not probe the stack, so the change only shortens their frame. They were not built. Co-Authored-By: Claude Opus 5.5 --- port/linux/README.md | 1 + source/rasterizer/rasterizer.c | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/port/linux/README.md b/port/linux/README.md index dc15ed39..37c94300 100644 --- a/port/linux/README.md +++ b/port/linux/README.md @@ -1139,6 +1139,7 @@ Other changes: | `input/input_abstraction.c`, `game/player_control.c`, `game/players.c`, `game/player_queues_new.c`, `units/units.h` | The keyboard and mouse's actions (`src/xinput_sdl.c`, `include/halo_keyboard.h`) join controller 1's game controls; their reload key reloads on its own, and their action key only acts (a control flag of the port's, sent with the player's action, stops the reload the controller's X falls back to). | | `sound/sound_manager.c`, `interface/hud.c`, `game/game_engine.c` | The music's and the other sounds' volumes; the HUD's and the scoreboard's settings are read again when Settings changes them. | | `rasterizer/xbox/rasterizer_xbox_shadows.c` | With larger shadow maps (`display.shadow_resolution`), the blur's taps stay half a texel apart, and more passes widen it to cover the same part of the map as on the Xbox. | +| `rasterizer/rasterizer.c` | The 128 KB of vertices of the debug display of a model's vertices are static, not on the stack: the compiler inlines the function in `render_model`, and the Windows build probed the stack a page at a time for every model drawn. | | `render/render.c` | The 3D view of each window is antialiased before the HUD is drawn (`display.anti_aliasing`). | | `interface/hud.c` | In multiplayer, players' names are drawn above their heads (`display.player_names`, `display.player_name_scale`). | | `rasterizer/rasterizer_text.c`, `text/draw_string.c` | Text is drawn from an atlas of the fonts' glyphs, rasterized at the resolution the game draws at (`src/text_hires.c`), when the font has every character of the string. Text can be drawn scaled about a point (`rasterizer_text_set_scale`), as the players' names are. Each glyph's advance is centred on the font tag character's, so the layout is the same, and a glyph is cut at a text box only where the font tag's character visibly was. | diff --git a/source/rasterizer/rasterizer.c b/source/rasterizer/rasterizer.c index 68709606..de9e17c3 100644 --- a/source/rasterizer/rasterizer.c +++ b/source/rasterizer/rasterizer.c @@ -1889,7 +1889,11 @@ void rasterizer_debug_model_vertices( short triangle_vertex_index; char model_vertex_string[256]; char triangle_vertex_string[256]; - struct rasterizer_debug_model_vertex debug_vertices[MAXIMUM_RASTERIZER_DEBUG_MODEL_VERTICES]; + /* port: static. render_model calls this for each part it draws, and + the compiler inlines it there: on the stack, the Windows build probed + the 128 KB the debug display rarely uses a page at a time (_chkstk) for + every model drawn */ + static struct rasterizer_debug_model_vertex debug_vertices[MAXIMUM_RASTERIZER_DEBUG_MODEL_VERTICES]; match_assert( "c:\\halo\\SOURCE\\rasterizer\\rasterizer.c",