mirror of
https://github.com/jkdansereau/goldeneye-pc-port.git
synced 2026-10-23 15:52:42 +02:00
D339 (#92): GE_PERFSTAT perf probe + measured CPU budget (CPU likely not the low-end bottleneck; GPU suspect)
Env-gated per-frame timing: render phases, tris/batches, game-thread busy, GL_TIME_ELAPSED GPU timer. Measured ~2.1 ms/frame total CPU on the heaviest levels here; the GPU timer is only meaningful when GPU-bound. Target-hardware numbers needed before a low-end preset. Golden 3/3; Win + Linux builds.
This commit is contained in:
1 parent
02c361c909
commit
36de85e789
6 files changed
+134
No files matched your search
@@ -72,6 +72,7 @@ Two classes:
|
||||
| `GE_D235_RELOAD=<frames>` | `src/boss.c` (same block + `bossMainloop` retrace branch) | **TEMP** reload harness: once the title stage loads after the first level (e.g. after a scripted watch Abort), wait `<frames>` retraces, then re-enter that level via `bossSetLoadedStage()`, the front end's own mission-start call. A headless death/restart without the pointer-menu walk. Pair with `GE_INPUTSCRIPT="800:START;1200:A;1300:RIGHT;1400:A"` (abort) on `-level_XX`. | **TEMP** (D235; remove when D235 closes) |
|
||||
| `GE_D235_NEXT=<stage id>` | `src/boss.c` (with `GE_D235_RELOAD`) | **TEMP**: re-enter a *different* stage after the abort (level A → title → level B), used for D336 (Runway → Frigate). `GE_D85TEX=1` now also logs each stage's texture-pool size and address range (`src/game/initmttex.c`). | **TEMP** |
|
||||
| `GE_AIMLOG=1` (+ `GE_INPUTSCRIPT` tokens `MDX<n>` `MDY<n>` `RHOLD` `LHOLD` `RREL`) | `port/src/input.c` | D337 aim-model harness: scripted sustained mouse deltas (treated as a grabbed mouse) and aim holds, plus a per-poll line with aim state, active device, the game's drawn crosshair x, `crosshair_x/y_pos` and camera angles. Measures range, edge-scroll and jitter headlessly. | **live** |
|
||||
| `GE_PERFSTAT=1` | `port/fast3d/gfx_pc.cpp` (`gfx_run`/`gfx_end_frame`), `port/fast3d/gfx_opengl.cpp` (start/end_frame), `src/boss.c` (main loop) | #92/D339 perf probe: per-300-frame averages of render phases (pre / display-list / post / swap+pace), tris and draw batches per frame, game-thread busy time per scheduler message, and a GL_TIME_ELAPSED GPU timer (meaningful only when GPU-bound). | **live** |
|
||||
| `GE_D75V` | `port/fast3d/gfx_pc.cpp` (`gfx_sp_vertex`, end of the copy/transform loop; cached env check) | D75 (Nintendo logo) per-batch vertex probe: for each `G_VTX` batch in frames `lo..hi`, logs frame#, source pointer, n_vertices, original dest_index, raw ob[0..2] of the first vertex, min/max of the transformed x/y/z/w across the batch, and the MP translation row. Used to prove the transform is correct (M-195) and that every batch encodes v0=0 (slot-overwrite hypothesis). Value form `"lo-hi"` (e.g. `300-900` = the logo screen); unset = off. | **live** (D75) |
|
||||
| `GE_D75D` | `port/fast3d/gfx_pc.cpp` (`gfx_sp_vertex` G_VTX case + `gfx_sp_tri1` rejection/emit gates; cached env check) | D75 (Nintendo logo) per-frame draw-path probe (M-196): for frames `lo..hi`, logs one line/frame with the V/T token stream (`seq`), max triangle vertex index, cumulative vertices loaded, and per-triangle accounting — trivial-reject / backface-cull counts, how many tris reach GL, how many of those are on-screen (NDC bbox ⊂ [−1,1]²), invisible-flag count, vertex-color min/max, first oml word, depth z/w range + NaN count, texture-sampler presence (`utex` = GL shader, `cutex` = combiner), combine mode, prim/env color. Used to REFUTE the slot-overwrite hypothesis (DL is streamed, max index 15) and narrow the bug to a texture-modulate material rendering black. M-197 added logo-mode `lg_*` fields (sampled only on tris with the logo combine word — the frame-level `utex`/`cutex` are first-tri-wins and were the source of the "combiner claims 0" false anomaly): `lg_utex`/`lg_tex` + tile-0 descriptor + texture buffer address/id/size for the logo material. Value form `"lo-hi"` (logo window ≈ `244-320` on a bare front-end boot); unset = off. Companion one-shot `D75DCC:` log in `gfx_generate_cc` fires when `combine_mode==0x009ffe4f19ffe4f1` to decode the logo's combine slots. | **live** (D75) |
|
||||
|
||||
|
||||
@@ -216,3 +216,4 @@ D335,?,"Native widescreen, HUD + front end (WIDESCREEN-FOV-PLAN Phase 3):","IMPL
|
||||
D336,FIXED,"Frigate (and any level) ""all polygons break except the gun"" after turning:","FIXED (src/game/bondhead.c #ifdef PORT, ABI/layout); headless repro (Runway → exit → Frigate → turn, D294 2× room pool) clean, D156 0 fires; golden 3/3; Win + Linux builds."
|
||||
D337,OPEN,Aim modes folded (user decision):,IMPLEMENTED (port/src/input.c + optionsoverlay.c); headless-measured with new scripted-mouse harness; golden 3/3; Win + Linux builds.
|
||||
D338,?,"Input.AimRange (F10 ""Aim range""):","IMPLEMENTED + measured (PC 98%/72%, N64 65%/49%); golden 3/3; Win + Linux builds."
|
||||
D339,PARTIAL,"#92 (low-end ~30 fps, Celeron N3060 / HD 400) —",INVESTIGATING — probe landed; target-hardware numbers needed before any fix.
|
||||
|
@@ -624,6 +624,7 @@ covers D24–D69; the log continues in §H (D32 procedure, D70–D121).
|
||||
| D336 | **Frigate (and any level) "all polygons break except the gun" after turning: Bond's head-bob anim read two never-written placeholder fields (`field_5C0`, `animFlipFlag`) that on N64 are raw-offset aliases into the inline `player.model` (D100 follow-up; A1 class). Likely the D311 upstream anim-poison source.** — full `## D336` entry at file tail | FIXED (src/game/bondhead.c `#ifdef PORT`, ABI/layout); headless repro (Runway → exit → Frigate → turn, D294 2× room pool) clean, D156 0 fires; golden 3/3; Win + Linux builds. **User-confirmed 2026-09-24.** |
|
||||
| D337 | **Aim modes folded (user decision): N64 (default) = the N64 aim model with the mouse fed through the game's integrator at PD's damp (D332 made default); CENTRED (PC) opt-in; Q/L and Toggle-aim now route mouse aim like RMB; pad/keyboard aim no longer swallowed by the mouse integration.** — full `## D337` entry at file tail | IMPLEMENTED (port/src/input.c + optionsoverlay.c); headless-measured with new scripted-mouse harness; golden 3/3; Win + Linux builds. Open: N64-range calibration decision. |
|
||||
| D338 | **`Input.AimRange` (F10 "Aim range"): PC (default, GEPD/mouse-injector full-screen crosshair) or N64 (original stick limits: 65% of half-width, camera turn from ~49%).** — full `## D338` entry at file tail | IMPLEMENTED + measured (PC 98%/72%, N64 65%/49%); golden 3/3; Win + Linux builds. |
|
||||
| D339 | **#92 (low-end ~30 fps, Celeron N3060 / HD 400) — measured CPU budget: game thread ~0.2–0.35 ms/frame, render-thread display-list pass 0.4–1.8 ms/frame on this box; CPU very likely not the bottleneck. New `GE_PERFSTAT=1` probe (render phases, tris/batches, game-thread busy, GPU timer query).** — full `## D339` entry at file tail | INVESTIGATING — probe landed; target-hardware numbers needed before any fix. |
|
||||
|
||||
Phase 2 replaced the Phase-1 demo loop with the real `mainproc()` on real OS
|
||||
threads, compiled GE's real `src/sched.c`, and brought in PD's fast3d software
|
||||
@@ -13304,3 +13305,22 @@ Implemented as `Input.PdMouseAim` (**default off**, because it changes aim feel)
|
||||
**User decision (D337 follow-up):** keep the GEPD / mouse-injector feel (the crosshair reaches the screen edge, edge-scroll from 72%) as the PC default even though it isn't N64-exact, and offer the original behaviour as an option. **`Input.AimRange`** 0 = PC, 1 = N64 (F10 "Aim range", hidden while the aim style is Centred (PC)). N64 derivation: aim turn is `stick × 0.65/80` per tick, so full deflection settles at a drawn offset of 0.65 × half-width regardless of weapon damp (`screen = pos × (1−damp) × W/2`, gunfire.c), and the camera turns past stick 60/80 = 75% of that range. Implementation: the mouse accumulator is unchanged; its screen mapping is scaled by 0.65 (PD turn and legacy GEPD write alike) and the edge-scroll threshold moves to 0.75. The non-aim "adopt" of the game crosshair into the accumulator now converts through the game's screen mapping and the range scale, so aim entry never jumps (it copied raw units before, a small pre-existing mismatch on the PD path). **Measured (GE_AIMLOG harness, 3 px/poll sweep):** PC max drawn x 316/320 (98%, the game's 4 px edge clamp), camera turn from 72%; N64 max 264 (65%), camera turn from 237.9 px (49%); aim entry at 160 (centre) in both. Golden 3/3; Windows + Linux builds clean.
|
||||
**D337/D338 user feel check (2026-09-24):** "Seems good." The session exercised the legacy-key migration live: the user's ini had `AimStyle = 2` (Centred) from D333 testing and loaded as `AimMode = 1` as designed. User's ini then set back to `AimMode = 0` (N64, their stated preference), `AimRange = 0` (PC).
|
||||
|
||||
## D339 — #92 low-end performance: CPU budget measured, GPU the likely bottleneck; GE_PERFSTAT probe (2026-09-24)
|
||||
|
||||
**Report (#92, filed by the maintainer for a user):** Celeron N3060 (2C, 1.6 GHz) + Intel HD 400 (Bay Trail), Windows 10: the port runs ~30 fps, "a bit higher in enclosed areas", while the PD PC port holds 60 on the same machine.
|
||||
|
||||
**Probe (`GE_PERFSTAT=1`, env-gated, zero cost when unset):** `port/fast3d/gfx_pc.cpp` averages over 300 frames: `pre` (frame setup), `dl` (display-list pass = software RSP + GL draw submission), `post` (MSAA resolve / end_frame), `swap/pace` (swap_buffers_begin, which contains the D186 frame-pacing wait), triangles and draw batches per frame. `src/boss.c` reports game-thread busy time per scheduler message (~2 messages/frame). `port/fast3d/gfx_opengl.cpp` adds a double-buffered `GL_TIME_ELAPSED` GPU timer (logged with `GL_RENDERER`/`GL_VERSION`).
|
||||
|
||||
**Measured (this machine: RTX 5090, fast desktop CPU; 1280×720, defaults):**
|
||||
|
||||
| Level | dl (ms) | tris/frame | batches/frame | game thread (ms/frame) |
|
||||
|---|---|---|---|---|
|
||||
| Bunker 1 | 0.32–0.39 | ~560 | ~99 | ~0.2 |
|
||||
| Dam | 1.24 | ~2,700 | ~233 | — |
|
||||
| Streets | 1.69–1.71 | ~3,080 | ~411 | ~0.35 |
|
||||
| Egypt | 1.77–1.79 | ~3,560 | ~322 | ~0.3 |
|
||||
|
||||
`pre`/`post` ≈ 0; `swap/pace` ≈ 2 ms is the pacing wait, not work. **CPU cost scales with scene complexity** (matching the reporter's "higher in enclosed areas"), but totals only ~2.1 ms/frame at the heaviest. Scaled for an N3060 (~5× slower per core, logic and render on separate threads), that's roughly 2 + 9 ms on two cores, which fits in 16.7 ms. CPU is therefore unlikely to be what pins the reporter at 30. **GPU is the prime suspect:** an HD 400 at native resolution with the port's defaults (MSAA 4×, 16× anisotropic, the 3-point filter shader) against the PD port's lighter defaults. **GPU timer caveat:** on this RTX 5090 the query read 1.7 ms at defaults and 4.1 ms at MSAA 1 / aniso 1 / bilinear, an inversion that shows the timer also captures swap-chain back-buffer waits on the direct (non-FBO) path. It is only meaningful on a GPU-bound machine (it would then read close to the frame time).
|
||||
|
||||
**Next (needs HD 400-class hardware, not reporter logs):** run `GE_PERFSTAT=1` on a comparable machine at defaults vs MSAA 1 / aniso 1 / bilinear; if GPU-bound, consider a first-run low-end preset (the Steam Deck preset, `da31edaa`, is the precedent) keyed on the GL renderer. CPU-side headroom if ever needed: batches per frame (100–411) is the obvious lever (state-change batching in `gfx_flush`).
|
||||
|
||||
Reference in new issue
Block a user