Settings menu: a Lama patches tab with the settings of the RX 580 patches

Released textures kept, top texture levels left out, hot pools in system memory, the heap limit, the upload batch
limit, the kept ASTC buffer, mesh emulation and its arena and task records (greyed where the GPU has mesh shaders),
the overwritten-texture fix, the vector index fix, -O2 game code, pass times and the frame dump key. Each key gets a
row in the settings table; make_game.py reads guest_opt from nx2navi.ini when the environment does not set it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Tobim6
2026-11-12 16:22:31 +01:00
parent f18639e055
commit 9259149527
7 changed files with 154 additions and 5 deletions

View File

@@ -421,6 +421,9 @@
# is read and written by the GPU in system memory instead (0: every pool keeps its video memory copy). For GPUs and
# buses short of bandwidth; on an RX 580 the pools the game refills every frame cost about 8 ms a frame in copies.
# mirror_hot = 0
# 2: the next Rebuild the Game compiles the game's code at -O2 instead of -O1 (faster game threads on a slower CPU, a
# build several times longer). Read by tools/make_game.py; the environment variable NX2NAVI_GUEST_OPT wins.
# guest_opt = 1
# GPUs without mesh shaders (VK_EXT_mesh_shader: AMD before RDNA 2, NVIDIA before Turing): 1 runs the game's mesh
# and task shaders (grass and other foliage) as compute shaders and draws what they make; 0 skips those draws. The
# arena for their vertices and triangles is mesh_emu_mb MiB of video memory, with mesh_emu_tasks task records (3 KiB

View File

