23 Commits
Author SHA1 Message Date
itaskaev2andClaude Opus 5.5 6d6b66461b Reflex: one present ID per frame from its start to its present; mode again on a new swapchain; presentId feature
The latency markers and the present carried different present IDs: g_reflex_present_id went up only in flip_locked, so
frame k's simulation, input and submits had ID k and its present k+1 (and with frame_queue or replay_async frames could
share one). Each frame now gets its ID once, when the game acquires its window texture (SIMULATION_START,
vk_reflex_frame_begin), and carries it: INPUT_SAMPLE and SIMULATION_END take the game's current frame, a submission
the frame of the thread that submits it (the game thread's, or the one the replay thread got with its ReplayItem, or
the present thread's from its PresentJob), and the present the frame of its blit (PresentJob.pid -> g_flip_pid). A
present without a frame ID takes the next value, as present IDs must grow on a swapchain.

From the review: a new swapchain sets the sleep mode again (it starts with low latency off), Reflex is off without the
presentId feature, REFLEX sorted in known[], and the ru and pt-BR descriptions name the Boost option as the menu does.

TOTK_TRACE=perf logs every 600 presents the frame start to present time, and with Reflex on how many of the driver's
reports (vkGetLatencyTimingsNV) came back with every marker and their simulation start to GPU render end.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 18:20:16 +01:00
Tears of the SteelTemple 3209ea4358 Implement Native NVIDIA Reflex Low Latency (VK_NV_low_latency2)
- Enable VK_NV_low_latency2 and VK_KHR_present_id with present ID features
- Add VkSwapchainLatencyCreateInfoNV to swapchain creation
- Link present and submission IDs with standard Vulkan latency types
- Insert latency markers: simulation start/end, input sample, render submit, and present
- Gate all extensions and latency chains on reflex != off (RESTART setting)
- Log graceful notice when Reflex is requested on unsupported hardware
- Add UI menu setting and translations for en, ru, pt-BR, zh-Hans
- Document reflex setting in totk.ini.example and docs/settings.md
2026-11-10 18:20:16 +01: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 79c6951688 Measure whether device-local memory takes process commit instead of assuming it per vendor
c838d96 counted system memory for every discrete GPU but NVIDIA's, an assumption. An RTX 5080 log (#398) showed 10.4 GB
of process commit at frame 1200, about what the RX 9070 holds with its VRAM counted, and the RTX 3060 Ti in #670 ran
out of system commit (17.8 GB) at 4K with its VRAM full. vk_mem_host_probe now allocates 128 MiB of device-local memory
once after device creation and compares the process commit before and after; half the size or more turns the system
memory cap on. The log line carries the measured amount, so user logs show what each driver does.

RX 9070: "a 128 MiB device-local allocation took 128 MiB of process commit".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-09 09:39:54 +03:00
Valiantsin DzerakhandClaude Opus 5.5 dc45de0e9a Stamp deferred frees with the submission being recorded, whichever thread destroys the object
With the synchronous replay (the default since 7be68ec) a game thread finalizing a texture destroys released texture
cache entries while another game thread records a submission that slot_resolve may already have handed one of them.
defer() saw the recording's value only on the recording thread and stamped the others with the last submitted value,
so the completion thread freed the image before the submission naming it ran: "write invalid" device faults on NVIDIA
(#788, #802). vk_sync_submit now notes the value at the start of the recording, and every deferral made from then on
waits for it. A fight run counted 10 such deferrals during the world load.

Device faults now log the deferred-free state, and with VK_EXT_device_address_binding_report the object that held the
faulting address and whether it was unbound before the fault (TOTK_ADDR_REPORT=0 turns the map off). The census line
counts deferrals made off the recording thread during a recording.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-07 19:16:50 +03:00
Valiantsin DzerakhandClaude Opus 5.5 57037ccc29 Deswizzle block-linear textures on the GPU when their storage is an imported pool
The replay thread deswizzled every block-linear texture on the CPU, and entering a new area stalled it for 50-236 ms. Now a compute pass reads the texture straight from the pool's imported buffer and writes a linear copy into a device-local scratch pool; the upload batch copies it into the image, or the ASTC decoder takes it. Large texture loads submit the batch early so the staging and scratch pools do not grow on the replay thread, and both pools are made at device creation.

On fight2 the render thread waits about 270 ms on textures per run instead of 900, and the load frame drops from 145 to about 80 ms. Mean fps is unchanged. TOTK_DESWIZZLE=cpu turns it off and check compares every upload with the CPU result (0 of 196k regions differ). Shadow mode (Linux/Wine) and textures outside the device's limits stay on the CPU.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-07 16:38:26 +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 f700c28cc4 Merge pull request #113: Add NVIDIA DLSS/DLAA and a toggle for the game's FXAA (DizzyMan1337)
The sampler keeps both the DLSS mip bias and pull request #321's anisotropic level; DLAA's pass hook runs after the
contact shadows'; the extension arrays grow for NGX's extensions beside HDR's and the calibrated timestamps.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 11:40:27 +03:00
Valiantsin Dzerakh f30bbf048a Merge pull request #281: Add HDR10 output (ProSep)
# Conflicts:
#	THIRD_PARTY_NOTICES.md
#	runtime/cfg.c
#	runtime/vk.h
#	runtime/vk_device.c
2026-11-01 11:15:24 +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
SchulzCode 9e079622dc Merge main (0.2.1) into the DLSS branch
Conflicts: the known-key and section lists in cfg.c keep both sides; vk_backend.c, vk_device.c and vk_exec_draw.c include platform.h and vk_dlaa.h; create_instance takes the window's instance extensions from gfx_window_vk_extensions as on main, in a 12-entry array for NGX's.
2026-10-31 16:19:27 +01:00
lowlevel-larryandClaude Opus 5.5 c79b5f6cf7 Split the GPU's idle time by whether the next part was submitted yet, with calibrated timestamps
The perf line's "bound" said cpu at 640x360 on a Ryzen 5 4600G (Vega 7, RADV) and also at 1600x900, where lowering the
resolution showed the GPU held the frame back; the GPU busy time alone cannot tell the two apart. With
VK_KHR/EXT_calibrated_timestamps the GPU timestamps of each part go on the CPU clock (QPC on Windows, CLOCK_MONOTONIC
elsewhere), each part records when it was handed to vkQueueSubmit2, and a third perf line splits the gap before each
timed part: submitted after the previous part ended (the GPU waited for the replay or the game) or already queued
(untimed uploads and presents, or a wait). It also gives the gaps over 0.5 ms, the longest one and the mean time from
submit to start.

On the 4600G at 640x360 (44 fps) it reads 11.3 ms idle a frame, 10.3 ms of it waiting for the next submission, in 3-4
gaps of up to 8 ms, with the replay at 16 ms a frame: the GPU starves behind the replay. Without the extension, or when
the driver refuses the domain pair, the line is left out. Only TOTK_TRACE=perf and the full overlay time the GPU.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 11:42:51 -03:00
Valiantsin DzerakhandClaude Opus 5.5 43a18a9bb1 Merge pull request #60: Linux port (AppImage) and Steam Deck support (wdiasjunior)
The branch forked 79 commits before main and 98 before dev. Resolutions:

1. Aspect ratio: dev's implementation stays (camera patch at page +56 on 1.4.3, tools/ultrawide_layout.py layouts per
   size in romfs-patches-<w>x<h>, the aspect = fit|stretch setting). The PR's second implementation is dropped: the
   aspect sets of patches-v121.txt and patches-v143.txt (the 1.4.3 one patched the same viewport sites as dev's),
   tools/aspect_layouts.py, the resolution.c shapes that limited game resolutions to 16:9, 16:10 and 21:9, and the
   picture_fit setting. Its letterbox code (gfx_fit_rect) is kept and reads TOTK_ASPECT.
2. Code dev changed where the PR moved it: the stick dead zone, the test gamepad and the paddles go to input.c; the
   DPI awareness, keep-awake and IME detach of gfx_window.c go to gfx_window_win.c; device fault reports and GPU
   breadcrumbs to gfx_present.c. gfx_window_dpi gets an SDL version.
3. dev's Win32 calls in shared code go through platform.h: the shader cache pack reader (PlatFile), the romfs
   overlay checks, the audio pacing waits, the motion, ASTC and device fault locks. plat_cpu_usable and
   plat_commit_info get Linux versions; plat_cpu_count counts the machine's processors on both. dpi_probe.c becomes
   dpi_probe_win.c.
4. assume_focus defaults to 1 as the PR has it (a load interrupted by a focus loss can stop for good) and stays live,
   with dev's Game tab row.
5. The frame limits 40 and 45 join dev's list. The BC 3D storage fallback for Vega only runs with
   TOTK_BLOCK_VIEWS_3D=1, since dev makes 3D BC images without block views by default.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 13:26:42 +03:00
TotK localandClaude Opus 5.5 1512d9ed65 Add NVIDIA DLAA and a switch for the game's FXAA
DLAA runs DLSS at the scene's own size on the R11G11B10F light target, right before the bloom chain's first pass,
so bloom, post and HUD read the anti-aliased picture. NGX is loaded from the driver's NGX core at run time; no NVIDIA
SDK code is compiled in, and nvngx_dlss.dll goes next to totk.exe. The scene's draws get a Halton(2,3) viewport
jitter that steps after each DLAA run; camera motion vectors come from the scene depth reprojected through this and
last frame's view-projection of the scene camera block (c4), read from the uniform snapshot. One DLSS feature per
scene size keeps dynamic resolution from stalling. dlaa and fxaa switch live from the settings menu; fxaa skips the
draw of the game's FXAA pass.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 03:34:55 +08:00
Wellington Dias b7baf43332 Keep the Linux setup's temp files and Mesa's shader cache with the game, and stop the setup with one message on a glibc older than 2.34.
A Steam Deck tester had 1.2 GB free in /home, where the setup put its 1.3 GB of generated C and objects
(~/.cache/totk-setup) and RADV its shader cache (up to 1 GB, about 35 MB a minute at the title screen), while the game
goes to the SD card. The setup's temp is now .setup-temp in the install folder (--temp changes it; the empty-folder
check leaves it out), and totk points MESA_SHADER_CACHE_DIR at mesa-cache beside itself unless it is set. A scan of
every ELF file in the release folder showed the bundled LLVM and the cryptography wheel need glibc 2.34, not the 2.31
the docs gave: make_release_linux.py now checks that floor (check_glibc), the setup's check stops below it
(check.glibc_old) instead of failing on a compiler that cannot start, and the docs give both floors. The Linux notes
also record the testers' results, that the Deck has the host-import extension too, and its software ASTC decoding.
2026-10-30 14:56:54 -03:00
Valiantsin DzerakhandClaude Opus 5.5 43704c0d9f Turn off the recorder thread on AMD GPUs and GPL on AMD's RDNA 1/2 driver, and log GPU breadcrumbs on a lost device
AMD drivers lost the device at boot or at menu opens with the recorder thread; vk_recorder = 0 ended it for three
RX 9070 XT users (issue #5), and RADV saw an illegal opcode at the end of a command buffer (issue #40). It now
defaults to off on vendor 0x1002; TOTK_VK_RECORDER=1 turns it back on.

On AMD's separate driver branch for RDNA 1/2 ("AMD proprietary shader compiler") every device loss came with a cold
pipeline cache and draws waiting on fast-linked pipelines, and the recorder setting did not help there. TOTK_GPL now
has no fixed default: off on that branch, on elsewhere.

VK_AMD_buffer_marker breadcrumbs (vk_crumbs.c) mark the start and end of each submission part, upload batch, ASTC
decode chunk and present; on device lost the log names the last point the GPU reached and the last one it finished.

vk_fsr.c ensure_images held no queue lock around vkDeviceWaitIdle, which needs every queue externally synchronized.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 19:48:38 +03:00
Valiantsin DzerakhandClaude Opus 5.5 112fb2dd74 Log the VK_EXT_device_fault report when the device is lost
vk_device_fault_report queries vkGetDeviceFaultInfoEXT once per process after VK_ERROR_DEVICE_LOST and logs the
description, the faulting addresses with type and precision, and the vendor codes. The submit, upload, occlusion
query and wait fatals call it before rt_fatal, and the present path calls it on a failed acquire, blit submit or
present. Threads that lose the device together wait until the report is written. The extension counts as usable only
when the driver reports the deviceFault feature. No cost unless the device is lost.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 13:21:14 +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 d1149e5060 Allocate the next VMA block of each memory type on a background thread: a new block made by another thread wakes vk_headroom.c, which allocates half a block every 500 ms and keeps it as the anchor of a block it had to create, so the render thread finds room instead of calling vkAllocateMemory for 8-19 ms; no headroom above 85% of the VRAM budget (TOTK_VRAM_HEADROOM)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 16:05:24 +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 9a859dfb2c Decode ASTC textures with a compute shader in the upload batch, or upload them natively where the device samples ASTC, behind TOTK_ASTC
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 14:42:51 +03:00
Valiantsin DzerakhandClaude Opus 5.5 04314ef476 Count what a VRAM mirror of buffer-bound pools would upload under TOTK_TRACE=perf
At the start of every submit the dirty census queries write watch over the imported pools the replay bound as vertex,
index, uniform, storage or indirect buffers, stamps the shared page generations and logs eager, lazy and first-use
bytes per frame and per submit by pool class as mem: dirty every 60 frames, with FlushMappedRange calls and bytes and
the live and cumulative mirror size. The device class line (uma or discrete, heaps and memory types) is logged once at
device selection and the pool census also at frame 600. perf_summary.py summarises the new lines.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 00:12:47 +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