Merge branch '7.8'
[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 #ifdef PIPE_OS_WINDOWS
58
59 static INLINE boolean
60 st_hardpipe_load(void)
61 {
62 WNDCLASS wc;
63 HWND hwnd;
64 HGLRC hglrc;
65 HDC hdc;
66 PIXELFORMATDESCRIPTOR pfd;
67 int iPixelFormat;
68
69 if(pfnGetGalliumScreenMESA && pfnCreateGalliumContextMESA)
70 return TRUE;
71
72 memset(&wc, 0, sizeof wc);
73 wc.lpfnWndProc = DefWindowProc;
74 wc.lpszClassName = "gallium";
75 wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
76 RegisterClass(&wc);
77
78 hwnd = CreateWindow(wc.lpszClassName, "gallium", 0, 0, 0, 0, 0, NULL, 0, wc.hInstance, NULL);
79 if (!hwnd)
80 return FALSE;
81
82 hdc = GetDC(hwnd);
83 if (!hdc)
84 return FALSE;
85
86 pfd.cColorBits = 3;
87 pfd.cRedBits = 1;
88 pfd.cGreenBits = 1;
89 pfd.cBlueBits = 1;
90 pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
91 pfd.iLayerType = PFD_MAIN_PLANE;
92 pfd.iPixelType = PFD_TYPE_RGBA;
93 pfd.nSize = sizeof(pfd);
94 pfd.nVersion = 1;
95
96 iPixelFormat = ChoosePixelFormat(hdc, &pfd);
97 if (!iPixelFormat) {
98 pfd.dwFlags |= PFD_DOUBLEBUFFER;
99 iPixelFormat = ChoosePixelFormat(hdc, &pfd);
100 }
101 if (!iPixelFormat)
102 return FALSE;
103
104 SetPixelFormat(hdc, iPixelFormat, &pfd);
105 hglrc = wglCreateContext(hdc);
106 if (!hglrc)
107 return FALSE;
108
109 if (!wglMakeCurrent(hdc, hglrc))
110 return FALSE;
111
112 pfnGetGalliumScreenMESA = (PFNGETGALLIUMSCREENMESAPROC)wglGetProcAddress("wglGetGalliumScreenMESA");
113 if(!pfnGetGalliumScreenMESA)
114 return FALSE;
115
116 pfnCreateGalliumContextMESA = (PFNCREATEGALLIUMCONTEXTMESAPROC)wglGetProcAddress("wglCreateGalliumContextMESA");
117 if(!pfnCreateGalliumContextMESA)
118 return FALSE;
119
120 DestroyWindow(hwnd);
121
122 return TRUE;
123 }
124
125 #else
126
127 static INLINE boolean
128 st_hardpipe_load(void)
129 {
130 Display *dpy;
131 int scrnum;
132 Window root;
133 int attribSingle[] = {
134 GLX_RGBA,
135 GLX_RED_SIZE, 1,
136 GLX_GREEN_SIZE, 1,
137 GLX_BLUE_SIZE, 1,
138 None };
139 int attribDouble[] = {
140 GLX_RGBA,
141 GLX_RED_SIZE, 1,
142 GLX_GREEN_SIZE, 1,
143 GLX_BLUE_SIZE, 1,
144 GLX_DOUBLEBUFFER,
145 None };
146 XVisualInfo *visinfo;
147 GLXContext ctx = NULL;
148 XSetWindowAttributes attr;
149 unsigned long mask;
150 int width = 100, height = 100;
151 Window win;
152
153 dpy = XOpenDisplay(NULL);
154 if (!dpy)
155 return FALSE;
156
157 scrnum = 0;
158
159 root = RootWindow(dpy, scrnum);
160
161 visinfo = glXChooseVisual(dpy, scrnum, attribSingle);
162 if (!visinfo)
163 visinfo = glXChooseVisual(dpy, scrnum, attribDouble);
164 if (!visinfo)
165 return FALSE;
166
167 ctx = glXCreateContext( dpy, visinfo, NULL, True );
168
169 if (!ctx)
170 return FALSE;
171
172 attr.background_pixel = 0;
173 attr.border_pixel = 0;
174 attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone);
175 attr.event_mask = StructureNotifyMask | ExposureMask;
176
177 mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
178
179 win = XCreateWindow(dpy, root, 0, 0, width, height,
180 0, visinfo->depth, InputOutput,
181 visinfo->visual, mask, &attr);
182
183 if (!glXMakeCurrent(dpy, win, ctx))
184 return FALSE;
185
186 pfnGetGalliumScreenMESA = (PFNGETGALLIUMSCREENMESAPROC)glXGetProcAddressARB((const GLubyte *)"glXGetGalliumScreenMESA");
187 if(!pfnGetGalliumScreenMESA)
188 return FALSE;
189
190 pfnCreateGalliumContextMESA = (PFNCREATEGALLIUMCONTEXTMESAPROC)glXGetProcAddressARB((const GLubyte *)"glXCreateGalliumContextMESA");
191 if(!pfnCreateGalliumContextMESA)
192 return FALSE;
193
194 glXDestroyContext(dpy, ctx);
195 XFree(visinfo);
196 XDestroyWindow(dpy, win);
197 XCloseDisplay(dpy);
198
199 return TRUE;
200 }
201
202 #endif
203
204
205 struct pipe_screen *
206 st_hardware_screen_create(void)
207 {
208 if(st_hardpipe_load())
209 return pfnGetGalliumScreenMESA();
210 else
211 return st_software_screen_create();
212 }