mirror of
https://github.com/glfw/glfw.git
synced 2024-11-22 13:04:35 +00:00
Added workaround for broken Mesa GLX_ARB_create_context_profile.
This commit is contained in:
parent
ea1ddfd7a4
commit
9e9457767f
@ -38,6 +38,11 @@
|
|||||||
void (*glXGetProcAddressEXT(const GLubyte* procName))();
|
void (*glXGetProcAddressEXT(const GLubyte* procName))();
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef GLXBadProfileARB
|
||||||
|
#define GLXBadProfileARB 13
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
//========================================================================
|
//========================================================================
|
||||||
// Thread local storage attribute macro
|
// Thread local storage attribute macro
|
||||||
//========================================================================
|
//========================================================================
|
||||||
@ -48,6 +53,12 @@ void (*glXGetProcAddressEXT(const GLubyte* procName))();
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
//========================================================================
|
||||||
|
// The X error code as provided to the X error handler
|
||||||
|
//========================================================================
|
||||||
|
static unsigned long _glfwErrorCode = Success;
|
||||||
|
|
||||||
|
|
||||||
//========================================================================
|
//========================================================================
|
||||||
// The per-thread current context/window pointer
|
// The per-thread current context/window pointer
|
||||||
//========================================================================
|
//========================================================================
|
||||||
@ -207,18 +218,48 @@ static _GLFWfbconfig* getFBConfigs(_GLFWwindow* window, unsigned int* found)
|
|||||||
|
|
||||||
|
|
||||||
//========================================================================
|
//========================================================================
|
||||||
// Error handler for BadMatch errors when requesting context with
|
// Error handler used when creating a context with the GLX_ARB_create_context
|
||||||
// unavailable OpenGL versions using the GLX_ARB_create_context extension
|
// extension set
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
static int errorHandler(Display *display, XErrorEvent* event)
|
static int errorHandler(Display *display, XErrorEvent* event)
|
||||||
{
|
{
|
||||||
|
_glfwErrorCode = event->error_code;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//========================================================================
|
//========================================================================
|
||||||
// Create the actual OpenGL context
|
// Create the OpenGL context using legacy API
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
static void createLegacyContext(_GLFWwindow* window,
|
||||||
|
const _GLFWwndconfig* wndconfig,
|
||||||
|
GLXFBConfig fbconfig,
|
||||||
|
GLXContext share)
|
||||||
|
{
|
||||||
|
if (_glfwLibrary.GLX.SGIX_fbconfig)
|
||||||
|
{
|
||||||
|
window->GLX.context =
|
||||||
|
_glfwLibrary.GLX.CreateContextWithConfigSGIX(_glfwLibrary.X11.display,
|
||||||
|
fbconfig,
|
||||||
|
GLX_RGBA_TYPE,
|
||||||
|
share,
|
||||||
|
True);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
window->GLX.context = glXCreateNewContext(_glfwLibrary.X11.display,
|
||||||
|
fbconfig,
|
||||||
|
GLX_RGBA_TYPE,
|
||||||
|
share,
|
||||||
|
True);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//========================================================================
|
||||||
|
// Create the OpenGL context
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
#define setGLXattrib(attribName, attribValue) \
|
#define setGLXattrib(attribName, attribValue) \
|
||||||
@ -386,6 +427,7 @@ static int createContext(_GLFWwindow* window,
|
|||||||
// it because glXCreateContextAttribsARB generates a BadMatch error if
|
// it because glXCreateContextAttribsARB generates a BadMatch error if
|
||||||
// the requested OpenGL version is unavailable (instead of a civilized
|
// the requested OpenGL version is unavailable (instead of a civilized
|
||||||
// response like returning NULL)
|
// response like returning NULL)
|
||||||
|
_glfwErrorCode = Success;
|
||||||
XSetErrorHandler(errorHandler);
|
XSetErrorHandler(errorHandler);
|
||||||
|
|
||||||
window->GLX.context =
|
window->GLX.context =
|
||||||
@ -397,36 +439,29 @@ static int createContext(_GLFWwindow* window,
|
|||||||
|
|
||||||
// We are done, so unset the error handler again (see above)
|
// We are done, so unset the error handler again (see above)
|
||||||
XSetErrorHandler(NULL);
|
XSetErrorHandler(NULL);
|
||||||
|
|
||||||
|
if (window->GLX.context == NULL)
|
||||||
|
{
|
||||||
|
// HACK: This is a fallback for the broken Mesa implementation of
|
||||||
|
// GLX_ARB_create_context_profile, which fails default 1.0 context
|
||||||
|
// creation with a GLXBadProfileARB error in violation of the spec
|
||||||
|
if (_glfwErrorCode == _glfwLibrary.GLX.errorBase + GLXBadProfileARB &&
|
||||||
|
wndconfig->clientAPI == GLFW_OPENGL_API &&
|
||||||
|
wndconfig->glProfile == GLFW_OPENGL_NO_PROFILE &&
|
||||||
|
wndconfig->glForward == GL_FALSE)
|
||||||
|
{
|
||||||
|
createLegacyContext(window, wndconfig, *fbconfig, share);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
createLegacyContext(window, wndconfig, *fbconfig, share);
|
||||||
if (_glfwLibrary.GLX.SGIX_fbconfig)
|
|
||||||
{
|
|
||||||
window->GLX.context =
|
|
||||||
_glfwLibrary.GLX.CreateContextWithConfigSGIX(_glfwLibrary.X11.display,
|
|
||||||
*fbconfig,
|
|
||||||
GLX_RGBA_TYPE,
|
|
||||||
share,
|
|
||||||
True);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
window->GLX.context = glXCreateNewContext(_glfwLibrary.X11.display,
|
|
||||||
*fbconfig,
|
|
||||||
GLX_RGBA_TYPE,
|
|
||||||
share,
|
|
||||||
True);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
XFree(fbconfig);
|
XFree(fbconfig);
|
||||||
|
|
||||||
if (window->GLX.context == NULL)
|
if (window->GLX.context == NULL)
|
||||||
{
|
{
|
||||||
// TODO: Handle all the various error codes here
|
_glfwSetError(GLFW_PLATFORM_ERROR, "GLX: Failed to create context");
|
||||||
|
|
||||||
_glfwSetError(GLFW_PLATFORM_ERROR,
|
|
||||||
"GLX: Failed to create context");
|
|
||||||
return GL_FALSE;
|
return GL_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -472,7 +507,9 @@ int _glfwInitOpenGL(void)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Check if GLX is supported on this display
|
// Check if GLX is supported on this display
|
||||||
if (!glXQueryExtension(_glfwLibrary.X11.display, NULL, NULL))
|
if (!glXQueryExtension(_glfwLibrary.X11.display,
|
||||||
|
&_glfwLibrary.GLX.errorBase,
|
||||||
|
&_glfwLibrary.GLX.eventBase))
|
||||||
{
|
{
|
||||||
_glfwSetError(GLFW_API_UNAVAILABLE, "GLX: GLX support not found");
|
_glfwSetError(GLFW_API_UNAVAILABLE, "GLX: GLX support not found");
|
||||||
return GL_FALSE;
|
return GL_FALSE;
|
||||||
|
@ -90,6 +90,8 @@ typedef struct _GLFWlibraryGLX
|
|||||||
{
|
{
|
||||||
// Server-side GLX version
|
// Server-side GLX version
|
||||||
int majorVersion, minorVersion;
|
int majorVersion, minorVersion;
|
||||||
|
int eventBase;
|
||||||
|
int errorBase;
|
||||||
|
|
||||||
// GLX extensions
|
// GLX extensions
|
||||||
PFNGLXSWAPINTERVALSGIPROC SwapIntervalSGI;
|
PFNGLXSWAPINTERVALSGIPROC SwapIntervalSGI;
|
||||||
|
Loading…
Reference in New Issue
Block a user