forked from Ports/goldeneye-pc-port
D291/D306: close Dam intro truck glitch as faithful; add repro probes
D291 (user-captured) is D306: Dam intro camera 5, truck over the walkway camera; reproduces at FovScale 100. All PC-specific leads refuted with evidence: FOV, depth precision/DrawDistance, depth state (every truck triangle is opaque z-tested), near-plane handling, wheel transforms. The image is a depth-correct view of the authored model from under the truck. GE_ZF's earlier "real fighting" was a +-255 z quantisation artefact. TEMP tools: GE_INTROCAM=<n> pins the level intro's first camera (bondview_r.c, #ifdef PORT, PRNG draw still consumed); GE_D306C depth-state census in gfx_pc.cpp. Golden gate 3/3.
This commit is contained in:
1 parent
f1207e915b
commit
0097469810
6 files changed
+75
-5
No files matched your search
@@ -68,6 +68,8 @@ Two classes:
|
||||
| `GE_D245_FIXEDSHIFT` | `src/game/sky.c:946` (`#ifdef PORT`) | D245 test override: pins the water tc shift `k` to the given integer (0..SKY_TC_MAX_SHIFT) instead of the computed per-vertex value, to A/B the allowShift=TRUE behavior. Off by default (unset = current behavior). | **live, test-only** (D245 OPEN) |
|
||||
| `GE_D252` | `port/fast3d/gfx_pc.cpp:733` (`import_texture`, cached `s_d252`) | D252 rainbow-particle diag: one-shot per (address,size) import log of the tile state (tmem/fmt/siz/addr/size/line) for small textures so a suspect particle tile can be checked against its source bytes by hand. Remove once D252 is resolved. | **live** (D252 OPEN — non-reproducible) |
|
||||
| `GE_D252POOL` | `src/game/image.c` (`texLoad`), `src/game/initmttex.c`, `port/src/gimgfixup.c` | **TEMP** (M-201): one line per new texture load (pool main/other, free bytes) + `POOL-FULL` events + stage pool range; `D252SYNC: N slots re-synced, M changed` per stage load (the D252 fix at work: M>0 from the 2nd stage on). Load-time only, no fps cost. | **TEMP** (D252 fixed; remove after release) |
|
||||
| `GE_D306C="f0 f1 [wmax]"` | `port/fast3d/gfx_pc.cpp` (after `zf_note_emit`) | **TEMP** (M-201): depth-state census of every emitted triangle in frames f0..f1 (GL depth mode, geometry_mode, other_mode_l, tile-0 texture, NDC centroid, z/w range, min w); optional `wmax` keeps near geometry only. Cap 60000 lines. | **TEMP** (D306 closed; remove post-release) |
|
||||
| `GE_INTROCAM=<n>` | `src/game/bondview_r.c` (`#ifdef PORT`, intro camera pick) | **TEMP/test-only**: force the level intro's first camera index (Dam truck shot = 5). The PRNG draw is still consumed. Logs `D306: intro camera index` when set (or with `GE_D306C`). | **TEMP** (useful repro tool) |
|
||||
| `GE_D235` | `src/boss.c` (per-stage `while (!done)` block, after `memaReset`; `#ifdef PORT`) | D235 evidence probe: logs how many GL-texture-cache entries the per-stage `videoResetTextureCache()` call purges at each level load. A cold boot into a level should log 0; a death/restart (or any transition from a level that uploaded textures) logs >0 — direct evidence of the stale-entry mechanism. The clear itself is **not** gated on this var (it's the fix, see below); the var only controls the log line. | **live** (D235) |
|
||||
| `GE_D235_OFF` | `src/boss.c` (same block) | **TEMP** A/B switch: skips the per-stage `videoResetTextureCache()`, i.e. reverts the D235 fix for one run. For comparing a restart with and without the fix. | **TEMP** (D235; remove when D235 closes) |
|
||||
| `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) |
|
||||
|
||||
@@ -169,7 +169,7 @@ D287,OPEN,"User-confirmed real, non-self-recovering freeze on Windows (M-141, 20
|
||||
D288,CLOSED,"Silo intro: a huge, flat-shaded, untextured brown/tan triangle sweeps across the frame during the camera pan down the missile shaft (M-141, user report —… —","CLOSED — not reproduced on the current build (2026-09-23 capture) and the 2026-09-25 user Silo playtest confirms it gone (""silo fixed"")."
|
||||
D289,OPEN,"Dam: a crash in the computer room, not reproducible on a second attempt (M-141, Steam Deck user playtest).","OPEN — needs a human re-test specifically on a build with the D255 fix (this session's release/v0.3.0, not any earlier build) to see if it still happens.…"
|
||||
D290,FIXED,"Watch's in-game ""controller"" section shows no control-pad graphic (M-141, Steam Deck user playtest).","FIXED (2026-09-23): D264-pattern template read in watchRenderController (flags read 0), plus 3 pointer-width/raw-Gfx sites on the same path; controller model verified rendering on Windows."
|
||||
D291,OPEN,"Dam: texture glitches when the truck drives past (M-141, Steam Deck user playtest).","OPEN — observed, not investigated."
|
||||
D291,CLOSED,"Dam: texture glitches when the truck drives past (M-141, Steam Deck user playtest).","CLOSED — duplicate of D306, faithful (M-201, 2026-09-26:"
|
||||
D292,FIXED,Death animations are glitched —,"MOSTLY FIXED as a side effect of D243 (2026-09-18, user-confirmed alongside D173) —"
|
||||
D293,FIXED,"QoL ask: no discoverable way to quit the game from the UI (M-141, Steam Deck user playtest —","FIXED (M-141) — ""Quit to desktop"" row added to the F10 overlay; build-verified Win+Linux, not yet live-confirmed.…"
|
||||
D294,FIXED,"Statue: ground geometry near the large CCCP/hammer-and-sickle monument briefly renders solid black over a wide area, then self-recovers 10-30 seconds later… —","FIXED, user playtest confirmed (2026-09-25:"
|
||||
@@ -184,7 +184,7 @@ D302,FIXED,"Render FPS regression to ~40-45fps on release/v0.3.0 (user QA on the
|
||||
D303,OPEN,"Some muzzle flashes (M16 named specifically, ""and some others"") draw wrong —","OPEN — investigated: pipeline + weapon stats + model conversion ruled out; GE_D303 capture probe in-tree (port/fast3d/gfx_pc.cpp), blocked on a live firing repro."
|
||||
D304,FIXED,"Mouse sensitivity menu overhaul (user request, 2026-09-18):","FIXED — see full entry for both the range/parity pass and the same-day follow-up (collapsed to a single Input.MouseSensitivity menu row + fixed overlayUpdateScroll()'s unconditional bottom-anchor, th…"
|
||||
D305,FIXED,"Steam Deck SIGSEGV on the v0.3.0 pre-release build (Cavern, early in the level, Game.AllUnlocked previously enabled on the session/save) —",FIXED (defensive guard) —
|
||||
D306,OPEN,"Dam intro/truck wheels render with odd transparent-looking areas, possibly z-fighting (user QA, 2026-09-18).",OPEN — confirmed real depth-fighting by the GE_ZF probe (sustained oscillation in the truck region); port-vs-faithful blocked on an N64 reference.
|
||||
D306,CLOSED,"Dam intro/truck wheels render with odd transparent-looking areas, possibly z-fighting (user QA, 2026-09-18).","CLOSED — faithful, confirmed on 1964 (M-201):"
|
||||
D307,OPEN,"In-level security camera entities can be flipped facing the wrong direction (backwards) on some levels, e.g.",OPEN (investigated 2026-09-21) —
|
||||
D308,OPEN,"Occasional z-fighting confirmed on some levels' geometry, general/broader than the D306 truck-wheel instance (user QA, 2026-09-18).","OPEN — investigated: PC depth precision == N64 (24-bit both sides; RSP writes full 16.16), so level-authored coincident geometry is the prime suspect; GE_ZF flicker probe in-tree."
|
||||
D309,FIXED,Complete non-self-recovering freeze (Windows) returning from Caverns to the intro screen —,FIXED via D310 — user-playtest-confirmed 2026-09-18 (Caverns→intro clean; the spin record itself observed resuming correctly in the post-fix probe log).
|
||||
|
||||
|
+23
-2
@@ -577,7 +577,7 @@ covers D24–D69; the log continues in §H (D32 procedure, D70–D121).
|
||||
| D288 | **Silo intro: a huge, flat-shaded, untextured brown/tan triangle sweeps across the frame during the camera pan down the missile shaft (M-141, user report —…** — full `## D288` entry at file tail | CLOSED — not reproduced on the current build (2026-09-23 capture) and the 2026-09-25 user Silo playtest confirms it gone ("silo fixed"). Fixer not isolated (D271 A/B ruled out). |
|
||||
| D289 | **Dam: a crash in the computer room, not reproducible on a second attempt (M-141, Steam Deck user playtest).** — full `## D289` entry at file tail | OPEN — needs a human re-test specifically on a build with the D255 fix (this session's `release/v0.3.0`, not any earlier build) to see if it still happens.… |
|
||||
| D290 | **Watch's in-game "controller" section shows no control-pad graphic (M-141, Steam Deck user playtest).** — full `## D290` entry at file tail | FIXED (2026-09-23): D264-pattern template read in `watchRenderController` (flags read 0), plus 3 pointer-width/raw-Gfx sites on the same path; controller model verified rendering on Windows. |
|
||||
| D291 | **Dam: texture glitches when the truck drives past (M-141, Steam Deck user playtest).** — full `## D291` entry at file tail | OPEN — observed, not investigated. Needs a live repro with the truck's exact position/timing and, ideally, a screenshot. |
|
||||
| D291 | **Dam: texture glitches when the truck drives past (M-141, Steam Deck user playtest).** — full `## D291` entry at file tail | CLOSED — duplicate of D306, faithful (M-201, 2026-09-26: user-captured, Dam intro camera 5 only). Earlier: OPEN — observed, not investigated. Needs a live repro with the truck's exact position/timing and, ideally, a screenshot. |
|
||||
| D292 | **Death animations are glitched — Bond is often sunk halfway into the floor (M-141, Steam Deck user playtest).** — full `## D292` entry at file tail | **MOSTLY FIXED as a side effect of D243 (2026-09-18, user-confirmed alongside D173) — same fix, same outcome: right 9/10 times, small residual offset only when off, no more full sinking/glitching.** See D173 for the user's exact confirmation wording; not separately re-tested, reported together. |
|
||||
| D293 | **QoL ask: no discoverable way to quit the game from the UI (M-141, Steam Deck user playtest — "couldn't see a way to exit the game. Maybe build this into the…** — full `## D293` entry at file tail | FIXED (M-141) — "Quit to desktop" row added to the F10 overlay; build-verified Win+Linux, not yet live-confirmed.… |
|
||||
| D294 | **Statue: ground geometry near the large CCCP/hammer-and-sickle monument briefly renders solid black over a wide area, then self-recovers 10-30 seconds later…** — full `## D294` entry at file tail | **FIXED, user playtest confirmed (2026-09-25: not reproduced)** — root cause: room-model POOL exhaustion (authored `-ma220`=220 KB < ~250 KB monument-plaza demand at FovScale 130 + max DD/Lod); `memaAlloc` NULL → silent skip → undrawn room shows the night-sky clear colour. Stochastic (wall-clock seed → load order). Fix: `portRoomPoolScale()` (video.c, identity at N64-faithful settings) applied in `bossMainloop`; verified headless (faithful→exact authored size; user settings→0 failures; `GE_ROOMPOOL=0.25`→exhaustion on demand). Playtest: main patch gone; residual corner flicker traced to full-level residency (487 KB = 2.2× authored) starving the 2× pool; the 3×/linear fix REGRESSED the renderer on the menu-driven path (D156 NaN anim state, not a bank overflow) → reverted to sqrt + 2.0 cap (ma=450560). Residual open; probes in place for next capture. High-DD horizon edge on night levels = setting-inherent, documented only.… |
|
||||
@@ -592,7 +592,7 @@ covers D24–D69; the log continues in §H (D32 procedure, D70–D121).
|
||||
| D303 | **Some muzzle flashes (M16 named specifically, "and some others") draw wrong — the flash renders very long, extending straight up from the gun (user QA on the v0.3.0 pre-release build, 2026-09-18).** — full `## D303` entry at file tail | OPEN — investigated: pipeline + weapon stats + model conversion ruled out; GE_D303 capture probe in-tree (`port/fast3d/gfx_pc.cpp`), blocked on a live firing repro. |
|
||||
| D304 | **Mouse sensitivity menu overhaul (user request, 2026-09-18): aim speed/turn speed sliders weren't "1:1", had too little range, and (follow-up) risked decoupling into a bad state; F10 menu also had a click-jump bug.** — full `## D304` entry at file tail | FIXED — see full entry for both the range/parity pass and the same-day follow-up (collapsed to a single `Input.MouseSensitivity` menu row + fixed `overlayUpdateScroll()`'s unconditional bottom-anchor, the actual cause of the reported "menu jumps to the setting below on click"). Build-verified (Windows) both passes; headless overlay smoke test clean after each. **Live F10 playtest done (2026-09-18): user confirmed the collapsed single-sensitivity menu works, the click-jump is gone, and the D251 bottom-row duplication no longer occurs.** |
|
||||
| D305 | **Steam Deck SIGSEGV on the v0.3.0 pre-release build (Cavern, early in the level, `Game.AllUnlocked` previously enabled on the session/save) — same exact FAULT ADDR 0x62 / `sndHandleEvent` signature as D285, reproduced AFTER D285's own lock fix was already live-verified crash-free on real hardware.** — full `## D305` entry at file tail | FIXED (defensive guard) — `sndHandleEvent`'s preempt-scan (`src/snd.c`) dereferenced its list-walk pointer before ever checking it for NULL (a do-while always runs its body once); D285's `osSetIntMask` lock only prevents another thread from emptying the list mid-scan, not a scan that starts with an already-empty list, so the crash could still happen even with that fix in place. Added the missing `iterState != NULL` guard before the loop, matching D255's established skip-instead-of-dereference precedent. Root desync mechanism (why pool-exhaustion accounting and the list can disagree) still not identified; `Game.AllUnlocked` correlation not proven, only reported. **Live-verified on the Deck (2026-09-18):** user ran two test sessions on Cavern with the updated build, plus toggled `Game.AllUnlocked` off then back on and relaunched — no crash in any of them. |
|
||||
| D306 | **Dam intro/truck wheels render with odd transparent-looking areas, possibly z-fighting (user QA, 2026-09-18).** — full `## D306` entry at file tail | OPEN — confirmed real depth-fighting by the GE_ZF probe (sustained oscillation in the truck region); port-vs-faithful blocked on an N64 reference. |
|
||||
| D306 | **Dam intro/truck wheels render with odd transparent-looking areas, possibly z-fighting (user QA, 2026-09-18).** — full `## D306` entry at file tail | CLOSED — faithful, confirmed on 1964 (M-201): all PC-specific leads refuted (FOV, depth precision, depth state, near plane, wheel transforms); it is the authored truck geometry seen from intro camera 5 under the truck. Absorbs D291. Earlier GE_ZF "real fighting" was a probe-quantisation artefact. |
|
||||
| D307 | **In-level security camera entities can be flipped facing the wrong direction (backwards) on some levels, e.g. Bunker (user QA, 2026-09-18) — NOT the player's view camera.** — full `## D307` entry at file tail | OPEN (investigated 2026-09-21) — no port-side bug found: orientation path traced, every input verified N64-faithful vs ROM (`PcctvZ` switch data, room-scaled boundpads, config words), all math byte-identical `src/game`. Blocked on user repro detail; `GE_D307=1` diagnostic in-tree. |
|
||||
| D308 | **Occasional z-fighting confirmed on some levels' geometry, general/broader than the D306 truck-wheel instance (user QA, 2026-09-18).** — full `## D308` entry at file tail | OPEN — investigated: PC depth precision == N64 (24-bit both sides; RSP writes full 16.16), so level-authored coincident geometry is the prime suspect; GE_ZF flicker probe in-tree. |
|
||||
| D309 | **Complete non-self-recovering freeze (Windows) returning from Caverns to the intro screen — boss thread spins forever in `ai()` on `m_RunToBondPersistent` via a phantom `GotoNext(lblZero)` created by `chraiitemsize`'s `AI_PRINT` NUL-scan mis-sizing a stringless PRINT record (user report + live GDB diagnosis, 2026-09-18).** — full `## D309` entry at file tail | **FIXED via D310 — user-playtest-confirmed 2026-09-18** (Caverns→intro clean; the spin record itself observed resuming correctly in the post-fix probe log). The teardown-ordering open question (why PC presents the unreachable-Bond state) remains documented but is now harmless. |
|
||||
@@ -11792,6 +11792,10 @@ Superseded history below (the original OPEN investigation, root cause not found
|
||||
**Status:** OPEN; still needs the playtest item (Dam: watch the truck pass, F12 screenshot if glitched, note whether it's the wheels, i.e. D306).
|
||||
|
||||
|
||||
**2026-09-26 (M-201): merged into D306.** Captured by the user: intro-only (Dam level intro/attract, truck over the walkway camera), wheels drawing through the body; reproduces at FovScale 100. Tracked under D306 from here.
|
||||
|
||||
**Status: CLOSED with D306 (faithful).**
|
||||
|
||||
## D292 — Death animations are glitched — Bond is often sunk halfway into the floor (M-141, Steam Deck user playtest).
|
||||
|
||||
**Death animations are glitched — Bond is often sunk halfway into the floor (M-141, Steam Deck user playtest).** **User confirms this is the same broader "Bond's world model is positioned wrong" problem as D173** — not a new/separate mechanism, another surface of the same known-but-under-investigated bug. The umbrella is already tracked: `GRAPHICS-BACKLOG.md` D148 is explicitly "the tracking entry for the whole cutscene-reliability problem," already lists D173 (floating at level start / Cuba credits) and a Cradle instance ("Bond spins in circles" during the Trevelyan-falls cutscene) under it — findings.md's D173 entry has the fullest investigation detail (M-106's two ruled-out D209-style struct-aliasing candidates, LOW-MEDIUM confidence that class is even the right one). Nothing has actually been lost — the write-up just isn't concentrated in one place (split across `GRAPHICS-BACKLOG.md` D148/D173 and `findings.md` D173), which reads as "known but not detailed" unless you go looking. Sunk-into-floor is a third concrete instance of the family (level-start floating, cutscene spin, now death-pose sinking) — worth keeping as one thread when it's next investigated live, since a single root cause (most likely the render-side puppet/joint transform, not collision) could explain all three.
|
||||
@@ -12331,6 +12335,23 @@ do {
|
||||
|
||||
**Status:** OPEN — confirmed as real z-fighting by probe; port-vs-faithful question open (see D308).
|
||||
|
||||
**2026-09-26 (v0.4.0, M-201): D291 is this same bug; FOV ruled out.** User captured the D291 "Dam truck" glitch with F12: it happens only on the Dam level intro (also the attract demo), in the shot where the truck drives over the low walkway camera (~frames 280–440 from `-level_33` boot). Wheels and tyre treads draw through the mudguards/body. It reproduces at **FovScale 100** (user re-test, `scratch/d291_shots/fov100_full.png`) as well as at 150 + native widescreen (`shot_000..003.png`), so the port's wider cutscene FOV is not what exposes it. Headless A/B at default vs user settings: `scratch/d291_AB.png` (runs not frame-locked; `GE_ZF` hit its 600-line cap in both). Occlusion-state path checked in passing: fast3d honours `G_ZBUFFER`/`G_ZS_PRIM`/`Z_CMP`/`Z_UPD` per triangle (`gfx_pc.cpp` depth_mode), so no obvious state gap. **Still gated on an N64/emulator reference of this exact shot** (porting-notes D12): if the N64 shows clean wheels there, the fight is PC-specific and the next suspect is the vehicle model's per-part transforms at extreme close range; if it shows the same, close as faithful.
|
||||
|
||||
**2026-09-26 (M-201, user: "investigate the PC-specific leads"): every PC-specific lead refuted; the artifact is the authored truck geometry seen from under the truck.**
|
||||
|
||||
- **Repro pinned:** Dam has 6 intro cameras and picks the first at random (`bondview_r.c`, `randomGetNext() % g_SetupIntroCameraCount`); the truck-over-walkway shot is **index 5**. New TEMP `GE_INTROCAM=5` forces it (PRNG draw still consumed). `GE_RSEED` does not reliably select it. With it pinned the truck passes at ~frames 280–320 (60 fps), and frame 280 at **default settings** (640x480/1280x720, FovScale 100) shows the same tread-slab look as the user's captures.
|
||||
- **FOV:** refuted (user re-test at FovScale 100).
|
||||
- **Depth precision / DrawDistance:** refuted. DrawDistance does move the far plane (`bgfog.c` → `viSetZRange`), but perspective depth resolution near the camera is set by the near plane; at the truck's range (w ≈ 280–790) 24-bit depth resolves far below the tyre↔mudguard separation, so these non-coplanar surfaces cannot precision-fight at any setting.
|
||||
- **Depth state:** refuted. TEMP `GE_D306C="f0 f1 [wmax]"` census (per emitted triangle: GL depth mode, geometry_mode, other_mode_l, tile-0 texture, NDC, z/w, min w): every truck triangle is `dm=07` (test+compare+update, ZMODE_OPA, `G_ZBUFFER` on). The only no-compare near geometry (`dm=01`, `oml=c8102048`) is the walkway/ground under the camera, and 2D text is `dm=00`.
|
||||
- **Near plane:** refuted. Truck triangles have w ≥ 278, no eye-plane crossings; only the ground under the camera crosses w=0, and GL clips it in homogeneous space.
|
||||
- **Wheel transforms:** refuted. TEMP wheel-state log (removed): `wheelyrot` = 0 through the straight run, `wheelxrot` advances normally, radius/scale constant; the one ~20° steering blip (t≈530, `turnrot60`=0.0026) is the original formula's response and is outside the overhead pass. The wheel code uses named fields only (no A1 raw-offset reads).
|
||||
- **Conclusion:** the rendered image is a depth-correct depiction of the geometry (correct depth state, sane z/w, sane transforms, ROM model data). The camera sits under the truck, where the model's wheel/mudguard construction (tyres passing through the arches, open-backed panels) is visible; it is not seen from normal gameplay angles. **Faithful with high confidence**; an N64/emulator frame of intro camera 5 would make it certain.
|
||||
- **Probe-quality correction:** `GE_ZF` quantises NDC z to ±255 (`z24 = ndc_z*255`, not 24-bit as its comment says) with tolerance 2, so it flags unrelated nearby surfaces as "oscillating". The 2026-09-18 "confirmed real depth-fighting" was over-read and should not be cited as evidence of a fight.
|
||||
|
||||
**N64 reference (user, 2026-09-26):** the same shot on the 1964 emulator (GEPD bundle) shows the same wheel/body fighting as the port. Confirmed faithful.
|
||||
|
||||
**Status: CLOSED — faithful, confirmed against 1964 (authored geometry; no PC-specific cause). D291 closes with it.**
|
||||
|
||||
## D307 — In-level security camera entities can be flipped facing the wrong direction (backwards) on some levels, e.g. Bunker (user QA, 2026-09-18).
|
||||
|
||||
**Reported only, not investigated, explicitly not for v0.3.0.** User playtest: on some levels (Bunker named specifically), the in-level **security camera props/entities** — the gameplay objects that spot the player and alert guards, not the player's own view camera — can end up facing backwards (the wrong direction) "for some reason." No further repro detail given (trigger condition, whether it self-corrects, whether it's tied to a specific spawn/setup path). No code read done. **Correction (same day): initially misread as the player's view camera — clarified by the user to mean the in-level security camera entities specifically.**
|
||||
|
||||
@@ -1249,7 +1249,7 @@ produce the same visual symptom but need opposite fixes.
|
||||
|
||||
When a user reports z-fighting, do NOT assume the software renderer has less depth precision than the RDP. Verified for GE: the RSP's vertex transform (`rsp/graphics/gmain.s`) writes post-transform x/y/z/w back to the vertex buffer as **full 32-bit 16.16 fixed-point** (`sdv` stores), not s16 8.8 — the RDP interpolates from full-precision NDC and quantizes once, into its 24-bit z-image. The port keeps floats through `gfx_sp_vertex` and writes a `GL_DEPTH24_STENCIL8` buffer: same or better precision at every stage, same near/far. So coincident geometry authored into the level fights on both platforms; a PC-only explanation needs positive evidence (an N64 reference of the same spot), not just the existence of the symptom. A mitigation like switching to 32-bit float depth would *reduce* fighting but diverge from N64 behavior — that's a rule-2-style decision, not a silent fix.
|
||||
|
||||
**Probe technique that worked (vs. three variants that didn't):** detecting z-fighting from emitted triangles requires filtering out (a) tessellation gradients — adjacent tris of one surface have near-equal depths by construction — and (b) camera-motion coincidences — as the camera moves, unrelated world points pass through the same screen cell and their depths happen to sit close. What survives both: a coarse screen-cell grid keeping a short per-cell depth history, flagging only **non-monotonic** (a-b-a) oscillation within a small tolerance that **recurs many times at the same cell**. Monotonic drift = gradient; one-off close pairs = motion artifact; sustained recurrence = a real fight. `GE_ZF` in `port/fast3d/gfx_pc.cpp` implements this (`GE_ZFTOL` tolerance, `GE_ZFBOX` region filter).
|
||||
**Probe technique that worked (vs. three variants that didn't):** detecting z-fighting from emitted triangles requires filtering out (a) tessellation gradients — adjacent tris of one surface have near-equal depths by construction — and (b) camera-motion coincidences — as the camera moves, unrelated world points pass through the same screen cell and their depths happen to sit close. What survives both: a coarse screen-cell grid keeping a short per-cell depth history, flagging only **non-monotonic** (a-b-a) oscillation within a small tolerance that **recurs many times at the same cell**. Monotonic drift = gradient; one-off close pairs = motion artifact; sustained recurrence = a real fight. `GE_ZF` in `port/fast3d/gfx_pc.cpp` implements this (`GE_ZFTOL` tolerance, `GE_ZFBOX` region filter). **Caveat (M-201):** `GE_ZF` actually quantises NDC z to ±255, not 24 bits, so at its default tolerance it flags unrelated nearby surfaces; treat a hit as a lead, not proof. Before calling anything "z-fighting", check the separation against the near plane: at close range 24-bit depth resolves far finer than any non-coplanar model parts, so "whole surfaces in the wrong order" there is depth *state* or geometry, not precision. Use `GE_D306C` (per-triangle depth-state census) for that; D306 turned out to be authored geometry seen from an unusual camera.
|
||||
|
||||
## D13. Per-render accumulation is not associative: the port's 1 tick/frame can reach states the N64's 2–3 ticks/frame never did (D329)
|
||||
|
||||
|
||||
@@ -2637,6 +2637,40 @@ static void gfx_sp_tri1(uint8_t vtx1_idx, uint8_t vtx2_idx, uint8_t vtx3_idx, bo
|
||||
d75d_note_emit(videoGetFrameCount(), v_arr); // survived all rejection gates -> reaches GL
|
||||
d303_note_emit(videoGetFrameCount(), v_arr); // TEMP D303
|
||||
zf_note_emit(videoGetFrameCount(), v_arr); // TEMP D306/D308
|
||||
/* TEMP D306 (M-201): depth-state census of emitted triangles in a frame
|
||||
* window, GE_D306C="f0 f1". One line per tri: depth flags as sent to GL,
|
||||
* geometry_mode, other_mode_l, tile-0 texture, NDC centroid, z/w range and
|
||||
* min w (<=0 = crosses the eye plane). Cap 60000. */
|
||||
{
|
||||
static int d306c = -1; static uint32_t d306f0 = 0, d306f1 = 0, d306n = 0; static float d306wmax = 1e30f;
|
||||
if (d306c < 0) {
|
||||
const char* e = getenv("GE_D306C");
|
||||
d306c = (e && sscanf(e, "%u %u %f", &d306f0, &d306f1, &d306wmax) >= 2) ? 1 : 0;
|
||||
}
|
||||
const uint32_t fc = videoGetFrameCount();
|
||||
if (d306c && fc >= d306f0 && fc <= d306f1 && d306n < 60000) {
|
||||
float cx = 0, cy = 0, zmin = 1e9f, zmax = -1e9f, wmin = 1e9f;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
const float w = v_arr[i]->w;
|
||||
if (w < wmin) wmin = w;
|
||||
if (w > 0.f) {
|
||||
const float zn = v_arr[i]->z / w;
|
||||
cx += v_arr[i]->x / w; cy += v_arr[i]->y / w;
|
||||
if (zn < zmin) zmin = zn;
|
||||
if (zn > zmax) zmax = zn;
|
||||
}
|
||||
}
|
||||
cx /= 3.f; cy /= 3.f;
|
||||
if (wmin > d306wmax) goto d306c_skip; /* optional 3rd arg: near geometry only */
|
||||
{
|
||||
const void* t0 = rendering_state.textures[0] ? (const void*)rendering_state.textures[0]->first.texture_addr : nullptr;
|
||||
d306n++;
|
||||
fprintf(stderr, "D306C f=%u dm=%02x geom=%08x oml=%08x tex0=%p c=(%.3f,%.3f) z=[%.5f,%.5f] wmin=%.2f\n",
|
||||
fc, rendering_state.depth_mode, rsp.geometry_mode, rdp.other_mode_l, t0, cx, cy, zmin, zmax, wmin);
|
||||
}
|
||||
}
|
||||
d306c_skip:;
|
||||
}
|
||||
d75d_note_emit_z(videoGetFrameCount(), v_arr, (used_textures[0] || used_textures[1]) ? 1 : 0, comb->used_textures[0] ? 1 : 0);
|
||||
for (int i = 0; i < 3; i++) {
|
||||
float z = v_arr[i]->z, w = v_arr[i]->w;
|
||||
|
||||
@@ -372,6 +372,19 @@ void bondviewLoadSetupIntroSection(void)
|
||||
{
|
||||
ptr_random06cam_entry = g_CurrentSetupIntroCamera;
|
||||
rand_camera_index = (s32)(randomGetNext() % (u32) g_SetupIntroCameraCount);
|
||||
#ifdef PORT
|
||||
/* TEMP D306 (M-201): test-only override of the first intro camera,
|
||||
* GE_INTROCAM=<n> (n < count). The PRNG draw above still happens, so
|
||||
* the rest of the random sequence is unchanged. Inert unset. */
|
||||
{
|
||||
extern char *getenv(const char *name);
|
||||
extern int atoi(const char *s);
|
||||
const char *ic = getenv("GE_INTROCAM");
|
||||
if (ic || getenv("GE_D306C")) osSyncPrintf("D306: intro camera index %d of %d%s\n", (int)rand_camera_index,
|
||||
(int)g_SetupIntroCameraCount, ic ? " (GE_INTROCAM override)" : "");
|
||||
if (ic) rand_camera_index = (s32)((u32)atoi(ic) % (u32)g_SetupIntroCameraCount);
|
||||
}
|
||||
#endif
|
||||
while (rand_camera_index > 0)
|
||||
{
|
||||
rand_camera_index--;
|
||||
|
||||
Reference in new issue
Block a user