Merge branch 'mesa_7_7_branch'
[mesa.git] / src / gallium / state_trackers / python / st_hardpipe_winsys.c
1 /**************************************************************************
2 *
3 * Copyright 2008 Tungsten Graphics, Inc., Bismarck, ND., USA
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
18 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 * USE OR OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * The above copyright notice and this permission notice (including the
23 * next paragraph) shall be included in all copies or substantial portions
24 * of the Software.
25 *
26 *
27 **************************************************************************/
28
29 /**
30 * @file
31 * Get a hardware accelerated Gallium screen/context from the OpenGL driver.
32 */
33
34
35 #include "pipe/p_compiler.h"
36
37 #ifdef PIPE_OS_WINDOWS
38 #include <windows.h>
39 #include <GL/gl.h>
40 #else
41 #include <X11/Xlib.h>
42 #include <X11/Xutil.h>
43 #include <GL/gl.h>
44 #include <GL/glx.h>
45 #endif
46
47 #include "st_winsys.h"
48
49
50 typedef struct pipe_screen * (GLAPIENTRY *PFNGETGALLIUMSCREENMESAPROC) (void);
51 typedef struct pipe_context * (GLAPIENTRY* PFNCREATEGALLIUMCONTEXTMESAPROC) (void);
52
53 static PFNGETGALLIUMSCREENMESAPROC pfnGetGalliumScreenMESA = NULL;
54 static PFNCREATEGALLIUMCONTEXTMESAPROC pfnCreateGalliumContextMESA = NULL;
55
56
57 /* XXX: Force init_gallium symbol to be linked */
58 extern void init_gallium(void);
59 void (*force_init_gallium_linkage)(void) = &init_gallium;
60
61
62 #ifdef PIPE_OS_WINDOWS
63
64 static INLINE boolean
65 st_hardpipe_load(void)
66 {
67 WNDCLASS wc;
68 HWND hwnd;
69 HGLRC hglrc;
70 HDC hdc;
71 PIXELFORMATDESCRIPTOR pfd;
72 int iPixelFormat;
73
74 if(pfnGetGalliumScreenMESA && pfnCreateGalliumContextMESA)
75 return TRUE;
76
77 memset(&wc, 0, sizeof wc);
78 wc.lpfnWndProc = DefWindowProc;
79 wc.lpszClassName = "gallium";
80 wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
81 RegisterClass(&wc);
82
83 hwnd = CreateWindow(wc.lpszClassName, "gallium", 0, 0, 0, 0, 0, NULL, 0, wc.hInstance, NULL);
84 if (!hwnd)
85 return FALSE;
86
87 hdc = GetDC(hwnd);
88 if (!hdc)
89 return FALSE;
90
91 pfd.cColorBits = 3;
92 pfd.cRedBits = 1;
93 pfd.cGreenBits = 1;
94 pfd.cBlueBits = 1;
95 pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
96 pfd.iLayerType = PFD_MAIN_PLANE;
97 pfd.iPixelType = PFD_TYPE_RGBA;
98 pfd.nSize = sizeof(pfd);
99 pfd.nVersion = 1;
100
101 iPixelFormat = ChoosePixelFormat(hdc, &pfd);
102 if (!iPixelFormat) {
103 pfd.dwFlags |= PFD_DOUBLEBUFFER;
104 iPixelFormat = ChoosePixelFormat(hdc, &pfd);
105 }
106 if (!iPixelFormat)
107 return FALSE;
108
109 SetPixelFormat(hdc, iPixelFormat, &pfd);
110 hglrc = wglCreateContext(hdc);
111 if (!hglrc)
112 return FALSE;
113
114 if (!wglMakeCurrent(hdc, hglrc))
115 return FALSE;
116
117 pfnGetGalliumScreenMESA = (PFNGETGALLIUMSCREENMESAPROC)wglGetProcAddress("wglGetGalliumScreenMESA");
118 if(!pfnGetGalliumScreenMESA)
119 return FALSE;
120
121 pfnCreateGalliumContextMESA = (PFNCREATEGALLIUMCONTEXTMESAPROC)wglGetProcAddress("wglCreateGalliumContextMESA");
122 if(!pfnCreateGalliumContextMESA)
123 return FALSE;
124
125 DestroyWindow(hwnd);
126
127 return TRUE;
128 }
129
130 #else
131
132 static INLINE boolean
133 st_hardpipe_load(void)
134 {
135 Display *dpy;
136 int scrnum;
137 Window root;
138 int attribSingle[] = {
139 GLX_RGBA,
140 GLX_RED_SIZE, 1,
141 GLX_GREEN_SIZE, 1,
142 GLX_BLUE_SIZE, 1,
143 None };
144 int attribDouble[] = {
145 GLX_RGBA,
146 GLX_RED_SIZE, 1,
147 GLX_GREEN_SIZE, 1,
148 GLX_BLUE_SIZE, 1,
149 GLX_DOUBLEBUFFER,
150 None };
151 XVisualInfo *visinfo;
152 GLXContext ctx = NULL;
153 XSetWindowAttributes attr;
154 unsigned long mask;
155 int width = 100, height = 100;
156 Window win;
157
158 dpy = XOpenDisplay(NULL);
159 if (!dpy)
160 return FALSE;
161
162 scrnum = 0;
163
164 root = RootWindow(dpy, scrnum);
165
166 visinfo = glXChooseVisual(dpy, scrnum, attribSingle);
167 if (!visinfo)
168 visinfo = glXChooseVisual(dpy, scrnum, attribDouble);
169 if (!visinfo)
170 return FALSE;
171
172 ctx = glXCreateContext( dpy, visinfo, NULL, True );
173
174 if (!ctx)
175 return FALSE;
176
177 attr.background_pixel = 0;
178 attr.border_pixel = 0;
179 attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone);
180 attr.event_mask = StructureNotifyMask | ExposureMask;
181
182 mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
183
184 win = XCreateWindow(dpy, root, 0, 0, width, height,
185 0, visinfo->depth, InputOutput,
186 visinfo->visual, mask, &attr);
187
188 if (!glXMakeCurrent(dpy, win, ctx))
189 return FALSE;
190
191 pfnGetGalliumScreenMESA = (PFNGETGALLIUMSCREENMESAPROC)glXGetProcAddressARB((const GLubyte *)"glXGetGalliumScreenMESA");
192 if(!pfnGetGalliumScreenMESA)
193 return FALSE;
194
195 pfnCreateGalliumContextMESA = (PFNCREATEGALLIUMCONTEXTMESAPROC)glXGetProcAddressARB((const GLubyte *)"glXCreateGalliumContextMESA");
196 if(!pfnCreateGalliumContextMESA)
197 return FALSE;
198
199 glXDestroyContext(dpy, ctx);
200 XFree(visinfo);
201 XDestroyWindow(dpy, win);
202 XCloseDisplay(dpy);
203
204 return TRUE;
205 }
206
207 #endif
208
209
210 static struct pipe_screen *
211 st_hardpipe_screen_create(void)
212 {
213 if(st_hardpipe_load())
214 return pfnGetGalliumScreenMESA();
215 else
216 return st_softpipe_winsys.screen_create();
217 }
218
219
220 static struct pipe_context *
221 st_hardpipe_context_create(struct pipe_screen *screen)
222 {
223 if(st_hardpipe_load()) {
224 if(screen == pfnGetGalliumScreenMESA())
225 return pfnCreateGalliumContextMESA();
226 else
227 return NULL;
228 }
229 else
230 return st_softpipe_winsys.context_create(screen);
231 }
232
233
234 const struct st_winsys st_hardpipe_winsys = {
235 &st_hardpipe_screen_create,
236 &st_hardpipe_context_create
237 };