diff --git a/docs/releases/v0.9.3.md b/docs/releases/v0.9.3.md index 3d967b56..2eb81315 100644 --- a/docs/releases/v0.9.3.md +++ b/docs/releases/v0.9.3.md @@ -11,9 +11,19 @@ instead of 47.8 standing. Its pictures matched standing, along the route and through warps to five areas, but it is new: leave it off to play, and report what you see if you try it. It does nothing without one of those upscalers, and nothing yet on NVIDIA and Intel cards, where the lazy write-back is on. +- **Experimental: the replay workers take more of a frame off the game's render thread** (`replay_pipe` and + `replay_small` in nx2navi.ini, both 0 by default, both with `replay_workers`; contributed by epicmeme546). With + `replay_pipe = N`, 1 to 4, the thread goes on past up to N groups of draws its workers still record. With + `replay_small = N` as well, a group of N draws or more that is too small to share out goes whole to one worker. On + the same PC standing in Kokiri Forest, with `tail_early = 1`: 60.5 fps with 3 workers alone, 62.2 with 5 workers and + `replay_pipe = 4`, 63.2 with `replay_small = 16` added, against 45.4 with all four settings off. The pictures matched + there and through warps to five areas. ## Changed - **The draw replay on several CPU cores is off by default again** (`replay_workers = 0`). With three workers on by default in 0.9.1 and 0.9.2 some players' games ended with a lost graphics device; the cause is not found yet. The settings menu has it under Game, Testing, as *Replay workers (experimental)*: 0 to 8, after a restart. +- **The other experimental performance settings have rows there too**: *Worker groups in flight* (`replay_pipe`), + *Small groups to one worker* (`replay_small`) and *Early frame end* (`tail_early`). A row whose setting does nothing + without another one is greyed out and says which it needs. diff --git a/nx2navi.ini.example b/nx2navi.ini.example index 1a7abada..ca84c394 100644 --- a/nx2navi.ini.example +++ b/nx2navi.ini.example @@ -79,11 +79,13 @@ # results it reads are there. A frame whose end hands the game anything else runs as before. Default: 0. Standing in # Hyrule Field on an RX 7900 XT with FSR 4: 50.7 instead of 42.5 fps, and 63.5 instead of 49.4 with replay_workers = 3. # 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, Early frame end. # tail_early = 0 # EXPERIMENTAL, with replay_workers. replay_pipe = N (1 to 4, default 0): the submitting thread goes on past up to N # groups its workers still record. replay_small = N (default 0, needs replay_pipe): a group of N draws or more that is # too small to share out goes whole to one worker. 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. +# 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, Worker groups in flight and Small groups to one worker. # 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 diff --git a/runtime/ui/menu.cpp b/runtime/ui/menu.cpp index 6b791da5..cfeddcd8 100644 --- a/runtime/ui/menu.cpp +++ b/runtime/ui/menu.cpp @@ -1412,8 +1412,15 @@ static void tab_game(float scale) { rows_saves(); // Testing: experimental rows, then the debug menu where the game version has it opt_group_text("Testing"); - // vk_exec.c rw_init reads it at start: the row notes the restart and the bar's Restart does it + // vk_exec.c rw_init and tail_enabled read these at start: each row notes the restart and the bar's Restart does + // it. A row whose setting does nothing without another one (rw_init) is greyed out until that one is set. opt_slider("NX2NAVI_REPLAY_WORKERS", UI_MENU_REPLAY_WORKERS, 0, 8, UI_MENU_REPLAY_WORKERS_DESC, 1, "%.0f"); + const bool workers = cfg_int("NX2NAVI_REPLAY_WORKERS") > 0, pipe = workers && cfg_int("NX2NAVI_REPLAY_PIPE") > 0; + if (!workers) opt_disable_next(UI_MENU_NEEDS_WORKERS); + opt_slider("NX2NAVI_REPLAY_PIPE", UI_MENU_REPLAY_PIPE, 0, 4, UI_MENU_REPLAY_PIPE_DESC, 1, "%.0f"); + if (!pipe) opt_disable_next(workers ? UI_MENU_NEEDS_PIPE : UI_MENU_NEEDS_WORKERS); + opt_slider("NX2NAVI_REPLAY_SMALL", UI_MENU_REPLAY_SMALL, 0, 64, UI_MENU_REPLAY_SMALL_DESC, 4, "%.0f"); + opt_toggle("NX2NAVI_TAIL_EARLY", UI_MENU_TAIL_EARLY, UI_MENU_TAIL_EARLY_DESC); // The debug menu, a tool for testing with English text of its own: off unless switched on here if (dbg_supported()) { const bool on = cfg_bool("NX2NAVI_DEBUG_MENU"); diff --git a/runtime/ui_text.c b/runtime/ui_text.c index 3b5de514..44279421 100644 --- a/runtime/ui_text.c +++ b/runtime/ui_text.c @@ -473,8 +473,24 @@ static const char *const text_en[UI_TEXT_COUNT] = { [UI_MENU_REPLAY_WORKERS] = "Replay workers (experimental)", [UI_MENU_REPLAY_WORKERS_DESC] = "CPU threads that help translate each frame's draws for the GPU, beside the game's own " "thread. 3 gave about 20% more frames a second in Hyrule Field on an 8-core CPU; more " - "than 3 gave nothing more. Some players' games crashed with them on: 0 (off) is the " - "safe choice. Takes effect after a restart.", + "than 3 gave little more. Some players' games crashed with them on: 0 (off) is the " + "safe choice.", + [UI_MENU_REPLAY_PIPE] = "Worker groups in flight (experimental)", + [UI_MENU_REPLAY_PIPE_DESC] = "How many groups of draws the replay workers may have in hand at once while the game's " + "render thread goes on to the draws after them. At 0 the thread waits for each group " + "and helps with it. 2 to 4 gave 1 to 2% more frames a second with 5 workers and the " + "early frame end on, and nothing without it.", + [UI_MENU_REPLAY_SMALL] = "Small groups to one worker (experimental)", + [UI_MENU_REPLAY_SMALL_DESC] = "A group of at least this many draws that is too small to split between workers goes " + "whole to one worker, and the game's render thread goes on. 0 is off: the thread " + "records such groups itself. 16 gave about 2% more frames a second in Kokiri Forest.", + [UI_MENU_TAIL_EARLY] = "Early frame end (experimental)", + [UI_MENU_TAIL_EARLY_DESC] = "Lets the game start its next frame while the GPU still runs the upscaler and the rest " + "of the frame's end. With FSR 4 on a Radeon RX 7900 XT it gave 19 to 29% more frames a " + "second in Hyrule Field, measured on that card only and not in long sessions. It needs " + "TAA, or DLSS, FSR 3.1 or FSR 4 under Upscaling, and for now an AMD card: without " + "them the game runs as before.", + [UI_MENU_NEEDS_WORKERS] = "needs replay workers", [UI_MENU_NEEDS_PIPE] = "needs worker groups in flight", [UI_MENU_DISCORD_RPC] = "Discord Rich Presence", [UI_MENU_DISCORD_RPC_DESC] = "Shows \"Playing NX2navi\" with the play time in your Discord status while the " "game runs. discord_app_id and discord_image in nx2navi.ini choose the application.", diff --git a/runtime/ui_text.h b/runtime/ui_text.h index 13cfb95e..04266add 100644 --- a/runtime/ui_text.h +++ b/runtime/ui_text.h @@ -165,7 +165,10 @@ typedef enum { // Menu tab UI_MENU_MENU_LANG, UI_MENU_MENU_LANG_DESC, UI_MENU_MENU_LANG_AUTO, UI_MENU_DISCORD_RPC, UI_MENU_DISCORD_RPC_DESC, UI_MENU_LOW_END_GPU, UI_MENU_LOW_END_GPU_DESC, - UI_MENU_REPLAY_WORKERS, UI_MENU_REPLAY_WORKERS_DESC, // the Game tab, English only + // the Game tab's Testing rows (ui/menu.cpp tab_game), English only + UI_MENU_REPLAY_WORKERS, UI_MENU_REPLAY_WORKERS_DESC, UI_MENU_REPLAY_PIPE, UI_MENU_REPLAY_PIPE_DESC, + UI_MENU_REPLAY_SMALL, UI_MENU_REPLAY_SMALL_DESC, UI_MENU_TAIL_EARLY, UI_MENU_TAIL_EARLY_DESC, + UI_MENU_NEEDS_WORKERS, UI_MENU_NEEDS_PIPE, // why a row is greyed out // Language names, each in its own language and the same in every row (game language and menu language lists) UI_MENU_LANGNAME_EN, UI_MENU_LANGNAME_JA, UI_MENU_LANGNAME_FR, UI_MENU_LANGNAME_DE, UI_MENU_LANGNAME_IT,