16 Commits
Author SHA1 Message Date
Valiantsin DzerakhandClaude Opus 5.5 213bc6af6a Wait out a short out-of-memory spell instead of ending the game
Crash logs ended in fatal errors when the system's commit ran out for a moment: a staging buffer (-2), a guest commit
with the system at 24442 of 24447 MB, image creation (-2). Windows grows a system-managed page file and some drivers
charge device memory to the process commit, so the same request often succeeds a moment later.

oom.c holds the wait nvn_api_cmd.c realloc_wait already used: it requests a release, retries every 10 ms for up to
30 s, logs the first 8 with the commit numbers. rt_oom_request sets a flag that vk_texture_new_submit takes (one atomic
load per submit): it drops up to 256 released textures of the two kinds sweep_pressure drops (overwritten, clean
mirrored), never GPU-written content, and frees the headroom blocks. vk_oom_release does at once what needs no submit:
headroom blocks, finished upload batches and deferred objects.

- memory.c commit: waits and retries without frz_lock between tries; every caller waits, boot ones too.
- vk_staging and the draw-data chunks (vk_exec_draw.c scratch): release, then wait; the open upload batch is not
  submitted, its caller still records into it.
- create_tex: release and one retry; no wait under the texture lock, the texture is asked for again at its next use.
- the texture write-back buffer: release, then wait.
- the headroom thread keeps no spare block for 30 s after a failure.

