diff options
-rw-r--r-- | progs/xdemos/glxinfo.c | 136 |
1 files changed, 127 insertions, 9 deletions
diff --git a/progs/xdemos/glxinfo.c b/progs/xdemos/glxinfo.c index cfc3bc4a1a..21a9a60331 100644 --- a/progs/xdemos/glxinfo.c +++ b/progs/xdemos/glxinfo.c @@ -1,7 +1,7 @@ -/* $Id: glxinfo.c,v 1.11 2001/03/19 13:58:45 alanh Exp $ */ +/* $Id: glxinfo.c,v 1.12 2001/03/23 21:41:44 brianp Exp $ */ /* - * Copyright (C) 1999 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -28,20 +28,29 @@ * -t print wide table * -v print verbose information * -display DisplayName specify the X display to interogate + * -b only print ID of "best" visual on screen 0 * * Brian Paul 26 January 2000 */ +#define DO_GLU /* may want to remove this for easier XFree86 building? */ #include <X11/Xlib.h> #include <X11/Xutil.h> #include <GL/gl.h> +#ifdef DO_GLU #include <GL/glu.h> +#endif #include <GL/glx.h> #include <stdio.h> #include <string.h> +#ifndef GLX_NONE_EXT +#define GLX_NONE_EXT 0x8000 +#endif + + typedef enum { Normal, @@ -194,8 +203,10 @@ print_screen_info(Display *dpy, int scrnum) const char *glRenderer = (const char *) glGetString(GL_RENDERER); const char *glVersion = (const char *) glGetString(GL_VERSION); const char *glExtensions = (const char *) glGetString(GL_EXTENSIONS); +#ifdef DO_GLU const char *gluVersion = (const char *) gluGetString(GLU_VERSION); const char *gluExtensions = (const char *) gluGetString(GLU_EXTENSIONS); +#endif printf("display: %s screen:%d\n", DisplayString(dpy), scrnum); printf("direct rendering: %s\n", glXIsDirect(dpy, ctx) ? "Yes" : "No"); printf("server glx vendor string: %s\n", serverVendor); @@ -213,9 +224,11 @@ print_screen_info(Display *dpy, int scrnum) printf("OpenGL version string: %s\n", glVersion); printf("OpenGL extensions:\n"); print_extension_list(glExtensions); +#ifdef DO_GLU printf("glu version: %s\n", gluVersion); printf("glu extensions:\n"); print_extension_list(gluExtensions); +#endif } else { fprintf(stderr, "Error: glXMakeCurrent failed\n"); @@ -489,6 +502,98 @@ print_visual_info(Display *dpy, int scrnum, InfoMode mode) } +/* + * Stand-alone Mesa doesn't really implement the GLX protocol so it + * doesn't really know the GLX attributes associated with an X visual. + * The first time a visual is presented to Mesa's pseudo-GLX it + * attaches ancilliary buffers to it (like depth and stencil). + * But that usually only works if glXChooseVisual is used. + * This function calls glXChooseVisual() to sort of "prime the pump" + * for Mesa's GLX so that the visuals that get reported actually + * reflect what applications will see. + * This has no effect when using true GLX. + */ +static void +mesa_hack(Display *dpy, int scrnum) +{ + static int attribs[] = { + GLX_RGBA, + GLX_RED_SIZE, 1, + GLX_GREEN_SIZE, 1, + GLX_BLUE_SIZE, 1, + GLX_DEPTH_SIZE, 1, + GLX_STENCIL_SIZE, 1, + GLX_ACCUM_RED_SIZE, 1, + GLX_ACCUM_GREEN_SIZE, 1, + GLX_ACCUM_BLUE_SIZE, 1, + GLX_ACCUM_ALPHA_SIZE, 1, + GLX_DOUBLEBUFFER, + None + }; + XVisualInfo *visinfo; + + visinfo = glXChooseVisual(dpy, scrnum, attribs); + if (visinfo) + XFree(visinfo); +} + + +/* + * Examine all visuals to find the so-called best one. + * We prefer deepest RGBA buffer with depth, stencil and accum + * that has no caveats. + */ +static int +find_best_visual(Display *dpy, int scrnum) +{ + XVisualInfo template; + XVisualInfo *visuals; + int numVisuals; + long mask; + int i; + struct visual_attribs bestVis; + + /* get list of all visuals on this screen */ + template.screen = scrnum; + mask = VisualScreenMask; + visuals = XGetVisualInfo(dpy, mask, &template, &numVisuals); + + /* init bestVis with first visual info */ + get_visual_attribs(dpy, &visuals[0], &bestVis); + + /* try to find a "better" visual */ + for (i = 1; i < numVisuals; i++) { + struct visual_attribs vis; + + get_visual_attribs(dpy, &visuals[i], &vis); + + /* always skip visuals with caveats */ + if (vis.visualCaveat != GLX_NONE_EXT) + continue; + + /* see if this vis is better than bestVis */ + if ((!bestVis.supportsGL && vis.supportsGL) || + (bestVis.visualCaveat != GLX_NONE_EXT) || + (!bestVis.rgba && vis.rgba) || + (!bestVis.doubleBuffer && vis.doubleBuffer) || + (bestVis.redSize < vis.redSize) || + (bestVis.greenSize < vis.greenSize) || + (bestVis.blueSize < vis.blueSize) || + (bestVis.alphaSize < vis.alphaSize) || + (bestVis.depthSize < vis.depthSize) || + (bestVis.stencilSize < vis.stencilSize) || + (bestVis.accumRedSize < vis.accumRedSize)) { + /* found a better visual */ + bestVis = vis; + } + } + + XFree(visuals); + + return bestVis.id; +} + + int main(int argc, char *argv[]) { @@ -496,6 +601,7 @@ main(int argc, char *argv[]) Display *dpy; int numScreens, scrnum; InfoMode mode = Normal; + GLboolean findBest = GL_FALSE; int i; for (i = 1; i < argc; i++) { @@ -509,6 +615,9 @@ main(int argc, char *argv[]) else if (strcmp(argv[i], "-v") == 0) { mode = Verbose; } + else if (strcmp(argv[i], "-b") == 0) { + findBest = GL_TRUE; + } } dpy = XOpenDisplay(displayName); @@ -517,13 +626,22 @@ main(int argc, char *argv[]) return -1; } - numScreens = ScreenCount(dpy); - for (scrnum = 0; scrnum < numScreens; scrnum++) { - print_screen_info(dpy, scrnum); - printf("\n"); - print_visual_info(dpy, scrnum, mode); - if (scrnum + 1 < numScreens) - printf("\n\n"); + if (findBest) { + int b; + mesa_hack(dpy, 0); + b = find_best_visual(dpy, 0); + printf("%d\n", b); + } + else { + numScreens = ScreenCount(dpy); + for (scrnum = 0; scrnum < numScreens; scrnum++) { + mesa_hack(dpy, scrnum); + print_screen_info(dpy, scrnum); + printf("\n"); + print_visual_info(dpy, scrnum, mode); + if (scrnum + 1 < numScreens) + printf("\n\n"); + } } XCloseDisplay(dpy); |