Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ jobs:
make GAME="$GAME" -j3 t_perf_order
./t_perf_order --cpu 2>&1 | tee ../../../logs/t_perf_order.log
make GAME="$GAME" -j3 perf-order-tsan 2>&1 | tee ../../../logs/t_perf_order-tsan.log
tests="t_gfx_suspend t_capture t_dirty_slots t_dirty_race t_dirty_retire_race t_tex_layout t_pace t_fstep t_link_ticks t_cpu_tex t_hmap t_cover t_pso_skey t_refl t_rt_range_ro t_present_rescue t_gpuprof t_sparse_layout t_timestamp t_rt_depth_ro t_rt_range_shape t_ub t_pso_pending t_vk_desc t_rec_draws"
tests="t_gfx_suspend t_capture t_dirty_slots t_dirty_race t_dirty_retire_race t_tex_layout t_pace t_fstep t_link_ticks t_cpu_tex t_hmap t_cover t_pso_skey t_refl t_rt_range_ro t_present_rescue t_gpuprof t_sparse_layout t_timestamp t_counter_clock t_rt_depth_ro t_rt_range_shape t_ub t_pso_pending t_vk_desc t_rec_draws"
make GAME="$GAME" -j3 $tests 2>&1 | tee ../../../logs/gfx-build.log
failed=0
for t in $tests; do
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ Under a game, "60 fps with 1.2.0" means it runs at 60 fps (30 on the console) wi
<tr>
<td align="center" valign="top" width="33%"><img src="docs/images/mario-tennis-fever.jpg" width="256" alt="Mario Tennis Fever"><br><small><b><a href="dm/games/0400D4201C6EA000/README.md">Mario Tennis Fever</a></b><br>Switch 2, Mac only, from a dump</small></td>
<td align="center" valign="top" width="33%"><img src="docs/images/yoshi-and-the-mysterious-book.jpg" width="256" alt="Yoshi and the Mysterious Book"><br><small><b><a href="dm/games/0400245021D2C000/README.md">Yoshi and the Mysterious Book</a></b><br>Switch 2, Mac only</small></td>
<td align="center" valign="top" width="33%"><img src="docs/images/zelda-ocarina-of-time.jpg" width="256" alt="The Legend of Zelda: Ocarina of Time"><br><small><b><a href="dm/games/0400486024DEC000/README.md">The Legend of Zelda: Ocarina of Time</a></b><br>Switch 2, Mac only, from a NUP</small></td>
<td align="center" valign="top" width="33%"><img src="docs/images/zelda-ocarina-of-time.jpg" width="256" alt="The Legend of Zelda: Ocarina of Time"><br><small><b><a href="dm/games/0400486024DEC000/README.md">The Legend of Zelda: Ocarina of Time</a></b></small></td>
</tr>
<tr>
<td align="center" valign="top" width="33%"><img src="docs/images/mario-kart-8-deluxe.jpg" width="256" alt="Mario Kart 8 Deluxe"><br><small><b><a href="dm/games/0100152000022000/README.md">Mario Kart 8 Deluxe</a></b><br>no Mii heads</small></td>
Expand Down
571 changes: 476 additions & 95 deletions dm/games/0400486024DEC000/README.md

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions dm/games/0400486024DEC000/bench.tsv
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Routes start from the Kokiri Forest autosave beside Saria, after exiting Link's house.
# name, DM_KEYS, measurement start and duration in seconds, description
kokiri-stand 25:A,30:A,35:A,40:A 70 60 Reload the Kokiri Forest autosave and stand beside Saria; check the screenshot before accepting timing.
kokiri-walk 25:A,30:A,35:A,40:A,75:LLeft~1,80:LUp~2,90:LUp~4,105:RRight~2,115:RLeft~2 70 60 The same save: step around Saria, walk through the village and turn the camera.
kokiri-camera 25:A,30:A,35:A,40:A,75:RRight~2,85:RLeft~2,95:RRight~2,105:RLeft~2,115:RRight~2,125:RLeft~2 70 60 Keep Link at the loaded save position and turn the camera repeatedly; compare first and repeat turns, and check the screenshots before accepting timing.
kokiri-vines-camera 25:A,30:A,35:A,40:A,65:RRight~1,75:RLeft~1,85:RRight~1 60 30 Latest manual save at the Kokiri vines: stand in place and turn the camera; compare screenshots and display samples.
kokiri-vines-climb 25:A,30:A,35:A,40:A,65:LUp~6 60 30 Latest manual save at the Kokiri vines: climb to the upper ledge; verify progress and uploads, not identical-position performance.
1 change: 1 addition & 0 deletions dm/games/0400486024DEC000/bf_want.tsv
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# generated
39 changes: 19 additions & 20 deletions dm/games/0400486024DEC000/game.tsv
Original file line number Diff line number Diff line change
@@ -1,46 +1,45 @@
# The Legend of Zelda: Ocarina of Time (Switch 2, update v131072)
# Nintendo EPD's engine (sead / agl / gsys, Phive; project Owl, the Tears of the Kingdom engine's file layout), SDK 22.2.8 built for the Switch 2 (Ounce), NVN2 (Ampere shaders); modules main + subsdk0 (movie) + sdk.
# Packed from a NUP container (scripts/pack_nup.py). Shaders: Shader/*.Nin_Ounce_NVN2.bfsha.zs (BNSH with Ampere code).
# The Legend of Zelda: Ocarina of Time (Switch 2), v0 and standalone v131072. Nintendo SDK 22.2.8, NVN2.

