Skip to content
Snippets Groups Projects
Commit 3ab3209a authored by Jose Fonseca's avatar Jose Fonseca
Browse files

python: Obtain pipe_screen/pipe_context from the system's OpenGL driver.

parent 6b7b13b5
No related branches found
No related tags found
No related merge requests found
......@@ -15,6 +15,19 @@ if 'python' in env['statetrackers']:
env.Append(CPPPATH = '.')
if env['platform'] == 'windows':
env.Append(LIBS = [
'opengl32',
'gdi32',
'user32',
'kernel32',
])
else:
env.Append(LIBS = [
'GL',
'X11',
])
pyst = env.ConvenienceLibrary(
target = 'pyst',
source = [
......
......@@ -28,31 +28,206 @@
/**
* @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);
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment