Cache D3D12 recording lookups without retaining game resources

This commit is contained in:
Codex committed 2026-10-01 20:23:08 +03:00
1 parent 73ee2e5ecc
commit 74aad12938
10 files changed
+268 -13

No files matched your search

+2
View File
@@ -53,6 +53,8 @@ command-list split/replay, submitted state publication and suffix completion.
The recording interval measures NGX calls on the recording thread, not Present.
`-ProfileKernels` enables synchronizing HIP-event kernel profiling and changes
frame scheduling; use it separately from a production FPS measurement.
`-ProfileCommandHooks` samples one in 64 D3D12 interceptions to distinguish
tracking/lock waits from driver calls. It is disabled in ordinary runs.
The runner drains stdout/stderr concurrently as raw bytes; the earlier
line-oriented PowerShell collector imposed large per-frame delays. The optional
ZLUDA kernel profiler is for diagnostics only. Measurements and reproduction
+34
View File
@@ -138,5 +138,39 @@ The installer accepts them with `-LocalTextureKernels` only after validation,
checking the exact DLL identity, object and manifest hashes. M retains its
independently validated FP16-equivalent baseline.
The following no-debugger K/4K run completes 9982 frames and 9982 finite GPU
scans. Kernel event profiling is disabled; the validated private output tail
executes natively. The user reports 43-47 FPS. Mean NGX recording interval is
21.867 ms. No backend failure, CPU image copy or previous-frame output occurs.
Random one-in-64 hook samples then identify contention in the shared routing
table used by every intercepted D3D12 command. Per-thread weak lookup caches
now bypass that table on repeated calls to a list. Table mutations invalidate
cache generations; Reset/address reuse cannot route to a previous suffix, and
thread caches do not retain game resources. The per-list and submission locks
remain. A GPU regression resets and re-splits the exact same list with changed
root constants twice per iteration, checking both prefix and suffix results.
| Sampled command-hook access | Shared table | Per-thread weak cache |
| --- | ---: | ---: |
| Busiest recording thread, mean us/call | 0.203 | 0.066 |
| Estimated access + capture across threads, ms/s | 977.528 | 233.606 |
The latter estimate includes lock waits summed across concurrently running
threads, not CPU execution time or serial frame latency. The two game runs
have different thread populations (31 versus 29); there is no identical frame
trace. Generated forwarding methods have separate driver/capture markers;
special-case hooks contribute access samples but lack those body markers.
With the cache, 4770 complete K/4K frames and finite GPU scans pass, with zero
backend failures, CPU image copies or previous-frame output. Median NGX
recording interval is 19.473 ms. The user reports 49-51 FPS and 53% GPU usage
in the previously measured scene. These user readings are separate from the
sampled hook estimates and do not establish isolated WMMA utilization.
All sixteen CTest gates pass, including 64 same-object Reset/split checks in
each physical command-backend test and the software indirect-root regression.
Use `-ProfileCommandHooks -ProfileStages` to collect samples; the sampler is
disabled for ordinary play.
References: [HIP events](https://rocmdocs.amd.com/projects/HIP/en/develop/doxygen/html/group___event.html),
[HIP occupancy API](https://rocm.docs.amd.com/projects/HIP/en/latest/doxygen/html/group___occupancy.html).
+21
View File
@@ -54,6 +54,27 @@ public ZIPs exclude these objects. Install/restore with private overrides
restores sentinel DLL/config byte-exactly, without duplicate slash/backslash
manifest paths.
Production K/4K with private output stores completes 9982 frames and 9982
finite GPU scans; the user reports 43-47 FPS. Random per-hook CPU sampling
then localizes contention to the shared command-list routing map. A per-thread
weak lookup cache bypasses that mutex for repeated calls, invalidating on map
mutations to preserve Reset/final Release/address reuse. Queue and per-list
synchronization remain. The regression resets/re-splits the same object twice
per iteration with different root constants and verifies both GPU outputs.
All sixteen CTest gates pass. The cached game run completes 4770 K/4K frames
and 4770 finite GPU scans, zero failures/CPU image copies/aged outputs. The user
reports 49-51 FPS and 53% GPU usage. Aggregated sampled access/capture time
falls from 977.528 to 233.606 ms/s across threads; it includes parallel lock
waits and must not be treated as serial frame time. Median recording interval
is 19.473 ms. `-ProfileCommandHooks` is optional and off during ordinary play.
Detailed scope and timings are in [windows-performance.md](windows-performance.md).
Post-cache full-pipeline checks also pass: three K/4K HDR frames and four M
512x288 frames match their previously validated controls with max absolute and
relative RGB error 0, all RGBA finite. Public archive validation checks all 63
entries and their SHA256 against package.json; NVIDIA DLLs and private texture
objects are absent. `package-windows-game.ps1 -ArchivePath <zip>` archives only
the staged manifest, including on Windows PowerShell 5.1.
Performance diagnostics (2026-10-01): the separate ZLUDA `b0161a4` runtime
passes 32 PTX launches in each context and all four native K/M frames with
bit-exact RGB against their controls. All thirteen exported patches (0002