From 58b9cd411fd81e257364efb3f2738bd1ac556e34 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Fri, 30 Jan 2009 14:43:03 -0800 Subject: [PATCH] glxgears: Log a message if synched to vblank Tries to use either GLX_MESA_swap_control or GLX_SGI_video_sync to detect whether the display is synchronized to the vertical blank. If it detects this, a message will be printed. HOPEFULLY this will prevent some of the bug reports such as "glxgears only gets 59.7fps. What's wrong with my driver?" --- progs/xdemos/glxgears.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/progs/xdemos/glxgears.c b/progs/xdemos/glxgears.c index 8db717f1aa3..dfe071b9c2e 100644 --- a/progs/xdemos/glxgears.c +++ b/progs/xdemos/glxgears.c @@ -39,6 +39,9 @@ #include #include +static int is_glx_extension_supported(Display *dpy, const char *query); + +static void query_vsync(Display *dpy); #define BENCHMARK @@ -561,12 +564,82 @@ make_window( Display *dpy, const char *name, /** + * Determine whether or not a GLX extension is supported. + */ +int +is_glx_extension_supported(Display *dpy, const char *query) +{ + const int scrnum = DefaultScreen(dpy); + const char *glx_extensions = NULL; + const size_t len = strlen(query); + const char *ptr; + + if (glx_extensions == NULL) { + glx_extensions = glXQueryExtensionsString(dpy, scrnum); + } + + ptr = strstr(glx_extensions, query); + return ((ptr != NULL) && ((ptr[len] == ' ') || (ptr[len] == '\0'))); +} + + +/** + * Attempt to determine whether or not the display is synched to vblank. + */ +void +query_vsync(Display *dpy) +{ + int interval = 0; + + +#ifdef GLX_MESA_swap_control + if ((interval <= 0) + && is_glx_extension_supported(dpy, "GLX_MESA_swap_control")) { + PFNGLXGETSWAPINTERVALMESAPROC pglXGetSwapIntervalMESA = + (PFNGLXGETSWAPINTERVALMESAPROC) + glXGetProcAddressARB((const GLubyte *) "glXGetSwapIntervalMESA"); + + interval = (*pglXGetSwapIntervalMESA)(); + } +#endif + + +#ifdef GLX_SGI_video_sync + if ((interval <= 0) + && is_glx_extension_supported(dpy, "GLX_SGI_video_sync")) { + PFNGLXGETVIDEOSYNCSGIPROC pglXGetVideoSyncSGI = + (PFNGLXGETVIDEOSYNCSGIPROC) + glXGetProcAddressARB((const GLubyte *) "glXGetVideoSyncSGI"); + unsigned count; + + if ((*pglXGetVideoSyncSGI)(& count) == 0) { + interval = (int) count; + } + } +#endif + + + if (interval > 0) { + printf("Running synchronized to the vertical refresh. The framerate should be\n"); + if (interval == 1) { + printf("approximately the same as the montior refresh rate.\n"); + } else if (interval > 1) { + printf("approximately 1/%d the montior refresh rate.\n", + interval); + } + } +} + +/** * Handle one X event. * \return NOP, EXIT or DRAW */ static int handle_event(Display *dpy, Window win, XEvent *event) { + (void) dpy; + (void) win; + switch (event->type) { case Expose: return DRAW; @@ -686,6 +759,7 @@ main(int argc, char *argv[]) make_window(dpy, "glxgears", x, y, winWidth, winHeight, &win, &ctx); XMapWindow(dpy, win); glXMakeCurrent(dpy, win, ctx); + query_vsync(dpy); if (printInfo) { printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); -- 2.11.0