diff options
Diffstat (limited to 'hw/xwin/glx/indirect.c')
-rw-r--r-- | hw/xwin/glx/indirect.c | 380 |
1 files changed, 294 insertions, 86 deletions
diff --git a/hw/xwin/glx/indirect.c b/hw/xwin/glx/indirect.c index 239327ed4..6aeabf4c9 100644 --- a/hw/xwin/glx/indirect.c +++ b/hw/xwin/glx/indirect.c @@ -87,6 +87,7 @@ #include <wgl_ext_api.h> #include <winglobals.h> #include <indirect.h> +#include <setjmp.h> #define NUM_ELEMENTS(x) (sizeof(x)/ sizeof(x[1])) @@ -102,6 +103,12 @@ #endif +typedef struct { + int notOpenGL; + int unknownPixelType; + int unaccelerated; +} PixelFormatRejectStats; + /* ---------------------------------------------------------------------- */ /* * Various debug helpers @@ -287,23 +294,29 @@ swap_method_name(int mthd) } static void -fbConfigsDump(unsigned int n, __GLXconfig * c) +fbConfigsDump(unsigned int n, __GLXconfig * c, PixelFormatRejectStats *rejects) { LogMessage(X_INFO, "%d fbConfigs\n", n); + LogMessage(X_INFO, "ignored pixel formats: %d not OpenGL, %d unknown pixel type, %d unaccelerated\n", + rejects->notOpenGL, rejects->unknownPixelType, rejects->unaccelerated); if (g_iLogVerbose < 3) return; - ErrorF("%d fbConfigs\n", n); + ErrorF - ("pxf vis fb render Ste aux accum MS drawable Group/\n"); + ("pxf vis fb render Ste aux accum MS drawable Group/ sRGB\n"); ErrorF - ("idx ID ID VisualType Depth Lvl RGB CI DB Swap reo R G B A Z S buf AR AG AB AA bufs num W P Pb Float Trans Caveat\n"); + ("idx ID ID VisualType Depth Lvl RGB CI DB Swap reo R G B A Z S buf AR AG AB AA bufs num W P Pb Float Trans Caveat cap \n"); ErrorF - ("-----------------------------------------------------------------------------------------------------------------------------\n"); + ("----------------------------------------------------------------------------------------------------------------------------------\n"); while (c != NULL) { unsigned int i = ((GLXWinConfig *) c)->pixelFormatIndex; + const char *float_col = "."; + if (c->renderType & GLX_RGBA_FLOAT_BIT_ARB) float_col = "s"; + if (c->renderType & GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT) float_col = "u"; + ErrorF("%3d %3x %3x " "%-11s" " %3d %3d %s %s %s %s %s " @@ -315,7 +328,8 @@ fbConfigsDump(unsigned int n, __GLXconfig * c) " %s %s %s " " %s " " %s " - " %d %s" + " %d %s " + " %s" "\n", i, c->visualID, c->fbconfigID, visual_class_name(c->visualType), @@ -334,11 +348,11 @@ fbConfigsDump(unsigned int n, __GLXconfig * c) (c->drawableType & GLX_WINDOW_BIT) ? "y" : ".", (c->drawableType & GLX_PIXMAP_BIT) ? "y" : ".", (c->drawableType & GLX_PBUFFER_BIT) ? "y" : ".", - (c->renderType & (GLX_RGBA_FLOAT_BIT_ARB | - GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT)) ? "y" : ".", + float_col, (c->transparentPixel != GLX_NONE_EXT) ? "y" : ".", c->visualSelectGroup, - (c->visualRating == GLX_SLOW_VISUAL_EXT) ? "*" : " "); + (c->visualRating == GLX_SLOW_VISUAL_EXT) ? "*" : " ", + c->sRGBCapable ? "y" : "."); c = c->next; } @@ -373,7 +387,8 @@ static HDC glxWinMakeDC(__GLXWinContext * gc, __GLXWinDrawable * draw, static void glxWinReleaseDC(HWND hwnd, HDC hdc, __GLXWinDrawable * draw); static void glxWinCreateConfigs(HDC dc, glxWinScreen * screen); -static void glxWinCreateConfigsExt(HDC hdc, glxWinScreen * screen); +static void glxWinCreateConfigsExt(HDC hdc, glxWinScreen * screen, + PixelFormatRejectStats * rejects); static int fbConfigToPixelFormat(__GLXconfig * mode, PIXELFORMATDESCRIPTOR * pfdret, int drawableTypeOverride); @@ -468,6 +483,30 @@ glxLogExtensions(const char *prefix, const char *extensions) free(str); } +static jmp_buf jmp_sig; +static struct sigaction old_act; +extern Bool install_os_signal_handler; + +static void +glxWinScreenProbeSigHandler(int signo, siginfo_t * sip, void *context) +{ + // log a message + ErrorFSigSafe("segfault in WGL during glxWinScreenProbe()\n"); + + // show a messagebox + MessageBox(NULL, + "Windows OpenGL has been disabled as a crash occurred during initialization.\n" + "\n" + "Please try updating the display driver.\n" + "\n" + "You can disable the use of Windows OpenGL by starting the X server using the -nowgl option.", + XVENDORNAMESHORT, + MB_OK | MB_ICONERROR | MB_TASKMODAL | MB_SETFOREGROUND); + + // continue via longjmp() + longjmp(jmp_sig, 1); +} + /* This is called by GlxExtensionInit() asking the GLX provider if it can handle the screen... */ static __GLXscreen * glxWinScreenProbe(ScreenPtr pScreen) @@ -479,6 +518,7 @@ glxWinScreenProbe(ScreenPtr pScreen) HWND hwnd; HDC hdc; HGLRC hglrc; + PixelFormatRejectStats rejects; GLWIN_DEBUG_MSG("glxWinScreenProbe"); @@ -499,8 +539,11 @@ glxWinScreenProbe(ScreenPtr pScreen) return NULL; // Select the native GL implementation (WGL) - if (glWinSelectImplementation(1)) + if (glWinSelectImplementation(1)) { + LogMessage(X_ERROR, "AIGLX: WGL not available\n"); + free(screen); return NULL; + } // create window class #define WIN_GL_TEST_WINDOW_CLASS "XWinGLTest" @@ -511,7 +554,7 @@ glxWinScreenProbe(ScreenPtr pScreen) WNDCLASSEX wc; wc.cbSize = sizeof(WNDCLASSEX); - wc.style = CS_HREDRAW | CS_VREDRAW; + wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; wc.lpfnWndProc = DefWindowProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; @@ -526,22 +569,79 @@ glxWinScreenProbe(ScreenPtr pScreen) } } + // The following tests seem particularly prone to crashing somewhere in the + // display driver's OpenGL implementation. So temporarily install a special + // SIGSEGV handler so can catch that and offer some remedial advice... + if (install_os_signal_handler) + { + struct sigaction act; + sigemptyset(&act.sa_mask); + act.sa_sigaction = glxWinScreenProbeSigHandler; + act.sa_flags = SA_SIGINFO; + sigaction(SIGSEGV, &act, &old_act); + + if (setjmp(jmp_sig)) { + LogMessage(X_ERROR, "AIGLX: Not using WGL due to SEGV\n"); + goto error; + } + } + // create an invisible window for a scratch DC hwnd = CreateWindowExA(0, WIN_GL_TEST_WINDOW_CLASS, "XWin GL Renderer Capabilities Test Window", 0, 0, 0, 0, 0, NULL, NULL, GetModuleHandle(NULL), NULL); - if (hwnd == NULL) + if (hwnd == NULL) { LogMessage(X_ERROR, "AIGLX: Couldn't create a window for render capabilities testing\n"); + goto error; + } hdc = GetDC(hwnd); + if (!hdc) { + LogMessage(X_ERROR, "AIGLX: Couldn't create a DC for render capabilities testing\n"); + goto error; + } + + // we must set a pixel format before we can create a context + { + PIXELFORMATDESCRIPTOR pfd = { + sizeof(PIXELFORMATDESCRIPTOR), + 1, + PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DEPTH_DONTCARE | PFD_DOUBLEBUFFER_DONTCARE | PFD_STEREO_DONTCARE, + PFD_TYPE_RGBA, + 24, + 0, 0, 0, 0, 0, 0, + 0, + 0, + 0, + 0, 0, 0, 0, + 0, + 0, + 0, + PFD_MAIN_PLANE, + 0, + 0, 0, 0 + }; + int iPixelFormat = ChoosePixelFormat(hdc, &pfd); + if (iPixelFormat == 0) { + LogMessage(X_ERROR, "AIGLX: ChoosePixelFormat failed\n"); + goto error; + } + + if (!SetPixelFormat(hdc, iPixelFormat, NULL)) { + LogMessage(X_ERROR, "AIGLX: SetPixelFormat %d failed\n", iPixelFormat); + goto error; + } + LogMessage(X_INFO, "AIGLX: Testing pixelFormatIndex %d\n",iPixelFormat); + } - // we must set a pixel format before we can create a context, just use the first one... - SetPixelFormat(hdc, 1, NULL); hglrc = wglCreateContext(hdc); - wglMakeCurrent(hdc, hglrc); + if (!wglMakeCurrent(hdc, hglrc)) { + ErrorF("glxWinScreenProbe: wglMakeCurrent error: %08x dc %p ctx %p\n", + (unsigned)GetLastError(), hdc, hglrc); + } // initialize wgl extension proc pointers (don't call them before here...) // (but we need to have a current context for them to be resolvable) @@ -553,6 +653,8 @@ glxWinScreenProbe(ScreenPtr pScreen) gl_renderer = (const char *) glGetString(GL_RENDERER); ErrorF("GL_RENDERER: %s\n", gl_renderer); gl_extensions = (const char *) glGetString(GL_EXTENSIONS); + if (!gl_extensions) + gl_extensions = ""; wgl_extensions = wglGetExtensionsStringARBWrapper(hdc); if (!wgl_extensions) wgl_extensions = ""; @@ -562,10 +664,15 @@ glxWinScreenProbe(ScreenPtr pScreen) glxLogExtensions("WGL_EXTENSIONS: ", wgl_extensions); } + if (!gl_renderer) { + LogMessage(X_ERROR, + "AIGLX: Native renderer not identified\n"); + goto error; + } + if (strcasecmp(gl_renderer, "GDI Generic") == 0) { - free(screen); LogMessage(X_ERROR, - "AIGLX: Won't use generic native renderer as it is not accelerated\n"); + "AIGLX: Won't use the generic native renderer as it is not accelerated\n"); goto error; } @@ -574,47 +681,68 @@ glxWinScreenProbe(ScreenPtr pScreen) // might have completely different capabilities. Of course, good luck getting // those screens to be accelerated in XP and earlier... + { + int i; + + const struct + { + const char *wglext; + const char *glxext; + Bool mandatory; + } extensionMap[] = { + { "WGL_ARB_make_current_read", "GLX_SGI_make_current_read", 1 }, + { "WGL_EXT_swap_control", "GLX_SGI_swap_control", 0 }, + { "WGL_EXT_swap_control", "GLX_MESA_swap_control", 0 }, + // { "WGL_ARB_render_texture", "GLX_EXT_texture_from_pixmap", 0 }, + // Sufficiently different that it's not obvious if this can be done... + { "WGL_ARB_pbuffer", "GLX_SGIX_pbuffer", 1 }, + { "WGL_ARB_multisample", "GLX_ARB_multisample", 1 }, + { "WGL_ARB_multisample", "GLX_SGIS_multisample", 0 }, + { "WGL_ARB_pixel_format_float", "GLX_ARB_fbconfig_float", 0 }, + { "WGL_EXT_pixel_format_packed_float", "GLX_EXT_fbconfig_packed_float", 0 }, + { "WGL_ARB_create_context", "GLX_ARB_create_context", 0 }, + { "WGL_ARB_create_context_profile", "GLX_ARB_create_context_profile", 0 }, + { "WGL_ARB_create_context_robustness", "GLX_ARB_create_context_robustness", 0 }, + { "WGL_EXT_create_context_es2_profile", "GLX_EXT_create_context_es2_profile", 0 }, + { "WGL_ARB_framebuffer_sRGB", "GLX_ARB_framebuffer_sRGB", 0 }, + }; + // // Based on the WGL extensions available, enable various GLX extensions - // XXX: make this table-driven ? // __glXInitExtensionEnableBits(screen->base.glx_enable_bits); - if (strstr(wgl_extensions, "WGL_ARB_make_current_read")) - screen->has_WGL_ARB_make_current_read = TRUE; - else - LogMessage(X_WARNING, "AIGLX: missing WGL_ARB_make_current_read\n"); + for (i = 0; i < sizeof(extensionMap)/sizeof(extensionMap[0]); i++) { + if (strstr(wgl_extensions, extensionMap[i].wglext)) { + __glXEnableExtension(screen->glx_enable_bits, extensionMap[i].glxext); + LogMessage(X_INFO, "GLX: enabled %s\n", extensionMap[i].glxext); + } + else if (extensionMap[i].mandatory) { + LogMessage(X_ERROR, "required WGL extension %s is missing\n", extensionMap[i].wglext); + } + } + // Because it pre-dates WGL_EXT_extensions_string, GL_WIN_swap_hint might + // only be in GL_EXTENSIONS if (strstr(gl_extensions, "GL_WIN_swap_hint")) { __glXEnableExtension(screen->base.glx_enable_bits, "GLX_MESA_copy_sub_buffer"); LogMessage(X_INFO, "AIGLX: enabled GLX_MESA_copy_sub_buffer\n"); } - if (strstr(wgl_extensions, "WGL_EXT_swap_control")) { - __glXEnableExtension(screen->base.glx_enable_bits, - "GLX_SGI_swap_control"); - LogMessage(X_INFO, "AIGLX: enabled GLX_SGI_swap_control\n"); - } - -/* // Hmm? screen->texOffset */ -/* if (strstr(wgl_extensions, "WGL_ARB_render_texture")) */ -/* { */ -/* __glXEnableExtension(screen->base.glx_enable_bits, "GLX_EXT_texture_from_pixmap"); */ -/* LogMessage(X_INFO, "AIGLX: GLX_EXT_texture_from_pixmap backed by buffer objects\n"); */ -/* screen->has_WGL_ARB_render_texture = TRUE; */ -/* } */ + if (strstr(wgl_extensions, "WGL_ARB_make_current_read")) + screen->has_WGL_ARB_make_current_read = TRUE; if (strstr(wgl_extensions, "WGL_ARB_pbuffer")) screen->has_WGL_ARB_pbuffer = TRUE; - else - LogMessage(X_WARNING, "AIGLX: missing WGL_ARB_pbuffer\n"); if (strstr(wgl_extensions, "WGL_ARB_multisample")) screen->has_WGL_ARB_multisample = TRUE; - else - LogMessage(X_WARNING, "AIGLX: missing WGL_ARB_multisample\n"); + + if (strstr(wgl_extensions, "WGL_ARB_framebuffer_sRGB")) { + screen->has_WGL_ARB_framebuffer_sRGB = TRUE; + } screen->base.destroy = glxWinScreenDestroy; screen->base.createContext = glxWinCreateContext; @@ -623,8 +751,9 @@ glxWinScreenProbe(ScreenPtr pScreen) screen->base.pScreen = pScreen; // Creating the fbConfigs initializes screen->base.fbconfigs and screen->base.numFBConfigs + memset(&rejects, 0, sizeof(rejects)); if (strstr(wgl_extensions, "WGL_ARB_pixel_format")) { - glxWinCreateConfigsExt(hdc, screen); + glxWinCreateConfigsExt(hdc, screen, &rejects); /* Some graphics drivers appear to advertise WGL_ARB_pixel_format, @@ -637,6 +766,7 @@ glxWinScreenProbe(ScreenPtr pScreen) } if (screen->base.numFBConfigs <= 0) { + memset(&rejects, 0, sizeof(rejects)); glxWinCreateConfigs(hdc, screen); screen->has_WGL_ARB_pixel_format = FALSE; } @@ -645,7 +775,6 @@ glxWinScreenProbe(ScreenPtr pScreen) If we still didn't get any fbConfigs, we can't provide GLX for this screen */ if (screen->base.numFBConfigs <= 0) { - free(screen); LogMessage(X_ERROR, "AIGLX: No fbConfigs could be made from native OpenGL pixel formats\n"); goto error; @@ -664,7 +793,7 @@ glxWinScreenProbe(ScreenPtr pScreen) DestroyWindow(hwnd); // dump out fbConfigs now fbConfigIds and visualIDs have been assigned - fbConfigsDump(screen->base.numFBConfigs, screen->base.fbconfigs); + fbConfigsDump(screen->base.numFBConfigs, screen->base.fbconfigs, &rejects); /* Wrap RealizeWindow, UnrealizeWindow and CopyWindow on this screen */ screen->RealizeWindow = pScreen->RealizeWindow; @@ -677,9 +806,17 @@ glxWinScreenProbe(ScreenPtr pScreen) // Note that WGL is active on this screen winSetScreenAiglxIsActive(pScreen); + // Restore the previous sighandler + sigaction(SIGSEGV, &old_act, NULL); + return &screen->base; error: + // Restore the previous sighandler + sigaction(SIGSEGV, &old_act, NULL); + + free(screen); + // Something went wrong and we can't use the native GL implementation // so make sure the mesa GL implementation is selected instead glWinSelectImplementation(0); @@ -1135,7 +1272,30 @@ glxWinSetPixelFormat(HDC hdc, int bppOverride, int drawableTypeOverride, (config->redBits + config->greenBits + config->blueBits), bppOverride, config->drawableType, drawableTypeOverride); - if (!winScreen->has_WGL_ARB_pixel_format) { + if (winScreen->has_WGL_ARB_pixel_format) { + int pixelFormat = + fbConfigToPixelFormatIndex(hdc, config, + drawableTypeOverride, winScreen); + if (pixelFormat != 0) { + GLWIN_DEBUG_MSG("wglChoosePixelFormat: chose pixelFormatIndex %d", + pixelFormat); + ErrorF + ("wglChoosePixelFormat: chose pixelFormatIndex %d (rather than %d as originally planned)\n", + pixelFormat, winConfig->pixelFormatIndex); + + if (!SetPixelFormat(hdc, pixelFormat, NULL)) { + ErrorF("SetPixelFormat error: %s\n", glxWinErrorMessage()); + return FALSE; + } + } + } + + /* + For some drivers, wglChoosePixelFormatARB() can fail when the provided + DC doesn't belong to the driver (e.g. it's a compatible DC for a bitmap, + so allow fallback to ChoosePixelFormat() + */ + { PIXELFORMATDESCRIPTOR pfd; int pixelFormat; @@ -1171,25 +1331,6 @@ glxWinSetPixelFormat(HDC hdc, int bppOverride, int drawableTypeOverride, return FALSE; } } - else { - int pixelFormat = fbConfigToPixelFormatIndex(hdc, config, - drawableTypeOverride, - winScreen); - if (pixelFormat == 0) { - return FALSE; - } - - GLWIN_DEBUG_MSG("wglChoosePixelFormat: chose pixelFormatIndex %d", - pixelFormat); - ErrorF - ("wglChoosePixelFormat: chose pixelFormatIndex %d (rather than %d as originally planned)\n", - pixelFormat, winConfig->pixelFormatIndex); - - if (!SetPixelFormat(hdc, pixelFormat, NULL)) { - ErrorF("SetPixelFormat error: %s\n", glxWinErrorMessage()); - return FALSE; - } - } return TRUE; } @@ -1656,13 +1797,34 @@ fbConfigToPixelFormatIndex(HDC hdc, __GLXconfig * mode, int attribList[60]; SET_ATTR_VALUE(WGL_SUPPORT_OPENGL_ARB, TRUE); - SET_ATTR_VALUE(WGL_PIXEL_TYPE_ARB, - (mode->visualType == - GLX_TRUE_COLOR) ? WGL_TYPE_RGBA_ARB : - WGL_TYPE_COLORINDEX_ARB); - SET_ATTR_VALUE(WGL_COLOR_BITS_ARB, - (mode->visualType == - GLX_TRUE_COLOR) ? mode->rgbBits : mode->indexBits); + + switch (mode->renderType) + { + case GLX_COLOR_INDEX_BIT: + case GLX_RGBA_BIT | GLX_COLOR_INDEX_BIT: + SET_ATTR_VALUE(WGL_PIXEL_TYPE_ARB, WGL_TYPE_COLORINDEX_ARB); + SET_ATTR_VALUE(WGL_COLOR_BITS_ARB, mode->indexBits); + break; + + default: + ErrorF("unexpected renderType %x\n", mode->renderType); + /* fall-through */ + case GLX_RGBA_BIT: + SET_ATTR_VALUE(WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB); + SET_ATTR_VALUE(WGL_COLOR_BITS_ARB, mode->rgbBits); + break; + + case GLX_RGBA_FLOAT_BIT_ARB: + SET_ATTR_VALUE(WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_FLOAT_ARB); + SET_ATTR_VALUE(WGL_COLOR_BITS_ARB, mode->rgbBits); + break; + + case GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT: + SET_ATTR_VALUE(WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT); + SET_ATTR_VALUE(WGL_COLOR_BITS_ARB, mode->rgbBits); + break; + } + SET_ATTR_VALUE(WGL_RED_BITS_ARB, mode->redBits); SET_ATTR_VALUE(WGL_GREEN_BITS_ARB, mode->greenBits); SET_ATTR_VALUE(WGL_BLUE_BITS_ARB, mode->blueBits); @@ -1692,6 +1854,11 @@ fbConfigToPixelFormatIndex(HDC hdc, __GLXconfig * mode, if (mode->visualRating == GLX_SLOW_VISUAL_EXT) SET_ATTR_VALUE(WGL_ACCELERATION_ARB, WGL_NO_ACCELERATION_ARB); + if (winScreen->has_WGL_ARB_multisample) { + SET_ATTR_VALUE(WGL_SAMPLE_BUFFERS_ARB, mode->sampleBuffers); + SET_ATTR_VALUE(WGL_SAMPLES_ARB, mode->samples); + } + // must support all the drawable types the mode supports if ((mode->drawableType | drawableTypeOverride) & GLX_WINDOW_BIT) SET_ATTR_VALUE(WGL_DRAW_TO_WINDOW_ARB, TRUE); @@ -1715,6 +1882,9 @@ fbConfigToPixelFormatIndex(HDC hdc, __GLXconfig * mode, SET_ATTR_VALUE(WGL_DRAW_TO_PBUFFER_ARB, TRUE); } + if (winScreen->has_WGL_ARB_framebuffer_sRGB) + SET_ATTR_VALUE(WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB, TRUE); + SET_ATTR_VALUE(0, 0); // terminator /* choose the first match */ @@ -1851,6 +2021,8 @@ glxWinCreateConfigs(HDC hdc, glxWinScreen * screen) /* EXT_visual_rating / GLX 1.2 */ if (pfd.dwFlags & PFD_GENERIC_FORMAT) { c->base.visualRating = GLX_SLOW_VISUAL_EXT; + GLWIN_DEBUG_MSG("pixelFormat %d is un-accelerated, skipping", i + 1); + continue; } else { // PFD_GENERIC_ACCELERATED is not considered, so this may be MCD or ICD acclerated... @@ -1984,7 +2156,7 @@ getAttrValue(const int attrs[], int values[], unsigned int num, int attr, // Create the GLXconfigs using wglGetPixelFormatAttribfvARB() extension // static void -glxWinCreateConfigsExt(HDC hdc, glxWinScreen * screen) +glxWinCreateConfigsExt(HDC hdc, glxWinScreen * screen, PixelFormatRejectStats * rejects) { GLXWinConfig *c, *result, *prev = NULL; int i = 0; @@ -2077,6 +2249,11 @@ glxWinCreateConfigsExt(HDC hdc, glxWinScreen * screen) ADD_ATTR(WGL_MAX_PBUFFER_HEIGHT_ARB); } + if (screen->has_WGL_ARB_framebuffer_sRGB) { + // we may not query these attrs if WGL_ARB_framebuffer_sRGB is not offered + ADD_ATTR(WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB); + } + /* fill in configs */ for (i = 0; i < numConfigs; i++) { int values[num_attrs]; @@ -2096,6 +2273,7 @@ glxWinCreateConfigsExt(HDC hdc, glxWinScreen * screen) #define ATTR_VALUE(a, d) getAttrValue(attrs, values, num_attrs, (a), (d)) if (!ATTR_VALUE(WGL_SUPPORT_OPENGL_ARB, 0)) { + rejects->notOpenGL++; GLWIN_DEBUG_MSG ("pixelFormat %d isn't WGL_SUPPORT_OPENGL_ARB, skipping", i + 1); @@ -2129,26 +2307,46 @@ glxWinCreateConfigsExt(HDC hdc, glxWinScreen * screen) c->base.indexBits = ATTR_VALUE(WGL_COLOR_BITS_ARB, 0); c->base.rgbBits = 0; c->base.visualType = GLX_STATIC_COLOR; + c->base.renderType = GLX_RGBA_BIT | GLX_COLOR_INDEX_BIT; + + /* + Assume RGBA rendering is available on all single-channel visuals + (it is specified to render to red component in single-channel + visuals, if supported, but there doesn't seem to be any mechanism + to check if it is supported) + + Color index rendering is only supported on single-channel visuals + */ + + break; + + case WGL_TYPE_RGBA_ARB: + c->base.indexBits = 0; + c->base.rgbBits = ATTR_VALUE(WGL_COLOR_BITS_ARB, 0); + c->base.visualType = GLX_TRUE_COLOR; + c->base.renderType = GLX_RGBA_BIT; break; case WGL_TYPE_RGBA_FLOAT_ARB: - GLWIN_DEBUG_MSG - ("pixelFormat %d is WGL_TYPE_RGBA_FLOAT_ARB, skipping", i + 1); - continue; + c->base.indexBits = 0; + c->base.rgbBits = ATTR_VALUE(WGL_COLOR_BITS_ARB, 0); + c->base.visualType = GLX_TRUE_COLOR; + c->base.renderType = GLX_RGBA_FLOAT_BIT_ARB; + // assert pbuffer drawable + // assert WGL_ARB_pixel_format_float + break; case WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT: - GLWIN_DEBUG_MSG - ("pixelFormat %d is WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT, skipping", - i + 1); - continue; - - case WGL_TYPE_RGBA_ARB: c->base.indexBits = 0; c->base.rgbBits = ATTR_VALUE(WGL_COLOR_BITS_ARB, 0); c->base.visualType = GLX_TRUE_COLOR; + c->base.renderType = GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT; + // assert pbuffer drawable + // assert WGL_EXT_pixel_format_packed_float break; default: + rejects->unknownPixelType++; ErrorF ("wglGetPixelFormatAttribivARB returned unknown value 0x%x for WGL_PIXEL_TYPE_ARB\n", ATTR_VALUE(WGL_PIXEL_TYPE_ARB, 0)); @@ -2189,7 +2387,10 @@ glxWinCreateConfigsExt(HDC hdc, glxWinScreen * screen) ATTR_VALUE(WGL_ACCELERATION_ARB, 0)); case WGL_NO_ACCELERATION_ARB: + rejects->unaccelerated++; c->base.visualRating = GLX_SLOW_VISUAL_EXT; + GLWIN_DEBUG_MSG("pixelFormat %d is un-accelerated, skipping", i + 1); + continue; break; case WGL_GENERIC_ACCELERATION_ARB: @@ -2260,11 +2461,16 @@ glxWinCreateConfigsExt(HDC hdc, glxWinScreen * screen) /* SGIX_pbuffer / GLX 1.3 */ if (screen->has_WGL_ARB_pbuffer) { - c->base.maxPbufferWidth = ATTR_VALUE(WGL_MAX_PBUFFER_WIDTH_ARB, -1); - c->base.maxPbufferHeight = - ATTR_VALUE(WGL_MAX_PBUFFER_HEIGHT_ARB, -1); - c->base.maxPbufferPixels = - ATTR_VALUE(WGL_MAX_PBUFFER_PIXELS_ARB, -1); + // mesa libGL "can't handle the truth" about max pbuffer size. + // We must report 0, which exactly matches what it expects + // + // ATTR_VALUE(WGL_MAX_PBUFFER_WIDTH_ARB, -1); + // ATTR_VALUE(WGL_MAX_PBUFFER_PIXELS_ARB, -1); + // ATTR_VALUE(WGL_MAX_PBUFFER_HEIGHT_ARB, -1); + // + c->base.maxPbufferWidth = 0; + c->base.maxPbufferHeight = 0; + c->base.maxPbufferPixels = 0; } else { c->base.maxPbufferWidth = -1; @@ -2331,7 +2537,9 @@ glxWinCreateConfigsExt(HDC hdc, glxWinScreen * screen) GLX_TEXTURE_1D_BIT_EXT | GLX_TEXTURE_2D_BIT_EXT | GLX_TEXTURE_RECTANGLE_BIT_EXT; c->base.yInverted = -1; - c->base.sRGBCapable = 0; + + /* WGL_ARB_framebuffer_sRGB */ + c->base.sRGBCapable = ATTR_VALUE(WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB, 0); n++; |