Port NieR Automata with 60 fps and geometry fixes
This commit is contained in:
1 parent
a5513d4ae0
commit
31b5944eb4
49 files changed
+3838
-86
No files matched your search
@@ -135,6 +135,7 @@ Under each game: the IPA's size, and "60 fps with 1.2.0" where the game runs at
|
||||
<tr>
|
||||
<td align="center" valign="top" width="33%"><img src="docs/images/taiko-risshiden-v-dx.jpg" width="256" alt="Taiko Risshiden V DX"><br>Taiko Risshiden V DX<br><sub>~3.3 GB · Japanese · played by touch</sub></td>
|
||||
<td align="center" valign="top" width="33%"><img src="docs/images/unicorn-overlord.jpg" width="256" alt="Unicorn Overlord"><br>Unicorn Overlord<br><sub>~4 GB</sub></td>
|
||||
<td align="center" valign="top" width="33%"><img src="docs/images/nier-automata.png" width="256" alt="NieR:Automata The End of YoRHa Edition"><br>NieR:Automata The End of YoRHa Edition<br><sub>~10.9 GB · 60 fps with 1.0.3</sub></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
# NieR:Automata The End of YoRHa Edition (`010056B015FE8000`)
|
||||
|
||||
Update 1.0.3 (v131072) over the base cartridge dump. PlatinumGames' engine, SDK 12.3.9, NVN, CRI CPK archives and Sofdec USM movies, Wwise audio through `AudioOut`. Modules `main`, `subsdk0` (NintendoSDK_movie) and `sdk`. Mac startup, save creation/loading and opening flight gameplay pass; iPhone testing is pending.
|
||||
|
||||
## What it needs
|
||||
|
||||
| Setting | Where | Why |
|
||||
|---|---|---|
|
||||
| `mem_reserve 0x140000000`, `mem_alias 0x118000000`, `mem_stack 0x10000000`, `app_pool 0xCD500000` | [`game.tsv`](game.tsv) | 5 GB guest block with a 4.375 GB alias region; the game maps its own memory there and never sets a heap during startup |
|
||||
| `sys_resource 0x1000000` | `game.tsv` | the NPDM declares 16 MB of system resource, enabling virtual address memory |
|
||||
| `pad_layout full` | `game.tsv` | movement and camera/aiming use both sticks |
|
||||
| `tex_flush_upload on` | `game.tsv` | CPU-filled texture storage is published through mapped-range flushes; without uploads the title background is magenta |
|
||||
| `feedback_snap fd2c47b73f0e7e24` | `game.tsv` | `filter09.pso` samples the HDR attachment it writes through separate texture slot 128; a snapshot prevents NaNs spreading through bloom |
|
||||
| `present_interval display` | `game.tsv` | replaces the game's interval-two presentation target with 60 Hz; the native clock already measures elapsed time |
|
||||
| `gpu_timestamps segment` | `game.tsv` | the renderer subtracts two raw timestamp reports; one timestamp for the whole submission makes its measured GPU cost zero |
|
||||
| Four dynamic-resolution threshold cuts | [`patches.py`](patches.py) | the verified 1.0.3 main build uses 22.5 / 16.005 / 15 ms thresholds for a 60 fps budget |
|
||||
|
||||
## Files and shaders
|
||||
|
||||
- 660 RomFS files, 10.84 GB: 30 CRI CPK archives (6.20 GB), 162 USM movies (3.52 GB), loose Wwise banks and streams, and Enlighten data.
|
||||
- **Resolved: the shader split found zero shaders.** Five DAT archives in `data000.cpk` contain 1,371 size-delimited shader objects: 819 pixel, 517 vertex, 31 compute and four geometry objects, before deduplication. Every object has a 0x88-byte binding prefix, a length-prefixed NVN code area, then a length-prefixed 0x880-byte control section. All section bounds and control code lengths agree. They produce 1,225 distinct keys, including the initial runtime keys `f2fd6cfd0ff14a18`, `7855550732b71e48` and `62026f624061e259`. The general reader is linked below.
|
||||
- The full RomFS scan finds 451 distinct vertex, 739 pixel, 31 compute and four geometry shaders, with 902 single-stage cover pairs.
|
||||
- **Resolved: magenta title background.** The `render02` / `flush01` route captures frame 1,200 with identical inputs; enabling `tex_flush_upload` alone changes the magenta pixel share from 91.8% to zero and restores the cream title background. `TEXINFO` also finds populated guest texture storage without packaged layouts (for example a 1024×1024 format `0x7d` texture, 279,870 nonzero bytes of 704,512). No dirty-write tracking is enabled.
|
||||
- **Resolved: geometry shader compilation and binding failures.** All four geometry objects use viewport-mask output in their generated raster reader. The reader's scalar/array mismatch, missing geometry storage-buffer table and incorrect write-flag interpretation are general chain/host fixes linked below. All 1,225 shaders build for Mac and iOS after these changes.
|
||||
- **Resolved: passthrough output bounds and raster emission.** All four geometry objects set SPH `GpPassthrough` with a raw output bound of one. The earlier metadata underallocated the raw scratch/index region and read the wrong stride, while native passthrough support left compute raster output absent. The shared fixes derive bounds/output topology from input, explicitly emit positions and generic attributes, and preserve viewport-zero culling. Native canaries, compaction and real-translator GPU tests cover every topology and the full capture map. Rebuilt flight scenes render the ship models and effects.
|
||||
- **Resolved: green flight scene and dark rectangles.** HDR targets contained sparse red/blue NaNs, most on 16-pixel seams; bloom spread them across both channels. `filter09.pso` (`fd2c47b73f0e7e24`) samples the HDR attachment it also writes, through a separate texture slot. The host's snapshot path skipped separate slots before its general fix. `snap01` with the snapshot restores ship, cloud and exhaust colors; scans at frames 3,000, 3,060, 3,540 and 3,600 find no non-finite passes. Both default and active LUTs matched deswizzled guest storage byte-for-byte, ruling out their upload/layout. Enabling dirty-write tracking alone did not fix the green output and is left off.
|
||||
|
||||
## Status on the Mac
|
||||
|
||||
- The title, menus, keyboard naming, a new Easy game with auto-chips, save creation and save loading pass. The opening formation cinematic and ocean combat render ships, clouds, lighting, exhaust, shots and HUD correctly. Left/right movement and firing respond to input (`snap01_control_*`, `fps60_opt_*`).
|
||||
- Both logo movies decode through NintendoSDK_movie. The final 300-second run exits cleanly after the test's SIGTERM; Wwise output has zero underruns through 28,000 device callbacks. Resident memory peaks around 2,811 MB and Metal allocations around 2,995 MB, then settle below those peaks while the route streams more objects; its last report is 2,794 / 2,933 MB at frame 17,700.
|
||||
- **Resolved: repeated geometry drains and sorting.** The original heavy flight route spent most sampled main-thread time waiting in `mdi_wait`, followed by sorting capture indices. The shared synchronization/bitset fix linked below removes those hotspots.
|
||||
- **Resolved: serial geometry prefix scan.** A GPU profile of frame 4,600 in the 720p `fps60_seg` records 79 geometry sequences: 7.246 ms in their serial scans out of a 16.19 ms GPU span, with 521 encoders. The general parallel scan and combined compute encoder preserve ordered primitive compaction; native checks cover 129,032 groups and the translated geometry stages. The final 1080p route's frame 4,600 uses 284 encoders, 4.19 ms compute/copy and an 11.17 ms GPU span. The mode and camera timing differ, so these totals are supporting encoder evidence rather than an isolated same-frame speedup.
|
||||
- Both standard NSP build workflows pass. The unsigned `NieRAutomata.ipa` is 11,712,290,740 bytes (about 10.9 GiB), with all 1,225 Mac/iOS shader libraries on chain `20fe3d62b9f6` and 331 recorded prewarm entries. Its four cuts and all three embedded main sections match the tested rewrite; all 3,551 archive entries pass CRC verification. The normal Mac executable is `010056B015FE8000_build/tools/dmhost`.
|
||||
- Work folder: `/Volumes/T7/nsp/NieR Automata The End of YoRHa Edition/010056B015FE8000-work`. `run/boot.py <name> <seconds> [KEY=VALUE ...]` runs the adjacent `010056B015FE8000_build/tools/dmhost` with bounded duration, control file `run/<name>.ctl`, logs and save data beside it.
|
||||
|
||||
## 60 fps
|
||||
|
||||
Only main build `3c10ec35c5ef4c3686b4053afb0e58e7` gets the four cuts. They replace immediate constants at `0x9bf434`, `0x9bf484`, `0x9bf4d4` and `0x9bf4f8`, with original-byte assertions, following the [FPSLocker 1.0.3 threshold sites](https://github.com/masagrator/FPSLocker-Warehouse/blob/v4/SaltySD/plugins/FPSLocker/patches/010056B015FE8000/3C10EC35C5EF4C36.yaml). No address is carried to another build and no function-matched cuts are enabled.
|
||||
|
||||
The native clock at `main+0x8fc7a8` converts elapsed milliseconds to 60 Hz ticks and clamps each step to [1, 2]. It needs no clock rewrite. Probe `main:8fc888@x19+b0` reads step, accumulator, scale and elapsed milliseconds. The paired title runs measure 33.34 ms / step 2 at the original target and 16.66 ms / step 1 at 60 Hz. Slow flight before the geometry fix clamps to step 2 and loses game time; raising the presentation target alone was insufficient.
|
||||
|
||||
The final M4 Pro run, `fps60_final`, uses the profile's default console mode (1920×1080), 60 Hz presentation, the four 1.0.3 cuts, the current shader chain, sound and native-clock/DR probes. No resolution reduction is required for this route:
|
||||
|
||||
| Window after launch | Average fps | Frame p50 / p95 | Average GPU time | Game seconds / wall second |
|
||||
|---|---:|---:|---:|---:|
|
||||
| 80–110 s, heavy opening formation | 59.79 | 16.67 / 17.99 ms | 10.15 ms | 1.011 |
|
||||
| 120–150 s, flight transition | 60.03 | 16.67 / 17.23 ms | 10.99 ms | 1.010 |
|
||||
| 170–200 s, free flight | 60.00 | 16.66 / 17.39 ms | 10.93 ms | 1.011 |
|
||||
| 220–250 s, ocean combat | 59.92 | 16.66 / 17.26 ms | 10.06 ms | 1.009 |
|
||||
|
||||
These are measured windows, not a full-game or iPhone frame-rate guarantee. The frame rate stays near 60 with occasional longer frames; the native clock's minimum-one-tick clamp gives about 1% timing bias with host jitter in these flight windows.
|
||||
|
||||
Reproduce the save-load route with `DM_KEYS=40:A,45:A,50:A,52:Left,53:A,60:A`, `DM_PRESENT_LINK=0` and sound enabled. Headless timing runs unset `DM_WINDOW`. To compare the original presentation target, set `DM_PRESENT_INTERVAL=game`; `display` selects 60 Hz. `DM_OPMODE=0` selects the game's native 720p handheld mode; `1` selects 1080p console mode.
|
||||
|
||||
**Resolved: dynamic-resolution cost reads zero or 32 times too small.** The renderer's producer at `main+0x9ba6d4` waits for a ring fence, maps its counter buffer and subtracts timestamp fields at +8 and +0x18; its inline conversion publishes milliseconds through renderer +0x10c4. Submission timestamps gave zero. Segment timestamps need the shared raw-unit fix linked below: this consumer expects 614.4 MHz, while the host previously wrote 19.2 MHz. Both report paths and the nanosecond API now use the proper rate. The native scale floor is currently 1.0; its existing preset setter can select 0.7. No floor override is applied.
|
||||
|
||||
## Found on this game
|
||||
|
||||
- [Size-delimited PlatinumGames shader objects](../../../docs/reference/shaders.md#size-delimited-platinumgames-shader-objects).
|
||||
- [Mapped-range flushes taken as uploads](../../../docs/reference/nvn-objects.md#mapped-range-flushes-taken-as-uploads-tex_flush_upload).
|
||||
- [Geometry reader viewport masks](../../../docs/reference/shaders.md#geometry-reader-viewport-masks).
|
||||
- [Geometry-stage storage-buffer table](../../../docs/reference/shaders.md#geometry-stage-storage-buffer-table).
|
||||
- [Storage-buffer write flag in translation metadata](../../../docs/reference/shaders.md#storage-buffer-write-flag-in-translation-metadata).
|
||||
- [Passthrough geometry output bounds follow input topology](../../../docs/reference/shaders.md#passthrough-geometry-output-bounds-follow-input-topology).
|
||||
- [Passthrough geometry kernels lose raster vertices](../../../docs/reference/shaders.md#passthrough-geometry-kernels-lose-raster-vertices).
|
||||
- [Same-pass feedback read through a snapshot](../../../docs/reference/rendering.md#same-pass-feedback-read-through-a-snapshot).
|
||||
- [Geometry capture waits for every indexed draw](../../../docs/reference/shaders.md#geometry-capture-waits-for-every-indexed-draw).
|
||||
- [Geometry compaction serial prefix scan](../../../docs/reference/shaders.md#geometry-compaction-serial-prefix-scan).
|
||||
- [Raw NVN timestamp units](../../../docs/reference/frame-rate.md#raw-nvn-timestamp-units).
|
||||
- [GPU timestamps per submission segment](../../../docs/reference/frame-rate.md#gpu-timestamps-per-submission-segment).
|
||||
|
||||
## Open
|
||||
|
||||
- Conditional rendering is still drawn unconditionally (`SetRenderEnableConditional` is the route's only `[RED]` warning); no visible fault was found from it in this route.
|
||||
- Validate on an iPhone and test beyond the opening flight; full-game coverage is pending.
|
||||
@@ -0,0 +1 @@
|
||||
# generated
|
||||
|
@@ -0,0 +1,47 @@
|
||||
# NieR:Automata 1.0.3 (v131072), PlatinumGames engine, SDK 12.3.9, NVN.
|
||||
# Format: see dm/games/README.md; bring-up evidence and status: README.md.
|
||||
|
||||
# ---- Identity ----
|
||||
title_id 010056B015FE8000
|
||||
program_id 010056B015FE8000
|
||||
|
||||
# ---- App ----
|
||||
name NieR:Automata The End of YoRHa Edition
|
||||
ipa NieRAutomata.ipa
|
||||
app_category public.app-category.action-games
|
||||
# Movement and aiming/camera use both sticks.
|
||||
pad_layout full
|
||||
|
||||
# ---- Versions ----
|
||||
build v131072 1.0.3 main=3c10ec35c5ef4c3686b4053afb0e58e7 subsdk0=be1ee79a9968a35a6b63fc8f1036a6d4 sdk=e8cdceb1e77a8465fe20f21928e8d296
|
||||
package v131072
|
||||
shader_versions v131072
|
||||
|
||||
# ---- Files ----
|
||||
# every module main imports from
|
||||
modules main subsdk0 sdk
|
||||
romfs_marker data014.cpk
|
||||
zip_store .bnk:.cpk:.usm:.wem:.wsp:.metallib
|
||||
|
||||
# ---- Memory ----
|
||||
# the NPDM declares 16 MB of system resource (virtual address memory) and main never sets a heap: a 5 GB block with a 4.375 GB alias region, where the game maps its memory itself
|
||||
mem_reserve 0x140000000
|
||||
mem_alias 0x118000000
|
||||
mem_stack 0x10000000
|
||||
app_pool 0xCD500000
|
||||
# the NPDM declares 16 MB of system resource
|
||||
sys_resource 0x1000000
|
||||
|
||||
# ---- Rendering ----
|
||||
# The native clock measures elapsed time; dynamic-resolution thresholds target 60 fps in patches.py.
|
||||
present_interval display
|
||||
# The renderer subtracts two raw timestamp reports to measure its GPU cost.
|
||||
gpu_timestamps segment
|
||||
# The game fills texture storage on the CPU and publishes it with mapped-range flushes.
|
||||
tex_flush_upload on
|
||||
# filter09 samples its own HDR attachment through a separate texture slot.
|
||||
feedback_snap fd2c47b73f0e7e24
|
||||
|
||||
# ---- Shader split ----
|
||||
shader_groups /Enlighten/=enlighten /movie/=movie /sound/=sound /movie_logo/=movielogo
|
||||
shader_note NieR:Automata The End of YoRHa Edition shaders
|
||||
|
@@ -0,0 +1,15 @@
|
||||
# NieR:Automata (010056B015FE8000): patches of this game's own builds, keyed by NSO build ID.
|
||||
# The rewriter asserts each original byte sequence before applying a CUTS entry.
|
||||
CUTS = {
|
||||
# 1.0.3 (v131072) main: dynamic resolution compares measured frame cost with 45 / 32.01 / 30 ms thresholds for the Switch's 30 fps target.
|
||||
# At 60 fps use 1.35 / 0.9603 / 0.9 times 1000/60 ms: 22.5 / 16.005 / 15 ms. These are the four sites verified by FPSLocker Warehouse:
|
||||
# https://github.com/masagrator/FPSLocker-Warehouse/blob/v4/SaltySD/plugins/FPSLocker/patches/010056B015FE8000/3C10EC35C5EF4C36.yaml
|
||||
# Keep the instruction sequence and replace its constants directly; the profile's present_interval display supplies the 60 Hz presentation target.
|
||||
# The game clock already measures elapsed time at 60 ticks per second (main+0x8fc7a8); it needs no frame-step rewrite.
|
||||
'3c10ec35c5ef4c3686b4053afb0e58e7': [
|
||||
(0x9bf434, '8c46a8528301271e', '8c36a8528301271e', 'dynamic resolution: bad frame cost 45 -> 22.5 ms at 60 fps'),
|
||||
(0x9bf484, 'ac4781520c40a872', 'ac4781520c30a872', 'dynamic resolution: optimal frame cost 32.01 -> 16.005 ms at 60 fps (first load)'),
|
||||
(0x9bf4d4, 'ac4781520c40a87283cc201e8001271e', 'ac4781520c30a87283cc201e8001271e', 'dynamic resolution: optimal frame cost 32.01 -> 16.005 ms at 60 fps (second load)'),
|
||||
(0x9bf4f8, '00d0271e', '00d0251e', 'dynamic resolution: good frame cost 30 -> 15 ms at 60 fps'),
|
||||
],
|
||||
}
|
||||
@@ -0,0 +1,333 @@
|
||||
# Prewarm seed list: NieR:Automata 1.0.3, Mac title, save load and opening flight combat.
|
||||
# Rows: S<TAB>shader key<TAB>stage / R<TAB>render pipeline key / C<TAB>compute shader key.
|
||||
S f2fd6cfd0ff14a18_b 0
|
||||
S 7855550732b71e48_b 1
|
||||
R 663266643663666430666631346131385f62000000000000373835353535303733326237316534385f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004600000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000f00ffff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000220000001600000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S 65426d1f51dbaa57_b 0
|
||||
S b437477297003e29_b 1
|
||||
R 363534323664316635316462616135375f62000000000000623433373437373239373030336532395f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003700000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000f00ffff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000220000001600000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S 54855c38a82e3f39_b 0
|
||||
S ce2642e6452fe67c_b 1
|
||||
S 5578d381f2aba12e_b 1
|
||||
R 353438353563333861383265336633395f62000000000000636532363432653634353266653637635f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001900000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000f00ffff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000220000001600000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S 4072f08f140e1da8_b 5
|
||||
C 4072f08f140e1da8_b
|
||||
R 353438353563333861383265336633395f62000000000000353537386433383166326162613132655f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004600000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000f00ffff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000220000001600000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S f897d9ae7bc2050f_b 5
|
||||
C f897d9ae7bc2050f_b
|
||||
S 5a5c9133d0f16649_b 0
|
||||
S f7dfe9e15839daa3_b 1
|
||||
R 356135633931333364306631363634395f62000000000000663764666539653135383339646161335f62000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046000000000000000000000000000000000000000000000000000000000000000000000000000000010000000f0000000f00ffff00000000281804810400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S 46e8cd0de7414e7f_b 0
|
||||
S 62026f624061e259_b 1
|
||||
R 343665386364306465373431346537665f62000000000000363230323666363234303631653235395f62000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046000000000000000000000000000000000000000000000000000000000000000000000000000000010000000f0000000700ffff00000000281804810400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e0000002e1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S 3075f4bd6e97a74b_b 0
|
||||
S 6be4be1df7441a64_b 1
|
||||
R 333037356634626436653937613734625f62000000000000366265346265316466373434316136345f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004600000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000f00ffff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000220000001600000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S 216aa0959283e224_b 1
|
||||
S fe25a5abd42c1333_b 1
|
||||
S 869fc2472b4ea013_b 1
|
||||
S df6e63a1cf5740a7_b 1
|
||||
S af6be82ada4ab609_b 1
|
||||
S 7b61c45a469b1f1b_b 1
|
||||
S b41adaf519bed4dc_b 1
|
||||
R 353438353563333861383265336633395f62000000000000323136616130393539323833653232345f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c00000000000000000000000000000000000000000000000000000000000000040100000401000001000000000000000f00ffff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000220000001600000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 353438353563333861383265336633395f62000000000000666532356135616264343263313333335f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c00000000000000000000000000000000000000000000000000000000000000040100000401000001000000000000000f00ffff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000220000001600000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 663266643663666430666631346131385f62000000000000383639666332343732623465613031335f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000700ffff00000000088b0581040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000220000001600000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 353438353563333861383265336633395f62000000000000646636653633613163663537343061375f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c0000005c000000000000000000000000000000000000000000000000000000000000000000000001000000000000007700ffff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000220000001600000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 353438353563333861383265336633395f62000000000000616636626538326164613461623630395f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c00000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000f00ffff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000220000001600000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 353438353563333861383265336633395f62000000000000376236316334356134363962316631625f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c00000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000f00ffff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000220000001600000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 663266643663666430666631346131385f62000000000000383639666332343732623465613031335f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c00000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000700ffff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000220000001600000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 663266643663666430666631346131385f62000000000000383639666332343732623465613031335f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000000000000000000010000000f0000000700ffff0000000010080481040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000220000001600000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 663266643663666430666631346131385f62000000000000623431616461663531396265643464635f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c00000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000f00ffff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000220000001600000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S 167b8b8aa79b4262_b 0
|
||||
S 38576bae7718d067_b 1
|
||||
R 313637623862386161373962343236325f62000000000000333835373662616537373138643036375f62000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046000000000000000000000000000000000000000000000000000000000000000000000000000000010000000f0000000700ffff00000000281804810400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e0000002e1000002e2000002e300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S c0ed2509be567cef_b 1
|
||||
S 8cc2ef399c68e1e0_b 0
|
||||
S a176007d74d54879_b 1
|
||||
S 9e275b948823ffb2_b 1
|
||||
S 2a4420c4331b87e7_b 0
|
||||
S c56225e38c167f60_b 1
|
||||
S 9a2be07bdef5ad90_b 1
|
||||
R 313637623862386161373962343236325f62000000000000633065643235303962653536376365665f62000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046000000000000000000000000000000000000000000000000000000000000000000000000000000010000000f0000000700ffff00000000280804810400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e0000002e1000002e2000002e300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 386363326566333939633638653165305f62000000000000613137363030376437346435343837395f62000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046000000000000000000000000000000000000000000000000000000000000000000000000000000010000000f0000000f00ffff0000000028180a860400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e0000002e100000000000002e300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 313637623862386161373962343236325f62000000000000396532373562393438383233666662325f62000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046000000000000000000000000000000000000000000000000000000000000000000000000000000010000000f0000000700ffff00000000281804810400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e0000002e1000002e2000002e300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 326134343230633433333162383765375f62000000000000633536323235653338633136376636305f62000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046000000000000000000000000000000000000000000000000000000000000000000000000000000010000000f0000000f00ffff0000000028180a860400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e0000002e100000000000002e300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 313637623862386161373962343236325f62000000000000396132626530376264656635616439305f62000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046000000000000000000000000000000000000000000000000000000000000000000000000000000010000000f0000000700ffff00000000281804810400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e0000002e1000002e2000002e300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 313637623862386161373962343236325f62000000000000633065643235303962653536376365665f62000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046000000000000000000000000000000000000000000000000000000000000000000000000000000010000000f0000000700ffff00000000281804810400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e0000002e1000002e2000002e300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 313637623862386161373962343236325f62000000000000396532373562393438383233666662325f62000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046000000000000000000000000000000000000000000000000000000000000000000000000000000010000000f0000000700ffff00000000280804810400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e0000002e1000002e2000002e300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 313637623862386161373962343236325f62000000000000333835373662616537373138643036375f62000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046000000000000000000000000000000000000000000000000000000000000000000000000000000010000000f0000000700ffff00000000280804810500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e0000002e1000002e2000002e300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 313637623862386161373962343236325f62000000000000396132626530376264656635616439305f62000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046000000000000000000000000000000000000000000000000000000000000000000000000000000010000000f0000000700ffff00000000280804810400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e0000002e1000002e2000002e300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 386363326566333939633638653165305f62000000000000613137363030376437346435343837395f62000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046000000000000000000000000000000000000000000000000000000000000000000000000000000010000000f0000000700ffff00000000280804810500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e0000002e100000000000002e300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S fbcd81e58fa6bf78_b 0
|
||||
S 49bd7a780255b6e9_b 1
|
||||
S 137b54dc5462e5bb_b 2
|
||||
S 137b54dc5462e5bb_bg3 2
|
||||
S 137b54dc5462e5bb_bgv 0
|
||||
R 313337623534646335343632653562625f62677600000000343962643761373830323535623665395f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003700000000000000000000000000000000000000000000000000000000000000040100000401000001000000000000000000ffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S 5c55eae177dace24_b 0
|
||||
S 57290de615ee7295_b 1
|
||||
S e7a8b3a1f5573ed5_b 5
|
||||
C e7a8b3a1f5573ed5_b
|
||||
R 356335356561653137376461636532345f62000000000000353732393064653631356565373239355f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c00000000000000000000000000000000000000000000000000000000000000040100000401000001000000000000000f00ffff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000220000001110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S 9be04df03c735fe6_b 5
|
||||
C 9be04df03c735fe6_b
|
||||
S 13fb7b749ddae3e3_b 5
|
||||
C 13fb7b749ddae3e3_b
|
||||
S 18a435d220de55ff_b 0
|
||||
R 313861343335643232306465353566665f62000000000000343962643761373830323535623665395f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003700000000000000000000000000000000000000000000000000000000000000fc0000000000000001000000000000000000ffff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000220000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 313637623862386161373962343236325f62000000000000633065643235303962653536376365665f62000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046000000000000000000000000000000000000000000000000000000000000000000000000000000010000000f0000000700ffff00000000280804810500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e0000002e1000002e2000002e300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S 85676cd8b3df3c91_b 0
|
||||
S 05daf17a1d8bc556_b 1
|
||||
R 383536373663643862336466336339315f62000000000000303564616631376131643862633535365f62000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046000000000000000000000000000000000000000000000000000000000000000000000000000000010000000f0000000700ffff00000000281804810400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e00000016100000161800002e2000002e3000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S 9000f50a7f75f079_b 5
|
||||
C 9000f50a7f75f079_b
|
||||
S a1702cc1957ebba5_b 5
|
||||
C a1702cc1957ebba5_b
|
||||
S a8dd21c1a70c4f58_b 5
|
||||
C a8dd21c1a70c4f58_b
|
||||
S 957b438fe26d42d7_b 5
|
||||
C 957b438fe26d42d7_b
|
||||
S 0bc5457eddc461e0_b 5
|
||||
C 0bc5457eddc461e0_b
|
||||
S d60cb43c9eec8a9e_b 5
|
||||
C d60cb43c9eec8a9e_b
|
||||
S 5f880399702b500c_b 0
|
||||
S ac309751c3e03b53_b 1
|
||||
R 356638383033393937303262353030635f62000000000000616333303937353163336530336235335f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff000000002818028604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029000000110800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S 187155c4af22ae76_b 0
|
||||
S 951331942e24f535_b 1
|
||||
S c119ee64a3e14a6d_b 1
|
||||
S 8c35b63ea0e416f8_b 0
|
||||
S ba879d1a5066adcb_b 1
|
||||
R 313837313535633461663232616537365f62000000000000393531333331393432653234663533355f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff000000002808028604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029000000110800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 356638383033393937303262353030635f62000000000000633131396565363461336531346136645f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff000000002818028604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029000000110800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 386333356236336561306534313666385f62000000000000616333303937353163336530336235335f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff000000002818028604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029000000110800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 356638383033393937303262353030635f62000000000000626138373964316135303636616463625f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff000000002818028604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029000000110800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 356638383033393937303262353030635f62000000000000616333303937353163336530336235335f62000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046000000000000000000000000000000000000000000000000000000000000000000000000000000010000000f0000000f00ffff000000002818028604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029000000110800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S 00086b38854dbb7d_b 0
|
||||
S 32b1ff538c7f5a22_b 1
|
||||
R 303030383662333838353464626237645f62000000000000333262316666353338633766356132325f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000700ffff000000002818028604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029000000110800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S f87b8075106ce3d1_b 1
|
||||
R 356638383033393937303262353030635f62000000000000663837623830373531303663653364315f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff000000005018028604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029000000110800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S 35918cd6ef409d47_b 0
|
||||
S c2f38b84d2c4e4d2_b 1
|
||||
R 333539313863643665663430396434375f62000000000000633266333862383464326334653464325f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000700ffff000000002818028604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029000000110800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S 5b7145817478b9e7_b 0
|
||||
S ea056aefdcc718fa_b 1
|
||||
R 356237313435383137343738623965375f62000000000000656130353661656664636337313866615f62000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046000000000000000000000000000000000000000000000000000000000000000000000000000000010000000f0000000700ffff00000000281804810400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e0000002e100000000000002e300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S 27e74443a67249cf_b 0
|
||||
S fd2c47b73f0e7e24_b 1
|
||||
R 323765373434343361363732343963665f62000000000000666432633437623733663065376532345f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c00000000000000000000000000000000000000000000000000000000000000040100000401000001000000000000000700ffff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000220000001600000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S eaf2df477c4919a3_b 0
|
||||
S 317bc48071a2dad7_b 0
|
||||
S 7b1100e8e9c11eca_b 1
|
||||
S 4a2b0df808307d63_b 2
|
||||
S 4a2b0df808307d63_bg3 2
|
||||
S 4a2b0df808307d63_bgv 0
|
||||
R 346132623064663830383330376436335f62677600000000376231313030653865396331316563615f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003700000000000000000000000000000000000000000000000000000000000000040100000401000001000000000000000000ffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S 23522240236d2b54_b 0
|
||||
S 4ea5793c080d8942_b 0
|
||||
S 4b89d7798c7db77e_b 1
|
||||
S 8d9d5331523f7131_b 0
|
||||
S 176547245fdff6b1_b 1
|
||||
S 6f93dc566009c1a0_b 0
|
||||
S a27ababf8a8adb96_b 1
|
||||
S c0693ab8b19c70c9_b 0
|
||||
S 1c487ae9c00f701a_b 1
|
||||
S 15f99d6b2584dc48_b 0
|
||||
S 0e46d7a4f4ad2f7f_b 1
|
||||
S 31d3215892261509_b 1
|
||||
S c57286ef1fde5711_b 0
|
||||
R 323335323232343032333664326235345f62000000000000343962643761373830323535623665395f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003700000000000000000000000000000000000000000000000000000000000000fc0000000000000001000000000000000000ffff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000220000002714000025180000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 346561353739336330383064383934325f62000000000000346238396437373938633764623737655f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c00000000000000000000000000000000000000000000000000000000000000040100000401000001000000000000000f00ffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022000000250c000011100000271400002518000011000008290800080000000000000000000000000000000000000000000000000000000000000000000000001c0000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 386439643533333135323366373133315f62000000000000313736353437323435666466663662315f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c00000000000000000000000000000000000000000000000000000000000000040100000401000001000000000000000f00ffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022000000250c000011100000271400002518000011000008290800080000000000000000000000000000000000000000000000000000000000000000000000001c0000000000000014000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 366639336463353636303039633161305f62000000000000613237616261626638613861646239365f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c00000000000000000000000000000000000000000000000000000000000000040100000401000001000000000000000f00ffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022000000250c000011100000271400002518000011000008290400080000000000000000000000000000000000000000000000000000000000000000000000001c000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 633036393361623862313963373063395f62000000000000316334383761653963303066373031615f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c00000000000000000000000000000000000000000000000000000000000000040100000401000001000000000000000f00ffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022000000250c000011100000271400002518000011000008290800080000000000000000000000000000000000000000000000000000000000000000000000001c0000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 313566393964366232353834646334385f62000000000000306534366437613466346164326637665f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c00000000000000000000000000000000000000000000000000000000000000040100000401000001000000000000000f00ffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022000000250c000011100000271400002518000011000008290800080000000000000000000000000000000000000000000000000000000000000000000000001c0000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 346561353739336330383064383934325f62000000000000333164333231353839323236313530395f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c00000000000000000000000000000000000000000000000000000000000000040100000401000001000000000000000f00ffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022000000250c000011100000271400002518000011000008290800080000000000000000000000000000000000000000000000000000000000000000000000001c0000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 633537323836656631666465353731315f62000000000000353732393064653631356565373239355f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000700ffff0000000048040481040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000220000001110000027140000251800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S 5bc10e8e62fdf92b_b 1
|
||||
R 386439643533333135323366373133315f62000000000000356263313065386536326664663932625f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff000000002818028604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022000000250c000011100000271400002518000011000008290800080000000000000000000000000000000000000000000000000000000000000000000000001c0000000000000014000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S 317b2aa94bc181e2_b 0
|
||||
S 915f419ee6ec9147_b 1
|
||||
S 4af18498a895f57b_b 0
|
||||
S 480167c6e07ebabb_b 1
|
||||
S 097ff49ca182250e_b 0
|
||||
S 8166d5ef5dec556c_b 1
|
||||
R 356335356561653137376461636532345f62000000000000353732393064653631356565373239355f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff0000000028180286040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000220000001110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 333137623261613934626331383165325f62000000000000393135663431396565366563393134375f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff000000002818028604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022000000250c000011100000111400002518000029000008000000000000000000000000000000000000000000000000000000000000000000000000000000001c0000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 346166313834393861383935663537625f62000000000000343830313637633665303765626162625f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff000000002818048104000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022000000250c000011100000111400002518000029000008000000000000000000000000000000000000000000000000000000000000000000000000000000001c0000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 303937666634396361313832323530655f62000000000000383136366435656635646563353536635f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff00000000281802860400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e000000160000081600001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000008000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S 44bf8b3fb1a520f3_b 0
|
||||
S 3601f0cbce8c8fae_b 1
|
||||
R 343462663862336662316135323066335f62000000000000333630316630636263653863386661655f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff000000002818028604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029000000110800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S 66ba9531fa973a4b_b 1
|
||||
S 1865bf0505118a21_b 1
|
||||
S cabfe9953b061521_b 0
|
||||
R 356638383033393937303262353030635f62000000000000363662613935333166613937336134625f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff000000002818028604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029000000110800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 356638383033393937303262353030635f62000000000000313836356266303530353131386132315f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff000000002818028604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029000000110800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 356638383033393937303262353030635f62000000000000616333303937353163336530336235335f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff000000002808028604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029000000110800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 636162666539393533623036313532315f62000000000000313836356266303530353131386132315f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff0000000028180286040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000220000001110000027140000251800002504000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c0000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S 22559a5d012bcfe9_b 0
|
||||
S ab378ee0b46b3bf1_b 1
|
||||
R 323235353961356430313262636665395f62000000000000616233373865653062343662336266315f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000700ffff0000000028180286040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000220000001110000027140000251800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S 6d95d272391f899b_b 0
|
||||
S 7c7dec85e83167ed_b 1
|
||||
R 366439356432373233393166383939625f62000000000000376337646563383565383331363765645f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff000000002818028604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029000000110800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S 47303205c5b2b2db_b 1
|
||||
R 366439356432373233393166383939625f62000000000000343733303332303563356232623264625f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff000000002808028604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029000000110800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S 924549389994d73c_b 0
|
||||
R 393234353439333839393934643733635f62000000000000343962643761373830323535623665395f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c00000000000000000000000000000000000000000000000000000000000000040100000401000001000000000000000000ffff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000290000002e0000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S ad605bb71408b791_b 1
|
||||
R 313337623534646335343632653562625f62677600000000616436303562623731343038623739315f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003700000000000000000000000000000000000000000000000000000000000000040100000401000001000000000000000000ffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S 3ff064bdad4f2152_b 1
|
||||
S b487b287f7eba379_b 1
|
||||
R 346132623064663830383330376436335f62677600000000336666303634626461643466323135325f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003700000000000000000000000000000000000000000000000000000000000000040100000401000001000000000000000000ffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 633537323836656631666465353731315f62000000000000623438376232383766376562613337395f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000700ffff0000000048040481040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000220000001110000027140000251800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S 0ca08863622f48e3_b 1
|
||||
R 356335356561653137376461636532345f62000000000000306361303838363336323266343865335f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c00000000000000000000000000000000000000000000000000000000000000040100000401000001000000000000000f00ffff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000220000001110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S 1f85d195cc4880d7_b 1
|
||||
S f587a5955e3880b5_b 1
|
||||
R 386439643533333135323366373133315f62000000000000316638356431393563633438383064375f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c00000000000000000000000000000000000000000000000000000000000000040100000401000001000000000000000f00ffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022000000250c000011100000271400002518000011000008290800080000000000000000000000000000000000000000000000000000000000000000000000001c0000000000000014000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 366639336463353636303039633161305f62000000000000663538376135393535653338383062355f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c00000000000000000000000000000000000000000000000000000000000000040100000401000001000000000000000f00ffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022000000250c000011100000271400002518000011000008290400080000000000000000000000000000000000000000000000000000000000000000000000001c000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 633537323836656631666465353731315f62000000000000306361303838363336323266343865335f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000700ffff0000000048040481040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000220000001110000027140000251800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S 147106bbef6f8b1a_b 1
|
||||
R 313566393964366232353834646334385f62000000000000313437313036626265663666386231615f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c00000000000000000000000000000000000000000000000000000000000000040100000401000001000000000000000f00ffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022000000250c000011100000271400002518000011000008290800080000000000000000000000000000000000000000000000000000000000000000000000001c0000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 356638383033393937303262353030635f62000000000000383136366435656635646563353536635f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff000000002818028604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029000000110800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 366439356432373233393166383939625f62000000000000616233373865653062343662336266315f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c00000000000000000000000000000000000000000000000000000000000000040100000401000001000000000000000700ffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029000000110800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 356638383033393937303262353030635f62000000000000383136366435656635646563353536635f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000700ffff000000002818028604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029000000110800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 303937666634396361313832323530655f62000000000000616333303937353163336530336235335f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff00000000281802860400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e000000160000081600001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000008000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S 87f4ea2936a0e90b_b 1
|
||||
R 386439643533333135323366373133315f62000000000000383766346561323933366130653930625f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff000000002818028604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022000000250c000011100000271400002518000011000008290800080000000000000000000000000000000000000000000000000000000000000000000000001c0000000000000014000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S 30c40d9559b78eab_b 0
|
||||
R 333063343064393535396237386561625f62000000000000616333303937353163336530336235335f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff0000000028180286040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000220000001110000025180000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S 8317525804b1f341_b 0
|
||||
S 242ad8600bfc2b6f_b 1
|
||||
R 383331373532353830346231663334315f62000000000000323432616438363030626663326236665f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff0000000028180286040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000220000001110000025180000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S c802fe0a8cd8de2e_b 0
|
||||
S 335c6a03b18ba361_b 1
|
||||
R 633830326665306138636438646532655f62000000000000333335633661303362313862613336315f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff000000002818028604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029000000290000082900001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000008000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S dbdd4a4c311713f2_b 0
|
||||
S 2a709697b3633bff_b 1
|
||||
R 646264643461346333313137313366325f62000000000000326137303936393762333633336266665f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff00000000281802860400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e000000160000081600001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000008000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S 27d006f56f9e71cf_b 1
|
||||
S aa7e9ae5cceebd07_b 0
|
||||
S 5cbe7c78863df41f_b 1
|
||||
R 646264643461346333313137313366325f62000000000000323764303036663536663965373163665f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff00000000281802860400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e000000160000081600001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000008000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 616137653961653563636565626430375f62000000000000356362653763373838363364663431665f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000700ffff000000002818028604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S 686414e8eef18e19_b 1
|
||||
R 356638383033393937303262353030635f62000000000000363836343134653865656631386531395f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff000000002818028604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029000000110800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S 2fec68ad345a00ce_b 0
|
||||
S d56528d0b0b6ac87_b 1
|
||||
S d2605ef087e446a1_b 0
|
||||
S 07de47162192fec7_b 1
|
||||
S 45d81a473a5f853a_b 1
|
||||
S cfa6e5b9379506fe_b 1
|
||||
S 004f3abb6c4ac1d8_b 1
|
||||
R 326665633638616433343561303063655f62000000000000643536353238643062306236616338375f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff000000002808028604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029000000290000082900001029000018000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000008000000000000000800000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 356638383033393937303262353030635f62000000000000363662613935333166613937336134625f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff000000002808028604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029000000110800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 643236303565663038376534343661315f62000000000000303764653437313632313932666563375f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff000000002818028604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029000000110800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 356638383033393937303262353030635f62000000000000343564383161343733613566383533615f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff000000002818028604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029000000110800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 356638383033393937303262353030635f62000000000000636661366535623933373935303666655f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff000000002818028604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029000000110800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 616137653961653563636565626430375f62000000000000303034663361626236633461633164385f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000700ffff000000002818028604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 303937666634396361313832323530655f62000000000000383136366435656635646563353536635f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff0000000028080a860400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e000000160000081600001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000008000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S 7dda3d1efa67bfa0_b 0
|
||||
S c195767a8b43a6ea_b 1
|
||||
R 376464613364316566613637626661305f62000000000000633139353736376138623433613665615f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff00000000281802860400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e000000160000081600001022000018250c00180000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000008000000000000000800000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S 1c51616cce770866_b 0
|
||||
S d7c9a92fe3ab4385_b 1
|
||||
S 5d54918ab58471fa_b 1
|
||||
R 316335313631366363653737303836365f62000000000000643763396139326665336162343338355f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff00000000281802860400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e000000160000081600001022000018250c00180000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000008000000000000000800000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 316335313631366363653737303836365f62000000000000356435343931386162353834373166615f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff00000000281802860400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e000000160000081600001022000018250c00180000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000008000000000000000800000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S 018d05d06e74d76f_b 5
|
||||
C 018d05d06e74d76f_b
|
||||
R 326665633638616433343561303063655f62000000000000643536353238643062306236616338375f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff000000002818028604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029000000290000082900001029000018000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000008000000000000000800000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S 4fbd33883a8d4656_b 1
|
||||
R 343462663862336662316135323066335f62000000000000346662643333383833613864343635365f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff000000001004028604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029000000110800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S 72a5eb8f7c029309_b 1
|
||||
R 343462663862336662316135323066335f62000000000000346662643333383833613864343635365f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff000000002808028605000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029000000110800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 343462663862336662316135323066335f62000000000000373261356562386637633032393330395f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff0000000028180a8604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029000000110800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S 8971677029c75df0_b 0
|
||||
R 383937313637373032396337356466305f62000000000000313736353437323435666466663662315f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c00000000000000000000000000000000000000000000000000000000000000040100000401000001000000000000000f00ffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022000000250c000011100000111400002900000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S 13386def4bfcabe5_b 0
|
||||
R 313333383664656634626663616265355f62000000000000313836356266303530353131386132315f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff0000000028180286040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000220000001110000027140000251800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S 063c1af58c3213f2_b 0
|
||||
R 356638383033393937303262353030635f62000000000000343564383161343733613566383533615f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff000000002808028604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029000000110800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 303633633161663538633332313366325f62000000000000643763396139326665336162343338355f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff000000002818028604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029000000110800002e000008250c0008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 356638383033393937303262353030635f62000000000000343564383161343733613566383533615f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff0000000028080a8604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029000000110800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S de59ef04e8eadad0_b 5
|
||||
C de59ef04e8eadad0_b
|
||||
S ee57bd3b73c9fe7d_b 5
|
||||
C ee57bd3b73c9fe7d_b
|
||||
S 59531a4ae5e35b53_b 5
|
||||
C 59531a4ae5e35b53_b
|
||||
S db5f9ca88a17671b_b 5
|
||||
C db5f9ca88a17671b_b
|
||||
R 356638383033393937303262353030635f62000000000000616333303937353163336530336235335f62000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000073000000000000000000000000000000000000000000000000000000000000000000000000000000010000000f0000000f00ffff0000000028180a8204000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029000000110800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S 1eb8d5b0fcd3627e_b 0
|
||||
S d653f2bfc07a7c75_b 1
|
||||
S 9ff4a40f4e4d72c1_b 0
|
||||
S 0d3e57ccad0e0335_b 0
|
||||
S c9f0217965db1050_b 1
|
||||
S 16130a95a06ad436_b 0
|
||||
S 29a1250c30216387_b 1
|
||||
R 316562386435623066636433363237655f62000000000000643635336632626663303761376337355f62000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000073000000000000000000000000000000000000000000000000000000000000000000000000000000010000000f0000000f00ffff0000000028180a8204000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022000000250c000011100000290000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c0000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 396666346134306634653464373263315f62000000000000356435343931386162353834373166615f62000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000073000000000000000000000000000000000000000000000000000000000000000000000000000000010000000f0000000f00ffff0000000028180a8204000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022000000250c000011100000251800002900000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c0000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 306433653537636361643065303333355f62000000000000633966303231373936356462313035305f62000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000073000000000000000000000000000000000000000000000000000000000000000000000000000000010000000f0000000f00ffff0000000028180a8204000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022000000250c000011100000290000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c0000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 313631333061393561303661643433365f62000000000000323961313235306333303231363338375f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff000000002818028604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029000000110800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S 4cee2136a047e8be_b 0
|
||||
S 42be10c2fd8feb1e_b 1
|
||||
R 346365653231333661303437653862655f62000000000000343262653130633266643866656231655f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000700ffff000000002818028604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022000000250c000011100000251800002900000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c0000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S d8aed7e827ac0817_b 0
|
||||
S 5aa81f6bd90fb6d5_b 1
|
||||
R 643861656437653832376163303831375f62000000000000356161383166366264393066623664355f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff000000002818028604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022000000250c000011100000251800002900000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c0000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 396666346134306634653464373263315f62000000000000356435343931386162353834373166615f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff000000002818028604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022000000250c000011100000251800002900000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c0000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S 0dfbe641afa019fe_b 1
|
||||
R 343462663862336662316135323066335f62000000000000306466626536343161666130313966655f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff0000000028080a8604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029000000110800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S d96667c18c3d1d9d_b 0
|
||||
S a5486013a179d13a_b 1
|
||||
R 643936363637633138633364316439645f62000000000000613534383630313361313739643133615f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff0000000028180286040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000220000002714000025180000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 356638383033393937303262353030635f62000000000000616333303937353163336530336235335f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff000000002808028605000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029000000110800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S d4163f0e3fa71736_b 1
|
||||
R 366439356432373233393166383939625f62000000000000643431363366306533666137313733365f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000700ffff000000002818028604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029000000110800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 366439356432373233393166383939625f62000000000000343733303332303563356232623264625f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff000000002818028604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029000000110800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 616137653961653563636565626430375f62000000000000303034663361626236633461633164385f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c00000000000000000000000000000000000000000000000000000000000000040100000401000001000000000000000700ffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 366439356432373233393166383939625f62000000000000323764303036663536663965373163665f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff000000002818028604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029000000110800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 356638383033393937303262353030635f62000000000000626138373964316135303636616463625f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000700ffff000000002818028604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029000000110800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S 23269153708c4022_b 1
|
||||
R 366439356432373233393166383939625f62000000000000323332363931353337303863343032325f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000700ffff000000002818028604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029000000110800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 386333356236336561306534313666385f62000000000000616333303937353163336530336235335f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff0000000028180a8604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029000000110800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S bd6a98605d7d8dda_b 1
|
||||
R 303937666634396361313832323530655f62000000000000626436613938363035643764386464615f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff00000000281802860400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e000000160000081600001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000008000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S edae9db9494d0d8d_b 1
|
||||
R 303030383662333838353464626237645f62000000000000656461653964623934393464306438645f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff000000002818028604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029000000110800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 303030383662333838353464626237645f62000000000000656461653964623934393464306438645f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff000000002808028604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029000000110800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 636162666539393533623036313532315f62000000000000616333303937353163336530336235335f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff0000000028180286040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000220000001110000027140000251800002504000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c0000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S e3b4b7cc9fe7f581_b 0
|
||||
S 7564b55d5e84edbc_b 1
|
||||
R 653362346237636339666537663538315f62000000000000373536346235356435653834656462635f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003700000000000000000000000000000000000000000000000000000000000000fc0000000000000001000000000000000000ffff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000220000001110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S 01d32dbfe956c1f3_b 1
|
||||
R 333539313863643665663430396434375f62000000000000303164333264626665393536633166335f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000700ffff000000002818028604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029000000110800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 303937666634396361313832323530655f62000000000000633131396565363461336531346136645f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff00000000281802860400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e000000160000081600001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000008000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 303937666634396361313832323530655f62000000000000383136366435656635646563353536635f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff0000000028180a860400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e000000160000081600001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000008000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S 66db13312407223e_b 0
|
||||
R 383937313637373032396337356466305f62000000000000356263313065386536326664663932625f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c00000000000000000000000000000000000000000000000000000000000000040100000401000001000000000000000f00ffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022000000250c000011100000111400002900000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S f6ec5c17a2390753_b 1
|
||||
R 356335356561653137376461636532345f62000000000000663665633563313761323339303735335f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c00000000000000000000000000000000000000000000000000000000000000040100000401000001000000000000000f00ffff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000220000001110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S 143c95fa6bb7fc68_b 0
|
||||
S 216abf94edd48257_b 1
|
||||
R 313433633935666136626237666336385f62000000000000323136616266393465646434383235375f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff000000002818028604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029000000110800002e000008250c0008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S 8ad6cf0376b55912_b 1
|
||||
R 343462663862336662316135323066335f62000000000000386164366366303337366235353931325f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff000000002818028604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029000000110800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 383937313637373032396337356466305f62000000000000356263313065386536326664663932625f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c00000000000000000000000000000000000000000000000000000000000000040100000401000001000000000000000f00ffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022000000250c000011100000111400002900000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c0000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 383937313637373032396337356466305f62000000000000313736353437323435666466663662315f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c00000000000000000000000000000000000000000000000000000000000000040100000401000001000000000000000f00ffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022000000250c000011100000111400002900000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c0000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S 0ff2b3373c66d85e_b 1
|
||||
R 383937313637373032396337356466305f62000000000000306666326233333733633636643835655f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c00000000000000000000000000000000000000000000000000000000000000040100000401000001000000000000000f00ffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022000000250c000011100000111400002900000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S 0cb53cd5f310dc2e_b 1
|
||||
R 383937313637373032396337356466305f62000000000000306362353363643566333130646332655f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c00000000000000000000000000000000000000000000000000000000000000040100000401000001000000000000000f00ffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022000000250c000011100000111400002900000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
R 313333383664656634626663616265355f62000000000000383136366435656635646563353536635f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff0000000028180286040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000220000001110000027140000251800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
S 87be4f2b6e0ccb2e_b 0
|
||||
S 9c6f16c9691a0414_b 1
|
||||
R 383762653466326236653063636232655f62000000000000396336663136633936393161303431345f6200000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000401000004010000010000000f0000000f00ffff000000002818028604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022000000250c000011100000271400002518000029080008000000000000000000000000000000000000000000000000000000000000000000000000000000001c0000000000000014000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
|
@@ -0,0 +1,32 @@
|
||||
# Answer table for translation queries (generated by dm/gfx/tools/shader_split.py, do not edit): key <TAB> fact JSON. This game has no PC version to pair with: only the thread group / shared memory of compute shaders (taken from the control section); other queries get the translator defaults
|
||||
018d05d06e74d76f {"local":[1024,1,1],"shared":0}
|
||||
0bc5457eddc461e0 {"local":[1024,1,1],"shared":0}
|
||||
0febe44312c0d328 {"local":[1024,1,1],"shared":0}
|
||||
13fb7b749ddae3e3 {"local":[256,1,1],"shared":1024}
|
||||
14206a699c7c386c {"local":[1024,1,1],"shared":0}
|
||||
4072f08f140e1da8 {"local":[16,16,1],"shared":0}
|
||||
50ada2c643a0588e {"local":[1024,1,1],"shared":0}
|
||||
59531a4ae5e35b53 {"local":[1024,1,1],"shared":0}
|
||||
674bfb353124bc97 {"local":[1024,1,1],"shared":0}
|
||||
77a0de8243f56f03 {"local":[1024,1,1],"shared":0}
|
||||
80a484813d46c213 {"local":[32,32,1],"shared":0}
|
||||
80b069d0f0564d71 {"local":[4,1,1],"shared":0}
|
||||
80c196aa5760ce34 {"local":[32,30,1],"shared":18432}
|
||||
83d07e6559f93bd9 {"local":[4,1,1],"shared":0}
|
||||
9000f50a7f75f079 {"local":[1024,1,1],"shared":0}
|
||||
957b438fe26d42d7 {"local":[1024,1,1],"shared":20480}
|
||||
9be04df03c735fe6 {"local":[8,8,1],"shared":256}
|
||||
a1702cc1957ebba5 {"local":[1024,1,1],"shared":0}
|
||||
a23ffa20896a1366 {"local":[1024,1,1],"shared":0}
|
||||
a8dd21c1a70c4f58 {"local":[16,1,1],"shared":0}
|
||||
bc4ab6938c1bceac {"local":[4,1,1],"shared":0}
|
||||
d3cd49deb376ac1f {"local":[32,30,1],"shared":18240}
|
||||
d481918e7ee673c6 {"local":[32,30,1],"shared":0}
|
||||
d5077e43ea265ae8 {"local":[32,18,1],"shared":0}
|
||||
d60cb43c9eec8a9e {"local":[16,1,1],"shared":0}
|
||||
db5f9ca88a17671b {"local":[1024,1,1],"shared":8192}
|
||||
dd75cd3bcb3407bc {"local":[40,24,1],"shared":0}
|
||||
de59ef04e8eadad0 {"local":[1024,1,1],"shared":0}
|
||||
e7a8b3a1f5573ed5 {"local":[16,16,1],"shared":6448}
|
||||
ee57bd3b73c9fe7d {"local":[1,1,1],"shared":0}
|
||||
f897d9ae7bc2050f {"local":[16,16,1],"shared":2048}
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 19.
|
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,2 @@
|
||||
# kind: evidence control-section key conflict rulings: empty
|
||||
dm_ctl_sha16 chosen_pc class candidates records
|
||||
|
@@ -0,0 +1,903 @@
|
||||
# kind: evidence vertex / pixel shader pairs within BNSH variations (generated by dm/gfx/tools/shader_split.py, do not edit): vertex key <TAB> pixel key
|
||||
00086b38854dbb7d 003014fbe32aebf4
|
||||
00086b38854dbb7d 29409290c370fbb3
|
||||
008fbe3f0ef72297 003014fbe32aebf4
|
||||
008fbe3f0ef72297 29409290c370fbb3
|
||||
0110d92b5ae3921d 003014fbe32aebf4
|
||||
0110d92b5ae3921d 29409290c370fbb3
|
||||
025102bf43e81a7d 003014fbe32aebf4
|
||||
025102bf43e81a7d 29409290c370fbb3
|
||||
02888586097d15b7 003014fbe32aebf4
|
||||
02888586097d15b7 29409290c370fbb3
|
||||
049dc69f46e23a20 003014fbe32aebf4
|
||||
049dc69f46e23a20 29409290c370fbb3
|
||||
049dd89064d11d5d 003014fbe32aebf4
|
||||
049dd89064d11d5d 29409290c370fbb3
|
||||
05dea90b96ac259b 003014fbe32aebf4
|
||||
05dea90b96ac259b 29409290c370fbb3
|
||||
05e8db074e60df57 003014fbe32aebf4
|
||||
05e8db074e60df57 29409290c370fbb3
|
||||
063c1af58c3213f2 003014fbe32aebf4
|
||||
063c1af58c3213f2 29409290c370fbb3
|
||||
0693aad293de4625 003014fbe32aebf4
|
||||
0693aad293de4625 29409290c370fbb3
|
||||
06ad2817f4f78941 003014fbe32aebf4
|
||||
06ad2817f4f78941 29409290c370fbb3
|
||||
06fd5958059102a7 003014fbe32aebf4
|
||||
06fd5958059102a7 29409290c370fbb3
|
||||
0702bf2f8170e6af 003014fbe32aebf4
|
||||
0702bf2f8170e6af 29409290c370fbb3
|
||||
076504bba2a2af9e 003014fbe32aebf4
|
||||
076504bba2a2af9e 29409290c370fbb3
|
||||
079f7d55c336ce54 003014fbe32aebf4
|
||||
079f7d55c336ce54 29409290c370fbb3
|
||||
08b59f8aaf517fed 003014fbe32aebf4
|
||||
08b59f8aaf517fed 29409290c370fbb3
|
||||
097ff49ca182250e 003014fbe32aebf4
|
||||
097ff49ca182250e 29409290c370fbb3
|
||||
09a3cf31af3d29b4 003014fbe32aebf4
|
||||
09a3cf31af3d29b4 29409290c370fbb3
|
||||
0acb636a5add55dd 003014fbe32aebf4
|
||||
0acb636a5add55dd 29409290c370fbb3
|
||||
0b56a3660c83e994 003014fbe32aebf4
|
||||
0b56a3660c83e994 29409290c370fbb3
|
||||
0b5767dc98685b4b 003014fbe32aebf4
|
||||
0b5767dc98685b4b 29409290c370fbb3
|
||||
0b935131beed4743 003014fbe32aebf4
|
||||
0b935131beed4743 29409290c370fbb3
|
||||
0cdca2296de6edba 003014fbe32aebf4
|
||||
0cdca2296de6edba 29409290c370fbb3
|
||||
0d3e57ccad0e0335 003014fbe32aebf4
|
||||
0d3e57ccad0e0335 29409290c370fbb3
|
||||
0d9a66edbbdc52dc 003014fbe32aebf4
|
||||
0d9a66edbbdc52dc 29409290c370fbb3
|
||||
0dd3ed4fa5eafa7f 003014fbe32aebf4
|
||||
0dd3ed4fa5eafa7f 29409290c370fbb3
|
||||
0ddb1f1c36043a79 003014fbe32aebf4
|
||||
0ddb1f1c36043a79 29409290c370fbb3
|
||||
0df1af6bd808eff9 003014fbe32aebf4
|
||||
0df1af6bd808eff9 29409290c370fbb3
|
||||
0f49664d230b7cc1 003014fbe32aebf4
|
||||
0f49664d230b7cc1 29409290c370fbb3
|
||||
0fa9cef06a5f2fde 003014fbe32aebf4
|
||||
0fa9cef06a5f2fde 29409290c370fbb3
|
||||
0fcbbb58b684b5f1 003014fbe32aebf4
|
||||
0fcbbb58b684b5f1 29409290c370fbb3
|
||||
10800de3d176cc00 003014fbe32aebf4
|
||||
10800de3d176cc00 29409290c370fbb3
|
||||
115786ab3509ab61 003014fbe32aebf4
|
||||
115786ab3509ab61 29409290c370fbb3
|
||||
1180bb74a61ba5aa 003014fbe32aebf4
|
||||
1180bb74a61ba5aa 29409290c370fbb3
|
||||
13386def4bfcabe5 003014fbe32aebf4
|
||||
13386def4bfcabe5 29409290c370fbb3
|
||||
13c91d98579483b8 003014fbe32aebf4
|
||||
13c91d98579483b8 29409290c370fbb3
|
||||
13f9509ae8ef5388 003014fbe32aebf4
|
||||
13f9509ae8ef5388 29409290c370fbb3
|
||||
143c95fa6bb7fc68 003014fbe32aebf4
|
||||
143c95fa6bb7fc68 29409290c370fbb3
|
||||
159b3c8dcf639c37 003014fbe32aebf4
|
||||
159b3c8dcf639c37 29409290c370fbb3
|
||||
15f99d6b2584dc48 003014fbe32aebf4
|
||||
15f99d6b2584dc48 29409290c370fbb3
|
||||
16130a95a06ad436 003014fbe32aebf4
|
||||
16130a95a06ad436 29409290c370fbb3
|
||||
166ed938a94ad3ab 003014fbe32aebf4
|
||||
166ed938a94ad3ab 29409290c370fbb3
|
||||
167b8b8aa79b4262 003014fbe32aebf4
|
||||
167b8b8aa79b4262 29409290c370fbb3
|
||||
1742b4f98bd0989b 003014fbe32aebf4
|
||||
1742b4f98bd0989b 29409290c370fbb3
|
||||
187155c4af22ae76 003014fbe32aebf4
|
||||
187155c4af22ae76 29409290c370fbb3
|
||||
18a435d220de55ff 003014fbe32aebf4
|
||||
18a435d220de55ff 29409290c370fbb3
|
||||
1a6ef47568d1adaa 003014fbe32aebf4
|
||||
1a6ef47568d1adaa 29409290c370fbb3
|
||||
1b0bd03e1815f8cc 003014fbe32aebf4
|
||||
1b0bd03e1815f8cc 29409290c370fbb3
|
||||
1b3ae40f334887a5 003014fbe32aebf4
|
||||
1b3ae40f334887a5 29409290c370fbb3
|
||||
1b3dfee2dc5fbae7 003014fbe32aebf4
|
||||
1b3dfee2dc5fbae7 29409290c370fbb3
|
||||
1b5dd369daedddc2 003014fbe32aebf4
|
||||
1b5dd369daedddc2 29409290c370fbb3
|
||||
1c4111920c273418 003014fbe32aebf4
|
||||
1c4111920c273418 29409290c370fbb3
|
||||
1c51616cce770866 003014fbe32aebf4
|
||||
1c51616cce770866 29409290c370fbb3
|
||||
1df4301e765cd0bc 003014fbe32aebf4
|
||||
1df4301e765cd0bc 29409290c370fbb3
|
||||
1df5ab32043dd29d 003014fbe32aebf4
|
||||
1df5ab32043dd29d 29409290c370fbb3
|
||||
1e53d5a1ada08a71 003014fbe32aebf4
|
||||
1e53d5a1ada08a71 29409290c370fbb3
|
||||
1eb8d5b0fcd3627e 003014fbe32aebf4
|
||||
1eb8d5b0fcd3627e 29409290c370fbb3
|
||||
1f67c861e4121c15 003014fbe32aebf4
|
||||
1f67c861e4121c15 29409290c370fbb3
|
||||
202cd4ed023df975 003014fbe32aebf4
|
||||
202cd4ed023df975 29409290c370fbb3
|
||||
20d738034dc188a3 003014fbe32aebf4
|
||||
20d738034dc188a3 29409290c370fbb3
|
||||
211736e6fda6162d 003014fbe32aebf4
|
||||
211736e6fda6162d 29409290c370fbb3
|
||||
22559a5d012bcfe9 003014fbe32aebf4
|
||||
22559a5d012bcfe9 29409290c370fbb3
|
||||
22a19e095bbc59bf 003014fbe32aebf4
|
||||
22a19e095bbc59bf 29409290c370fbb3
|
||||
23522240236d2b54 003014fbe32aebf4
|
||||
23522240236d2b54 29409290c370fbb3
|
||||
23f84817448387c6 003014fbe32aebf4
|
||||
23f84817448387c6 29409290c370fbb3
|
||||
245246ecc69b9520 003014fbe32aebf4
|
||||
245246ecc69b9520 29409290c370fbb3
|
||||
24ea2d84b2a209ee 003014fbe32aebf4
|
||||
24ea2d84b2a209ee 29409290c370fbb3
|
||||
2684e72f470ead30 003014fbe32aebf4
|
||||
2684e72f470ead30 29409290c370fbb3
|
||||
2699352be721c40d 003014fbe32aebf4
|
||||
2699352be721c40d 29409290c370fbb3
|
||||
26f4501e9a33b938 003014fbe32aebf4
|
||||
26f4501e9a33b938 29409290c370fbb3
|
||||
275ba46b2d284f96 003014fbe32aebf4
|
||||
275ba46b2d284f96 29409290c370fbb3
|
||||
27bb7ba5acb49f2e 003014fbe32aebf4
|
||||
27bb7ba5acb49f2e 29409290c370fbb3
|
||||
27e74443a67249cf 003014fbe32aebf4
|
||||
27e74443a67249cf 29409290c370fbb3
|
||||
27f84887ba047a0f 003014fbe32aebf4
|
||||
27f84887ba047a0f 29409290c370fbb3
|
||||
28bf04958fb618ba 003014fbe32aebf4
|
||||
28bf04958fb618ba 29409290c370fbb3
|
||||
28fab3ac6021643c 003014fbe32aebf4
|
||||
28fab3ac6021643c 29409290c370fbb3
|
||||
2927d1cc4a4bc614 003014fbe32aebf4
|
||||
2927d1cc4a4bc614 29409290c370fbb3
|
||||
2951a62451bc8cc3 003014fbe32aebf4
|
||||
2951a62451bc8cc3 29409290c370fbb3
|
||||
295b294220f90e24 003014fbe32aebf4
|
||||
295b294220f90e24 29409290c370fbb3
|
||||
29ddf580a55222ae 003014fbe32aebf4
|
||||
29ddf580a55222ae 29409290c370fbb3
|
||||
2a4420c4331b87e7 003014fbe32aebf4
|
||||
2a4420c4331b87e7 29409290c370fbb3
|
||||
2a8a3b0b4a9ec8fa 003014fbe32aebf4
|
||||
2a8a3b0b4a9ec8fa 29409290c370fbb3
|
||||
2b584d16178d8578 003014fbe32aebf4
|
||||
2b584d16178d8578 29409290c370fbb3
|
||||
2bca666743d245d4 003014fbe32aebf4
|
||||
2bca666743d245d4 29409290c370fbb3
|
||||
2e4f678dbc818b58 003014fbe32aebf4
|
||||
2e4f678dbc818b58 29409290c370fbb3
|
||||
2e5cd104ff68700c 003014fbe32aebf4
|
||||
2e5cd104ff68700c 29409290c370fbb3
|
||||
2f64b946ae766851 003014fbe32aebf4
|
||||
2f64b946ae766851 29409290c370fbb3
|
||||
2fa0719caa180198 003014fbe32aebf4
|
||||
2fa0719caa180198 29409290c370fbb3
|
||||
2fec68ad345a00ce 003014fbe32aebf4
|
||||
2fec68ad345a00ce 29409290c370fbb3
|
||||
3060931a7a3ebec5 003014fbe32aebf4
|
||||
3060931a7a3ebec5 29409290c370fbb3
|
||||
3075f4bd6e97a74b 003014fbe32aebf4
|
||||
3075f4bd6e97a74b 29409290c370fbb3
|
||||
30c40d9559b78eab 003014fbe32aebf4
|
||||
30c40d9559b78eab 29409290c370fbb3
|
||||
3120a2170b7f30b7 003014fbe32aebf4
|
||||
3120a2170b7f30b7 29409290c370fbb3
|
||||
3172794a7c1c4a89 003014fbe32aebf4
|
||||
3172794a7c1c4a89 29409290c370fbb3
|
||||
317b2aa94bc181e2 003014fbe32aebf4
|
||||
317b2aa94bc181e2 29409290c370fbb3
|
||||
317bc48071a2dad7 003014fbe32aebf4
|
||||
317bc48071a2dad7 29409290c370fbb3
|
||||
3200818d3576ee6e 003014fbe32aebf4
|
||||
3200818d3576ee6e 29409290c370fbb3
|
||||
3228d0f8b5e49bcf 003014fbe32aebf4
|
||||
3228d0f8b5e49bcf 29409290c370fbb3
|
||||
33915f0dfe0a2f0f 003014fbe32aebf4
|
||||
33915f0dfe0a2f0f 29409290c370fbb3
|
||||
33abe98dd91667f7 003014fbe32aebf4
|
||||
33abe98dd91667f7 29409290c370fbb3
|
||||
3442455a6629a3e8 003014fbe32aebf4
|
||||
3442455a6629a3e8 29409290c370fbb3
|
||||
3478e636faeea720 003014fbe32aebf4
|
||||
3478e636faeea720 29409290c370fbb3
|
||||
34be2668d5c14ce4 003014fbe32aebf4
|
||||
34be2668d5c14ce4 29409290c370fbb3
|
||||
35918cd6ef409d47 003014fbe32aebf4
|
||||
35918cd6ef409d47 29409290c370fbb3
|
||||
35bdf55d0b9c2b59 003014fbe32aebf4
|
||||
35bdf55d0b9c2b59 29409290c370fbb3
|
||||
376ce02e4efdcc95 003014fbe32aebf4
|
||||
376ce02e4efdcc95 29409290c370fbb3
|
||||
3798a8667a4e8bb4 003014fbe32aebf4
|
||||
3798a8667a4e8bb4 29409290c370fbb3
|
||||
381529be7a9052e5 003014fbe32aebf4
|
||||
381529be7a9052e5 29409290c370fbb3
|
||||
381c70bf5a519c9f 003014fbe32aebf4
|
||||
381c70bf5a519c9f 29409290c370fbb3
|
||||
38cd449544dbe683 003014fbe32aebf4
|
||||
38cd449544dbe683 29409290c370fbb3
|
||||
3c0314978d8f875d 003014fbe32aebf4
|
||||
3c0314978d8f875d 29409290c370fbb3
|
||||
3c827071d2e51c47 003014fbe32aebf4
|
||||
3c827071d2e51c47 29409290c370fbb3
|
||||
3d91412b0e5ba0f1 003014fbe32aebf4
|
||||
3d91412b0e5ba0f1 29409290c370fbb3
|
||||
3df89f36b5ff6f8a 003014fbe32aebf4
|
||||
3df89f36b5ff6f8a 29409290c370fbb3
|
||||
3e2e98bafd67d1aa 003014fbe32aebf4
|
||||
3e2e98bafd67d1aa 29409290c370fbb3
|
||||
3ee3760b773ea1d4 003014fbe32aebf4
|
||||
3ee3760b773ea1d4 29409290c370fbb3
|
||||
403bf2b2b7c59f69 003014fbe32aebf4
|
||||
403bf2b2b7c59f69 29409290c370fbb3
|
||||
420342ab9fc06e85 003014fbe32aebf4
|
||||
420342ab9fc06e85 29409290c370fbb3
|
||||
4243a4b49cbfe516 003014fbe32aebf4
|
||||
4243a4b49cbfe516 29409290c370fbb3
|
||||
426e4ffb80f1bcce 003014fbe32aebf4
|
||||
426e4ffb80f1bcce 29409290c370fbb3
|
||||
4335c6476c8e077a 003014fbe32aebf4
|
||||
4335c6476c8e077a 29409290c370fbb3
|
||||
4481bf793f39a968 003014fbe32aebf4
|
||||
4481bf793f39a968 29409290c370fbb3
|
||||
44bf8b3fb1a520f3 003014fbe32aebf4
|
||||
44bf8b3fb1a520f3 29409290c370fbb3
|
||||
46e8cd0de7414e7f 003014fbe32aebf4
|
||||
46e8cd0de7414e7f 29409290c370fbb3
|
||||
47949807306be426 003014fbe32aebf4
|
||||
47949807306be426 29409290c370fbb3
|
||||
48e8a2852445c753 003014fbe32aebf4
|
||||
48e8a2852445c753 29409290c370fbb3
|
||||
495ebfcad1b0de03 003014fbe32aebf4
|
||||
495ebfcad1b0de03 29409290c370fbb3
|
||||
49bdc22d873840fc 003014fbe32aebf4
|
||||
49bdc22d873840fc 29409290c370fbb3
|
||||
4a25362eea9931a0 003014fbe32aebf4
|
||||
4a25362eea9931a0 29409290c370fbb3
|
||||
4af18498a895f57b 003014fbe32aebf4
|
||||
4af18498a895f57b 29409290c370fbb3
|
||||
4b04fe80f4563802 003014fbe32aebf4
|
||||
4b04fe80f4563802 29409290c370fbb3
|
||||
4b267a484535e791 003014fbe32aebf4
|
||||
4b267a484535e791 29409290c370fbb3
|
||||
4b504cb00ac17c32 003014fbe32aebf4
|
||||
4b504cb00ac17c32 29409290c370fbb3
|
||||
4b8e46eb92a07042 003014fbe32aebf4
|
||||
4b8e46eb92a07042 29409290c370fbb3
|
||||
4c21a42cc8eb836d 003014fbe32aebf4
|
||||
4c21a42cc8eb836d 29409290c370fbb3
|
||||
4c6f1a3f92b40935 003014fbe32aebf4
|
||||
4c6f1a3f92b40935 29409290c370fbb3
|
||||
4ce29aa1f7e99c6b 003014fbe32aebf4
|
||||
4ce29aa1f7e99c6b 29409290c370fbb3
|
||||
4cee2136a047e8be 003014fbe32aebf4
|
||||
4cee2136a047e8be 29409290c370fbb3
|
||||
4dd8e12bbc0ef039 003014fbe32aebf4
|
||||
4dd8e12bbc0ef039 29409290c370fbb3
|
||||
4ea5793c080d8942 003014fbe32aebf4
|
||||
4ea5793c080d8942 29409290c370fbb3
|
||||
4f1f3fedbaa30b31 003014fbe32aebf4
|
||||
4f1f3fedbaa30b31 29409290c370fbb3
|
||||
50f2180636058b9d 003014fbe32aebf4
|
||||
50f2180636058b9d 29409290c370fbb3
|
||||
5167197e20b9f6da 003014fbe32aebf4
|
||||
5167197e20b9f6da 29409290c370fbb3
|
||||
516d7dd5b5c25e66 003014fbe32aebf4
|
||||
516d7dd5b5c25e66 29409290c370fbb3
|
||||
527a21a215dedb48 003014fbe32aebf4
|
||||
527a21a215dedb48 29409290c370fbb3
|
||||
538c428a5a300101 003014fbe32aebf4
|
||||
538c428a5a300101 29409290c370fbb3
|
||||
539866479aac520f 003014fbe32aebf4
|
||||
539866479aac520f 29409290c370fbb3
|
||||
53ff15f43c32fe44 003014fbe32aebf4
|
||||
53ff15f43c32fe44 29409290c370fbb3
|
||||
54855c38a82e3f39 003014fbe32aebf4
|
||||
54855c38a82e3f39 29409290c370fbb3
|
||||
558515d7412057c3 003014fbe32aebf4
|
||||
558515d7412057c3 29409290c370fbb3
|
||||
5612e3d2cd7cd78d 003014fbe32aebf4
|
||||
5612e3d2cd7cd78d 29409290c370fbb3
|
||||
564a41fa6fd0f33f 003014fbe32aebf4
|
||||
564a41fa6fd0f33f 29409290c370fbb3
|
||||
56ad169bb86186c9 003014fbe32aebf4
|
||||
56ad169bb86186c9 29409290c370fbb3
|
||||
56fe21797160696d 003014fbe32aebf4
|
||||
56fe21797160696d 29409290c370fbb3
|
||||
570bb14e98ed8be0 003014fbe32aebf4
|
||||
570bb14e98ed8be0 29409290c370fbb3
|
||||
5716b91f0a823f72 003014fbe32aebf4
|
||||
5716b91f0a823f72 29409290c370fbb3
|
||||
57b294603b0d5af0 003014fbe32aebf4
|
||||
57b294603b0d5af0 29409290c370fbb3
|
||||
58b01056e8e1d0e1 003014fbe32aebf4
|
||||
58b01056e8e1d0e1 29409290c370fbb3
|
||||
5937c2f58eb77b3a 003014fbe32aebf4
|
||||
5937c2f58eb77b3a 29409290c370fbb3
|
||||
5a5c9133d0f16649 003014fbe32aebf4
|
||||
5a5c9133d0f16649 29409290c370fbb3
|
||||
5abfc76b38083f5c 003014fbe32aebf4
|
||||
5abfc76b38083f5c 29409290c370fbb3
|
||||
5b0cd4648ce3fc42 003014fbe32aebf4
|
||||
5b0cd4648ce3fc42 29409290c370fbb3
|
||||
5b7145817478b9e7 003014fbe32aebf4
|
||||
5b7145817478b9e7 29409290c370fbb3
|
||||
5bc4618af9175578 003014fbe32aebf4
|
||||
5bc4618af9175578 29409290c370fbb3
|
||||
5c55eae177dace24 003014fbe32aebf4
|
||||
5c55eae177dace24 29409290c370fbb3
|
||||
5c5804269a156941 003014fbe32aebf4
|
||||
5c5804269a156941 29409290c370fbb3
|
||||
5d589a8c4f58dfeb 003014fbe32aebf4
|
||||
5d589a8c4f58dfeb 29409290c370fbb3
|
||||
5f880399702b500c 003014fbe32aebf4
|
||||
5f880399702b500c 29409290c370fbb3
|
||||
60b0fdd0212bf1b1 003014fbe32aebf4
|
||||
60b0fdd0212bf1b1 29409290c370fbb3
|
||||
60efcbb6068d4311 003014fbe32aebf4
|
||||
60efcbb6068d4311 29409290c370fbb3
|
||||
620bb1048fcba35c 003014fbe32aebf4
|
||||
620bb1048fcba35c 29409290c370fbb3
|
||||
621589bd6c91847f 003014fbe32aebf4
|
||||
621589bd6c91847f 29409290c370fbb3
|
||||
62dcb5a12f6c4f1a 003014fbe32aebf4
|
||||
62dcb5a12f6c4f1a 29409290c370fbb3
|
||||
6339e2754623a767 003014fbe32aebf4
|
||||
6339e2754623a767 29409290c370fbb3
|
||||
633b77f5411adf73 003014fbe32aebf4
|
||||
633b77f5411adf73 29409290c370fbb3
|
||||
65426d1f51dbaa57 003014fbe32aebf4
|
||||
65426d1f51dbaa57 29409290c370fbb3
|
||||
66260b27255ca9db 003014fbe32aebf4
|
||||
66260b27255ca9db 29409290c370fbb3
|
||||
663373274dd577f3 003014fbe32aebf4
|
||||
663373274dd577f3 29409290c370fbb3
|
||||
66db13312407223e 003014fbe32aebf4
|
||||
66db13312407223e 29409290c370fbb3
|
||||
66e3950216a635cf 003014fbe32aebf4
|
||||
66e3950216a635cf 29409290c370fbb3
|
||||
6738fc27e8a94cf2 003014fbe32aebf4
|
||||
6738fc27e8a94cf2 29409290c370fbb3
|
||||
67ddcaa39b8473c5 003014fbe32aebf4
|
||||
67ddcaa39b8473c5 29409290c370fbb3
|
||||
690c747bec63bdbf 003014fbe32aebf4
|
||||
690c747bec63bdbf 29409290c370fbb3
|
||||
693ed4a0cce8633b 003014fbe32aebf4
|
||||
693ed4a0cce8633b 29409290c370fbb3
|
||||
69ecb19157e68527 003014fbe32aebf4
|
||||
69ecb19157e68527 29409290c370fbb3
|
||||
6ab0a50ad4cfbebc 003014fbe32aebf4
|
||||
6ab0a50ad4cfbebc 29409290c370fbb3
|
||||
6b5c6bbf33603eda 003014fbe32aebf4
|
||||
6b5c6bbf33603eda 29409290c370fbb3
|
||||
6bdf8484cbb69b7f 003014fbe32aebf4
|
||||
6bdf8484cbb69b7f 29409290c370fbb3
|
||||
6c56bc83bdeb399f 003014fbe32aebf4
|
||||
6c56bc83bdeb399f 29409290c370fbb3
|
||||
6c5de24d75200f4d 003014fbe32aebf4
|
||||
6c5de24d75200f4d 29409290c370fbb3
|
||||
6c713ff6aa3952e0 003014fbe32aebf4
|
||||
6c713ff6aa3952e0 29409290c370fbb3
|
||||
6c9e7daf527cea9d 003014fbe32aebf4
|
||||
6c9e7daf527cea9d 29409290c370fbb3
|
||||
6d95d272391f899b 003014fbe32aebf4
|
||||
6d95d272391f899b 29409290c370fbb3
|
||||
6e18499028aead6a 003014fbe32aebf4
|
||||
6e18499028aead6a 29409290c370fbb3
|
||||
6ea7b8809476c3f9 003014fbe32aebf4
|
||||
6ea7b8809476c3f9 29409290c370fbb3
|
||||
6f93dc566009c1a0 003014fbe32aebf4
|
||||
6f93dc566009c1a0 29409290c370fbb3
|
||||
70c45d397c6ea923 003014fbe32aebf4
|
||||
70c45d397c6ea923 29409290c370fbb3
|
||||
7125a9f1fa9ff7f3 003014fbe32aebf4
|
||||
7125a9f1fa9ff7f3 29409290c370fbb3
|
||||
714905b9d69c454d 003014fbe32aebf4
|
||||
714905b9d69c454d 29409290c370fbb3
|
||||
729cacd79f798cce 003014fbe32aebf4
|
||||
729cacd79f798cce 29409290c370fbb3
|
||||
74e5d663cb14a321 003014fbe32aebf4
|
||||
74e5d663cb14a321 29409290c370fbb3
|
||||
759e816ddf716ada 003014fbe32aebf4
|
||||
759e816ddf716ada 29409290c370fbb3
|
||||
75db9ce3f57d8d3f 003014fbe32aebf4
|
||||
75db9ce3f57d8d3f 29409290c370fbb3
|
||||
761e0ee659291f78 003014fbe32aebf4
|
||||
761e0ee659291f78 29409290c370fbb3
|
||||
762884900028e9ca 003014fbe32aebf4
|
||||
762884900028e9ca 29409290c370fbb3
|
||||
76fd7922ed50d4f6 003014fbe32aebf4
|
||||
76fd7922ed50d4f6 29409290c370fbb3
|
||||
77761daa405f8b2e 003014fbe32aebf4
|
||||
77761daa405f8b2e 29409290c370fbb3
|
||||
79db7c61c0eea8aa 003014fbe32aebf4
|
||||
79db7c61c0eea8aa 29409290c370fbb3
|
||||
79dc0bdf302fa006 003014fbe32aebf4
|
||||
79dc0bdf302fa006 29409290c370fbb3
|
||||
7a3fc512451d2158 003014fbe32aebf4
|
||||
7a3fc512451d2158 29409290c370fbb3
|
||||
7afeb2f654fd1d85 003014fbe32aebf4
|
||||
7afeb2f654fd1d85 29409290c370fbb3
|
||||
7b77d30b615a7da8 003014fbe32aebf4
|
||||
7b77d30b615a7da8 29409290c370fbb3
|
||||
7cf5a3649909c1cd 003014fbe32aebf4
|
||||
7cf5a3649909c1cd 29409290c370fbb3
|
||||
7d4a2886de306898 003014fbe32aebf4
|
||||
7d4a2886de306898 29409290c370fbb3
|
||||
7dce6394debb6626 003014fbe32aebf4
|
||||
7dce6394debb6626 29409290c370fbb3
|
||||
7dda3d1efa67bfa0 003014fbe32aebf4
|
||||
7dda3d1efa67bfa0 29409290c370fbb3
|
||||
802a6975d5b720c5 003014fbe32aebf4
|
||||
802a6975d5b720c5 29409290c370fbb3
|
||||
814722586879cba9 003014fbe32aebf4
|
||||
814722586879cba9 29409290c370fbb3
|
||||
8185a60f85543d50 003014fbe32aebf4
|
||||
8185a60f85543d50 29409290c370fbb3
|
||||
826a7d03f858d621 003014fbe32aebf4
|
||||
826a7d03f858d621 29409290c370fbb3
|
||||
82aa28863ce57170 003014fbe32aebf4
|
||||
82aa28863ce57170 29409290c370fbb3
|
||||
8317525804b1f341 003014fbe32aebf4
|
||||
8317525804b1f341 29409290c370fbb3
|
||||
832c75a10e2936b1 003014fbe32aebf4
|
||||
832c75a10e2936b1 29409290c370fbb3
|
||||
834f02f8ff2639ab 003014fbe32aebf4
|
||||
834f02f8ff2639ab 29409290c370fbb3
|
||||
839502121e8dc98c 003014fbe32aebf4
|
||||
839502121e8dc98c 29409290c370fbb3
|
||||
8493734b79f86ce9 003014fbe32aebf4
|
||||
8493734b79f86ce9 29409290c370fbb3
|
||||
84d42b630f551588 003014fbe32aebf4
|
||||
84d42b630f551588 29409290c370fbb3
|
||||
85676cd8b3df3c91 003014fbe32aebf4
|
||||
85676cd8b3df3c91 29409290c370fbb3
|
||||
8582074f224ca0b8 003014fbe32aebf4
|
||||
8582074f224ca0b8 29409290c370fbb3
|
||||
86ee1eeb894ffdc0 003014fbe32aebf4
|
||||
86ee1eeb894ffdc0 29409290c370fbb3
|
||||
8748eb8a3aff0784 003014fbe32aebf4
|
||||
8748eb8a3aff0784 29409290c370fbb3
|
||||
876fa391da6d971d 003014fbe32aebf4
|
||||
876fa391da6d971d 29409290c370fbb3
|
||||
87be4f2b6e0ccb2e 003014fbe32aebf4
|
||||
87be4f2b6e0ccb2e 29409290c370fbb3
|
||||
8889f9c128c017cb 003014fbe32aebf4
|
||||
8889f9c128c017cb 29409290c370fbb3
|
||||
8916a280e66a48fc 003014fbe32aebf4
|
||||
8916a280e66a48fc 29409290c370fbb3
|
||||
896eaabe86861d6f 003014fbe32aebf4
|
||||
896eaabe86861d6f 29409290c370fbb3
|
||||
8971677029c75df0 003014fbe32aebf4
|
||||
8971677029c75df0 29409290c370fbb3
|
||||
89e1d6f2b304ae32 003014fbe32aebf4
|
||||
89e1d6f2b304ae32 29409290c370fbb3
|
||||
89e34eeb688730ef 003014fbe32aebf4
|
||||
89e34eeb688730ef 29409290c370fbb3
|
||||
8a8ff4eef2621073 003014fbe32aebf4
|
||||
8a8ff4eef2621073 29409290c370fbb3
|
||||
8b5876f088e53b59 003014fbe32aebf4
|
||||
8b5876f088e53b59 29409290c370fbb3
|
||||
8b8b5d7e70d853ff 003014fbe32aebf4
|
||||
8b8b5d7e70d853ff 29409290c370fbb3
|
||||
8c35b63ea0e416f8 003014fbe32aebf4
|
||||
8c35b63ea0e416f8 29409290c370fbb3
|
||||
8c74b8315a452ed4 003014fbe32aebf4
|
||||
8c74b8315a452ed4 29409290c370fbb3
|
||||
8cc2ef399c68e1e0 003014fbe32aebf4
|
||||
8cc2ef399c68e1e0 29409290c370fbb3
|
||||
8d6ec6ca914d4aca 003014fbe32aebf4
|
||||
8d6ec6ca914d4aca 29409290c370fbb3
|
||||
8d9d5331523f7131 003014fbe32aebf4
|
||||
8d9d5331523f7131 29409290c370fbb3
|
||||
8dd406037cbad7d6 003014fbe32aebf4
|
||||
8dd406037cbad7d6 29409290c370fbb3
|
||||
8dd44e4fb7e0ccda 003014fbe32aebf4
|
||||
8dd44e4fb7e0ccda 29409290c370fbb3
|
||||
8e71d5dd0634163d 003014fbe32aebf4
|
||||
8e71d5dd0634163d 29409290c370fbb3
|
||||
8ec452184db7c614 003014fbe32aebf4
|
||||
8ec452184db7c614 29409290c370fbb3
|
||||
9012452bd73f8362 003014fbe32aebf4
|
||||
9012452bd73f8362 29409290c370fbb3
|
||||
9120f4bd1b68706c 003014fbe32aebf4
|
||||
9120f4bd1b68706c 29409290c370fbb3
|
||||
91469cbd164aca18 003014fbe32aebf4
|
||||
91469cbd164aca18 29409290c370fbb3
|
||||
91fbe24d458ab15f 003014fbe32aebf4
|
||||
91fbe24d458ab15f 29409290c370fbb3
|
||||
924549389994d73c 003014fbe32aebf4
|
||||
924549389994d73c 29409290c370fbb3
|
||||
92edc9746a27d939 003014fbe32aebf4
|
||||
92edc9746a27d939 29409290c370fbb3
|
||||
930171e5a698ecb0 003014fbe32aebf4
|
||||
930171e5a698ecb0 29409290c370fbb3
|
||||
93683ad476b7d2e1 003014fbe32aebf4
|
||||
93683ad476b7d2e1 29409290c370fbb3
|
||||
938d74daef7caf9e 003014fbe32aebf4
|
||||
938d74daef7caf9e 29409290c370fbb3
|
||||
93f1b4ad7ef277a9 003014fbe32aebf4
|
||||
93f1b4ad7ef277a9 29409290c370fbb3
|
||||
95216b02a9a7dc40 003014fbe32aebf4
|
||||
95216b02a9a7dc40 29409290c370fbb3
|
||||
95e7d53ed7584047 003014fbe32aebf4
|
||||
95e7d53ed7584047 29409290c370fbb3
|
||||
9630116e931a0caf 003014fbe32aebf4
|
||||
9630116e931a0caf 29409290c370fbb3
|
||||
9717c92c548b9a52 003014fbe32aebf4
|
||||
9717c92c548b9a52 29409290c370fbb3
|
||||
973780a354d0dd71 003014fbe32aebf4
|
||||
973780a354d0dd71 29409290c370fbb3
|
||||
979181b0e49f979f 003014fbe32aebf4
|
||||
979181b0e49f979f 29409290c370fbb3
|
||||
97cf973d9f71d31a 003014fbe32aebf4
|
||||
97cf973d9f71d31a 29409290c370fbb3
|
||||
98dd8d75472885e6 003014fbe32aebf4
|
||||
98dd8d75472885e6 29409290c370fbb3
|
||||
9917eb8c593b3da7 003014fbe32aebf4
|
||||
9917eb8c593b3da7 29409290c370fbb3
|
||||
997ac1e6edd764bc 003014fbe32aebf4
|
||||
997ac1e6edd764bc 29409290c370fbb3
|
||||
99be8b2d637faa41 003014fbe32aebf4
|
||||
99be8b2d637faa41 29409290c370fbb3
|
||||
9b21c1feeab01eee 003014fbe32aebf4
|
||||
9b21c1feeab01eee 29409290c370fbb3
|
||||
9b8b89aed614281a 003014fbe32aebf4
|
||||
9b8b89aed614281a 29409290c370fbb3
|
||||
9c5cb393add3099a 003014fbe32aebf4
|
||||
9c5cb393add3099a 29409290c370fbb3
|
||||
9cdd4aa5e9b0ad25 003014fbe32aebf4
|
||||
9cdd4aa5e9b0ad25 29409290c370fbb3
|
||||
9d3680589c217e3d 003014fbe32aebf4
|
||||
9d3680589c217e3d 29409290c370fbb3
|
||||
9db77a31add7e6e7 003014fbe32aebf4
|
||||
9db77a31add7e6e7 29409290c370fbb3
|
||||
9dc6d7c6d52db5c6 003014fbe32aebf4
|
||||
9dc6d7c6d52db5c6 29409290c370fbb3
|
||||
9e44b177fc95bcdf 003014fbe32aebf4
|
||||
9e44b177fc95bcdf 29409290c370fbb3
|
||||
9e5bb361ded7fec1 003014fbe32aebf4
|
||||
9e5bb361ded7fec1 29409290c370fbb3
|
||||
9e7d815ba0bc5004 003014fbe32aebf4
|
||||
9e7d815ba0bc5004 29409290c370fbb3
|
||||
9f11a2b3be5b1317 003014fbe32aebf4
|
||||
9f11a2b3be5b1317 29409290c370fbb3
|
||||
9ff4a40f4e4d72c1 003014fbe32aebf4
|
||||
9ff4a40f4e4d72c1 29409290c370fbb3
|
||||
a0297cce3a2664cc 003014fbe32aebf4
|
||||
a0297cce3a2664cc 29409290c370fbb3
|
||||
a2827aae7cf93b1a 003014fbe32aebf4
|
||||
a2827aae7cf93b1a 29409290c370fbb3
|
||||
a2de1b9e3ed333e0 003014fbe32aebf4
|
||||
a2de1b9e3ed333e0 29409290c370fbb3
|
||||
a34248d56ac62380 003014fbe32aebf4
|
||||
a34248d56ac62380 29409290c370fbb3
|
||||
a38809153bc9f336 003014fbe32aebf4
|
||||
a38809153bc9f336 29409290c370fbb3
|
||||
a45798e7e5405bce 003014fbe32aebf4
|
||||
a45798e7e5405bce 29409290c370fbb3
|
||||
a5fe1b142e455790 003014fbe32aebf4
|
||||
a5fe1b142e455790 29409290c370fbb3
|
||||
a6570dda8e02225c 003014fbe32aebf4
|
||||
a6570dda8e02225c 29409290c370fbb3
|
||||
a6722e943cd49d24 003014fbe32aebf4
|
||||
a6722e943cd49d24 29409290c370fbb3
|
||||
a909766e4c3c5b65 003014fbe32aebf4
|
||||
a909766e4c3c5b65 29409290c370fbb3
|
||||
a9849d62a26d8be8 003014fbe32aebf4
|
||||
a9849d62a26d8be8 29409290c370fbb3
|
||||
aa25e3c5744607c7 003014fbe32aebf4
|
||||
aa25e3c5744607c7 29409290c370fbb3
|
||||
aa7e9ae5cceebd07 003014fbe32aebf4
|
||||
aa7e9ae5cceebd07 29409290c370fbb3
|
||||
aadbeef39fa4fecd 003014fbe32aebf4
|
||||
aadbeef39fa4fecd 29409290c370fbb3
|
||||
aaed1af8aecf585e 003014fbe32aebf4
|
||||
aaed1af8aecf585e 29409290c370fbb3
|
||||
ab008b65280a6dcc 003014fbe32aebf4
|
||||
ab008b65280a6dcc 29409290c370fbb3
|
||||
ac2629ecce1ec96d 003014fbe32aebf4
|
||||
ac2629ecce1ec96d 29409290c370fbb3
|
||||
ad33d76034eab219 003014fbe32aebf4
|
||||
ad33d76034eab219 29409290c370fbb3
|
||||
ad6702c9bda26e00 003014fbe32aebf4
|
||||
ad6702c9bda26e00 29409290c370fbb3
|
||||
ae0e4109b70060eb 003014fbe32aebf4
|
||||
ae0e4109b70060eb 29409290c370fbb3
|
||||
ae1a4c7b1a79f5de 003014fbe32aebf4
|
||||
ae1a4c7b1a79f5de 29409290c370fbb3
|
||||
ae362216b7a3264b 003014fbe32aebf4
|
||||
ae362216b7a3264b 29409290c370fbb3
|
||||
af4356dd3fcea48e 003014fbe32aebf4
|
||||
af4356dd3fcea48e 29409290c370fbb3
|
||||
afa437dfea94da6f 003014fbe32aebf4
|
||||
afa437dfea94da6f 29409290c370fbb3
|
||||
afcc06ac32ed22bc 003014fbe32aebf4
|
||||
afcc06ac32ed22bc 29409290c370fbb3
|
||||
b11ee5716261b91a 003014fbe32aebf4
|
||||
b11ee5716261b91a 29409290c370fbb3
|
||||
b14660d17d527147 003014fbe32aebf4
|
||||
b14660d17d527147 29409290c370fbb3
|
||||
b20d5f1ca502b96b 003014fbe32aebf4
|
||||
b20d5f1ca502b96b 29409290c370fbb3
|
||||
b3397155c49b686d 003014fbe32aebf4
|
||||
b3397155c49b686d 29409290c370fbb3
|
||||
b36ac8dfd38e7351 003014fbe32aebf4
|
||||
b36ac8dfd38e7351 29409290c370fbb3
|
||||
b3bd0a92c3852b18 003014fbe32aebf4
|
||||
b3bd0a92c3852b18 29409290c370fbb3
|
||||
b51857c9e702891e 003014fbe32aebf4
|
||||
b51857c9e702891e 29409290c370fbb3
|
||||
b573c5dd40a228f2 003014fbe32aebf4
|
||||
b573c5dd40a228f2 29409290c370fbb3
|
||||
b67cfa491cce2186 003014fbe32aebf4
|
||||
b67cfa491cce2186 29409290c370fbb3
|
||||
b72253dc348b4fc0 003014fbe32aebf4
|
||||
b72253dc348b4fc0 29409290c370fbb3
|
||||
b77aa46089eb19cc 003014fbe32aebf4
|
||||
b77aa46089eb19cc 29409290c370fbb3
|
||||
b7bd7e52f0ce3a0f 003014fbe32aebf4
|
||||
b7bd7e52f0ce3a0f 29409290c370fbb3
|
||||
bac25df2344c12b6 003014fbe32aebf4
|
||||
bac25df2344c12b6 29409290c370fbb3
|
||||
baea40ab3b7b2400 003014fbe32aebf4
|
||||
baea40ab3b7b2400 29409290c370fbb3
|
||||
bc0e9846b60db73a 003014fbe32aebf4
|
||||
bc0e9846b60db73a 29409290c370fbb3
|
||||
bcdf492944f07b1a 003014fbe32aebf4
|
||||
bcdf492944f07b1a 29409290c370fbb3
|
||||
bd62d0be7821db4d 003014fbe32aebf4
|
||||
bd62d0be7821db4d 29409290c370fbb3
|
||||
bdfd132010d67f46 003014fbe32aebf4
|
||||
bdfd132010d67f46 29409290c370fbb3
|
||||
beee5b62246fe9d9 003014fbe32aebf4
|
||||
beee5b62246fe9d9 29409290c370fbb3
|
||||
bf35982bafaad392 003014fbe32aebf4
|
||||
bf35982bafaad392 29409290c370fbb3
|
||||
bf7d3982cb787842 003014fbe32aebf4
|
||||
bf7d3982cb787842 29409290c370fbb3
|
||||
c053e0d90c05e920 003014fbe32aebf4
|
||||
c053e0d90c05e920 29409290c370fbb3
|
||||
c0693ab8b19c70c9 003014fbe32aebf4
|
||||
c0693ab8b19c70c9 29409290c370fbb3
|
||||
c095fa961fef42f7 003014fbe32aebf4
|
||||
c095fa961fef42f7 29409290c370fbb3
|
||||
c0fb5fe67a335c04 003014fbe32aebf4
|
||||
c0fb5fe67a335c04 29409290c370fbb3
|
||||
c1b2e3d056378866 003014fbe32aebf4
|
||||
c1b2e3d056378866 29409290c370fbb3
|
||||
c36c80e2342b6a3f 003014fbe32aebf4
|
||||
c36c80e2342b6a3f 29409290c370fbb3
|
||||
c3f2d89cd13798f5 003014fbe32aebf4
|
||||
c3f2d89cd13798f5 29409290c370fbb3
|
||||
c48011d4f360342b 003014fbe32aebf4
|
||||
c48011d4f360342b 29409290c370fbb3
|
||||
c4b48feb6aa428af 003014fbe32aebf4
|
||||
c4b48feb6aa428af 29409290c370fbb3
|
||||
c4fb9df6b9be6f95 003014fbe32aebf4
|
||||
c4fb9df6b9be6f95 29409290c370fbb3
|
||||
c537ca0faa209796 003014fbe32aebf4
|
||||
c537ca0faa209796 29409290c370fbb3
|
||||
c54a5d9f61c279c1 003014fbe32aebf4
|
||||
c54a5d9f61c279c1 29409290c370fbb3
|
||||
c57286ef1fde5711 003014fbe32aebf4
|
||||
c57286ef1fde5711 29409290c370fbb3
|
||||
c6651a43c886e208 003014fbe32aebf4
|
||||
c6651a43c886e208 29409290c370fbb3
|
||||
c6dd69f31fd331a7 003014fbe32aebf4
|
||||
c6dd69f31fd331a7 29409290c370fbb3
|
||||
c6efab8738be05cd 003014fbe32aebf4
|
||||
c6efab8738be05cd 29409290c370fbb3
|
||||
c7758a32b5a4077e 003014fbe32aebf4
|
||||
c7758a32b5a4077e 29409290c370fbb3
|
||||
c802fe0a8cd8de2e 003014fbe32aebf4
|
||||
c802fe0a8cd8de2e 29409290c370fbb3
|
||||
c8820ae63c6627e5 003014fbe32aebf4
|
||||
c8820ae63c6627e5 29409290c370fbb3
|
||||
c8d0df92d94249c5 003014fbe32aebf4
|
||||
c8d0df92d94249c5 29409290c370fbb3
|
||||
ca654998a0e0d5ed 003014fbe32aebf4
|
||||
ca654998a0e0d5ed 29409290c370fbb3
|
||||
ca869f9f731aa601 003014fbe32aebf4
|
||||
ca869f9f731aa601 29409290c370fbb3
|
||||
cabfe9953b061521 003014fbe32aebf4
|
||||
cabfe9953b061521 29409290c370fbb3
|
||||
cbbdea5dccfdfc00 003014fbe32aebf4
|
||||
cbbdea5dccfdfc00 29409290c370fbb3
|
||||
cd7bc819e2763806 003014fbe32aebf4
|
||||
cd7bc819e2763806 29409290c370fbb3
|
||||
ce9fb573b0eef687 003014fbe32aebf4
|
||||
ce9fb573b0eef687 29409290c370fbb3
|
||||
ceb9b40fa25e0334 003014fbe32aebf4
|
||||
ceb9b40fa25e0334 29409290c370fbb3
|
||||
cf64f4081d2719bd 003014fbe32aebf4
|
||||
cf64f4081d2719bd 29409290c370fbb3
|
||||
d0391cf29b76c91e 003014fbe32aebf4
|
||||
d0391cf29b76c91e 29409290c370fbb3
|
||||
d06883a417d22518 003014fbe32aebf4
|
||||
d06883a417d22518 29409290c370fbb3
|
||||
d1f396ef263d2116 003014fbe32aebf4
|
||||
d1f396ef263d2116 29409290c370fbb3
|
||||
d20896dc8e3ba12f 003014fbe32aebf4
|
||||
d20896dc8e3ba12f 29409290c370fbb3
|
||||
d2605ef087e446a1 003014fbe32aebf4
|
||||
d2605ef087e446a1 29409290c370fbb3
|
||||
d2fe18f2217d1d99 003014fbe32aebf4
|
||||
d2fe18f2217d1d99 29409290c370fbb3
|
||||
d302a65eee05990c 003014fbe32aebf4
|
||||
d302a65eee05990c 29409290c370fbb3
|
||||
d327cfe5bbbacd2b 003014fbe32aebf4
|
||||
d327cfe5bbbacd2b 29409290c370fbb3
|
||||
d32edce903afc320 003014fbe32aebf4
|
||||
d32edce903afc320 29409290c370fbb3
|
||||
d39266d2d141f073 003014fbe32aebf4
|
||||
d39266d2d141f073 29409290c370fbb3
|
||||
d46edf962074a484 003014fbe32aebf4
|
||||
d46edf962074a484 29409290c370fbb3
|
||||
d49701500ef16c35 003014fbe32aebf4
|
||||
d49701500ef16c35 29409290c370fbb3
|
||||
d5bd18c5953449ee 003014fbe32aebf4
|
||||
d5bd18c5953449ee 29409290c370fbb3
|
||||
d6b6df684e3a4f0b 003014fbe32aebf4
|
||||
d6b6df684e3a4f0b 29409290c370fbb3
|
||||
d7278048d5116989 003014fbe32aebf4
|
||||
d7278048d5116989 29409290c370fbb3
|
||||
d8aed7e827ac0817 003014fbe32aebf4
|
||||
d8aed7e827ac0817 29409290c370fbb3
|
||||
d96667c18c3d1d9d 003014fbe32aebf4
|
||||
d96667c18c3d1d9d 29409290c370fbb3
|
||||
d9759eec27700316 003014fbe32aebf4
|
||||
d9759eec27700316 29409290c370fbb3
|
||||
d9da67c9b7283100 003014fbe32aebf4
|
||||
d9da67c9b7283100 29409290c370fbb3
|
||||
db83bdf58f818682 003014fbe32aebf4
|
||||
db83bdf58f818682 29409290c370fbb3
|
||||
dbb2220b85bc89d4 003014fbe32aebf4
|
||||
dbb2220b85bc89d4 29409290c370fbb3
|
||||
dbdd4a4c311713f2 003014fbe32aebf4
|
||||
dbdd4a4c311713f2 29409290c370fbb3
|
||||
dbfec15f2f3704e0 003014fbe32aebf4
|
||||
dbfec15f2f3704e0 29409290c370fbb3
|
||||
dd1168979ad75928 003014fbe32aebf4
|
||||
dd1168979ad75928 29409290c370fbb3
|
||||
dd7f5569ca37bd0e 003014fbe32aebf4
|
||||
dd7f5569ca37bd0e 29409290c370fbb3
|
||||
dea3924af7d6bab7 003014fbe32aebf4
|
||||
dea3924af7d6bab7 29409290c370fbb3
|
||||
dee839d6734828da 003014fbe32aebf4
|
||||
dee839d6734828da 29409290c370fbb3
|
||||
df059ddd471f1625 003014fbe32aebf4
|
||||
df059ddd471f1625 29409290c370fbb3
|
||||
e005ab8f4502e4f8 003014fbe32aebf4
|
||||
e005ab8f4502e4f8 29409290c370fbb3
|
||||
e066d5a81aae7579 003014fbe32aebf4
|
||||
e066d5a81aae7579 29409290c370fbb3
|
||||
e0c6a0852df1e723 003014fbe32aebf4
|
||||
e0c6a0852df1e723 29409290c370fbb3
|
||||
e2f0ebe796307a0f 003014fbe32aebf4
|
||||
e2f0ebe796307a0f 29409290c370fbb3
|
||||
e2faa4237bfc09c7 003014fbe32aebf4
|
||||
e2faa4237bfc09c7 29409290c370fbb3
|
||||
e31c5472b9a02392 003014fbe32aebf4
|
||||
e31c5472b9a02392 29409290c370fbb3
|
||||
e39fba587301e272 003014fbe32aebf4
|
||||
e39fba587301e272 29409290c370fbb3
|
||||
e3b4b7cc9fe7f581 003014fbe32aebf4
|
||||
e3b4b7cc9fe7f581 29409290c370fbb3
|
||||
e3b63dda66e1cdf6 003014fbe32aebf4
|
||||
e3b63dda66e1cdf6 29409290c370fbb3
|
||||
e3dcf71f5d467eda 003014fbe32aebf4
|
||||
e3dcf71f5d467eda 29409290c370fbb3
|
||||
e516a21d097921b1 003014fbe32aebf4
|
||||
e516a21d097921b1 29409290c370fbb3
|
||||
e54a62db3d6fa8f1 003014fbe32aebf4
|
||||
e54a62db3d6fa8f1 29409290c370fbb3
|
||||
e55cdf7241b4c37b 003014fbe32aebf4
|
||||
e55cdf7241b4c37b 29409290c370fbb3
|
||||
e5a38229a95b1005 003014fbe32aebf4
|
||||
e5a38229a95b1005 29409290c370fbb3
|
||||
e7021b4cf387fd43 003014fbe32aebf4
|
||||
e7021b4cf387fd43 29409290c370fbb3
|
||||
e7687846a25a34da 003014fbe32aebf4
|
||||
e7687846a25a34da 29409290c370fbb3
|
||||
e79097551ae9aca6 003014fbe32aebf4
|
||||
e79097551ae9aca6 29409290c370fbb3
|
||||
e8562eb57530b1db 003014fbe32aebf4
|
||||
e8562eb57530b1db 29409290c370fbb3
|
||||
e87106e9c5d3826c 003014fbe32aebf4
|
||||
e87106e9c5d3826c 29409290c370fbb3
|
||||
e9390fcd0f89d286 003014fbe32aebf4
|
||||
e9390fcd0f89d286 29409290c370fbb3
|
||||
e98511d54fb82bc8 003014fbe32aebf4
|
||||
e98511d54fb82bc8 29409290c370fbb3
|
||||
eaa51ebf13679257 003014fbe32aebf4
|
||||
eaa51ebf13679257 29409290c370fbb3
|
||||
eae85c777336bce3 003014fbe32aebf4
|
||||
eae85c777336bce3 29409290c370fbb3
|
||||
eaf2df477c4919a3 003014fbe32aebf4
|
||||
eaf2df477c4919a3 29409290c370fbb3
|
||||
eaf3bc1596a04691 003014fbe32aebf4
|
||||
eaf3bc1596a04691 29409290c370fbb3
|
||||
eb03699d1d2ff7db 003014fbe32aebf4
|
||||
eb03699d1d2ff7db 29409290c370fbb3
|
||||
eb14335f4c471c0c 003014fbe32aebf4
|
||||
eb14335f4c471c0c 29409290c370fbb3
|
||||
eba8a2e7dea8ee96 003014fbe32aebf4
|
||||
eba8a2e7dea8ee96 29409290c370fbb3
|
||||
ec12ffab66265c55 003014fbe32aebf4
|
||||
ec12ffab66265c55 29409290c370fbb3
|
||||
ec2e6a4bea800289 003014fbe32aebf4
|
||||
ec2e6a4bea800289 29409290c370fbb3
|
||||
ecfb82c08ca1adb5 003014fbe32aebf4
|
||||
ecfb82c08ca1adb5 29409290c370fbb3
|
||||
ecfd669875be7073 003014fbe32aebf4
|
||||
ecfd669875be7073 29409290c370fbb3
|
||||
ed27fd9b8d01b781 003014fbe32aebf4
|
||||
ed27fd9b8d01b781 29409290c370fbb3
|
||||
ed9240b3cdb51327 003014fbe32aebf4
|
||||
ed9240b3cdb51327 29409290c370fbb3
|
||||
ee1d03f1dd7bdd27 003014fbe32aebf4
|
||||
ee1d03f1dd7bdd27 29409290c370fbb3
|
||||
ee82a709f025499b 003014fbe32aebf4
|
||||
ee82a709f025499b 29409290c370fbb3
|
||||
ef230a8b1fad34e0 003014fbe32aebf4
|
||||
ef230a8b1fad34e0 29409290c370fbb3
|
||||
f232a7250ab2d860 003014fbe32aebf4
|
||||
f232a7250ab2d860 29409290c370fbb3
|
||||
f288addb4bff850a 003014fbe32aebf4
|
||||
f288addb4bff850a 29409290c370fbb3
|
||||
f2fd6cfd0ff14a18 003014fbe32aebf4
|
||||
f2fd6cfd0ff14a18 29409290c370fbb3
|
||||
f3919c82e489b011 003014fbe32aebf4
|
||||
f3919c82e489b011 29409290c370fbb3
|
||||
f3bc48abc1137f59 003014fbe32aebf4
|
||||
f3bc48abc1137f59 29409290c370fbb3
|
||||
f3d7b5da7e812a20 003014fbe32aebf4
|
||||
f3d7b5da7e812a20 29409290c370fbb3
|
||||
f5eabfdffd8ebb91 003014fbe32aebf4
|
||||
f5eabfdffd8ebb91 29409290c370fbb3
|
||||
f67708bff2af6b1e 003014fbe32aebf4
|
||||
f67708bff2af6b1e 29409290c370fbb3
|
||||
f71613f753032bdc 003014fbe32aebf4
|
||||
f71613f753032bdc 29409290c370fbb3
|
||||
f75555232ab8c6d9 003014fbe32aebf4
|
||||
f75555232ab8c6d9 29409290c370fbb3
|
||||
f7d79b2e216932c9 003014fbe32aebf4
|
||||
f7d79b2e216932c9 29409290c370fbb3
|
||||
f85271204f42be88 003014fbe32aebf4
|
||||
f85271204f42be88 29409290c370fbb3
|
||||
f8783d3bbec69c31 003014fbe32aebf4
|
||||
f8783d3bbec69c31 29409290c370fbb3
|
||||
f8b63f0517d55324 003014fbe32aebf4
|
||||
f8b63f0517d55324 29409290c370fbb3
|
||||
f98fd91e702894bf 003014fbe32aebf4
|
||||
f98fd91e702894bf 29409290c370fbb3
|
||||
f9e2bbfbd3f28b5c 003014fbe32aebf4
|
||||
f9e2bbfbd3f28b5c 29409290c370fbb3
|
||||
fa1d30612fbae734 003014fbe32aebf4
|
||||
fa1d30612fbae734 29409290c370fbb3
|
||||
fb064fc657a7e0e9 003014fbe32aebf4
|
||||
fb064fc657a7e0e9 29409290c370fbb3
|
||||
fbb4cc245f84df08 003014fbe32aebf4
|
||||
fbb4cc245f84df08 29409290c370fbb3
|
||||
fbcd81e58fa6bf78 003014fbe32aebf4
|
||||
fbcd81e58fa6bf78 29409290c370fbb3
|
||||
fc27b3452fa63d5d 003014fbe32aebf4
|
||||
fc27b3452fa63d5d 29409290c370fbb3
|
||||
fc5ca0a7ec242066 003014fbe32aebf4
|
||||
fc5ca0a7ec242066 29409290c370fbb3
|
||||
fc63930d46014f2d 003014fbe32aebf4
|
||||
fc63930d46014f2d 29409290c370fbb3
|
||||
fc8f349c4e5a634c 003014fbe32aebf4
|
||||
fc8f349c4e5a634c 29409290c370fbb3
|
||||
fd2bb3f2a89bfda8 003014fbe32aebf4
|
||||
fd2bb3f2a89bfda8 29409290c370fbb3
|
||||
fdc856af7c36349d 003014fbe32aebf4
|
||||
fdc856af7c36349d 29409290c370fbb3
|
||||
ff48ccf774f7f2dd 003014fbe32aebf4
|
||||
ff48ccf774f7f2dd 29409290c370fbb3
|
||||
|
@@ -77,6 +77,7 @@ One row per profile; the notes are each profile's `README.md`.
|
||||
| [Metroid Dread](010093801237C000/README.md) | `010093801237C000` | 2.1.0 | 11.4.3 | MercurySteam's engine | NVN |
|
||||
| [Monster Hunter Rise](0100B04011742000/README.md) | `0100B04011742000` | 16.0.2 | 11.4.3 | Capcom's RE Engine | NVN |
|
||||
| [Monster Train 2](010051701FB46000/README.md) | `010051701FB46000` | 1.1.1 | 18.3.5 | Unity 2022.3.54f1 IL2CPP | NVN |
|
||||
| [NieR:Automata The End of YoRHa Edition](010056B015FE8000/README.md) | `010056B015FE8000` | 1.0.3 | 12.3.9 | PlatinumGames' engine | NVN |
|
||||
| [Octopath Traveler 0](01005270232F2000/README.md) | `01005270232F2000` | 1.0.5 | 19.3.13 | Unreal Engine 5 | NVN |
|
||||
| [OCTOPATH TRAVELER II](0100A3501946E000/README.md) | `0100A3501946E000` | 1.1.1 | 12.3.2 | Unreal Engine 4.27 | NVN |
|
||||
| [Paper Mario: The Thousand-Year Door](0100ECD018EBE000/README.md) | `0100ECD018EBE000` | 1.0.1 | 15.3.2 | Intelligent Systems' engine on NintendoWare | NVN |
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
// Generated file (dm/gfx/tools/dmsh_chain.py --header): the B shader library translation chain version this source tree expects (default options), one for every game;
|
||||
// the host loads only <library dir>/b-<V>/. Run dmsh_chain.py --header after changing the chain's tools and commit this file with the change
|
||||
#define DMSH_CHAIN "467efdfd0b62"
|
||||
#define DMSH_CHAIN "20fe3d62b9f6"
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "nvn_mtl.h"
|
||||
#include "nvn_pace.h"
|
||||
#include "nvn_fstep.h"
|
||||
#include "nvn_timestamp.h"
|
||||
#include "../../host/front.h"
|
||||
#include "nvn_dirty.h"
|
||||
#include <mach/mach_time.h>
|
||||
@@ -2096,8 +2097,8 @@ NVN(nvnCommandBufferDrawTransformFeedback, void, NVNcommandBuffer *c, NVNdrawPri
|
||||
NVN(nvnDeviceGetTextureHandle, NVNtextureHandle, const NVNdevice *d, int tex, int samp) { (void)d; return (NVNtextureHandle)((uint64_t)(uint32_t)tex | (uint64_t)(uint32_t)samp << 20); }
|
||||
// Handle for texel fetches only (Monster Hunter Rise): a fetch reads the texture descriptor and no sampler, so the handle is the texture ID with sampler ID 0
|
||||
NVN(nvnDeviceGetTexelFetchHandle, NVNtextureHandle, const NVNdevice *d, int tex) { (void)d; return (NVNtextureHandle)(uint64_t)(uint32_t)tex; }
|
||||
// Counter timestamps are 19.2 MHz GPU ticks (nvn_mtl.m gpu_ticks: ns × 12 / 625); convert back to ns. They used to be returned as is, about 52 times smaller than GetCurrentTimestampInNanoseconds, so subtracting one from the other gave garbage
|
||||
NVN(nvnDeviceGetTimestampInNanoseconds, uint64_t, const NVNdevice *d, const NVNcounterData *c) { (void)d; return c->timestamp * 625 / 12; }
|
||||
// Convert the raw 614.4 MHz report to ns on the same guest clock as GetCurrentTimestampInNanoseconds.
|
||||
NVN(nvnDeviceGetTimestampInNanoseconds, uint64_t, const NVNdevice *d, const NVNcounterData *c) { (void)d; return nvn_timestamp_to_ns(c->timestamp); }
|
||||
// Current GPU time (ns): the same clock as the counter timestamps -- the guest clock (guest_ns, nvn_mtl.m gpu_ticks)
|
||||
NVN(nvnDeviceGetCurrentTimestampInNanoseconds, uint64_t, const NVNdevice *d) { (void)d; return guest_ns(); }
|
||||
NVN(nvnDeviceRegisterFastClearColor, NVNboolean, NVNdevice *d, const float *c, NVNformat f) { (void)d; (void)c; (void)f; return 1; }
|
||||
|
||||
@@ -71,29 +71,34 @@ static size_t nvn_geo_assemble(int prim, const uint32_t *src, size_t count, int
|
||||
// does not depend on Metal primitive-restart behaviour. Preserve triangle-strip
|
||||
// winding and the last vertex. Unwritten GS index slots are UINT_MAX.
|
||||
// Three dispatches, in order: geo_pack_count (a thread per invocation group counts the indices it
|
||||
// emits), geo_pack_scan (one thread turns the counts into offsets and writes the indirect arguments)
|
||||
// emits), geo_pack_scan (one workgroup scans contiguous chunks into ordered offsets and writes the indirect arguments)
|
||||
// and geo_pack_write (a thread per group writes its indices at its offset). A single thread used to
|
||||
// walk every group: with it, each frame that drew OCTOPATH TRAVELER II's 129,032-triangle cube shadow mesh
|
||||
// (drawn in runs, nvn_geometry.inc geo_split) took about 300 ms; now only the first one is long.
|
||||
static const char k_nvn_geo_pack_msl[] =
|
||||
"#include <metal_stdlib>\nusing namespace metal;\n"
|
||||
"struct geo_pack { device const uint *src; device uint *dst; device uint *args; uint groups, stride, topology, capacity; device uint *cnt; };\n"
|
||||
"static bool geo_room(constant geo_pack&j,uint o,uint k,uint n){return o<=j.capacity&&k<=j.capacity-o&&n<=j.capacity-o-k;}\n"
|
||||
"static uint geo_group(constant geo_pack& j, uint g, bool w, uint o) {\n"
|
||||
" uint a=0,b=0,n=0,k=0;\n"
|
||||
" for(uint i=0;i<j.stride;i++) { uint v=j.src[g*j.stride+i];\n"
|
||||
" if(v==0xffffffffu) {n=0;continue;}\n"
|
||||
" if(j.topology==1) {if(w && o+k+1<=j.capacity) j.dst[o+k]=v; k+=1;}\n"
|
||||
" else if(j.topology==6) {if(n) {if(w && o+k+2<=j.capacity) {j.dst[o+k]=b;j.dst[o+k+1]=v;} k+=2;}}\n"
|
||||
" else if(n>=2) {if(w && o+k+3<=j.capacity) {j.dst[o+k]=(n&1)?b:a;j.dst[o+k+1]=(n&1)?a:b;j.dst[o+k+2]=v;} k+=3;}\n"
|
||||
" if(j.topology==1) {if(w && geo_room(j,o,k,1)) j.dst[o+k]=v; k+=1;}\n"
|
||||
" else if(j.topology==6) {if(n) {if(w && geo_room(j,o,k,2)) {j.dst[o+k]=b;j.dst[o+k+1]=v;} k+=2;}}\n"
|
||||
" else if(n>=2) {if(w && geo_room(j,o,k,3)) {j.dst[o+k]=(n&1)?b:a;j.dst[o+k+1]=(n&1)?a:b;j.dst[o+k+2]=v;} k+=3;}\n"
|
||||
" a=b;b=v;n++;\n"
|
||||
" }\n"
|
||||
" return k;\n"
|
||||
"}\n"
|
||||
"kernel void geo_pack_count(constant geo_pack& j [[buffer(0)]], uint g [[thread_position_in_grid]]) { if(g<j.groups) j.cnt[g]=geo_group(j,g,false,0); }\n"
|
||||
"kernel void geo_pack_scan(constant geo_pack& j [[buffer(0)]]) {\n"
|
||||
" uint s=0; for(uint g=0;g<j.groups;g++) {uint c=j.cnt[g]; j.cnt[g]=s; s+=c;}\n"
|
||||
" uint w=j.topology==1?1u:j.topology==6?2u:3u, n=s<=j.capacity?s:j.capacity-j.capacity%w;\n"
|
||||
" j.args[0]=n;j.args[1]=1;j.args[2]=0;j.args[3]=0;j.args[4]=0;\n"
|
||||
"kernel void geo_pack_scan(constant geo_pack& j [[buffer(0)]],uint t[[thread_index_in_threadgroup]],uint3 tg[[threads_per_threadgroup]]) {\n"
|
||||
" threadgroup ulong sums[256]; uint nt=tg.x, chunk=j.groups/nt+uint(j.groups%nt!=0);\n"
|
||||
" uint begin=uint(min(ulong(t)*chunk,ulong(j.groups))),end=begin+min(chunk,j.groups-begin);\n"
|
||||
" ulong s=0;for(uint g=begin;g<end;g++)s+=j.cnt[g];sums[t]=s;threadgroup_barrier(mem_flags::mem_threadgroup);\n"
|
||||
" for(uint d=1;d<nt;d<<=1){ulong a=t>=d?sums[t-d]:0;threadgroup_barrier(mem_flags::mem_threadgroup);sums[t]+=a;threadgroup_barrier(mem_flags::mem_threadgroup);}\n"
|
||||
" s=t?sums[t-1]:0;for(uint g=begin;g<end;g++){uint c=j.cnt[g];j.cnt[g]=uint(min(s,ulong(0xffffffffu)));s+=c;}\n"
|
||||
" if(t==0){ulong total=sums[nt-1];uint w=j.topology==1?1u:j.topology==6?2u:3u,n=total<=j.capacity?uint(total):j.capacity-j.capacity%w;\n"
|
||||
" j.args[0]=n;j.args[1]=1;j.args[2]=0;j.args[3]=0;j.args[4]=0;}\n"
|
||||
"}\n"
|
||||
"kernel void geo_pack_write(constant geo_pack& j [[buffer(0)]], uint g [[thread_position_in_grid]]) { if(g<j.groups) geo_group(j,g,true,j.cnt[g]); }\n";
|
||||
// The job record geo_pack reads (host side): the counts / offsets buffer holds a word per group
|
||||
|
||||
+89
-26
@@ -9,6 +9,67 @@ static int geo_cmp_index(const void *a, const void *b) {
|
||||
uint32_t x = *(const uint32_t *)a, y = *(const uint32_t *)b;
|
||||
return (x > y) - (x < y);
|
||||
}
|
||||
enum { GEO_CAPTURE_VERTICES = (256u << 20) / (144 * 4) };
|
||||
// The capture span is already bounded by its scratch allocation. A bit per
|
||||
// vertex gives the same ascending unique list without sorting every reference.
|
||||
// Keep an in-place sort fallback for allocation failure or a wider caller.
|
||||
// order may be changed; a short destination is never partially written.
|
||||
static size_t geo_capture_unique(uint32_t *order, size_t count, int restart, uint32_t restart_index,
|
||||
uint32_t lo, uint64_t span, uint32_t *dst, size_t capacity) {
|
||||
if (!span || span > (uint64_t)UINT32_MAX + 1 - lo) return SIZE_MAX;
|
||||
for (size_t i = 0; i < count; i++) if (!(restart && order[i] == restart_index) &&
|
||||
(order[i] < lo || (uint64_t)order[i] - lo >= span)) return SIZE_MAX;
|
||||
size_t nw = (size_t)((span + 63) / 64), n = 0;
|
||||
uint64_t *bits = span <= GEO_CAPTURE_VERTICES ? calloc(nw, sizeof *bits) : NULL;
|
||||
if (bits) {
|
||||
for (size_t i = 0; i < count; i++) if (!(restart && order[i] == restart_index)) {
|
||||
uint32_t v = order[i] - lo; bits[v >> 6] |= 1ull << (v & 63);
|
||||
}
|
||||
for (size_t i = 0; i < nw; i++) n += (size_t)__builtin_popcountll(bits[i]);
|
||||
if (n <= capacity) for (size_t i = 0, k = 0; i < nw; i++) {
|
||||
uint64_t word = bits[i];
|
||||
while (word) { dst[k++] = lo + (uint32_t)(i * 64 + __builtin_ctzll(word)); word &= word - 1; }
|
||||
}
|
||||
free(bits);
|
||||
} else {
|
||||
size_t references = 0;
|
||||
for (size_t i = 0; i < count; i++) if (!(restart && order[i] == restart_index)) order[references++] = order[i];
|
||||
qsort(order, references, sizeof *order, geo_cmp_index);
|
||||
for (size_t i = 0; i < references; i++) if (!i || order[i] != order[i - 1]) n++;
|
||||
if (n <= capacity) for (size_t i = 0, k = 0; i < references; i++)
|
||||
if (!i || order[i] != order[i - 1]) dst[k++] = order[i];
|
||||
}
|
||||
return n <= capacity ? n : SIZE_MAX;
|
||||
}
|
||||
// Only CPU reads need a completed snapshot. Native vertex capture stays on the
|
||||
// GPU and follows earlier writes through normal encoder ordering. Unknown or
|
||||
// overflowing write sets always retain the conservative drain.
|
||||
static int geo_cpu_hazard(uint64_t lo, uint64_t n) {
|
||||
if (!n) return 0;
|
||||
if (!lo || n > UINT64_MAX - lo || g_sbw_over) return 1;
|
||||
return pend_hits(lo, n) || sbw_hits(lo, lo + n) || gw_live(lo, lo + n);
|
||||
}
|
||||
static int geo_conversion_hazard(NvShader *vs) {
|
||||
for (int v = 0; v < vs->rf.nv; v++) {
|
||||
int a = vs->rf.v[v].nvn;
|
||||
if (a >= S.nattr || !vconv_wanted(&vs->rf, v, NULL, 0)) continue;
|
||||
int st = S.attr[a].stream;
|
||||
if (st < 16 && S.vbuf[st].address && geo_cpu_hazard(S.vbuf[st].address, S.vbuf[st].size)) return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
// GS output -> counts -> offsets/indirect args -> packed indices stay in one
|
||||
// compute encoder. Each transition needs dispatch ordering and device-memory
|
||||
// visibility; full queue barriers remain at the encoder's boundaries.
|
||||
static void geo_pack_encode(id<MTL4ComputeCommandEncoder> ce, id<MTLComputePipelineState> __strong *pack, uint64_t job, uint32_t groups) {
|
||||
enc_c_args(ce, job, 0);
|
||||
for (int i = 0; i < 3; i++) {
|
||||
[ce barrierAfterEncoderStages:MTLStageDispatch beforeEncoderStages:MTLStageDispatch visibilityOptions:MTL4VisibilityOptionDevice];
|
||||
enc_c_pso(ce, pack[i]);
|
||||
NSUInteger threads = i == 1 ? MIN((NSUInteger)256, pack[i].maxTotalThreadsPerThreadgroup) : 64;
|
||||
enc_c_dispatch(ce, i == 1 ? MTLSizeMake(1, 1, 1) : MTLSizeMake((groups + 63) / 64, 1, 1), MTLSizeMake(threads, 1, 1));
|
||||
}
|
||||
}
|
||||
static id<MTLRenderPipelineState> geo_capture_pso(NvShader *vs) {
|
||||
pso_key k; static const uint32_t cf[8]; pso_key_fill(&k, vs, nil, cf, 0, 0, 1, 0); k.fsfn = GEO_MARK;
|
||||
id<MTLRenderPipelineState> ps = hm_get_id(&g_pso, &k);
|
||||
@@ -31,6 +92,13 @@ static void geo_draw(NvProg *pr, const p_draw *dw0, const p_draw_idx *di0);
|
||||
// Returns 0 when the draw cannot be split (the caller reports it)
|
||||
enum { GEO_RUN_PRIMS = 4096 }; static const uint64_t GEO_RUN_SPAN = 64ull << 20;
|
||||
static int g_geo_split_depth; // > 0 while geo_split draws its runs: they skip the GPU wait
|
||||
static int geo_sync_cpu(int *drained) {
|
||||
if (*drained) return 1;
|
||||
mdi_wait();
|
||||
if (g_mdi_ev.signaledValue < g_mdi_v) return 0;
|
||||
memset(g_vconv, 0, sizeof g_vconv); *drained = 1;
|
||||
return 1;
|
||||
}
|
||||
static int geo_split(NvProg *pr, const p_draw *dw, const p_draw_idx *di, int count, int instances, uint32_t first_instance) {
|
||||
int prim = dw ? dw->prim : di->prim, per = prim == 0 ? 1 : prim == 1 ? 2 : prim == 4 ? 3 : prim == 10 ? 4 : prim == 12 ? 6 : 0;
|
||||
if (!per || (di && S.restart.on) || count / per < 1) return 0;
|
||||
@@ -76,15 +144,13 @@ static void geo_draw(NvProg *pr, const p_draw *dw0, const p_draw_idx *di0) {
|
||||
p_draw dw = dw0 ? *dw0 : (p_draw){0}; p_draw_idx di = di0 ? *di0 : (p_draw_idx){0};
|
||||
if (di0 && (di.itype < 0 || di.itype > 2)) { MLOG("[RED] geometry index type %d is invalid", di.itype); return; }
|
||||
uint64_t ind = dw0 ? dw.ind : di.ind;
|
||||
// Indirect records and GPU-written index data need a coherent CPU snapshot
|
||||
// for primitive assembly. This is deliberately a correctness path; no such
|
||||
// wait is added to ordinary VS/FS draws.
|
||||
int wait = ind != 0 || di0 != NULL; // CPU assembly must also see writes from earlier submissions.
|
||||
for (int i = 0; i < 16; i++) if (S.vbuf[i].size && pend_hits(S.vbuf[i].address, S.vbuf[i].size)) wait = 1;
|
||||
for (int i = 0; i < vs->rf.nv; i++) if (vconv_wanted(&vs->rf, i, NULL, 0)) wait = 1;
|
||||
if (defer_has_active()) defer_fallback();
|
||||
lc_land(); rp_flush(); rp_end(); ubd_land();
|
||||
if (wait && !g_geo_split_depth) { mdi_wait(); if (g_mdi_ev.signaledValue < g_mdi_v) return; memset(g_vconv, 0, sizeof g_vconv); }
|
||||
int drained = g_geo_split_depth != 0;
|
||||
// Decode indirect arguments only after their CPU snapshot is safe. They
|
||||
// select the index range checked below; no GPU work is encoded between the
|
||||
// two checks, so a successful drain covers both and the converted streams.
|
||||
if ((geo_conversion_hazard(vs) || (ind && geo_cpu_hazard(ind, dw0 ? 16 : 20))) && !geo_sync_cpu(&drained)) return;
|
||||
if (ind) {
|
||||
uint32_t a[5] = {0}; size_t n = dw0 ? 16 : 20;
|
||||
if (!nvn_host_readable(ind, n)) { MLOG("[RED] geometry indirect arguments are not readable"); return; }
|
||||
@@ -101,6 +167,7 @@ static void geo_draw(NvProg *pr, const p_draw *dw0, const p_draw_idx *di0) {
|
||||
if (count <= 0 || instances < 0) return;
|
||||
if (!instances) instances = 1;
|
||||
if (topology < 0 || count > (1 << 22)) { MLOG("[RED] geometry primitive %d or count %d exceeds the assembly path", prim, count); return; }
|
||||
if (di0 && geo_cpu_hazard(di.ibuf, (uint64_t)count << di.itype) && !geo_sync_cpu(&drained)) return;
|
||||
NSString *key = [[NSString stringWithUTF8String:base->key] substringToIndex:16];
|
||||
NvShader *gs = shader_get([key stringByAppendingFormat:@"_bg%d", topology], 2);
|
||||
NvShader *reader = shader_get([key stringByAppendingString:@"_bgv"], 0);
|
||||
@@ -115,36 +182,36 @@ static void geo_draw(NvProg *pr, const p_draw *dw0, const p_draw_idx *di0) {
|
||||
for (int i = 0; i < 3 && lib; i++) if (!(pack[i] = [g_dev newComputePipelineStateWithFunction:[lib newFunctionWithName:@(fn[i])] error:&e])) break;
|
||||
if (!pack[2]) { pack[0] = pack[1] = nil; MLOG("[RED] geometry index compaction: %s", e.localizedDescription.UTF8String); return; } }
|
||||
|
||||
uint32_t *order = malloc((size_t)count * 4), *unique = malloc((size_t)count * 4);
|
||||
if (!order || !unique) { free(order); free(unique); MLOG("[RED] geometry index allocation failed"); return; }
|
||||
uint32_t *order = malloc((size_t)count * 4);
|
||||
if (!order) { MLOG("[RED] geometry index allocation failed"); return; }
|
||||
uint32_t lo = UINT32_MAX, hi = 0; size_t nu = 0;
|
||||
int restart = di0 && S.restart.on;
|
||||
int isz = di0 ? 1 << di.itype : 0;
|
||||
uint32_t restart_index = S.restart.index & (isz == 1 ? UINT8_MAX : isz == 2 ? UINT16_MAX : UINT32_MAX);
|
||||
if (di0 && (di.itype < 0 || di.itype > 2 || !nvn_host_readable(di.ibuf, (uint64_t)count * isz))) {
|
||||
free(order); free(unique); MLOG("[RED] geometry index buffer is not readable"); return;
|
||||
free(order); MLOG("[RED] geometry index buffer is not readable"); return;
|
||||
}
|
||||
for (int i = 0; i < count; i++) {
|
||||
uint32_t v = (uint32_t)i;
|
||||
if (di0) { v = 0; memcpy(&v, (const uint8_t *)(uintptr_t)di.ibuf + (size_t)i * isz, isz); }
|
||||
order[i] = v;
|
||||
if (restart && v == restart_index) continue;
|
||||
lo = MIN(lo, v); hi = MAX(hi, v); unique[nu++] = v;
|
||||
lo = MIN(lo, v); hi = MAX(hi, v); nu++;
|
||||
}
|
||||
if (!nu) { free(order); free(unique); return; }
|
||||
if (!nu) { free(order); return; }
|
||||
int64_t first = di0 ? (int64_t)lo + di.base_vertex : dw.first;
|
||||
uint64_t span = (uint64_t)hi - lo + 1;
|
||||
if (first < 0 || first + span > (uint64_t)UINT32_MAX + 1) { free(order); free(unique); MLOG("[RED] geometry vertex range is outside 32-bit vertex IDs"); return; }
|
||||
if (first < 0 || first + span > (uint64_t)UINT32_MAX + 1) { free(order); MLOG("[RED] geometry vertex range is outside 32-bit vertex IDs"); return; }
|
||||
// Normalize only after assembly, so a restart value cannot collide with a
|
||||
// normalized vertex number. Indexed captures use a sorted unique index list.
|
||||
size_t words = nvn_geo_assemble(prim, order, count, restart, restart_index, NULL, 0);
|
||||
int width = nvn_geo_width(topology);
|
||||
uint64_t np = words == SIZE_MAX ? 0 : words / width;
|
||||
if (!np) { free(order); free(unique); return; }
|
||||
if (!np) { free(order); return; }
|
||||
uint64_t groups = np * (uint64_t)instances * gs->geo_invocations;
|
||||
if (groups > UINT32_MAX || span * (uint64_t)instances > (256ull << 20) / (144 * 4) ||
|
||||
if (groups > UINT32_MAX || span * (uint64_t)instances > GEO_CAPTURE_VERTICES ||
|
||||
(uint64_t)first_instance + instances > (uint64_t)UINT32_MAX + 1) {
|
||||
free(order); free(unique);
|
||||
free(order);
|
||||
if (!geo_split(pr, dw0 ? &dw : NULL, dw0 ? NULL : &di, count, instances, first_instance)) MLOG("[RED] geometry draw exceeds the capture or invocation bound"); return;
|
||||
}
|
||||
uint64_t input_size = span * instances * 144 * 4;
|
||||
@@ -153,7 +220,7 @@ static void geo_draw(NvProg *pr, const p_draw *dw0, const p_draw_idx *di0) {
|
||||
uint64_t packed_size = groups * gs->geo_vertices * (gs->geo_output == 7 ? 3 : gs->geo_output == 6 ? 2 : 1) * 4;
|
||||
uint64_t total = input_size + output_size + raw_size + packed_size + groups * 4 + words * 4 + nu * 4 + 4096;
|
||||
if (groups > UINT32_MAX || total > (256ull << 20) || np > UINT32_MAX) {
|
||||
free(order); free(unique);
|
||||
free(order);
|
||||
if (!geo_split(pr, dw0 ? &dw : NULL, dw0 ? NULL : &di, count, instances, first_instance)) MLOG("[RED] geometry draw needs %llu MiB of scratch, above the 256 MiB bound", (unsigned long long)(total >> 20)); return;
|
||||
}
|
||||
id<MTLBuffer> scratch; size_t off = arena_alloc((size_t)total, &scratch);
|
||||
@@ -170,10 +237,9 @@ static void geo_draw(NvProg *pr, const p_draw *dw0, const p_draw_idx *di0) {
|
||||
if (used > total) MDIE("geometry scratch size accounting");
|
||||
nvn_geo_assemble(prim, order, count, restart, restart_index, pmap, words);
|
||||
for (size_t i = 0; i < words; i++) ((uint32_t *)pmap)[i] -= lo;
|
||||
qsort(unique, nu, 4, geo_cmp_index);
|
||||
size_t unique_count = 0;
|
||||
for (size_t i = 0; i < nu; i++) if (!i || unique[i] != unique[i - 1]) ((uint32_t *)pcapture_ix)[unique_count++] = unique[i];
|
||||
free(order); free(unique);
|
||||
size_t unique_count = di0 ? geo_capture_unique(order, count, restart, restart_index, lo, span, pcapture_ix, nu) : 0;
|
||||
free(order);
|
||||
if (unique_count == SIZE_MAX) { MLOG("[RED] geometry capture indices exceed their range or allocation"); return; }
|
||||
uint32_t vi[8] = {(uint32_t)span, (uint32_t)instances, 0, 0, (uint32_t)np, 0, 0, 0}; memcpy(pinfo, vi, 32);
|
||||
uint64_t ci[2] = {input, 0}; memcpy(pcapture_info, ci, 16);
|
||||
uint32_t cc[4] = {(uint32_t)first, (uint32_t)span, first_instance, (uint32_t)instances}; memcpy((uint8_t *)pcapture_info + 16, cc, 16);
|
||||
@@ -192,11 +258,8 @@ static void geo_draw(NvProg *pr, const p_draw *dw0, const p_draw_idx *di0) {
|
||||
g_geo_bind[0] = input; g_geo_bind[1] = output; g_geo_bind[2] = raw; g_geo_bind[3] = info; g_geo_bind[4] = map;
|
||||
id<MTL4ComputeCommandEncoder> ce = enc_c_begin(NULL);
|
||||
args_dirty_all(); encode_args(ce, gs, 2, 0); enc_c_pso(ce, gs->geo_pso);
|
||||
enc_c_dispatch(ce, MTLSizeMake((np + 31) / 32, instances, gs->geo_invocations), MTLSizeMake(32, 1, 1)); enc_c_end(ce);
|
||||
for (int i = 0; i < 3; i++) { // count per group, offsets (one thread), write per group: each waits for the one before
|
||||
ce = enc_c_begin(NULL); enc_c_pso(ce, pack[i]); enc_c_args(ce, job, 0);
|
||||
enc_c_dispatch(ce, i == 1 ? MTLSizeMake(1, 1, 1) : MTLSizeMake((groups + 63) / 64, 1, 1), MTLSizeMake(i == 1 ? 1 : 64, 1, 1)); enc_c_end(ce);
|
||||
}
|
||||
enc_c_dispatch(ce, MTLSizeMake((np + 31) / 32, instances, gs->geo_invocations), MTLSizeMake(32, 1, 1));
|
||||
geo_pack_encode(ce, pack, job, (uint32_t)groups); enc_c_end(ce);
|
||||
args_dirty_all(); g_enc_pso = nil; g_enc_dss = nil; g_ed.ok = 0;
|
||||
swrite_note(pr); udc_note_draw(pr); g_wr_epoch++; g_mdx_epoch++;
|
||||
if (S.rast_discard) return;
|
||||
|
||||
@@ -25,16 +25,18 @@
|
||||
#include "nvn_refl.h"
|
||||
#include "nvn_cover.h"
|
||||
#include "nvn_primitive.h"
|
||||
#include "nvn_timestamp.h"
|
||||
#include "dmsh_chain.h" // DMSH_CHAIN: the translation chain version of the B shader library expected by this source tree, one for every game (beside this file, tools/dmsh_chain.py --header)
|
||||
#include "game_profile.h" // game profile constants (profile id, the profile's switches)
|
||||
// Texture slot table per stage: 0-127 the combined handles (nvnCommandBufferBindTexture), 128-255 the separate texture binds (NVN_SEPTEX_SLOT0, nvn_obj.h)
|
||||
#define NTEX 256
|
||||
// The NVN driver's constant segments, one layout in every game (dm/gfx/tools/dmsh_build.py), byte offsets: c2 holds the combined handles at 0x20 + 8 r (41 slots up to the separate table:
|
||||
// past slot 31 they lie in the image table, 0x120 + 8 r, 8 slots), the separate textures at 0x168 + 8 r and the separate samplers at 0x568 + 8 r (128 each);
|
||||
// c0 the storage buffer table at base + 0x10 r (address 64 bits, size 32 bits), base vertex 0x110, compute 0x310, pixel 0x510. The replay fills one DRV_SIZE buffer per segment a shader reads
|
||||
// c0 the storage buffer table at base + 0x10 r (address 64 bits, size 32 bits), base vertex 0x110, compute 0x310, geometry 0x410, pixel 0x510. The replay fills one DRV_SIZE buffer per segment a shader reads
|
||||
enum { C2_TEX = 0x20, C2_TEX_SLOTS = 41, C2_IMG = 0x120, C2_IMG_SLOTS = 8, C2_SEPTEX = 0x168, C2_SAMP = 0x568, DRV_SIZE = 0xA00 };
|
||||
_Static_assert(C2_TEX + 8 * C2_TEX_SLOTS == C2_SEPTEX && C2_SEPTEX + 8 * 128 == C2_SAMP && C2_SAMP + 8 * 128 <= DRV_SIZE && NVN_SEPTEX_SLOT0 + 128 == NTEX, "NVN driver handle tables");
|
||||
static int c0_ssbo_base(int stage) { return stage == 0 ? 0x110 : stage == 1 ? 0x510 : stage == 5 ? 0x310 : -1; } // NVN stages 0 vertex, 1 pixel, 5 compute; geometry / hull / domain never seen
|
||||
// Geometry's counter/output addresses are c0+0x410/0x430 (NieR:Automata's MOVC/IADDC pairs); they use the logical NVN stage even when Metal executes a compute kernel.
|
||||
static int c0_ssbo_base(int stage) { return stage == 0 ? 0x110 : stage == 1 ? 0x510 : stage == 2 ? 0x410 : stage == 5 ? 0x310 : -1; } // NVN stages 0 vertex, 1 pixel, 2 geometry, 5 compute; hull / domain never seen
|
||||
// The handle a texture binding of slot reg reads: as c2 holds it (encode_args fills c2 the same way), a combined slot past 31 shares its word with an image slot, and a bound image
|
||||
// is what lies there. A texture instruction on an image handle names such a slot: a size query of the image a compute shader writes (Unreal's GetDimensions on a RWTexture3D,
|
||||
// dmsh_build.py decode_tex). DRAGON QUEST VII Reimagined's volumetric lightmap indirection patch read the empty texture slot 32 there, got a 1x1 size and wrote only cell (0, 0, 0)
|
||||
@@ -1129,10 +1131,10 @@ void mtl_sub_event(volatile uint32_t *val, uint32_t mode, uint32_t v) { post((po
|
||||
void mtl_sub_counter(uint64_t addr, uint32_t type) { sbw_note(addr, 16, SBW_REPORT); post((post_op){2, NULL, 0, 0, addr, type, NULL, g_seg}); }
|
||||
void mtl_counter_stats(uint64_t rep[32], uint64_t rst[32]) { memcpy(rep, g_cnt_report, sizeof g_cnt_report); memcpy(rst, g_cnt_reset, sizeof g_cnt_reset); }
|
||||
|
||||
// Counter timestamps (19.2 MHz) are taken from the guest clock (hle_os.c guest_ns, the same source as svc GetSystemTick / cntpct): on hardware GPU timestamps and the CPU counter share one timebase, and games compare them.
|
||||
// Counter timestamps (614.4 MHz) are taken from the guest clock (hle_os.c guest_ns, the same epoch as svc GetSystemTick / cntpct, whose ticks are 19.2 MHz).
|
||||
// They used to come from CLOCK_MONOTONIC, which keeps running while the Mac sleeps while the guest clock (mach_absolute_time) does not, so the two differed by the sleep time; once timestamps were converted to ns, Mario halved its frame rate. In graphics unit tests guest_ns is a weak definition returning 0; fall back to the monotonic clock
|
||||
uint64_t guest_ns(void);
|
||||
static uint64_t gpu_ticks(void) { uint64_t g = guest_ns(); if (!g) { struct timespec t; clock_gettime(CLOCK_MONOTONIC, &t); g = (uint64_t)t.tv_sec * 1000000000ull + t.tv_nsec; } return g * 12 / 625; }
|
||||
static uint64_t gpu_ticks(void) { uint64_t g = guest_ns(); if (!g) { struct timespec t; clock_gettime(CLOCK_MONOTONIC, &t); g = (uint64_t)t.tv_sec * 1000000000ull + t.tv_nsec; } return nvn_timestamp_from_ns(g); }
|
||||
// Counter timestamps by segment (profile gpu_timestamps segment; DM_NVN_GPU_TS=segment / submission overrides it). On hardware a timestamp report is written when the GPU reaches it, so two reports of one submission bracket the GPU work between them.
|
||||
// The host writes all reports of a submission in its completion handler; with one time for all of them a game that measures its GPU time that way reads 0 (Breath of the Wild: frame-interval controller and dynamic resolution).
|
||||
// In segment mode a report takes the GPU time of the segment it was encoded in (sub_cut): TIMESTAMP_TOP (0x10) that segment's GPU start, other types its GPU end. The writes stay in the last segment's handler, before the fence,
|
||||
@@ -1147,11 +1149,11 @@ static uint64_t gpu_s_guest_ns(double s) { // a feedback GPU time (seconds on
|
||||
if (s <= 0 || !g || at > now || now - at > g) return 0;
|
||||
return g - (now - at);
|
||||
}
|
||||
static uint64_t rep_ticks(const post_op *o, seg_clk *sc, uint32_t last, uint64_t c0, uint64_t c1) { // the time a counter report records (19.2 MHz); c0 / c1: the last segment's GPU start / end on the guest clock
|
||||
static uint64_t rep_ticks(const post_op *o, seg_clk *sc, uint32_t last, uint64_t c0, uint64_t c1) { // the time a counter report records (614.4 MHz); c0 / c1: the last segment's GPU start / end on the guest clock
|
||||
int top = o->type == 0x10; uint64_t ns = 0;
|
||||
if (sc && o->seg < last && o->seg < SEG_CLK_N) ns = atomic_load(&sc->t[o->seg][!top]);
|
||||
if (!ns) ns = top ? c0 : c1;
|
||||
return ns ? ns * 12 / 625 : gpu_ticks();
|
||||
return ns ? nvn_timestamp_from_ns(ns) : gpu_ticks();
|
||||
}
|
||||
|
||||
// ---------- Boot instrumentation (DM_BOOTPROF=1): metallib loading, pipeline creation (both happen synchronously during replay on the submit thread), texture upload, first-frame present ----------
|
||||
@@ -6741,7 +6743,7 @@ static void fb_prepare(NvProg *pr) {
|
||||
if (g_fb_rebind) { args_dirty_all(); g_fb_rebind = 0; } // the previous draw had a substituted binding: re-encode with the original bindings this time
|
||||
if (!pr || !pr->sh[1] || !R.rt.n || g_fz.active || g_defer_replaying || !fb_want(pr->sh[1]->key)) return;
|
||||
NvShader *fs = pr->sh[1];
|
||||
for (int i = 0; i < fs->rf.nb && g_fb_n < 4; i++) { const nvn_rbind *b = &fs->rf.b[i]; if (b->kind != NVN_RB_TEX || b->reg >= 128) continue;
|
||||
for (int i = 0; i < fs->rf.nb && g_fb_n < 4; i++) { const nvn_rbind *b = &fs->rf.b[i]; if (b->kind != NVN_RB_TEX || b->reg >= NTEX) continue;
|
||||
int tid = (int)(tex_slot_h(S.tex[1], S.img[1], b->reg) & 0xfffff); if (!tid) continue;
|
||||
os_unfair_lock_lock(&g_rmu); uint64_t ser = tid < g_ntreg && g_treg[tid].ok ? g_treg[tid].t.serial : 0; os_unfair_lock_unlock(&g_rmu);
|
||||
if (!ser) continue;
|
||||
|
||||
@@ -27,7 +27,7 @@ static int arr_len(NSString *ty, NSString **el) {
|
||||
return [[ty substringWithRange:NSMakeRange(NSMaxRange(c), ty.length - 1 - NSMaxRange(c))] intValue];
|
||||
}
|
||||
|
||||
// Whether a storage buffer binding may be written: route A's reflection says so ("rw"); route B's does not, and there SPIRV-Cross types a buffer the shader never writes as const device
|
||||
// Whether a storage buffer binding may be written: current B reflection carries the translator's write flag ("rw"); old samples without it fall back to SPIRV-Cross's const device qualifier.
|
||||
static int sbuf_rw(NSDictionary *b) { id rw = b[@"rw"]; if (rw) return [rw boolValue]; id ty = b[@"msl_type"]; return !([ty isKindOfClass:[NSString class]] && [ty hasPrefix:@"const "]); }
|
||||
int nvn_refl_from_json(NSDictionary *j, nvn_refl *o, char *err, int errlen) {
|
||||
memset(o, 0, sizeof *o);
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
// NVN counter timestamps are 614.4 MHz ticks (384 ticks per 625 ns), not the CPU's 19.2 MHz system counter.
|
||||
// Keep the guest clock's epoch in both directions. Wide products avoid overflow on long host uptimes.
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
static inline uint64_t nvn_timestamp_from_ns(uint64_t ns) { return (uint64_t)((__uint128_t)ns * 384 / 625); }
|
||||
static inline uint64_t nvn_timestamp_to_ns(uint64_t ticks) { return (uint64_t)((__uint128_t)ticks * 625 / 384); }
|
||||
@@ -9,6 +9,8 @@ t_deswz_gpu
|
||||
t_deswz_gpu.dSYM/
|
||||
t_builtin.dSYM/
|
||||
t_pace
|
||||
t_timestamp
|
||||
t_timestamp.dSYM/
|
||||
t_fstep
|
||||
.precommit.err
|
||||
.precommit_snap/
|
||||
@@ -52,6 +54,8 @@ t_vbuf
|
||||
t_vbuf.dSYM/
|
||||
t_geometry
|
||||
t_geometry.dSYM/
|
||||
t_feedback
|
||||
t_feedback.dSYM/
|
||||
t_dirty_race
|
||||
t_dirty_race.dSYM/
|
||||
t_vin
|
||||
|
||||
+10
-1
@@ -53,6 +53,8 @@ t_cover: t_cover.c ../nvn/nvn_cover.h
|
||||
clang -O1 -Wall -o $@ t_cover.c
|
||||
t_pace: t_pace.c ../nvn/nvn_pace.h
|
||||
clang -O1 -Wall -o $@ t_pace.c
|
||||
t_timestamp: t_timestamp.c ../nvn/nvn_timestamp.h
|
||||
$(CC) -std=c11 -O2 -g -Wall -Wextra -Werror -o $@ $<
|
||||
t_fstep: t_fstep.c ../nvn/nvn_fstep.h
|
||||
clang -O1 -Wall -o $@ t_fstep.c
|
||||
t_fuse_check: t_fuse_check.m $(MTL_T_DEP)
|
||||
@@ -94,6 +96,12 @@ t_vbuf: t_vbuf.m $(MTL_T_DEP)
|
||||
clang $(CFLAGS) -fobjc-arc -o $@ t_vbuf.m $(MTL_T_SRC) $(FW)
|
||||
t_geometry: t_geometry.m $(MTL_T_DEP)
|
||||
clang $(CFLAGS) -fobjc-arc -o $@ t_geometry.m $(MTL_T_SRC) $(FW)
|
||||
t_feedback: t_feedback.m $(MTL_T_DEP)
|
||||
clang $(CFLAGS) -fobjc-arc -o $@ t_feedback.m $(MTL_T_SRC) $(FW)
|
||||
.PHONY: check_t_feedback
|
||||
check_t_feedback: t_feedback
|
||||
MTL_DEBUG_LAYER=1 ./t_feedback
|
||||
run: check_t_feedback
|
||||
t_mip_extent: t_mip_extent.m ../nvn/hle_nvn.c ../../host/crash.c ../../host/hle_bigstack.c t_host_stubs.c $(GFX) $(GFX_H)
|
||||
clang $(CFLAGS) -fobjc-arc -o $@ t_mip_extent.m ../../host/crash.c ../../host/hle_bigstack.c t_host_stubs.c $(filter-out ../nvn/nvn_mtl.m,$(GFX)) $(FW)
|
||||
t_rt_range_shape: t_rt_range_shape.m $(MTL_T_DEP)
|
||||
@@ -157,7 +165,7 @@ t_stencil_view: t_stencil_view.m $(MTL_T_DEP)
|
||||
# The Vulkan layer (#included) over the whole NVN layer, whose device and present path it uses
|
||||
t_vk_desc: t_vk_desc.m ../vk/hle_vk.m $(MTL_T_DEP)
|
||||
clang $(CFLAGS) -I../../third_party/vulkan-headers/include -fobjc-arc -o $@ t_vk_desc.m $(MTL_T_SRC) ../nvn/nvn_mtl.m $(FW)
|
||||
run: t_nvn t_dirty_slots t_dirty_race t_builtin t_vin t_tbuf2d t_deswz_gpu t_pace t_fstep t_refl t_hmap t_cover t_fuse_check t_present_crop t_reorder_chain t_defer_chain t_zskip t_xv t_ub t_vbuf t_geometry t_mip_extent t_rt_range_shape t_rt_range_ro t_rt_range t_rt_depth_ro t_pso_skey t_pso_archive t_pso_pending t_pfv t_view_levels t_view_swizzle t_vk_desc t_integer_blend t_primitive_restart t_clear_ds t_depth16_clear t_upgrade_alias t_stencil_view
|
||||
run: t_nvn t_dirty_slots t_dirty_race t_builtin t_vin t_tbuf2d t_deswz_gpu t_pace t_timestamp t_fstep t_refl t_hmap t_cover t_fuse_check t_present_crop t_reorder_chain t_defer_chain t_zskip t_xv t_ub t_vbuf t_geometry t_mip_extent t_rt_range_shape t_rt_range_ro t_rt_range t_rt_depth_ro t_pso_skey t_pso_archive t_pso_pending t_pfv t_view_levels t_view_swizzle t_vk_desc t_integer_blend t_primitive_restart t_clear_ds t_depth16_clear t_upgrade_alias t_stencil_view
|
||||
./t_nvn
|
||||
./t_dirty_slots
|
||||
./t_dirty_race
|
||||
@@ -166,6 +174,7 @@ run: t_nvn t_dirty_slots t_dirty_race t_builtin t_vin t_tbuf2d t_deswz_gpu t_pac
|
||||
./t_tbuf2d
|
||||
./t_deswz_gpu
|
||||
./t_pace
|
||||
./t_timestamp
|
||||
./t_fstep
|
||||
./t_refl
|
||||
./t_hmap
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
// Feedback snapshots and their per-draw argument substitution include separate texture slots.
|
||||
#include "../nvn/nvn_mtl.m"
|
||||
void *front_metal_layer(void) { return NULL; }
|
||||
module_t *module_of(const void *p) { (void)p; return NULL; }
|
||||
module_t g_mod[MAX_MOD]; int g_nmod;
|
||||
void svc_thread_dump(void) {}
|
||||
uint64_t now_ns(void) { return bp_now(); }
|
||||
static int checks, failed;
|
||||
#define CHECK(c, label) do { checks++; if (!(c)) { failed++; fprintf(stderr, "FAIL: %s\n", label); } } while (0)
|
||||
|
||||
static id<MTLTexture> target(tex_t *t, uint64_t serial) {
|
||||
*t = (tex_t){.magic=MAGIC('T','E','X',0), .serial=serial};
|
||||
t->d = (nvn_texdesc){.target=NVN_TEXTURE_TARGET_2D, .format=NVN_FORMAT_RGBA8,
|
||||
.width=4, .height=4, .depth=1, .levels=1, .samples=1};
|
||||
MTLTextureDescriptor *d = tex_desc(t, 0); d.storageMode = MTLStorageModeShared;
|
||||
id<MTLTexture> texture = [g_dev newTextureWithDescriptor:d];
|
||||
CHECK(texture != nil, "render target created");
|
||||
res_add(texture); mtl_tex_init(t); serial_put(serial, texture);
|
||||
return texture;
|
||||
}
|
||||
static void clear(MTLClearColor color) {
|
||||
R.clear_c[0] = 1; R.cc[0] = color;
|
||||
CHECK(rp_begin() != nil, "production render pass opens");
|
||||
}
|
||||
static void sample(NvShader *fs, id<MTLRenderPipelineState> pipeline) {
|
||||
clear(MTLClearColorMake(0, 0, 0, 1));
|
||||
enc_r_pso(g_enc, pipeline);
|
||||
enc_r_viewport(g_enc, (MTLViewport){0, 0, 4, 4, 0, 1});
|
||||
CHECK(encode_args((id<MTLCommandEncoder>)g_enc, fs, 1, 0), "production fragment arguments encoded");
|
||||
enc_r_draw(g_enc, MTLPrimitiveTypeTriangle, 0, 3);
|
||||
rp_end();
|
||||
}
|
||||
static void readback(id<MTLTexture> t, id<MTLBuffer> b, unsigned offset) {
|
||||
enc_b_copy_texture_buffer(blit(), t, 0, 0, MTLOriginMake(0, 0, 0), MTLSizeMake(4, 4, 1), b, offset, 256, 1024);
|
||||
}
|
||||
static void pixels(id<MTLBuffer> b, unsigned offset, const uint8_t want[4], const char *label) {
|
||||
int valid = 1;
|
||||
for (int y = 0; y < 4; y++) for (int x = 0; x < 4; x++)
|
||||
valid &= !memcmp((const uint8_t *)b.contents + offset + y * 256 + x * 4, want, 4);
|
||||
CHECK(valid, label);
|
||||
}
|
||||
static void slot_case(NvProg *pr, id<MTLRenderPipelineState> pipeline, int slot, int index) {
|
||||
int before = failed, tid = 600 + index;
|
||||
NvShader *fs = pr->sh[1]; fs->rf.b[0].reg = slot;
|
||||
tex_t source, output;
|
||||
id<MTLTexture> original = target(&source, 99700 + index * 2);
|
||||
id<MTLTexture> destination = target(&output, 99701 + index * 2);
|
||||
mtl_reg_tex(tid, &source, NULL);
|
||||
id<MTLBuffer> result = [g_dev newBufferWithLength:2048 options:MTLResourceStorageModeShared]; res_add(result);
|
||||
state_reset(); memset(&R, 0, sizeof R); mtl_sub_begin();
|
||||
R.has_rt = 1; R.rt.n = 1; R.rt.color[0] = &source; S.tex[1][slot] = tid;
|
||||
clear(MTLClearColorMake(1, 0, 0, 1));
|
||||
fb_prepare(pr);
|
||||
CHECK(!g_enc, "snapshot closes the preceding render pass");
|
||||
CHECK(g_fb_n == 1, "feedback attachment receives a snapshot");
|
||||
CHECK(g_fb_n == 1 && g_fb_src[0] == original && g_fb_use[0] != original,
|
||||
"snapshot substitutes a distinct texture for the registered source");
|
||||
rp_end();
|
||||
// Overwrite the attachment after the snapshot, then render the sampled value
|
||||
// into a distinct target. This makes a missing snapshot fail deterministically
|
||||
// even on GPUs that happen to tolerate sampling an attached render target.
|
||||
clear(MTLClearColorMake(0, 1, 0, 1)); rp_end();
|
||||
R.rt.color[0] = &output;
|
||||
sample(fs, pipeline);
|
||||
uint64_t bound = *(uint64_t *)((uint8_t *)fs->ab_buf.contents + fs->ab_off);
|
||||
CHECK(g_fb_n == 1 && bound == g_fb_rid[0] && bound != original.gpuResourceID._impl,
|
||||
"production argument buffer contains the snapshot resource ID");
|
||||
readback(destination, result, 0);
|
||||
// With a different attachment the following draw restores the original binding.
|
||||
fb_prepare(pr);
|
||||
CHECK(g_fb_n == 0, "following draw needs no snapshot");
|
||||
sample(fs, pipeline);
|
||||
bound = *(uint64_t *)((uint8_t *)fs->ab_buf.contents + fs->ab_off);
|
||||
CHECK(bound == original.gpuResourceID._impl, "following draw restores the original resource ID");
|
||||
readback(destination, result, 1024);
|
||||
CHECK(mtl_wait(mtl_sub_commit(), 5000000000ull), "GPU submission completed");
|
||||
CHECK(!mtl_last_commit_error(), "GPU submission has no error");
|
||||
pixels(result, 0, (const uint8_t[]){255, 0, 0, 255}, "first draw reads the red pre-overwrite snapshot");
|
||||
pixels(result, 1024, (const uint8_t[]){0, 255, 0, 255}, "following draw reads the green original attachment");
|
||||
printf("feedback slot %d: %s\n", slot, before == failed ? "PASS" : "FAIL");
|
||||
mtl_tex_release(&source); mtl_tex_release(&output);
|
||||
}
|
||||
int main(void) { @autoreleasepool {
|
||||
setenv("DM_NVN_FB_SNAP", "0123456789abcdef", 1);
|
||||
setenv("DM_NVN_TBDR", "0", 1);
|
||||
mtl_init(); NSError *error = nil;
|
||||
id<MTLLibrary> lib = [g_dev newLibraryWithSource:@"#include <metal_stdlib>\nusing namespace metal;\n"
|
||||
"vertex float4 v(uint i[[vertex_id]]) { return float4(i == 1 ? 3.0 : -1.0, i == 2 ? 3.0 : -1.0, 0, 1); }\n"
|
||||
"struct A {texture2d<float, access::read> source[[id(0)]];};\n"
|
||||
"fragment float4 f(float4 p[[position]], constant A&a[[buffer(0)]]) {return a.source.read(uint2(p.xy));}\n"
|
||||
options:nil error:&error];
|
||||
CHECK(lib != nil, "synthetic shader compiles");
|
||||
if (!lib) { fprintf(stderr, "%s\n", error.localizedDescription.UTF8String); return 1; }
|
||||
NvProg *pr = [NvProg new]; NvShader *fs = [NvShader new]; pr->sh[1] = fs;
|
||||
fs->stage = 1; strcpy(fs->key, "0123456789abcdef"); fs->fn = [lib newFunctionWithName:@"f"];
|
||||
fs->ae = [fs->fn newArgumentEncoderWithBufferIndex:0]; fs->arg_len = fs->ae.encodedLength;
|
||||
fs->rf.nb = 1; fs->rf.b[0] = (nvn_rbind){.kind=NVN_RB_TEX, .aid=0, .dtt=MTLTextureType2D};
|
||||
MTLRenderPipelineDescriptor *d = [MTLRenderPipelineDescriptor new];
|
||||
d.vertexFunction = [lib newFunctionWithName:@"v"]; d.fragmentFunction = fs->fn;
|
||||
d.colorAttachments[0].pixelFormat = MTLPixelFormatRGBA8Unorm;
|
||||
id<MTLRenderPipelineState> pipeline = [g_dev newRenderPipelineStateWithDescriptor:d error:&error];
|
||||
CHECK(pipeline != nil, "synthetic render pipeline compiles");
|
||||
if (!pipeline) { fprintf(stderr, "%s\n", error.localizedDescription.UTF8String); return 1; }
|
||||
const int slots[] = {0, 128, 255};
|
||||
for (int i = 0; i < 3; i++) slot_case(pr, pipeline, slots[i], i);
|
||||
printf("feedback snapshot: %d checks, %d failed\n", checks, failed);
|
||||
return failed != 0;
|
||||
} }
|
||||
+316
-14
@@ -35,6 +35,67 @@ static void assembly(void) {
|
||||
EXPECT("triangle adjacency",6,nvn_geo_assemble(12,a,8,0,0,out,32));
|
||||
EXPECT("unsupported",SIZE_MAX,nvn_geo_assemble(99,a,8,0,0,NULL,0));
|
||||
}
|
||||
static void capture_indices(void) {
|
||||
uint32_t order[]={229,105,UINT32_MAX,101,164,105,102,229},want[]={101,102,105,164,229},out[8];
|
||||
memset(out,0xcc,sizeof out);
|
||||
EXPECT("sparse duplicate capture count",5,geo_capture_unique(order,8,1,UINT32_MAX,100,130,out,8));
|
||||
EXPECT("ascending capture order",0,memcmp(out,want,sizeof want));
|
||||
EXPECT("capture output canary",0xcccccccc,out[5]);
|
||||
memset(out,0xcc,sizeof out);
|
||||
EXPECT("short capture destination rejected",SIZE_MAX,geo_capture_unique(order,8,1,UINT32_MAX,100,130,out,4));
|
||||
for(int i=0;i<8;i++)EXPECT("short capture destination untouched",0xcccccccc,out[i]);
|
||||
uint32_t wide[]={UINT32_MAX,0,5,UINT32_MAX},wide_want[]={0,5,UINT32_MAX};
|
||||
EXPECT("wide-span sorted fallback",3,geo_capture_unique(wide,4,0,0,0,(uint64_t)UINT32_MAX+1,out,8));
|
||||
EXPECT("fallback capture order",0,memcmp(out,wide_want,sizeof wide_want));
|
||||
uint32_t restart[]={17,17};memset(out,0xcc,sizeof out);
|
||||
EXPECT("restart-only capture",0,geo_capture_unique(restart,2,1,17,0,1,out,8));
|
||||
EXPECT("restart-only output canary",0xcccccccc,out[0]);
|
||||
uint32_t invalid[]={9,11};
|
||||
EXPECT("capture below declared span rejected",SIZE_MAX,geo_capture_unique(invalid,2,0,0,10,2,out,8));
|
||||
EXPECT("capture above declared span rejected",SIZE_MAX,geo_capture_unique(invalid,2,0,0,9,2,out,8));
|
||||
EXPECT("capture address overflow rejected",SIZE_MAX,geo_capture_unique(invalid,2,0,0,UINT32_MAX,2,out,8));
|
||||
EXPECT("invalid capture output canary",0xcccccccc,out[0]);
|
||||
}
|
||||
static void cpu_read_proofs(void) {
|
||||
// Independent hazards from each production tracker, including its unknown
|
||||
// cases. Fake addresses are queried only; no CPU/GPU memory is dereferenced.
|
||||
const uint64_t address=0x40000000;pend_reset();memset(g_gw,0,sizeof g_gw);g_gw_all=0;state_reset();
|
||||
EXPECT("clean CPU range",0,geo_cpu_hazard(address,64));
|
||||
for(int kind=1;kind<=3;kind++) {
|
||||
pend_reset();pend_add(address+16,16,kind);
|
||||
EXPECT("queued update copy or fill overlap",1,geo_cpu_hazard(address,64));
|
||||
EXPECT("unrelated queued write",0,geo_cpu_hazard(address+4096,64));
|
||||
}
|
||||
pend_reset();sbw_note(address,64,SBW_GPU);
|
||||
EXPECT("current shader write overlap",1,geo_cpu_hazard(address+32,4));
|
||||
EXPECT("unrelated current shader write",0,geo_cpu_hazard(address+4096,64));
|
||||
pend_reset();sbw_note(address,16,SBW_REPORT);
|
||||
EXPECT("deferred CPU counter report is not current GPU data",0,geo_cpu_hazard(address,64));
|
||||
pend_reset();g_pend_over=1;EXPECT("unknown pending writes",1,geo_cpu_hazard(address,64));
|
||||
pend_reset();g_sbw_over=1;EXPECT("unknown storage writes",1,geo_cpu_hazard(address,64));
|
||||
pend_reset();gw_put(address,address+64,g_done+1,g_done);
|
||||
EXPECT("previous submission live write",1,geo_cpu_hazard(address,64));
|
||||
EXPECT("unrelated previous live write",0,geo_cpu_hazard(address+4096,64));
|
||||
memset(g_gw,0,sizeof g_gw);gw_put(address,address+64,g_done,g_done);
|
||||
EXPECT("completed previous write",0,geo_cpu_hazard(address,64));
|
||||
g_gw_all=g_done+1;EXPECT("previous write overflow",1,geo_cpu_hazard(address,64));g_gw_all=0;
|
||||
EXPECT("CPU range overflow",1,geo_cpu_hazard(UINT64_MAX-3,8));
|
||||
EXPECT("empty CPU range",0,geo_cpu_hazard(0,0));
|
||||
NvShader *vs=[NvShader new];vs->rf.nv=1;vs->rf.v[0].nvn=0;vs->rf.v[0].ct=NVN_CT_FLOAT;
|
||||
S.nattr=1;S.attr[0].stream=0;S.attr[0].fmt=0x0a;S.vbuf[0]=(NVNbufferRange){address,64};
|
||||
pend_add(address,64,2);
|
||||
EXPECT("GPU-only native vertex stream does not need CPU snapshot",0,geo_conversion_hazard(vs));
|
||||
S.attr[0].fmt=0x51;
|
||||
EXPECT("converted vertex stream waits for queued write",1,geo_conversion_hazard(vs));
|
||||
pend_reset();EXPECT("clean converted stream",0,geo_conversion_hazard(vs));
|
||||
sbw_note(address,64,SBW_GPU);EXPECT("converted stream current GPU write",1,geo_conversion_hazard(vs));
|
||||
pend_reset();gw_put(address,address+64,g_done+1,g_done);
|
||||
EXPECT("converted stream prior GPU write",1,geo_conversion_hazard(vs));
|
||||
memset(g_gw,0,sizeof g_gw);S.attr[0].stream=1;S.vbuf[1]=(NVNbufferRange){address+4096,64};pend_add(address,64,2);
|
||||
EXPECT("conversion checks its actual stream",0,geo_conversion_hazard(vs));
|
||||
pend_reset();g_sbw_over=1;EXPECT("converted stream unknown GPU write",1,geo_conversion_hazard(vs));
|
||||
pend_reset();memset(g_gw,0,sizeof g_gw);state_reset();
|
||||
}
|
||||
static void pack_test(void) {
|
||||
id<MTLLibrary> l=library(@(k_nvn_geo_pack_msl)); NSError *e=nil;
|
||||
id<MTLComputePipelineState> p[3]; const char *fn[3]={"geo_pack_count","geo_pack_scan","geo_pack_write"};
|
||||
@@ -47,8 +108,7 @@ static void pack_test(void) {
|
||||
nvn_geo_pack_job j={b.gpuAddress,b.gpuAddress+512,b.gpuAddress+1024,3,8,t==0?7:t==1?6:1,100,b.gpuAddress+3072};
|
||||
memcpy((char*)b.contents+2048,&j,sizeof j);
|
||||
mtl_sub_begin();
|
||||
for(int i=0;i<3;i++) { id<MTL4ComputeCommandEncoder> en=enc_c_begin(NULL); enc_c_pso(en,p[i]);enc_c_args(en,b.gpuAddress+2048,0);
|
||||
enc_c_dispatch(en,MTLSizeMake(1,1,1),MTLSizeMake(i==1?1:64,1,1));enc_c_end(en); }
|
||||
id<MTL4ComputeCommandEncoder> en=enc_c_begin(NULL);geo_pack_encode(en,p,b.gpuAddress+2048,3);enc_c_end(en);
|
||||
finish();
|
||||
uint32_t *args=(uint32_t*)((char*)b.contents+1024);
|
||||
EXPECT("compacted index count",t==0?15:t==1?18:13,args[0]);
|
||||
@@ -57,13 +117,206 @@ static void pack_test(void) {
|
||||
EXPECT("output bound sentinel",0xcccccccc,((uint32_t*)((char*)b.contents+512))[args[0]]);
|
||||
}
|
||||
}
|
||||
static void pack_dependency_test(uint32_t groups) {
|
||||
// A GPU producer and all three production compaction dispatches share one
|
||||
// encoder. Compare every output and offset with an independent CPU list.
|
||||
NSString *source=[@(k_nvn_geo_pack_msl) stringByAppendingString:@"\nstruct E{device uint*raw;uint groups;};\n"
|
||||
"kernel void produce(constant E&e[[buffer(0)]],uint g[[thread_position_in_grid]]){if(g>=e.groups)return;"
|
||||
"for(uint i=0;i<8;i++)e.raw[g*8+i]=(g%5&&i<4)?g*4+i:0xffffffffu;}\n"];
|
||||
id<MTLLibrary> lib=library(source);NSError *error=nil;id<MTLComputePipelineState> pack[3];
|
||||
const char *names[]={"geo_pack_count","geo_pack_scan","geo_pack_write"};
|
||||
for(int i=0;i<3;i++){pack[i]=[g_dev newComputePipelineStateWithFunction:[lib newFunctionWithName:@(names[i])] error:&error];if(!pack[i])abort();}
|
||||
id<MTLComputePipelineState> producer=[g_dev newComputePipelineStateWithFunction:[lib newFunctionWithName:@"produce"] error:&error];if(!producer)abort();
|
||||
size_t raw_bytes=(size_t)groups*32,packed_off=(raw_bytes+259)&~255ull,packed_bytes=(size_t)groups*24;
|
||||
size_t count_off=(packed_off+packed_bytes+259)&~255ull,args_off=(count_off+(size_t)groups*4+259)&~255ull,job_off=args_off+256,emit_off=job_off+256;
|
||||
id<MTLBuffer> b=[g_dev newBufferWithLength:emit_off+256 options:MTLResourceStorageModeShared];res_add(b);
|
||||
const uint32_t topology[]={1,6,7},width[]={1,2,3},per[]={4,6,6},order[3][6]={{0,1,2,3},{0,1,1,2,2,3},{0,1,2,2,1,3}};
|
||||
uint32_t *want=malloc(packed_bytes?packed_bytes:4),*offsets=malloc(groups?(size_t)groups*4:4);if(!want||!offsets)abort();
|
||||
for(int t=0;t<3;t++) {
|
||||
uint32_t n=0;for(uint32_t g=0;g<groups;g++){offsets[g]=n;if(g%5)for(uint32_t k=0;k<per[t];k++)want[n++]=g*4+order[t][k];}
|
||||
uint32_t caps[]={0,1,2,3,5,6,n?n-1:0,n};int first=groups>257?7:0;
|
||||
for(int c=first;c<8;c++) {
|
||||
uint32_t capacity=caps[c],written=n<=capacity?n:capacity-capacity%width[t];
|
||||
memset(b.contents,0xcc,b.length);
|
||||
nvn_geo_pack_job job={b.gpuAddress,b.gpuAddress+packed_off,b.gpuAddress+args_off,groups,8,topology[t],capacity,b.gpuAddress+count_off};
|
||||
memcpy((char*)b.contents+job_off,&job,sizeof job);uint64_t emit[]={b.gpuAddress,groups};memcpy((char*)b.contents+emit_off,emit,sizeof emit);
|
||||
mtl_sub_begin();id<MTL4ComputeCommandEncoder> ce=enc_c_begin(NULL);enc_c_pso(ce,producer);enc_c_args(ce,b.gpuAddress+emit_off,0);
|
||||
enc_c_dispatch(ce,MTLSizeMake((groups+63)/64,1,1),MTLSizeMake(64,1,1));
|
||||
geo_pack_encode(ce,pack,b.gpuAddress+job_off,groups);enc_c_end(ce);finish();
|
||||
uint32_t *raw=b.contents,*packed=(uint32_t*)((char*)b.contents+packed_off),*counts=(uint32_t*)((char*)b.contents+count_off),*args=(uint32_t*)((char*)b.contents+args_off);
|
||||
EXPECT("parallel compaction count",written,args[0]);EXPECT("parallel compaction instance count",1,args[1]);
|
||||
EXPECT("parallel compaction complete ordered output",0,memcmp(packed,want,(size_t)written*4));
|
||||
EXPECT("parallel prefix offsets for every group",0,memcmp(counts,offsets,(size_t)groups*4));
|
||||
EXPECT("GPU producer allocation canary",0xcccccccc,raw[(size_t)groups*8]);
|
||||
EXPECT("parallel compaction output canary",0xcccccccc,packed[written]);
|
||||
EXPECT("parallel prefix allocation canary",0xcccccccc,counts[groups]);
|
||||
EXPECT("parallel indirect args canary",0xcccccccc,args[5]);
|
||||
}
|
||||
}
|
||||
free(want);free(offsets);
|
||||
}
|
||||
static void scan_edges(void) {
|
||||
id<MTLLibrary> lib=library(@(k_nvn_geo_pack_msl));NSError *error=nil;
|
||||
id<MTLComputePipelineState> scan=[g_dev newComputePipelineStateWithFunction:[lib newFunctionWithName:@"geo_pack_scan"] error:&error];if(!scan)abort();
|
||||
id<MTLBuffer> b=[g_dev newBufferWithLength:32768 options:MTLResourceStorageModeShared];res_add(b);
|
||||
const uint32_t sizes[]={0,1,2,31,32,33,63,64,65,255,256,257,1023},threads[]={1,32,192,256};uint32_t want[1023];
|
||||
for(int sz=0;sz<13;sz++)for(int nt=0;nt<4;nt++) {
|
||||
uint32_t groups=sizes[sz],sum=0;memset(b.contents,0xcc,b.length);uint32_t *counts=b.contents;
|
||||
for(uint32_t g=0;g<groups;g++){want[g]=sum;counts[g]=g%5?g%4:0;sum+=counts[g];}
|
||||
nvn_geo_pack_job job={0,0,b.gpuAddress+16384,groups,0,7,37,b.gpuAddress};memcpy((char*)b.contents+16640,&job,sizeof job);
|
||||
mtl_sub_begin();id<MTL4ComputeCommandEncoder> ce=enc_c_begin(NULL);enc_c_pso(ce,scan);enc_c_args(ce,b.gpuAddress+16640,0);
|
||||
enc_c_dispatch(ce,MTLSizeMake(1,1,1),MTLSizeMake(threads[nt],1,1));enc_c_end(ce);finish();
|
||||
uint32_t *args=(uint32_t*)((char*)b.contents+16384);
|
||||
EXPECT("scan edge complete offsets",0,memcmp(counts,want,(size_t)groups*4));
|
||||
EXPECT("scan edge capacity count",sum<=37?sum:36,args[0]);EXPECT("scan edge counts canary",0xcccccccc,counts[groups]);
|
||||
EXPECT("scan edge args canary",0xcccccccc,args[5]);
|
||||
}
|
||||
// Large invalid totals must not wrap back into the writable output range.
|
||||
memset(b.contents,0xcc,b.length);uint32_t *counts=b.contents;counts[0]=UINT32_MAX-5;counts[1]=10;counts[2]=100;
|
||||
nvn_geo_pack_job job={0,0,b.gpuAddress+16384,3,0,7,64,b.gpuAddress};memcpy((char*)b.contents+16640,&job,sizeof job);
|
||||
mtl_sub_begin();id<MTL4ComputeCommandEncoder> ce=enc_c_begin(NULL);enc_c_pso(ce,scan);enc_c_args(ce,b.gpuAddress+16640,0);
|
||||
enc_c_dispatch(ce,MTLSizeMake(1,1,1),MTLSizeMake(256,1,1));enc_c_end(ce);finish();
|
||||
uint32_t *args=(uint32_t*)((char*)b.contents+16384);
|
||||
EXPECT("overflow prefix first",0,counts[0]);EXPECT("overflow prefix second",UINT32_MAX-5,counts[1]);EXPECT("overflow prefix saturates",UINT32_MAX,counts[2]);
|
||||
EXPECT("overflow total stays capacity bounded",63,args[0]);EXPECT("overflow scan counts canary",0xcccccccc,counts[3]);
|
||||
// Exercise the production write bound with an offset whose addition used
|
||||
// to wrap. All output bytes must remain untouched.
|
||||
id<MTLComputePipelineState> write=[g_dev newComputePipelineStateWithFunction:[lib newFunctionWithName:@"geo_pack_write"] error:&error];if(!write)abort();
|
||||
uint32_t *raw=(uint32_t*)((char*)b.contents+4096);raw[0]=0;raw[1]=1;raw[2]=2;counts[0]=UINT32_MAX-1;
|
||||
job=(nvn_geo_pack_job){b.gpuAddress+4096,b.gpuAddress+8192,b.gpuAddress+16384,1,3,7,8,b.gpuAddress};memcpy((char*)b.contents+16640,&job,sizeof job);
|
||||
mtl_sub_begin();ce=enc_c_begin(NULL);enc_c_pso(ce,write);enc_c_args(ce,b.gpuAddress+16640,0);
|
||||
enc_c_dispatch(ce,MTLSizeMake(1,1,1),MTLSizeMake(64,1,1));enc_c_end(ce);finish();
|
||||
uint32_t *output=(uint32_t*)((char*)b.contents+8192);for(int i=0;i<9;i++)EXPECT("overflow offset never writes output",0xcccccccc,output[i]);
|
||||
}
|
||||
static void passthrough_bounds(NSArray *layouts) {
|
||||
// The synthetic emitter uses the translator's topology-specific bound;
|
||||
// allocations and compaction consume metadata from output_layout(). Old
|
||||
// header-only metadata overwrites both canaries and compacts the wrong span.
|
||||
const uint32_t vertices[]={1,2,2,3,3};const int groups=3;
|
||||
EXPECT("five passthrough topology layouts",5,layouts.count);if(layouts.count!=5)return;
|
||||
id<MTLLibrary> packlib=library(@(k_nvn_geo_pack_msl));NSError *error=nil;
|
||||
id<MTLComputePipelineState> pack[3];const char *names[]={"geo_pack_count","geo_pack_scan","geo_pack_write"};
|
||||
for(int i=0;i<3;i++){pack[i]=[g_dev newComputePipelineStateWithFunction:[packlib newFunctionWithName:@(names[i])] error:&error];if(!pack[i])abort();}
|
||||
id<MTLBuffer> b=[g_dev newBufferWithLength:32768 options:MTLResourceStorageModeShared];res_add(b);
|
||||
for(int t=0;t<5;t++) {
|
||||
NSDictionary *layout=layouts[t];uint32_t bound=[layout[@"vertices"] unsignedIntValue],stride=[layout[@"index_stride"] unsignedIntValue],topology=[layout[@"output"] unsignedIntValue];
|
||||
if(bound>100||stride>200){EXPECT("bounded fixture layout",1,0);continue;}
|
||||
id<MTLLibrary> emitlib=library([NSString stringWithFormat:@"#include <metal_stdlib>\nusing namespace metal;\n"
|
||||
"struct A{device uint*raw;device float4*vertices;};\n"
|
||||
"kernel void emit(constant A&a[[buffer(0)]],uint g[[thread_position_in_grid]]){const uint nv=%u;"
|
||||
"for(uint v=0;v<nv;v++){a.raw[g*nv*2+v]=g*nv+v;a.vertices[g*nv+v]=float4(float(g),float(v),0,1);}"
|
||||
"for(uint v=nv;v<nv*2;v++)a.raw[g*nv*2+v]=0xffffffffu;}\n",vertices[t]]);
|
||||
id<MTLComputePipelineState> emit=[g_dev newComputePipelineStateWithFunction:[emitlib newFunctionWithName:@"emit"] error:&error];if(!emit)abort();
|
||||
memset(b.contents,0xcc,b.length);uint64_t emitargs[]={b.gpuAddress,b.gpuAddress+16384};memcpy((char*)b.contents+28672,emitargs,sizeof emitargs);
|
||||
nvn_geo_pack_job job={b.gpuAddress,b.gpuAddress+4096,b.gpuAddress+8192,groups,stride,topology,100,b.gpuAddress+12288};memcpy((char*)b.contents+28928,&job,sizeof job);
|
||||
mtl_sub_begin();id<MTL4ComputeCommandEncoder> en=enc_c_begin(NULL);enc_c_pso(en,emit);enc_c_args(en,b.gpuAddress+28672,0);
|
||||
enc_c_dispatch(en,MTLSizeMake(groups,1,1),MTLSizeMake(1,1,1));
|
||||
geo_pack_encode(en,pack,b.gpuAddress+28928,groups);enc_c_end(en);finish();
|
||||
uint32_t *raw=b.contents,*output=(uint32_t*)((char*)b.contents+16384),*indices=(uint32_t*)((char*)b.contents+4096),*args=(uint32_t*)((char*)b.contents+8192);
|
||||
EXPECT("passthrough raw allocation canary",0xcccccccc,raw[groups*stride]);
|
||||
EXPECT("passthrough vertex allocation canary",0xcccccccc,output[groups*bound*4]);
|
||||
EXPECT("passthrough compacted count",groups*vertices[t],args[0]);
|
||||
for(unsigned i=0;i<groups*vertices[t];i++)EXPECT("passthrough compacted order",i,indices[i]);
|
||||
EXPECT("passthrough compacted allocation canary",0xcccccccc,indices[groups*vertices[t]]);
|
||||
}
|
||||
}
|
||||
static NvShader *shader(id<MTLLibrary> l, NSString *name, int stage, const int *helpers, int n) {
|
||||
NvShader *s=[NvShader new];s->stage=stage;s->fn=[l newFunctionWithName:name];s->rf.nb=n;
|
||||
if(n) {s->ae=[s->fn newArgumentEncoderWithBufferIndex:0];s->arg_len=s->ae.encodedLength;}
|
||||
for(int i=0;i<n;i++)s->rf.b[i]=(nvn_rbind){.kind=NVN_RB_GEOMETRY,.reg=helpers[i],.aid=i};
|
||||
return s;
|
||||
}
|
||||
static void storage_buffers(void) {
|
||||
// Exercise the production JSON conversion and argument encoder: geometry
|
||||
// keeps NVN stage 2 even though this function runs as a Metal kernel.
|
||||
id<MTLLibrary> l=library(@"#include <metal_stdlib>\nusing namespace metal;\n"
|
||||
"struct A {constant uint*driver[[id(0)]];device uint*output[[id(1)]];};\n"
|
||||
"kernel void table(constant A&a[[buffer(0)]]) {for(uint i=0;i<3;i++){a.output[i]=a.driver[0x104+i];a.output[3+i]=a.driver[0x10c+i];}}\n");
|
||||
int helpers[]={0,0};NvShader *s=shader(l,@"table",2,helpers,2);char error[160]={0};
|
||||
NSDictionary *json=@{@"route":@"B",@"bindings":@[
|
||||
@{@"kind":@"drvcb",@"bank":@0,@"arg_id":@0,@"msl_name":@"gp_c0",@"msl_type":@"constant uint*"},
|
||||
@{@"kind":@"sbuf",@"reg":@2,@"arg_id":@1,@"msl_name":@"gp_s1",@"msl_type":@"device uint*",@"rw":@YES}]};
|
||||
EXPECT("geometry storage reflection",0,nvn_refl_from_json(json,&s->rf,error,sizeof error));
|
||||
EXPECT("geometry storage write flag",1,s->rf.b[1].rw);
|
||||
NSDictionary *readonly=@{@"route":@"B",@"bindings":@[
|
||||
@{@"kind":@"sbuf",@"reg":@2,@"arg_id":@0,@"msl_name":@"gp_s1",@"msl_type":@"device uint*",@"rw":@NO}]};
|
||||
nvn_refl rr;EXPECT("explicit read-only reflection",0,nvn_refl_from_json(readonly,&rr,error,sizeof error));
|
||||
EXPECT("explicit read-only flag overrides device qualifier",0,rr.b[0].rw);
|
||||
uint8_t *data;if(posix_memalign((void**)&data,getpagesize(),12288))abort();memset(data,0xcc,12288);mtl_pool_add(data,12288);
|
||||
state_reset();S.ssbo[2][0]=(p_bind_buf){.stage=2,.index=0,.addr=(uint64_t)data,.size=123};
|
||||
S.ssbo[2][2]=(p_bind_buf){.stage=2,.index=2,.addr=(uint64_t)(data+4096),.size=64};
|
||||
S.ssbo[5][0]=(p_bind_buf){.stage=5,.index=0,.addr=(uint64_t)(data+8192),.size=99};
|
||||
NSError *e=nil;id<MTLComputePipelineState> ps=[g_dev newComputePipelineStateWithFunction:s->fn error:&e];if(!ps)abort();
|
||||
mtl_sub_begin();id<MTL4ComputeCommandEncoder> en=enc_c_begin(NULL);args_dirty_all();encode_args(en,s,2,0);enc_c_pso(en,ps);
|
||||
EXPECT("geometry storage write tracked",1,sbw_hits((uint64_t)(data+4096),(uint64_t)(data+4096)+24));
|
||||
enc_c_dispatch(en,MTLSizeMake(1,1,1),MTLSizeMake(1,1,1));enc_c_end(en);finish();
|
||||
uint64_t row0=0,row2=0;uint32_t *out=(uint32_t*)(data+4096);memcpy(&row0,out,8);memcpy(&row2,out+3,8);
|
||||
EXPECT("geometry c0 row 0 guest address",(uint64_t)data,row0);EXPECT("geometry c0 row 0 size",123,out[2]);
|
||||
EXPECT("geometry c0 row 2 guest address",(uint64_t)(data+4096),row2);EXPECT("geometry c0 row 2 size",64,out[5]);
|
||||
mtl_pool_del(data);mtl_drain();free(data);
|
||||
}
|
||||
static void passthrough_kernels(const char *directory) {
|
||||
// Actual EXIT-only Maxwell passthrough shaders, compiled by dmsh_xlate.
|
||||
// Positions and all unmodified generic attributes must survive compute
|
||||
// lowering, with adjacency removed and instances kept independent.
|
||||
const uint32_t widths[]={1,2,4,3,6},vertices[]={1,2,2,3,3};
|
||||
const uint32_t source_vertex[5][3]={{0},{0,1},{1,2},{0,1,2},{0,2,4}};
|
||||
const uint32_t primitives=3,instances=2,groups=primitives*instances;
|
||||
id<MTLLibrary> packlib=library(@(k_nvn_geo_pack_msl));NSError *error=nil;
|
||||
id<MTLComputePipelineState> pack[3];const char *names[]={"geo_pack_count","geo_pack_scan","geo_pack_write"};
|
||||
for(int i=0;i<3;i++){pack[i]=[g_dev newComputePipelineStateWithFunction:[packlib newFunctionWithName:@(names[i])] error:&error];if(!pack[i])abort();}
|
||||
for(int t=0;t<5;t++) {
|
||||
fprintf(stderr,"compiled passthrough topology %d\n",t);
|
||||
NSString *stem=[@(directory) stringByAppendingPathComponent:[NSString stringWithFormat:@"pass%d",t]];
|
||||
NSData *data=[NSData dataWithContentsOfFile:[stem stringByAppendingString:@".json"]];
|
||||
NSDictionary *json=data?[NSJSONSerialization JSONObjectWithData:data options:0 error:&error]:nil;
|
||||
id<MTLLibrary> lib=[g_dev newLibraryWithURL:[NSURL fileURLWithPath:[stem stringByAppendingString:@".macosx.metallib"]] error:&error];
|
||||
EXPECT("compiled passthrough fixture loaded",1,json&&lib);if(!json||!lib)continue;
|
||||
NvShader *s=shader(lib,@"main0",2,NULL,0);char message[160]={0};
|
||||
EXPECT("passthrough reflection",0,nvn_refl_from_json(json,&s->rf,message,sizeof message));
|
||||
s->ae=[s->fn newArgumentEncoderWithBufferIndex:0];s->arg_len=s->ae.encodedLength;
|
||||
NSDictionary *layout=json[@"geometry"];
|
||||
uint32_t bound=[layout[@"vertices"] unsignedIntValue],stride=[layout[@"stride"] unsignedIntValue],index_stride=[layout[@"index_stride"] unsignedIntValue];
|
||||
EXPECT("passthrough topology bound",vertices[t],bound);EXPECT("passthrough complete generic map",133,stride);
|
||||
if(bound!=vertices[t]||stride!=133||index_stride!=vertices[t]*2)continue;
|
||||
id<MTLComputePipelineState> pipeline=[g_dev newComputePipelineStateWithFunction:s->fn error:&error];
|
||||
if(!pipeline){fprintf(stderr,"passthrough topology %d: %s\n",t,error.localizedDescription.UTF8String);abort();}
|
||||
id<MTLBuffer> b=[g_dev newBufferWithLength:65536 options:MTLResourceStorageModeShared];res_add(b);memset(b.contents,0xcc,b.length);
|
||||
const uint32_t count=primitives*widths[t];float *in=b.contents;
|
||||
for(unsigned i=0;i<count*instances;i++) {
|
||||
float *p=in+i*144;memset(p,0,144*4);
|
||||
p[0]=i+.25f;p[1]=i+.5f;p[2]=i+.75f;p[3]=1;p[4]=1;
|
||||
for(unsigned c=0;c<128;c++)p[16+c]=i*128+c+.125f;
|
||||
}
|
||||
uint32_t vi[8]={count,instances,0,0,primitives,0,0,0};memcpy((char*)b.contents+24576,vi,sizeof vi);
|
||||
uint32_t *map=(uint32_t*)((char*)b.contents+24832);for(unsigned v=0;v<count;v++)map[v]=v;
|
||||
state_reset();g_geo_bind[0]=b.gpuAddress;g_geo_bind[1]=b.gpuAddress+32768;g_geo_bind[2]=b.gpuAddress+49152;
|
||||
g_geo_bind[3]=b.gpuAddress+24576;g_geo_bind[4]=b.gpuAddress+24832;
|
||||
nvn_geo_pack_job job={g_geo_bind[2],b.gpuAddress+50176,b.gpuAddress+53248,groups,index_stride,[layout[@"output"] unsignedIntValue],100,b.gpuAddress+53504};
|
||||
memcpy((char*)b.contents+54016,&job,sizeof job);
|
||||
mtl_sub_begin();id<MTL4ComputeCommandEncoder> en=enc_c_begin(NULL);args_dirty_all();encode_args(en,s,2,0);enc_c_pso(en,pipeline);
|
||||
enc_c_dispatch(en,MTLSizeMake(1,instances,1),MTLSizeMake(32,1,1));
|
||||
geo_pack_encode(en,pack,b.gpuAddress+54016,groups);enc_c_end(en);finish();
|
||||
float *out=(float*)((char*)b.contents+32768);uint32_t *raw=(uint32_t*)((char*)b.contents+49152),*packed=(uint32_t*)((char*)b.contents+50176),*args=(uint32_t*)((char*)b.contents+53248);
|
||||
for(unsigned g=0;g<groups;g++) {
|
||||
for(unsigned v=0;v<vertices[t];v++) {
|
||||
float *q=in+((g/primitives)*count+(g%primitives)*widths[t]+source_vertex[t][v])*144,*p=out+(g*bound+v)*stride;
|
||||
for(unsigned c=0;c<4;c++)EXPECT("passthrough position",1,p[c]==q[c]);
|
||||
for(unsigned c=0;c<128;c++)EXPECT("passthrough generic attribute",1,p[5+c]==q[16+c]);
|
||||
EXPECT("passthrough raw index",g*bound+v,raw[g*index_stride+v]);
|
||||
EXPECT("passthrough compacted index",g*bound+v,packed[g*bound+v]);
|
||||
}
|
||||
for(unsigned v=bound;v<index_stride;v++)EXPECT("passthrough restart padding",UINT32_MAX,raw[g*index_stride+v]);
|
||||
}
|
||||
EXPECT("passthrough output canary",0xcccccccc,((uint32_t*)out)[groups*bound*stride]);
|
||||
EXPECT("passthrough index canary",0xcccccccc,raw[groups*index_stride]);
|
||||
EXPECT("passthrough compacted count",groups*bound,args[0]);
|
||||
EXPECT("passthrough compacted canary",0xcccccccc,packed[groups*bound]);
|
||||
}
|
||||
}
|
||||
static void replay(int mode) {
|
||||
int kind=mode<7?mode:mode>=16?5:3;
|
||||
int conversion=mode==12||mode==13,native_stream=mode==11;
|
||||
id<MTLLibrary> l=library(@"#include <metal_stdlib>\nusing namespace metal;\n"
|
||||
"struct C {device float *dst;uint4 info;};\n"
|
||||
"vertex void capture(uint v[[vertex_id]],uint i[[instance_id]],constant C&c[[buffer(13)]]) {uint n=v-c.info.x,inst=i-c.info.z;device float*p=c.dst+(inst*c.info.y+n)*144; p[0]=float(n);p[1]=float(inst);p[2]=0;p[3]=1;}\n"
|
||||
@@ -71,14 +324,16 @@ static void replay(int mode) {
|
||||
"struct G{device const float*in[[id(0)]];device float4*out[[id(1)]];device uint*ix[[id(2)]];constant uint4*info[[id(3)]];device const uint*map[[id(4)]];};\n"
|
||||
"kernel void geometry(constant G&g[[buffer(0)]],uint3 t[[thread_position_in_grid]]) {if(t.x>=g.info[1].x||t.y>=g.info[0].y)return;uint k=(t.y*g.info[1].x+t.x)*2+t.z;uint v=g.map[t.x];float2 q=float2(g.in[(t.y*g.info[0].x+v)*144],g.in[(t.y*g.info[0].x+v)*144+1]);float2 a=q*0.5-0.9;float2 d[4]={float2(0),float2(.4,0),float2(0,.4),float2(.4)};for(uint n=0;n<4;n++){g.out[k*4+n]=float4(a+d[n],0,1);g.ix[k*5+n]=k*4+n;}g.ix[k*5+4]=0xffffffffu;}\n"
|
||||
"struct V{device const float4*p[[id(0)]];};vertex float4 reader(uint v[[vertex_id]],constant V&a[[buffer(0)]]){return a.p[v];}\n"
|
||||
"fragment float4 red(){return float4(1,0,0,1);}\n");
|
||||
"fragment float4 red(){return float4(1,0,0,1);}\n"
|
||||
"kernel void index_write(device uint*p[[buffer(0)]]){p[0]=12;p[1]=10;p[2]=0xffffffffu;p[3]=11;}\n");
|
||||
int helpers[]={0,1,2,3,4}, rh[]={1};
|
||||
NvProg *pr=[NvProg new];pr->sh[0]=shader(l,@"unused",0,NULL,0);pr->sh[0]->geo_fn=[l newFunctionWithName:@"capture"];
|
||||
pr->sh[1]=shader(l,@"red",1,NULL,0);pr->sh[2]=shader(l,@"geometry",2,helpers,5);
|
||||
if(conversion||native_stream){pr->sh[0]->rf.nv=1;pr->sh[0]->rf.v[0].ct=NVN_CT_FLOAT;pr->sh[0]->rf.v[0].nvn=pr->sh[0]->rf.v[0].loc=0;}
|
||||
NvShader *gs=pr->sh[2];strcpy(gs->key,"0123456789abcdef_b");gs->geo_vertices=4;gs->geo_invocations=2;gs->geo_output=7;gs->geo_stride=4;gs->geo_index_stride=5;
|
||||
g_shcache=[NSMutableDictionary dictionary];g_shcache[@"0123456789abcdef_bg0"]=gs;g_shcache[@"0123456789abcdef_bgv"]=shader(l,@"reader",0,rh,1);
|
||||
static NSMutableArray *keep;if(!keep)keep=[NSMutableArray array];[keep addObject:pr];[keep addObject:g_shcache[@"0123456789abcdef_bgv"]];
|
||||
static prog_t cp[7];cp[mode].serial=8700+mode;serial_put(cp[mode].serial,pr);
|
||||
static prog_t cp[18];cp[mode].serial=8700+mode;serial_put(cp[mode].serial,pr);
|
||||
tex_t target={.magic=MAGIC('T','E','X',0),.serial=8800+mode};target.d.width=target.d.height=32;target.d.depth=target.d.samples=target.d.levels=1;target.d.target=NVN_TEXTURE_TARGET_2D;target.d.format=NVN_FORMAT_RGBA8;
|
||||
uint8_t *commands; if(posix_memalign((void**)&commands,getpagesize(),65536))abort();memset(commands,0,65536);mtl_pool_add(commands,65536);
|
||||
size_t used=0;
|
||||
@@ -87,28 +342,70 @@ static void replay(int mode) {
|
||||
p_viewports vp={.n=1};vp.v[0][2]=vp.v[0][3]=32;EMIT(OP_VIEWPORTS,vp);p_scissor sc={0,0,32,32};EMIT(OP_SCISSOR,sc);
|
||||
p_clear_color cl={.index=0,.mask=15,.rgba={0,0,0,1}};EMIT(OP_CLEAR_COLOR,cl);
|
||||
p_bind_program bp={&cp[mode],7};EMIT(OP_BIND_PROGRAM,bp);
|
||||
p_draw d={.prim=0,.first=7,.count=mode==6?9000:3,.instances=2,.base_instance=5};
|
||||
if((mode>=1&&mode<=3)||mode==5) {
|
||||
int type=mode==5?1:mode-1;uint32_t ix[]={12,10,UINT32_MAX,11};
|
||||
if(conversion||native_stream) {
|
||||
p_bind_vattr va={.n=1};va_st attribute={.fmt=conversion?0x51:0x0a};memcpy(va.st,&attribute,4);EMIT(OP_BIND_VATTR,va);
|
||||
p_bind_vstream stream={.n=1};stream.st[0].stride=conversion?1:4;EMIT(OP_BIND_VSTREAM,stream);
|
||||
p_bind_vbuf vb={.n=1};vb.r[0]=(NVNbufferRange){(uint64_t)(commands+24576),64};EMIT(OP_BIND_VBUF,vb);
|
||||
memset(commands+24576,conversion?17:0,64);
|
||||
}
|
||||
p_draw d={.prim=0,.first=7,.count=kind==6?9000:3,.instances=2,.base_instance=5};
|
||||
if((kind>=1&&kind<=3)||kind==5) {
|
||||
int type=kind==5?1:kind-1;uint32_t ix[]={12,10,UINT32_MAX,11};
|
||||
for(int i=0;i<4;i++)memcpy(commands+8192+(i<<type),ix+i,1<<type);
|
||||
p_prim_restart restart={1,UINT32_MAX};EMIT(OP_PRIM_RESTART,restart);
|
||||
p_draw_idx di={.prim=0,.itype=type,.count=4,.instances=2,.base_vertex=-3,.base_instance=5,.ibuf=(uint64_t)(commands+8192)};
|
||||
if(mode==5){uint32_t args[]={4,2,0,(uint32_t)-3,5};memcpy(commands+16384,args,sizeof args);di.ind=(uint64_t)(commands+16384);}
|
||||
if(kind==5){uint32_t args[]={4,2,mode==17?16:0,(uint32_t)-3,5};memcpy(commands+16384,args,sizeof args);di.ind=(uint64_t)(commands+16384);if(mode==17)di.ibuf-=32;}
|
||||
if(mode==7||mode==10||mode==11||mode==13||mode==16||mode==17) {
|
||||
uint64_t destination=(uint64_t)(commands+(mode==10?32768:mode==11||mode==13?24576:mode==16?16384:8192));
|
||||
uint64_t n=mode==11||mode==13?64:mode==16?20:(uint64_t)4<<type;
|
||||
memcpy(commands+12288,(void*)(uintptr_t)destination,n);
|
||||
if(mode!=10)memset((void*)(uintptr_t)destination,mode==13?3:0,n);
|
||||
struct{uint64_t source,destination,bytes;}copy={(uint64_t)(commands+12288),destination,n};EMIT(OP_COPY_B2B,copy);
|
||||
}
|
||||
if(mode==8||mode==9)memset(commands+8192,0,16);
|
||||
EMIT(OP_DRAW_IDX,di);
|
||||
} else {
|
||||
if(mode==4){uint32_t args[]={3,2,7,5};memcpy(commands+16384,args,sizeof args);d.ind=(uint64_t)(commands+16384);}
|
||||
if(kind==4){uint32_t args[]={3,2,7,5};memcpy(commands+16384,args,sizeof args);d.ind=(uint64_t)(commands+16384);}
|
||||
EMIT(OP_DRAW,d);
|
||||
}
|
||||
op_hdr end={OP_END,8};memcpy(commands+used,&end,8);
|
||||
#undef EMIT
|
||||
state_reset();memset(&R,0,sizeof R);mtl_sub_begin();uint64_t h=(uint64_t)commands;mtl_sub_index(&h,1);mtl_exec(commands);
|
||||
id<MTLComputePipelineState> writer;
|
||||
if(mode==8||mode==9){NSError *error=nil;writer=[g_dev newComputePipelineStateWithFunction:[l newFunctionWithName:@"index_write"] error:&error];if(!writer)abort();}
|
||||
id<MTLSharedEvent> gate;
|
||||
if(mode==9) {
|
||||
// Hold a previous submission live until this draw reaches its hazard
|
||||
// check; a completed prior write correctly needs no second wait.
|
||||
gate=[g_dev newSharedEvent];rec_drain();[g_q4 waitForEvent:gate value:1];
|
||||
mtl_sub_begin();id<MTL4ComputeCommandEncoder> en=enc_c_begin(NULL);enc_c_pso(en,writer);
|
||||
uint64_t gpu,offset;void *buffer;mtl_gpu_addr((uint64_t)(commands+8192),16,&buffer,&offset,&gpu);enc_c_args(en,gpu,0);
|
||||
enc_c_dispatch(en,MTLSizeMake(1,1,1),MTLSizeMake(1,1,1));enc_c_end(en);sbw_note((uint64_t)(commands+8192),16,SBW_GPU);
|
||||
mtl_sub_commit();rec_drain();
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW,500000000),dispatch_get_global_queue(QOS_CLASS_USER_INITIATED,0),^{gate.signaledValue=1;});
|
||||
}
|
||||
state_reset();memset(&R,0,sizeof R);mtl_sub_begin();uint64_t waits=g_mdi_v;
|
||||
if(mode==8) {
|
||||
id<MTL4ComputeCommandEncoder> en=enc_c_begin(NULL);enc_c_pso(en,writer);
|
||||
uint64_t gpu,offset;void *buffer;mtl_gpu_addr((uint64_t)(commands+8192),16,&buffer,&offset,&gpu);enc_c_args(en,gpu,0);
|
||||
enc_c_dispatch(en,MTLSizeMake(1,1,1),MTLSizeMake(1,1,1));enc_c_end(en);sbw_note((uint64_t)(commands+8192),16,SBW_GPU);
|
||||
}
|
||||
if(mode==14)g_sbw_over=1;
|
||||
if(mode==15)g_pend_over=1;
|
||||
uint64_t h=(uint64_t)commands;mtl_sub_index(&h,1);mtl_exec(commands);
|
||||
char wait_name[80];snprintf(wait_name,sizeof wait_name,"geometry CPU snapshot wait mode %d",mode);
|
||||
EXPECT(wait_name,mode==7||mode==8||mode==9||mode==13||mode>=14,g_mdi_v-waits);
|
||||
if(conversion) {
|
||||
float first=-1;for(int i=0;i<64;i++)if(g_vconv[i].serial==g_sub_serial&&g_vconv[i].addr==(uint64_t)(commands+24576))
|
||||
for(NvArena *a in g_sub_arenas)if(g_vconv[i].gpu>=a->gpu&&g_vconv[i].gpu+4<=a->gpu+a->buf.length)memcpy(&first,(char*)a->buf.contents+g_vconv[i].gpu-a->gpu,4);
|
||||
EXPECT("CPU conversion sees the queued GPU write",1,first==17);
|
||||
}
|
||||
id<MTLBuffer> b=[g_dev newBufferWithLength:4096 options:MTLResourceStorageModeShared];
|
||||
uint32_t *args=NULL;id<MTLBuffer> argsBuffer;
|
||||
for(NvArena *a in g_sub_arenas)if(g_geo_args>=a->gpu&&g_geo_args+20<=a->gpu+a->buf.length){argsBuffer=a->buf;args=(uint32_t*)((char*)argsBuffer.contents+g_geo_args-a->gpu);}
|
||||
[blit() copyFromTexture:tex_mtl(&target) sourceSlice:0 sourceLevel:0 sourceOrigin:MTLOriginMake(0,0,0) sourceSize:MTLSizeMake(32,32,1) toBuffer:b destinationOffset:0 destinationBytesPerRow:128 destinationBytesPerImage:4096];finish();
|
||||
EXPECT("two GS invocations per input primitive",mode==6?216000:72,args?args[0]:0);
|
||||
EXPECT("two GS invocations per input primitive",kind==6?216000:72,args?args[0]:0);
|
||||
int red=0;uint8_t *px=b.contents;for(int i=0;i<1024;i++)if(px[i*4]>200)red++;
|
||||
EXPECT("expanded quads rasterized",mode==6?288:216,red);
|
||||
EXPECT("expanded quads rasterized",kind==6?288:216,red);
|
||||
EXPECT("each instance has independent capture and output",1,px[(24*32+4)*4]>200);
|
||||
mtl_pool_del(commands);mtl_drain();free(commands);
|
||||
}
|
||||
@@ -176,7 +473,12 @@ static void translated(const char *directory) {
|
||||
mtl_pool_del(uniforms);mtl_drain();free(uniforms);
|
||||
}
|
||||
int main(int argc,char **argv) {@autoreleasepool {
|
||||
setvbuf(stdout,NULL,_IONBF,0);assembly();mtl_init();pack_test();for(int mode=0;mode<7;mode++)replay(mode);
|
||||
if(argc>1)translated(argv[1]);
|
||||
setvbuf(stdout,NULL,_IONBF,0);assembly();capture_indices();mtl_init();storage_buffers();cpu_read_proofs();pack_test();
|
||||
scan_edges();pack_dependency_test(3);pack_dependency_test(257);pack_dependency_test(129032);for(int mode=0;mode<18;mode++)replay(mode);
|
||||
if(argc>2&&!strcmp(argv[1],"--passthrough-layouts")) {
|
||||
NSData *data=[NSData dataWithContentsOfFile:@(argv[2])];NSArray *layouts=data?[NSJSONSerialization JSONObjectWithData:data options:0 error:nil]:nil;
|
||||
passthrough_bounds(layouts);
|
||||
} else if(argc>2&&!strcmp(argv[1],"--passthrough-kernels"))passthrough_kernels(argv[2]);
|
||||
else if(argc>1)translated(argv[1]);
|
||||
printf("t_geometry: %d checks, %d failed\n",checks,failed);return failed!=0;
|
||||
}}
|
||||
@@ -202,9 +202,11 @@ int main(void) {
|
||||
P(nvnQueueBuilderSetQueueMemory)(&qb, qmem, qsz);
|
||||
EXPECT("QueueInitialize succeeds", 1, P(nvnQueueInitialize)(&q, &qb));
|
||||
NVNcommandHandle hs[2] = {h1, h2};
|
||||
uint64_t counter_before = now_ns();
|
||||
P(nvnQueueSubmitCommands)(&q, 2, hs);
|
||||
NVNsync sf; P(nvnSyncInitialize)(&sf, &dev); P(nvnQueueFenceSync)(&q, &sf, NVN_SYNC_CONDITION_ALL_GPU_COMMANDS_COMPLETE, 0);
|
||||
int wr = P(nvnSyncWait)(&sf, 5000000000ull);
|
||||
uint64_t counter_after = now_ns();
|
||||
EXPECT("fence wait after submit succeeds (0 or 1)", 1, wr == 0 || wr == 1);
|
||||
int ub_ok = 1;
|
||||
for (int k = 0; k < 20; k++) for (int i = 0; i < 16; i++) { uint32_t w; memcpy(&w, ub + k * 64 + i * 4, 4); ub_ok &= w == (uint32_t)(k * 100 + i); }
|
||||
@@ -213,6 +215,11 @@ int main(void) {
|
||||
EXPECT("buffer copy 64 B identical", 0, memcmp(src, dst, 64));
|
||||
uint64_t ts[2]; memcpy(ts, cnt, 16);
|
||||
EXPECT("counter timestamp written (non-zero)", 1, ts[0] != 0 && ts[0] == ts[1]);
|
||||
NVNcounterData fixed_counter = {0, 614400};
|
||||
EXPECT("614400 raw counter ticks = 1 ms", 1000000, P(nvnDeviceGetTimestampInNanoseconds)(&dev, &fixed_counter));
|
||||
NVNcounterData reported_counter; memcpy(&reported_counter, cnt, sizeof reported_counter);
|
||||
uint64_t counter_ns = P(nvnDeviceGetTimestampInNanoseconds)(&dev, &reported_counter);
|
||||
EXPECT("report converted to ns lies inside submit/wait", 1, counter_ns + 2 >= counter_before && counter_ns <= counter_after);
|
||||
|
||||
// 5a. Command memory per recording, as GetCommandMemoryUsed reports it (games size prerecorded command blocks by it: Breath of the Wild records one scratch draw per mesh):
|
||||
// no BEGIN record, a plain indexed draw without the indirect / multi-draw fields, and the handle is the first record; an indirect draw keeps its address
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
// NVN raw timestamp ABI: known vectors, long uptimes and an independent game's inline conversion.
|
||||
#include "../nvn/nvn_timestamp.h"
|
||||
#include <stdio.h>
|
||||
|
||||
static int checks, fails;
|
||||
#define CHECK(c, why) do { checks++; if (!(c)) { fails++; fprintf(stderr, "FAIL: %s\n", why); } } while (0)
|
||||
|
||||
// NieR:Automata 1.0.3 main build 3c10ec35c5ef4c3686b4053afb0e58e7, main+0x9ba7a8..0x9ba808.
|
||||
// These are its integer instructions, including the two multiply-high divisions, before SCVTF / FDIV by 1000.
|
||||
// The consumer never calls our conversion helper: 614400 raw ticks must become 1 ms in its own arithmetic.
|
||||
static float nier_dr_ms(uint64_t ticks) {
|
||||
uint64_t a = ticks * 625;
|
||||
a = (uint64_t)((__uint128_t)a * UINT64_C(0xaaaaaaaaaaaaaaab) >> 64);
|
||||
uint64_t b = (a >> 8) & UINT32_MAX;
|
||||
a >>= 40;
|
||||
uint64_t c = a * UINT64_C(0xe353f7cf);
|
||||
uint64_t d = b * UINT64_C(0xe353f7cf);
|
||||
d = c + (d >> 32);
|
||||
a *= UINT64_C(0x20c49ba5);
|
||||
b *= UINT64_C(0x20c49ba5);
|
||||
b += (uint32_t)d;
|
||||
a += d >> 32;
|
||||
a += b >> 32;
|
||||
return (float)(int64_t)(a >> 7) / 1000.0f;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
const struct { uint64_t ns, ticks; } exact[] = {
|
||||
{0, 0}, {625, 384}, {1000000, 614400}, {16000000, 9830400}, {1000000000, 614400000},
|
||||
{UINT64_C(5000000000000000000), UINT64_C(3072000000000000000)},
|
||||
};
|
||||
for (unsigned i = 0; i < sizeof exact / sizeof *exact; i++) {
|
||||
CHECK(nvn_timestamp_from_ns(exact[i].ns) == exact[i].ticks, "known ns -> 614.4 MHz ticks");
|
||||
CHECK(nvn_timestamp_to_ns(exact[i].ticks) == exact[i].ns, "known raw ticks -> ns");
|
||||
}
|
||||
CHECK(nvn_timestamp_from_ns(1) == 0 && nvn_timestamp_from_ns(2) == 1, "ns -> ticks rounds down");
|
||||
CHECK(nvn_timestamp_to_ns(1) == 1 && nvn_timestamp_to_ns(2) == 3, "ticks -> ns rounds down");
|
||||
const uint64_t ns[] = {1, 2, 624, 626, 16666667, UINT64_C(1234567890123456789), UINT64_MAX};
|
||||
for (unsigned i = 0; i < sizeof ns / sizeof *ns; i++) {
|
||||
uint64_t back = nvn_timestamp_to_ns(nvn_timestamp_from_ns(ns[i]));
|
||||
CHECK(back <= ns[i] && ns[i] - back <= 2, "ns round trip loses at most 2 ns, including long uptime");
|
||||
}
|
||||
CHECK(nier_dr_ms(614400) == 1.0f, "independent NieR raw counter conversion: 614400 ticks = 1 ms");
|
||||
CHECK(nier_dr_ms(nvn_timestamp_from_ns(16000000)) == 16.0f, "NieR sees a 16 ms GPU report as 16 ms");
|
||||
CHECK(nier_dr_ms(nvn_timestamp_from_ns(1000000000)) == 1000.0f, "NieR sees a 1 second GPU report as 1000 ms");
|
||||
CHECK(nier_dr_ms(307200) == 0.5f, "old 19.2 MHz report of 16 ms was read as 0.5 ms");
|
||||
printf("timestamp: %d checks, %d failed\n", checks, fails);
|
||||
return fails != 0;
|
||||
}
|
||||
@@ -0,0 +1,236 @@
|
||||
"""Synthetic geometry lowering, compiler and optional native GPU regressions."""
|
||||
import ast
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
import re
|
||||
import shutil
|
||||
import struct
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / 'tools'))
|
||||
import dmsh_geometry
|
||||
|
||||
RASTER_CHECK = r'''#import <Foundation/Foundation.h>
|
||||
#import <Metal/Metal.h>
|
||||
int main(int argc, const char **argv) { @autoreleasepool {
|
||||
id<MTLDevice> device = MTLCreateSystemDefaultDevice();
|
||||
if (!device) { fprintf(stderr, "no Metal device\n"); return 77; }
|
||||
NSError *error = nil;
|
||||
id<MTLLibrary> library = [device newLibraryWithURL:[NSURL fileURLWithPath:@(argv[1])] error:&error];
|
||||
if (!library) { fprintf(stderr, "%s\n", error.description.UTF8String); return 1; }
|
||||
MTLRenderPipelineDescriptor *pipeline = [MTLRenderPipelineDescriptor new];
|
||||
pipeline.vertexFunction = [library newFunctionWithName:@(argv[2])];
|
||||
pipeline.fragmentFunction = [library newFunctionWithName:@"pixel"];
|
||||
pipeline.colorAttachments[0].pixelFormat = MTLPixelFormatRGBA8Unorm;
|
||||
id<MTLRenderPipelineState> state = [device newRenderPipelineStateWithDescriptor:pipeline error:&error];
|
||||
if (!state) { fprintf(stderr, "%s\n", error.description.UTF8String); return 1; }
|
||||
MTLTextureDescriptor *td = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatRGBA8Unorm width:16 height:16 mipmapped:NO];
|
||||
td.usage = MTLTextureUsageRenderTarget; td.storageMode = MTLStorageModeShared;
|
||||
id<MTLTexture> texture = [device newTextureWithDescriptor:td];
|
||||
id<MTLCommandQueue> queue = [device newCommandQueue];
|
||||
uint32_t masks[] = {0, 1, 2, 3, 0x80000000u, 0xffffffffu};
|
||||
for (unsigned clamp = 0; clamp < 2; clamp++)
|
||||
for (uint32_t points = 0; points < 2; points++)
|
||||
for (unsigned i = 0; i < sizeof(masks) / sizeof(*masks); i++) {
|
||||
MTLRenderPassDescriptor *pass = [MTLRenderPassDescriptor new];
|
||||
pass.colorAttachments[0].texture = texture;
|
||||
pass.colorAttachments[0].loadAction = MTLLoadActionClear;
|
||||
pass.colorAttachments[0].storeAction = MTLStoreActionStore;
|
||||
pass.colorAttachments[0].clearColor = MTLClearColorMake(0, 0, 0, 1);
|
||||
id<MTLCommandBuffer> command = [queue commandBuffer];
|
||||
id<MTLRenderCommandEncoder> encoder = [command renderCommandEncoderWithDescriptor:pass];
|
||||
[encoder setRenderPipelineState:state];
|
||||
[encoder setDepthClipMode:clamp ? MTLDepthClipModeClamp : MTLDepthClipModeClip];
|
||||
[encoder setVertexBytes:&masks[i] length:sizeof(masks[i]) atIndex:0];
|
||||
[encoder setVertexBytes:&points length:sizeof(points) atIndex:1];
|
||||
[encoder drawPrimitives:points ? MTLPrimitiveTypePoint : MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:points ? 1 : 3];
|
||||
[encoder endEncoding]; [command commit]; [command waitUntilCompleted];
|
||||
if (command.error) { fprintf(stderr, "%s\n", command.error.description.UTF8String); return 1; }
|
||||
uint8_t pixel[4];
|
||||
[texture getBytes:pixel bytesPerRow:4 fromRegion:MTLRegionMake2D(8, 8, 1, 1) mipmapLevel:0];
|
||||
if ((pixel[0] != 0) != ((masks[i] & 1u) != 0)) {
|
||||
fprintf(stderr, "mask %#x, points=%u, depth clamp=%u: red=%u\n", masks[i], points, clamp, pixel[0]); return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
} }
|
||||
'''
|
||||
|
||||
|
||||
def mask_reader():
|
||||
# GenerateVertexPassthroughForCompute treats ViewportMask (int[1]) as a
|
||||
# scalar output. SPIRV-Cross emits this invalid array-copy expression.
|
||||
return '''#include <metal_stdlib>
|
||||
using namespace metal;
|
||||
template<typename T, uint N>
|
||||
inline void spvArrayCopyFromStackToStack(thread T (&dst)[N], thread const T (&src)[N])
|
||||
{ for (uint i = 0; i < N; i++) dst[i] = src[i]; }
|
||||
struct main0_out
|
||||
{
|
||||
float4 gl_Position [[position]];
|
||||
float gl_PointSize [[point_size]];
|
||||
};
|
||||
vertex main0_out main0(uint vid [[vertex_id]], constant uint& mask [[buffer(0)]], constant uint& points [[buffer(1)]])
|
||||
{
|
||||
main0_out out = {};
|
||||
float2 positions[] = {float2(-1.0, -1.0), float2(3.0, -1.0), float2(-1.0, 3.0)};
|
||||
out.gl_Position = float4(points ? float2(0.0) : positions[vid], 0.0, 1.0);
|
||||
out.gl_PointSize = 64.0;
|
||||
float bits = as_type<float>(mask);
|
||||
spvArrayCopyFromStackToStack(gl_BuiltIn_5253, as_type<int>(bits).elements);
|
||||
return out;
|
||||
}
|
||||
fragment float4 pixel() { return float4(1.0, 0.0, 0.0, 1.0); }
|
||||
'''
|
||||
|
||||
|
||||
def depth_entries(src):
|
||||
# Exercise the same post-reader depth conversion as geometry_finish without
|
||||
# importing the builder's command-line and game-profile initialization.
|
||||
builder = Path(dmsh_geometry.__file__).with_name('dmsh_build.py').read_text()
|
||||
node = next(n for n in ast.parse(builder).body if isinstance(n, ast.FunctionDef) and n.name == 'vs_depth')
|
||||
ns = {'re': re, 'sys': sys}
|
||||
exec(ast.get_source_segment(builder, node), ns)
|
||||
# The production helper locates the translated vertex entry at file end.
|
||||
vertex, pixel = src.split('fragment float4 pixel()', 1)
|
||||
return ns['vs_depth'](vertex)[1] + 'fragment float4 pixel()' + pixel
|
||||
|
||||
|
||||
class GeometryReader(unittest.TestCase):
|
||||
def test_capture_loads_preserve_input_reads(self):
|
||||
source = 'device _22* vertex_output [[id(1)]]; device _22* geometry_vb_output [[id(2)]];'
|
||||
self.assertEqual(dmsh_geometry.capture_input(source),
|
||||
'device volatile _22* vertex_output [[id(1)]]; device _22* geometry_vb_output [[id(2)]];')
|
||||
self.assertEqual(dmsh_geometry.capture_input('kernel void main0() {}'), 'kernel void main0() {}')
|
||||
with self.assertRaisesRegex(ValueError, 'capture-input declaration'):
|
||||
dmsh_geometry.capture_input('unknown vertex_output;')
|
||||
|
||||
def test_ordinary_reader_is_unchanged(self):
|
||||
src = mask_reader().replace(' spvArrayCopyFromStackToStack(gl_BuiltIn_5253, as_type<int>(bits).elements);\n', '')
|
||||
self.assertEqual(dmsh_geometry.reader(src), src)
|
||||
|
||||
def test_unknown_mask_expression_is_rejected(self):
|
||||
for expression in ('gl_BuiltIn_5253[0] = 1;',
|
||||
'spvArrayCopyFromStackToStack(gl_BuiltIn_5253, as_type<int>(bits + 1.0).elements);'):
|
||||
with self.subTest(expression=expression), self.assertRaisesRegex(ValueError, 'viewport-mask expression'):
|
||||
dmsh_geometry.reader(mask_reader().replace(
|
||||
'spvArrayCopyFromStackToStack(gl_BuiltIn_5253, as_type<int>(bits).elements);', expression))
|
||||
|
||||
@unittest.skipUnless(sys.platform == 'darwin' and shutil.which('xcrun'), 'requires Metal on macOS')
|
||||
def test_mask_controls_viewport_zero_visibility(self):
|
||||
with tempfile.TemporaryDirectory(prefix='dmsh_geometry_raster_') as d:
|
||||
root = Path(d)
|
||||
source = root / 'reader.metal'; source.write_text(depth_entries(dmsh_geometry.reader(mask_reader())))
|
||||
library = root / 'reader.metallib'
|
||||
compiler = ['xcrun', '-sdk', 'macosx', 'metal', '-fmodules-cache-path=' + d + '/modules']
|
||||
r = subprocess.run([*compiler, '-c', str(source), '-o', str(root / 'reader.air')], capture_output=True, text=True)
|
||||
self.assertEqual(r.returncode, 0, r.stderr)
|
||||
subprocess.run(['xcrun', '-sdk', 'macosx', 'metallib', str(root / 'reader.air'), '-o', str(library)], check=True, capture_output=True)
|
||||
executable = root / 'raster'
|
||||
subprocess.run(['xcrun', 'clang', '-fobjc-arc', '-x', 'objective-c', '-', '-o', str(executable),
|
||||
'-framework', 'Foundation', '-framework', 'Metal'], input=RASTER_CHECK,
|
||||
text=True, check=True, capture_output=True)
|
||||
for entry in ('main0', 'main0_z'):
|
||||
with self.subTest(entry=entry):
|
||||
r = subprocess.run([str(executable), str(library), entry], capture_output=True, text=True)
|
||||
if r.returncode == 77:
|
||||
self.skipTest(r.stderr.strip())
|
||||
self.assertEqual(r.returncode, 0, r.stderr)
|
||||
|
||||
@unittest.skipUnless(shutil.which('xcrun'), 'requires the Metal compiler')
|
||||
def test_viewport_mask_reader_compiles(self):
|
||||
with tempfile.TemporaryDirectory(prefix='dmsh_geometry_test_') as d:
|
||||
src = Path(d) / 'reader.metal'
|
||||
src.write_text(dmsh_geometry.reader(mask_reader()))
|
||||
for sdk in ('macosx', 'iphoneos'):
|
||||
with self.subTest(sdk=sdk):
|
||||
r = subprocess.run(['xcrun', '-sdk', sdk, 'metal',
|
||||
'-fmodules-cache-path=' + d + '/modules', '-fsyntax-only', str(src)],
|
||||
capture_output=True, text=True)
|
||||
self.assertEqual(r.returncode, 0, r.stderr)
|
||||
|
||||
|
||||
def geometry_header(passthrough=True, vertices=1, topology=7, invocations=1):
|
||||
return struct.pack('<5I', int(passthrough) << 24, 0, invocations << 24, topology << 24, vertices)
|
||||
|
||||
|
||||
class GeometryOutputLayout(unittest.TestCase):
|
||||
def test_passthrough_uses_input_primitive_vertex_count(self):
|
||||
layouts = [dmsh_geometry.output_layout(geometry_header(), t) for t in range(5)]
|
||||
self.assertEqual([g['vertices'] for g in layouts], [1, 2, 2, 3, 3])
|
||||
self.assertEqual([g['index_stride'] for g in layouts], [2, 4, 4, 6, 6])
|
||||
self.assertEqual([g['output'] for g in layouts], [1, 6, 6, 7, 7])
|
||||
|
||||
def test_regular_geometry_retains_declared_bound(self):
|
||||
for t in range(5):
|
||||
self.assertEqual(dmsh_geometry.output_layout(geometry_header(False, 12, 6, 3), t),
|
||||
{'vertices': 12, 'invocations': 3, 'output': 6, 'index_stride': 24})
|
||||
|
||||
def test_invalid_header_or_topology_is_rejected(self):
|
||||
for code, t in ((b'', 0), (geometry_header(), 5), (geometry_header(), -1),
|
||||
(geometry_header(False, vertices=0), 0), (geometry_header(invocations=0), 0),
|
||||
(geometry_header(False, topology=3), 0)):
|
||||
with self.subTest(code=code, topology=t), self.assertRaises(ValueError):
|
||||
dmsh_geometry.output_layout(code, t)
|
||||
|
||||
@unittest.skipUnless(os.environ.get('DM_TEST_GEOMETRY'), 'set DM_TEST_GEOMETRY to the native t_geometry executable')
|
||||
def test_native_passthrough_canaries_and_compaction(self):
|
||||
layouts = [dmsh_geometry.output_layout(geometry_header(), t) for t in range(5)]
|
||||
with tempfile.TemporaryDirectory(prefix='geometry_bounds_') as d:
|
||||
path = Path(d) / 'layouts.json'; path.write_text(json.dumps(layouts))
|
||||
r = subprocess.run([os.environ['DM_TEST_GEOMETRY'], '--passthrough-layouts', str(path)], capture_output=True, text=True)
|
||||
self.assertEqual(r.returncode, 0, r.stdout + r.stderr)
|
||||
|
||||
|
||||
@unittest.skipUnless(os.environ.get('DMSH_TEST_XLATE'), 'set DMSH_TEST_XLATE to the offline translator')
|
||||
class PassthroughCompiler(unittest.TestCase):
|
||||
def test_passthrough_emits_positions_and_generic_attributes(self):
|
||||
from test_dmsh_reflect import REFLECT
|
||||
root = Path(__file__).resolve().parents[3]
|
||||
table = (root / 'dm/third_party/ryujinx/src/Ryujinx.Graphics.Shader/Decoders/InstTable.cs').read_text()
|
||||
pattern = re.search(r'Add\("([01x]{64})", InstName\.Exit\s*,', table)[1]
|
||||
exit_instruction = int(pattern.replace('x', '0'), 2) | (7 << 16) | 15
|
||||
with tempfile.TemporaryDirectory(prefix='geometry_passthrough_') as d:
|
||||
work = Path(d); jobs = []
|
||||
for t in range(5):
|
||||
header = bytearray(0x50)
|
||||
struct.pack_into('<5I', header, 0, (1 << 24) | (4 << 10) | (3 << 5) | 1,
|
||||
0, 1 << 24, 7 << 24, 1)
|
||||
code = work / f'pass{t}.bin'; code.write_bytes(header + struct.pack('<QQ', 0, exit_instruction))
|
||||
jobs.append(dict(key=f'pass{t}', stage='gs', code=str(code), geometry_topology=t,
|
||||
tex={}, img={}, attr={}, fout={}, debug=True, reduced=True))
|
||||
job_file = work / 'jobs.json'; job_file.write_text(json.dumps(jobs))
|
||||
r = subprocess.run([os.environ['DMSH_TEST_XLATE'], str(job_file), d], capture_output=True, text=True)
|
||||
self.assertEqual(r.returncode, 0, r.stdout + r.stderr)
|
||||
for t, job in enumerate(jobs):
|
||||
with self.subTest(topology=t):
|
||||
spv = work / f'pass{t}.spv'; dmsh_geometry.flatten_sets(spv)
|
||||
r = subprocess.run(['spirv-cross', '--msl', '--msl-version', '20300', '--msl-argument-buffers',
|
||||
'--msl-texture-buffer-native', str(spv)], capture_output=True, text=True)
|
||||
self.assertEqual(r.returncode, 0, r.stderr)
|
||||
src = dmsh_geometry.capture_input(dmsh_geometry.topology_pointer(r.stdout))
|
||||
self.assertTrue('geometry_vb_output' in src, 'passthrough kernel discarded its raster output')
|
||||
res = json.loads((work / f'pass{t}.res.json').read_text())
|
||||
layout = dmsh_geometry.output_layout((work / f'pass{t}.bin').read_bytes(), t)
|
||||
self.assertEqual(res['geometry_stride'], 133) # position, point size, all 32 float4 generic outputs
|
||||
reflection = dict(route='B', bindings=REFLECT('synthetic', 'gs', src, res),
|
||||
geometry=dict(layout, stride=res['geometry_stride']))
|
||||
(work / f'pass{t}.json').write_text(json.dumps(reflection))
|
||||
metal = work / f'pass{t}.metal'; metal.write_text(src)
|
||||
for sdk in ('macosx', 'iphoneos'):
|
||||
air = work / f'pass{t}.{sdk}.air'
|
||||
r = subprocess.run(['xcrun', '-sdk', sdk, 'metal', '-fmodules-cache-path=' + d + '/modules',
|
||||
'-c', str(metal), '-o', str(air)], capture_output=True, text=True)
|
||||
self.assertEqual(r.returncode, 0, r.stderr)
|
||||
subprocess.run(['xcrun', '-sdk', sdk, 'metallib', str(air), '-o', str(work / f'pass{t}.{sdk}.metallib')], check=True, capture_output=True)
|
||||
if os.environ.get('DM_TEST_GEOMETRY'):
|
||||
r = subprocess.run([os.environ['DM_TEST_GEOMETRY'], '--passthrough-kernels', d], capture_output=True, text=True)
|
||||
self.assertEqual(r.returncode, 0, r.stdout + r.stderr)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -0,0 +1,63 @@
|
||||
"""Production reflection conversion with synthetic translator descriptors."""
|
||||
import ast
|
||||
from pathlib import Path
|
||||
import re
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
TOOLS = Path(__file__).resolve().parents[1] / 'tools'
|
||||
sys.path.insert(0, str(TOOLS))
|
||||
import dmsh_geometry
|
||||
|
||||
|
||||
def builder_reflection():
|
||||
# Isolate pure reflection code from the builder's CLI/profile initialization.
|
||||
tree = ast.parse((TOOLS / 'dmsh_build.py').read_text())
|
||||
names = {'reflect', 'decode_tex', 'decode_ubo_tex', 'const_sampler', 'c2_array'}
|
||||
selected = [n for n in tree.body if (isinstance(n, ast.FunctionDef) and n.name in names)
|
||||
or (isinstance(n, ast.Assign) and any(isinstance(t, ast.Name) and t.id == 'SSBO' for t in n.targets))]
|
||||
ns = {'re': re, 'dmsh_geometry': dmsh_geometry}
|
||||
exec(compile(ast.Module(body=selected, type_ignores=[]), str(TOOLS / 'dmsh_build.py'), 'exec'), ns)
|
||||
return ns['reflect']
|
||||
|
||||
|
||||
REFLECT = builder_reflection()
|
||||
|
||||
|
||||
def bindings(stage, offsets, flags, cb_slot=0):
|
||||
source = 'struct spvDescriptorSetBuffer0\n{\n' + ''.join(
|
||||
f' device uint* gp_s{i} [[id({i})]];\n' for i in range(len(offsets))) + '};\n'
|
||||
res = {'sbufs': [{'binding': 40 + i, 'slot': i, 'cb_slot': cb_slot,
|
||||
'cb_offset': off // 4, 'flags': flag}
|
||||
for i, (off, flag) in enumerate(zip(offsets, flags))]}
|
||||
return REFLECT('synthetic', stage, source, res)
|
||||
|
||||
|
||||
class StorageBuffers(unittest.TestCase):
|
||||
def test_geometry_driver_table_offsets(self):
|
||||
got = bindings('gs', [0x410, 0x430], [1, 1])
|
||||
self.assertEqual([(b['kind'], b['reg']) for b in got], [('sbuf', 0), ('sbuf', 2)])
|
||||
|
||||
def test_write_flag_from_translator_json(self):
|
||||
# BufferUsageFlags.Write = 1 << 0; Program.cs serializes it unchanged.
|
||||
got = bindings('cs', [0x310, 0x320], [1, 0])
|
||||
self.assertEqual([b['rw'] for b in got], [True, False])
|
||||
|
||||
def test_write_flag_for_address_in_guest_uniform(self):
|
||||
got = bindings('gs', [0x38], [1], cb_slot=3)
|
||||
self.assertEqual((got[0]['kind'], got[0]['reg'], got[0]['off'], got[0]['rw']),
|
||||
('sbuf_ubo', 0, 0x38, True))
|
||||
|
||||
def test_existing_stage_tables(self):
|
||||
for stage, base in [('vs', 0x110), ('cs', 0x310), ('ps', 0x510)]:
|
||||
with self.subTest(stage=stage):
|
||||
got = bindings(stage, [base, base + 15 * 16], [0, 0])
|
||||
self.assertEqual([b['reg'] for b in got], [0, 15])
|
||||
|
||||
def test_unknown_or_unaligned_offsets_stay_unresolved(self):
|
||||
self.assertIsNone(bindings('gs', [0x414], [1])[0]['reg'])
|
||||
self.assertIsNone(bindings('hs', [0x410], [1])[0]['reg'])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -0,0 +1,58 @@
|
||||
"""PlatinumGames' binding-table shader objects, without game data."""
|
||||
from pathlib import Path
|
||||
import struct
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / 'tools'))
|
||||
import shader_split as split
|
||||
|
||||
|
||||
def object_data(stage):
|
||||
ctl, code = bytearray(0x880), bytearray(0x100)
|
||||
ctl[:4] = split.CTL_MAGIC
|
||||
struct.pack_into('<I', ctl, 0x20, len(ctl))
|
||||
struct.pack_into('<I', ctl, 0x704, len(code))
|
||||
code[:4] = split.CS_MAGIC if stage == 'cs' else split.GFX_MAGIC
|
||||
if stage != 'cs':
|
||||
struct.pack_into('<I', code, 0x30, (split.STAGES.index(stage) + 1) << 10 | 1)
|
||||
binding = struct.pack('<I', 0x88) + bytes([0xff]) * 0x84
|
||||
return binding + struct.pack('<I', len(code)) + code + struct.pack('<I', len(ctl)) + ctl, bytes(ctl), bytes(code)
|
||||
|
||||
|
||||
def archive(data):
|
||||
# One DAT member, exercising the recursive path used by the CPK scanner.
|
||||
name = b'test.pso\0'
|
||||
header = struct.pack('<4s6I', b'DAT\0', 1, 0x20, 0x24, 0x28, 0x38, 0)
|
||||
return (header.ljust(0x20, b'\0') + struct.pack('<I', 0x40) + b'pso\0'
|
||||
+ struct.pack('<I', len(name)) + name).ljust(0x38, b'\0') + struct.pack('<I', len(data)) + bytes(4) + data
|
||||
|
||||
|
||||
class BindingTableShaderTests(unittest.TestCase):
|
||||
def test_all_stages_through_dat_scan(self):
|
||||
for stage in split.STAGES:
|
||||
with self.subTest(stage=stage):
|
||||
data, ctl, code = object_data(stage)
|
||||
found = []
|
||||
split.scan_blob(archive(data), '/shader.dat', found)
|
||||
self.assertEqual(len(found), 1)
|
||||
self.assertEqual([(s, c, k) for _, s, c, k in found], [(stage, ctl, code)])
|
||||
self.assertIn('#PGSO', found[0][0])
|
||||
|
||||
def test_truncated_or_unrelated_data_is_not_a_shader(self):
|
||||
data = object_data('ps')[0]
|
||||
for bad in (data[:3], data[:0x8c], data[:-1], bytes(0x1000), struct.pack('<I', 0xffffffff) + data):
|
||||
with self.subTest(size=len(bad)):
|
||||
found = []
|
||||
split.scan_blob(bad, '/unrelated', found)
|
||||
self.assertEqual(found, [])
|
||||
|
||||
def test_control_and_code_lengths_must_agree(self):
|
||||
data = bytearray(object_data('vs')[0])
|
||||
struct.pack_into('<I', data, 0x8c + 0x100 + 4 + 0x704, 0x80)
|
||||
with self.assertRaisesRegex(SystemExit, 'code area length'):
|
||||
split.scan_blob(bytes(data), '/bad shader', [])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
+10
-14
@@ -56,9 +56,9 @@ def mac_compile(msl, air, lib): # same interface as ios_metal.compile
|
||||
# c2 0x120 + 8 r: images (nvnCommandBufferBindImage), slot r < 8
|
||||
# c2 0x168 + 8 r: separate textures (nvnCommandBufferBindSeparateTexture), reported as slot 128 + r, where the host binds them (hle_nvn.c, NVN_SEPTEX_SLOT0); Unity, Unreal and RE Engine bind these
|
||||
# c2 0x568 + 8 r: separate samplers (nvnCommandBufferBindSeparateSampler), slot r < 128
|
||||
# c0 base + 0x10 r: storage buffer r (64-bit address, 32-bit size), base vertex 0x110, compute 0x310, pixel 0x510 (the hull / domain stages' bases were never seen)
|
||||
# c0 base + 0x10 r: storage buffer r (64-bit address, 32-bit size), base vertex 0x110, compute 0x310, geometry 0x410, pixel 0x510 (the hull / domain stages' bases were never seen)
|
||||
TEX_BASE, IMG_BASE, IMG_SLOTS, SEPTEX_BASE, SEPTEX_SLOT0, SAMP_BASE = 0x20, 0x120, 8, 0x168, 128, 0x568
|
||||
SSBO = {'vs': 0x110, 'cs': 0x310, 'ps': 0x510}
|
||||
SSBO = {'vs': 0x110, 'cs': 0x310, 'gs': 0x410, 'ps': 0x510}
|
||||
|
||||
def records(d):
|
||||
r = [m.start() for m in re.finditer(b'BTCDBTCD', d)]
|
||||
@@ -484,7 +484,7 @@ def reflect(key, stage, msl, res):
|
||||
e['fetch1d'] = True
|
||||
if re.search(r'\b%s\.get_width\(' % re.escape(nm), msl): e['fetch1d_size'] = True # also size-queried: a texture buffer of more than 16384 elements reports 16384 there
|
||||
binds.append(e)
|
||||
# Storage buffers: SPIR-V binding number → c0 offset → NVN storage buffer slot (c0 base: vertex 0x110, compute 0x310, pixel 0x510, 0x10 per slot)
|
||||
# Storage buffers: SPIR-V binding number → c0 offset → NVN storage buffer slot (c0 base: vertex 0x110, compute 0x310, geometry 0x410, pixel 0x510, 0x10 per slot)
|
||||
base = SSBO.get(stage) # storage buffer base for the hull / domain stages has not been measured: a storage buffer there is reported with no slot
|
||||
sb_sorted = sorted(res['sbufs'], key=lambda b: b['binding'])
|
||||
for e in binds:
|
||||
@@ -496,7 +496,7 @@ def reflect(key, stage, msl, res):
|
||||
elif b and b['cb_slot'] >= 3: # the address is in the game's own uniform buffer c[n] = uniform slot n - 3 (Monster Hunter Rise's compute shaders: c3 + 0x38); the replay reads it there
|
||||
e.update(kind='sbuf_ubo', reg=b['cb_slot'] - 3, off=b['cb_offset'] * 4)
|
||||
else: e['reg'] = (off - base) // 16 if off is not None and base is not None and 0 <= off - base < 0x100 and (off - base) % 16 == 0 else None
|
||||
e['rw'] = bool(b and b['flags'] & 2)
|
||||
e['rw'] = bool(b and b['flags'] & 1) # BufferUsageFlags.Write; Program.cs serializes the translator enum unchanged (atomics count as writes too)
|
||||
return binds
|
||||
|
||||
DRV_FILL = {0: [(b, b + 0x100) for b in sorted(SSBO.values())], # c0: storage buffer address tables (vertex / compute / pixel, 16 slots × 0x10 each)
|
||||
@@ -749,28 +749,24 @@ def geometry_finish(key, w, j, c1):
|
||||
Resources retain logical NVN stage 2 even though Metal executes a kernel.
|
||||
"""
|
||||
code = open(j['code'], 'rb').read()
|
||||
w2, w3, w4 = struct.unpack_from('<3I', code, 8)
|
||||
nv, inv, topology = w4 & 4095, w2 >> 24, w3 >> 24 & 15
|
||||
if topology not in (1, 6, 7) or not nv or not inv:
|
||||
return 'geometry failed', 'invalid output declaration', None
|
||||
nidx = nv * 2 # one restart after every emitted vertex, including incomplete strips
|
||||
dmsh_geometry.output_layout(code, 0) # validate before running the translator
|
||||
jobs = [{**j, 'key': key + '_g' + str(t), 'geometry_topology': t} for t in range(5)]
|
||||
jp = os.path.join(w, key + '_geometry.json'); atomic_json(jp, jobs)
|
||||
rx = subprocess.run([XLATE, jp, w], capture_output=True, text=True)
|
||||
if rx.returncode: return 'geometry failed', rx.stderr.strip()[:160], None
|
||||
base = None
|
||||
for t, job in enumerate(jobs):
|
||||
layout = dmsh_geometry.output_layout(code, t)
|
||||
k = job['key']; spv = os.path.join(w, k + '.spv')
|
||||
dmsh_geometry.flatten_sets(spv)
|
||||
r = subprocess.run(['spirv-cross', *XC, spv], capture_output=True, text=True)
|
||||
if r.returncode: return 'geometry MSL failed', r.stderr.strip()[:160], None
|
||||
src = dmsh_geometry.topology_pointer(precise(dmsh_atomic.lower_msl(r.stdout)))
|
||||
src = dmsh_geometry.capture_input(dmsh_geometry.topology_pointer(precise(dmsh_atomic.lower_msl(r.stdout))))
|
||||
res = json.load(open(os.path.join(w, k + '.res.json')))
|
||||
refl = {'key': key + '_bg' + str(t), 'route': 'B', 'chain': CHAIN, 'dm_ctl': key,
|
||||
'source': f'{loc[key][0]}#{loc[key][1]}', 'pc_paired': pc_of[key], 'stage': 'gs',
|
||||
'entry': 'main0', 'msl_entry_kind': 'kernel', 'threadgroup_size': [32, 1, 1],
|
||||
'geometry': {'vertices': nv, 'invocations': inv, 'output': topology,
|
||||
'stride': res['geometry_stride'], 'index_stride': nidx},
|
||||
'geometry': dict(layout, stride=res['geometry_stride']),
|
||||
'c1': c1.hex(), 'notes': res['notes'], 'drv_reads': drv_reads(src), 'drv_unfillable': [],
|
||||
'bindings': reflect(key, 'gs', src, res), 'vertex_inputs': [], 'raster': {}}
|
||||
def save(suffix, text, meta):
|
||||
@@ -787,11 +783,11 @@ def geometry_finish(key, w, j, c1):
|
||||
spv = os.path.join(w, k + '.reader.spv'); dmsh_geometry.flatten_sets(spv)
|
||||
r = subprocess.run(['spirv-cross', *XC, spv], capture_output=True, text=True)
|
||||
if r.returncode: return 'geometry reader failed', r.stderr.strip()[:160], None
|
||||
reader = vs_layer(vs_init(precise(dmsh_atomic.lower_msl(r.stdout))))
|
||||
reader = vs_layer(vs_init(dmsh_geometry.reader(precise(dmsh_atomic.lower_msl(r.stdout)))))
|
||||
analysis, full = vs_depth(reader)
|
||||
meta = {'key': key + '_bgv', 'route': 'B', 'chain': CHAIN, 'dm_ctl': key,
|
||||
'stage': 'vs', 'entry': 'main0', 'entry_z': 'main0_z', 'msl_entry_kind': 'vertex',
|
||||
'geometry_reader': True, 'geometry_output': topology, 'c1': '', 'notes': [], 'drv_reads': {}, 'drv_unfillable': [],
|
||||
'geometry_reader': True, 'geometry_output': layout['output'], 'c1': '', 'notes': [], 'drv_reads': {}, 'drv_unfillable': [],
|
||||
'bindings': reflect(key, 'vs', analysis, {'sbufs': []}), 'vertex_inputs': [], 'raster': {}}
|
||||
save('_bgv', full, meta)
|
||||
return 'ok', '', base
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Translation chain tool fingerprints (written by dmsh_chain.py --update-lock; regenerate after changing tools and commit it)
|
||||
dmsh_xlate.dll 0d9b8700c85c7194
|
||||
Ryujinx.Graphics.Shader.dll eff19af935aefcdb
|
||||
Ryujinx.Common.dll b99db57e72c1fa16
|
||||
xlate_source 729b1339ce845abb
|
||||
dmsh_xlate.dll 770e81bc853cde4e
|
||||
Ryujinx.Graphics.Shader.dll 5c427183cb7ec561
|
||||
Ryujinx.Common.dll 50db51f83d8cb36d
|
||||
xlate_source af0a596483e1ec36
|
||||
spirv-cross d9dc197f061b42a5
|
||||
metal_macosx Apple metal version 32023.921 (metalfe-32023.921.6)
|
||||
metal_iphoneos Apple metal version 32023.921 (metalfe-32023.921.6)
|
||||
@@ -21,7 +21,7 @@ FILES = ['tools/dmsh_chain.py', 'tools/dmsh_build.py', 'tools/dmsh_atomic.py', '
|
||||
FILES += ['../third_party/ryujinx/src/Ryujinx.Graphics.Shader/' + f for f in (
|
||||
'Instructions/InstEmitSurface.cs', 'IntermediateRepresentation/TextureFlags.cs',
|
||||
'Translation/TranslationFlags.cs', 'Translation/HostCapabilities.cs',
|
||||
'Translation/TranslatorContext.cs', 'CodeGen/Spirv/Instructions.cs',
|
||||
'Translation/TranslatorContext.cs', 'Translation/EmitterContext.cs', 'Translation/ShaderDefinitions.cs', 'CodeGen/Spirv/Instructions.cs',
|
||||
'StructuredIr/ShaderProperties.cs', 'Translation/Optimizations/BindlessElimination.cs')]
|
||||
INPUT_TABLES = ['shader_facts.tsv', 'shader_map.tsv', 'shader_map.tsv.conflicts.tsv', 'shader_pairs.tsv', 'bf_want.tsv'] # in the game profile folder
|
||||
LOCK = os.path.join(HERE, 'dmsh_chain.lock'); HEADER = os.path.join(GFX, 'nvn/dmsh_chain.h')
|
||||
|
||||
@@ -15,6 +15,66 @@ HELPERS = {'vertex_output': 0, 'geometry_vb_output': 1,
|
||||
'vb_input': 1}
|
||||
|
||||
|
||||
def output_layout(code, input_topology):
|
||||
"""Geometry output bounds in the translator's fixed-input compute ABI."""
|
||||
if len(code) < 20 or input_topology not in range(5):
|
||||
raise ValueError('invalid geometry header or input topology')
|
||||
w2, w3, w4 = struct.unpack_from('<3I', code, 8)
|
||||
vertices, invocations, topology = w4 & 4095, w2 >> 24, w3 >> 24 & 15
|
||||
# ShaderDefinitions overrides a passthrough GS's raw SPH bound with the
|
||||
# non-adjacent input vertex count. Match that override for every topology;
|
||||
# raw bounds can be 1 even when a triangle kernel writes three vertices and
|
||||
# six index words per invocation (including restart padding).
|
||||
if struct.unpack_from('<I', code)[0] & (1 << 24):
|
||||
vertices = (1, 2, 2, 3, 3)[input_topology]
|
||||
topology = (1, 6, 6, 7, 7)[input_topology]
|
||||
if topology not in (1, 6, 7) or not vertices or not invocations:
|
||||
raise ValueError('invalid geometry output declaration')
|
||||
return {'vertices': vertices, 'invocations': invocations, 'output': topology,
|
||||
'index_stride': vertices * 2}
|
||||
|
||||
|
||||
def reader(src):
|
||||
"""Preserve viewport-zero culling in the generated raster vertex reader.
|
||||
|
||||
ResourceReservations stores ViewportMask as one word, but the passthrough
|
||||
generator treats it as scalar while IoMap declares int[1]. SPIRV-Cross then
|
||||
emits this invalid array copy for builtin 5253 (ViewportMaskNV). Metal has
|
||||
no viewport-mask output. Replay binds viewport zero only, so its bit is the
|
||||
visibility decision: a zero moves the vertex beyond the X clip plane, which
|
||||
still culls when depth clamping is enabled. The mask must agree across a
|
||||
primitive, as for portable NV viewport-mask output; broadcasting to other
|
||||
viewports is not implemented.
|
||||
Unknown expressions are rejected rather than losing their culling effect.
|
||||
"""
|
||||
builtin = 'gl_BuiltIn_5253'
|
||||
if builtin not in src:
|
||||
return src
|
||||
store = re.compile(r'\bspvArrayCopyFromStackToStack\(\s*' + builtin
|
||||
+ r'\s*,\s*as_type<int>\((\w+)\)\.elements\s*\);')
|
||||
lowered, n = store.subn(r'dm_gs_viewport_mask = as_type<uint>(\1);', src)
|
||||
if not n or builtin in lowered or 'dm_gs_viewport_mask' in src:
|
||||
raise ValueError('geometry reader: unsupported viewport-mask expression')
|
||||
output = re.search(r'struct main0_out\s*\{(.*?)\};', lowered, re.S)
|
||||
position = re.search(r'\bfloat4 (\w+) \[\[position(?:, invariant)?\]\];', output[1]) if output else None
|
||||
entry = re.search(r'\bvertex\s+main0_out\s+main0\s*\([^{}]*\)\s*\{', lowered)
|
||||
if not position or not entry:
|
||||
raise ValueError('geometry reader: missing vertex position or entry')
|
||||
begin, depth, end = entry.end(), 1, entry.end()
|
||||
while depth and end < len(lowered):
|
||||
depth += (lowered[end] == '{') - (lowered[end] == '}')
|
||||
end += 1
|
||||
if depth:
|
||||
raise ValueError('geometry reader: unterminated vertex entry')
|
||||
body = lowered[begin:end - 1]
|
||||
if body.count('dm_gs_viewport_mask') != n or 'return out;' not in body:
|
||||
raise ValueError('geometry reader: viewport mask outside the vertex entry')
|
||||
body = body.replace('return out;',
|
||||
'{ if ((dm_gs_viewport_mask & 1u) == 0u) '
|
||||
f'out.{position[1]} = float4(2.0, 0.0, 0.0, 1.0); return out; }}')
|
||||
return lowered[:begin] + '\n uint dm_gs_viewport_mask = 1u;' + body + lowered[end - 1:]
|
||||
|
||||
|
||||
def capture(src):
|
||||
"""Append a rasterizer-discard vertex entry to the unmodified-depth source."""
|
||||
m = re.search(r'\bvertex main0_out main0\((.*?)\)\s*\{', src, re.S)
|
||||
@@ -80,7 +140,8 @@ def capture(src):
|
||||
|
||||
def flatten_sets(path):
|
||||
"""Give auxiliary sets their own binding ranges in the ordinary set-0 ABI."""
|
||||
data = open(path, 'rb').read()
|
||||
with open(path, 'rb') as f:
|
||||
data = f.read()
|
||||
w = list(struct.unpack('<%dI' % (len(data) // 4), data))
|
||||
sets, bindings = {}, {}
|
||||
i = 5
|
||||
@@ -98,7 +159,8 @@ def flatten_sets(path):
|
||||
raise ValueError('unknown geometry auxiliary descriptor set')
|
||||
w[bindings[ident]] += 10000 if s == 1 else 11000
|
||||
w[at] = 0
|
||||
open(path, 'wb').write(struct.pack('<%dI' % len(w), *w))
|
||||
with open(path, 'wb') as f:
|
||||
f.write(struct.pack('<%dI' % len(w), *w))
|
||||
|
||||
|
||||
def topology_pointer(src):
|
||||
@@ -122,3 +184,20 @@ def topology_pointer(src):
|
||||
if 'trb_data.read' in src:
|
||||
raise ValueError('unconverted geometry topology read')
|
||||
return src
|
||||
|
||||
|
||||
def capture_input(src):
|
||||
"""Keep the full Maxwell capture map readable by optimized Metal kernels.
|
||||
|
||||
Copying all 128 contiguous generic components can make Metal's optimized
|
||||
AIR fail AGX pipeline compilation. Volatile capture reads retain each scalar
|
||||
load without changing the captured values or disabling kernel optimization.
|
||||
Ordinary geometry kernels which do not read captured input stay unchanged.
|
||||
"""
|
||||
if 'vertex_output' not in src:
|
||||
return src
|
||||
lowered, n = re.subn(r'\bdevice (\w+)\* vertex_output\b',
|
||||
r'device volatile \1* vertex_output', src)
|
||||
if n != 1:
|
||||
raise ValueError('unknown geometry capture-input declaration')
|
||||
return lowered
|
||||
@@ -107,6 +107,9 @@ static class SwshXlate
|
||||
public int QueryComputeSharedMemorySize() => _job["shared"] is JsonNode n ? (int)n : 0; // the shared memory size in the compute shader's control section (shader_split.py)
|
||||
static AttributeType Attr(string s) => s switch { "sint" => AttributeType.Sint, "uint" => AttributeType.Uint, _ => AttributeType.Float };
|
||||
public bool QueryGeometryInputFixed() => _job["geometry_topology"] != null;
|
||||
// Compute lowering must emit passthrough vertices explicitly: Metal
|
||||
// cannot supply the native NV geometry-passthrough stage afterwards.
|
||||
public bool QueryHostSupportsGeometryShaderPassthrough() => _job["geometry_topology"] == null;
|
||||
public GpuGraphicsState QueryGraphicsState()
|
||||
{
|
||||
Array32<AttributeType> attr = default; Array8<AttributeType> fout = default;
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,11 +1,12 @@
|
||||
{
|
||||
"runtimeTarget": {
|
||||
"name": ".NETCoreApp,Version=v10.0",
|
||||
"name": ".NETCoreApp,Version=v10.0/osx-arm64",
|
||||
"signature": ""
|
||||
},
|
||||
"compilationOptions": {},
|
||||
"targets": {
|
||||
".NETCoreApp,Version=v10.0": {
|
||||
".NETCoreApp,Version=v10.0": {},
|
||||
".NETCoreApp,Version=v10.0/osx-arm64": {
|
||||
"dmsh_xlate/1.0.0": {
|
||||
"dependencies": {
|
||||
"Ryujinx.Common": "1.0.0",
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -29,6 +29,7 @@
|
||||
# · PKZ (PlatinumGames, Bayonetta 3): shader objects (VSO / PSO / CSO / HSO / DSO, a control section and a code area each) in the DAT archives of the PKZ entries (Oodle Kraken, decoded by the
|
||||
# game's own decoder in the Mac host), see pkz_entries, pgdat_members and pg_shader
|
||||
# · CPK (CRI's file system, Bayonetta 2): BNSH files ('.vso' / '.pso') in the PlatinumGames DAT archives of the CPK entries (CRILAYLA entries, cpk.py), see cpk_jobs
|
||||
# NieR:Automata's DAT members instead prefix length-delimited NVN code and control sections with a binding table (pg_sized_shader)
|
||||
# · HNSHV002 (Needle, Persona 5 Royal): NVN section descriptors in the shader containers embedded in main and the GSC files of its CPK archives, see needle_shaders
|
||||
# · GFPAK (Game Freak, Pokémon Sword): BNSH entries of the archives under bin/archive (LZ4 entries), see gfpak_members
|
||||
# · .tfxo (Silicon Studio's YEBIS post effects, Pokémon Sword): control sections each followed by its code area, in a zlib stream in main, see tfxo_streams and tfxo_shaders
|
||||
@@ -527,6 +528,25 @@ def pg_shader(d, label):
|
||||
if why: red(f'{label} ({st}): {why}')
|
||||
return [(f'{label}#PGSO', st, ctl, code)]
|
||||
|
||||
def pg_sized_shader(d, label):
|
||||
"""PlatinumGames' binding-table form: u32 prefix length (including itself), bindings, u32 code length, code, u32 control length, control. NieR:Automata's 1,371 objects in five DATs
|
||||
all have a 0x88-byte prefix and 0x880 control bytes; keys match the objects passed to NVN at boot. Recognize the section boundaries and NVN magics, without relying on a title or filename."""
|
||||
if len(d) < 12: return []
|
||||
prefix = struct.unpack_from('<I', d)[0]
|
||||
if prefix < 4 or prefix & 3 or prefix + 8 > len(d): return []
|
||||
ncode = struct.unpack_from('<I', d, prefix)[0]
|
||||
codeoff, ctlsize = prefix + 4, prefix + 4 + ncode
|
||||
if ncode < 0x80 or ctlsize + 4 > len(d) or d[codeoff:codeoff + 4] not in (GFX_MAGIC, CS_MAGIC): return []
|
||||
nctl = struct.unpack_from('<I', d, ctlsize)[0]
|
||||
ctloff = ctlsize + 4
|
||||
if nctl < 0x760 or ctloff + nctl != len(d) or d[ctloff:ctloff + 4] != CTL_MAGIC: return []
|
||||
ctl, code = d[ctloff:], d[codeoff:ctlsize]
|
||||
st = 'cs' if code[:4] == CS_MAGIC else sph_stage(code)
|
||||
if st is None: red(f'{label}: binding-table shader has an unknown SPH stage')
|
||||
why = check(label, st, ctl, code)
|
||||
if why: red(f'{label} ({st}): {why}')
|
||||
return [(f'{label}#PGSO', st, ctl, code)]
|
||||
|
||||
MTARC, MTSPK = b'ARC\0', b'SPK\0'
|
||||
def mtarc_members(d, label):
|
||||
"""Capcom's MT Framework archive (The Great Ace Attorney Chronicles: 447 '.arc' files under nativeNXx64): 'ARC\\0', u16 version 7, u16 entry count, then one 0x90-byte entry per file
|
||||
@@ -1526,6 +1546,7 @@ def scan_blob(d, label, out):
|
||||
for nm, m in mem: scan_blob(m, f'{label}/{nm}', out)
|
||||
return
|
||||
if d[:4] in PG_STAGES and len(d) >= 0x18 and d[(o := struct.unpack_from('<I', d, 0xc)[0]):o + 4] == CTL_MAGIC: out.extend(pg_shader(d, label)); return
|
||||
if shaders := pg_sized_shader(d, label): out.extend(shaders); return
|
||||
for m in re.finditer(b'BNSH\0\0\0\0', d):
|
||||
size = struct.unpack_from('<I', d, m.start() + 0x1c)[0]
|
||||
if m.start() + size <= len(d) and d[m.start() + 0x60:m.start() + 0x64] == b'grsc': out.extend(bnsh_shaders(d, m.start(), label))
|
||||
|
||||
Vendored
+2
@@ -9,5 +9,7 @@ Three projects from Ryujinx 1.3.2: `Ryujinx.Graphics.Shader`, `Ryujinx.Common` a
|
||||
|
||||
- `Ryujinx.Graphics.Shader/Instructions/InstEmitTexture.cs`, `EmitTex` (TLD 1D with integer coordinates only) and `EmitTexs` (TLDS `Texture1DLodZero`), with `IGpuAccessor.RecordTexelFetch1D`: Maxwell reads a 1D texture and a texture buffer with the same instruction, and the bound descriptor decides. When the texture type query does not answer "buffer", the read is translated as 2D at `(x & 0x3FFF, x >> 14)` instead of `(x, 0)`, and the handle is reported. A 1D texture (one row at most 16384 wide on the host) reads the same; the host binds a texture buffer in such a slot as a linear 2D texture of 16384-texel rows over its memory (`nvn_mtl.m` `tbuf_as_2d`). Upstream read `(x, 0)` and the host had only a dummy texture to give: the light and decal lists of Age of Calamity (at least 15,000 shaders) and Three Houses read zeros (2026-10-21). Marked `nxnative:` in the code.
|
||||
|
||||
- `Ryujinx.Graphics.Shader/Translation/EmitterContext.cs` and `Translation/ShaderDefinitions.cs`: fixed-input compute lowering explicitly forwards passthrough positions and all captured generic attributes not replaced by the geometry shader, and inherits its output primitive from input topology. Independent offline stages have no next-stage usage mask, and Metal cannot provide the native NV passthrough raster stage. See [passthrough compute emission](../../../docs/reference/shaders.md#passthrough-geometry-kernels-lose-raster-vertices) and [output bounds](../../../docs/reference/shaders.md#passthrough-geometry-output-bounds-follow-input-topology).
|
||||
|
||||
The shader translation tool in `dm/gfx/tools/dmsh_xlate` references them to translate the original Switch shaders to SPIR-V.
|
||||
License: MIT, see `LICENSE.txt`. Upstream: <https://github.com/Ryubing>.
|
||||
+7
-1
@@ -426,7 +426,13 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||
{
|
||||
WritePositionOutput(primIndex);
|
||||
|
||||
int passthroughAttributes = TranslatorContext.AttributeUsage.PassthroughAttributes;
|
||||
// Independently compiled fixed-input stages meet through
|
||||
// the complete Maxwell map, with no linked next-stage
|
||||
// usage to populate PassthroughAttributes. Preserve every
|
||||
// captured generic output the GS did not replace.
|
||||
int passthroughAttributes = TranslatorContext.GpuAccessor.QueryGeometryInputFixed()
|
||||
? ~TranslatorContext.AttributeUsage.UsedOutputAttributes
|
||||
: TranslatorContext.AttributeUsage.PassthroughAttributes;
|
||||
while (passthroughAttributes != 0)
|
||||
{
|
||||
int index = BitOperations.TrailingZeroCount(passthroughAttributes);
|
||||
|
||||
+9
-1
@@ -156,7 +156,15 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||
_graphicsState = graphicsState;
|
||||
GpPassthrough = gpPassthrough;
|
||||
ThreadsPerInputPrimitive = threadsPerInputPrimitive;
|
||||
OutputTopology = outputTopology;
|
||||
// Native geometry passthrough inherits the input primitive; its
|
||||
// SPH output declaration is unused. Compute emulation must expose
|
||||
// the same primitive to index compaction and raster replay.
|
||||
OutputTopology = gpPassthrough ? graphicsState.Topology switch
|
||||
{
|
||||
InputTopology.Points => OutputTopology.PointList,
|
||||
InputTopology.Lines or InputTopology.LinesAdjacency => OutputTopology.LineStrip,
|
||||
_ => OutputTopology.TriangleStrip,
|
||||
} : outputTopology;
|
||||
MaxOutputVertices = gpPassthrough ? graphicsState.Topology.InputVertexCountNoAdjacency : maxOutputVertices;
|
||||
ImapTypes = imapTypes;
|
||||
OmapTargets = omapTargets;
|
||||
|
||||
@@ -207,6 +207,7 @@ One line per symptom in the [subsystem references](../reference/): what you see
|
||||
|
||||
- a 30 fps game to run at 60; after the floor was lowered, slow motion on a GPU-bound device (GitHub issue #9). → [sead's dynamic present interval, `ksys::VFR` and the host's frame step](../reference/frame-rate.md#seads-dynamic-present-interval-ksysvfr-and-the-hosts-frame-step)
|
||||
- slow motion when the GPU is the bottleneck: a game's interval controller that times the GPU never steps up (GitHub issue #9). → [GPU timestamps per submission segment](../reference/frame-rate.md#gpu-timestamps-per-submission-segment)
|
||||
- GPU time reads 32 times too small when a game converts raw NVN counter timestamps itself. → [Raw NVN timestamp units](../reference/frame-rate.md#raw-nvn-timestamp-units)
|
||||
- the game presents at interval 1, yet every frame takes exactly 33.3 ms of "frame work"; after only the limiter was raised, everything ran twice as fast on the iPhone. → [A render-thread limiter with a constant and a fixed time step](../reference/frame-rate.md#a-render-thread-limiter-with-a-constant-and-a-fixed-time-step)
|
||||
- 55 fps with every frame 18.2 ms, the main thread asleep most of the time; every 11th frame stays on screen two vsyncs. → [A frame-end wait polled in 2 ms sleeps](../reference/frame-rate.md#a-frame-end-wait-polled-in-2-ms-sleeps)
|
||||
- the app is active and the game keeps running, but the picture freezes while display-link callbacks stop; the log repeatedly drops queued frames. → [Present thread rescues a silent display link](../reference/frame-rate.md#present-thread-rescues-a-silent-display-link)
|
||||
@@ -351,6 +352,7 @@ One line per symptom in the [subsystem references](../reference/): what you see
|
||||
- an NVN game's split finds none of its shipped shaders, and the ones it compiles at run time were not captured: the game's renderer is in NROs that call `glslcCompile`, and its whole RomFS is one zip. → [GLSLC outputs in a zip archive, and those NROs compile at run time](../reference/shaders.md#glslc-outputs-in-a-zip-archive-and-those-nros-compile-at-run-time)
|
||||
- 24 shaders before the control-length fix, 1,355 after. → [SPKG packages in KTGL LINKDATA](../reference/shaders.md#spkg-packages-in-ktgl-linkdata)
|
||||
- `[RED] ... PKZ version 0x10000: only 0x20000 is known` stops the shader split. → [PKZ version 1 archives](../reference/shaders.md#pkz-version-1-archives)
|
||||
- the split finds zero shaders and refuses the shader build, although the CPK's DAT archives contain the objects passed to NVN at boot. → [Size-delimited PlatinumGames shader objects](../reference/shaders.md#size-delimited-platinumgames-shader-objects)
|
||||
- the split finds no shaders, although `main` contains NVN control sections; it reports that no data record or code-address pair identifies their code areas. → [Needle shader containers in main and GFD archives](../reference/shaders.md#needle-shader-containers-in-main-and-gfd-archives)
|
||||
- shaders the game draws are missing from the map (`DM_NVN_SHDUMP`), in no RomFS file and no module, stored or LZ4, and not compiled at run time. → [Shaders in a zlib stream in main (YEBIS .tfxo)](../reference/shaders.md#shaders-in-a-zlib-stream-in-main-yebis-tfxo)
|
||||
- two `[RED] shader … is not in the shader map` lines and `program has no vertex shader` as the opening movie starts; every movie drew white. → [Loose control sections and code areas in main (Bink 2)](../reference/shaders.md#loose-control-sections-and-code-areas-in-main-bink-2)
|
||||
@@ -373,10 +375,17 @@ One line per symptom in the [subsystem references](../reference/): what you see
|
||||
- `SPIRV-Cross threw an exception: Subgroup builtins are not available in this type of function`. → [Subgroup operations rewritten for a one-lane subgroup](../reference/shaders.md#subgroup-operations-rewritten-for-a-one-lane-subgroup)
|
||||
- the tone mapper read an empty LUT and the screen came out a flat blue. → [Geometry shaders that only pick the layer](../reference/shaders.md#geometry-shaders-that-only-pick-the-layer)
|
||||
- a geometry shader fails to compile with `unknown main0_out`: SPIRV-Cross writes `unknown main0_out main0()` for the geometry stage, and the shader does not build. → [Geometry shaders with no Metal stage](../reference/shaders.md#geometry-shaders-with-no-metal-stage)
|
||||
- the geometry kernel compiles, but its `_bgv.metal` vertex reader fails with `use of undeclared identifier 'gl_BuiltIn_5253'` and `member reference base type 'int' is not a structure or union`. → [Geometry reader viewport masks](../reference/shaders.md#geometry-reader-viewport-masks)
|
||||
- a passthrough geometry kernel writes beyond its vertex and raw-index scratch regions, and compaction reads the wrong groups; corruption can reach the following primitive-map buffers without a red diagnostic. → [Passthrough geometry output bounds follow input topology](../reference/shaders.md#passthrough-geometry-output-bounds-follow-input-topology)
|
||||
- a geometry kernel compiles and runs its storage-buffer side effects, but contains no `geometry_vb_output` binding and fills its index stream with restart markers; its following raster pass draws no geometry. → [Passthrough geometry kernels lose raster vertices](../reference/shaders.md#passthrough-geometry-kernels-lose-raster-vertices)
|
||||
- geometry-heavy frames have a large submission wall/CPU gap despite short GPU execution; stack samples spend most of the main thread in `geo_draw` → `mdi_wait` → shared-event wait, with index sorting another substantial cost. → [Geometry capture waits for every indexed draw](../reference/shaders.md#geometry-capture-waits-for-every-indexed-draw)
|
||||
- geometry-heavy frames remain GPU-bound after CPU readback waits are removed; encoder timestamps attribute most compaction time to the offset scan rather than the geometry shader or index writes. → [Geometry compaction serial prefix scan](../reference/shaders.md#geometry-compaction-serial-prefix-scan)
|
||||
- `[RED] geometry draw needs 261 MiB of scratch, above the 256 MiB bound` (or `exceeds the capture or invocation bound`); the draw is skipped. → [Geometry draws above the capture scratch bound](../reference/shaders.md#geometry-draws-above-the-capture-scratch-bound)
|
||||
- `primitive type 14 not implemented`; patch draws skipped. → [Tessellation stages are not drawn](../reference/shaders.md#tessellation-stages-are-not-drawn)
|
||||
- a vertex or compute shader reads zeros from NVN's driver segment `c0`. → [Driver-segment reads outside fragment shaders](../reference/shaders.md#driver-segment-reads-outside-fragment-shaders)
|
||||
- flickering hard-edged white tiles (tiled lighting with every tile row getting row 0's or other rows' lights). → [Compute `c0`: dispatch size and uniform buffer table](../reference/shaders.md#compute-c0-dispatch-size-and-uniform-buffer-table)
|
||||
- `[RED] shader ... reflection conversion failed: B binding gp_s0 has no resolved slot number`; a geometry shader reading driver segment `c0` reports that its storage-buffer table base was never measured. → [Geometry-stage storage buffer table](../reference/shaders.md#geometry-stage-storage-buffer-table)
|
||||
- a storage buffer the shader stores to or uses atomically has `rw: false` in its generated reflection; replay does not record its GPU writes for dependent buffer reads. → [Storage-buffer write flag in translation metadata](../reference/shaders.md#storage-buffer-write-flag-in-translation-metadata)
|
||||
- point sprites of size 0 (Odyssey's Cap Kingdom fog never parted around Mario). → [Graphics `c0 + 0x610`: the largest point size](../reference/shaders.md#graphics-c0--0x610-the-largest-point-size)
|
||||
- occlusion queries that always return 0 samples (Z-A: characters' legs folded back from the hips once they walked); every instanced draw's transform taken for instance 0. → [Graphics `c0 + 0x644`: the draw's base instance](../reference/shaders.md#graphics-c0--0x644-the-draws-base-instance)
|
||||
- a menu's labels drawn as plain bars, other menus empty except for the cursor (one pool's textures overwritten by another's); a black screen when IDs past a fixed table read as empty slots. → [Texture and sampler pools with overlapping IDs](../reference/shaders.md#texture-and-sampler-pools-with-overlapping-ids)
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 2.2 MiB |
@@ -20,6 +20,14 @@ Frame pacing: the host's frame step, engine frame limiters, present intervals an
|
||||
- **Fix:** the profile key `gpu_timestamps segment` makes each report take the GPU start (`TIMESTAMP_TOP`) or end (other types) of the `sub_cut` segment ([Submissions handed to the GPU in segments](#submissions-handed-to-the-gpu-in-segments)) it was encoded in (`rep_ticks` in `nvn_mtl.m`: MTL4CommitFeedback times converted to the guest clock, written in the last segment's handler as before). `DM_NVN_GPU_TS=submission` gives the old timestamps.
|
||||
- **Found on:** [The Legend of Zelda: Breath of the Wild](../../dm/games/01007EF00011E000/README.md) (legacy frame-step method): BotW's frame has 5 reports in one submission (`main+0xe94584`, `main+0xe94664`); with two more cuts the controller always takes the GPU path, and the GPU time now reads the frame's GPU span, gaps where the GPU waits for the host's translation included. Measured on the Mac with two BotW runs sharing the GPU under a heavy CPU load (load average about 75, a shader rebuild running): GPU time p50 16–23 ms; the fixed run stayed at interval 2 (3 while the GPU time passed 1.9 vsyncs, 1 for under 2% of the frames) at 0.93–0.98 of real time, while a run with `DM_NVN_GPU_TS=submission` spent 10–70% of its frames at interval 1 and ran at 0.78–0.95. The same GPU time drives the game's dynamic resolution.
|
||||
|
||||
### Raw NVN timestamp units
|
||||
|
||||
- **Symptom:** GPU time reads 32 times too small when a game converts raw NVN counter timestamps itself.
|
||||
- **Cause:** the host wrote reports in 19.2 MHz CPU ticks, while the raw NVN timestamp field uses 614.4 MHz ticks (384 ticks per 625 ns). Games calling `nvnDeviceGetTimestampInNanoseconds` saw correct time because its inverse conversion had the same wrong rate, but an inline conversion read a 16 ms span as 0.5 ms.
|
||||
- **Fix:** `nvn_timestamp.h` shares the 614.4 MHz conversions between all report writes (`gpu_ticks`, `rep_ticks`) and `nvnDeviceGetTimestampInNanoseconds`. Wide integer products preserve long uptimes. The guest clock epoch stays the same; CPU system counters stay at 19.2 MHz, and the API still returns nanoseconds.
|
||||
- **Found on:** [NieR:Automata The End of YoRHa Edition](../../dm/games/010056B015FE8000/README.md), whose dynamic-resolution controller subtracts two raw report timestamps and converts the difference inline.
|
||||
- **Check:** `t_timestamp` checks known vectors, long uptimes, round-trip precision and the game's exact inline arithmetic. `t_nvn` checks the API's known units and bounds a completed report between submit and fence wait.
|
||||
|
||||
## Engine frame limiters
|
||||
|
||||
### A render-thread limiter with a constant and a fixed time step
|
||||
|
||||
@@ -232,6 +232,7 @@ Games read this count as a position in their own command memory and size their h
|
||||
- **Cause:** the decoder's NV12 output is copied by the game into textures in a CPU-visible pool and published with `nvnMemoryPoolFlushMappedRange`, which the host did not take as an upload.
|
||||
- **Fix:** the profile key `tex_flush_upload`. Buffer textures stay out of that path: they are views onto the pool buffer, and an upload would have sent them past Metal's 2D size limit.
|
||||
- **Found on:** [Hyrule Warriors: Age of Calamity](../../dm/games/01002B00111A2000/README.md): a 1280×720 R8 and a 640×360 RG8 texture; the buffer texture kept out is a 1,048,576-texel R32F one.
|
||||
- **Also found on:** [NieR:Automata The End of YoRHa Edition](../../dm/games/010056B015FE8000/README.md): the title background; the game note records the controlled comparison.
|
||||
|
||||
### CPU writes with no flush, caught by page protection (`tex_dirty_upload`)
|
||||
|
||||
|
||||
@@ -261,7 +261,8 @@ The replay on Metal (`dm/gfx/nvn/nvn_mtl.m`) and the Vulkan and OpenGL layers. E
|
||||
|
||||
- **Symptom:** solid magenta blocks, exactly (255, 0, 255), hard-edged and aligned to the 16-pixel grid (16×16, sometimes two stacked): Super Mario 3D World showed them only on the iPhone; Captain Toad on a Mac, Apple M6, in about half the frames of the opening course, moving with the falling leaves.
|
||||
- **Cause:** a program writes an attachment while sampling it (agl's post-effect program writes the 1920x1080 RGB10A2 image as an attachment while sampling it). Writing and sampling one attachment within a render pass is undefined in Metal: the M4 Pro happens to return the old content, while the A20 Pro now and then returns whole 16×16 blocks as (1, 0, 1), probably blocks of the compressed render target caught mid-write. On the Switch the read returns the content from before the draw.
|
||||
- **Fix:** for the fragment shaders the profile's `feedback_snap` key lists, the host ends the pass before such a draw, copies the attachment's level and layer into a snapshot texture in the replay stream, and binds the snapshot for that draw (`fb_prepare` in `nvn_mtl.m`). A sampled view that spans more levels than the attachment's one is left as before with a red line.
|
||||
- **Fix:** for the fragment shaders the profile's `feedback_snap` key lists, the host ends the pass before such a draw, copies the attachment's level and layer into a snapshot texture in the replay stream, and binds the snapshot for that draw (`fb_prepare` in `nvn_mtl.m`). The binding scan covers combined slots 0–127 and separate texture slots 128–255 (`NTEX`), using the argument encoder's handle lookup; an earlier bound of 128 silently skipped separate bindings even for a listed shader. A sampled view that spans more levels than the attachment's one is left as before with a red line.
|
||||
- **Check:** `make -C dm/gfx/tests GAME=<id> check_t_feedback` exercises the production snapshot and argument encoder at slots 0, 128 and 255. GPU readback must retain a red snapshot after the original attachment is overwritten green, then read the green original on the next draw. The old slot bound fails 10 of 56 checks; the corrected bound passes all 56 with Metal API validation on the M4 Pro.
|
||||
- **Found on:**
|
||||
- [Super Mario 3D World + Bowser's Fury](../../dm/games/010028600EBDA000/README.md): `DM_NVN_MAGSCAN` on the A20 Pro found the blocks first in the 1920×1080 RGB10A2 composite (`ser=30`) in World 1-1, in the pass whose shader `66a71a3081b91b9a` renders into that texture while sampling it. They kept appearing with the sparkle particle `5e4de7561c670fee` dropped, so that earlier suspect (picked by position) is not the cause. `feedback_snap` lists `66a71a3081b91b9a` and `30e3ccb0bd304ead` (which samples a G-buffer target of its own pass on the title screen); in 1-1 that is one 8 MB copy per frame. `3e8567da37eb28a1` renders level 1 of a texture while its view covers levels 0–4 (mip-chain passes) and keeps the red line. The source said the fix was in place and waiting for a device run when written; the README lists the game as tested and playable on the iPhone.
|
||||
- [Captain Toad: Treasure Tracker](../../dm/games/01009BF0072D4000/README.md): agl's post-effect program 987 (`54f58a7cab608766`, the same program as 3D World's `66a71a3081b91b9a` in another build); `DM_NVN_FB_SNAP=all` cleared every frame and named this one shader, now in the profile's `feedback_snap`.
|
||||
|
||||
@@ -128,6 +128,13 @@ Finding, keying and translating shaders (`dm/gfx/tools/shader_split.py`, `dmsh_b
|
||||
- PlatinumGames' shader objects: `VSO\0` / `PSO\0` / `CSO\0` / `HSO\0` / `DSO\0` (the stage), u32 compiler version, u32 control length, u32 control offset (0x18), u32 code length, u32 code offset, and nothing else. The engine makes a program of each and binds them per stage at draw time, so they are single-stage programs, paired with a cover pixel shader (`shader_split.py` `pg_shader`; the archives: [01](../agents/01-extract.md)). It finds its built-in ones by name (`hwfillcolor.vso`, …) and checks each object's GPU code version against the driver's (the NVN layer reports the translator's supported GPU-code range: [Newest GPU code version reported by the driver](nvn-objects.md#newest-gpu-code-version-reported-by-the-driver), SDK 13.3.2).
|
||||
- **Found on:** [Bayonetta 3](../../dm/games/01004A4010FEA000/README.md): 8,024 objects in `root_000.pkz` (`shader.dat`, `shader2.dat`, `shadereff*.dat`, `autoshadereff.dat`); 6,424 distinct keys (4,288 pixel, 2,047 vertex, 78 compute, 6 domain, 5 hull).
|
||||
|
||||
### Size-delimited PlatinumGames shader objects
|
||||
|
||||
- **Symptom:** the split finds zero shaders and refuses the shader build, although the CPK's DAT archives contain the objects passed to NVN at boot.
|
||||
- **Cause:** another PlatinumGames wrapper stores a binding table before the code and control sections, rather than the stage-tagged object above or a BNSH file: u32 prefix length (including that word), binding bytes, u32 code length, code, u32 control length, control. The observed prefix is `0x88` bytes and the control section `0x880` bytes.
|
||||
- **Fix:** `shader_split.py` `pg_sized_shader` recognizes the self-described section boundaries and NVN magics (`0x12345678` for graphics code, `0x12345679` for compute, `0x98761234` for control). The prefix must be aligned and in bounds, both sections must fit, the record must end with its control section, and the control's code length at `+0x704` must agree. Graphics stages come from SPH; the compute magic identifies compute. The reader emits `#PGSO` records so the existing single-stage cover pairing applies. Recognition needs no title or filename rule, and the shader translation chain is unchanged.
|
||||
- **Found on:** [NieR:Automata The End of YoRHa Edition](../../dm/games/010056B015FE8000/README.md): the objects in five DAT shader archives inside `data000.cpk`; the game note records the census and the runtime-key checks.
|
||||
|
||||
### BNSH files in PlatinumGames DAT archives inside CRI CPK archives
|
||||
|
||||
- PlatinumGames' engine in its Wii U form keeps its shaders as BNSH files of one stage each, the `.vso` / `.pso` members of PlatinumGames DAT archives (`shader.dat`, `shader2.dat`, `shadereff.dat`) inside a CRI CPK archive, all CRILAYLA-compressed ([01](../agents/01-extract.md) has the CPK layout). `dm/gfx/tools/cpk.py` reads the @UTF tables (and the masked ones of Unicorn Overlord's CPKs, the same tables as before once unmasked), the TOC and CRILAYLA (a decoder over a bit string, about 29 MB/s); `shader_split.py` `cpk_jobs` splits the CPKs into jobs and scans each entry (a CPK it cannot read is scanned as one file, with a `[RED]` line).
|
||||
@@ -405,6 +412,47 @@ Finding, keying and translating shaders (`dm/gfx/tools/shader_split.py`, `dmsh_b
|
||||
- **Note:** Big Brain Academy's 12 geometry shaders (`_BezelSystemResources/line/shader/line.bfsha`) do not build (`unknown main0_out`) and their draws are skipped (`[RED] primitive type 11 not implemented`). They take a line strip with adjacency (primitive type 11) and emit up to 12 vertices per segment as triangle strips: thick lines with joins and caps (28 emit sites). From the main menu on, every frame draws one such line (width 10 in its uniform block) into the top-left 512x512 of the frame and copies that region into a texture, so the menu's chart loses its outlines. Not done.
|
||||
- **Note:** the vendored Ryujinx translator has its geometry-to-compute transforms (`VertexToCompute`, `GeometryToCompute`), which the chain does not use yet.
|
||||
|
||||
### Geometry reader viewport masks
|
||||
|
||||
- **Symptom:** the geometry kernel compiles, but its `_bgv.metal` vertex reader fails with `use of undeclared identifier 'gl_BuiltIn_5253'` and `member reference base type 'int' is not a structure or union`.
|
||||
- **Cause:** `ResourceReservations` packs `ViewportMask` into one output word; `GenerateVertexPassthroughForCompute` stores that word as a scalar although SPIR-V `IoMap` declares builtin 5253 (`ViewportMaskNV`) as `int[1]`. SPIRV-Cross emits an invalid array-copy expression for it, and Metal has no viewport-mask output. The mask still matters: zero discards a primitive, while bit zero selects viewport zero ([NV_viewport_array2](https://registry.khronos.org/OpenGL/extensions/NV/NV_viewport_array2.txt)).
|
||||
- **Fix:** `dmsh_geometry.reader` recognizes that generated scalar-array store, retains the mask's integer bits and moves vertices beyond the X clip plane when bit zero is clear. This runs before `vs_depth` makes both depth entries. Using the X plane preserves culling with depth clamp too; moving vertices beyond the far depth plane allowed masked points to render when depth clamp was enabled. Unknown mask expressions fail the build instead of silently losing culling. No pinned translator change is required.
|
||||
- **Found on:** [NieR:Automata The End of YoRHa Edition](../../dm/games/010056B015FE8000/README.md): its four geometry shaders' readers.
|
||||
- **Check:** `dm/gfx/tests/test_dmsh_geometry.py` uses synthetic generated-reader MSL. Both Mac and iOS compiler checks reproduce the original error before the fix. Mac GPU readback covers six masks, points and triangles, depth clip and clamp, and both production depth entries (48 cases); zero-mask points under depth clamp fail with the earlier depth-plane cull. All four original readers also pass both platform syntax checks.
|
||||
- **Limits:** replay binds viewport zero only. Multi-viewport fanout is not implemented, and per-vertex-disagreeing masks are not validated; the tested primitives use one mask for every vertex. These tests establish compilation and viewport-zero culling, not the appearance of those effects in gameplay.
|
||||
|
||||
### Passthrough geometry output bounds follow input topology
|
||||
|
||||
- **Symptom:** a passthrough geometry kernel writes beyond its vertex and raw-index scratch regions, and compaction reads the wrong groups; corruption can reach the following primitive-map buffers without a red diagnostic.
|
||||
- **Cause:** the builder used the SPH's raw maximum output count for every topology. Ryujinx's `ShaderDefinitions` overrides that count for `GpPassthrough` (SPH word 0 bit 24) with the input primitive's vertex count excluding adjacency. A header can declare one vertex while the triangle variant writes three vertices and six raw index words per group. Allocating two index words per group then overlaps later scratch regions.
|
||||
- **Fix:** `dmsh_geometry.output_layout` mirrors the translator's override for each input variant: points, lines, lines with adjacency, triangles, triangles with adjacency use vertex bounds `1, 2, 2, 3, 3` and index strides `2, 4, 4, 6, 6`. Passthrough also inherits the input primitive: native GLSL omits the SPH's output primitive declaration, so `ShaderDefinitions` and metadata use point, line strip or triangle strip accordingly. `geometry_finish` writes those bounds and topology into each variant's metadata, which replay uses for allocation and compaction. Ordinary geometry shaders retain their declared bound and topology. Rebuild shaders and the host for the new chain.
|
||||
- **Found on:** [NieR:Automata The End of YoRHa Edition](../../dm/games/010056B015FE8000/README.md): its passthrough index-building geometry shaders; the triangle kernel's six-word stores disagreed with its two-word metadata while rendering flight. The game note tracks the visual result after correction.
|
||||
- **Check:** `test_dmsh_geometry.py` covers all five variants, ordinary bounds and malformed headers. With `DM_TEST_GEOMETRY` pointing at `t_geometry`, it passes production-generated layouts to a native emitter with independent topology bounds. GPU canaries protect the nominal vertex and raw-index allocations, and compaction must preserve the emitted count and order. The old rule produced 34 failures; the corrected metadata passes all 170 native checks with Metal validation.
|
||||
|
||||
### Passthrough geometry kernels lose raster vertices
|
||||
|
||||
- **Symptom:** a geometry kernel compiles and runs its storage-buffer side effects, but contains no `geometry_vb_output` binding and fills its index stream with restart markers; its following raster pass draws no geometry.
|
||||
- **Cause:** the offline accessor inherited native geometry-passthrough support. Native NV passthrough forwards input vertices without an explicit emit, but Metal's compute stage must emit them. Disabling native support alone still loses generic attributes: independently compiled stages have no linked next-stage usage to populate `PassthroughAttributes`.
|
||||
- **Fix:** fixed-input compute jobs report no native geometry-passthrough support. `EmitterContext` explicitly emits input positions and every captured generic attribute the GS did not replace, removing adjacency vertices as the input topology requires. This uses the complete Maxwell capture map; ordinary linked translation retains its existing usage mask. Copying all 128 generic components also exposes a Metal backend compiler failure at normal optimization (`Internal compiler error` when creating the pipeline, despite successful offline compilation). `dmsh_geometry.capture_input` keeps capture reads volatile, preserving their values and normal kernel optimization while preventing that failure. No game IDs or shader keys participate.
|
||||
- **Found on:** [NieR:Automata The End of YoRHa Edition](../../dm/games/010056B015FE8000/README.md): its passthrough index-building shaders run before depth-writing raster passes during flight. The game note tracks rendering after rebuilding.
|
||||
- **Check:** `PassthroughCompiler` translates a synthetic EXIT-only Maxwell passthrough shader for all five input topologies, deliberately declaring triangle output in every raw header. Both Mac and iOS compile checks run. With `DM_TEST_GEOMETRY`, production reflection and the argument encoder dispatch the actual kernels; readback checks positions, all 32 generic attributes, adjacency selection, two instances, raw indices, restart padding, primitive compaction and allocation canaries (9,066 native checks). The original pinned translator fails all five variants because raster output is absent. Removing volatile capture reads makes the 128-component synthetic pipeline fail to compile on the M4 Pro; reducing to 96 components or compiling at `-O0` independently removes that failure.
|
||||
|
||||
### Geometry capture waits for every indexed draw
|
||||
|
||||
- **Symptom:** geometry-heavy frames have a large submission wall/CPU gap despite short GPU execution; stack samples spend most of the main thread in `geo_draw` → `mdi_wait` → shared-event wait, with index sorting another substantial cost.
|
||||
- **Cause:** every indexed geometry draw unconditionally committed and drained the GPU before assembling its primitives on the CPU. It also waited for vertex streams consumed only by native GPU capture. The capture list sorted every index reference to remove duplicates, even though the scratch bound already limits the vertex span.
|
||||
- **Fix:** `nvn_geometry.inc` checks each actual CPU-read range against pending copies/updates/fills, current shader writes and previous live submission writes. Unknown or overflowing write sets retain the wait. Indirect records are checked before decoding; their selected index ranges are checked afterwards. CPU-converted vertex bindings retain the same hazard checks, while native capture follows GPU encoder ordering. A successful drain covers the remaining reads of that draw. Capture uniqueness uses a bounded vertex-span bitset and ascending set-bit enumeration; allocation failure or a wider span retains an in-place sort fallback. Non-indexed captures need no unique index list. The primitive map, restart handling, base vertex and instance semantics are unchanged.
|
||||
- **Found on:** [NieR:Automata The End of YoRHa Edition](../../dm/games/010056B015FE8000/README.md): its flight geometry path. The game note records matched frame-time and visual validation.
|
||||
- **Check:** `t_geometry` first reproduced five unnecessary drains for clean static and indirect inputs. Its 226 native checks cover clean versus pending/current/prior GPU-written ranges, unknown write sets, GPU-only and converted streams, indirect arguments selecting a different dirty index range, 8/16/32-bit indices, restart, base vertex and instances. Actual copy/compute writes and raster readback validate synchronization; converted data must see the new GPU-written value. Sparse duplicates, ascending output, short destinations, fallback and allocation canaries cover the capture list. These checks establish behavior; throughput is measured separately in gameplay.
|
||||
|
||||
### Geometry compaction serial prefix scan
|
||||
|
||||
- **Symptom:** geometry-heavy frames remain GPU-bound after CPU readback waits are removed; encoder timestamps attribute most compaction time to the offset scan rather than the geometry shader or index writes.
|
||||
- **Cause:** count and write dispatches ran in parallel, but one GPU thread walked all group counts to compute ordered offsets. Geometry replay also created a separate compute encoder for each of the geometry, count, scan and write dispatches, with full queue barriers at every boundary.
|
||||
- **Fix:** `geo_pack_scan` divides the groups into contiguous chunks across at most 256 threads. Each thread sums its chunk; a threadgroup prefix scan gives its starting offset; a second chunk pass writes the ordered offsets. The group count does not need to fit in the threadgroup. Totals use 64 bits; unrepresentable 32-bit offsets saturate, output writes use subtraction-based capacity checks, and indirect counts retain complete-primitive truncation. `geo_pack_encode` keeps the geometry and three compaction dispatches in one encoder, with explicit dispatch-to-dispatch device-memory barriers. Full barriers remain at its boundaries. The primitive order and large-draw algorithm are preserved; no shader-library chain change is required.
|
||||
- **Found on:** [NieR:Automata The End of YoRHa Edition](../../dm/games/010056B015FE8000/README.md): its flight geometry passes. The game note records the baseline encoder timings and matched result.
|
||||
- **Check:** `t_geometry` passes 1,066 checks with Metal validation. A GPU producer and the production compaction stages share one encoder; readback compares every offset and ordered index with an independent CPU result, including 129,032 groups. Cases cover points, lines and triangle strips, empty groups, zero/odd/thread-boundary group counts, 1/32/192/256-thread scans, short capacities, integer overflow and allocation canaries. The actual translated passthrough integration also passes all five input topologies through the same encoder path. Performance is checked separately with matched gameplay.
|
||||
|
||||
### Geometry draws above the capture scratch bound
|
||||
|
||||
- **Symptom:** `[RED] geometry draw needs 261 MiB of scratch, above the 256 MiB bound` (or `exceeds the capture or invocation bound`); the draw is skipped.
|
||||
@@ -438,6 +486,22 @@ Finding, keying and translating shaders (`dm/gfx/tools/shader_split.py`, `dmsh_b
|
||||
- **Found on:** [The Legend of Zelda: Link's Awakening](../../dm/games/01006BB00C6F0000/README.md) (Mac and iPhone): the step of Marin and Tarin's doorway. The room shaders use tiled forward lighting: the fragment position picks a 64×64-pixel tile (`trunc(y / 64) × ceil(width / 64) + trunc(x / 64)`), whose light count and light indices come from two storage buffers that a compute shader (`light_culling_compute.bfsha`, one thread per workgroup, one workgroup per tile) fills every frame. Every row's workgroups wrote row 0's entries, the last writer won (a different one each frame), and the bottom tile row, where the step is, got the lights of other rows; a dump of the tile lists showed only the first of 17 rows filled. After the fix every tile row has its lights and the doorway shows the game's soft light from outside.
|
||||
- **Check:** Breath of the Wild (101 compute and 4 vertex shaders read `c0`) and Super Mario 3D World (11 and 1) render the same as before on the Mac.
|
||||
|
||||
### Geometry-stage storage buffer table
|
||||
|
||||
- **Symptom:** `[RED] shader ... reflection conversion failed: B binding gp_s0 has no resolved slot number`; a geometry shader reading driver segment `c0` reports that its storage-buffer table base was never measured.
|
||||
- **Cause:** geometry shaders access their storage buffers through `c0 + 0x410 + 0x10 r`, but the builder's `SSBO` map and replay's `c0_ssbo_base` covered only vertex, pixel and compute. Running the lowered geometry shader as a Metal kernel does not change its logical NVN stage or driver table.
|
||||
- **Fix:** geometry uses base `0x410` in both reflection and driver-buffer population. `encode_args` keeps NVN stage 2 for these kernels, so storage slots and driver-table rows come from the geometry bindings. Hull and domain bases remain unmeasured and unresolved.
|
||||
- **Found on:** [NieR:Automata The End of YoRHa Edition](../../dm/games/010056B015FE8000/README.md): the original shader's constant-buffer operands and the pinned translator's metadata agree on addresses in rows 0 and 2.
|
||||
- **Check:** `dm/gfx/tests/test_dmsh_reflect.py` resolves synthetic geometry descriptors to slots 0 and 2 and rejects unknown or unaligned table addresses. `t_geometry` passes synthetic metadata through native reflection and the production argument encoder; GPU readback checks both rows' guest addresses and sizes with different compute-stage bindings, plus a write through the geometry storage pointer.
|
||||
|
||||
### Storage-buffer write flag in translation metadata
|
||||
|
||||
- **Symptom:** a storage buffer the shader stores to or uses atomically has `rw: false` in its generated reflection; replay does not record its GPU writes for dependent buffer reads.
|
||||
- **Cause:** Ryujinx's `BufferUsageFlags.Write` is bit 0 (`1`), and `Program.cs` serializes that enum unchanged. The builder tested bit 1 (`2`), incorrectly marking every such descriptor read-only. Native reflection honors the explicit `rw` field, so its older fallback to the MSL pointer qualifier could not correct it.
|
||||
- **Fix:** `reflect` tests bit 0 for both driver-table storage buffers and addresses carried in guest uniform buffers. Replay then uses its existing write-access and pending-write tracking paths. Rebuild shaders to replace the old metadata.
|
||||
- **Found on:** [NieR:Automata The End of YoRHa Edition](../../dm/games/010056B015FE8000/README.md): its geometry counter atomic and output stream both emitted translator flag `1` but reached reflection as read-only.
|
||||
- **Check:** `test_dmsh_reflect.py` exercises writable and read-only translator descriptors, including an address in a guest uniform. `t_geometry` verifies that native reflection preserves explicit true and false flags and that the writable geometry output enters the GPU-write tracker before its dispatch.
|
||||
|
||||
### Graphics `c0 + 0x610`: the largest point size
|
||||
|
||||
- **Symptom:** point sprites of size 0 (Odyssey's Cap Kingdom fog never parted around Mario).
|
||||
|
||||
Reference in new issue
Block a user