mirror of
https://github.com/tangerineturtle1/NX2navi.git
synced 2026-11-15 19:19:58 -04:00
Name the queue lock's long holders under NX2NAVI_LOCK_TIME, and time each swapchain rebuild's hold of it.
With lock_time = 1 the 0.10.0 session showed flip_locked waiting up to 48.61 ms for the queue lock, and the replay's queue_submit up to 8.05 ms. Nothing named who held it: only vk_texture.c's lock records its holders. A swapchain rebuild holds the lock across vkDeviceWaitIdle and the create, and that hold was not timed either. vk_queue_lock, vk_queue_lock_raw and vk_queue_trylock_raw are no longer inlined. Each takes the lock with plat_rmutex_lock_at and its own return address, so the wait report keeps naming the caller (before, the inlined call named a site inside flip_locked). At the outermost take, with lock_time on, the holder's site and the time are noted. vk_queue_unlock passes a hold of 5 ms or more to perf.c perf_qlock_hold. The frame-time summary then prints "queue lock held 5 ms or more" beside the texture lock's holds, by site, as the waits are. create_swapchain logs how long a successful rebuild took: the wait for the lock, the hold, and the part spent waiting for the device to idle. It logs the first 16 rebuilds and each doubling of their count. Diagnostics only: the counters are behind NX2NAVI_LOCK_TIME, which is off by default, plus one capped line per rebuild. Checks that passed: pass_cc_check on every runtime file (host.h changed), no new -Wall -Wextra warnings in gfx_present.c and perf.c, stutter_hitch_check, pgo_build_test, sync_hw_check. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -516,6 +516,7 @@ static uint64_t summary_t0; // start of the current period (0: not started)
|
||||
#define LT_N 512
|
||||
static struct { void *site; uint64_t ns, n, max, ns0, n0; } lt[LT_N];
|
||||
static struct { void *site; uint64_t ns, n, max, ns0, n0; } lh[LT_N]; // texture lock holds over 1 ms (perf_lock_hold)
|
||||
static struct { void *site; uint64_t ns, n, max, ns0, n0; } lq[LT_N]; // queue lock holds of 5 ms or more (perf_qlock_hold)
|
||||
static uint64_t lt_lost_ns, lt_rec0[2];
|
||||
static volatile int64_t fr_hold_ns; // the texture lock's holds over 1 ms since the last present (ft_frame)
|
||||
void (*perf_rec_waits)(uint64_t *full_ns, uint64_t *drain_ns);
|
||||
@@ -541,6 +542,7 @@ void perf_lock_hold(void *site, uint64_t ns) {
|
||||
lt_add((typeof(lt[0]) *)lh, site, ns);
|
||||
plat_add64(&fr_hold_ns, (int64_t)ns);
|
||||
}
|
||||
void perf_qlock_hold(void *site, uint64_t ns) { lt_add((typeof(lt[0]) *)lq, site, ns); }
|
||||
|
||||
static int lt_on = -1;
|
||||
int perf_lock_holds_on(void) {
|
||||
@@ -582,7 +584,8 @@ static uint64_t lt_top(typeof(lt[0]) *tab, char *line, int *n, size_t cap, uint6
|
||||
return all;
|
||||
}
|
||||
|
||||
// The lock lines of a summary: the replay threads' waits with the recorder's, then the texture lock's long holds.
|
||||
// The lock lines of a summary: the replay threads' waits with the recorder's, then the texture lock's and the queue
|
||||
// lock's long holds.
|
||||
static void lt_report(void) {
|
||||
uint64_t rec[2] = {0, 0}, waits, holds;
|
||||
if (perf_rec_waits) perf_rec_waits(&rec[0], &rec[1]);
|
||||
@@ -598,6 +601,11 @@ static void lt_report(void) {
|
||||
snprintf(line, sizeof line, "frametime: texture lock held over 1 ms: %.0f ms (%llu holds):%s", all / 1e6,
|
||||
(unsigned long long)holds, top);
|
||||
rt_log("%s", line);
|
||||
n = 0, top[0] = 0;
|
||||
all = lt_top((typeof(lt[0]) *)lq, top, &n, sizeof top, &holds);
|
||||
snprintf(line, sizeof line, "frametime: queue lock held 5 ms or more: %.0f ms (%llu holds):%s", all / 1e6,
|
||||
(unsigned long long)holds, top);
|
||||
rt_log("%s", line);
|
||||
lt_rec0[0] = rec[0], lt_rec0[1] = rec[1], lt_lost_ns = 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user