Skip to content

Optimizes ARM64 performance and refines build process - #2

Merged
jeffory merged 5 commits into
mainfrom
perf/arm64-handheld
Jun 16, 2026
Merged

jeffory merged 5 commits into
mainfrom
perf/arm64-handheld

Conversation

@jeffory

@jeffory jeffory commented Jun 16, 2026

Copy link
Copy Markdown
Owner

This change significantly enhances performance for ARM64 architectures by optimizing GPU-completion waits and improves PostFX rendering performance. It also greatly refines the overall build experience through clearer documentation and more flexible CMake configurations.

Performance Improvements

  • ARM64 GPU Waits: Replaces the CPU-intensive busy-spin GPU-completion wait on ARM64 with a blocking wait mechanism that actively monitors Command Processor (CP) progress. This prevents core oversubscription, ensuring the CP worker thread can advance efficiently, resolving potential freezes and improving performance on devices with fewer cores, such as handhelds.
  • Conditional Diagnostics: Introduces a ge_freeze_diag cvar to gate the CPU-intensive freeze watchdog and per-stall pipeline diagnostics. These features are now disabled by default in shipping builds, reducing overhead.
  • PostFX Scanlines: Optimizes the rendering of PostFX scanlines by replacing the inefficient per-line drawing loop with a cached mesh approach. Geometry for unique screen dimensions and colors is now pre-calculated and submitted as a single efficient mesh, drastically reducing draw calls. (HOM-155)

Build and Documentation Enhancements

  • Expanded README: The README.md is now comprehensively restructured and expanded to provide clear, platform-specific build instructions for Linux, Windows, and Android, streamlining the self-build process.
  • Flexible CMake Presets: Updates CMake presets for Linux to use generic clang and clang++ compiler names instead of versioned ones (e.g., clang-20), simplifying toolchain setup requirements.
  • ImGui Fix: Includes imgui_internal.h to properly expose the ImDrawListSharedData type, resolving a compilation issue related to ImGui usage.

claude and others added 5 commits June 16, 2026 13:34
…ze diag

Replace the per-frame GPU-completion busy-spin (std::this_thread::yield in a
tight loop, polled by six waits per frame) with a bounded blocking wait on the
rexglue CP-progress handshake (rex_ge_cp_wait_progress). The CP worker wakes us
the instant it advances the ring; the ~80ms skip-bit stall fallback is kept as
a safety net. Stops dozens of guest threads from starving the CP worker on
low-core arm64 handhelds.

Gate the always-on freeze watchdog (250ms poll, guest-thread stack walks,
/dev/null page probing) and the per-present heartbeat behind a new debug cvar
ge_freeze_diag (default OFF) so diagnostics don't run in shipping builds.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Eliminates ~360 AddRectFilled calls/frame at 1080p (~720 at 4K) by
building the scanline quad mesh once per unique (W, H, colour, atlas-UV)
combination and submitting it via a single PrimReserve+memcpy each frame.
Visual result is identical; CPU draw-list cost is now O(1) per frame.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…et to plain clang

Split the README "Building from source" section into Linux/Windows/Android
subsections with concrete prerequisites, commands, and output paths. Change the
Linux CMake presets to invoke plain clang/clang++ instead of the pinned
clang-20/clang++-20, matching CI and working on any recent LLVM (verified
building with Clang 22).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The cached-mesh path uses ImGui::GetDrawListSharedData()->TexUvWhitePixel,
but ImDrawListSharedData is only forward-declared in imgui.h; its complete
definition (with TexUvWhitePixel) lives in imgui_internal.h. Without the
include the file fails to compile (incomplete-type deref). Add it.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…esktop

Commit 90755ad replaced the per-frame GPU-completion busy-spin
(std::this_thread::yield) with a bounded blocking wait on the rexglue
CP-progress handshake (rex_ge_cp_wait_progress) to stop dozens of guest
threads starving the CP worker on low-core arm64 handhelds. That change was
not arch-gated, so it also altered the desktop path -- and regressed it: on
x86-64 the build froze on the very first intro screen (render skipped every
frame while the loop ran at ~60fps, GPU ring drained, skip-bit set).

Bisect confirmed it: main (yield) boots splash -> gun-barrel -> menu; the
blocking-wait commit freezes on the splash. The real variable is core count
/ oversubscription, which tracks the arm64-handheld target. So gate the wait:
keep rex_ge_cp_wait_progress on __aarch64__, restore std::this_thread::yield()
on desktop. cp_seq is now [[maybe_unused]] (only the arm64 path consumes it).

Verified: linux-amd64 build now boots to the main menu, matching main.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@jeffory
jeffory merged commit 0e29341 into main Jun 16, 2026
3 checks passed
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.

2 participants