/* * nvidia-settings: A tool for configuring the NVIDIA X driver on Unix * and Linux systems. * * Copyright (C) 2004 NVIDIA Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #include "NvCtrlAttributes.h" #include "query-assign.h" #include "msg.h" #include "glxinfo.h" #include /* GLX #defines */ #include /* * print_extension_list() - Formats OpenGL/GLX extension strings * to contain commas and returns a pointer to the formatted string. * The user is responsible for freeing this buffer. * * If there is an error or there is not enough memory to create * the buffer, NULL is returned. * */ static char * format_extension_list(const char *ext) { int i; char * extTmp = NULL; /* Actual string to print */ const char *extCountTmp; if ( !ext || !ext[0] ) return NULL; /* Count number of extensions (to get number of commas needed) */ i = 0; extCountTmp = ext; while ( *extCountTmp != '\0' ) { if ( *extCountTmp == ' ' ) { i++; } extCountTmp++; } /* * Allocate buffer that will hold the extension string with * commas in it */ extTmp = nvalloc( (strlen(ext) +i +1) *sizeof(char) ); /* Copy extension string to buffer, adding commas */ i = 0; while ( *ext != '\0' && *ext != '\n' ) { if ( *ext == ' ' ) { extTmp[i++] = ','; } extTmp[i++] = *ext; ext++; } extTmp[i] = '\0'; /* Remove any trailing whitespace and commas */ while ( extTmp[ strlen(extTmp)-1 ] == ' ' || extTmp[ strlen(extTmp)-1 ] == ',' ) { extTmp[ strlen(extTmp)-1 ] = '\0'; } return extTmp; } /* format_extension_list() */ /* * print_fbconfig_attribs() & helper functions - * Prints a table of fbconfig attributes * * NOTE: Only support FBconfig for GLX v1.3+ * */ #ifdef GLX_VERSION_1_3 const char * render_type_abbrev(int rend_type) { switch (rend_type) { case GLX_RGBA_BIT: return "rgb"; case GLX_COLOR_INDEX_BIT: return "ci"; case (GLX_RGBA_BIT | GLX_COLOR_INDEX_BIT): return "any"; default: return "."; } } const char * transparent_type_abbrev(int trans_type) { switch (trans_type) { case GLX_NONE: return "."; case GLX_TRANSPARENT_RGB: return "rg"; case GLX_TRANSPARENT_INDEX: return "ci"; default: return "."; } } const char * x_visual_type_abbrev(int x_visual_type) { switch (x_visual_type) { case GLX_TRUE_COLOR: return "tc"; case GLX_DIRECT_COLOR: return "dc"; case GLX_PSEUDO_COLOR: return "pc"; case GLX_STATIC_COLOR: return "sc"; case GLX_GRAY_SCALE: return "gs"; case GLX_STATIC_GRAY: return "sg"; default: return "."; } } const char * caveat_abbrev(int caveat) { if (caveat == GLX_NONE_EXT || caveat == 0) return("."); else if (caveat == GLX_SLOW_VISUAL_EXT) return("slo"); else if (caveat == GLX_NON_CONFORMANT_VISUAL_EXT) return("NoC"); else return("."); } static void print_fbconfig_attribs(const GLXFBConfigAttr *fbca) { int i; /* Iterator */ if ( fbca == NULL ) { return; } printf("--fc- --vi- vt buf lv rgb d s colorbuffer ax dp st " "accumbuffer ---ms---- cav -----pbuffer----- ---transparent----\n"); printf(" id id siz l ci b t r g b a bf th en " " r g b a mvs mcs b eat widt hght max-pxs typ r g b a i\n"); printf("---------------------------------------------------" "--------------------------------------------------------------\n"); i = 0; while ( fbca[i].fbconfig_id != 0 ) { printf("0x%03x ", fbca[i].fbconfig_id); if ( fbca[i].visual_id ) { printf("0x%03x ", fbca[i].visual_id); } else { printf(" . "); } printf("%2.2s %3d %2d %3.3s %1c %1c ", x_visual_type_abbrev(fbca[i].x_visual_type), fbca[i].buffer_size, fbca[i].level, render_type_abbrev(fbca[i].render_type), fbca[i].doublebuffer ? 'y' : '.', fbca[i].stereo ? 'y' : '.' ); printf("%2d %2d %2d %2d %2d %2d %2d ", fbca[i].red_size, fbca[i].green_size, fbca[i].blue_size, fbca[i].alpha_size, fbca[i].aux_buffers, fbca[i].depth_size, fbca[i].stencil_size ); printf("%2d %2d %2d %2d ", fbca[i].accum_red_size, fbca[i].accum_green_size, fbca[i].accum_blue_size, fbca[i].accum_alpha_size ); if ( fbca[i].multi_sample_valid == 1 ) { printf("%3d ", fbca[i].multi_samples ); if ( fbca[i].multi_sample_coverage_valid == 1 ) { printf("%3d ", fbca[i].multi_samples_color ); } else { printf("%3d ", fbca[i].multi_samples ); } printf("%1d ", fbca[i].multi_sample_buffers ); } else { printf(" . . . "); } printf("%3.3s %4x %4x %7x %3.3s %2d %2d %2d %2d %2d\n", caveat_abbrev(fbca[i].config_caveat), fbca[i].pbuffer_width, fbca[i].pbuffer_height, fbca[i].pbuffer_max, transparent_type_abbrev(fbca[i].transparent_type), fbca[i].transparent_red_value, fbca[i].transparent_green_value, fbca[i].transparent_blue_value, fbca[i].transparent_alpha_value, fbca[i].transparent_index_value ); i++; } /* Done printing FBConfig attributes for FBConfig */ } /* print_fbconfig_attribs() */ #endif /* GLX_VERSION_1_3 */ /* * print_glxinfo() - prints information about glx * */ #define TAB " " #define SAFE_FREE(m) \ if ( (m) != NULL ) { \ free( m ); \ m = NULL; \ } #define NULL_TO_EMPTY(s) \ ((s)!=NULL)?(s):"" void print_glxinfo(const char *display_name, CtrlSystemList *systems) { CtrlSystem *system; CtrlTargetNode *node; ReturnStatus status = NvCtrlSuccess; char *direct_rendering = NULL; char *glx_extensions = NULL; char *server_vendor = NULL; char *server_version = NULL; char *server_extensions = NULL; char *client_vendor = NULL; char *client_version = NULL; char *client_extensions = NULL; char *opengl_vendor = NULL; char *opengl_renderer = NULL; char *opengl_version = NULL; char *opengl_extensions = NULL; GLXFBConfigAttr *fbconfig_attribs = NULL; char *formatted_ext_str = NULL; system = NvCtrlConnectToSystem(display_name, systems); if (system == NULL) { return; } /* Print information for each screen */ for (node = system->targets[X_SCREEN_TARGET]; node; node = node->next) { CtrlTarget *t = node->t; /* No screen, move on */ if ( !t->h ) continue; nv_msg(NULL, "GLX Information for %s:", t->name); /* Get GLX information */ status = NvCtrlGetStringAttribute(t, NV_CTRL_STRING_GLX_DIRECT_RENDERING, &direct_rendering); if ( status != NvCtrlSuccess && status != NvCtrlNoAttribute ) { goto finish; } status = NvCtrlGetStringAttribute(t, NV_CTRL_STRING_GLX_GLX_EXTENSIONS, &glx_extensions); if ( status != NvCtrlSuccess && status != NvCtrlNoAttribute ) { goto finish; } if ( glx_extensions != NULL ) { formatted_ext_str = format_extension_list(glx_extensions); if ( formatted_ext_str != NULL ) { free(glx_extensions); glx_extensions = formatted_ext_str; } } /* Get server GLX information */ status = NvCtrlGetStringAttribute(t, NV_CTRL_STRING_GLX_SERVER_VENDOR, &server_vendor); if ( status != NvCtrlSuccess && status != NvCtrlNoAttribute ) { goto finish; } status = NvCtrlGetStringAttribute(t, NV_CTRL_STRING_GLX_SERVER_VERSION, &server_version); if ( status != NvCtrlSuccess && status != NvCtrlNoAttribute ) { goto finish; } status = NvCtrlGetStringAttribute(t, NV_CTRL_STRING_GLX_SERVER_EXTENSIONS, &server_extensions); if ( status != NvCtrlSuccess && status != NvCtrlNoAttribute ) { goto finish; } if ( server_extensions != NULL ) { formatted_ext_str = format_extension_list(server_extensions); if ( formatted_ext_str != NULL ) { free(server_extensions); server_extensions = formatted_ext_str; } } /* Get client GLX information */ status = NvCtrlGetStringAttribute(t, NV_CTRL_STRING_GLX_CLIENT_VENDOR, &client_vendor); if ( status != NvCtrlSuccess && status != NvCtrlNoAttribute ) { goto finish; } status = NvCtrlGetStringAttribute(t, NV_CTRL_STRING_GLX_CLIENT_VERSION, &client_version); if ( status != NvCtrlSuccess && status != NvCtrlNoAttribute ) { goto finish; } status = NvCtrlGetStringAttribute(t, NV_CTRL_STRING_GLX_CLIENT_EXTENSIONS, &client_extensions); if ( status != NvCtrlSuccess && status != NvCtrlNoAttribute ) { goto finish; } if ( client_extensions != NULL ) { formatted_ext_str = format_extension_list(client_extensions); if ( formatted_ext_str != NULL ) { free(client_extensions); client_extensions = formatted_ext_str; } } /* Get OpenGL information */ status = NvCtrlGetStringAttribute(t, NV_CTRL_STRING_GLX_OPENGL_VENDOR, &opengl_vendor); if ( status != NvCtrlSuccess && status != NvCtrlNoAttribute ) { goto finish; } status = NvCtrlGetStringAttribute(t, NV_CTRL_STRING_GLX_OPENGL_RENDERER, &opengl_renderer); if ( status != NvCtrlSuccess && status != NvCtrlNoAttribute ) { goto finish; } status = NvCtrlGetStringAttribute(t, NV_CTRL_STRING_GLX_OPENGL_VERSION, &opengl_version); if ( status != NvCtrlSuccess && status != NvCtrlNoAttribute ) { goto finish; } status = NvCtrlGetStringAttribute(t, NV_CTRL_STRING_GLX_OPENGL_EXTENSIONS, &opengl_extensions); if ( status != NvCtrlSuccess && status != NvCtrlNoAttribute ) { goto finish; } if ( opengl_extensions != NULL ) { formatted_ext_str = format_extension_list(opengl_extensions); if ( formatted_ext_str != NULL ) { free(opengl_extensions); opengl_extensions = formatted_ext_str; } } /* Get FBConfig information */ status = NvCtrlGetVoidAttribute(t, NV_CTRL_ATTR_GLX_FBCONFIG_ATTRIBS, (void *)(&fbconfig_attribs)); if ( status != NvCtrlSuccess && status != NvCtrlNoAttribute ) { goto finish; } /* Print results */ nv_msg(TAB, "direct rendering: %s", NULL_TO_EMPTY(direct_rendering)); nv_msg(TAB, "GLX extensions:"); nv_msg(" ", "%s", NULL_TO_EMPTY(glx_extensions)); nv_msg(" ", "\n"); nv_msg(TAB, "server glx vendor string: %s", NULL_TO_EMPTY(server_vendor)); nv_msg(TAB, "server glx version string: %s", NULL_TO_EMPTY(server_version)); nv_msg(TAB, "server glx extensions:"); nv_msg(" ", "%s", NULL_TO_EMPTY(server_extensions)); nv_msg(" ", "\n"); nv_msg(TAB, "client glx vendor string: %s", NULL_TO_EMPTY(client_vendor)); nv_msg(TAB, "client glx version string: %s", NULL_TO_EMPTY(client_version)); nv_msg(TAB, "client glx extensions:"); nv_msg(" ", "%s", NULL_TO_EMPTY(client_extensions)); nv_msg(" ", "\n"); nv_msg(TAB, "OpenGL vendor string: %s", NULL_TO_EMPTY(opengl_vendor)); nv_msg(TAB, "OpenGL renderer string: %s", NULL_TO_EMPTY(opengl_renderer)); nv_msg(TAB, "OpenGL version string: %s", NULL_TO_EMPTY(opengl_version)); nv_msg(TAB, "OpenGL extensions:"); nv_msg(" ", "%s", NULL_TO_EMPTY(opengl_extensions)); #ifdef GLX_VERSION_1_3 if ( fbconfig_attribs != NULL ) { nv_msg(" ", "\n"); print_fbconfig_attribs(fbconfig_attribs); } #endif fflush(stdout); /* Free memory used */ SAFE_FREE(server_vendor); SAFE_FREE(server_version); SAFE_FREE(server_extensions); SAFE_FREE(client_vendor); SAFE_FREE(client_version); SAFE_FREE(client_extensions); SAFE_FREE(direct_rendering); SAFE_FREE(glx_extensions); SAFE_FREE(opengl_vendor); SAFE_FREE(opengl_renderer); SAFE_FREE(opengl_version); SAFE_FREE(opengl_extensions); SAFE_FREE(fbconfig_attribs); } /* Done looking at all screens */ /* Fall through */ finish: if ( status == NvCtrlError ) { nv_error_msg("Error fetching GLX Information: %s", NvCtrlAttributesStrError(status) ); } /* Free any leftover memory used */ SAFE_FREE(server_vendor); SAFE_FREE(server_version); SAFE_FREE(server_extensions); SAFE_FREE(client_vendor); SAFE_FREE(client_version); SAFE_FREE(client_extensions); SAFE_FREE(direct_rendering); SAFE_FREE(glx_extensions); SAFE_FREE(opengl_vendor); SAFE_FREE(opengl_renderer); SAFE_FREE(opengl_version); SAFE_FREE(opengl_extensions); SAFE_FREE(fbconfig_attribs); NvCtrlFreeAllSystems(systems); } /* print_glxinfo() */ /* * EGL information * */ const char *egl_color_buffer_type_abbrev(int type) { switch (type) { case EGL_RGB_BUFFER: return "rgb"; case EGL_LUMINANCE_BUFFER: return "lum"; default: return "."; } } const char *egl_config_caveat_abbrev(int type) { switch (type) { case EGL_SLOW_CONFIG: return "slo"; case EGL_NON_CONFORMANT_CONFIG: return "NoC"; case EGL_NONE: default: return "."; } } const char *egl_transparent_type_abbrev(int type) { switch (type) { case EGL_TRANSPARENT_RGB: return "rgb"; case EGL_NONE: default: return "."; } } static void print_egl_config_attribs(const EGLConfigAttr *fbca) { int i; if (fbca == NULL) { return; } printf("--fc- --vi- --vt-- buf lv rgb colorbuffer am lm dp st " "-bind cfrm sb sm cav -----pbuffer----- swapin nv rn su " "-transparent--\n"); printf(" id id siz l lum r g b a sz sz th en " " - a eat widt hght max-pxs mx mn rd ty ty " "typ r g b \n"); printf("------------------------------------------------------" "-----------------------------------------------------------" "--------------\n"); for (i = 0; fbca[i].config_id != 0; i++) { printf("0x%03x ", fbca[i].config_id); if (fbca[i].native_visual_id) { printf("0x%03x ", fbca[i].native_visual_id); } else { printf(" . "); } printf("0x%X %3d %2d %3s ", fbca[i].native_visual_type, fbca[i].buffer_size, fbca[i].level, egl_color_buffer_type_abbrev(fbca[i].color_buffer_type)); printf("%2d %2d %2d %2d %2d %2d %2d %2d ", fbca[i].red_size, fbca[i].green_size, fbca[i].blue_size, fbca[i].alpha_size, fbca[i].alpha_mask_size, fbca[i].luminance_size, fbca[i].depth_size, fbca[i].stencil_size); printf("%2c %2c ", fbca[i].bind_to_texture_rgb ? 'y' : '.', fbca[i].bind_to_texture_rgba ? 'y' : '.'); printf("0x%02X %2d %2d ", fbca[i].conformant, fbca[i].sample_buffers, fbca[i].samples); printf("%3.3s %4x %4x %7x %2d %2d ", egl_config_caveat_abbrev(fbca[i].config_caveat), fbca[i].max_pbuffer_width, fbca[i].max_pbuffer_height, fbca[i].max_pbuffer_pixels, fbca[i].max_swap_interval, fbca[i].min_swap_interval); printf("%2c %4x %4x ", fbca[i].native_renderable ? 'y' : '.', fbca[i].renderable_type, fbca[i].surface_type); printf("%3s %2d %2d %2d\n", egl_transparent_type_abbrev(fbca[i].transparent_type), fbca[i].transparent_red_value, fbca[i].transparent_green_value, fbca[i].transparent_blue_value); } } /* print_egl_config_attribs() */ /* * print_eglinfo() - prints information about egl * */ void print_eglinfo(const char *display_name, CtrlSystemList *systems) { CtrlSystem *system; CtrlTargetNode *node; ReturnStatus status = NvCtrlSuccess; char *egl_vendor = NULL; char *egl_version = NULL; char *egl_extensions = NULL; char *formatted_ext_str = NULL; EGLConfigAttr *egl_config_attribs = NULL; system = NvCtrlConnectToSystem(display_name, systems); if (system == NULL) { return; } /* Print information for each screen */ for (node = system->targets[X_SCREEN_TARGET]; node; node = node->next) { CtrlTarget *t = node->t; /* No screen, move on */ if (!t->h) continue; nv_msg(NULL, "EGL Information for %s:", t->name); /* Get EGL information */ status = NvCtrlGetStringAttribute(t, NV_CTRL_STRING_EGL_VENDOR, &egl_vendor); if (status != NvCtrlSuccess && status != NvCtrlNoAttribute) { goto finish; } status = NvCtrlGetStringAttribute(t, NV_CTRL_STRING_EGL_VERSION, &egl_version); if (status != NvCtrlSuccess && status != NvCtrlNoAttribute) { goto finish; } status = NvCtrlGetStringAttribute(t, NV_CTRL_STRING_EGL_EXTENSIONS, &egl_extensions); if (status != NvCtrlSuccess && status != NvCtrlNoAttribute) { goto finish; } if (egl_extensions != NULL) { formatted_ext_str = format_extension_list(egl_extensions); if (formatted_ext_str != NULL) { free(egl_extensions); egl_extensions = formatted_ext_str; } } /* Get FBConfig information */ status = NvCtrlGetVoidAttribute(t, NV_CTRL_ATTR_EGL_CONFIG_ATTRIBS, (void *)(&egl_config_attribs)); if (status != NvCtrlSuccess && status != NvCtrlNoAttribute) { goto finish; } /* Print results */ nv_msg(TAB, "EGL vendor string: %s", NULL_TO_EMPTY(egl_vendor)); nv_msg(TAB, "EGL version string: %s", NULL_TO_EMPTY(egl_version)); nv_msg(TAB, "EGL extensions:"); nv_msg(" ", "%s", NULL_TO_EMPTY(egl_extensions)); nv_msg(" ", "\n"); if (egl_config_attribs != NULL) { nv_msg(" ", "\n"); print_egl_config_attribs(egl_config_attribs); } fflush(stdout); /* Free memory used */ SAFE_FREE(egl_vendor); SAFE_FREE(egl_version); SAFE_FREE(egl_extensions); SAFE_FREE(egl_config_attribs); } /* Done looking at all screens */ /* Fall through */ finish: if (status == NvCtrlError) { nv_error_msg("Error fetching EGL Information: %s", NvCtrlAttributesStrError(status) ); } /* Free any leftover memory used */ SAFE_FREE(egl_vendor); SAFE_FREE(egl_version); SAFE_FREE(egl_extensions); SAFE_FREE(egl_config_attribs); NvCtrlFreeAllSystems(systems); } /* print_eglinfo() */