Skip to content

iris-hostgl: flush presents don't wait, and come at most once a frame - #248

Merged
techomancer merged 3 commits into
techomancer:mainfrom
atomchild411:hostgl-flush-presents
Oct 17, 2026
Merged

techomancer merged 3 commits into
techomancer:mainfrom
atomchild411:hostgl-flush-presents

Conversation

@atomchild411

@atomchild411 atomchild411 commented Oct 17, 2026 •

Copy link
Copy Markdown
Collaborator

iris-hostgl: flush presents don't wait, and come at most once a frame

SGI's IRIS GL flushes after every primitive it draws into the front buffer. Under host GL each flush was a full present the program waited for, so flight's cockpit drew itself instrument by instrument, over a second or more. On the board, and under SGI's own libraries on the emulated Max IMPACT, it appears at once.

The change

  1. Swap intervals pace swaps only. GLX_SGI_swap_control applied its wait to every OP_SWAP: showing the front buffer, or a colour-index window, after a flush slept up to interval frames each. flight asks for swapinterval(2), so it drew a few primitives a second. A new bit 4 in the seventh slot marks a present as a flush, for colour-index windows, which have no front bit. Only swaps wait now.
  2. Flush presents never wait for the presenter. Each one replaces that window's frame still waiting, so the screen gets the newest drawing as fast as the presenter can put it there, and always the last one. Colour-index frames take the queue like RGBA ones. The queue keeps one waiting frame per window rather than one overall, so one window's flushes never drop another window's frame.
  3. OP_PRESENT_LATER (0x1_0012). It takes OP_SWAP's slots.
    • On the GL thread it is answered 1 at once and queued in order with the client's buffers. The GL thread shows a client's window at most once per FLUSH_GAP (a 60 Hz frame).
    • When a present is still waiting, it is shown when the gap is up; the thread wakes for that when nothing else comes. It is also shown before the client's next call that isn't a buffer, which is the only thing that can change what the client draws to.
    • Without the GL thread it is OP_SWAP; a host without it answers EINVAL.
    • The library sends it only for a window whose last present the display took, so nothing ever has to come back.
    • OP_SWAP's body moves into GlService::swap, unchanged, for both.

Tests

  • Unit tests: flush_presents_wait_out_the_gap, present_later_is_answered_at_once_and_runs_in_order. The first sets its own gap (GlService::flush_gap), so it doesn't depend on how fast the host draws. With FLUSH_GAP itself it failed about one run in six on a loaded VM, where a present took longer than a frame. It passed 10 of 10 there afterwards.
  • cargo test --manifest-path iris-hostgl/Cargo.toml: 35 passed on macOS.
  • cargo test --lib mgras: 177 passed.
  • flight under host GL (IRIX 6.5.22m, Max IMPACT, macOS host, guest tools v20261017-proto2), measured from screenshots every 0.1 s from launch:
    • cockpit complete in 0.56–0.66 s on this branch;
    • 2 s on upstream IRIS with the same guest library;
    • 0.55 s under SGI's own libraries on the emulated board.
  • gltest all ok (n32, o32), glcheck PASSED, irisgltest the same 12 failures as SGI's libraries.
  • On Linux (Debian 12 arm64 VM, Mesa, virgl):

🤖 Generated with Claude Code

atomchild411 and others added 3 commits October 17, 2026 15:04
… flushes

OP_SWAP applied GLX_SGI_swap_control's wait to every call, and every call
moved the next one's due time: showing the front buffer after a flush
(bit 1) and a colour-index window shown after a flush slept up to
interval frames each. SGI's IRIS GL flushes after each primitive it draws
into the front buffer, and flight asks for swapinterval(2): it drew a few
primitives a second (the IRIS GL shim's flight ran at 4 frames a second
the same way). Only swaps wait now; the seventh slot's new bit 4 says a
present is a flush, for colour-index windows, whose frames carry no front
bit. Unpaced, IGLOO's flight runs at 230 frames a second on IMPACT.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… too

SGI's IRIS GL flushes after every primitive it draws into the front buffer:
flight drew its cockpit with 2,736 presents in five seconds, each a
full-window composite, and each waited for the presenter (2.8 s of the
five), so the instruments appeared one by one where SGI's library shows
them at once.

- A present made because the program flushed (OP_SWAP's front bit, or bit
  4 for a colour-index window) never waits for the presenter: it replaces
  that window's frame still waiting. The screen gets the newest drawing as
  fast as the presenter can put it there, and the last one always.
- Colour-index frames take the queue like RGBA ones (the first of each
  drawable synchronously, to learn whether the display takes it).
- The queue keeps one waiting frame a window, not one in all, so one
  window's flushes never drop another's frame.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…off the CPU thread

SGI's IRIS GL flushes after every primitive it draws into the front
buffer -- two thousand a second in flight's cockpit -- and each flush was
an OP_SWAP: a trip to the GL thread behind the client's queued buffers,
and a whole frame copied for the screen. The cockpit drew itself over a
second; on the board it takes a few hundred milliseconds.

OP_PRESENT_LATER takes OP_SWAP's slots. On the GL thread it is read and
answered 1 at once and queued in order with the buffers; the GL thread
shows a client's window at most once a FLUSH_GAP (a 60 Hz frame), the
latest waiting when the gap is up -- waking for it when nothing else
comes -- or before the client's next call that is not a buffer, the only
thing that changes what it draws to. Without the GL thread it is
OP_SWAP. The library sends it only for a window whose last present the
display took, so nothing ever has to come back.

OP_SWAP's body moves into GlService::swap, unchanged, for both.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@atomchild411
atomchild411 force-pushed the hostgl-flush-presents branch from 5d1e8b1 to e9e9d5d Compare October 17, 2026 23:06
@atomchild411 atomchild411 changed the title iris-hostgl: flush presents don't wait, and come at most once a frame (stacked on #247) iris-hostgl: flush presents don't wait, and come at most once a frame Oct 17, 2026
@techomancer
techomancer merged commit f600ff1 into techomancer:main Oct 17, 2026
7 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