1 /* Support for window-specific OpenGL extensions.
3 * Copyright (c) 2004 Lionel Ulmer
4 * Copyright (c) 2005 Alex Woods
5 * Copyright (c) 2005 Raphael Junqueira
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include "wine/port.h"
36 #include "opengl_ext.h"
37 #include "wine/library.h"
38 #include "wine/debug.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(opengl);
43 /* x11drv GDI escapes */
44 #define X11DRV_ESCAPE 6789
45 enum x11drv_escape_codes
47 X11DRV_GET_DISPLAY, /* get X11 display for a DC */
48 X11DRV_GET_DRAWABLE, /* get current drawable for a DC */
49 X11DRV_GET_FONT, /* get current X font for a DC */
50 X11DRV_SET_DRAWABLE, /* set current drawable for a DC */
52 struct x11drv_escape_set_drawable
54 enum x11drv_escape_codes code; /* escape code (X11DRV_SET_DRAWABLE) */
55 Drawable drawable; /* X drawable */
56 int mode; /* ClipByChildren or IncludeInferiors */
57 POINT org; /* origin of DC relative to drawable */
58 POINT drawable_org; /* origin of drawable relative to screen */
61 /* retrieve the X display to use on a given DC */
62 inline static Display *get_display( HDC hdc )
65 enum x11drv_escape_codes escape = X11DRV_GET_DISPLAY;
67 if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape,
68 sizeof(display), (LPSTR)&display )) display = NULL;
71 inline static void set_drawable( HDC hdc, Drawable drawable )
73 struct x11drv_escape_set_drawable escape;
75 escape.code = X11DRV_SET_DRAWABLE;
76 escape.drawable = drawable;
77 escape.mode = IncludeInferiors;
78 escape.org.x = escape.org.y = 0;
79 escape.drawable_org.x = escape.drawable_org.y = 0;
81 ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape, 0, NULL );
84 /* Some WGL extensions... */
85 static const char *WGL_extensions_base = "WGL_ARB_extensions_string WGL_EXT_extensions_string";
86 static char *WGL_extensions = NULL;
89 * Extensions-query functions
91 * @TODO: use a struct to handle parameters
93 BOOL query_function_make_current_read(glXGetProcAddressARB_t proc, const char *gl_version, const char *gl_extensions,
94 const char* glx_version, const char *glx_extensions,
95 const char *server_glx_extensions, const char *client_glx_extensions)
97 return 0 <= strcmp("1.3", glx_version);
100 BOOL query_function_multisample(glXGetProcAddressARB_t proc, const char *gl_version, const char *gl_extensions,
101 const char* glx_version, const char *glx_extensions,
102 const char *server_glx_extensions, const char *client_glx_extensions)
104 return NULL != strstr(glx_extensions, "GLX_ARB_multisample");
107 BOOL query_function_pbuffer(glXGetProcAddressARB_t proc, const char *gl_version, const char *gl_extensions,
108 const char* glx_version, const char *glx_extensions,
109 const char *server_glx_extensions, const char *client_glx_extensions)
111 TRACE("gl_version is: \"%s\"\n", gl_version);
112 TRACE("glx_exts is: \"%s\"\n", glx_extensions);
114 return 0 <= strcmp("1.3", glx_version) || NULL != strstr(glx_extensions, "GLX_SGIX_pbuffer");
117 BOOL query_function_pixel_format(glXGetProcAddressARB_t proc, const char *gl_version, const char *gl_extensions,
118 const char* glx_version, const char *glx_extensions,
119 const char *server_glx_extensions, const char *client_glx_extensions)
124 /** GLX_ARB_render_texture */
126 * http://oss.sgi.com/projects/ogl-sample/registry/ARB/wgl_render_texture.txt
127 * ~/tmp/ogl/ogl_offscreen_rendering_3
129 Bool (*p_glXBindTexImageARB)(Display *dpy, GLXPbuffer pbuffer, int buffer);
130 Bool (*p_glXReleaseTexImageARB)(Display *dpy, GLXPbuffer pbuffer, int buffer);
131 Bool (*p_glXDrawableAttribARB)(Display *dpy, GLXDrawable draw, const int *attribList);
132 int use_render_texture_emulation = 0;
133 BOOL query_function_render_texture(glXGetProcAddressARB_t proc, const char *gl_version, const char *gl_extensions,
134 const char* glx_version, const char *glx_extensions,
135 const char *server_glx_extensions, const char *client_glx_extensions)
137 BOOL bTest = (0 <= strcmp("1.3", glx_version) || NULL != strstr(glx_extensions, "GLX_SGIX_pbuffer"));
139 if (NULL != strstr(glx_extensions, "GLX_ARB_render_texture")) {
140 p_glXBindTexImageARB = proc( (const GLubyte *) "glXBindTexImageARB");
141 p_glXReleaseTexImageARB = proc( (const GLubyte *) "glXReleaseTexImageARB");
142 p_glXDrawableAttribARB = proc( (const GLubyte *) "glXDrawableAttribARB");
143 bTest = (NULL != p_glXBindTexImageARB && NULL != p_glXReleaseTexImageARB && NULL != p_glXDrawableAttribARB);
145 use_render_texture_emulation = 0;
151 int (*p_glXSwapIntervalSGI)(int);
152 BOOL query_function_swap_control(glXGetProcAddressARB_t proc, const char *gl_version, const char *gl_extensions,
153 const char* glx_version, const char *glx_extensions,
154 const char *server_glx_extensions, const char *client_glx_extensions)
156 BOOL bTest = (0 <= strcmp("1.3", glx_version) || NULL != strstr(glx_extensions, "GLX_SGI_swap_control"));
158 p_glXSwapIntervalSGI = proc( (const GLubyte *) "glXSwapIntervalSGI");
159 bTest = (NULL != p_glXSwapIntervalSGI);
164 /***********************************************************************
165 * wglGetExtensionsStringEXT(OPENGL32.@)
167 const char * WINAPI wglGetExtensionsStringEXT(void) {
168 TRACE("() returning \"%s\"\n", WGL_extensions);
170 return WGL_extensions;
173 /***********************************************************************
174 * wglGetExtensionsStringARB(OPENGL32.@)
176 const char * WINAPI wglGetExtensionsStringARB(HDC hdc) {
177 TRACE("() returning \"%s\"\n", WGL_extensions);
179 return WGL_extensions;
182 static int swap_interval = 1;
184 /***********************************************************************
185 * wglSwapIntervalEXT(OPENGL32.@)
187 BOOL WINAPI wglSwapIntervalEXT(int interval) {
188 TRACE("(%d)\n", interval);
189 swap_interval = interval;
190 if (NULL != p_glXSwapIntervalSGI) {
191 return 0 == p_glXSwapIntervalSGI(interval);
193 WARN("(): GLX_SGI_swap_control extension seems not supported\n");
197 /***********************************************************************
198 * wglGetSwapIntervalEXT(OPENGL32.@)
200 int WINAPI wglGetSwapIntervalEXT(VOID) {
202 return swap_interval;
205 typedef struct wine_glpbuffer {
214 int use_render_texture;
215 GLuint texture_target;
216 GLuint texture_bind_target;
221 #define PUSH1(attribs,att) attribs[nAttribs++] = (att);
222 #define PUSH2(attribs,att,value) attribs[nAttribs++] = (att); attribs[nAttribs++] = (value);
224 #define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
225 #define WGL_DRAW_TO_WINDOW_ARB 0x2001
226 #define WGL_DRAW_TO_BITMAP_ARB 0x2002
227 #define WGL_ACCELERATION_ARB 0x2003
228 #define WGL_NEED_PALETTE_ARB 0x2004
229 #define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005
230 #define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006
231 #define WGL_SWAP_METHOD_ARB 0x2007
232 #define WGL_NUMBER_OVERLAYS_ARB 0x2008
233 #define WGL_NUMBER_UNDERLAYS_ARB 0x2009
234 #define WGL_TRANSPARENT_ARB 0x200A
235 #define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037
236 #define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038
237 #define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039
238 #define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A
239 #define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B
240 #define WGL_SHARE_DEPTH_ARB 0x200C
241 #define WGL_SHARE_STENCIL_ARB 0x200D
242 #define WGL_SHARE_ACCUM_ARB 0x200E
243 #define WGL_SUPPORT_GDI_ARB 0x200F
244 #define WGL_SUPPORT_OPENGL_ARB 0x2010
245 #define WGL_DOUBLE_BUFFER_ARB 0x2011
246 #define WGL_STEREO_ARB 0x2012
247 #define WGL_PIXEL_TYPE_ARB 0x2013
248 #define WGL_COLOR_BITS_ARB 0x2014
249 #define WGL_RED_BITS_ARB 0x2015
250 #define WGL_RED_SHIFT_ARB 0x2016
251 #define WGL_GREEN_BITS_ARB 0x2017
252 #define WGL_GREEN_SHIFT_ARB 0x2018
253 #define WGL_BLUE_BITS_ARB 0x2019
254 #define WGL_BLUE_SHIFT_ARB 0x201A
255 #define WGL_ALPHA_BITS_ARB 0x201B
256 #define WGL_ALPHA_SHIFT_ARB 0x201C
257 #define WGL_ACCUM_BITS_ARB 0x201D
258 #define WGL_ACCUM_RED_BITS_ARB 0x201E
259 #define WGL_ACCUM_GREEN_BITS_ARB 0x201F
260 #define WGL_ACCUM_BLUE_BITS_ARB 0x2020
261 #define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
262 #define WGL_DEPTH_BITS_ARB 0x2022
263 #define WGL_STENCIL_BITS_ARB 0x2023
264 #define WGL_AUX_BUFFERS_ARB 0x2024
266 #define WGL_NO_ACCELERATION_ARB 0x2025
267 #define WGL_GENERIC_ACCELERATION_ARB 0x2026
268 #define WGL_FULL_ACCELERATION_ARB 0x2027
270 #define WGL_PBUFFER_WIDTH_ARB 0x2034
271 #define WGL_PBUFFER_HEIGHT_ARB 0x2035
272 #define WGL_PBUFFER_LOST_ARB 0x2036
273 #define WGL_DRAW_TO_PBUFFER_ARB 0x202D
274 #define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E
275 #define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F
276 #define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030
277 #define WGL_PBUFFER_LARGEST_ARB 0x2033
279 #define WGL_TYPE_RGBA_ARB 0x202B
280 #define WGL_TYPE_COLORINDEX_ARB 0x202C
282 #define WGL_SAMPLE_BUFFERS_ARB 0x2041
283 #define WGL_SAMPLES_ARB 0x2042
288 /** GetPixelFormat/ChoosePixelFormat */
289 #define WGL_BIND_TO_TEXTURE_RGB_ARB 0x2070
290 #define WGL_BIND_TO_TEXTURE_RGBA_ARB 0x2071
291 /** CreatePbuffer / QueryPbuffer */
292 #define WGL_TEXTURE_FORMAT_ARB 0x2072
293 #define WGL_TEXTURE_TARGET_ARB 0x2073
294 #define WGL_MIPMAP_TEXTURE_ARB 0x2074
295 /** CreatePbuffer / QueryPbuffer */
296 #define WGL_TEXTURE_RGB_ARB 0x2075
297 #define WGL_TEXTURE_RGBA_ARB 0x2076
298 #define WGL_NO_TEXTURE_ARB 0x2077
299 /** CreatePbuffer / QueryPbuffer */
300 #define WGL_TEXTURE_CUBE_MAP_ARB 0x2078
301 #define WGL_TEXTURE_1D_ARB 0x2079
302 #define WGL_TEXTURE_2D_ARB 0x207A
303 #define WGL_NO_TEXTURE_ARB 0x2077
304 /** SetPbufferAttribARB/QueryPbufferARB parameters */
305 #define WGL_MIPMAP_LEVEL_ARB 0x207B
306 #define WGL_CUBE_MAP_FACE_ARB 0x207C
307 /** SetPbufferAttribARB/QueryPbufferARB attribs */
308 #define WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x207D
309 #define WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x207E
310 #define WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x207F
311 #define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x2080
312 #define WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x2081
313 #define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x2082
314 /** BindTexImageARB/ReleaseTexImageARB */
315 #define WGL_FRONT_LEFT_ARB 0x2083
316 #define WGL_FRONT_RIGHT_ARB 0x2084
317 #define WGL_BACK_LEFT_ARB 0x2085
318 #define WGL_BACK_RIGHT_ARB 0x2086
319 #define WGL_AUX0_ARB 0x2087
320 #define WGL_AUX1_ARB 0x2088
321 #define WGL_AUX2_ARB 0x2089
322 #define WGL_AUX3_ARB 0x208A
323 #define WGL_AUX4_ARB 0x208B
324 #define WGL_AUX5_ARB 0x208C
325 #define WGL_AUX6_ARB 0x208D
326 #define WGL_AUX7_ARB 0x208E
327 #define WGL_AUX8_ARB 0x208F
328 #define WGL_AUX9_ARB 0x2090
330 #if 0 /* not used yet */
331 static unsigned ConvertAttribGLXtoWGL(const int* iWGLAttr, int* oGLXAttr) {
332 unsigned nAttribs = 0;
333 FIXME("not yet implemented!\n");
338 static unsigned ConvertAttribWGLtoGLX(const int* iWGLAttr, int* oGLXAttr, Wine_GLPBuffer* pbuf) {
339 unsigned nAttribs = 0;
343 int wantColorBits = 0;
346 while (0 != iWGLAttr[cur]) {
347 TRACE("pAttr[%d] = %x\n", cur, iWGLAttr[cur]);
349 switch (iWGLAttr[cur]) {
350 case WGL_COLOR_BITS_ARB:
351 pop = iWGLAttr[++cur];
352 wantColorBits = pop; /** see end */
354 case WGL_BLUE_BITS_ARB:
355 pop = iWGLAttr[++cur];
356 PUSH2(oGLXAttr, GLX_BLUE_SIZE, pop);
357 TRACE("pAttr[%d] = GLX_BLUE_SIZE: %d\n", cur, pop);
359 case WGL_RED_BITS_ARB:
360 pop = iWGLAttr[++cur];
361 PUSH2(oGLXAttr, GLX_RED_SIZE, pop);
362 TRACE("pAttr[%d] = GLX_RED_SIZE: %d\n", cur, pop);
364 case WGL_GREEN_BITS_ARB:
365 pop = iWGLAttr[++cur];
366 PUSH2(oGLXAttr, GLX_GREEN_SIZE, pop);
367 TRACE("pAttr[%d] = GLX_GREEN_SIZE: %d\n", cur, pop);
369 case WGL_ALPHA_BITS_ARB:
370 pop = iWGLAttr[++cur];
372 PUSH2(oGLXAttr, GLX_ALPHA_SIZE, pop);
373 TRACE("pAttr[%d] = GLX_ALPHA_SIZE: %d\n", cur, pop);
375 case WGL_DEPTH_BITS_ARB:
376 pop = iWGLAttr[++cur];
377 PUSH2(oGLXAttr, GLX_DEPTH_SIZE, pop);
378 TRACE("pAttr[%d] = GLX_DEPTH_SIZE: %d\n", cur, pop);
380 case WGL_STENCIL_BITS_ARB:
381 pop = iWGLAttr[++cur];
382 PUSH2(oGLXAttr, GLX_STENCIL_SIZE, pop);
383 TRACE("pAttr[%d] = GLX_STENCIL_SIZE: %d\n", cur, pop);
385 case WGL_DOUBLE_BUFFER_ARB:
386 pop = iWGLAttr[++cur];
387 PUSH2(oGLXAttr, GLX_DOUBLEBUFFER, pop);
388 TRACE("pAttr[%d] = GLX_DOUBLEBUFFER: %d\n", cur, pop);
391 case WGL_PIXEL_TYPE_ARB:
392 pop = iWGLAttr[++cur];
394 case WGL_TYPE_RGBA_ARB: pop = GLX_RGBA_BIT; break ;
395 case WGL_TYPE_COLORINDEX_ARB: pop = GLX_COLOR_INDEX_BIT; isColor = 1; break ;
397 ERR("unexpected PixelType(%x)\n", pop);
400 PUSH2(oGLXAttr, GLX_RENDER_TYPE, pop);
401 TRACE("pAttr[%d] = GLX_RENDER_TYPE: %d\n", cur, pop);
404 case WGL_SUPPORT_GDI_ARB:
405 case WGL_DRAW_TO_WINDOW_ARB:
406 case WGL_DRAW_TO_BITMAP_ARB:
407 case WGL_DRAW_TO_PBUFFER_ARB:
408 pop = iWGLAttr[++cur];
409 PUSH2(oGLXAttr, GLX_X_RENDERABLE, pop);
410 TRACE("pAttr[%d] = GLX_RENDERABLE: %d\n", cur, pop);
413 case WGL_ACCELERATION_ARB:
414 case WGL_SUPPORT_OPENGL_ARB:
415 pop = iWGLAttr[++cur];
416 /** nothing to do, if we are here, supposing support Accelerated OpenGL */
417 TRACE("pAttr[%d] = WGL_SUPPORT_OPENGL_ARB: %d\n", cur, pop);
420 case WGL_PBUFFER_LARGEST_ARB:
421 pop = iWGLAttr[++cur];
422 PUSH2(oGLXAttr, GLX_LARGEST_PBUFFER, pop);
423 TRACE("pAttr[%d] = GLX_LARGEST_PBUFFER: %x\n", cur, pop);
426 case WGL_SAMPLE_BUFFERS_ARB:
427 pop = iWGLAttr[++cur];
428 PUSH2(oGLXAttr, GLX_SAMPLE_BUFFERS_ARB, pop);
429 TRACE("pAttr[%d] = GLX_SAMPLE_BUFFERS_ARB: %x\n", cur, pop);
432 case WGL_SAMPLES_ARB:
433 pop = iWGLAttr[++cur];
434 PUSH2(oGLXAttr, GLX_SAMPLES_ARB, pop);
435 TRACE("pAttr[%d] = GLX_SAMPLES_ARB: %x\n", cur, pop);
438 case WGL_TEXTURE_FORMAT_ARB:
439 case WGL_TEXTURE_TARGET_ARB:
440 case WGL_MIPMAP_TEXTURE_ARB:
441 TRACE("WGL_render_texture Attributes: %x as %x\n", iWGLAttr[cur], iWGLAttr[cur + 1]);
443 ERR("trying to use GLX_Pbuffer Attributes without Pbuffer (was %x)\n", iWGLAttr[cur]);
445 if (!use_render_texture_emulation) {
446 ERR("trying to use WGL_render_texture Attributes without support (was %x)\n", iWGLAttr[cur]);
448 pop = iWGLAttr[++cur];
452 FIXME("unsupported %x WGL Attribute\n", iWGLAttr[cur]);
459 * Trick as WGL_COLOR_BITS_ARB != GLX_BUFFER_SIZE
460 * WGL_COLOR_BITS_ARB + WGL_ALPHA_BITS_ARB == GLX_BUFFER_SIZE
463 * The number of color bitplanes in each color buffer. For RGBA
464 * pixel types, it is the size of the color buffer, excluding the
465 * alpha bitplanes. For color-index pixels, it is the size of the
466 * color index buffer.
469 * This attribute defines the number of bits per color buffer.
470 * For GLX FBConfigs that correspond to a PseudoColor or StaticColor visual,
471 * this is equal to the depth value reported in the X11 visual.
472 * For GLX FBConfigs that correspond to TrueColor or DirectColor visual,
473 * this is the sum of GLX_RED_SIZE, GLX_GREEN_SIZE, GLX_BLUE_SIZE, and GLX_ALPHA_SIZE.
476 if (0 < wantColorBits) {
478 wantColorBits += sz_alpha;
480 if (32 < wantColorBits) {
481 ERR("buggy %d GLX_BUFFER_SIZE default to 32\n", wantColorBits);
484 PUSH2(oGLXAttr, GLX_BUFFER_SIZE, wantColorBits);
485 TRACE("pAttr[%d] = WGL_COLOR_BITS_ARB: %d\n", cur, wantColorBits);
491 GLboolean WINAPI wglGetPixelFormatAttribivARB(HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues)
493 Display* display = get_display( hdc );
495 GLXFBConfig* cfgs = NULL;
496 GLXFBConfig curCfg = NULL;
502 TRACE("(%p, %d, %d, %d, %p, %p)\n", hdc, iPixelFormat, iLayerPlane, nAttributes, piAttributes, piValues);
504 if (0 < iLayerPlane) {
505 FIXME("unsupported iLayerPlane(%d) > 0, returns FALSE\n", iLayerPlane);
509 cfgs = glXGetFBConfigs(display, DefaultScreen(display), &nCfgs);
511 ERR("no FB Configs found for display(%p)\n", display);
515 for (i = 0; i < nAttributes; ++i) {
516 const int curWGLAttr = piAttributes[i];
517 TRACE("pAttr[%d] = %x\n", i, curWGLAttr);
519 switch (curWGLAttr) {
520 case WGL_NUMBER_PIXEL_FORMATS_ARB:
524 case WGL_SUPPORT_OPENGL_ARB:
525 piValues[i] = GL_TRUE;
528 case WGL_ACCELERATION_ARB:
529 curGLXAttr = GLX_CONFIG_CAVEAT;
530 if (nCfgs < iPixelFormat || 0 >= iPixelFormat) goto pix_error;
531 curCfg = cfgs[iPixelFormat - 1];
532 hTest = glXGetFBConfigAttrib(display, curCfg, curGLXAttr, &tmp);
533 if (hTest) goto get_error;
535 case GLX_NONE: piValues[i] = WGL_FULL_ACCELERATION_ARB; break;
536 case GLX_SLOW_CONFIG: piValues[i] = WGL_NO_ACCELERATION_ARB; break;
537 case GLX_NON_CONFORMANT_CONFIG: piValues[i] = WGL_FULL_ACCELERATION_ARB; break;
539 ERR("unexpected Config Caveat(%x)\n", tmp);
540 piValues[i] = WGL_NO_ACCELERATION_ARB;
544 case WGL_TRANSPARENT_ARB:
545 curGLXAttr = GLX_TRANSPARENT_TYPE;
546 if (nCfgs < iPixelFormat || 0 >= iPixelFormat) goto pix_error;
547 curCfg = cfgs[iPixelFormat - 1];
548 hTest = glXGetFBConfigAttrib(display, curCfg, curGLXAttr, &tmp);
549 if (hTest) goto get_error;
550 piValues[i] = GL_FALSE;
551 if (GLX_NONE != tmp) piValues[i] = GL_TRUE;
554 case WGL_PIXEL_TYPE_ARB:
555 curGLXAttr = GLX_RENDER_TYPE;
556 if (nCfgs < iPixelFormat || 0 >= iPixelFormat) goto pix_error;
557 curCfg = cfgs[iPixelFormat - 1];
558 hTest = glXGetFBConfigAttrib(display, curCfg, curGLXAttr, &tmp);
559 if (hTest) goto get_error;
561 case GLX_RGBA_BIT: piValues[i] = WGL_TYPE_RGBA_ARB; break;
562 case GLX_COLOR_INDEX_BIT: piValues[i] = WGL_TYPE_COLORINDEX_ARB; break ;
564 ERR("unexpected RenderType(%x)\n", tmp);
565 piValues[i] = WGL_TYPE_RGBA_ARB;
569 case WGL_COLOR_BITS_ARB:
570 /** see ConvertAttribWGLtoGLX for explain */
571 if (nCfgs < iPixelFormat || 0 >= iPixelFormat) goto pix_error;
572 curCfg = cfgs[iPixelFormat - 1];
573 hTest = glXGetFBConfigAttrib(display, curCfg, GLX_BUFFER_SIZE, piValues + i);
574 if (hTest) goto get_error;
575 hTest = glXGetFBConfigAttrib(display, curCfg, GLX_ALPHA_SIZE, &tmp);
576 if (hTest) goto get_error;
577 piValues[i] = piValues[i] - tmp;
580 case WGL_BLUE_BITS_ARB:
581 curGLXAttr = GLX_BLUE_SIZE;
583 case WGL_RED_BITS_ARB:
584 curGLXAttr = GLX_RED_SIZE;
586 case WGL_GREEN_BITS_ARB:
587 curGLXAttr = GLX_GREEN_SIZE;
589 case WGL_ALPHA_BITS_ARB:
590 curGLXAttr = GLX_ALPHA_SIZE;
592 case WGL_DEPTH_BITS_ARB:
593 curGLXAttr = GLX_DEPTH_SIZE;
595 case WGL_STENCIL_BITS_ARB:
596 curGLXAttr = GLX_STENCIL_SIZE;
598 case WGL_DOUBLE_BUFFER_ARB:
599 curGLXAttr = GLX_DOUBLEBUFFER;
602 curGLXAttr = GLX_STEREO;
604 case WGL_AUX_BUFFERS_ARB:
605 curGLXAttr = GLX_AUX_BUFFERS;
608 case WGL_SUPPORT_GDI_ARB:
609 case WGL_DRAW_TO_WINDOW_ARB:
610 case WGL_DRAW_TO_BITMAP_ARB:
611 case WGL_DRAW_TO_PBUFFER_ARB:
612 curGLXAttr = GLX_X_RENDERABLE;
615 case WGL_PBUFFER_LARGEST_ARB:
616 curGLXAttr = GLX_LARGEST_PBUFFER;
619 case WGL_SAMPLE_BUFFERS_ARB:
620 curGLXAttr = GLX_SAMPLE_BUFFERS_ARB;
623 case WGL_SAMPLES_ARB:
624 curGLXAttr = GLX_SAMPLES_ARB;
627 case WGL_BIND_TO_TEXTURE_RGB_ARB:
628 case WGL_BIND_TO_TEXTURE_RGBA_ARB:
629 if (!use_render_texture_emulation) {
630 piValues[i] = GL_FALSE;
633 curGLXAttr = GLX_RENDER_TYPE;
634 if (nCfgs < iPixelFormat || 0 >= iPixelFormat) goto pix_error;
635 curCfg = cfgs[iPixelFormat - 1];
636 hTest = glXGetFBConfigAttrib(display, curCfg, curGLXAttr, &tmp);
637 if (hTest) goto get_error;
638 if (GLX_COLOR_INDEX_BIT == tmp) {
639 piValues[i] = GL_FALSE;
642 curGLXAttr = GLX_X_RENDERABLE;
646 FIXME("unsupported %x WGL Attribute\n", curWGLAttr);
649 if (0 != curGLXAttr) {
650 if (nCfgs < iPixelFormat || 0 >= iPixelFormat) goto pix_error;
651 curCfg = cfgs[iPixelFormat - 1];
652 hTest = glXGetFBConfigAttrib(display, curCfg, curGLXAttr, piValues + i);
653 if (hTest) goto get_error;
655 piValues[i] = GL_FALSE;
662 ERR("(%p): unexpected failure on GetFBConfigAttrib(%x) returns FALSE\n", hdc, curGLXAttr);
667 ERR("(%p): unexpected iPixelFormat(%d) vs nFormats(%d), returns FALSE\n", hdc, iPixelFormat, nCfgs);
672 GLboolean WINAPI wglGetPixelFormatAttribfvARB(HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues)
674 FIXME("(%p, %d, %d, %d, %p, %p): stub\n", hdc, iPixelFormat, iLayerPlane, nAttributes, piAttributes, pfValues);
678 * http://publib.boulder.ibm.com/infocenter/pseries/index.jsp?topic=/com.ibm.aix.doc/libs/openglrf/glXChooseFBConfig.htm
680 GLboolean WINAPI wglChoosePixelFormatARB(HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats)
682 Display* display = get_display( hdc );
685 unsigned nAttribs = 0;
687 GLXFBConfig* cfgs = NULL;
692 GLXFBConfig* cfgs_fmt = NULL;
699 TRACE("(%p, %p, %p, %d, %p, %p): hackish\n", hdc, piAttribIList, pfAttribFList, nMaxFormats, piFormats, nNumFormats);
700 if (NULL != pfAttribFList) {
701 FIXME("unused pfAttribFList\n");
704 nAttribs = ConvertAttribWGLtoGLX(piAttribIList, attribs, NULL);
705 PUSH1(attribs, None);
707 cfgs = glXChooseFBConfig(display, DefaultScreen(display), attribs, &nCfgs);
709 WARN("Compatible Pixel Format not found\n");
713 cfgs_fmt = glXGetFBConfigs(display, DefaultScreen(display), &nCfgs_fmt);
714 if (NULL == cfgs_fmt) {
715 ERR("Failed to get All FB Configs\n");
720 for (it = 0; it < nMaxFormats && it < nCfgs; ++it) {
721 gl_test = glXGetFBConfigAttrib(display, cfgs[it], GLX_FBCONFIG_ID, &fmt_id);
723 ERR("Failed to retrieve FBCONFIG_ID from GLXFBConfig, expect problems.\n");
726 for (it_fmt = 0; it_fmt < nCfgs_fmt; ++it_fmt) {
727 gl_test = glXGetFBConfigAttrib(display, cfgs_fmt[it_fmt], GLX_FBCONFIG_ID, &tmp_fmt_id);
729 ERR("Failed to retrieve FBCONFIG_ID from GLXFBConfig, expect problems.\n");
732 if (fmt_id == tmp_fmt_id) {
734 piFormats[pfmt_it] = it_fmt + 1;
736 glXGetFBConfigAttrib(display, cfgs_fmt[it_fmt], GLX_ALPHA_SIZE, &tmp);
737 TRACE("for FBCONFIG_ID(%d/%d) found '%d'\n", it_fmt + 1, nCfgs_fmt, tmp);
741 if (it_fmt == nCfgs_fmt) {
742 ERR("Failed to get valid fmt for %d. Try next.\n", it);
745 TRACE("at %d/%d found FBCONFIG_ID(%d/%d)\n", it + 1, nCfgs, piFormats[it], nCfgs_fmt);
748 *nNumFormats = pfmt_it;
755 #define HPBUFFERARB void *
756 HPBUFFERARB WINAPI wglCreatePbufferARB(HDC hdc, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList)
758 Wine_GLPBuffer* object = NULL;
759 Display* display = get_display( hdc );
760 GLXFBConfig* cfgs = NULL;
763 unsigned nAttribs = 0;
765 TRACE("(%p, %d, %d, %d, %p)\n", hdc, iPixelFormat, iWidth, iHeight, piAttribList);
767 if (0 >= iPixelFormat) {
768 ERR("(%p): unexpected iPixelFormat(%d) <= 0, returns NULL\n", hdc, iPixelFormat);
769 SetLastError(ERROR_INVALID_PIXEL_FORMAT);
770 return NULL; /* unespected error */
773 cfgs = glXGetFBConfigs(display, DefaultScreen(display), &nCfgs);
775 if (NULL == cfgs || 0 == nCfgs) {
776 ERR("(%p): Cannot get FB Configs for iPixelFormat(%d), returns NULL\n", hdc, iPixelFormat);
777 SetLastError(ERROR_INVALID_PIXEL_FORMAT);
778 return NULL; /* unespected error */
780 if (nCfgs < iPixelFormat) {
781 ERR("(%p): unexpected iPixelFormat(%d) > nFormats(%d), returns NULL\n", hdc, iPixelFormat, nCfgs);
782 SetLastError(ERROR_INVALID_PIXEL_FORMAT);
783 goto create_failed; /* unespected error */
786 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(Wine_GLPBuffer));
787 if (NULL == object) {
788 SetLastError(ERROR_NO_SYSTEM_RESOURCES);
789 goto create_failed; /* unespected error */
792 object->display = display;
793 object->width = iWidth;
794 object->height = iHeight;
795 object->pixelFormat = iPixelFormat;
797 nAttribs = ConvertAttribWGLtoGLX(piAttribList, attribs, object);
798 PUSH2(attribs, GLX_PBUFFER_WIDTH, iWidth);
799 PUSH2(attribs, GLX_PBUFFER_HEIGHT, iHeight);
800 PUSH1(attribs, None);
802 while (0 != *piAttribList) {
804 switch (*piAttribList) {
805 case WGL_TEXTURE_FORMAT_ARB: {
806 if (!use_render_texture_emulation) {
807 SetLastError(ERROR_INVALID_DATA);
811 attr_v = *piAttribList;
812 TRACE("WGL_render_texture Attribute: WGL_TEXTURE_FORMAT_ARB as %x\n", attr_v);
814 case WGL_TEXTURE_RGB_ARB:
815 case WGL_TEXTURE_RGBA_ARB:
816 case WGL_NO_TEXTURE_ARB:
819 SetLastError(ERROR_INVALID_DATA);
825 case WGL_TEXTURE_TARGET_ARB: {
826 if (!use_render_texture_emulation) {
827 SetLastError(ERROR_INVALID_DATA);
831 attr_v = *piAttribList;
832 TRACE("WGL_render_texture Attribute: WGL_TEXTURE_TARGET_ARB as %x\n", attr_v);
834 case WGL_TEXTURE_CUBE_MAP_ARB: {
835 if (iWidth != iHeight) {
836 SetLastError(ERROR_INVALID_DATA);
839 object->texture_target = GL_TEXTURE_CUBE_MAP;
840 object->texture_bind_target = GL_TEXTURE_CUBE_MAP;
843 case WGL_TEXTURE_1D_ARB: {
845 SetLastError(ERROR_INVALID_DATA);
848 object->texture_target = GL_TEXTURE_1D;
849 object->texture_bind_target = GL_TEXTURE_1D;
852 case WGL_TEXTURE_2D_ARB: {
853 object->texture_target = GL_TEXTURE_2D;
854 object->texture_bind_target = GL_TEXTURE_2D;
857 case WGL_NO_TEXTURE_ARB:
860 SetLastError(ERROR_INVALID_DATA);
866 case WGL_MIPMAP_TEXTURE_ARB: {
867 if (!use_render_texture_emulation) {
868 SetLastError(ERROR_INVALID_DATA);
872 attr_v = *piAttribList;
873 TRACE("WGL_render_texture Attribute: WGL_MIPMAP_TEXTURE_ARB as %x\n", attr_v);
875 SetLastError(ERROR_INVALID_DATA);
885 object->drawable = glXCreatePbuffer(display, cfgs[iPixelFormat - 1], attribs);
886 TRACE("new Pbuffer drawable as %p\n", (void*) object->drawable);
887 if (!object->drawable) {
888 SetLastError(ERROR_NO_SYSTEM_RESOURCES);
889 goto create_failed; /* unespected error */
891 TRACE("->(%p)\n", object);
895 return (HPBUFFERARB) object;
898 if (NULL != cfgs) XFree(cfgs);
899 if (NULL != object) HeapFree(GetProcessHeap(), 0, object);
900 TRACE("->(FAILED)\n");
901 return (HPBUFFERARB) NULL;
904 HDC WINAPI wglGetPbufferDCARB(HPBUFFERARB hPbuffer)
906 Wine_GLPBuffer* object = (Wine_GLPBuffer*) hPbuffer;
908 if (NULL == object) {
909 SetLastError(ERROR_INVALID_HANDLE);
912 hDC = CreateCompatibleDC(object->hdc);
913 set_drawable(hDC, object->drawable); /* works ?? */
914 TRACE("(%p)->(%p)\n", hPbuffer, hDC);
918 int WINAPI wglReleasePbufferDCARB(HPBUFFERARB hPbuffer, HDC hdc)
920 TRACE("(%p, %p)\n", hPbuffer, hdc);
925 GLboolean WINAPI wglDestroyPbufferARB(HPBUFFERARB hPbuffer)
927 Wine_GLPBuffer* object = (Wine_GLPBuffer*) hPbuffer;
928 TRACE("(%p)\n", hPbuffer);
929 if (NULL == object) {
930 SetLastError(ERROR_INVALID_HANDLE);
933 glXDestroyPbuffer(object->display, object->drawable);
934 HeapFree(GetProcessHeap(), 0, object);
938 GLboolean WINAPI wglQueryPbufferARB(HPBUFFERARB hPbuffer, int iAttribute, int *piValue)
940 Wine_GLPBuffer* object = (Wine_GLPBuffer*) hPbuffer;
941 TRACE("(%p, 0x%x, %p)\n", hPbuffer, iAttribute, piValue);
942 if (NULL == object) {
943 SetLastError(ERROR_INVALID_HANDLE);
946 switch (iAttribute) {
947 case WGL_PBUFFER_WIDTH_ARB:
948 glXQueryDrawable(object->display, object->drawable, GLX_WIDTH, (unsigned int*) piValue);
950 case WGL_PBUFFER_HEIGHT_ARB:
951 glXQueryDrawable(object->display, object->drawable, GLX_HEIGHT, (unsigned int*) piValue);
954 case WGL_PBUFFER_LOST_ARB:
955 FIXME("unsupported WGL_PBUFFER_LOST_ARB (need glXSelectEvent/GLX_DAMAGED work)\n");
958 case WGL_TEXTURE_FORMAT_ARB:
959 case WGL_TEXTURE_TARGET_ARB:
960 case WGL_MIPMAP_TEXTURE_ARB:
961 if (!object->use_render_texture) {
962 SetLastError(ERROR_INVALID_HANDLE);
965 if (!use_render_texture_emulation) {
966 SetLastError(ERROR_INVALID_DATA);
967 return GL_FALSE; /** how to FIX ? */
969 FIXME("unsupported WGL_ARB_render_texture attribute query for 0x%x\n", iAttribute);
973 FIXME("unexpected attribute %x\n", iAttribute);
980 GLboolean WINAPI wglBindTexImageARB(HPBUFFERARB hPbuffer, int iBuffer)
982 Wine_GLPBuffer* object = (Wine_GLPBuffer*) hPbuffer;
983 TRACE("(%p, %d)\n", hPbuffer, iBuffer);
984 if (NULL == object) {
985 SetLastError(ERROR_INVALID_HANDLE);
988 if (!object->use_render_texture) {
989 SetLastError(ERROR_INVALID_HANDLE);
992 if (1 == use_render_texture_emulation) {
995 if (NULL != p_glXBindTexImageARB) {
996 return p_glXBindTexImageARB(object->display, object->drawable, iBuffer);
1001 GLboolean WINAPI wglReleaseTexImageARB(HPBUFFERARB hPbuffer, int iBuffer)
1003 Wine_GLPBuffer* object = (Wine_GLPBuffer*) hPbuffer;
1004 TRACE("(%p, %d)\n", hPbuffer, iBuffer);
1005 if (NULL == object) {
1006 SetLastError(ERROR_INVALID_HANDLE);
1009 if (!object->use_render_texture) {
1010 SetLastError(ERROR_INVALID_HANDLE);
1013 if (1 == use_render_texture_emulation) {
1014 GLint prev_binded_tex;
1015 glGetIntegerv(object->texture_target, &prev_binded_tex);
1016 glBindTexture(object->texture_target, object->texture);
1017 if (GL_TEXTURE_1D == object->texture_target) {
1018 glCopyTexSubImage1D(object->texture_bind_target, object->texture_level, 0, 0, 0, object->width);
1020 glCopyTexSubImage2D(object->texture_bind_target, object->texture_level, 0, 0, 0, 0, object->width, object->height);
1022 glBindTexture(object->texture_target, prev_binded_tex);
1025 if (NULL != p_glXReleaseTexImageARB) {
1026 return p_glXReleaseTexImageARB(object->display, object->drawable, iBuffer);
1031 GLboolean WINAPI wglSetPbufferAttribARB(HPBUFFERARB hPbuffer, const int *piAttribList)
1033 Wine_GLPBuffer* object = (Wine_GLPBuffer*) hPbuffer;
1034 WARN("(%p, %p): alpha-testing, report any problem\n", hPbuffer, piAttribList);
1035 if (NULL == object) {
1036 SetLastError(ERROR_INVALID_HANDLE);
1039 if (!object->use_render_texture) {
1040 SetLastError(ERROR_INVALID_HANDLE);
1043 if (1 == use_render_texture_emulation) {
1046 if (NULL != p_glXDrawableAttribARB) {
1047 return p_glXDrawableAttribARB(object->display, object->drawable, piAttribList);
1052 static const struct {
1054 BOOL (*query_function)(glXGetProcAddressARB_t proc, const char *gl_version, const char *gl_extensions,
1055 const char *glx_version, const char *glx_extensions,
1056 const char *server_glx_extensions, const char *client_glx_extensions);
1057 } extension_list[] = {
1058 { "WGL_ARB_make_current_read", query_function_make_current_read },
1059 { "WGL_ARB_multisample", query_function_multisample },
1060 { "WGL_ARB_pbuffer", query_function_pbuffer },
1061 { "WGL_ARB_pixel_format" , query_function_pixel_format },
1062 { "WGL_ARB_render_texture", query_function_render_texture },
1063 { "WGL_EXT_swap_control", query_function_swap_control }
1066 /* Used to initialize the WGL extension string at DLL loading */
1067 void wgl_ext_initialize_extensions(Display *display, int screen, glXGetProcAddressARB_t proc, const char* disabled_extensions)
1069 int size = strlen(WGL_extensions_base);
1070 const char *glx_extensions = glXQueryExtensionsString(display, screen);
1071 const char *server_glx_extensions = glXQueryServerString(display, screen, GLX_EXTENSIONS);
1072 const char *client_glx_extensions = glXGetClientString(display, GLX_EXTENSIONS);
1073 const char *gl_extensions = (const char *) glGetString(GL_EXTENSIONS);
1074 const char *gl_version = (const char *) glGetString(GL_VERSION);
1075 const char *glx_version = glXGetClientString(display, GLX_VERSION);
1078 TRACE("GL version : %s.\n", debugstr_a(gl_version));
1079 TRACE("GL exts : %s.\n", debugstr_a(gl_extensions));
1080 TRACE("GLX exts : %s.\n", debugstr_a(glx_extensions));
1081 TRACE("Server GLX exts : %s.\n", debugstr_a(server_glx_extensions));
1082 TRACE("Client GLX exts : %s.\n", debugstr_a(client_glx_extensions));
1084 for (i = 0; i < (sizeof(extension_list) / sizeof(extension_list[0])); i++) {
1085 if (strstr(disabled_extensions, extension_list[i].name)) continue ; /* disabled by config, next */
1086 if (extension_list[i].query_function(proc,
1087 gl_version, gl_extensions,
1088 glx_version, glx_extensions,
1089 server_glx_extensions, client_glx_extensions)) {
1090 size += strlen(extension_list[i].name) + 1;
1094 /* For the moment, only 'base' extensions are supported. */
1095 WGL_extensions = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size + 1);
1096 if (WGL_extensions == NULL) {
1097 WGL_extensions = (char *) WGL_extensions_base;
1099 strcpy(WGL_extensions, WGL_extensions_base);
1100 for (i = 0; i < (sizeof(extension_list) / sizeof(extension_list[0])); i++) {
1101 if (strstr(disabled_extensions, extension_list[i].name)) continue ; /* disabled by config, next */
1102 if (extension_list[i].query_function(proc,
1103 gl_version, gl_extensions,
1104 glx_version, glx_extensions,
1105 server_glx_extensions, client_glx_extensions)) {
1106 strcat(WGL_extensions, " ");
1107 strcat(WGL_extensions, extension_list[i].name);
1112 TRACE("Supporting following WGL extensions : %s.\n", debugstr_a(WGL_extensions));
1115 void wgl_ext_finalize_extensions(void)
1117 if (WGL_extensions != WGL_extensions_base) {
1118 HeapFree(GetProcessHeap(), 0, WGL_extensions);
1123 /* these are located in wgl.c for convenience of implementation */
1124 BOOL WINAPI wglMakeContextCurrentARB(HDC,HDC,HGLRC);
1125 HDC WINAPI wglGetCurrentReadDCARB(void);
1129 * Putting this at the end to prevent having to write the prototypes :-)
1131 * @WARNING: this list must be ordered by name
1133 * @TODO: real handle caps on providing some func_init functions (third param, ex: to check extensions)
1135 WGL_extension wgl_extension_registry[] = {
1136 { "wglBindTexImageARB", (void *) wglBindTexImageARB, NULL, NULL},
1137 { "wglChoosePixelFormatARB", (void *) wglChoosePixelFormatARB, NULL, NULL},
1138 { "wglCreatePbufferARB", (void *) wglCreatePbufferARB, NULL, NULL},
1139 { "wglDestroyPbufferARB", (void *) wglDestroyPbufferARB, NULL, NULL},
1140 { "wglGetCurrentReadDCARB", (void *) wglGetCurrentReadDCARB, NULL, NULL},
1141 { "wglGetExtensionsStringARB", (void *) wglGetExtensionsStringARB, NULL, NULL},
1142 { "wglGetExtensionsStringEXT", (void *) wglGetExtensionsStringEXT, NULL, NULL},
1143 { "wglGetPbufferDCARB", (void *) wglGetPbufferDCARB, NULL, NULL},
1144 { "wglGetPixelFormatAttribfvARB", (void *) wglGetPixelFormatAttribfvARB, NULL, NULL},
1145 { "wglGetPixelFormatAttribivARB", (void *) wglGetPixelFormatAttribivARB, NULL, NULL},
1146 { "wglGetSwapIntervalEXT", (void *) wglGetSwapIntervalEXT, NULL, NULL},
1147 { "wglMakeContextCurrentARB", (void *) wglMakeContextCurrentARB, NULL, NULL },
1148 { "wglQueryPbufferARB", (void *) wglQueryPbufferARB, NULL, NULL},
1149 { "wglReleasePbufferDCARB", (void *) wglReleasePbufferDCARB, NULL, NULL},
1150 { "wglReleaseTexImageARB", (void *) wglReleaseTexImageARB, NULL, NULL},
1151 { "wglSetPbufferAttribARB", (void *) wglSetPbufferAttribARB, NULL, NULL},
1152 { "wglSwapIntervalEXT", (void *) wglSwapIntervalEXT, NULL, NULL}
1154 int wgl_extension_registry_size = sizeof(wgl_extension_registry) / sizeof(wgl_extension_registry[0]);