driver: choose sgi_video_sync scheduler for NVIDIA

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
Yuxuan Shui
2023-12-18 22:00:51 +00:00
parent d7a2f8ade6
commit 0b45b3415b
4 changed files with 26 additions and 5 deletions

View File

@@ -19,6 +19,13 @@ void apply_driver_workarounds(struct session *ps, enum driver driver) {
}
}
enum vblank_scheduler_type choose_vblank_scheduler(enum driver driver) {
if (driver & DRIVER_INTEL) {
return SGI_VIDEO_SYNC_VBLANK_SCHEDULER;
}
return PRESENT_VBLANK_SCHEDULER;
}
enum driver detect_driver(xcb_connection_t *c, backend_t *backend_data, xcb_window_t window) {
enum driver ret = 0;
// First we try doing backend agnostic detection using RANDR

View File

@@ -7,6 +7,7 @@
#include <stdio.h>
#include <xcb/xcb.h>
#include "config.h"
#include "utils.h"
struct session;
@@ -41,6 +42,8 @@ enum driver detect_driver(xcb_connection_t *, struct backend_base *, xcb_window_
/// Apply driver specified global workarounds. It's safe to call this multiple times.
void apply_driver_workarounds(struct session *ps, enum driver);
/// Choose a vblank scheduler based on the driver.
enum vblank_scheduler_type choose_vblank_scheduler(enum driver driver);
// Print driver names to stdout, for diagnostics
static inline void print_drivers(enum driver drivers) {

View File

@@ -83,6 +83,14 @@ enum vblank_scheduler_type {
LAST_VBLANK_SCHEDULER,
};
static inline const char *vblank_scheduler_type_str(enum vblank_scheduler_type type) {
switch (type) {
case PRESENT_VBLANK_SCHEDULER: return "present";
case SGI_VIDEO_SYNC_VBLANK_SCHEDULER: return "sgi_video_sync";
default: return "invalid";
}
}
/// Internal, private options for debugging and development use.
struct debug_options {
/// Try to reduce frame latency by using vblank interval and render time

View File

@@ -1485,6 +1485,10 @@ static bool redirect_start(session_t *ps) {
ps->frame_pacing = false;
}
// Re-detect driver since we now have a backend
ps->drivers = detect_driver(ps->c.c, ps->backend_data, ps->c.screen_info->root);
apply_driver_workarounds(ps, ps->drivers);
if (ps->present_exists && ps->frame_pacing) {
// Initialize rendering and frame timing statistics, and frame pacing
// states.
@@ -1492,11 +1496,14 @@ static bool redirect_start(session_t *ps) {
ps->last_msc = 0;
ps->last_schedule_delay = 0;
render_statistics_reset(&ps->render_stats);
enum vblank_scheduler_type scheduler_type = PRESENT_VBLANK_SCHEDULER;
enum vblank_scheduler_type scheduler_type =
choose_vblank_scheduler(ps->drivers);
if (ps->o.debug_options.force_vblank_scheduler != LAST_VBLANK_SCHEDULER) {
scheduler_type =
(enum vblank_scheduler_type)ps->o.debug_options.force_vblank_scheduler;
}
log_info("Using vblank scheduler: %s.",
vblank_scheduler_type_str(scheduler_type));
ps->vblank_scheduler = vblank_scheduler_new(
ps->loop, &ps->c, session_get_target_window(ps), scheduler_type);
if (!ps->vblank_scheduler) {
@@ -1515,10 +1522,6 @@ static bool redirect_start(session_t *ps) {
ps->redirected = true;
ps->first_frame = true;
// Re-detect driver since we now have a backend
ps->drivers = detect_driver(ps->c.c, ps->backend_data, ps->c.screen_info->root);
apply_driver_workarounds(ps, ps->drivers);
root_damaged(ps);
// Repaint the whole screen