1006 Commits
Author SHA1 Message Date
Valiantsin DzerakhandClaude Opus 5.5 7a37fc3c34 Up version 0.4.0
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
v0.4.0
2026-11-10 19:25:38 +03:00
Valiantsin DzerakhandClaude Opus 5.5 bb8b4b1797 Turn the recorder thread on by default on AMD GPUs too; vk_recorder = 0 turns it off where the device is lost
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 19:25:37 +03:00
Valiantsin DzerakhandClaude Opus 5.5 396c4ae621 Describe the profile-guided build in docs/pgo.md: where and how to train, free play, merge, measure
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 19:07:38 +03:00
Valiantsin DzerakhandClaude Opus 5.5 27a63dfb0f Merge pull request #1065: Xbox prompts at every game resolution the setup lays the UI out for (cdonatom, #378)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 18:59:22 +03:00
Valiantsin DzerakhandClaude Opus 5.5 6f6704640a Merge pull request #1066: describe deswizzle, kspin_us, pcore, rec_async and rec_spin_us in docs/settings.md (itaskaev2)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 18:55:58 +03:00
Valiantsin DzerakhandClaude Opus 5.5 574c1ecc49 Merge task/climb: Link climbs walls and ladders at full speed above 60 fps (#35, #276, #1001)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 18:46:30 +03:00
Valiantsin DzerakhandClaude Opus 5.5 06811330e7 Extend the climb controller's frame-rate factor above 60 fps, so Link climbs walls and ladders at full speed (#35, #276, #1001)
The climb velocity step (1.4.3 main+0x1f49754, 1.2.1 main+0x1918220) multiplies the requested velocity by Nintendo's
factor for a movement loss that grows with the frame rate. 1.4.3 fits it at 30 and 60 fps and caps it at 2 from about
77 fps (63% climb speed at 120, 34% at 240); 1.2.1 has no 60 fps branch (78% at 60). Below a 1/60 s step the set climb
continues the factor with a curve fitted to a replayed ladder climb, taking the patch page's frame ratio without the
time scale, so 30 and 60 fps keep the shipping factor bit for bit, slow motion included. Only the player's climb
modules reach this code. Its own setting, climb_fix under [frame rate], with a menu toggle; off without the real-time
step. Ladder replay, 1.4.3: 1.665 / 1.663 / 1.669 / 1.681 m/s at 30 / 60 / 120 / 240 (shipping 120 1.046, 240 0.563).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 18:44:18 +03:00
itaskaev2andClaude Opus 5.5 e8fd6fd7a5 Describe deswizzle, kspin_us, pcore, rec_async and rec_spin_us in docs/settings.md
tests/settings_doc_check.py failed on dev with these five names in known[] and described nowhere. The rows follow the
code: vk_deswizzle.c (TOTK_DESWIZZLE), kernel.c kspin_ns, main.c (rt_knob PCORE), vk_rec.c rec_submit and rec_main.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 16:28:21 +01:00
Valiantsin DzerakhandClaude Opus 5.5 be7c27047a Keep the 4096-a-side scene of an output near 8K under the new heap bound
The heap bound in scene_for counts the output's own growth against the 2 GiB limit, so a 7680x4320 output at
render_scale game went from the 4096x2304 scene dev renders to 2712x1526, with no setting changed. The bound now
shrinks no scene below 4096 a side, the size dev gave; scenes the 4096 cap kept smaller still grow up to the bound.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 18:20:31 +03:00
Valiantsin DzerakhandClaude Opus 5.5 1c1ff975f3 Default dynamic_res to 1 so the game keeps its own dynamic resolution
With dynamic_res at 0 by default the fixres set held the scene at 100 % for every player, the reason #573 was turned
down. The default is now 1, so the set stays off unless a player turns dynamic resolution off in the menu or
totk.ini, and the Steam Deck profile no longer needs its own entry.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 18:20:31 +03:00
Valiantsin DzerakhandClaude Opus 5.5 b6738cf41b Merge pull request #916: dynamic resolution as a setting, on by default, and a scene past 4096 wide (#573 by ProSep, carried by itaskaev2)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 18:20:31 +03:00
Valiantsin DzerakhandClaude Opus 5.5 dfc0b57457 Keep the per-frame pass table's comment to what the code does
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 17:59:54 +03:00
Valiantsin DzerakhandClaude Opus 5.5 173462f33d Merge pull request #1040: keep the targets a frame renders in the per-frame pass table, so draws with a pipeline still building skip a frame instead of waiting 50 to 400 ms (ipavlin98)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 17:59:53 +03:00
Valiantsin DzerakhandClaude Opus 5.5 3e037f0044 Keep the shadow log of players without sync_ahead as it was, sort the new setting names, and fix the sync_ahead frame-time sentence
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 17:55:57 +03:00
Valiantsin DzerakhandClaude Opus 5.5 b2db7809b4 Merge pull request #917: let the game run one frame further ahead of the GPU, sync_ahead, off by default (#676 by ProSep, carried by itaskaev2)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 17:55:23 +03:00
Carlos DonatoandClaude Opus 5.5 fb34177cfd Make the Xbox prompts for every game resolution the setup lays the UI out for (#378)
The setup wrote romfs-patches-xbox and romfs-patches-xbox-label for 16:9 only, so prompts = xbox on a 21:9, 32:9,
16:10 or 3:2 screen (the Steam Deck's 1280x800 among them) kept the game resolution at 1920x1080 (cfg.c) or, with
output_res set to the screen's shape, fell back to the Switch prompts. #979 fixed this for prompts = pc; this extends
the same mechanism to both Xbox folders, the shared-files option of #378 by way of #979's --reuse.

- The setup builds romfs-patches-xbox-<w>x<h> and romfs-patches-xbox-label-<w>x<h> for each of ASPECT_SIZES, from
  their 16:9 folder with --reuse, as it does for romfs-patches-pc-<w>x<h>.
- romfs.c overlay_init: at a game resolution of another shape any prompts' folder loads from <folder>-<w>x<h> in place
  of romfs-patches-<w>x<h>, not only the PC one; without it the Switch prompts stay, and the log names the missing
  folder and the command that makes it. romfs_shaped_pc_ready becomes romfs_shaped_prompts_ready(folder, w, h).
- cfg.c: the display-shaped output_res default applies with prompts = xbox when the folder of the pad layout
  (romfs-patches-xbox with the Nintendo layout, romfs-patches-xbox-label with any other) is there for that size.
- The menu's note for a missing shaped folder reads "off at this game resolution (no layout made for it)" in every
  menu language, since 16:9 is no longer the only shape with prompts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 15:53:49 +01:00
Valiantsin DzerakhandClaude Opus 5.5 8da13aa9b4 Merge pull request #1006: stop the installer space check at an unavailable drive root (Luxury213)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 17:43:41 +03:00
Valiantsin DzerakhandClaude Opus 5.5 719196f183 Merge pull request #1061: let a validation run with DLSS finish, a valid OpSelect in the motion fragment shader and set 1 bound first for the motion draws (itaskaev2)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 17:43:41 +03:00
Valiantsin DzerakhandClaude Opus 5.5 fce6364236 Merge pull request #1060: take the feedback-layout images back to GENERAL before the contact shadows' march (itaskaev2)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 17:43:40 +03:00
itaskaev2andClaude Opus 5.5 0adcc96bae Bind the motion draws' set 1 before pushing set 0 under the validation layer, as the replay's draws do
vk_mvobj_execute's draws (mo_emit) push set 0 and then bind set 1. Under the validation layer (SDK 1.4.363) a push for
a new INDEPENDENT_SETS layout keeps the push set the layer made for an earlier layout (the replay's last draw) and drops
the writes to bindings that layout lacks: every run with DLSS and validation reported the last-frame banks as missing
(VUID-vkCmdDrawIndexed-None-08114, variable vp_c20) and then faulted inside VkLayer_khronos_validation.dll. The
replay's own draws avoid this by binding set 1 first (set1_first in bind_descriptors); the motion draws now do the
same, only while the layer is active.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 15:11:08 +01:00
itaskaev2andClaude Opus 5.5 f804facd8b Take the feedback-layout images back to GENERAL before the contact shadows' march
vk_contact_exec ended the pass and recorded a memory barrier only. Once a G-buffer draw samples the linear depth or the
scene colour in its own pass, those images stay in ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT across passes
(vk_exec_draw.c, feedback loops), and the march then bound them in GENERAL as a sampled and a storage image. The Vulkan
validation layer reported it on every frame with contact shadows on (vkCmdDispatch imageLayout-00344, followed by
barrier, BeginRendering and QueueSubmit layout errors: 40 per run at Lookout Landing, 0 with contact_shadows = 0).
vk_exec_barrier ends the pass and moves those images back to GENERAL in the same full barrier, as every other
barrier does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 14:59:34 +01:00
itaskaev2andClaude Opus 5.5 708e0cfe8d Give the per-object motion fragment shader's OpSelect a condition vector, as SPIR-V 1.0 needs
tools/make_mvobj_fs.py assembled OpSelect of a vec4 with a scalar bool condition, which only SPIR-V 1.4 and later
allow. The module is 1.0, so spirv-val in the Vulkan validation layer rejected it (Expected vector sizes of Result Type
and the condition to be equal: Select). The condition is now splatted into a bvec4 first; runtime/vk_mvobj_fs.h is
regenerated and passes spirv-val.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 14:59:31 +01:00
Valiantsin DzerakhandClaude Opus 5.5 7f82a52da8 Merge task/gears: gear doors open above 30 fps on 1.2.1 (#330, #984)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 15:36:35 +03:00
Valiantsin DzerakhandClaude Opus 5.5 6433550e3d Scale the 1.2.1 gear rotation threshold by the AI update's frame delta, as 1.4.3 does (#330, #984)
ActorCheckRotateModule's update compared the angle a gear turned since the last update with one 30 Hz frame's worth,
so above 30 fps gears and water wheels read as stopped and the Riogok, Turakamik and Wind Temple doors stayed shut.
The new set gears keeps the update context's +8 (frames elapsed in 30 Hz units, the value 1.4.3 divides by) and
multiplies the threshold by it. Measured: the context is 0.25 at 120 fps with the real-time step and 0.5 at 60 fps
without it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 15:35:16 +03:00
Valiantsin DzerakhandClaude Opus 5.5 1503b17f7d Merge task/crash705: list the compound physics shape's children in the crash report (#705)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 10:20:07 +03:00
Valiantsin DzerakhandClaude Opus 5.5 4c4bd8c67a List the compound physics shape's children in the crash report for the 1.2.1 fault after the material lookup (#705)
On 1.2.1 the game asks a compound physics shape for its first child's material at main+0xe056d0 and reads the result
without a check. At the reported crash the shape had none of its 125 children left, although every child is filled
when the shape is built. The crash handler now prints that shape's live bits and each record's shape pointer and name,
which tells removed children from switched-off ones and names the object. It runs only after the crash.
--probe-kernel builds a fake shape in a crashing child and checks the listing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 10:19:50 +03:00
Valiantsin DzerakhandClaude Opus 5.5 3d386fe37e Merge task/inteluhd: dynamic alpha to coverage and vertex input off by default on Intel's Windows driver for integrated GPUs (#970, #992)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 09:13:52 +03:00
Valiantsin DzerakhandClaude Opus 5.5 905e2e720d Turn dynamic alpha to coverage and dynamic vertex input off by default on Intel's Windows driver for integrated GPUs (#970, #992)
UHD Graphics (i3-1215U, i3-1305U) and Iris Xe drew coloured noise on foliage with dynamic alpha to coverage and black
patches over the scenery with dynamic vertex input; players confirmed that vk_dyn_a2c = 0 and vk_dyn_vertex = 0 clear
both. vk_caps.intel_igpu_win marks Intel's proprietary Windows driver on an integrated GPU, and both defaults follow it.
An explicit ini value still wins. Arc discrete GPUs and Mesa's ANV keep both on: no report there, and the ANV report
(#989) had both off with its glitch still present.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 09:01:54 +03:00
Valiantsin DzerakhandClaude Opus 5.5 729b00a1c0 Merge task/sdl3420: ship SDL 3.4.20 in the release for pads without motion calibration (#912)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 08:58:32 +03:00
Valiantsin DzerakhandClaude Opus 5.5 2fe1ea1716 Bump the bundled Windows SDL to 3.4.20 (#912)
SDL 3.4.20 uses default Switch controller stick and IMU calibration when the
pad has none, which fixes the infinite gyro readings on the Beitong Asura 2 Pro+.
The pins in tools/make_release.py (version, zip and devel sha256, SDL3.dll sha256)
and the Windows rows of THIRD_PARTY_NOTICES.md follow. The sniper sysroot row stays.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 08:53:49 +03:00
Valiantsin DzerakhandClaude Opus 5.5 32f86a3296 Merge task/cheatc0: run cheat opcodes C0-C3 in the data cheat VM (#973)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 08:07:24 +03:00
Valiantsin DzerakhandClaude Opus 5.5 14b1b1aece Run cheat opcodes C0-C3 in the data cheat VM (#973)
The VM refused C0 (register conditional), so cheats like C046B400 FFFFFFFF were greyed out as unsupported. C0 now
runs with dmnt's operand types 0-5, widths and conditions; C1 and C2 save, restore and clear registers, C3 moves
registers to and from the static registers. tools/cheats.py gives the same opcode lengths and accepts the same opcodes.

skip() took the end of a nested block at depth 1 for the else of the failed outer block; it now counts depth the way
dmnt does, and 2x000000 is an else only for x = 1.

tests/cheats_vm_check.py runs tools/cheats.py and runtime/cheats.c on cheats of its own, the two from the issue
included.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 08:05:01 +03:00
ipavlin98 a4b46fa7a9 Keep the targets a frame renders in the table that tells per-frame passes from one-shot ones
The table of the frames each target was last rendered into was direct-mapped with 1024 entries. In a 1.4.3 field run about 16 entries rendered the frame before were taken by another subresource each frame, the scene's colour target among them, so every draw there whose pipeline was still building waited for it as one-shot, 50 to 400 ms, instead of skipping a frame. Sets of 8 ways that evict the way rendered longest ago lost none in the same run.
2026-11-09 21:22:38 +03:00
Valiantsin Dzerakh 8aba3647e0 Up version 0.3.14 2026-11-09 19:57:07 +03:00
Valiantsin DzerakhandClaude Opus 5.5 0238f3069a Merge task/pgostale: warn when a PGO profile was trained with other runtime headers
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-09 18:50:36 +03:00
Valiantsin DzerakhandClaude Opus 5.5 2d2c6782af Record the runtime headers a PGO profile was trained with and warn when they change
The floating-point helpers in simd.h and simd_fp.h inline into every lifted function before llvm-profdata matches
the profile, so the fpcheap change left pgo-v143 with a fifth of its weight while recomp/ stayed the same and
make_release saw nothing. pgo.py merge now reads the instrumented build's Ninja deps log and stores the digests of
the runtime/ headers the generated objects include (cpu.h, simd.h, simd_fp.h); make_release warns when one differs
or a record has none. docs/building.md says to retrain after a change to those headers, and build_game.py names the
libiconv-2.dll that MSYS2's SDL3.dll needs in deps-mingw/bin.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-09 18:50:36 +03:00
Valiantsin DzerakhandClaude Opus 5.5 bdcfb42c07 Add contributor and agent guides for pull requests, running and debugging
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-09 14:44:59 +03:00
Valiantsin DzerakhandClaude Opus 5.5 f9ed079614 Merge task/handheldscene: render the handheld scene at the asked size on 1.4.3
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-09 14:38:44 +03:00
Valiantsin DzerakhandClaude Opus 5.5 bed6962e09 Render the handheld scene at the asked size on 1.4.3
1.4.3 scales the scene size it reads from the patch page by canvas width over the console mode's base width, which is
1280 in handheld, not 1920. A handheld 1280x720 output at render_scale 100 put 1920x1080 on the page, so the game
rendered a 1920x1080 scene while the DynamicTextureAllocator heap was sized for 1280x720, and heavy scenes ran it out
(crash at main+0x1c2590). scene_scale now uses the mode's base for res_init and res_dlss_mode. In handheld the game
composes a 1280x720 canvas unless the output patch is on, so the output patch is switched on with the scene patch there
and the canvas is the output the factor and the heap assume. Docked is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-09 14:38:03 +03:00
itaskaev2 59eb026bd7 Merge branch 'dev' into carry/dynamic-res-100 2026-11-09 09:55:24 +01:00
itaskaev2 2e5d59df83 Merge remote-tracking branch 'origin/dev' into carry/sync-ahead
# Conflicts:
#	docs/architecture.md
#	runtime/cfg.c
#	runtime/vk_sync.c
2026-11-09 09:54:45 +01:00
Valiantsin DzerakhandClaude Opus 5.5 34b39ceca0 Merge task/memcommit: take 64 MiB blocks from the driver for buffers and other images
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-09 11:08:31 +03:00
Valiantsin DzerakhandClaude Opus 5.5 29cb79086f Take 64 MiB blocks from the driver for buffers and other images
Since the textures moved to a pool of their own, the default device-local
blocks hold mirrors and other buffers. With VMA's 256 MiB blocks one block
held 53 MiB of them after 10 minutes in the field, and the headroom thread
kept half a block of each device-local type ahead. TOTK_VMA_BLOCK_MIB
(default 64, 0 = VMA's 256) sets the size; the headroom spare follows it.

On the RX 9070, 10 minutes in the field: VMA blocks 3582 -> 3252 MiB,
process commit 8614 -> 8327 MB, slow frames 13 (2.8 s) -> 9 (1.1 s).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-09 10:51:49 +03:00
Valiantsin DzerakhandClaude Opus 5.5 a78268935a Merge task/memcommit: wait out a short out-of-memory spell instead of ending the game
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-09 10:15:50 +03:00
Valiantsin DzerakhandClaude Opus 5.5 cf44e9013c Merge task/memoom: wait out a short out-of-memory spell instead of ending the game
Conflicts: the image retry goes through vk_texture_image, sweep_pressure keeps the released-texture cap on the new
drop helpers, and vk_headroom_release also frees the texture pool's anchor.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-09 10:12:55 +03:00
Valiantsin DzerakhandClaude Opus 5.5 4ea472e864 Merge task/memcommit: textures in a pool of their own with 64 MiB blocks
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-09 10:11:51 +03:00
Valiantsin DzerakhandClaude Opus 5.5 8e05d2b409 Give textures a pool of their own with 64 MiB blocks
Textures shared the default 256 MiB blocks with the mirrors and other buffers, and a block went back to the driver
only once everything in it was gone. On the RX 9070 after a few minutes of roaming the field, 3 of 9 device-local
blocks were 13-27% full, held by a hundred small textures and buffers each, and blocks held 0.8-1.4 GB more than their
allocations; where device memory takes process commit, that commit backs nothing.

Own-memory textures now go to a VMA pool with 64 MiB blocks (TOTK_TEX_BLOCK_MIB, 0 = the default pools). Images of a
quarter block or more, images the driver wants a dedicated allocation for, and images the pool's memory type does not
take get memory of their own; the requirements are read before the image is made, since VMA checks neither for a
custom pool. The headroom thread keeps the pool's next block ahead like the default pools'.

Same 10-minute route: 807 MiB of blocks beyond their allocations instead of 1037, most pool blocks 75-100% full, slow
frames not up. Probes pass on v143.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-09 10:11:44 +03:00
Valiantsin DzerakhandClaude Opus 5.5 a79ff17314 Merge task/memcommit: count device memory against system memory where it takes process commit, BC3 for ASTC on integrated GPUs, cap the released-texture cache by bytes
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-09 09:58:10 +03:00
Valiantsin DzerakhandClaude Opus 5.5 0005c01cf5 Remove the stray brace in vk_mem_census that stopped vk_memory.c from compiling
79c6951 left the closing brace of a debug block in the per-heap loop, so the function ended early and the build failed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-09 09:57:32 +03:00
Valiantsin DzerakhandClaude Opus 5.5 34b340a208 Cap the released-texture cache by bytes
Released textures stayed until 2048 of them were kept or VRAM passed 90% of the budget. On the RX 9070 a 10-minute
field run kept 818 MiB of them, while almost every take-back came within a second. TOTK_TEX_RELEASED_MIB (default
256) runs the same drops as under VRAM pressure while the released entries hold more own memory than that. On the
same route the run ended with 1.1 GB less process commit and 1 GB less in VMA blocks; 15 dropped textures were
created again and the slow frames did not change.

Also documents TOTK_MEM_RESERVE_MIB.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-09 09:57:32 +03:00