@@ -61,6 +61,7 @@ static const char *const known[] = {
"ONE_PER_CORE", "OPERATION_MODE", "OUTPUT_RES", "PAD_LAYOUT", "PACE_HZ", "PASS_CRUMBS", "PATCH_OUTPUT", "PATCH_RES_FIXED", "PATCH_SCENE", "PATCH_WIDE_ASPECT", "PATCH_WIDE_HUD", "PATCH_WIDE_MOVIE", "PATCH_WIDE_OUT", "PATCH_FREECAM", "PATCH_WIDE_SCENE", "PCSS", "PCSS_K", "PERF_OVERLAY", "PERF_SLOW_MS", "PIPELINE_CACHE", "PIPELINE_CACHE_MAX_MB", "PIPELINE_CACHE_PLAY", "PIPELINE_CACHE_PLAY_MB", "PIPE_BINARIES", "PIPE_BINARIES_MAX_MB", "PIPE_FEEDBACK", "PIPE_MEMO", "PIPE_PREBUILD", "PIPE_SEED", "PIPE_SKIP", "PIPE_SYNC", "PIPE_WAIT", "POWER_FULL", "TEX_SAME", "TEX_FLAT3D", "TEX_KEEP_TAKEN", "TEX_STALE_KEPT", "PRESENT_HELD", "HELD_SYNC",
"PREPARE_PIPELINES", "PREWARM_FULL", "PREWARM_WAIT_MS", "PREWARM_XLATE", "PROBE_MOVIE", "PROBE_MOVIE_SHOT", "PROFILE", "PROFILE_CHAINS", "PROFILE_DIR", "PROFILE_FRAMES", "PROFILE_REPLAY", "PROFILE_SLOW",
"POOL_FAST", "POOL_GROUP", "POOL_GROUP_CHECK", "POOL_PRESNAP",
"SUBMIT_FINISH_GPU", "SVC_WAITS", "SNAP_WIDEN", "SUBMIT_FINISH_RESULTS", "SUBMIT_FINISH_KINDS", "FOLIAGE", "MIRROR_STAGE", "FLUSH_SKIP_CLEAN", "MIRROR_HOT", "MESH_EMULATION", "MESH_EMU_MB", "MESH_EMU_TASKS", "MESH_EMU_BATCH", "GUEST_OPT", "LOG_TEX_NEW", "DUMP_KEY", "VEC_INDEX_FIX", "PASS_TIMES",
"PROFILE_MAIN", "PROFILE_RENDER", "PROMPTS", "PUSH_SKIP", "PUSH_STAGE", "RDOC", "RDOC_DIR", "RDOC_DLL", "REALTIME", "REC_END", "REEXEC",
"REFLEX", "RENDER_SCALE", "REPLAY_ASYNC", "REPLAY_PIPE", "REPLAY_RUNS", "REPLAY_WORKERS", "RTSS", "RTSS_ENUM", "SCENE_SHARE",
"PRESNAP_PLACE",
@@ -73,6 +74,7 @@ static const char *const known[] = {
"SET_AT", "SWKBD_TEST", "TAA", "DBG_TEST", "DEBUG_MENU", "MENU_TEST_DEBUG", "FSR4", "FSR4_FG", "FG4_VERSION", "FG4_SWAPCHAIN", "TEST_PAD", "TEST_PAD_AT", "TEST_PREPARE_SHADERS", "TEX_ALIAS", "DEPTH_INIT_INLINE", "DEPTH_ALIAS_LOG", "TEX_DISUSE", "TEX_DISUSE_EVICT", "TEX_GEN_UNDO", "TEX_MEMO", "TEX_VRAM_PRESSURE", "TEX_RELEASED_MB", "TEX_RELEASED_MAX", "TEX_REUSE", "TEX_SPLIT_FILL", "TEX_COMMIT_FREE_MB", "TEX_PROC_COMMIT_MB", "TEX_EVICT", "TEX_COMMIT_EVICT", "MIRROR_EVICT", "VRAM_BUDGET_MB", "TIMER_1MS", "TRACE", "TXD_TRANSPOSE", "UBO_SNAPSHOT", "EVO_TRACE", "EVENT_AT_SYNC", "UPSCALER", "VK_DYN_A2C", "VK_DYN_VERTEX", "VK_NAN_PRESERVE", "VK_NOOPT", "VK_NO_FLOAT64",
"VK_PRESENT", "VK_RECONVERGE", "VK_NAN_BITS", "VK_RECORDER", "VK_SSBO_ALIGN", "VK_SUBGROUP", "VK_SUBGROUP_PIN", "VK_VALIDATION", "VOLUME", "VRAM_HEADROOM", "VS_OUTS", "WATER_PROJECTIVE",
"WAIT_WATCH_S", "WALK_KEY", "WALK_SCALE", "WB_EXACT", "WB_FENCE_LIMIT", "WB_MERGE", "WB_NO_REUP", "WB_MERGE_MAX", "WB_PROBE", "WB_SPLIT", "WB_LAZY", "WB_LAZY_CHUNK", "WB_LAZY_TOUCH", "WINDOW_SIZE", "XLATE", "XLATE_ID", "XLATE_KEEP", "XLATE_PROCS",
"UPLOAD_BATCH_MB", "VRAM_HEAP_LIMIT", "VRAM_RESERVE_MB", "TEX_CLOBBER",
"ZSTD_CHECK", "ZSTD_NATIVE",
"BIND_REUSE", "DYN_DELTA", "STG_ARENA", "SUBMIT_BATCH", "ASTC_GPU_DESWIZZLE", "ASTC_SCRATCH_KEEP", "ASTC_ARENA", "ASTC_BC1",
"TEXUP_LOG_MS", "DYN_RES", "DYN_RES_TARGET", "DYN_RES_STEP", "TEXTURE_DETAIL",
@@ -88,6 +90,8 @@ static const char *const known[] = {
// The nx2navi.ini section a key cfg_set may write goes to when the file lacks it (nx2navi.ini.example's sections).
static const struct { const char *key, *section; } sections[] = {
// the menu's Lama patches tab (ui/menu.cpp tab_lama)
{"GUEST_OPT", "performance"}, {"PASS_TIMES", "diagnostics"}, {"DUMP_KEY", "diagnostics"},
{"FPS_LIMIT", "frame rate"}, {"FPS60", "frame rate"}, {"RTSS", "frame rate"},
{"REALTIME", "frame rate"}, {"CLOTH_REALTIME", "frame rate"}, {"HIGHFPS_FIX", "frame rate"},
{"PHYSICS_STEPS", "frame rate"}, {"PICKUP_COUNT", "frame rate"}, {"STEP_STEADY", "frame rate"},
@@ -293,6 +297,12 @@ static const CfgMeta metas[] = {
// all|<count>: the compute pipelines the boot keeps, those dispatched most recently (vk_pipeline.c, compute-used.bin)
{"COMPUTE_KEEP", "512", NULL, RESTART},
{"SHADER_CARRY", "1", "0|1", RESTART}, // gfx_shader.c "Carry": a previous translator's translations until translated again
// the menu's Lama patches tab (ui/menu.cpp tab_lama): the settings of the RX 580 patches
{"TEX_RELEASED_MAX", "", NULL, RESTART}, // vk_texture.c released_max: "" by the video memory budget, else 1..16384
{"MIRROR_HOT", "25", "0..1000", RESTART}, {"FREEZE_IDLE", "1800", "0..100000", RESTART},
{"VRAM_HEAP_LIMIT", "auto", NULL, RESTART}, // vk_device.c vram_heap_limits: auto, 0 or MiB
{"UPLOAD_BATCH_MB", "256", NULL, RESTART}, // vk_memory.c: MiB of staging before a batch goes early, 0 no limit
{"PASS_TIMES", "0", "0|1", RESTART}, {"DUMP_KEY", "", NULL, RESTART}, // vk_crumbs.c, vk_dump.c
// textures and memory
{"ASTC", "auto", "auto|gpu|native|cpu", RESTART}, {"MEMORY", "auto", "auto|import|mirror|verify", RESTART},
{"TEX_ALIAS", "1", "0|1", RESTART}, {"DEPTH_INIT_INLINE", "1", "0|1", RESTART}, {"DEPTH_ALIAS_LOG", "0", "0|1", RESTART}, {"TEX_DISUSE", "1", "0|1|2", RESTART}, {"TEX_DISUSE_EVICT", "0", "0|1", RESTART}, {"TEX_GEN_UNDO", "1", "0|1", RESTART}, {"TEX_REUSE", "1", "0|1", RESTART}, {"TEX_SPLIT_FILL", "1", "0|1|2", RESTART}, {"TEX_VRAM_PRESSURE", "80", "0..100", RESTART}, {"ASTC_BC", "", "0|1", RESTART}, {"ZSTD_NATIVE", "1", "0|1", RESTART}, {"ZSTD_CHECK", "0", "0|1", RESTART},

View File

@@ -83,6 +83,7 @@ int vk_fg4_failed(void); // ... it failed in this run, FSR 3.1's
int vk_fg4_active(void); // ... its swapchain is in place
const char *vk_fg4_name(void); // ... the version the library runs here ("3.1.6", "4.0.2")
int vk_texture_detail_auto(void); // vk_texture.c: the texture detail auto picks on this card, 0 full to 2 low
int vk_mesh_shader_native(void); // vk_device.c: the GPU has mesh shaders (the mesh emulation does nothing)
double frame_step_limit_hz(void);
int frame_limit_adjustable(void);
int rtss_limit_state(void);
@@ -504,7 +505,7 @@ static int fonts_up(float scale) {
// what the title face shows in the CJK languages: the menu's title and tabs (Simplified Chinese menu text) and
// the boot screen's title (the game's language)
static const UiTextId titles[] = {UI_MENU_TITLE, UI_MENU_TAB_SCREEN, UI_MENU_TAB_GAME, UI_MENU_TAB_SOUND,
UI_MENU_TAB_CONTROLS, UI_MENU_TAB_COOP, UI_BOOT_TITLE};
UI_MENU_TAB_CONTROLS, UI_MENU_TAB_LAMA, UI_MENU_TAB_COOP, UI_BOOT_TITLE};
for (int i = 0; i < N; i++) {
if (!data[i]) continue;
ImFontGlyphRangesBuilder b;
@@ -572,8 +573,8 @@ extern "C" void menu_vk_release(void) {
// NX2NAVI_ prefix optional) puts the cursor on that setting's row and scrolls it into view when the row is next drawn
// (opt_focus_key), so a page's shot shows a row below the first screenful; it does not switch tabs. COOP_PAGE, COOP_JOIN
// and COOP_ACCEPT_OFFER drive the Co-op tab (ui/coop_page.h coop_test_set).
// Ocarina of Time: the options this port has and co-op (ui/coop_page.cpp)
enum { TAB_SCREEN, TAB_GAME, TAB_SOUND, TAB_CONTROLS, TAB_COOP, TAB_COUNT };
// Ocarina of Time: the options this port has, co-op (ui/coop_page.cpp) and the Lama patches tab (the RX 580 patches)
enum { TAB_SCREEN, TAB_GAME, TAB_SOUND, TAB_CONTROLS, TAB_LAMA, TAB_COOP, TAB_COUNT }; // co-op last: tabs_shown
enum { TEST_PAGE_FRAMES = 30, TEST_SETS = 16, TEST_OPENS = 8 };
struct TestSet { uint64_t frame; char key[64], value[64]; };
static struct {
@@ -1623,8 +1624,52 @@ static void tab_coop(float scale) {
coop_after_page(scale);
}
// ---- the Lama patches tab: the settings the RX 580 patches add (apply_rx580_fix), each read where its patch reads it
static void tab_lama(float scale) {
opt_begin("##lama", scale);
opt_text(UI_MENU_LAMA_INTRO);
opt_group(UI_MENU_LAMA_MEMORY);
{ // vk_texture.c sweep_released
static const char *const values[] = {"", "512", "1024", "2048", "4096", "8192"};
const char *names[] = {menu_text(UI_MENU_AUTO), "512", "1024", "2048", "4096", "8192"};
opt_choice_list("NX2NAVI_TEX_RELEASED_MAX", UI_MENU_LAMA_RELEASED, values, names, 6, UI_MENU_LAMA_RELEASED_DESC);
opt_slider("NX2NAVI_MIRROR_HOT", UI_MENU_LAMA_MIRROR_HOT, 0, 100, UI_MENU_LAMA_MIRROR_HOT_DESC, 5, "%.0f %%");
{ // vk_device.c vram_heap_limits
static const char *const values[] = {"auto", "0"};
const char *names[] = {menu_text(UI_MENU_AUTO), menu_text(UI_MENU_OFF)};
opt_choice_list("NX2NAVI_VRAM_HEAP_LIMIT", UI_MENU_LAMA_HEAP_LIMIT, values, names, 2, UI_MENU_LAMA_HEAP_LIMIT_DESC);
{ // vk_memory.c upload_batch_cap
static const char *const values[] = {"128", "256", "512", "1024", "0"};
const char *names[] = {"128 MB", "256 MB", "512 MB", "1024 MB", menu_text(UI_MENU_LAMA_NO_LIMIT)};
opt_choice_list("NX2NAVI_UPLOAD_BATCH_MB", UI_MENU_LAMA_UPLOAD_BATCH, values, names, 5, UI_MENU_LAMA_UPLOAD_BATCH_DESC);
opt_toggle("NX2NAVI_ASTC_SCRATCH_KEEP", UI_MENU_LAMA_ASTC_KEEP, UI_MENU_LAMA_ASTC_KEEP_DESC);
opt_group(UI_MENU_LAMA_RENDER);
const bool native = vk_mesh_shader_native() != 0; // vk_exec_draw.c: the emulation only where the GPU lacks them
opt_toggle("NX2NAVI_MESH_EMULATION", UI_MENU_LAMA_MESH_EMU, UI_MENU_LAMA_MESH_EMU_DESC);
}
opt_slider("NX2NAVI_MESH_EMU_MB", UI_MENU_LAMA_MESH_MB, 64, 2048, UI_MENU_LAMA_MESH_MB_DESC, 64, "%.0f MB");
opt_slider("NX2NAVI_MESH_EMU_TASKS", UI_MENU_LAMA_MESH_TASKS, 4096, 65536, UI_MENU_LAMA_MESH_TASKS_DESC, 4096, "%.0f");
opt_toggle("NX2NAVI_TEX_CLOBBER", UI_MENU_LAMA_CLOBBER, UI_MENU_LAMA_CLOBBER_DESC);
static const UiTextId vec[] = {UI_MENU_OFF, UI_MENU_LAMA_VEC_AUTO, UI_MENU_ON}; // gfx_shader.c patch_vec_index
opt_choice("NX2NAVI_VEC_INDEX_FIX", UI_MENU_LAMA_VEC_INDEX, vec, 3, UI_MENU_LAMA_VEC_INDEX_DESC);
opt_group(UI_MENU_LAMA_BUILD);
// tools/make_game.py reads it from nx2navi.ini at the next Rebuild the Game (guest_opt_ini)
opt_toggle_value("NX2NAVI_GUEST_OPT", UI_MENU_LAMA_GUEST_OPT, UI_MENU_LAMA_GUEST_OPT_DESC, "2", "1",
menu_text(UI_MENU_LAMA_GUEST_OPT_NOTE));
opt_group(UI_MENU_LAMA_DIAG);
opt_toggle("NX2NAVI_PASS_TIMES", UI_MENU_LAMA_PASS_TIMES, UI_MENU_LAMA_PASS_TIMES_DESC); // vk_crumbs.c
#ifdef _WIN32
{ // vk_dump.c: the keys it knows
static const char *const values[] = {"", "pause", "scrolllock", "insert", "f12"};
const char *names[] = {menu_text(UI_MENU_OFF), "Pause", "Scroll Lock", "Insert", "F12"};
opt_choice_list("NX2NAVI_DUMP_KEY", UI_MENU_LAMA_DUMP_KEY, values, names, 5, UI_MENU_LAMA_DUMP_KEY_DESC);
}
#endif
opt_end();
}
static const UiTextId kTabNames[TAB_COUNT] = {UI_MENU_TAB_SCREEN, UI_MENU_TAB_GAME, UI_MENU_TAB_SOUND,
UI_MENU_TAB_CONTROLS, UI_MENU_TAB_COOP};
UI_MENU_TAB_CONTROLS, UI_MENU_TAB_LAMA, UI_MENU_TAB_COOP};
static int g_tab; // the tab shown
// The tabs the menu shows: the Co-op tab is a beta, shown only with coop_beta = 1 in nx2navi.ini (NX2NAVI_COOP_BETA),
@@ -1751,6 +1796,7 @@ static void layout_menu(uint32_t w, uint32_t h, float scale) {
case TAB_SOUND: tab_sound(scale); break;
case TAB_CONTROLS: tab_controls(scale); break;
case TAB_COOP: tab_coop(scale); break;
case TAB_LAMA: tab_lama(scale); break;
}
ImGui::EndTabItem();
}

View File

@@ -89,6 +89,59 @@ static const char *const text_en[UI_TEXT_COUNT] = {
[UI_MENU_TEX_DETAIL_DESC] = "Sharpness of large surface textures. Reduced and Low leave out their largest versions, so that an area fits the video memory of 6 and 8 GB cards; only surfaces seen up close look softer. Automatic picks by the card's video memory.",
[UI_MENU_TEX_DETAIL_AUTO] = "Automatic: %s",
[UI_MENU_TEX_DETAIL_FULL] = "Full", [UI_MENU_TEX_DETAIL_REDUCED] = "Reduced", [UI_MENU_TEX_DETAIL_LOW] = "Low",
[UI_MENU_TAB_LAMA] = "Lama patches",
[UI_MENU_LAMA_INTRO] = "Settings of the RX 580 patches (apply_rx580_fix). Most take effect after a restart.",
[UI_MENU_LAMA_MEMORY] = "Video memory and textures",
[UI_MENU_LAMA_RENDER] = "Rendering",
[UI_MENU_LAMA_BUILD] = "Build",
[UI_MENU_LAMA_DIAG] = "Diagnostics",
[UI_MENU_LAMA_RELEASED] = "Released textures kept",
[UI_MENU_LAMA_RELEASED_DESC] = "How many textures the game has released are kept as they are; past it only those that "
"lose nothing when dropped go. Fewer leaves more video memory for the rest; more "
"saves making them again; too few lets some blink black for a moment. Auto: one per 2 MB "
"of the video memory budget, 2048 to 8192.",
[UI_MENU_LAMA_CLOBBER] = "Fix overwritten textures",
[UI_MENU_LAMA_CLOBBER_DESC] = "A texture the game reads after another image was drawn over its memory gets memory of "
"its own. Fixes the teal splotches in Kokiri Forest's fog.",
[UI_MENU_LAMA_MIRROR_HOT] = "Pools copied every frame stay in system memory",
[UI_MENU_LAMA_MIRROR_HOT_DESC] = "A game memory pool whose copies to and from video memory each frame reach this "
[UI_MENU_LAMA_HEAP_LIMIT] = "Video memory heap limit",
[UI_MENU_LAMA_HEAP_LIMIT_DESC] = "Auto: on GPUs with a second video memory heap (an RX 580 shows 6 GB and 2 GB), "
"each heap is filled only to its budget before the next one is used, so the "
"driver does not run out. Off: no limit.",
[UI_MENU_LAMA_UPLOAD_BATCH] = "Upload batch limit",
[UI_MENU_LAMA_UPLOAD_BATCH_DESC] = "Texture uploads waiting in staging memory are sent to the GPU early once they "
"hold this much, so an area load cannot run video memory out.",
[UI_MENU_LAMA_NO_LIMIT] = "No limit",
[UI_MENU_LAMA_ASTC_KEEP] = "Keep the ASTC decode buffer",
[UI_MENU_LAMA_ASTC_KEEP_DESC] = "The buffer that GPU-decodes compressed textures is kept between upload batches "
"instead of being allocated again for each one.",
[UI_MENU_LAMA_MESH_EMU] = "Mesh shader emulation",
[UI_MENU_LAMA_MESH_EMU_DESC] = "Draws grass, moss and other foliage on GPUs without mesh shaders (AMD RX 400/500 "
"and Vega, GTX 10-series and older), with compute shaders. GPUs with mesh shaders "
"ignore it.",
[UI_MENU_LAMA_MESH_NATIVE] = "this GPU has mesh shaders",
[UI_MENU_LAMA_MESH_MB] = "Mesh emulation memory",
[UI_MENU_LAMA_MESH_MB_DESC] = "Video memory for the emulated meshes' vertices and indices, in MB.",
[UI_MENU_LAMA_MESH_TASKS] = "Mesh emulation task records",
[UI_MENU_LAMA_MESH_TASKS_DESC] = "Task records per submission for the emulated meshes. Raise it when the log reports "
"that a submission asked for more.",
[UI_MENU_LAMA_VEC_INDEX] = "Vector index fix",
[UI_MENU_LAMA_VEC_INDEX_DESC] = "Shaders read uniform vector components at computed indices whole and select the "
"component, for drivers that get such reads wrong. Auto: on AMD's own drivers.",
[UI_MENU_LAMA_VEC_AUTO] = "Auto (AMD)",
[UI_MENU_LAMA_GUEST_OPT] = "Optimised game code (-O2)",
[UI_MENU_LAMA_GUEST_OPT_DESC] = "The next Rebuild the Game in the launcher compiles the game's code at -O2 instead "
"of -O1: the game's own threads run faster on a slower CPU. The build takes "
"several times longer.",
[UI_MENU_LAMA_GUEST_OPT_NOTE] = "at the next rebuild",
[UI_MENU_LAMA_PASS_TIMES] = "Pass times in the log",
[UI_MENU_LAMA_PASS_TIMES_DESC] = "GPU time of every render pass and dispatch goes to the log, with the largest "
"viewport each kind of pass draws with. Costs a little frame time.",
[UI_MENU_LAMA_DUMP_KEY] = "Frame dump key",
[UI_MENU_LAMA_DUMP_KEY_DESC] = "Each press of this key in the game window dumps the next frame (images and the "
"frame's passes) to the dump folder, for a glitch caught while it is on screen. "
"Windows only.",
[UI_MENU_SHARPNESS] = "FSR sharpness",
[UI_MENU_SHARPNESS_DESC] = "How sharp FSR makes the picture. 0 turns it off.",
[UI_MENU_SHARPNESS_NEEDS_FSR] = "only with AMD FSR 1 or FSR 3.1",

View File

@@ -332,6 +332,20 @@ typedef enum {
UI_MENU_FRAMEGEN_MULT_UPTO, // printf: "%d", the highest multiplier this GPU and driver allow
UI_MENU_FRAMEGEN_MULT_OLD_DLL, // nx2navi_dlssg.dll is older than multi frame generation
UI_MENU_FRAMEGEN_UNAVAILABLE, UI_MENU_FRAMEGEN_OFF_FILES,
// the Lama patches tab (ui/menu.cpp tab_lama): the settings of the RX 580 patches, English only
UI_MENU_TAB_LAMA, UI_MENU_LAMA_INTRO, UI_MENU_LAMA_MEMORY, UI_MENU_LAMA_RENDER, UI_MENU_LAMA_BUILD,
UI_MENU_LAMA_DIAG,
UI_MENU_LAMA_RELEASED, UI_MENU_LAMA_RELEASED_DESC,
UI_MENU_LAMA_CLOBBER, UI_MENU_LAMA_CLOBBER_DESC,
UI_MENU_LAMA_MIRROR_HOT, UI_MENU_LAMA_MIRROR_HOT_DESC,
UI_MENU_LAMA_UPLOAD_BATCH, UI_MENU_LAMA_UPLOAD_BATCH_DESC, UI_MENU_LAMA_NO_LIMIT,
UI_MENU_LAMA_ASTC_KEEP, UI_MENU_LAMA_ASTC_KEEP_DESC,
UI_MENU_LAMA_MESH_EMU, UI_MENU_LAMA_MESH_EMU_DESC, UI_MENU_LAMA_MESH_NATIVE,
UI_MENU_LAMA_MESH_MB, UI_MENU_LAMA_MESH_MB_DESC, UI_MENU_LAMA_MESH_TASKS, UI_MENU_LAMA_MESH_TASKS_DESC,
UI_MENU_LAMA_VEC_INDEX, UI_MENU_LAMA_VEC_INDEX_DESC, UI_MENU_LAMA_VEC_AUTO,
UI_MENU_LAMA_GUEST_OPT, UI_MENU_LAMA_GUEST_OPT_DESC, UI_MENU_LAMA_GUEST_OPT_NOTE,
UI_MENU_LAMA_PASS_TIMES, UI_MENU_LAMA_PASS_TIMES_DESC,
UI_MENU_LAMA_DUMP_KEY, UI_MENU_LAMA_DUMP_KEY_DESC,
UI_TEXT_COUNT
} UiTextId;

View File

@@ -794,3 +794,6 @@ int probe_vkdevice(void) {
printf("probe-vkdevice: %s (validation errors %ld)\n", g_errors_total ? "FAILED" : "passed", g_errors_total);
return g_errors_total ? 1 : 0;
}
// The GPU has mesh shaders: the mesh emulation (NX2NAVI_MESH_EMULATION) does nothing there (the menu's Lama patches tab).
int vk_mesh_shader_native(void) { return g_vk.has_mesh_shader; }

View File

@@ -1425,10 +1425,29 @@ def fast_clang(msys, clang, env):
return fast if mine and clang_ident(fast, env) == mine else None
def guest_opt_ini(out):
"""NX2NAVI_GUEST_OPT from nx2navi.ini next to the exe (the menu's Lama patches tab writes it there) when the
environment does not set it: the next build of the game folder out takes it."""
if os.environ.get('NX2NAVI_GUEST_OPT', '').strip():
return
try:
for line in (Path(out) / 'nx2navi.ini').read_text(encoding='utf-8', errors='replace').splitlines():
key, eq, value = line.partition('=')
key = key.strip().lower()
if eq and key in ('guest_opt', 'nx2navi_guest_opt'):
value = value.split('#')[0].split(';')[0].strip().strip('"')
if value:
os.environ['NX2NAVI_GUEST_OPT'] = value
except OSError:
pass
def runtime_cmd(clang, clangxx, inc, level=0, fast=None, msys=None, first=()):
"""fast: fast_clang's compiler for the lifted code, with msys as its sysroot. first: include flags that go
ahead of inc for the runtime's sources only (vulkan_headers); the lifted code includes none of those headers,
and its command, which is part of its objects' keys, stays as it was."""
and its command, which is part of its objects' keys, stays as it was. NX2NAVI_GUEST_OPT (an environment variable,
or guest_opt in nx2navi.ini) 1 builds the lifted code at -O1; by default -O2: the game's own threads run it and
bound the frame on a slower CPU; the build takes several times longer."""
def cmd_for(src, dst):
cpp = src.suffix in ('.cpp', '.cxx')
# the lifted code at -O1 (its size makes -O2 slow to build), the runtime at -O2; neither may assume strict
@@ -1721,6 +1740,7 @@ def step_compile(out, cache_dir, msys, jobs, romfs_job=None, update=False):
cid, cid_old = compiler_ids(clang, env) # fast_clang's compiler writes the same objects: not part of the key
now = cpu_level(clang, env)
level = lifted_level(obj, now, update)
guest_opt_ini(out)
if os.environ.get('NX2NAVI_GUEST_OPT', '').strip() == '2': # runtime_cmd's guest_opt
say(' lifted code at -O2 (NX2NAVI_GUEST_OPT): a long build')
if level == now: