mirror of
https://github.com/tangerineturtle1/NX2navi.git
synced 2026-11-15 19:19:58 -04:00
Log RivaTuner Statistics Server's hold only while its want is still the current one.
The review found that A-11's fix stores the hold after every decision but also logs it then: when the want changed while the worker wrote the profile (frame generation switched on during the first write), rtss_limit.c set_active logged "RivaTuner Statistics Server does the limiting; the game's own limiter stands aside" while the game's limiter was pacing the new want (rtss_limit_active compares the hold with the want), and the kept-out line followed one poll later. set_active still stores the hold every time, so that a want going w, w2 and w again never finds an older hold, but logs a hold only while the want is still the one decided for; a decision that RTSS does not hold the game is logged as before. The next poll logs what holds the newer want. tests/rtss_worker_check.c active_logged switches frame generation on inside the first SaveProfile (a hook in the fake RTSS): no line may say RTSS does the limiting, the next poll logs the kept-out line, and a later limit is held and logged. It fails on the code before this change. Log only; rtss_limit_check passes 27 of 27, active_race included. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -222,11 +222,13 @@ static void put_back_op(void *ctx, const RtssOut *o) { // rtss_poll's RtssOps.
|
||||
|
||||
// Whether RTSS holds the game to the want w this poll read, and the log of which limiter is in use: the first decision,
|
||||
// then each change. The want may have changed since the poll read it: rtss_limit_active compares the two, so a stale
|
||||
// store never lets the game's limiter stand aside for a newer want.
|
||||
// store never lets the game's limiter stand aside for a newer want. The store is made either way (a want that went
|
||||
// w, w2, w again must not find an older hold), but a hold is logged only while its want is still the current one: the
|
||||
// game's limiter paces a newer want, and the next poll logs what holds it.
|
||||
static void set_active(int64_t w, int on, const char *why) {
|
||||
static int logged = -1;
|
||||
atomic_store(&active_for, on ? w : RTSS_UNSET);
|
||||
if (logged == on) return;
|
||||
if (logged == on || (on && atomic_load(&want) != w)) return;
|
||||
logged = on;
|
||||
if (on) rt_log("frame rate: RivaTuner Statistics Server does the limiting; the game's own limiter stands aside");
|
||||
else rt_log("frame rate: the game's own limiter (%s)", why);
|
||||
|
||||
@@ -67,9 +67,15 @@ static void WINAPI f_load(LPCSTR name) {
|
||||
(void)name;
|
||||
loaded = own.exists ? own : global;
|
||||
}
|
||||
static void (*during_save)(void); // runs inside the next SaveProfile, once
|
||||
static void WINAPI f_save(LPCSTR name) {
|
||||
(void)name;
|
||||
saves++;
|
||||
if (during_save) {
|
||||
void (*f)(void) = during_save;
|
||||
during_save = NULL;
|
||||
f();
|
||||
}
|
||||
if (readonly) return;
|
||||
DWORD stamp = own.stamp;
|
||||
own = loaded, own.exists = 1, own.stamp = stamp;
|
||||
@@ -453,6 +459,28 @@ static void active_race(void) {
|
||||
CHECK(!hits, "the game's limiter stood aside for a kept-out want %ld times", hits);
|
||||
}
|
||||
|
||||
// Frame generation switched on while the worker writes the first limit: RTSS holds that limit, but the game's limiter
|
||||
// paces the kept-out want, so the log must not say RTSS does the limiting; the next poll logs the kept-out line. A later
|
||||
// limit is held and logged as usual.
|
||||
static void framegen_on(void) { rtss_limit_want(RTSS_OUT_FRAMEGEN); }
|
||||
static void active_logged(void) {
|
||||
app_set(1, 0xA, 1000, 2000, 60);
|
||||
during_save = framegen_on;
|
||||
ask(60000);
|
||||
show("frame generation switched on during the first write");
|
||||
CHECK(own.exists && own.limit == 60, "the limit went into the profile");
|
||||
CHECK(!rtss_limit_active(), "the game's limiter paces the kept-out want");
|
||||
CHECK(!logged("does the limiting"), "no line says RTSS does the limiting");
|
||||
poll();
|
||||
show("the next poll");
|
||||
CHECK(logged("the game's own limiter (RivaTuner Statistics Server kept out: frame generation)"), "the kept-out line");
|
||||
CHECK(!logged("does the limiting"), "still no line says RTSS does the limiting");
|
||||
ask(60000);
|
||||
poll();
|
||||
show("frame generation off");
|
||||
CHECK(rtss_limit_active() && logged("does the limiting; the game's own limiter stands aside"), "held and logged");
|
||||
}
|
||||
|
||||
// A limit of a fractional monitor (display at 59.94 and 143.856 Hz): an RTSS that knows the denominator holds it as it
|
||||
// is, one that does not holds it rounded to whole frames, and the log says what the profile holds, not what was asked.
|
||||
static void round_logged(void) {
|
||||
@@ -721,6 +749,7 @@ static const struct { const char *name; void (*run)(void); } scenarios[] = {
|
||||
{"kept_lowlat_then_limit", kept_lowlat_then_limit},
|
||||
{"kept_framegen", kept_framegen},
|
||||
{"active_race", active_race},
|
||||
{"active_logged", active_logged},
|
||||
{"round_logged", round_logged},
|
||||
{"round_logged_whole", round_logged_whole},
|
||||
{"start_off_present", start_off_present},
|
||||
|
||||
Reference in New Issue
Block a user