I’m on the 580.95.05 driver with open kernel modules, with a gtx 1650.
I am using the framebuffer provided by the nvidia modesetting driver:
options nvidia-drm fbdev=1 modeset=1
The ioctl FBIO_WAITFORVSYNC succeeds, but doesn’t wait for vsync.
$ cat fb_rate.c
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <time.h>
#include <sys/ioctl.h>
#include <linux/fb.h>
#define PICOS2HZ(a) (1000000000000UL/(a))
int main(int ac, char **av)
{
int fd = open(ac > 1 ? av[1] : "/dev/fb0", O_RDWR);
if (fd < 0) {
perror("open");
}
struct fb_var_screeninfo info = {0};
int ret = ioctl(fd, FBIOGET_VSCREENINFO, &info);
if (ret < 0) {
perror("FBIOGET_VSCREENINFO");
}
long scanline = info.left_margin + info.xres * info.pixclock + info.right_margin + info.hsync_len;
long vblank = info.upper_margin + info.yres * scanline + info.lower_margin + info.vsync_len;
long freq = vblank ? PICOS2HZ(vblank) : -1;
printf("freq: %ld\n", freq);
long real_freq = 0;
struct timespec tv1 = {0};
struct timespec tv2 = {0};
long zero_arg = 0;
ret = ioctl(fd, FBIO_WAITFORVSYNC, &info);
if (ret < 0) {
perror("FBIO_WAITFORVSYNC");
}
ret = clock_gettime(CLOCK_REALTIME, &tv1);
if (ret < 0) {
perror("clock_gettime");
}
ret = ioctl(fd, FBIO_WAITFORVSYNC, &info);
if (ret < 0) {
perror("FBIO_WAITFORVSYNC");
}
ret = clock_gettime(CLOCK_REALTIME, &tv2);
if (ret < 0) {
perror("clock_gettime");
}
real_freq = (long)(tv2.tv_sec - tv1.tv_sec) * 1000000000L + (tv2.tv_nsec - tv1.tv_nsec);
real_freq = 1000000000L / real_freq;
printf("real_freq: %ld\n", real_freq);
}
$ gcc fb_rate.c -o fb_rate && ./fb_rate /dev/fb1
freq: -1
real_freq: 5263157
For comparison with the intel driver:
$ gcc fb_rate.c -o fb_rate && ./fb_rate /dev/fb0
freq: -1
real_freq: 144