TOTK_TEST_OOM=<site>:<n> (commit, staging, image, chunk) fails the first n attempts; probe-kernel forces 3 refused
commits, probe-vkexec 2 staging buffers, 1 image and 1 chunk, and both pass through them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-09 09:53:30 +03:00
Valiantsin DzerakhandClaude Opus 5.5 835310412c Copy a mirrored pool's flushes as exact ranges, so far-apart small flushes stop copying the pool between them
nvn_pool_flushed kept one span from the lowest to the highest flush of a pool and mirror_sync copied all of it. In
Kakariko one 252 MiB pool copied 22,121 MiB for 847 MiB flushed, in spans of up to the whole pool. Over PCIe 3.0 x8
(RX 6600, Ryzen 5 5500, issue #698) a typical span takes about 30 ms of GPU time, which fits the frame spikes there.

A pool now keeps up to 32 sorted ranges and merges the two nearest above that. Writes between ranges still reach the
mirror through the write watch. Over a walk in Kakariko the upload fell from 472.8 to 125.5 MiB and no flush range
reached 16 MiB. TOTK_FLUSH_SPAN=1 restores the span. The mirror summary gains a line with the upload by source, and
--probe-vkexec checks the range list and that two far-apart flushes copy only their pages.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:41:54 +03:00
Valiantsin DzerakhandClaude Opus 5.5 329acf81d2 Merge pull request #501: Keep a texture's pool flags instead of reading its pool object later (lowlevel-larry)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 17:02:31 +03:00
lowlevel-larryandClaude Opus 5.5 3675286747 Keep a texture's pool flags instead of reading its pool object later
tex_mirrored (vk_texture.c) read t->pool->flags whenever the back end created the host entry of a texture, which can
happen long after nvnTextureInitialize. A game may finalize a memory pool and free the memory the NVNmemoryPool object
lived in while textures from it are still looked up (on a level change, for instance); reading the freed object then
faults. The NVN driver keeps no pointer to the pool either. tex_t now records the pool's flags at Initialize, in the
padding after layout[8], so NVNtexture's size is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 10:40:51 -03:00
Valiantsin DzerakhandClaude Opus 5.5 710b7f5dd0 The device-lost report names the pass or dispatch the GPU was running
The replay marks the start and the end of every render pass and dispatch
(vk_exec.c vk_exec_pass_begin and vk_exec_pass_end, vk_exec_draw.c
op_dispatch and op_dispatch_ind), outside the pass so no pass is broken.
With VK_AMD_buffer_marker the GPU writes the last started and finished mark
into words 2 and 3 of the breadcrumb buffer; with
VK_NV_device_diagnostic_checkpoints the same points are checkpoints, read
with vkGetQueueCheckpointData2NV after the loss. A ring of 4096 records maps
a mark to its submission, index, target formats and size, draw count and the
input ids of the first and last draw's shaders. vk_device_fault_report logs
both marks with their records. The calls go through the recorder thread.

TOTK_PASS_CRUMBS (menu: GPU pass marks): unset, AMD buffer marks only; 1,
also NVIDIA checkpoints, whose extension is enabled only then; 0, none.
The design follows Savage Wind Recomp 3fae40c; the code is ours.

--probe-vkexec gets a pass marks part: pass, dispatch, pass in one
submission; the marks read back after the fence name the last pass and the
report text says so.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 09:50:30 +03:00
Valiantsin DzerakhandClaude Opus 5.5 b6ab660b00 A zero-byte memory pool initialises as an empty pool in the Vulkan back end
vk_pool_init gave a size-0 pool with storage a record: the host import of 0 bytes failed (the driver refuses the
memory, VK_ERROR_INVALID_EXTERNAL_HANDLE) and the record went into the pool index as the empty range [mem, mem]. A
lookup at that address then found the empty pool before the pool that starts there and reported it unbacked. TotK
makes such pools now and then (MacNativeGames d3407e29, 1.2.1). Such a pool now gets no record, as a GPU_NO_ACCESS
pool; vk_pool_fini finds none and does nothing. Removal by key already kept a neighbour's range safe at Finalize.

--probe-vkexec gains an empty pool part: a zero-byte pool at the start of another, lookups there before and after
its Finalize. It failed before ("a lookup at the start of a pool finds the empty pool there").

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 09:14:10 +03:00
ProSepandClaude Opus 5.5 007786d487 Add HDR10 output
With hdr = 1 the game's tonemap shader is replaced by one that keeps highlights up to the display's peak, the present
reads the float picture the game copies into its 8-bit window texture, and a compute pass encodes it as PQ in Rec. 2020
for an HDR10 swapchain. Peak, paper white and HUD brightness are live settings in the menu and totk.ini. The approach
follows the RenoDX TotK mod by souperman9 and Musa; no code was copied.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 21:17:12 +01:00
Wellington Dias 7766716e16 Fill a window one pixel wider than the picture, and let the probes use the shader census of either game version.
gfx_fit_rect rounded the picture up to an even size, so at 1167x656 a 16:9 picture was 1166 wide and the last column
stayed black, which failed --probe-vkexec; it now takes the window's parity, which keeps the bars equal at any size.
The present check of --probe-vkexec expects the picture's rectangle and black bars, as --probe-window does, so it
passes on a 16:10 screen too. --probe-shader, the draw part of --probe-vkexec and the pipeline self-test looked only
for build/v121/shaders; probe_census_dir takes the running version's census first, then the other one's. The Linux
notes say what the probes need over SSH.
2026-10-30 14:55:55 -03:00
Wellington Dias 1d51343ac1 Build and run the runtime natively on Linux.
Shared runtime code now goes through runtime/platform/platform.h, implemented by platform/win32.c and a new
platform/linux.c: futex locks, a userfaultfd and PAGEMAP_SCAN write watch, signal-based async preemption, our own
fiber switch, and a SIGSEGV handler for the thaw and crash hooks. The window, input, menu and software keyboard get
SDL3 back ends beside the Win32 ones, with the swapchain (gfx_present.c) and input merging (input.c) shared. SHA-256
replaces BCrypt, ELF builds get their own override sections, and the build tools gain Linux branches.

On Linux the selftest and the gfx-abi, astc, nvn and window probes pass. probe-vkmem still fails: imported guest
memory cannot be write-watched on Linux, which the shadow buffers in vk_memory.c will address.
2026-10-29 16:56:56 -03:00
Valiantsin DzerakhandClaude Opus 5.5 ce150130df Make code comments say what they mean instead of pointing at things a reader cannot follow
Comments cited codes from local notes (port-lessons P1, backlog), task labels (T6c1-T6c3, M4), bare upstream commit
hashes and issue numbers, a file that no longer exists (nvn_api.c, now nvn_api_*.c), a generated file (main_0103.c)
and line numbers into upstream files that refs/ has moved past, so they pointed at unrelated code. Those now name the
file, function or project and say what the cited code does. Attribution of copied code keeps its pinned commits.

Corrected facts: TOTK_REPLAY_ASYNC defaults to 0, and the shader cache, pipeline cache and pipeline keys live next to
totk.exe, not in build/v121.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 12:58:01 +03:00
Valiantsin DzerakhandClaude Opus 5.5 7abdbc90ac Render the game above 1080p and scale it to the window with FSR 1
The output and scene patch sets make the game read its output, swapchain and scene sizes from the patch page
(MacNativeGames' sites for 1.2.1 and 1.4.3); resolution.c picks them from TOTK_OUTPUT_RES and TOTK_RENDER_SCALE and
grows the HeapDef texture heap, its parent and the application pool to match. vk_fsr.c runs AMD FSR 1 EASU and RCAS
on the present when the window is larger than the game's output (TOTK_UPSCALER, TOTK_SHARPNESS).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 13:40:34 +03:00
Valiantsin DzerakhandClaude Opus 5.5 97d3762ba1 Strip milestone and task labels from code comments and drop the dead gfx_stubs.c
Comments named the agent task (T1-T7, M2-M5, Task 2.x) that once owned each file or block, and pointed at local
notes the repository does not carry (backlog items, milestone plans, research notes). They now say what the code
does. gfx_stubs.c held weak stand-ins for functions that every build has defined for a long time.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 13:12:50 +03:00
Valiantsin DzerakhandClaude Opus 5.5 8b514f6ead Keep every default in the settings table: cfg_value, cfg_int, cfg_double and cfg_bool read it, and the consumers of table keys drop their own defaults
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 09:32:30 +03:00
Valiantsin DzerakhandClaude Opus 5.5 1fe552ae0a Mirror buffer-bound pools in device-local memory on discrete GPUs
Imported pools put vertices, indices, constants and storage buffers in system memory, so discrete GPUs read them over
PCIe on every draw. A pool now gets a device-local mirror on its first use as a vertex, index, uniform, storage or
indirect buffer; bindings, buffer copies, fills and uniform updates use it at the same offsets. The first access of a
submission syncs the pages written since (write-watch snapshots shared with the texture checks, plus
nvnMemoryPoolFlushMappedRange ranges) in a prologue command buffer before the part; what the GPU writes into a mirror
goes back to guest memory at the end of the submission. TOTK_MEMORY=import|mirror|verify overrides the device class;
verify compares sampled mirror pages with guest memory at the fence. The vkexec probe gains a mirror part.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 00:45:56 +03:00
Valiantsin DzerakhandClaude Opus 5.5 ebdba400df Pace presents at the back edge, just before the host present
The pacer gave each frame its display time but the present thread queued vkQueuePresentKHR as soon as the game
handed the frame over, so every present shifted with the frame's replay time: at 60.0 fps mean, 17-18 ms intervals
alternated with 15-16 ms ones. The present thread now submits the blit at once (vk_present_blit, so
vk_present_drain and queue order are unchanged) and holds the host present until the pacer's slot
(vk_present_flip). Acquire keeps waiting until the image's slot plus one period, which is now the time the next
frame really goes out.

TOTK_TRACE=present logs one line per present: host interval, the game's present-call interval, wait and lateness.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 23:26:43 +03:00
Valiantsin DzerakhandClaude Opus 5.5 19c9b648d1 Add the recompiler, Windows runtime, tools and docs
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 22:27:54 +03:00