summaryrefslogtreecommitdiff
path: root/hw/xwin/glx/indirect.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/xwin/glx/indirect.c')
-rw-r--r--hw/xwin/glx/indirect.c380
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++;