aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakoroka <137927095+Takoroka@users.noreply.github.com>2026-10-29 08:12:52 -0400
committerTakoroka <137927095+Takoroka@users.noreply.github.com>2026-10-29 20:49:47 -0400
commit25bd673899ccdfc58477a286fcc39632feaf9def (patch)
treebd9c0dc7735aad21328d0821cb93ddc6e7f99715
parent6cefcce15f821cd0e65459173cf217bb7e622f43 (diff)
maxwell_3d: no method dispatch for non-executable register writes; notes 133-137
ProcessMethodCall and the draw manager behind it act only on executable methods, so CallMethod stops at the dirty flags for the rest (macro replays write ~2.4 million of those a second). No change beyond run-to-run noise in two profiled runs; it only removes work. Notes: row 133 corrected (those courses are bound by the GPU thread, not the host GPU: 20-40% busy), rows 135-137 (same-value writes, native compute registers, 2D blits).
-rw-r--r--NX2_NOTES.md6
-rw-r--r--src/video_core/engines/maxwell_3d.cpp6
2 files changed, 10 insertions, 2 deletions
diff --git a/NX2_NOTES.md b/NX2_NOTES.md
index 22382c5a2d..98d46d9e78 100644
--- a/NX2_NOTES.md
+++ b/NX2_NOTES.md
@@ -194,8 +194,11 @@ With the patched decoder, games 1/3/4 only leave ~60-110 rare SIMD encodings in
| 130 | measurements | a stuck `nvidia-smi -l` loop had spun one core for 12 h (every run since the evening of 10-28 had one core less); the attract loop shows different courses each run (frame means vary +-15%); stopped test loops kept running and overlapped | compare per-call costs (`C:\dev\nx2work\zones.py` on `EDEN_NX2_GPU_PROFILE` logs); `ab_env.sh` and `hangcheck.sh` refuse to start while eden-cli runs; `stopall.ps1` stops every loop |
| 131 | (title 1) 250-330 MB/s of buffer data copied back at fences (13,000-20,000 ranges a second) | Eden downloads every GPU-written range at the next fence. Measured: the native MME's DMA reads never touched those pages (`EDEN_NX2_GPU_PROFILE` counter), and with reactive flushing the guest CPU read GPU-written memory at most 64 times in 200 s | off for Switch 2 titles (d530bc4, `EDEN_NX2_BUFFER_DOWNLOADS=0/1` forces): fences ~1.1 us (were ~5), draw setup -7%, cache-lock spinning 1.8% |
| 132 | inline uploads 10.5% of the GPU thread | IsRegionGpuModified visited every GPU-written range in the query (they stay fragmented without downloads); std::hash of integers and pointers is FNV-1a on MSVC in every Common::unordered_map | RangeSet::Intersects (one lookup) and a pass-through hash for integer/pointer keys (0fe581f): 7.5% |
-| 133 | some courses (desert/canyon, dense city) bound by the host GPU: presents blocked 9-15 ms on the frame's fence (also before today: t14) | 8 GB laptop GPU: Vulkan usage 6.6-6.9 GB of a 7.1 GB budget; the collector evicts hundreds of decoded ASTC images per 600 frames and they are recreated (GPU ASTC->BC transcode). The two 8192x8192x68 ASTC arrays are already kept as RGBA8 from mip 3 (~380 MB each) | `EDEN_NX2_TC_MIN_AGE=120` (0f0fbb9) made no difference over three runs; open: where the host GPU time goes on those courses |
+| 133 | some courses (desert/canyon, dense city, highway) run 30-45 ms with presents blocked 9-15 ms on the previous frame's fence (also before today: t14) | not the host GPU (nvidia-smi: 20-40% busy, ~22 W) but the GPU thread: ~100% busy there, its command processing 370-420 ms/s instead of 300-350 (more commands per frame). The 8 GB laptop GPU is also near its budget (6.6-6.9 of 7.1 GB): the texture collector evicts hundreds of decoded ASTC images per 600 frames, the buffer collector GPU-written buffers every frame | `EDEN_NX2_TC_MIN_AGE=120` (0f0fbb9) made no difference over three runs; buffer evictions batched into one GPU wait (db4c539), still ~2.7% on those courses (open: asynchronous eviction) |
| 134 | each inline write invalidated the buffer, texture, shader and query caches on its own | thousands of small writes between draws | guest memory written at once, pending query results dropped at once, GPU-written buffer data uploaded in place; the other caches get merged ranges at the next FlushCaching (c06ac80, `EDEN_NX2_INLINE_DEFER=0` off): inline writes 4.4% |
+| 135 | ~6 million 3D register writes a second, ~60% writing the value the register already holds (mostly macro memo replays) | each went through shadow RAM, dirty flags (re-checked at the next draw) and the method switch | state registers (not in execution_mask) written with their value are dropped after shadow RAM processing (f265911, `EDEN_NX2_SKIP_SAME=0` off): macro calls 169 ns instead of 185, draw setup 5.80 us instead of 5.95. For non-executable registers ProcessMethodCall is skipped as well (it acts only on executable ones) |
+| 136 | native compute: ~20% of the GPU thread under KeplerCompute::ProcessNativeMethod (dispatches 8%, inline QMD/uploads 4%) | its compute macros replay ~64 QMD register writes per dispatch, each through the macro/QMD/upload/semaphore checks | plain native registers stored directly from CallMethod (f7a82b2): its own time 2.2% -> 1.6% |
+| 137 | 2D blits (Fermi2D) 3.6% on heavy courses | mip chains 64x64..4x1 copied near the GPU-only regions; neither image is GPU-written, so the software blitter (un)swizzles them on the CPU | open (expected for small copies; many of them) |
Run settings used (in `build/bin/user/config/sdl2-config.ini`): `memory_layout_mode=4`
(12 GB). Debug knobs: `EDEN_NX2_TC_EXPECTED_MIB` / `EDEN_NX2_TC_CRITICAL_MIB` (collector thresholds),
@@ -208,6 +211,7 @@ faulting stack as module+offset, then a minidump), `EDEN_NX2_AUTO_STUB`, `EDEN_N
`EDEN_NX2_FENCE_BATCH=0`, `EDEN_NX2_MACRO_COPY=1`, `EDEN_NX2_CNTPCT_PAUSE=0` (turn rows 124, 126, 127 off),
`EDEN_NX2_MME_MEMO_STATS` (memo counters),
`EDEN_NX2_BUFFER_DOWNLOADS=0/1`, `EDEN_NX2_INLINE_DEFER=0`, `EDEN_NX2_TC_MIN_AGE=<frames>` (rows 131, 134, 133),
+`EDEN_NX2_SKIP_SAME=0` (row 135),
`EDEN_NX2_FRAME_CAPTURE=<dir>` (every 120th presented frame as TGA), `EDEN_NX2_PB_CHECK`
(pushbuffer entries changed between submit and execution), `EDEN_NX2_QUERY_TRACE` (every GPU
report/semaphore write). `C:\dev\crashrun.sh` runs eden-cli under cdb and prints the crash stack;
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp
index f958b025bc..997ef474f5 100644
--- a/src/video_core/engines/maxwell_3d.cpp
+++ b/src/video_core/engines/maxwell_3d.cpp
@@ -466,7 +466,11 @@ void Maxwell3D::CallMethod(Core::System& system, u32 method, u32 method_argument
// million 3D register writes a second, ~60% of them same-value, most from macro replays.
// Methods with side effects (execution_mask: draws, clears, constant buffer data and
// binds, semaphores, ...) always run. EDEN_NX2_SKIP_SAME=0 turns it off.
- if (SkipSameValueWrites() && !execution_mask[method] && regs.reg_array[method] == argument) {
+ if (!execution_mask[method]) {
+ // ProcessMethodCall (and the draw manager behind it) acts only on executable methods.
+ if (!SkipSameValueWrites() || regs.reg_array[method] != argument) {
+ ProcessDirtyRegisters(method, argument);
+ }
return;
}
ProcessDirtyRegisters(method, argument);