# ---- Identity ----
title_id 0400486024DEC000
program_id 0400486024DEC000

# ---- App ----
name The Legend of Zelda: Ocarina of Time
ipa ZeldaOcarinaOfTime.ipa
app_category public.app-category.adventure-games
pad_layout full
ipa OcarinaOfTime.ipa
app_category public.app-category.games

# ---- Versions ----
build v0 v0 main=e0f3ccfaf50065ae4ea01eb5aeb13b1a subsdk0=b0110087a7b339ef74588d3bd0b4dd5d sdk=1643a838814f9c10c696f930ed681e7f
build v131072 v131072 main=e0f3ccfaf50065ae4ea01eb5aeb13b1a subsdk0=b0110087a7b339ef74588d3bd0b4dd5d sdk=1643a838814f9c10c696f930ed681e7f
package v131072
shader_versions v131072

# ---- Files ----
modules main subsdk0 sdk
romfs_marker Pack/ZsDic.pack.zs
zip_store .zs:.bwav:.webm:.metallib
romfs_marker Event/Movie/Dm_StaffCredit_0000.webm
zip_store .bwav:.webm:.zs:.metallib

# ---- Memory ----
# The Switch 2 leaves games 9 GB of its 12 GB (Donkey Kong Bananza's figure). The NPDM declares 48 MB of system resource, so virtual address memory is on.
# nninitStartup asks SetHeapSize 0x18ce00000 (6.2 GB) with the 9 GB pool, as Mario Kart World. 256 MB in front + 4 GB alias region + 256 MB stack region + 8 GB heap region: a starting split, to be measured
mem_reserve 0x320000000
mem_alias 0x100000000
mem_map_limit on
# The NPDM declares 48 MiB of system resources. Startup requests a 6.20 GiB heap.
mem_reserve 0x300000000
mem_alias 0x98000000
mem_stack 0x10000000
app_pool 0x240000000
sys_resource 0x3000000

# ---- Shader split (shader_split.py) ----
shader_groups /Shader/=shader /Effect/=effect /Lib/=lib /UI/=layout
shader_note Ocarina of Time shaders
# ---- Shader split ----
shader_groups /Shader/=shader /Lib/=lib /Effect/=effect /Layout2Shader/=layout /Movie/=movie
shader_note 0400486024DEC000 shaders

# ---- Graphics ----
# agl wraps its clears in render conditions on Donkey Kong Bananza and Splatoon Raiders; the same library here
# agl wraps its depth clears in render conditions, as on Donkey Kong Bananza and Splatoon Raiders: in Kokiri Forest the main opaque pass tests EQUAL against a copy of the prepass depth
# that a conditional clear (skipped on the console) wiped first, so no lit geometry landed and the full-screen sky showed through everywhere (a white scene)
render_cond on
gpu_timestamps segment
draw_barriers game
# As Tears of the Kingdom: the terrain's height, blend and hole maps are written by the CPU into textures after they are created. Without these keys they stay zero: holes in the ground and the wrong materials

# Terrain height tiles are filled by the CPU in mixed CPU/GPU pools without an NVN flush.
tex_flush_upload on
tex_dirty_upload on

# Experimental high-rate support; default stays 60. See the game note for validation limits.
fps_max 120
34 changes: 34 additions & 0 deletions dm/games/0400486024DEC000/patches.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
"""Experimental fractional timing adapted from upstream PR1543.
State +0x40: simulation FPS override (zero retains native step); +0x38: elapsed seconds.
The native rendering controller is unchanged. Short forest gameplay is validated;
movie/audio transitions and whole-game high-rate play remain open (see README.md).
"""
from nso_asm import ADRP, B


def real_speed(ctx):
ctx.fractional = 1
here, emit = ctx.here, ctx.emit
ctx.site(0x6e6cc4, '2818201e')
start = here()
emit(0x1e201828) # fdiv s8,s1,s0: native fallback
emit(ADRP(16, here(), ctx.state))
emit(0x52800051) # mov w17,#2: fractional contract
emit(0xb9003e11) # str w17,[x16,#0x3c]
emit(0xb9404211) # ldr w17,[x16,#0x40]: validated positive float bits or zero
emit(0x34000071) # cbz w17,+12: native fallback, preserves NZCV
emit(0x1e270220) # fmov s0,w17
emit(0x1e201828) # fdiv s8,s1,s0: requested simulation step
emit(0xbd403a00) # ldr s0,[x16,#0x38]: elapsed seconds
emit(0x1e210800) # fmul s0,s0,s1
emit(0x1e204908) # fmax s8,s8,s0: correct late frames
emit(B(here(), 0x6e6cc8))
ctx.put(0x6e6cc4, [B(0x6e6cc4, start)], 'EXPERIMENT: fractional simulation step without modifying native rendering budget')

FRAME_STEP = {'e0f3ccfaf50065ae4ea01eb5aeb13b1a': real_speed}

BINDING = [
{'what': 'frame step from the measured frame time', 'now': 'build', 'goal': 'game', 'purpose': 'frame rate',
'why': "this game's own frame loop; the frame-step state page is general",
'blocked': 'frame-step stubs have no function-matched form yet'},
]
Loading
Loading