At 1.5x the GPU needed 11.5 ms a frame (timestamps, vr.timing_gpu_stamps),
over 90 Hz's 11.1, almost all of it the eyes' pixels. The runtime's
visibility mask (XR_KHR_visibility_mask, 15.6% of each eye's image on the
Frame) is now drawn first in each eye's pass at the near plane, black, so
the scene is not shaded there (vr.visibility_mask, on). Two things it took:
the device binds its target and viewport lazily, so the mask binds the
eye's first (halo_vr_bind_current_target); and its depth goes through the
position, not gl_FragDepth, which turned Adreno's early depth culling off
for the rest of the pass (it saved 0.3 ms that way, 1.5 ms this way).
On the device in a30 at 1.5x: the GPU's frame from 11.5 to 10.0 ms (the
eyes 4.4/5.1 to 3.6/4.1), 85.5 fps with 45 misses in 10 s to 89.4 with 2
to 5. Cutscenes (the 3D screen, not masked) hold 78 to 89.
Also: vr.timing_gpu_passes (each pass waited for; Zink's glFinish costs
too much for it to mean much), glQueryCounterEXT and
glGetQueryObjectui64vEXT for the guest, the mask's share logged.
In stereo the game's screen flash (a white flash into a scene, a fade to
black) was drawn in the HUD pass, so it covered the HUD's panel: a box in
the middle of the view (reported worn). It is now drawn in each eye's pass,
with the game's own blend over the eye's image. The HUD pass keeps only a
flash that darkens (the darken type, or a lighten toward black), so a fade
to black still takes the HUD with it; one that lightens would light the
panel up as a box again.
While a hand-aimed weapon is zoomed, a pass between the eyes and the HUD
renders the view along the gun into a corner of the back buffer, sized
to the scope's 768x768 image. It goes through a sight mask (round, or
the sniper rifle's wide one) onto a layer held at the gun, at the PC
mod HaloCEVR's per-weapon offsets. The eyes never zoom: the first-person
gun stays in the hand and the HUD layer drops the zoom mask.
vr.scope and vr.scope_size are the settings; vr.diag_zoom_seconds zooms
unattended for dumps (vr-scope.bmp). The docs now cover the VR controls,
gestures, weapon feel and scope, and credit LivingFray's HaloCEVR for
their designs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With the hand aiming, the first-person weapon's camera puts the gun in
the right hand and used to carry both arms along with it. vr.arms "ik"
(the default) gives the arms shoulders where the body is (below and
either side of the eyes, turned with the heading) and solves each arm's
upper arm and forearm, elbows down and out, to reach its hand: the right
the gun's grip as the controller holds it (the wrist and the gun, its
child, stay as they are), the left the left controller, or the gun's
grip for it while the left controller is within 15 cm of it. Out of
reach, the shoulder comes forward rather than the hand letting go.
Fingers and other bones go with the bone above them. "hidden" shows the
gun alone, "animated" the arms as the animation moves them.
Halo's first-person graphs name the hands' bones "wriste"; the gun is the
right one's child.
Cutscene frames have their own dump trigger (vr.dump_cinema_frame).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Android renderer answered each visibility test (lens-flare
occlusion) by mapping the counter buffer for its one word, and each map
waits for the GPU's queue to drain; on the Steam Frame's Zink it also
flushes and logs a performance warning. In stereo, with the flare tests
of two eyes, that took 45% of the game thread: 13-20 frames a second in
the first level's cryo bay. All counters are now read together into a
copy the first time a result is asked for after a test ends (one wait a
frame), and the same scene runs at the headset's 72.
The headset's HUD pass took the planar fog, whose animation offset only
a structure pass consumes, and the next frame's assertion stopped the
game in fogged clusters; the HUD pass leaves the fog alone.
In VR the head's turns count as looking for the scripts that wait for
the player to look (the first level's look test).
The host's thread sampler takes fractions of a second.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A frame with one player and no cinematic renders the player's window
three times in render_frame's window loop: the left and right eyes, each
from the game's camera turned by its heading and moved by the tracked
eye (vr.world_scale, head reach limited to 0.35 m), with OpenXR's
off-centre field as render_camera_build_frustum's bounds, and each
copied into its swapchain image as it finishes; then the HUD alone on a
transparent ground, shown head-locked (vr.hud_distance, vr.hud_width).
What moves on as it draws does so once a frame: the sky's animation
phase, weather and glow particles run for the left eye only, and the
first-person weapon is posed once, from the head between the eyes. The
fog's screen layers, which assume a symmetric frustum, are left out of
the eyes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Import only independently reviewed production changes. Preserve canonical physics and virtual-keyboard repairs; keep B3 and all unresolved holds out.
Record exactly four approved canary debits (6987 meaningful bytes), six Halo admissions and two revocations. Keep vendor ioinit/storage work separate. Full build, 8252-row sweep, 1318 tests, park/admission/fake audits and 621-object binding pass within approved debit bounds.
Do not publish donor research dumps or private assets. README and unrelated user research remain untouched. See frontier_publication_reconciliation_20260927.md for complete evidence limits and accounting.
* misc changes and additions
formatting changes and add structs/constants for terminal work
* match write_to_error_file and add error_global_data
* console work
* requested changes
* terminal work
100% match all terminal functions
* Formatting
---------
Co-authored-by: punpckhdq <121350336+punpckhdq@users.noreply.github.com>