Name the upscalers' wait mark "upscaler GPU waits", since it also times the timeline wait after a refused creation.

The review of 9071dfc3 found that PERF_M_UPWAIT, printed as "upscaler device waits", times two waits: vk_dlaa.c
vk_upscaler_device_idle's wait for the device, and vk_upscaler_gpu_wait's host wait on the timeline after a refused
DLSS or FSR creation, which touches no queue. host.h tied the mark to the first alone, and a play-test that expects no
"upscaler device waits" would have read the second, at a refused creation on a card short of video memory, as a wait
for the device. perf.c now names the mark "upscaler GPU waits", and host.h, vk_ffx.h and vk_dlaa.c say that both waits
are in it. What makes it a wait for the device still shows in the log: the rollback switch in the "cfg: ... sets:"
line, a full list ("a wait for the device") and a failed timeline wait ("waiting for the device instead") in lines of
their own.

Checks that passed: perf.c, vk_dlaa.c and vk_ffx.cpp compile with -Wall -Wextra and no warning, upscaler_idle_check (one
name per mark kind), tools/check_content.py --staged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
chrg6
2026-11-13 19:36:50 -05:00
parent 4506988335
commit 74bedbee73
4 changed files with 6 additions and 4 deletions

View File

@@ -63,7 +63,8 @@ void perf_count(int kind);
// pipe_create_in), guest memory maps (heap size, MapPhysicalMemory), NVN memory pool initialize and finalize
// (vk_memory.c vk_pool_init, vk_pool_fini), device memory VMA allocates (blocks and dedicated memory, vk_device.c
// timed_alloc), and DLSS and DLSS frame generation feature creates (vk_dlaa.c). perf_mark_begin returns 0 while the trace is off, so a normal run pays one branch per site.
// UPWAIT: the upscalers' waits for the GPU before they free what they let go of (vk_dlaa.c vk_upscaler_device_idle);
// UPWAIT: the upscalers' waits for the GPU before they free what they let go of (vk_dlaa.c vk_upscaler_device_idle,
// and vk_upscaler_gpu_wait's timeline wait after a refused creation);
// UPREL: their releases of DLSS features and FSR contexts (vk_dlaa.c, vk_ffx.cpp, vk_ffx4.cpp).
enum { PERF_M_FILE, PERF_M_ZSTD, PERF_M_PIPE, PERF_M_GMEM, PERF_M_POOL, PERF_M_DEVMEM, PERF_M_NGX, PERF_M_UPWAIT,
PERF_M_UPREL, PERF_M_N };

View File

@@ -151,7 +151,7 @@ void perf_count(int kind) {
// names them on a slow frame's line and adds them to the 60-frame window's line.
static const char *const mark_name[PERF_M_N] = {"file reads", "zstd decodes", "pipeline creates", "guest memory maps",
"pool init/finalize", "device memory allocations",
"DLSS feature creates", "upscaler device waits", "upscaler releases"};
"DLSS feature creates", "upscaler GPU waits", "upscaler releases"};
static volatile int64_t mk_ns[PERF_M_N], mk_n[PERF_M_N], mk_bytes[PERF_M_N], mk_max[PERF_M_N]; // since the last present
typedef struct { uint64_t ns[PERF_M_N], n[PERF_M_N], bytes[PERF_M_N], max[PERF_M_N]; } MarkSums;
static MarkSums mk_win; // the 60-frame window's, present thread only

View File

@@ -730,7 +730,8 @@ static int idle_free(void) {
// The upscalers' waits for the device to be idle before they free what the GPU may still use (vk_dlaa.c, vk_ffx.cpp,
// vk_ffx4.cpp), with the queue lock held: the present's flip, the completion thread's hold release and every upload
// submit wait as long. NX2NAVI_TRACE=perf names them "upscaler device waits" on a slow frame's line.
// submit wait as long. NX2NAVI_TRACE=perf names them "upscaler GPU waits" on a slow frame's line, together with
// vk_upscaler_gpu_wait's timeline waits after a refused creation, which touch no queue.
void vk_upscaler_device_idle(void) {
uint64_t t0 = perf_mark_begin();
vk_queue_lock(), vkDeviceWaitIdle(vk_ctx()->device), vk_queue_unlock();

View File

@@ -17,7 +17,7 @@ typedef struct { float fov_y, znear, zfar, meters; } VkFfxCamera;
// vk_dlaa.c: the share (0..1) of the extra sharpening FSR 3.1 gets at a render width w of an output width ow
float vk_dlaa_fsr3_boost(uint32_t w, uint32_t ow);
// vk_dlaa.c: a wait for the device to be idle, the queue lock held, before an upscaler frees what the GPU may still
// use (NX2NAVI_TRACE=perf: "upscaler device waits")
// use (NX2NAVI_TRACE=perf: "upscaler GPU waits", with vk_upscaler_gpu_wait's)
void vk_upscaler_device_idle(void);
// vk_dlaa.c "what the upscalers let go of while the GPU may still use it", on the thread that makes the upscalers'
// calls (vk_dlaa.c's pass hooks):