Repository navigation
iris-hostgl: run command buffers on a GL thread of their own - #218
Merged
Merged
Conversation
A host call is answered on the thread that runs the emulated CPU, so while host GL replayed a buffer the whole machine stood still: no instruction, no interrupt. Big buffers took 2-5 ms; IRIX acknowledged its 1 kHz tick late ~15 times a second, its audio driver refilled its few-millisecond DMA ring late, and HAL2 played gaps -- 3% of a demo's sound, heard as crackle on every loud low note. The service now runs on a thread of its own (threaded.rs), which owns every context. The CPU thread hands it work through a bounded queue: - OP_BATCH_ASYNC (new): the buffer is read on the CPU thread (need-page as ever), queued and answered at once. The library sends only buffers that read nothing outside themselves this way; one that tries is cut short and logged. Without the thread it is OP_BATCH; a host without it answers EINVAL, which is how the library finds out -- the protocol number stays. - Every other call runs on the GL thread after the buffers before it, and the CPU thread waits for its answer. It lends the GL thread its view of the program's memory for the call -- it does nothing else until the answer comes -- so a call costs two hand-offs however much it reads. - But a call from a client with buffers still queued is answered ENOTYET (iris-hostcall: new, 0x3001) at once rather than held behind them: the library yields and asks again, so IRIX keeps running. Only a library that sends OP_BATCH_ASYNC can have buffers queued, so only one that knows ENOTYET is told it. Each side spins ~30 us for its next message before it sleeps, since most answers come sooner than a thread wakes. IRIS_HOSTGL_INLINE=1 keeps the service on the CPU thread. The thread wants a host core of its own beside the CPU thread. Measured against this tree without the change, same binary features and disk (IP28, Max IMPACT, macOS, the guest's libGL the async host-GL library): a GL demo with synthesized sound went from 19.7 to 3.7 output dropouts a second (31 -> 4 ms of sound lost a second; its score alone has none either way) and Quake 3's timedemo from 30.2-30.5 to 33.9 fps. Not host GL, unchanged: boot time, idle CPU, the score with no graphics, and SGI's own libGL on the emulated board. gltest 167/167 n32 and o32, glcheck passes with the reference checksum, irisgltest all ok. The new library on a host without the thread falls back to OP_BATCH (6 of 6 gltest runs clean); libraries without OP_BATCH_ASYNC work unchanged. gltest's "the window kept its pixels" fails now and then on either build, with or without the new library. Co-Authored-By: Claude Opus 5.5 <[email protected]>
atomchild411
added a commit
to atomchild411/iris-guest-tools
that referenced
this pull request
Oct 13, 2026
release/make-tardist.sh packages an unpacked release as an inst(1M) tardist, product iristools, with gendist on IRIX. It installs the release in /usr/local/iris-tools/release and runs its install.sh as an exitop; `versions remove iristools` runs install.sh -u as a removeop, so both ways in go through the same installer. README and the release's README.txt: the libraries send self-contained buffers with OP_BATCH_ASYNC, which wants an IRIS whose host GL runs on its own thread (techomancer/iris#218) and falls back to waiting on any other; IRIS_GL_ASYNC=0 turns it off. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Host GL answered every call on the emulated CPU's thread, so while it replayed a command
buffer the whole machine stood still: no instruction ran and no interrupt was taken. Big
buffers take 2-5 ms. IRIX then took its 1 kHz clock late ~15 times a second, its audio
driver refilled HAL2's DMA ring late, and sound crackled under any busy GL program, on
every loud low note of a demo, in Quake, and so on. It is the host-GL side of
rules/mgras/guest-gl-benchmarks-miss-board-time.md: whatever keeps the guest from takingits ticks costs it time and sound.
What changes
The GL service runs on a thread of its own (
iris-hostgl/src/threaded.rs), which ownsevery context. The CPU thread only hands it work, through a bounded queue:
OP_BATCH_ASYNC(new, 0x1_0010): the buffer is read on the CPU thread (a missingpage is still a need-page answer), queued, and answered at once. Only buffers that read
nothing outside themselves may be sent this way; one that tries is cut short and logged.
A host without the thread treats it as
OP_BATCH; an older host answers EINVAL, whichis how the library finds out. The protocol number does not change.
thread waits for its answer. It lends the GL thread its view of guest memory for the
call, so a call costs two hand-offs however much it reads.
ENOTYET(new, 0x3001,iris-hostcall): a call from a client with buffers stillqueued is answered at once instead of waiting behind them; the library yields and asks
again, so IRIX keeps running. Only a client that has sent
OP_BATCH_ASYNCcan havebuffers queued, so older libraries never see it.
IRIS_HOSTGL_INLINE=1keeps the service on the CPU thread, for comparison.The guest half (sending self-contained buffers with
OP_BATCH_ASYNC, retrying onENOTYET,IRIS_GL_ASYNC=0to turn it off) is in iris-guest-tools,gl/glshim_rt.c.Measurements
Same features (
hostgl,jitv2,tcache,lightning,gpujit), same disk, this tree with andwithout the change. IP28, Max IMPACT, IRIX 6.5.22, macOS; the guest's libGL is the
host-GL library with async buffers.
demo fourtimedemo, 1024x768The library on a host without the thread falls back to
OP_BATCH: gltest 6 of 6 runsclean. Libraries without
OP_BATCH_ASYNCwork unchanged. gltest's "the window kept itspixels" fails now and then on either build (once in 12 runs without the change, with or
without the new library); it is not this change.
Tests: 4 new in
iris-hostgl/src/tests.rs(buffers sent without waiting run in orderbefore a waited call; one that reaches for memory is cut short; on the CPU thread an async
buffer is a plain batch; a call behind queued buffers is told to come back). 31/31 on
macOS and on Linux (Debian 12 arm64, with a Linux backend that is not in this PR).
iris-hostglis outside the workspace, so CI does not build it.Notes
(Quake 3 22.8 -> 14 fps);
IRIS_HOSTGL_INLINE=1is there for such hosts.rules/hostgl/host-calls-hold-the-cpu-thread.md.🤖 Generated with Claude Code