diff --git a/include/rex/graphics/flags.h b/include/rex/graphics/flags.h index 583a474..47425f3 100644 --- a/include/rex/graphics/flags.h +++ b/include/rex/graphics/flags.h @@ -29,10 +29,6 @@ REXCVAR_DECLARE(int32_t, draw_resolution_scale_x); REXCVAR_DECLARE(int32_t, draw_resolution_scale_y); REXCVAR_DECLARE(bool, resolve_resolution_scale_fill_half_pixel_offset); REXCVAR_DECLARE(bool, draw_resolution_scaled_texture_offsets); -REXCVAR_DECLARE(bool, scaled_resolve_texture_loads_from_shared_memory); -REXCVAR_DECLARE(int32_t, scaled_resolve_texture_loads_from_shared_memory_max_pixels); -REXCVAR_DECLARE(bool, scaled_resolve_texture_loads_update_guest_memory); -REXCVAR_DECLARE(int32_t, scaled_resolve_small_texture_readback_max_length); REXCVAR_DECLARE(std::string, readback_resolve); REXCVAR_DECLARE(bool, readback_resolve_half_pixel_offset); REXCVAR_DECLARE(int32_t, native_render_force_resolve_readback_max_length); @@ -101,8 +97,6 @@ REXCVAR_DECLARE(int32_t, vulkan_debug_log_resolve_decisions_remaining); REXCVAR_DECLARE(int32_t, vulkan_debug_log_team_profile_background_candidates_remaining); REXCVAR_DECLARE(int32_t, vulkan_debug_log_team_profile_background_bindings_remaining); REXCVAR_DECLARE(int32_t, vulkan_debug_log_team_profile_background_draws_remaining); -REXCVAR_DECLARE(bool, vulkan_sync_after_resolve); -REXCVAR_DECLARE(bool, vulkan_barrier_after_scaled_resolve); REXCVAR_DECLARE(int32_t, vulkan_readback_resolve_max_length); REXCVAR_DECLARE(int32_t, vulkan_readback_resolve_min_address); REXCVAR_DECLARE(int32_t, vulkan_readback_resolve_max_address); diff --git a/src/core/logging.cpp b/src/core/logging.cpp index a91a38c..4991aab 100644 --- a/src/core/logging.cpp +++ b/src/core/logging.cpp @@ -55,6 +55,12 @@ REXCVAR_DEFINE_INT32(log_max_files, 20, "Log", "Max number of rotated log files .range(1, 100) .lifecycle(rex::cvar::Lifecycle::kInitOnly); +REXCVAR_DEFINE_INT32(log_keep_sessions, 5, "Log", + "Number of launches to keep sequential log files for; older sessions " + "are deleted at startup so logs do not accumulate across launches") + .range(1, 1000) + .lifecycle(rex::cvar::Lifecycle::kInitOnly); + namespace rex { namespace { @@ -75,18 +81,36 @@ std::filesystem::path NextSequentialLogPath(const std::filesystem::path& logs_di int max_seq = 0; std::string prefix = std::string(app_name) + "_"; + std::vector> session_files; std::error_code ec; for (const auto& entry : std::filesystem::directory_iterator(logs_dir, ec)) { if (!entry.is_regular_file()) continue; auto stem = entry.path().stem().string(); - if (stem.starts_with(prefix)) { - auto num_str = stem.substr(prefix.size()); - int num = 0; - auto [ptr, parse_ec] = std::from_chars(num_str.data(), num_str.data() + num_str.size(), num); - if (parse_ec == std::errc() && ptr == num_str.data() + num_str.size()) - max_seq = std::max(max_seq, num); - } + if (!stem.starts_with(prefix)) + continue; + auto num_str = stem.substr(prefix.size()); + int num = 0; + auto [ptr, parse_ec] = std::from_chars(num_str.data(), num_str.data() + num_str.size(), num); + if (parse_ec != std::errc() || ptr == num_str.data()) + continue; + const bool full_match = ptr == num_str.data() + num_str.size(); + // Rotated segments ("_NNN.1.log") stem-parse as "NNN."; they prune + // with their session but don't advance the sequence. + if (!full_match && *ptr != '.') + continue; + if (full_match) + max_seq = std::max(max_seq, num); + session_files.emplace_back(num, entry.path()); + } + + // Prune old sessions so log files don't accumulate across launches: after + // this launch takes max_seq + 1, everything at or below the cutoff goes. + const int keep = std::max(1, REXCVAR_GET(log_keep_sessions)); + const int cutoff = max_seq + 1 - keep; + for (const auto& [num, path] : session_files) { + if (num <= cutoff) + std::filesystem::remove(path, ec); } return logs_dir / fmt::format("{}_{:03d}.log", app_name, max_seq + 1); diff --git a/src/core/perf/counter.cpp b/src/core/perf/counter.cpp index 0298f25..5f471d9 100644 --- a/src/core/perf/counter.cpp +++ b/src/core/perf/counter.cpp @@ -688,9 +688,15 @@ bool ShouldCollectDrawDiagnostics() { return REXCVAR_GET(perf_diagnostics) || IsCaptureRecording(); } +// skate3_ultrawide_trace_draws lives in another DLL, so it is reachable only +// through the by-name registry query (mutex + map lookup), far too expensive +// for the per-draw call sites of ShouldCollectDrawFingerprints(). Cache the +// value and refresh it once per frame from ResetFrameCounters(). +static std::atomic g_trace_draws_cvar_cache{false}; + bool ShouldCollectDrawFingerprints() { return REXCVAR_GET(perf_draw_fingerprints) || - rex::cvar::Query("skate3_ultrawide_trace_draws") || + g_trace_draws_cvar_cache.load(std::memory_order_relaxed) || ShouldCollectDrawDiagnostics(); } @@ -699,6 +705,9 @@ int64_t GetCounter(CounterId id) { } void ResetFrameCounters() { + g_trace_draws_cvar_cache.store( + rex::cvar::Query("skate3_ultrawide_trace_draws"), + std::memory_order_relaxed); for (size_t i = 0; i < kNumCounters; ++i) { if (kIsGauge[i]) { // Gauges: snapshot the current value, don't zero diff --git a/src/graphics/command_processor.cpp b/src/graphics/command_processor.cpp index 183b5b6..dec8a25 100644 --- a/src/graphics/command_processor.cpp +++ b/src/graphics/command_processor.cpp @@ -46,18 +46,6 @@ REXCVAR_DEFINE_BOOL(clear_memory_page_state, false, "GPU", REXCVAR_DEFINE_BOOL(draw_resolution_scaled_texture_offsets, true, "GPU/Shader", "Scale texture offsets with draw resolution"); -REXCVAR_DEFINE_BOOL(scaled_resolve_texture_loads_from_shared_memory, false, "GPU/Texture", - "Materialize scaled render-to-texture resolves into guest memory on the GPU " - "before loading them as regular textures") - .lifecycle(rex::cvar::Lifecycle::kHotReload); - -REXCVAR_DEFINE_INT32(scaled_resolve_texture_loads_from_shared_memory_max_pixels, 1152 * 640, - "GPU/Texture", - "Maximum unscaled pixel count for GPU materialization of scaled " - "render-to-texture resolves into guest memory") - .range(1, 8192 * 8192) - .lifecycle(rex::cvar::Lifecycle::kHotReload); - REXCVAR_DEFINE_BOOL(occlusion_query_enable, true, "GPU", "Enable host occlusion query handling") .lifecycle(rex::cvar::Lifecycle::kHotReload); @@ -88,19 +76,6 @@ REXCVAR_DEFINE_BOOL(readback_resolve_half_pixel_offset, false, "GPU", "scaled block during resolve readback downscale") .lifecycle(rex::cvar::Lifecycle::kHotReload); -REXCVAR_DEFINE_BOOL(scaled_resolve_texture_loads_update_guest_memory, true, "GPU", - "When scaled resolve texture loads are materialized into shared memory, also " - "mirror the downscaled data into guest memory for CPU-visible coherency") - .lifecycle(rex::cvar::Lifecycle::kHotReload); - -REXCVAR_DEFINE_INT32(scaled_resolve_small_texture_readback_max_length, 0x2D0000, "GPU/Texture", - "Maximum unscaled byte length of a scaled render-to-texture resolve that " - "will be immediately read back even when readback_resolve is disabled. " - "This is intended for small UI thumbnails that depend on CPU-visible " - "resolved data without forcing full-screen resolve readbacks.") - .range(0, 16 * 1024 * 1024) - .lifecycle(rex::cvar::Lifecycle::kHotReload); - REXCVAR_DEFINE_INT32(native_render_force_resolve_readback_max_length, 0, "GPU", "When > 0, render-to-texture resolves up to this unscaled byte length are " "read back synchronously into CPU-visible guest memory even when " diff --git a/src/graphics/vulkan/command_processor.cpp b/src/graphics/vulkan/command_processor.cpp index f308fd0..7cb7a5e 100644 --- a/src/graphics/vulkan/command_processor.cpp +++ b/src/graphics/vulkan/command_processor.cpp @@ -95,17 +95,6 @@ REXCVAR_DEFINE_INT32(vulkan_debug_log_team_profile_background_draws_remaining, 0 .lifecycle(rex::cvar::Lifecycle::kHotReload) .debug_only(); -REXCVAR_DEFINE_BOOL(vulkan_sync_after_resolve, false, "GPU/Vulkan", - "Synchronously wait for Vulkan render-target resolves without CPU readback") - .lifecycle(rex::cvar::Lifecycle::kHotReload) - .debug_only(); - -REXCVAR_DEFINE_BOOL(vulkan_barrier_after_scaled_resolve, true, "GPU/Vulkan", - "Submit a GPU memory barrier after scaled Vulkan render-target resolves so " - "follow-up texture loads can read the scaled resolve buffer without CPU " - "readback") - .lifecycle(rex::cvar::Lifecycle::kHotReload); - REXCVAR_DEFINE_INT32(vulkan_readback_resolve_max_length, 0, "GPU/Vulkan", "Maximum resolve byte length eligible for Vulkan CPU readback " "(0 disables the length filter)") @@ -164,10 +153,12 @@ REXCVAR_DEFINE_BOOL(vulkan_gpu_timestamp_buckets, false, "GPU/Vulkan", "with timestamp queries and report them in the FPS overlay") .lifecycle(rex::cvar::Lifecycle::kHotReload); -REXCVAR_DEFINE_INT32(vulkan_gpu_clock_log_interval_frames, 120, "GPU/Vulkan", +REXCVAR_DEFINE_INT32(vulkan_gpu_clock_log_interval_frames, 0, "GPU/Vulkan", "How often (in guest frames) to log the GPU clock/P-state telemetry line; " - "P-state changes and large clock swings log immediately; 0 disables") + "P-state changes and large clock swings log immediately; 0 (default) " + "disables sampling and logging") .range(0, 36000) + .debug_only() .lifecycle(rex::cvar::Lifecycle::kHotReload); // The shared Skate 3 Hor+ classifier cvars (skate3_ultrawide_skip_shadow_targets, diff --git a/src/ui/overlay/simple_settings_overlay.cpp b/src/ui/overlay/simple_settings_overlay.cpp index 05cf01d..1c5756d 100644 --- a/src/ui/overlay/simple_settings_overlay.cpp +++ b/src/ui/overlay/simple_settings_overlay.cpp @@ -53,7 +53,7 @@ constexpr std::array kCoreSimpleSettingsCvars = { // Optional cvars persisted when the host defines them (HasCvar-gated: app // cvars like the native-renderer knobs don't exist in every embedder, and // backend/platform cvars don't exist in every build). -constexpr std::array kOptionalSimpleSettingsCvars = { +constexpr std::array kOptionalSimpleSettingsCvars = { "skate3_native_render_scene", "skate3_native_render_scene_msaa", "skate3_native_render_scene_shadows", @@ -66,6 +66,9 @@ constexpr std::array kOptionalSimpleSettingsCvars = { "skate3_native_render_scene_shafts", "skate3_native_render_scene_haze", "skate3_native_render_mode_indicator", + "skate3_draw_distance_scale", + "skate3_lod_distance_scale", + "skate3_draw_distance_stream_probe", "show_fps_counter", "monitor", "mnk_sensitivity", @@ -1439,7 +1442,7 @@ void SimpleSettingsDialog::BuildRows(std::vector& rows, int category) { SaveSimpleSettingsConfig(config_path_); }; row.reset = [this] { - renderer_native_ = CvarDefaultBool("skate3_native_render_scene", false); + renderer_native_ = CvarDefaultBool("skate3_native_render_scene", true); SetBoolCvar("skate3_native_render_scene", renderer_native_); SaveSimpleSettingsConfig(config_path_); }; @@ -1759,7 +1762,7 @@ void SimpleSettingsDialog::BuildRows(std::vector& rows, int category) { SaveSimpleSettingsConfig(config_path_); }; row.reset = [this] { - mode_indicator_ = CvarDefaultBool("skate3_native_render_mode_indicator", true); + mode_indicator_ = CvarDefaultBool("skate3_native_render_mode_indicator", false); SetBoolCvar("skate3_native_render_mode_indicator", mode_indicator_); SaveSimpleSettingsConfig(config_path_); }; diff --git a/src/ui/rex_app.cpp b/src/ui/rex_app.cpp index 4a05066..86e1762 100644 --- a/src/ui/rex_app.cpp +++ b/src/ui/rex_app.cpp @@ -208,8 +208,9 @@ void StartForcedExitWatchdog(const char* reason) { } // namespace -REXCVAR_DEFINE_BOOL(advanced_settings_overlay_enabled, true, "UI/Advanced", - "Enable the developer cvar browser on F4"); +REXCVAR_DEFINE_BOOL(advanced_settings_overlay_enabled, false, "UI/Advanced", + "Enable the developer cvar browser on F4") + .debug_only(); REXCVAR_DEFINE_STRING(gpu_backend, "auto", "GPU", "Graphics API used for rendering (auto, d3d12, vulkan). Auto prefers "