wgl: Correctly check GLX capabilities. Use client GLX extensions on ATI hardware to work around driver bugs.
This commit is contained in:
parent
511bdd9de8
commit
ae98679ebe
|
@ -82,9 +82,11 @@ struct WineGLInfo {
|
||||||
int glxVersion[2];
|
int glxVersion[2];
|
||||||
|
|
||||||
const char *glxServerVersion;
|
const char *glxServerVersion;
|
||||||
|
const char *glxServerVendor;
|
||||||
const char *glxServerExtensions;
|
const char *glxServerExtensions;
|
||||||
|
|
||||||
const char *glxClientVersion;
|
const char *glxClientVersion;
|
||||||
|
const char *glxClientVendor;
|
||||||
const char *glxClientExtensions;
|
const char *glxClientExtensions;
|
||||||
|
|
||||||
const char *glxExtensions;
|
const char *glxExtensions;
|
||||||
|
@ -148,6 +150,8 @@ static WineGLPixelFormat *WineGLPixelFormatList;
|
||||||
static int WineGLPixelFormatListSize = 0;
|
static int WineGLPixelFormatListSize = 0;
|
||||||
|
|
||||||
static void X11DRV_WineGL_LoadExtensions(void);
|
static void X11DRV_WineGL_LoadExtensions(void);
|
||||||
|
static BOOL glxRequireVersion(int requiredVersion);
|
||||||
|
static BOOL glxRequireExtension(const char *requiredExtension);
|
||||||
|
|
||||||
static void dump_PIXELFORMATDESCRIPTOR(const PIXELFORMATDESCRIPTOR *ppfd) {
|
static void dump_PIXELFORMATDESCRIPTOR(const PIXELFORMATDESCRIPTOR *ppfd) {
|
||||||
TRACE(" - size / version : %d / %d\n", ppfd->nSize, ppfd->nVersion);
|
TRACE(" - size / version : %d / %d\n", ppfd->nSize, ppfd->nVersion);
|
||||||
|
@ -318,9 +322,11 @@ static BOOL X11DRV_WineGL_InitOpenglInfo(void)
|
||||||
pglXQueryVersion(gdi_display, &WineGLInfo.glxVersion[0], &WineGLInfo.glxVersion[1]);
|
pglXQueryVersion(gdi_display, &WineGLInfo.glxVersion[0], &WineGLInfo.glxVersion[1]);
|
||||||
|
|
||||||
WineGLInfo.glxServerVersion = pglXQueryServerString(gdi_display, screen, GLX_VERSION);
|
WineGLInfo.glxServerVersion = pglXQueryServerString(gdi_display, screen, GLX_VERSION);
|
||||||
|
WineGLInfo.glxServerVendor = pglXQueryServerString(gdi_display, screen, GLX_VENDOR);
|
||||||
WineGLInfo.glxServerExtensions = pglXQueryServerString(gdi_display, screen, GLX_EXTENSIONS);
|
WineGLInfo.glxServerExtensions = pglXQueryServerString(gdi_display, screen, GLX_EXTENSIONS);
|
||||||
|
|
||||||
WineGLInfo.glxClientVersion = pglXGetClientString(gdi_display, GLX_VERSION);
|
WineGLInfo.glxClientVersion = pglXGetClientString(gdi_display, GLX_VERSION);
|
||||||
|
WineGLInfo.glxClientVendor = pglXGetClientString(gdi_display, GLX_VENDOR);
|
||||||
WineGLInfo.glxClientExtensions = pglXGetClientString(gdi_display, GLX_EXTENSIONS);
|
WineGLInfo.glxClientExtensions = pglXGetClientString(gdi_display, GLX_EXTENSIONS);
|
||||||
|
|
||||||
WineGLInfo.glxExtensions = pglXQueryExtensionsString(gdi_display, screen);
|
WineGLInfo.glxExtensions = pglXQueryExtensionsString(gdi_display, screen);
|
||||||
|
@ -330,9 +336,9 @@ static BOOL X11DRV_WineGL_InitOpenglInfo(void)
|
||||||
TRACE("GL renderer : %s.\n", pglGetString(GL_RENDERER));
|
TRACE("GL renderer : %s.\n", pglGetString(GL_RENDERER));
|
||||||
TRACE("GLX version : %d.%d.\n", WineGLInfo.glxVersion[0], WineGLInfo.glxVersion[1]);
|
TRACE("GLX version : %d.%d.\n", WineGLInfo.glxVersion[0], WineGLInfo.glxVersion[1]);
|
||||||
TRACE("Server GLX version : %s.\n", WineGLInfo.glxServerVersion);
|
TRACE("Server GLX version : %s.\n", WineGLInfo.glxServerVersion);
|
||||||
TRACE("Server GLX vendor: : %s.\n", pglXQueryServerString(gdi_display, screen, GLX_VENDOR));
|
TRACE("Server GLX vendor: : %s.\n", WineGLInfo.glxServerVendor);
|
||||||
TRACE("Client GLX version : %s.\n", WineGLInfo.glxClientVersion);
|
TRACE("Client GLX version : %s.\n", WineGLInfo.glxClientVersion);
|
||||||
TRACE("Client GLX vendor: : %s.\n", pglXGetClientString(gdi_display, GLX_VENDOR));
|
TRACE("Client GLX vendor: : %s.\n", WineGLInfo.glxClientVendor);
|
||||||
TRACE("Direct rendering enabled: %s\n", WineGLInfo.glxDirect ? "True" : "False");
|
TRACE("Direct rendering enabled: %s\n", WineGLInfo.glxDirect ? "True" : "False");
|
||||||
|
|
||||||
if(vis) XFree(vis);
|
if(vis) XFree(vis);
|
||||||
|
@ -348,7 +354,6 @@ static BOOL has_opengl(void)
|
||||||
{
|
{
|
||||||
static int init_done;
|
static int init_done;
|
||||||
static void *opengl_handle;
|
static void *opengl_handle;
|
||||||
const char *glx_extensions;
|
|
||||||
|
|
||||||
int error_base, event_base;
|
int error_base, event_base;
|
||||||
|
|
||||||
|
@ -449,55 +454,54 @@ LOAD_FUNCPTR(glXFreeMemoryNV)
|
||||||
* depends on the reported GLX client / server version and on the client / server extension list.
|
* depends on the reported GLX client / server version and on the client / server extension list.
|
||||||
* Those don't have to be the same.
|
* Those don't have to be the same.
|
||||||
*
|
*
|
||||||
* In general the server GLX information should be used in case of indirect rendering. When direct
|
* In general the server GLX information lists the capabilities in case of indirect rendering.
|
||||||
* rendering is used, the OpenGL client library is responsible for which GLX calls are available.
|
* When direct rendering is used, the OpenGL client library is responsible for which GLX calls are
|
||||||
* Nvidia's OpenGL drivers are the best in terms of GLX features. At the moment of writing their
|
* available and in that case the client GLX informat can be used.
|
||||||
* 8762 drivers support 1.3 for the server and 1.4 for the client and they support lots of extensions.
|
* OpenGL programs should use the 'intersection' of both sets of information which is advertised
|
||||||
* Unfortunately it is much more complicated for Mesa/DRI-based drivers and ATI's drivers.
|
* in the GLX version/extension list. When a program does this it works for certain for both
|
||||||
* Both sets of drivers report a server version of 1.2 and the client version can be 1.3 or 1.4.
|
* direct and indirect rendering.
|
||||||
* Further, in case of at least ATI's drivers, one crucial extension needed for our pixel format code
|
|
||||||
* is only available in the list of server extensions and not in the client list.
|
|
||||||
*
|
*
|
||||||
* The versioning checks below try to take into account the comments from above.
|
* The problem we are having in this area is that ATI's Linux drivers are broken. For some reason
|
||||||
|
* they haven't added some very important GLX extensions like GLX_SGIX_fbconfig to their client
|
||||||
|
* extension list which causes this extension not to be listed. (Wine requires this extension).
|
||||||
|
* ATI advertises a GLX client version of 1.3 which implies that this fbconfig extension among
|
||||||
|
* pbuffers is around.
|
||||||
|
*
|
||||||
|
* In order to provide users of Ati's proprietary drivers with OpenGL support, we need to detect
|
||||||
|
* the ATI drivers and from then on use GLX client information for them.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Depending on the use of direct or indirect rendering we need either the list of extensions
|
if(glxRequireVersion(3)) {
|
||||||
* exported by the client or by the server.
|
|
||||||
*/
|
|
||||||
if(WineGLInfo.glxDirect)
|
|
||||||
glx_extensions = WineGLInfo.glxClientExtensions;
|
|
||||||
else
|
|
||||||
glx_extensions = WineGLInfo.glxServerExtensions;
|
|
||||||
|
|
||||||
/* Based on the default opengl context we decide whether direct or indirect rendering is used.
|
|
||||||
* In case of indirect rendering we check if the GLX version of the server is 1.2 and else
|
|
||||||
* the client version is checked.
|
|
||||||
*/
|
|
||||||
if ((!WineGLInfo.glxDirect && !strcmp("1.2", WineGLInfo.glxServerVersion)) ||
|
|
||||||
(WineGLInfo.glxDirect && !strcmp("1.2", WineGLInfo.glxClientVersion)))
|
|
||||||
{
|
|
||||||
if (NULL != strstr(glx_extensions, "GLX_SGIX_fbconfig")) {
|
|
||||||
pglXChooseFBConfig = (void*)pglXGetProcAddressARB((const GLubyte *) "glXChooseFBConfigSGIX");
|
|
||||||
pglXGetFBConfigAttrib = (void*)pglXGetProcAddressARB((const GLubyte *) "glXGetFBConfigAttribSGIX");
|
|
||||||
pglXGetVisualFromFBConfig = (void*)pglXGetProcAddressARB((const GLubyte *) "glXGetVisualFromFBConfigSGIX");
|
|
||||||
} else {
|
|
||||||
ERR(" glx_version is %s and GLX_SGIX_fbconfig extension is unsupported. Expect problems.\n", WineGLInfo.glxClientVersion);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
pglXChooseFBConfig = (void*)pglXGetProcAddressARB((const GLubyte *) "glXChooseFBConfig");
|
pglXChooseFBConfig = (void*)pglXGetProcAddressARB((const GLubyte *) "glXChooseFBConfig");
|
||||||
pglXGetFBConfigAttrib = (void*)pglXGetProcAddressARB((const GLubyte *) "glXGetFBConfigAttrib");
|
pglXGetFBConfigAttrib = (void*)pglXGetProcAddressARB((const GLubyte *) "glXGetFBConfigAttrib");
|
||||||
pglXGetVisualFromFBConfig = (void*)pglXGetProcAddressARB((const GLubyte *) "glXGetVisualFromFBConfig");
|
pglXGetVisualFromFBConfig = (void*)pglXGetProcAddressARB((const GLubyte *) "glXGetVisualFromFBConfig");
|
||||||
|
pglXQueryDrawable = (void*)pglXGetProcAddressARB((const GLubyte *) "glXQueryDrawable");
|
||||||
|
} else if(glxRequireExtension("GLX_SGIX_fbconfig")) {
|
||||||
|
pglXChooseFBConfig = (void*)pglXGetProcAddressARB((const GLubyte *) "glXChooseFBConfigSGIX");
|
||||||
|
pglXGetFBConfigAttrib = (void*)pglXGetProcAddressARB((const GLubyte *) "glXGetFBConfigAttribSGIX");
|
||||||
|
pglXGetVisualFromFBConfig = (void*)pglXGetProcAddressARB((const GLubyte *) "glXGetVisualFromFBConfigSGIX");
|
||||||
|
|
||||||
|
/* The mesa libGL client library seems to forward glXQueryDrawable to the Xserver, so only
|
||||||
|
* enable this function when the Xserver understand GLX 1.3 or newer
|
||||||
|
*/
|
||||||
|
pglXQueryDrawable = NULL;
|
||||||
|
} else if(strcmp("ATI", WineGLInfo.glxClientVendor) == 0) {
|
||||||
|
TRACE("Overriding ATI GLX capabilities!\n");
|
||||||
|
pglXChooseFBConfig = (void*)pglXGetProcAddressARB((const GLubyte *) "glXChooseFBConfig");
|
||||||
|
pglXGetFBConfigAttrib = (void*)pglXGetProcAddressARB((const GLubyte *) "glXGetFBConfigAttrib");
|
||||||
|
pglXGetVisualFromFBConfig = (void*)pglXGetProcAddressARB((const GLubyte *) "glXGetVisualFromFBConfig");
|
||||||
|
pglXQueryDrawable = (void*)pglXGetProcAddressARB((const GLubyte *) "glXQueryDrawable");
|
||||||
|
|
||||||
|
/* Use client GLX information in case of the ATI drivers. We override the
|
||||||
|
* capabilities over here and not somewhere else as ATI might better their
|
||||||
|
* life in the future. In case they release proper drivers this block of
|
||||||
|
* code won't be called. */
|
||||||
|
WineGLInfo.glxExtensions = WineGLInfo.glxClientExtensions;
|
||||||
|
} else {
|
||||||
|
ERR(" glx_version is %s and GLX_SGIX_fbconfig extension is unsupported. Expect problems.\n", WineGLInfo.glxServerVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The mesa libGL client library seems to forward glXQueryDrawable to the Xserver, so only
|
if(glxRequireExtension("GLX_ATI_render_texture")) {
|
||||||
* enable this function when the Xserver understand GLX 1.3 or newer
|
|
||||||
*/
|
|
||||||
if (!strcmp("1.2", WineGLInfo.glxServerVersion))
|
|
||||||
pglXQueryDrawable = NULL;
|
|
||||||
else
|
|
||||||
pglXQueryDrawable = wine_dlsym(RTLD_DEFAULT, "glXQueryDrawable", NULL, 0);
|
|
||||||
|
|
||||||
if (NULL != strstr(glx_extensions, "GLX_ATI_render_texture")) {
|
|
||||||
pglXBindTexImageARB = (void*)pglXGetProcAddressARB((const GLubyte *) "glXBindTexImageARB");
|
pglXBindTexImageARB = (void*)pglXGetProcAddressARB((const GLubyte *) "glXBindTexImageARB");
|
||||||
pglXReleaseTexImageARB = (void*)pglXGetProcAddressARB((const GLubyte *) "glXReleaseTexImageARB");
|
pglXReleaseTexImageARB = (void*)pglXGetProcAddressARB((const GLubyte *) "glXReleaseTexImageARB");
|
||||||
pglXDrawableAttribARB = (void*)pglXGetProcAddressARB((const GLubyte *) "glXDrawableAttribARB");
|
pglXDrawableAttribARB = (void*)pglXGetProcAddressARB((const GLubyte *) "glXDrawableAttribARB");
|
||||||
|
@ -2915,7 +2919,7 @@ static BOOL glxRequireVersion(int requiredVersion)
|
||||||
|
|
||||||
static BOOL glxRequireExtension(const char *requiredExtension)
|
static BOOL glxRequireExtension(const char *requiredExtension)
|
||||||
{
|
{
|
||||||
if (strstr(WineGLInfo.glxClientExtensions, requiredExtension) == NULL) {
|
if (strstr(WineGLInfo.glxExtensions, requiredExtension) == NULL) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue