port: the frame rate is llvmpipe, not our draw path -- and my finding-4 candidate is downgraded
Last iteration left "is 9.7 fps llvmpipe or something in our draw path" open after publishing a candidate cause off it. That is not a question to leave open, so this iteration is the control. Pre-registered: if the rasteriser is the limit, a near-empty scene in the same container also runs at 10-25 fps; if our draw path is, it runs far faster, take >100 fps as the discriminator. empty 161.6 fps The engine loop, viewport and present path are not the limit, by 16x over the menu. 🔴 AND MY FIRST CONTROL WAS NOT A CONTROL. Its fill modes drew UNTEXTURED rects while every element the port draws is a texture, so it bounded nothing -- and it showed: the splashes were achieving ~21 Mpx/s against that control's ~50, which read as the port being mysteriously slow and was the control being mysteriously fast. With a matched textured mode: empty 161.6 | fill3 31.5 | tex3 23.9 | fill7 12.7 | tex7 11.2 and every port screen lands inside the bracket, ordered by large-quad count: publisher (1 quad) 17.3-25.0 ~ tex3; developer (1) 16.7-22.8 ~ tex3; title (6) 12.7-17.2 between; main_menu (5) 9.7 ~ tex7's 11.2. The port draws large textured alpha quads on a software rasteriser at exactly the rate a software rasteriser draws them. ⚠️ The control's own spread is 1.75x between runs (fill3 measured 18.0 once and 31.5 once), so the absolute figures are noise-dominated and only the ORDERING and the BRACKET are load-invariant. That is what the conclusion rests on -- TEMPORAL-VERIFICATION §3, prefer the quantities with no phase. 🔴 SO MY OWN CANDIDATE FOR FINDING 4 IS DOWNGRADED, AND THIS SAYS SO PLAINLY. Last iteration called the frame rate "the first candidate for finding 4 that is not already dead". The quantisation argument still holds -- a fade drawn in four steps is not a fade drawn in fifteen -- but it only bites at these rates, and these rates are a property of software rasterisation in this container. Five to seven full-screen quads at 720p is nothing to a GPU. Unless the human ran the port software-rendered, this is not what they saw, and EVERY candidate for finding 4 is now dead or near-dead. Written as a dead end rather than left standing as a lead. Leaving a plausible-sounding cause up after its own control has undercut it is exactly how "close but not right" got explained four different wrong ways. The one thing that would revive it costs the human nothing: the rate line prints on every boot now, so their next run answers it. What the port does NOT need, established rather than assumed: no draw-path optimisation (161.6 fps empty, screens on the fill curve where their quad counts put them), no texture caching (already at load_screen), no max_fps or vsync change (would not raise the rate here, and is a presentation decision not a defect). Not settled: what rate the human's machine manages -- now the only open half of a candidate I have otherwise talked myself out of; H6's +0x04 exposure; H1 (with the Decoder); the four red verify-screen rows. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018AHUQvXGyNcKonSEWsgWcX
This commit is contained in:
@@ -123,8 +123,16 @@ hitches**, which draws the splash's 45-unit build-in at **12–17 distinct alpha
|
||||
instead of 45** and the companion glow's 15-unit rise at **four to six instead
|
||||
of fifteen**.
|
||||
|
||||
⚠️ That is `llvmpipe` under Xvfb and **not a measurement of the human's
|
||||
hardware**, so it is a candidate and not a cause. The point is that the line
|
||||
🔴 **DOWNGRADED the next iteration by a matched control, and the downgrade is
|
||||
mine.** An empty scene in the same container runs at **161.6 fps**, and matched
|
||||
textured controls give **23.9 fps for three full-screen quads and 11.2 for
|
||||
seven** — every port screen lands inside that bracket in the order its quad count
|
||||
predicts (`main_menu`'s 9.7 against `tex7`'s 11.2). So the rate is software
|
||||
rasterisation of large textured alpha quads and **the port's draw path has no
|
||||
case to answer**; on any GPU the fade gets its full 45 steps. Unless the human
|
||||
ran it software-rendered this is not what they saw, which means **every candidate
|
||||
for finding 4 is now dead or near-dead**. Recorded as a dead end rather than left
|
||||
standing as a lead. The point is that the line
|
||||
now prints on every boot, so **the next play-test answers it for free**. See
|
||||
[`port-frame-rate.md`](port-frame-rate.md).
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# The port never reported its own frame rate — it does now, and it is 13–25 fps here
|
||||
|
||||
**Status:** ✅ **instrument added and measured.** 🟡 **The consequence is a live
|
||||
candidate for play-test finding 4 and it is environment-dependent, so it is
|
||||
recorded as a candidate and not as a cause.** Written 2026-09-01 by the Port at
|
||||
**Status:** ✅ **instrument added and measured.** 🔴 **The candidate it raised for
|
||||
play-test finding 4 is now DOWNGRADED to probably-dead by a matched control —
|
||||
see the last section. The port's draw path has no case to answer.** Written 2026-09-01 by the Port at
|
||||
`977965e`; HANDOFF on this branch answers `9ca1eb5`.
|
||||
|
||||
## The gap this closes
|
||||
@@ -132,3 +132,93 @@ finding over.
|
||||
and not decoded per frame — that was checked and is not the cause.
|
||||
* That capping or vsyncing would help. It would not raise the rate here, and
|
||||
changing presentation behaviour on my own authority is not mine to do.
|
||||
|
||||
|
||||
---
|
||||
|
||||
# The control: it is the software rasteriser, and the port has no case to answer
|
||||
|
||||
Written the iteration after the section above, because *"is 9.7 fps llvmpipe or
|
||||
something in our draw path"* was left open and it is not a question to leave open
|
||||
after publishing a candidate cause.
|
||||
|
||||
## Pre-registered (R2)
|
||||
|
||||
> If the rasteriser is the limit, a near-empty Godot scene in this same container
|
||||
> will also run at roughly 10–25 fps. If my draw path is the limit, it will run
|
||||
> far faster — take **>100 fps** as the discriminator.
|
||||
|
||||
Same container, same Xvfb, same 1280×720 viewport, same `[rendering]` settings,
|
||||
almost nothing drawn:
|
||||
|
||||
```
|
||||
FPSPROBE mode=empty: 651 frames in 4.03 s -- 161.6 fps, worst gap 54 ms
|
||||
```
|
||||
|
||||
**161.6 fps.** The engine loop, the viewport and the present path are not the
|
||||
limit, by a factor of sixteen over the menu.
|
||||
|
||||
## 🔴 And the first control was not a control
|
||||
|
||||
Its `fill` modes drew **untextured** `draw_rect`s while every element the port
|
||||
draws is a **texture**. A control that does not do what its subject does bounds
|
||||
nothing — and it showed: the port's splashes were achieving ~21 Mpx/s against
|
||||
that control's ~50, which read as the port being mysteriously slow and was really
|
||||
the control being mysteriously fast. Adding a matched textured mode:
|
||||
|
||||
| mode | full-screen quads | achieved |
|
||||
|---|---|---|
|
||||
| `empty` | 0 | **161.6 fps** |
|
||||
| `fill3` | 3, untextured | 31.5 |
|
||||
| **`tex3`** | **3, textured** | **23.9** |
|
||||
| `fill7` | 7, untextured | 12.7 |
|
||||
| **`tex7`** | **7, textured** | **11.2** |
|
||||
|
||||
## The port sits inside the bracket, ordered by large-quad count
|
||||
|
||||
| screen | full-screen-ish quads | measured | bracket |
|
||||
|---|---|---|---|
|
||||
| `publisher_logo` | 1 | 17.3–25.0 | ≈ `tex3` |
|
||||
| `developer_logos` | 1 | 16.7–22.8 | ≈ `tex3` |
|
||||
| `title` | 6 | 12.7–17.2 | between `tex3` and `tex7` |
|
||||
| **`main_menu`** | **5** | **9.7** | ≈ `tex7` (11.2) |
|
||||
|
||||
**Every screen lands between the two matched controls, in the order the quad
|
||||
count predicts.** The port is drawing large textured alpha quads on a software
|
||||
rasteriser at exactly the rate a software rasteriser draws large textured alpha
|
||||
quads.
|
||||
|
||||
⚠️ Note the control's own spread: `fill3` measured **18.0** on one run and
|
||||
**31.5** on another. The container's load swings by ~1.75×, so the absolute
|
||||
numbers here are noise-dominated and only the **ordering and the bracket** are
|
||||
load-invariant — which is what `TEMPORAL-VERIFICATION.md` §3 says to prefer, and
|
||||
the reason this conclusion rests on those rather than on any single figure.
|
||||
|
||||
## 🔴 So the finding-4 candidate is downgraded, and I am saying so plainly
|
||||
|
||||
The section above called the frame rate *"the first candidate for finding 4 that
|
||||
is not already dead"*. **That now looks wrong, and it was mine.**
|
||||
|
||||
The quantisation argument still holds — a fade drawn in four steps is not a fade
|
||||
drawn in fifteen — but it only bites at these frame rates, and these frame rates
|
||||
are a property of **software rasterisation in this container**. Five to seven
|
||||
full-screen quads at 720p is nothing to any GPU; on real hardware the port would
|
||||
hit vsync and the fade would get its full 45 steps.
|
||||
|
||||
So unless the human ran the port software-rendered, this is not what they saw,
|
||||
and **every candidate for play-test finding 4 is now dead or near-dead.** That is
|
||||
an honest dead end rather than a lead, and it is written as one: leaving a
|
||||
plausible-sounding cause standing when its own control has undercut it is exactly
|
||||
how *"close but not right"* got explained four different wrong ways.
|
||||
|
||||
**The one thing that would revive it costs the human nothing**: the rate line now
|
||||
prints on every boot. If their next run says 60 fps, this is finished.
|
||||
|
||||
## What the port does NOT need
|
||||
|
||||
* No draw-path optimisation. 161.6 fps empty says the loop is fine, and the
|
||||
screens sit on the fill curve exactly where their quad counts put them.
|
||||
* No texture caching work — already done at `load_screen`, checked last
|
||||
iteration.
|
||||
* No `max_fps` or vsync change. It would not raise the rate here, and it is a
|
||||
presentation decision rather than a defect.
|
||||
|
||||
Reference in New Issue
Block a user