132001f49Smrg/* 232001f49Smrg * Copyright (C) 2009 VMware, Inc. 332001f49Smrg * Copyright (C) 1999-2006 Brian Paul 432001f49Smrg * All Rights Reserved. 532001f49Smrg * 632001f49Smrg * Permission is hereby granted, free of charge, to any person obtaining a 732001f49Smrg * copy of this software and associated documentation files (the "Software"), 832001f49Smrg * to deal in the Software without restriction, including without limitation 932001f49Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 1032001f49Smrg * and/or sell copies of the Software, and to permit persons to whom the 1132001f49Smrg * Software is furnished to do so, subject to the following conditions: 1232001f49Smrg * 1332001f49Smrg * The above copyright notice and this permission notice shall be included 1432001f49Smrg * in all copies or substantial portions of the Software. 1532001f49Smrg * 1632001f49Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 1732001f49Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1832001f49Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1932001f49Smrg * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 2032001f49Smrg * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 2132001f49Smrg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2232001f49Smrg */ 2332001f49Smrg 2432001f49Smrg 2532001f49Smrg/* 2632001f49Smrg * This program is a work-alike of the GLX glxinfo program. 2732001f49Smrg * Command line options: 2832001f49Smrg * -t print wide table 2932001f49Smrg * -v print verbose information 3032001f49Smrg * -b only print ID of "best" visual on screen 0 3132001f49Smrg * -l print interesting OpenGL limits (added 5 Sep 2002) 3232001f49Smrg */ 3332001f49Smrg 3432001f49Smrg 357ec3b29aSmrg#include <windows.h> 367ec3b29aSmrg#include <stdbool.h> 3732001f49Smrg#include <GL/glew.h> 3832001f49Smrg#include <GL/wglew.h> 3932001f49Smrg#include <assert.h> 4032001f49Smrg#include <stdio.h> 4132001f49Smrg#include <string.h> 4232001f49Smrg#include <stdlib.h> 4332001f49Smrg#include "glinfo_common.h" 4432001f49Smrg 4532001f49Smrg 467ec3b29aSmrgstatic GLboolean have_WGL_ARB_create_context; 477ec3b29aSmrgstatic GLboolean have_WGL_ARB_pbuffer; 487ec3b29aSmrgstatic GLboolean have_WGL_ARB_pixel_format; 497ec3b29aSmrgstatic GLboolean have_WGL_ARB_multisample; 507ec3b29aSmrgstatic GLboolean have_WGL_ARB_framebuffer_sRGB; /* or EXT version */ 517ec3b29aSmrg 527ec3b29aSmrgstatic PFNWGLGETPIXELFORMATATTRIBIVARBPROC wglGetPixelFormatAttribivARB_func; 537ec3b29aSmrgstatic PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB_func; 5432001f49Smrg 5532001f49Smrg 567ec3b29aSmrg/** 577ec3b29aSmrg * An extension of PIXELFORMATDESCRIPTOR to handle multisample, etc. 587ec3b29aSmrg */ 597ec3b29aSmrgstruct format_info { 607ec3b29aSmrg PIXELFORMATDESCRIPTOR pfd; 617ec3b29aSmrg int sampleBuffers, numSamples; 627ec3b29aSmrg int transparency; 637ec3b29aSmrg bool floatComponents; 647ec3b29aSmrg bool srgb; 657ec3b29aSmrg bool draw_to_bitmap; 667ec3b29aSmrg bool draw_to_pbuffer; 677ec3b29aSmrg bool gdi_drawing; 687ec3b29aSmrg}; 697ec3b29aSmrg 7032001f49Smrg 7132001f49Smrgstatic LRESULT CALLBACK 7232001f49SmrgWndProc(HWND hWnd, 7332001f49Smrg UINT uMsg, 7432001f49Smrg WPARAM wParam, 7532001f49Smrg LPARAM lParam ) 7632001f49Smrg{ 7732001f49Smrg switch (uMsg) { 7832001f49Smrg case WM_DESTROY: 7932001f49Smrg PostQuitMessage(0); 8032001f49Smrg break; 8132001f49Smrg default: 8232001f49Smrg return DefWindowProc(hWnd, uMsg, wParam, lParam); 8332001f49Smrg } 8432001f49Smrg 8532001f49Smrg return 0; 8632001f49Smrg} 8732001f49Smrg 8832001f49Smrg 8932001f49Smrgstatic void 907ec3b29aSmrgprint_screen_info(HDC _hdc, const struct options *opts, GLboolean coreProfile) 9132001f49Smrg{ 9232001f49Smrg WNDCLASS wc; 9332001f49Smrg HWND win; 9432001f49Smrg HGLRC ctx; 9532001f49Smrg int visinfo; 9632001f49Smrg HDC hdc; 9732001f49Smrg PIXELFORMATDESCRIPTOR pfd; 9832001f49Smrg int version; 9932001f49Smrg const char *oglString = "OpenGL"; 10032001f49Smrg 10132001f49Smrg memset(&wc, 0, sizeof wc); 10232001f49Smrg wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1); 10332001f49Smrg wc.hCursor = LoadCursor(NULL, IDC_ARROW); 10432001f49Smrg wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); 10532001f49Smrg wc.lpfnWndProc = WndProc; 10632001f49Smrg wc.lpszClassName = "wglinfo"; 10732001f49Smrg wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; 10832001f49Smrg RegisterClass(&wc); 10932001f49Smrg 11032001f49Smrg win = CreateWindowEx(0, 11132001f49Smrg wc.lpszClassName, 11232001f49Smrg "wglinfo", 11332001f49Smrg WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 11432001f49Smrg CW_USEDEFAULT, 11532001f49Smrg CW_USEDEFAULT, 11632001f49Smrg CW_USEDEFAULT, 11732001f49Smrg CW_USEDEFAULT, 11832001f49Smrg NULL, 11932001f49Smrg NULL, 12032001f49Smrg wc.hInstance, 12132001f49Smrg NULL); 12232001f49Smrg if (!win) { 12332001f49Smrg fprintf(stderr, "Couldn't create window\n"); 12432001f49Smrg return; 12532001f49Smrg } 12632001f49Smrg 12732001f49Smrg hdc = GetDC(win); 12832001f49Smrg if (!hdc) { 12932001f49Smrg fprintf(stderr, "Couldn't obtain HDC\n"); 13032001f49Smrg return; 13132001f49Smrg } 13232001f49Smrg 1337ec3b29aSmrg memset(&pfd, 0, sizeof(pfd)); 13432001f49Smrg pfd.cColorBits = 3; 13532001f49Smrg pfd.cRedBits = 1; 13632001f49Smrg pfd.cGreenBits = 1; 13732001f49Smrg pfd.cBlueBits = 1; 13832001f49Smrg pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL; 13932001f49Smrg pfd.iLayerType = PFD_MAIN_PLANE; 14032001f49Smrg pfd.iPixelType = PFD_TYPE_RGBA; 14132001f49Smrg pfd.nSize = sizeof(pfd); 14232001f49Smrg pfd.nVersion = 1; 14332001f49Smrg 14432001f49Smrg visinfo = ChoosePixelFormat(hdc, &pfd); 14532001f49Smrg if (!visinfo) { 14632001f49Smrg pfd.dwFlags |= PFD_DOUBLEBUFFER; 14732001f49Smrg visinfo = ChoosePixelFormat(hdc, &pfd); 14832001f49Smrg } 14932001f49Smrg 15032001f49Smrg if (!visinfo) { 15132001f49Smrg fprintf(stderr, "Error: couldn't find RGB WGL visual\n"); 15232001f49Smrg return; 15332001f49Smrg } 15432001f49Smrg 15532001f49Smrg SetPixelFormat(hdc, visinfo, &pfd); 15632001f49Smrg ctx = wglCreateContext(hdc); 15732001f49Smrg if (!ctx) { 15832001f49Smrg fprintf(stderr, "Error: wglCreateContext failed\n"); 15932001f49Smrg return; 16032001f49Smrg } 16132001f49Smrg 16232001f49Smrg if (wglMakeCurrent(hdc, ctx)) { 16332001f49Smrg#if defined(WGL_ARB_extensions_string) 16432001f49Smrg PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB_func = 16532001f49Smrg (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB"); 16632001f49Smrg#endif 1677ec3b29aSmrg const char *glVendor, *glRenderer, *glVersion, *glExtensions; 1687ec3b29aSmrg const char *wglExtensions = NULL; 16932001f49Smrg struct ext_functions extfuncs; 17032001f49Smrg 17132001f49Smrg#if defined(WGL_ARB_extensions_string) 17232001f49Smrg if (wglGetExtensionsStringARB_func) { 1737ec3b29aSmrg wglExtensions = wglGetExtensionsStringARB_func(hdc); 1747ec3b29aSmrg if (extension_supported("WGL_ARB_pbuffer", wglExtensions)) { 1757ec3b29aSmrg have_WGL_ARB_pbuffer = GL_TRUE; 1767ec3b29aSmrg } 1777ec3b29aSmrg if (extension_supported("WGL_ARB_pixel_format", wglExtensions)) { 1787ec3b29aSmrg have_WGL_ARB_pixel_format = GL_TRUE; 1797ec3b29aSmrg } 1807ec3b29aSmrg if (extension_supported("WGL_ARB_multisample", wglExtensions)) { 1817ec3b29aSmrg have_WGL_ARB_multisample = GL_TRUE; 1827ec3b29aSmrg } 1837ec3b29aSmrg if (extension_supported("WGL_ARB_create_context", wglExtensions)) { 1847ec3b29aSmrg have_WGL_ARB_create_context = GL_TRUE; 1857ec3b29aSmrg } 1867ec3b29aSmrg if (extension_supported("WGL_ARB_framebuffer_sRGB", wglExtensions) || 1877ec3b29aSmrg extension_supported("WGL_EXT_framebuffer_sRGB", wglExtensions)) { 1887ec3b29aSmrg have_WGL_ARB_framebuffer_sRGB = GL_TRUE; 18932001f49Smrg } 19032001f49Smrg } 19132001f49Smrg#endif 1927ec3b29aSmrg 1937ec3b29aSmrg if (coreProfile && have_WGL_ARB_create_context) { 1947ec3b29aSmrg /* Try to create a new, core context */ 1957ec3b29aSmrg HGLRC core_ctx = 0; 1967ec3b29aSmrg int i; 1977ec3b29aSmrg 1987ec3b29aSmrg wglCreateContextAttribsARB_func = 1997ec3b29aSmrg (PFNWGLCREATECONTEXTATTRIBSARBPROC) 2007ec3b29aSmrg wglGetProcAddress("wglCreateContextAttribsARB"); 2017ec3b29aSmrg assert(wglCreateContextAttribsARB_func); 2027ec3b29aSmrg if (!wglCreateContextAttribsARB_func) { 2037ec3b29aSmrg printf("Failed to get wglCreateContextAttribsARB pointer."); 2047ec3b29aSmrg return; 2057ec3b29aSmrg } 2067ec3b29aSmrg 2077ec3b29aSmrg for (i = 0; gl_versions[i].major > 0; i++) { 2087ec3b29aSmrg int attribs[10], n; 2097ec3b29aSmrg 2107ec3b29aSmrg /* don't bother below GL 3.1 */ 2117ec3b29aSmrg if (gl_versions[i].major == 3 && gl_versions[i].minor == 0) { 2127ec3b29aSmrg break; 2137ec3b29aSmrg } 2147ec3b29aSmrg 2157ec3b29aSmrg n = 0; 2167ec3b29aSmrg attribs[n++] = WGL_CONTEXT_MAJOR_VERSION_ARB; 2177ec3b29aSmrg attribs[n++] = gl_versions[i].major; 2187ec3b29aSmrg attribs[n++] = WGL_CONTEXT_MINOR_VERSION_ARB; 2197ec3b29aSmrg attribs[n++] = gl_versions[i].minor; 2207ec3b29aSmrg if (gl_versions[i].major * 10 + gl_versions[i].minor > 31) { 2217ec3b29aSmrg attribs[n++] = WGL_CONTEXT_PROFILE_MASK_ARB; 2227ec3b29aSmrg attribs[n++] = WGL_CONTEXT_CORE_PROFILE_BIT_ARB; 2237ec3b29aSmrg } 2247ec3b29aSmrg attribs[n++] = 0; 2257ec3b29aSmrg 2267ec3b29aSmrg core_ctx = wglCreateContextAttribsARB_func(hdc, 0, attribs); 2277ec3b29aSmrg if (core_ctx) { 2287ec3b29aSmrg break; 2297ec3b29aSmrg } 2307ec3b29aSmrg } 2317ec3b29aSmrg 2327ec3b29aSmrg if (!core_ctx) { 2337ec3b29aSmrg printf("Failed to create core profile context.\n"); 2347ec3b29aSmrg return; 2357ec3b29aSmrg } 2367ec3b29aSmrg 2377ec3b29aSmrg ctx = core_ctx; 2387ec3b29aSmrg if (!wglMakeCurrent(hdc, ctx)) { 2397ec3b29aSmrg printf("Failed to bind core profile context.\n"); 2407ec3b29aSmrg return; 2417ec3b29aSmrg } 2427ec3b29aSmrg oglString = "OpenGL core profile"; 2437ec3b29aSmrg } 2447ec3b29aSmrg else { 2457ec3b29aSmrg coreProfile = GL_FALSE; 24632001f49Smrg } 24732001f49Smrg 24832001f49Smrg extfuncs.GetProgramivARB = (PFNGLGETPROGRAMIVARBPROC) 24932001f49Smrg wglGetProcAddress("glGetProgramivARB"); 25032001f49Smrg extfuncs.GetStringi = (PFNGLGETSTRINGIPROC) 25132001f49Smrg wglGetProcAddress("glGetStringi"); 25232001f49Smrg extfuncs.GetConvolutionParameteriv = (GETCONVOLUTIONPARAMETERIVPROC) 25332001f49Smrg wglGetProcAddress("glGetConvolutionParameteriv"); 25432001f49Smrg 2557ec3b29aSmrg glVendor = (const char *) glGetString(GL_VENDOR); 2567ec3b29aSmrg glRenderer = (const char *) glGetString(GL_RENDERER); 2577ec3b29aSmrg glVersion = (const char *) glGetString(GL_VERSION); 2587ec3b29aSmrg if (coreProfile) { 2597ec3b29aSmrg glExtensions = build_core_profile_extension_list(&extfuncs); 2607ec3b29aSmrg } 2617ec3b29aSmrg else { 2627ec3b29aSmrg glExtensions = (const char *) glGetString(GL_EXTENSIONS); 2637ec3b29aSmrg } 2647ec3b29aSmrg 2657ec3b29aSmrg /* 2667ec3b29aSmrg * Print all the vendor, version, extension strings. 2677ec3b29aSmrg */ 2687ec3b29aSmrg 2697ec3b29aSmrg if (!coreProfile) { 2707ec3b29aSmrg if (wglExtensions && opts->mode != Brief) { 2717ec3b29aSmrg printf("WGL extensions:\n"); 2727ec3b29aSmrg print_extension_list(wglExtensions, opts->singleLine); 2737ec3b29aSmrg } 2747ec3b29aSmrg printf("OpenGL vendor string: %s\n", glVendor); 2757ec3b29aSmrg printf("OpenGL renderer string: %s\n", glRenderer); 2767ec3b29aSmrg } 2777ec3b29aSmrg 2787ec3b29aSmrg printf("%s version string: %s\n", oglString, glVersion); 2797ec3b29aSmrg 28032001f49Smrg version = (glVersion[0] - '0') * 10 + (glVersion[2] - '0'); 28132001f49Smrg 2827ec3b29aSmrg#ifdef GL_VERSION_2_0 2837ec3b29aSmrg if (version >= 20) { 2847ec3b29aSmrg char *v = (char *) glGetString(GL_SHADING_LANGUAGE_VERSION); 2857ec3b29aSmrg printf("%s shading language version string: %s\n", oglString, v); 2867ec3b29aSmrg } 2877ec3b29aSmrg#endif 2887ec3b29aSmrg#ifdef GL_VERSION_3_0 2897ec3b29aSmrg if (version >= 30) { 2907ec3b29aSmrg GLint flags; 2917ec3b29aSmrg glGetIntegerv(GL_CONTEXT_FLAGS, &flags); 2927ec3b29aSmrg printf("%s context flags: %s\n", oglString, context_flags_string(flags)); 2937ec3b29aSmrg } 2947ec3b29aSmrg#endif 2957ec3b29aSmrg#ifdef GL_VERSION_3_2 2967ec3b29aSmrg if (version >= 32) { 2977ec3b29aSmrg GLint mask; 2987ec3b29aSmrg glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &mask); 2997ec3b29aSmrg printf("%s profile mask: %s\n", oglString, profile_mask_string(mask)); 3007ec3b29aSmrg } 3017ec3b29aSmrg#endif 3027ec3b29aSmrg 3037ec3b29aSmrg if (opts->mode != Brief) { 3047ec3b29aSmrg printf("%s extensions:\n", oglString); 3057ec3b29aSmrg print_extension_list(glExtensions, opts->singleLine); 3067ec3b29aSmrg } 3077ec3b29aSmrg 3087ec3b29aSmrg if (opts->limits) { 30932001f49Smrg print_limits(glExtensions, oglString, version, &extfuncs); 31032001f49Smrg } 31132001f49Smrg } 31232001f49Smrg else { 31332001f49Smrg fprintf(stderr, "Error: wglMakeCurrent failed\n"); 31432001f49Smrg } 31532001f49Smrg 31632001f49Smrg DestroyWindow(win); 31732001f49Smrg} 31832001f49Smrg 31932001f49Smrg 32032001f49Smrgstatic const char * 32132001f49Smrgvisual_render_type_name(BYTE iPixelType) 32232001f49Smrg{ 32332001f49Smrg switch (iPixelType) { 32432001f49Smrg case PFD_TYPE_RGBA: 32532001f49Smrg return "rgba"; 32632001f49Smrg case PFD_TYPE_COLORINDEX: 32732001f49Smrg return "ci"; 32832001f49Smrg default: 32932001f49Smrg return ""; 33032001f49Smrg } 33132001f49Smrg} 33232001f49Smrg 33332001f49Smrgstatic void 3347ec3b29aSmrgprint_visual_attribs_verbose(int iPixelFormat, const struct format_info *info) 33532001f49Smrg{ 3367ec3b29aSmrg printf("Visual ID: %x generic=%d drawToWindow=%d drawToBitmap=%d drawToPBuffer=%d GDI=%d\n", 33732001f49Smrg iPixelFormat, 3387ec3b29aSmrg info->pfd.dwFlags & PFD_GENERIC_FORMAT ? 1 : 0, 3397ec3b29aSmrg info->pfd.dwFlags & PFD_DRAW_TO_WINDOW ? 1 : 0, 3407ec3b29aSmrg info->draw_to_bitmap, 3417ec3b29aSmrg info->draw_to_pbuffer, 3427ec3b29aSmrg info->gdi_drawing); 34332001f49Smrg printf(" bufferSize=%d level=%d renderType=%s doubleBuffer=%d stereo=%d\n", 3447ec3b29aSmrg 0 /* info->pfd.bufferSize */, 0 /* info->pfd.level */, 3457ec3b29aSmrg visual_render_type_name(info->pfd.iPixelType), 3467ec3b29aSmrg info->pfd.dwFlags & PFD_DOUBLEBUFFER ? 1 : 0, 3477ec3b29aSmrg info->pfd.dwFlags & PFD_STEREO ? 1 : 0); 3487ec3b29aSmrg printf(" rgba: cRedBits=%d cGreenBits=%d cBlueBits=%d cAlphaBits=%d float=%c sRGB=%c\n", 3497ec3b29aSmrg info->pfd.cRedBits, info->pfd.cGreenBits, 3507ec3b29aSmrg info->pfd.cBlueBits, info->pfd.cAlphaBits, 3517ec3b29aSmrg info->floatComponents ? 'Y' : 'N', 3527ec3b29aSmrg info->srgb ? 'Y' : 'N'); 35332001f49Smrg printf(" cAuxBuffers=%d cDepthBits=%d cStencilBits=%d\n", 3547ec3b29aSmrg info->pfd.cAuxBuffers, info->pfd.cDepthBits, info->pfd.cStencilBits); 35532001f49Smrg printf(" accum: cRedBits=%d cGreenBits=%d cBlueBits=%d cAlphaBits=%d\n", 3567ec3b29aSmrg info->pfd.cAccumRedBits, info->pfd.cAccumGreenBits, 3577ec3b29aSmrg info->pfd.cAccumBlueBits, info->pfd.cAccumAlphaBits); 35832001f49Smrg printf(" multiSample=%d multiSampleBuffers=%d\n", 3597ec3b29aSmrg info->numSamples, info->sampleBuffers); 3607ec3b29aSmrg if (info->pfd.dwFlags & PFD_SWAP_EXCHANGE) 3617ec3b29aSmrg printf(" swapMethod = Exchange\n"); 3627ec3b29aSmrg else if (info->pfd.dwFlags & PFD_SWAP_COPY) 3637ec3b29aSmrg printf(" swapMethod = Copy\n"); 3647ec3b29aSmrg else 3657ec3b29aSmrg printf(" swapMethod = Undefined\n"); 36632001f49Smrg} 36732001f49Smrg 36832001f49Smrg 36932001f49Smrgstatic void 37032001f49Smrgprint_visual_attribs_short_header(void) 37132001f49Smrg{ 3727ec3b29aSmrg printf(" visual x bf lv rg d st colorbuffer sr ax dp st accumbuffer ms \n"); 3737ec3b29aSmrg printf(" id gen win sp sz l ci b ro r g b a F gb bf th cl r g b a ns b\n"); 3747ec3b29aSmrg printf("-------------------------------------------------------------------------\n"); 37532001f49Smrg} 37632001f49Smrg 37732001f49Smrg 37832001f49Smrgstatic void 3797ec3b29aSmrgprint_visual_attribs_short(int iPixelFormat, const struct format_info *info) 38032001f49Smrg{ 3817ec3b29aSmrg printf("0x%03x %2d %2d %2d %3d %2d %c%c %c %c %2d %2d %2d %2d %c %c %2d %2d %2d", 38232001f49Smrg iPixelFormat, 3837ec3b29aSmrg info->pfd.dwFlags & PFD_GENERIC_FORMAT ? 1 : 0, 3847ec3b29aSmrg info->pfd.dwFlags & PFD_DRAW_TO_WINDOW ? 1 : 0, 3857ec3b29aSmrg info->transparency, 3867ec3b29aSmrg info->pfd.cColorBits, 3877ec3b29aSmrg 0 /* info->pfd.level */, 3887ec3b29aSmrg info->pfd.iPixelType == PFD_TYPE_RGBA ? 'r' : ' ', 3897ec3b29aSmrg info->pfd.iPixelType == PFD_TYPE_COLORINDEX ? 'c' : ' ', 3907ec3b29aSmrg info->pfd.dwFlags & PFD_DOUBLEBUFFER ? 'y' : '.', 3917ec3b29aSmrg info->pfd.dwFlags & PFD_STEREO ? 'y' : '.', 3927ec3b29aSmrg info->pfd.cRedBits, info->pfd.cGreenBits, 3937ec3b29aSmrg info->pfd.cBlueBits, info->pfd.cAlphaBits, 3947ec3b29aSmrg info->floatComponents ? 'f' : '.', 3957ec3b29aSmrg info->srgb ? 's' : '.', 3967ec3b29aSmrg info->pfd.cAuxBuffers, 3977ec3b29aSmrg info->pfd.cDepthBits, 3987ec3b29aSmrg info->pfd.cStencilBits 39932001f49Smrg ); 40032001f49Smrg 4017ec3b29aSmrg printf(" %2d %2d %2d %2d %2d %1d\n", 4027ec3b29aSmrg info->pfd.cAccumRedBits, info->pfd.cAccumGreenBits, 4037ec3b29aSmrg info->pfd.cAccumBlueBits, info->pfd.cAccumAlphaBits, 4047ec3b29aSmrg info->numSamples, info->sampleBuffers); 40532001f49Smrg} 40632001f49Smrg 40732001f49Smrg 40832001f49Smrgstatic void 40932001f49Smrgprint_visual_attribs_long_header(void) 41032001f49Smrg{ 4117ec3b29aSmrg printf("Vis Vis Visual Trans buff lev render DB ste r g b a s aux dep ste accum buffers MS MS \n"); 4127ec3b29aSmrg printf(" ID Depth Type parent size el type reo sz sz sz sz flt rgb buf th ncl r g b a num bufs\n"); 4137ec3b29aSmrg printf("------------------------------------------------------------------------------------------------------------\n"); 41432001f49Smrg} 41532001f49Smrg 41632001f49Smrg 41732001f49Smrgstatic void 4187ec3b29aSmrgprint_visual_attribs_long(int iPixelFormat, const struct format_info *info) 41932001f49Smrg{ 4207ec3b29aSmrg printf("0x%3x %2d %11d %2d %2d %2d %4s %3d %3d %3d %3d %3d %3d", 42132001f49Smrg iPixelFormat, 4227ec3b29aSmrg info->pfd.dwFlags & PFD_GENERIC_FORMAT ? 1 : 0, 4237ec3b29aSmrg info->pfd.dwFlags & PFD_DRAW_TO_WINDOW ? 1 : 0, 42432001f49Smrg 0, 4257ec3b29aSmrg 0 /* info->pfd.bufferSize */, 4267ec3b29aSmrg 0 /* info->pfd.level */, 4277ec3b29aSmrg visual_render_type_name(info->pfd.iPixelType), 4287ec3b29aSmrg info->pfd.dwFlags & PFD_DOUBLEBUFFER ? 1 : 0, 4297ec3b29aSmrg info->pfd.dwFlags & PFD_STEREO ? 1 : 0, 4307ec3b29aSmrg info->pfd.cRedBits, info->pfd.cGreenBits, 4317ec3b29aSmrg info->pfd.cBlueBits, info->pfd.cAlphaBits 43232001f49Smrg ); 43332001f49Smrg 4347ec3b29aSmrg printf(" %c %c %3d %4d %2d %3d %3d %3d %3d %2d %2d\n", 4357ec3b29aSmrg info->floatComponents ? 'f' : '.', 4367ec3b29aSmrg info->srgb ? 's' : '.', 4377ec3b29aSmrg info->pfd.cAuxBuffers, 4387ec3b29aSmrg info->pfd.cDepthBits, 4397ec3b29aSmrg info->pfd.cStencilBits, 4407ec3b29aSmrg info->pfd.cAccumRedBits, info->pfd.cAccumGreenBits, 4417ec3b29aSmrg info->pfd.cAccumBlueBits, info->pfd.cAccumAlphaBits, 4427ec3b29aSmrg info->sampleBuffers, info->numSamples 44332001f49Smrg ); 44432001f49Smrg} 44532001f49Smrg 44632001f49Smrg 4477ec3b29aSmrg/** 4487ec3b29aSmrg * Wrapper for wglGetPixelFormatAttribivARB() 4497ec3b29aSmrg * \param attrib the WGL_* attribute to query 4507ec3b29aSmrg * \return value of the attribute, or 0 if failure 4517ec3b29aSmrg */ 4527ec3b29aSmrgstatic int 4537ec3b29aSmrgget_pf_attrib(HDC hdc, int pf, int attrib) 4547ec3b29aSmrg{ 4557ec3b29aSmrg int layer = 0, value; 4567ec3b29aSmrg assert(have_WGL_ARB_pixel_format); 4577ec3b29aSmrg if (wglGetPixelFormatAttribivARB_func(hdc, pf, layer, 1, &attrib, &value)) { 4587ec3b29aSmrg return value; 4597ec3b29aSmrg } 4607ec3b29aSmrg else { 4617ec3b29aSmrg return 0; 4627ec3b29aSmrg } 4637ec3b29aSmrg} 4647ec3b29aSmrg 4657ec3b29aSmrg 4667ec3b29aSmrg/** 4677ec3b29aSmrg * Fill in the format_info fields for the pixel format given by pf. 4687ec3b29aSmrg */ 4697ec3b29aSmrgstatic GLboolean 4707ec3b29aSmrgget_format_info(HDC hdc, int pf, struct format_info *info) 4717ec3b29aSmrg{ 4727ec3b29aSmrg memset(info, 0, sizeof(*info)); 4737ec3b29aSmrg 4747ec3b29aSmrg if (have_WGL_ARB_pixel_format) { 4757ec3b29aSmrg int swapMethod; 4767ec3b29aSmrg 4777ec3b29aSmrg info->pfd.dwFlags = 0; 4787ec3b29aSmrg if (get_pf_attrib(hdc, pf, WGL_DRAW_TO_WINDOW_ARB)) 4797ec3b29aSmrg info->pfd.dwFlags |= PFD_DRAW_TO_WINDOW; 4807ec3b29aSmrg if (!get_pf_attrib(hdc, pf, WGL_ACCELERATION_ARB)) 4817ec3b29aSmrg info->pfd.dwFlags |= PFD_GENERIC_FORMAT; 4827ec3b29aSmrg if (get_pf_attrib(hdc, pf, WGL_SUPPORT_OPENGL_ARB)) 4837ec3b29aSmrg info->pfd.dwFlags |= PFD_SUPPORT_OPENGL; 4847ec3b29aSmrg if (get_pf_attrib(hdc, pf, WGL_DOUBLE_BUFFER_ARB)) 4857ec3b29aSmrg info->pfd.dwFlags |= PFD_DOUBLEBUFFER; 4867ec3b29aSmrg if (get_pf_attrib(hdc, pf, WGL_STEREO_ARB)) 4877ec3b29aSmrg info->pfd.dwFlags |= PFD_STEREO; 4887ec3b29aSmrg 4897ec3b29aSmrg if (get_pf_attrib(hdc, pf, WGL_DRAW_TO_BITMAP_ARB)) 4907ec3b29aSmrg info->draw_to_bitmap = true; 4917ec3b29aSmrg if (have_WGL_ARB_pbuffer && get_pf_attrib(hdc, pf, WGL_DRAW_TO_PBUFFER_ARB)) 4927ec3b29aSmrg info->draw_to_pbuffer = true; 4937ec3b29aSmrg if (get_pf_attrib(hdc, pf, WGL_SUPPORT_GDI_ARB)) 4947ec3b29aSmrg info->gdi_drawing = true; 4957ec3b29aSmrg 4967ec3b29aSmrg swapMethod = get_pf_attrib(hdc, pf, WGL_SWAP_METHOD_ARB); 4977ec3b29aSmrg if (swapMethod == WGL_SWAP_EXCHANGE_ARB) 4987ec3b29aSmrg info->pfd.dwFlags |= PFD_SWAP_EXCHANGE; 4997ec3b29aSmrg else if (swapMethod == WGL_SWAP_COPY_ARB) 5007ec3b29aSmrg info->pfd.dwFlags |= PFD_SWAP_COPY; 5017ec3b29aSmrg 5027ec3b29aSmrg int pixel_type = get_pf_attrib(hdc, pf, WGL_PIXEL_TYPE_ARB); 5037ec3b29aSmrg if (pixel_type == WGL_TYPE_RGBA_ARB) 5047ec3b29aSmrg info->pfd.iPixelType = PFD_TYPE_RGBA; 5057ec3b29aSmrg else if (pixel_type == WGL_TYPE_COLORINDEX_ARB) 5067ec3b29aSmrg info->pfd.iPixelType = PFD_TYPE_COLORINDEX; 5077ec3b29aSmrg else if (pixel_type == WGL_TYPE_RGBA_FLOAT_ARB) { 5087ec3b29aSmrg info->pfd.iPixelType = PFD_TYPE_RGBA; 5097ec3b29aSmrg info->floatComponents = true; 5107ec3b29aSmrg } 5117ec3b29aSmrg 5127ec3b29aSmrg info->pfd.cColorBits = get_pf_attrib(hdc, pf, WGL_COLOR_BITS_ARB); 5137ec3b29aSmrg info->pfd.cRedBits = get_pf_attrib(hdc, pf, WGL_RED_BITS_ARB); 5147ec3b29aSmrg info->pfd.cGreenBits = get_pf_attrib(hdc, pf, WGL_GREEN_BITS_ARB); 5157ec3b29aSmrg info->pfd.cBlueBits = get_pf_attrib(hdc, pf, WGL_BLUE_BITS_ARB); 5167ec3b29aSmrg info->pfd.cAlphaBits = get_pf_attrib(hdc, pf, WGL_ALPHA_BITS_ARB); 5177ec3b29aSmrg 5187ec3b29aSmrg info->pfd.cDepthBits = get_pf_attrib(hdc, pf, WGL_DEPTH_BITS_ARB); 5197ec3b29aSmrg info->pfd.cStencilBits = get_pf_attrib(hdc, pf, WGL_STENCIL_BITS_ARB); 5207ec3b29aSmrg info->pfd.cAuxBuffers = get_pf_attrib(hdc, pf, WGL_AUX_BUFFERS_ARB); 5217ec3b29aSmrg 5227ec3b29aSmrg info->pfd.cAccumRedBits = get_pf_attrib(hdc, pf, 5237ec3b29aSmrg WGL_ACCUM_RED_BITS_ARB); 5247ec3b29aSmrg info->pfd.cAccumGreenBits = get_pf_attrib(hdc, pf, 5257ec3b29aSmrg WGL_ACCUM_GREEN_BITS_ARB); 5267ec3b29aSmrg info->pfd.cAccumBlueBits = get_pf_attrib(hdc, pf, 5277ec3b29aSmrg WGL_ACCUM_BLUE_BITS_ARB); 5287ec3b29aSmrg info->pfd.cAccumAlphaBits = get_pf_attrib(hdc, pf, 5297ec3b29aSmrg WGL_ACCUM_ALPHA_BITS_ARB); 5307ec3b29aSmrg 5317ec3b29aSmrg info->sampleBuffers = get_pf_attrib(hdc, pf, WGL_SAMPLE_BUFFERS_ARB); 5327ec3b29aSmrg info->numSamples = get_pf_attrib(hdc, pf, WGL_SAMPLES_ARB); 5337ec3b29aSmrg 5347ec3b29aSmrg info->transparency = get_pf_attrib(hdc, pf, WGL_TRANSPARENT_ARB); 5357ec3b29aSmrg 5367ec3b29aSmrg if (have_WGL_ARB_framebuffer_sRGB) { 5377ec3b29aSmrg info->srgb = get_pf_attrib(hdc, pf, WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB); 5387ec3b29aSmrg } 5397ec3b29aSmrg } 5407ec3b29aSmrg else { 5417ec3b29aSmrg if (!DescribePixelFormat(hdc, pf, 5427ec3b29aSmrg sizeof(PIXELFORMATDESCRIPTOR), &info->pfd)) 5437ec3b29aSmrg return GL_FALSE; 5447ec3b29aSmrg } 5457ec3b29aSmrg return GL_TRUE; 5467ec3b29aSmrg} 5477ec3b29aSmrg 5487ec3b29aSmrg 5497ec3b29aSmrg 55032001f49Smrgstatic void 55132001f49Smrgprint_visual_info(HDC hdc, InfoMode mode) 55232001f49Smrg{ 5537ec3b29aSmrg struct format_info info; 55432001f49Smrg int numVisuals, numWglVisuals; 55532001f49Smrg int i; 55632001f49Smrg 5577ec3b29aSmrg wglGetPixelFormatAttribivARB_func = 5587ec3b29aSmrg (PFNWGLGETPIXELFORMATATTRIBIVARBPROC) 5597ec3b29aSmrg wglGetProcAddress("wglGetPixelFormatAttribivARB"); 5607ec3b29aSmrg 5617ec3b29aSmrg /* Get number of visuals / pixel formats */ 5627ec3b29aSmrg numVisuals = DescribePixelFormat(hdc, 1, 5637ec3b29aSmrg sizeof(PIXELFORMATDESCRIPTOR), NULL); 5647ec3b29aSmrg printf("%d Regular pixel formats\n", numVisuals); 5657ec3b29aSmrg 5667ec3b29aSmrg if (have_WGL_ARB_pixel_format) { 5677ec3b29aSmrg int numExtVisuals = get_pf_attrib(hdc, 0, WGL_NUMBER_PIXEL_FORMATS_ARB); 5687ec3b29aSmrg printf("%d Regular + Extended pixel formats\n", numExtVisuals); 5697ec3b29aSmrg numVisuals = numExtVisuals; 5707ec3b29aSmrg } 5717ec3b29aSmrg 57232001f49Smrg if (numVisuals == 0) 57332001f49Smrg return; 57432001f49Smrg 57532001f49Smrg numWglVisuals = 0; 57632001f49Smrg for (i = 0; i < numVisuals; i++) { 5777ec3b29aSmrg if(!DescribePixelFormat(hdc, i, sizeof(PIXELFORMATDESCRIPTOR), &info.pfd)) 57832001f49Smrg continue; 57932001f49Smrg 5807ec3b29aSmrg //if(!(info.pfd.dwFlags & PFD_SUPPORT_OPENGL)) 58132001f49Smrg // continue; 58232001f49Smrg 58332001f49Smrg ++numWglVisuals; 58432001f49Smrg } 58532001f49Smrg 58632001f49Smrg printf("%d WGL Visuals\n", numWglVisuals); 58732001f49Smrg 58832001f49Smrg if (mode == Normal) 58932001f49Smrg print_visual_attribs_short_header(); 59032001f49Smrg else if (mode == Wide) 59132001f49Smrg print_visual_attribs_long_header(); 59232001f49Smrg 59332001f49Smrg for (i = 0; i < numVisuals; i++) { 5947ec3b29aSmrg get_format_info(hdc, i, &info); 59532001f49Smrg 59632001f49Smrg if (mode == Verbose) 5977ec3b29aSmrg print_visual_attribs_verbose(i, &info); 59832001f49Smrg else if (mode == Normal) 5997ec3b29aSmrg print_visual_attribs_short(i, &info); 60032001f49Smrg else if (mode == Wide) 6017ec3b29aSmrg print_visual_attribs_long(i, &info); 60232001f49Smrg } 60332001f49Smrg printf("\n"); 60432001f49Smrg} 60532001f49Smrg 60632001f49Smrg 60732001f49Smrg/* 60832001f49Smrg * Examine all visuals to find the so-called best one. 60932001f49Smrg * We prefer deepest RGBA buffer with depth, stencil and accum 61032001f49Smrg * that has no caveats. 61132001f49Smrg */ 61232001f49Smrgstatic int 61332001f49Smrgfind_best_visual(HDC hdc) 61432001f49Smrg{ 61532001f49Smrg#if 0 61632001f49Smrg XVisualInfo theTemplate; 61732001f49Smrg XVisualInfo *visuals; 61832001f49Smrg int numVisuals; 61932001f49Smrg long mask; 62032001f49Smrg int i; 62132001f49Smrg struct visual_attribs bestVis; 62232001f49Smrg 62332001f49Smrg /* get list of all visuals on this screen */ 62432001f49Smrg theTemplate.screen = scrnum; 62532001f49Smrg mask = VisualScreenMask; 62632001f49Smrg visuals = XGetVisualInfo(hdc, mask, &theTemplate, &numVisuals); 62732001f49Smrg 62832001f49Smrg /* init bestVis with first visual info */ 62932001f49Smrg get_visual_attribs(hdc, &visuals[0], &bestVis); 63032001f49Smrg 63132001f49Smrg /* try to find a "better" visual */ 63232001f49Smrg for (i = 1; i < numVisuals; i++) { 63332001f49Smrg struct visual_attribs vis; 63432001f49Smrg 63532001f49Smrg get_visual_attribs(hdc, &visuals[i], &vis); 63632001f49Smrg 63732001f49Smrg /* always skip visuals with caveats */ 63832001f49Smrg if (vis.visualCaveat != GLX_NONE_EXT) 63932001f49Smrg continue; 64032001f49Smrg 64132001f49Smrg /* see if this vis is better than bestVis */ 64232001f49Smrg if ((!bestVis.supportsGL && vis.supportsGL) || 64332001f49Smrg (bestVis.visualCaveat != GLX_NONE_EXT) || 64432001f49Smrg (bestVis.iPixelType != vis.iPixelType) || 64532001f49Smrg (!bestVis.doubleBuffer && vis.doubleBuffer) || 64632001f49Smrg (bestVis.cRedBits < vis.cRedBits) || 64732001f49Smrg (bestVis.cGreenBits < vis.cGreenBits) || 64832001f49Smrg (bestVis.cBlueBits < vis.cBlueBits) || 64932001f49Smrg (bestVis.cAlphaBits < vis.cAlphaBits) || 65032001f49Smrg (bestVis.cDepthBits < vis.cDepthBits) || 65132001f49Smrg (bestVis.cStencilBits < vis.cStencilBits) || 65232001f49Smrg (bestVis.cAccumRedBits < vis.cAccumRedBits)) { 65332001f49Smrg /* found a better visual */ 65432001f49Smrg bestVis = vis; 65532001f49Smrg } 65632001f49Smrg } 65732001f49Smrg 65832001f49Smrg return bestVis.id; 65932001f49Smrg#else 66032001f49Smrg return 0; 66132001f49Smrg#endif 66232001f49Smrg} 66332001f49Smrg 66432001f49Smrg 66532001f49Smrg 66632001f49Smrgint 66732001f49Smrgmain(int argc, char *argv[]) 66832001f49Smrg{ 66932001f49Smrg HDC hdc; 6707ec3b29aSmrg struct options opts; 67132001f49Smrg 6727ec3b29aSmrg parse_args(argc, argv, &opts); 67332001f49Smrg 67432001f49Smrg hdc = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL); 67532001f49Smrg 6767ec3b29aSmrg if (opts.findBest) { 67732001f49Smrg int b; 67832001f49Smrg b = find_best_visual(hdc); 67932001f49Smrg printf("%d\n", b); 68032001f49Smrg } 68132001f49Smrg else { 6827ec3b29aSmrg print_screen_info(hdc, &opts, GL_FALSE); 6837ec3b29aSmrg printf("\n"); 6847ec3b29aSmrg print_screen_info(hdc, &opts, GL_TRUE); 68532001f49Smrg printf("\n"); 6867ec3b29aSmrg if (opts.mode != Brief) { 6877ec3b29aSmrg print_visual_info(hdc, opts.mode); 6887ec3b29aSmrg } 68932001f49Smrg } 69032001f49Smrg 69132001f49Smrg return 0; 69232001f49Smrg} 693