/**
* @file
- * Stub for hardware pipe driver support.
+ * Get a hardware accelerated Gallium screen/context from the OpenGL driver.
*/
#include "pipe/p_compiler.h"
+#ifdef PIPE_OS_WINDOWS
+#include <windows.h>
+#include <GL/gl.h>
+#else
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <GL/gl.h>
+#include <GL/glx.h>
+#endif
+
#include "st_winsys.h"
+typedef struct pipe_screen * (GLAPIENTRY *PFNGETGALLIUMSCREENMESAPROC) (void);
+typedef struct pipe_context * (GLAPIENTRY* PFNCREATEGALLIUMCONTEXTMESAPROC) (void);
+
+static PFNGETGALLIUMSCREENMESAPROC pfnGetGalliumScreenMESA = NULL;
+static PFNCREATEGALLIUMCONTEXTMESAPROC pfnCreateGalliumContextMESA = NULL;
+
+
/* XXX: Force init_gallium symbol to be linked */
extern void init_gallium(void);
void (*force_init_gallium_linkage)(void) = &init_gallium;
+#ifdef PIPE_OS_WINDOWS
+
+static INLINE boolean
+st_hardpipe_load(void)
+{
+ WNDCLASS wc;
+ HWND hwnd;
+ HGLRC hglrc;
+ HDC hdc;
+ PIXELFORMATDESCRIPTOR pfd;
+ int iPixelFormat;
+
+ if(pfnGetGalliumScreenMESA && pfnCreateGalliumContextMESA)
+ return TRUE;
+
+ memset(&wc, 0, sizeof wc);
+ wc.lpfnWndProc = DefWindowProc;
+ wc.lpszClassName = "gallium";
+ wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
+ RegisterClass(&wc);
+
+ hwnd = CreateWindow(wc.lpszClassName, "gallium", 0, 0, 0, 0, 0, NULL, 0, wc.hInstance, NULL);
+ if (!hwnd)
+ return FALSE;
+
+ hdc = GetDC(hwnd);
+ if (!hdc)
+ return FALSE;
+
+ pfd.cColorBits = 3;
+ pfd.cRedBits = 1;
+ pfd.cGreenBits = 1;
+ pfd.cBlueBits = 1;
+ pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
+ pfd.iLayerType = PFD_MAIN_PLANE;
+ pfd.iPixelType = PFD_TYPE_RGBA;
+ pfd.nSize = sizeof(pfd);
+ pfd.nVersion = 1;
+
+ iPixelFormat = ChoosePixelFormat(hdc, &pfd);
+ if (!iPixelFormat) {
+ pfd.dwFlags |= PFD_DOUBLEBUFFER;
+ iPixelFormat = ChoosePixelFormat(hdc, &pfd);
+ }
+ if (!iPixelFormat)
+ return FALSE;
+
+ SetPixelFormat(hdc, iPixelFormat, &pfd);
+ hglrc = wglCreateContext(hdc);
+ if (!hglrc)
+ return FALSE;
+
+ if (!wglMakeCurrent(hdc, hglrc))
+ return FALSE;
+
+ pfnGetGalliumScreenMESA = (PFNGETGALLIUMSCREENMESAPROC)wglGetProcAddress("wglGetGalliumScreenMESA");
+ if(!pfnGetGalliumScreenMESA)
+ return FALSE;
+
+ pfnCreateGalliumContextMESA = (PFNCREATEGALLIUMCONTEXTMESAPROC)wglGetProcAddress("wglCreateGalliumContextMESA");
+ if(!pfnCreateGalliumContextMESA)
+ return FALSE;
+
+ DestroyWindow(hwnd);
+
+ return TRUE;
+}
+
+#else
+
+static INLINE boolean
+st_hardpipe_load(void)
+{
+ Display *dpy;
+ int scrnum;
+ Window root;
+ int attribSingle[] = {
+ GLX_RGBA,
+ GLX_RED_SIZE, 1,
+ GLX_GREEN_SIZE, 1,
+ GLX_BLUE_SIZE, 1,
+ None };
+ int attribDouble[] = {
+ GLX_RGBA,
+ GLX_RED_SIZE, 1,
+ GLX_GREEN_SIZE, 1,
+ GLX_BLUE_SIZE, 1,
+ GLX_DOUBLEBUFFER,
+ None };
+ XVisualInfo *visinfo;
+ GLXContext ctx = NULL;
+ XSetWindowAttributes attr;
+ unsigned long mask;
+ int width = 100, height = 100;
+ Window win;
+
+ dpy = XOpenDisplay(NULL);
+ if (!dpy)
+ return FALSE;
+
+ scrnum = 0;
+
+ root = RootWindow(dpy, scrnum);
+
+ visinfo = glXChooseVisual(dpy, scrnum, attribSingle);
+ if (!visinfo)
+ visinfo = glXChooseVisual(dpy, scrnum, attribDouble);
+ if (!visinfo)
+ return FALSE;
+
+ ctx = glXCreateContext( dpy, visinfo, NULL, True );
+
+ if (!ctx)
+ return FALSE;
+
+ attr.background_pixel = 0;
+ attr.border_pixel = 0;
+ attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone);
+ attr.event_mask = StructureNotifyMask | ExposureMask;
+
+ mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
+
+ win = XCreateWindow(dpy, root, 0, 0, width, height,
+ 0, visinfo->depth, InputOutput,
+ visinfo->visual, mask, &attr);
+
+ if (!glXMakeCurrent(dpy, win, ctx))
+ return FALSE;
+
+ pfnGetGalliumScreenMESA = (PFNGETGALLIUMSCREENMESAPROC)glXGetProcAddressARB((const GLubyte *)"glXGetGalliumScreenMESA");
+ if(!pfnGetGalliumScreenMESA)
+ return FALSE;
+
+ pfnCreateGalliumContextMESA = (PFNCREATEGALLIUMCONTEXTMESAPROC)glXGetProcAddressARB((const GLubyte *)"glXCreateGalliumContextMESA");
+ if(!pfnCreateGalliumContextMESA)
+ return FALSE;
+
+ glXDestroyContext(dpy, ctx);
+ XFree(visinfo);
+ XDestroyWindow(dpy, win);
+ XCloseDisplay(dpy);
+
+ return TRUE;
+}
+
+#endif
+
+
static struct pipe_screen *
st_hardpipe_screen_create(void)
{
- return st_softpipe_winsys.screen_create();
+ if(st_hardpipe_load())
+ return pfnGetGalliumScreenMESA();
+ else
+ return st_softpipe_winsys.screen_create();
}
static struct pipe_context *
st_hardpipe_context_create(struct pipe_screen *screen)
{
- return st_softpipe_winsys.context_create(screen);
+ if(st_hardpipe_load()) {
+ if(screen == pfnGetGalliumScreenMESA())
+ return pfnCreateGalliumContextMESA();
+ else
+ return NULL;
+ }
+ else
+ return st_softpipe_winsys.context_create(screen);
}