diff --git a/docs/releases/v0.10.2.md b/docs/releases/v0.10.2.md index 28f014eb..79f13975 100644 --- a/docs/releases/v0.10.2.md +++ b/docs/releases/v0.10.2.md @@ -14,16 +14,10 @@ cards). ## Changed -- **The Game tab's Testing settings are on by default:** - - *CPU helper threads*: Automatic (`replay_workers = auto`): half the CPU's cores less one, none on four cores or - fewer and none on AMD's driver for Radeon RX 6000 and older; - - *Helpers work ahead*: 4 (`replay_pipe = 4`); - - *Helpers take small jobs*: 16 (`replay_small = 16`); - - *Start next frame early*: On (`tail_early = 1`). - - The first and the last were already so in 0.10.1; the two in the middle are new. They are still experimental. A - value you chose yourself, in the settings menu or in nx2navi.ini, stays as you set it: to keep 0.10.1's behaviour, - set *Helpers work ahead* and *Helpers take small jobs* back to 0. +- **The Game tab's Testing settings keep 0.10.1's defaults:** *CPU helper threads* Automatic + (`replay_workers = auto`), *Start next frame early* On (`tail_early = 1`), and *Helpers work ahead* and *Helpers + take small jobs* off (`replay_pipe = 0`, `replay_small = 0`). The last two stay experimental: a tester's + measurement on an RTX 3090 found them slower at four of eight places and no more than 7 % faster at the others. - **Automatic texture detail is more careful with video memory** (`texture_detail = auto`): *Full* now starts at cards of 12 GB (10 GB cards get *Reduced*, as 8 GB cards do), and integrated graphics never get *Full*, because their video memory is the PC's own memory. With a card filled to the room of an 8 GB one, a tester measured 29.6 fps diff --git a/nx2navi.ini.example b/nx2navi.ini.example index a8850292..66cd207f 100644 --- a/nx2navi.ini.example +++ b/nx2navi.ini.example @@ -119,14 +119,16 @@ # Does nothing without one of those upscalers, nor with the lazy write-back (the default on NVIDIA and Intel cards). # Also in the menu: Game, Testing, Start next frame early. # tail_early = 1 -# EXPERIMENTAL, with replay_workers. replay_pipe = N (0 to 4, default 4): the submitting thread goes on past up to N -# groups its workers still record. replay_small = N (0 to 63, default 16, needs replay_pipe): a group of N draws or more +# EXPERIMENTAL, with replay_workers. replay_pipe = N (0 to 4, default 0): the submitting thread goes on past up to N +# groups its workers still record. replay_small = N (0 to 63, default 0, needs replay_pipe): a group of N draws or more # that is too small to share out (fewer than 64 draws) goes whole to one worker; 64 or more reads as 63. Kokiri Forest # standing on an RX 7900 XT with FSR 4, tail_early = 1, replay_workers = 5, replay_pipe = 4 and replay_small = 16: 63 -# instead of 45 fps with all of them off. Also in the menu: Game, Testing, Helpers work ahead (replay_pipe) and Helpers -# take small jobs (replay_small). Neither does anything without replay workers. -# replay_pipe = 4 -# replay_small = 16 +# instead of 45 fps with all of them off. On an RTX 3090 a tester measured the same three settings against the +# defaults at eight places: slower at four (50.1 instead of 58.1 fps at one) and level or up to 7 % faster at the +# other four. So both stay off unless you turn them on. Also in the menu: Game, Testing, Helpers work ahead +# (replay_pipe) and Helpers take small jobs (replay_small). Neither does anything without replay workers. +# replay_pipe = 0 +# replay_small = 0 # EXPERIMENTAL, THE GAME CRASHES WITH 1. 1 lifts the virtual core gate: guest threads run without the console's limit # of one thread per core, and the game keeps per-core data without locks. With 1 the game crashes or hangs, # usually at start. Keep 0 to play. diff --git a/runtime/cfg.c b/runtime/cfg.c index 515e9318..07c7e0c0 100644 --- a/runtime/cfg.c +++ b/runtime/cfg.c @@ -328,11 +328,11 @@ static const CfgMeta metas[] = { {"DISCORD_IMAGE", NX2NAVI_DISCORD_IMAGE_DEFAULT, NULL, LIVE}, // Advanced: scheduling {"ASYNC_PREEMPT", "1", "0|1|2", RESTART}, {"REPLAY_ASYNC", "0", "0|1", RESTART}, - {"REPLAY_PIPE", "4", "0..4", RESTART}, + {"REPLAY_PIPE", "0", "0..4", RESTART}, {"REPLAY_WORKERS", "auto", "auto|0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16", RESTART}, // vk_exec.c rw_init, vk_exec_replay_workers_auto // vk_exec.c "the early tail"; on by default since 0.10.0 {"TAIL_EARLY", "1", "0|1", RESTART}, - {"REPLAY_SMALL", "16", "0..63", RESTART}, // vk_exec.c group_start + {"REPLAY_SMALL", "0", "0..63", RESTART}, // vk_exec.c group_start {"FREE_CORES", "0", "0|1", RESTART}, {"TIMER_1MS", "1", "0|1", RESTART}, // dynamic resolution (dynres.c): the scene follows the GPU time toward DYN_RES_TARGET milliseconds (under 1: the // frame limit's frame time), holding each step DYN_RES_STEP 60 Hz frames of the clock diff --git a/runtime/vk_exec.c b/runtime/vk_exec.c index b032517c..6ee1cab0 100644 --- a/runtime/vk_exec.c +++ b/runtime/vk_exec.c @@ -1923,7 +1923,7 @@ static void op_one(VkExec *ex, const op_hdr *h) { // replays the op again once in turn, and so do the contact shadows' pass and the HDR pass's source. Per-object motion // lists its draws under a lock (vk_exec_draw.c mvobj_draw), and the occlusion queries' slots and segments follow the // stream (vk_exec_xfer.c vk_exec_xfer_slots, vk_exec_xfer_group_merge). -// NX2NAVI_REPLAY_PIPE=N (0-4, default 4): the submitting thread hands the group to the workers, takes chunks of it as +// NX2NAVI_REPLAY_PIPE=N (1-4, default 0): the submitting thread hands the group to the workers, takes chunks of it as // they do until none is left to take, and goes on with the ops after it, in a new command buffer after the chunks' // places in the part (vk_sync_append_later), while the last chunks are recorded; also into the front pass of the next // group: up to N (at most LIVE_GROUPS) groups are handed out and not in their part yet, their chunks taken from one @@ -2472,7 +2472,7 @@ static const op_hdr *group_start(VkExec *ex, const op_hdr *h, int depth) { int n = (int)(draws / CHUNK_DRAWS); if (n > RW.n + 1) n = RW.n + 1; if (n > GROUP_CHUNKS) n = GROUP_CHUNKS; - // NX2NAVI_REPLAY_SMALL=N (default 16, with NX2NAVI_REPLAY_PIPE): a group of N draws or more that is too small to cut + // NX2NAVI_REPLAY_SMALL=N (default 0, with NX2NAVI_REPLAY_PIPE): a group of N draws or more that is too small to cut // goes whole to one worker, and the submitting thread goes on with what follows it without taking the chunk // itself. Kokiri Forest standing, 5 workers, 4 groups out, the early tail on (2026-11-13): about 700 draws a frame // were in such groups, 3.6 ms of the submitting thread; with 16 the replay took 10.2 instead of 11.0 ms a frame