2010-02-26 20:47:00 +00:00
|
|
|
/********************************************************************
|
|
|
|
KWin - the KDE window manager
|
|
|
|
This file is part of the KDE project.
|
|
|
|
|
|
|
|
Copyright (C) 2010 Fredrik Höglund <fredrik@kde.org>
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*********************************************************************/
|
|
|
|
|
|
|
|
#include <X11/Xlib.h>
|
|
|
|
#include <GL/glx.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdio.h>
|
2012-08-22 06:05:45 +00:00
|
|
|
#include <stdlib.h>
|
2010-02-26 20:47:00 +00:00
|
|
|
|
2012-08-22 06:05:45 +00:00
|
|
|
// Command to get Catalyst release version string
|
|
|
|
// The output is similar as "String: 9.00-120629n-045581E-ATI"
|
|
|
|
#define SHELL_COMMAND "aticonfig --get-pcs-key=LDC,ReleaseVersion"
|
|
|
|
|
|
|
|
static bool getCatalystVersion(int *first, int *second)
|
|
|
|
{
|
|
|
|
FILE *fp = NULL;
|
|
|
|
|
|
|
|
fp = popen(SHELL_COMMAND, "r");
|
|
|
|
|
|
|
|
if (!fp)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
fscanf(fp, "String: %d.%d", first, second);
|
|
|
|
|
|
|
|
if (pclose(fp) != 0)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2010-02-26 20:47:00 +00:00
|
|
|
|
|
|
|
// Return 0 if we can use a direct context, 1 otherwise
|
|
|
|
int main(int argc, char *argv[])
|
|
|
|
{
|
|
|
|
Display *dpy = XOpenDisplay(0);
|
|
|
|
|
|
|
|
int error_base, event_base;
|
|
|
|
if (!glXQueryExtension(dpy, &error_base, &event_base))
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
int major, minor;
|
|
|
|
if (!glXQueryVersion(dpy, &major, &minor))
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
int attribs[] = {
|
|
|
|
GLX_RGBA,
|
|
|
|
GLX_RED_SIZE, 1,
|
|
|
|
GLX_GREEN_SIZE, 1,
|
|
|
|
GLX_BLUE_SIZE, 1,
|
|
|
|
None,
|
|
|
|
None
|
|
|
|
};
|
|
|
|
|
|
|
|
// Try to find an RGBA visual
|
|
|
|
XVisualInfo *xvi = glXChooseVisual(dpy, DefaultScreen(dpy), attribs);
|
|
|
|
if (!xvi) {
|
|
|
|
// Try again for a doubled buffered visual
|
|
|
|
attribs[sizeof(attribs) / sizeof(int) - 2] = GLX_DOUBLEBUFFER;
|
|
|
|
xvi = glXChooseVisual(dpy, DefaultScreen(dpy), attribs);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!xvi)
|
|
|
|
return 1;
|
|
|
|
|
2010-06-13 23:05:37 +00:00
|
|
|
// Create a direct rendering context
|
2010-02-26 20:47:00 +00:00
|
|
|
GLXContext ctx = glXCreateContext(dpy, xvi, NULL, True);
|
2010-06-13 23:05:37 +00:00
|
|
|
if (!glXIsDirect(dpy, ctx))
|
|
|
|
return 1;
|
2010-02-26 20:47:00 +00:00
|
|
|
|
|
|
|
// Create a window using the visual.
|
|
|
|
// We only need it to make the context current
|
|
|
|
XSetWindowAttributes attr;
|
|
|
|
attr.background_pixel = 0;
|
|
|
|
attr.border_pixel = 0;
|
|
|
|
attr.colormap = XCreateColormap(dpy, DefaultRootWindow(dpy), xvi->visual, AllocNone);
|
|
|
|
Window win = XCreateWindow(dpy, DefaultRootWindow(dpy), 0, 0, 1, 1, 0,
|
|
|
|
xvi->depth, InputOutput, xvi->visual,
|
|
|
|
CWBackPixel | CWBorderPixel | CWColormap, &attr);
|
|
|
|
|
2010-06-13 23:05:37 +00:00
|
|
|
// Try to make the context current
|
|
|
|
if (!glXMakeCurrent(dpy, win, ctx))
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
// glXCreatePixmap() is a GLX 1.3+ function, but it's also provided by EXT_texture_from_pixmap
|
|
|
|
const char *glxExtensions = glXQueryExtensionsString(dpy, DefaultScreen(dpy));
|
|
|
|
if ((major == 1 && minor < 3) && !strstr(glxExtensions, "GLX_EXT_texture_from_pixmap"))
|
|
|
|
return 1;
|
|
|
|
|
2011-05-01 09:49:26 +00:00
|
|
|
// Assume that all Mesa drivers support direct rendering
|
|
|
|
const GLubyte *version = glGetString(GL_VERSION);
|
|
|
|
if (strstr((const char *)version, "Mesa"))
|
2010-05-28 20:41:58 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
// Direct contexts also work with the NVidia driver
|
2010-02-26 20:47:00 +00:00
|
|
|
const GLubyte *vendor = glGetString(GL_VENDOR);
|
|
|
|
if (strstr((const char *)vendor, "NVIDIA"))
|
|
|
|
return 0;
|
|
|
|
|
2012-08-22 06:05:45 +00:00
|
|
|
// Enable direct rendering for AMD Catalyst driver 8.973/8.98 and later. There are
|
|
|
|
// three kinds of Catalyst releases, major, minor and point releses. For example,
|
|
|
|
// 8.98 is one major release, 8.981 is one minor release based on 8.98, and 8.981.1
|
|
|
|
// is one point release based on 8.981, 8.98.1 is one point release based on 8.98
|
|
|
|
if (strstr((const char *)vendor, "ATI") || strstr((const char *)vendor, "AMD")) {
|
|
|
|
int first = 0, second = 0;
|
|
|
|
if (getCatalystVersion(&first, &second))
|
|
|
|
if ((first > 8) || // 9.xx and future releases
|
|
|
|
((first == 8) && (second >= 98) && (second < 100)) || // 8.xx and 8.xx.z
|
|
|
|
((first == 8) && (second >= 973))) //8.xxy and 8.xxy.z
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-10-13 08:33:38 +00:00
|
|
|
// Direct context also works with VirtualBox's driver
|
|
|
|
const GLubyte *renderer = glGetString(GL_RENDERER);
|
|
|
|
if (strstr((const char *)vendor, "Humper") && strstr((const char *)renderer, "Chromium"))
|
|
|
|
return 0;
|
|
|
|
|
2010-02-26 20:47:00 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|