Windows GL vsync workaround: scope to the measured case

Narrow host_driver_vsync_unreliable() on Windows to the configuration the
stall was measured on: GL active, render thread running, GL_VENDOR NVIDIA,
not exclusive fullscreen. Other driver families and the unthreaded path
keep driver vsync; PSX_TRUST_DRIVER_VSYNC=1 still forces it everywhere.
Evaluated per call, so runtime renderer/fullscreen changes apply.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Shokunin
2026-10-22 14:17:33 -07:00
parent 594b507efd
commit cb17f2f2d4
3 changed files with 20 additions and 4 deletions
+1
View File
@@ -607,6 +607,7 @@ int gl_renderer_get_texture_window_batching(void);
int gl_renderer_render_thread_start(int max_frames);
void gl_renderer_render_thread_stop(void);
int gl_renderer_render_thread_active(void);
int gl_renderer_vendor_is_nvidia(void);
void gl_renderer_render_thread_frame_boundary(void);
void gl_renderer_render_thread_sync(const char *reason);
int gl_renderer_render_thread_json(char *out, size_t cap);
+8
View File
@@ -397,6 +397,8 @@ static int load_modern_gl(void) {
static SDL_Window *s_win = NULL;
static SDL_GLContext s_ctx = NULL;
static uint16_t *s_vram = NULL; /* CPU VRAM array (gpu.c's storage) */
/* GL_VENDOR names NVIDIA (captured at context creation). */
static int s_vendor_nvidia = 0;
static int s_swap_interval = 1; /* SDL_GL swap interval (vsync mode) */
/* ---- render thread ([video] render_thread, docs/RENDER_THREAD.md) --------
@@ -6450,6 +6452,10 @@ int gl_renderer_init_context(SDL_Window *win) {
const char *gpu = (const char *)glGetString(0x1F01 /* GL_RENDERER */);
fprintf(stdout, "psxrecomp: OpenGL context created (%s; %s)\n", ver ? ver : "?",
gpu ? gpu : "?");
{
const char *vendor = (const char *)glGetString(0x1F00 /* GL_VENDOR */);
s_vendor_nvidia = (vendor && strstr(vendor, "NVIDIA")) ? 1 : 0;
}
/* All-or-nothing: any missing entry point / failed shader / bad FBO means
* the whole GL renderer is unavailable and the runtime stays on the pure
@@ -14152,6 +14158,8 @@ void gl_renderer_render_thread_stop(void) {
gr_refresh_backend();
}
int gl_renderer_vendor_is_nvidia(void) { return s_vendor_nvidia; }
int gl_renderer_render_thread_active(void) { return s_rth_on; }
/* Frame boundary (once per vblank, after the present): hand the context back
+11 -4
View File
@@ -3958,11 +3958,18 @@ static int host_driver_vsync_unreliable(void) {
* then costs a whole refresh (16.7 ms "GPU" at any internal scale,
* render_busy 100 %), back-pressure slows the guest to 52-57 Hz, and
* dynamic resolution drops for nothing. Swap interval 0 under the
* wall-clock pacer: 60.0 Hz, 4.4 ms. Exclusive fullscreen (2) keeps
* driver vsync. PSX_TRUST_DRIVER_VSYNC=1 restores it everywhere. */
* wall-clock pacer: 60.0 Hz, 4.4 ms.
*
* Scope is the measured case only: GL renderer active, the render thread
* running, GL_VENDOR NVIDIA, and not exclusive fullscreen (2). Other
* driver families, the unthreaded path and exclusive fullscreen keep
* driver vsync. Re-evaluated per call, so runtime fullscreen/renderer
* changes take effect. PSX_TRUST_DRIVER_VSYNC=1 keeps driver vsync. */
if (const char *e = std::getenv("PSX_TRUST_DRIVER_VSYNC"); e && e[0] && e[0] != '0')
return 0;
return (g_video_renderer == 1 && g_fullscreen != 2) ? 1 : 0;
return (g_video_renderer == 1 && g_gl_active && g_fullscreen != 2 &&
gl_renderer_render_thread_active() &&
gl_renderer_vendor_is_nvidia()) ? 1 : 0;
#else
static int cached = -1;
if (cached >= 0)
@@ -4076,7 +4083,7 @@ static void log_present_cadence(void) {
"(%.4f ms/frame); driver vsync off (%s)\n",
g_frame_period_ms,
#ifdef _WIN32
"Windows GL: DWM composes"
"Windows GL, NVIDIA render thread: DWM composes"
#else
"under WSL"
#endif