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"
37 #include "opengl_ext.h"
38 #include "wine/library.h"
39 #include "wine/debug.h"
41 WINE_DEFAULT_DEBUG_CHANNEL(opengl
);
44 /* x11drv GDI escapes */
45 #define X11DRV_ESCAPE 6789
46 enum x11drv_escape_codes
48 X11DRV_GET_DISPLAY
, /* get X11 display for a DC */
49 X11DRV_GET_DRAWABLE
, /* get current drawable for a DC */
50 X11DRV_GET_FONT
, /* get current X font for a DC */
51 X11DRV_SET_DRAWABLE
, /* set current drawable for a DC */
53 struct x11drv_escape_set_drawable
55 enum x11drv_escape_codes code
; /* escape code (X11DRV_SET_DRAWABLE) */
56 Drawable drawable
; /* X drawable */
57 int mode
; /* ClipByChildren or IncludeInferiors */
58 POINT org
; /* origin of DC relative to drawable */
59 POINT drawable_org
; /* origin of drawable relative to screen */
62 /* retrieve the X display to use on a given DC */
63 inline static Display
*get_display( HDC hdc
)
66 enum x11drv_escape_codes escape
= X11DRV_GET_DISPLAY
;
68 if (!ExtEscape( hdc
, X11DRV_ESCAPE
, sizeof(escape
), (LPCSTR
)&escape
,
69 sizeof(display
), (LPSTR
)&display
)) display
= NULL
;
72 inline static void set_drawable( HDC hdc
, Drawable drawable
)
74 struct x11drv_escape_set_drawable escape
;
76 escape
.code
= X11DRV_SET_DRAWABLE
;
77 escape
.drawable
= drawable
;
78 escape
.mode
= IncludeInferiors
;
79 escape
.org
.x
= escape
.org
.y
= 0;
80 escape
.drawable_org
.x
= escape
.drawable_org
.y
= 0;
82 ExtEscape( hdc
, X11DRV_ESCAPE
, sizeof(escape
), (LPCSTR
)&escape
, 0, NULL
);
85 /* Some WGL extensions... */
86 static const char *WGL_extensions_base
= "WGL_ARB_extensions_string WGL_EXT_extensions_string";
87 static char *WGL_extensions
= NULL
;
90 * Extensions-query functions
92 * @TODO: use a struct to handle parameters
94 BOOL
query_function_make_current_read(glXGetProcAddressARB_t proc
, const char *gl_version
, const char *gl_extensions
,
95 const char* glx_version
, const char *glx_extensions
,
96 const char *server_glx_extensions
, const char *client_glx_extensions
)
98 return 0 <= strcmp("1.3", glx_version
);
101 BOOL
query_function_multisample(glXGetProcAddressARB_t proc
, const char *gl_version
, const char *gl_extensions
,
102 const char* glx_version
, const char *glx_extensions
,
103 const char *server_glx_extensions
, const char *client_glx_extensions
)
105 return NULL
!= strstr(glx_extensions
, "GLX_ARB_multisample");
108 BOOL
query_function_pbuffer(glXGetProcAddressARB_t proc
, const char *gl_version
, const char *gl_extensions
,
109 const char* glx_version
, const char *glx_extensions
,
110 const char *server_glx_extensions
, const char *client_glx_extensions
)
112 TRACE("gl_version is: \"%s\"\n", gl_version
);
113 TRACE("glx_exts is: \"%s\"\n", glx_extensions
);
115 return 0 <= strcmp("1.3", glx_version
) || NULL
!= strstr(glx_extensions
, "GLX_SGIX_pbuffer");
118 BOOL
query_function_pixel_format(glXGetProcAddressARB_t proc
, const char *gl_version
, const char *gl_extensions
,
119 const char* glx_version
, const char *glx_extensions
,
120 const char *server_glx_extensions
, const char *client_glx_extensions
)
125 /** GLX_ARB_render_texture */
127 * http://oss.sgi.com/projects/ogl-sample/registry/ARB/wgl_render_texture.txt
128 * ~/tmp/ogl/ogl_offscreen_rendering_3
130 Bool (*p_glXBindTexImageARB
)(Display
*dpy
, GLXPbuffer pbuffer
, int buffer
);
131 Bool (*p_glXReleaseTexImageARB
)(Display
*dpy
, GLXPbuffer pbuffer
, int buffer
);
132 Bool (*p_glXDrawableAttribARB
)(Display
*dpy
, GLXDrawable draw
, const int *attribList
);
133 int use_render_texture_emulation
= 0;
134 BOOL
query_function_render_texture(glXGetProcAddressARB_t proc
, const char *gl_version
, const char *gl_extensions
,
135 const char* glx_version
, const char *glx_extensions
,
136 const char *server_glx_extensions
, const char *client_glx_extensions
)
138 BOOL bTest
= (0 <= strcmp("1.3", glx_version
) || NULL
!= strstr(glx_extensions
, "GLX_SGIX_pbuffer"));
140 if (NULL
!= strstr(glx_extensions
, "GLX_ARB_render_texture")) {
141 p_glXBindTexImageARB
= proc( (const GLubyte
*) "glXBindTexImageARB");
142 p_glXReleaseTexImageARB
= proc( (const GLubyte
*) "glXReleaseTexImageARB");
143 p_glXDrawableAttribARB
= proc( (const GLubyte
*) "glXDrawableAttribARB");
144 bTest
= (NULL
!= p_glXBindTexImageARB
&& NULL
!= p_glXReleaseTexImageARB
&& NULL
!= p_glXDrawableAttribARB
);
146 use_render_texture_emulation
= 0;
152 int (*p_glXSwapIntervalSGI
)(int);
153 BOOL
query_function_swap_control(glXGetProcAddressARB_t proc
, const char *gl_version
, const char *gl_extensions
,
154 const char* glx_version
, const char *glx_extensions
,
155 const char *server_glx_extensions
, const char *client_glx_extensions
)
157 BOOL bTest
= (0 <= strcmp("1.3", glx_version
) || NULL
!= strstr(glx_extensions
, "GLX_SGI_swap_control"));
159 p_glXSwapIntervalSGI
= proc( (const GLubyte
*) "glXSwapIntervalSGI");
160 bTest
= (NULL
!= p_glXSwapIntervalSGI
);
165 /***********************************************************************
166 * wglGetExtensionsStringEXT(OPENGL32.@)
168 const char * WINAPI
wglGetExtensionsStringEXT(void) {
169 TRACE("() returning \"%s\"\n", WGL_extensions
);
171 return WGL_extensions
;
174 /***********************************************************************
175 * wglGetExtensionsStringARB(OPENGL32.@)
177 const char * WINAPI
wglGetExtensionsStringARB(HDC hdc
) {
178 TRACE("() returning \"%s\"\n", WGL_extensions
);
180 return WGL_extensions
;
183 static int swap_interval
= 1;
185 /***********************************************************************
186 * wglSwapIntervalEXT(OPENGL32.@)
188 BOOL WINAPI
wglSwapIntervalEXT(int interval
) {
189 TRACE("(%d)\n", interval
);
190 swap_interval
= interval
;
191 if (NULL
!= p_glXSwapIntervalSGI
) {
192 return 0 == p_glXSwapIntervalSGI(interval
);
194 WARN("(): GLX_SGI_swap_control extension seems not supported \n");
198 /***********************************************************************
199 * wglGetSwapIntervalEXT(OPENGL32.@)
201 int WINAPI
wglGetSwapIntervalEXT(VOID
) {
203 return swap_interval
;
206 typedef struct wine_glpbuffer
{
215 int use_render_texture
;
216 GLuint texture_target
;
217 GLuint texture_bind_target
;
222 #define PUSH1(attribs,att) attribs[nAttribs++] = (att);
223 #define PUSH2(attribs,att,value) attribs[nAttribs++] = (att); attribs[nAttribs++] = (value);
225 #define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
226 #define WGL_DRAW_TO_WINDOW_ARB 0x2001
227 #define WGL_DRAW_TO_BITMAP_ARB 0x2002
228 #define WGL_ACCELERATION_ARB 0x2003
229 #define WGL_NEED_PALETTE_ARB 0x2004
230 #define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005
231 #define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006
232 #define WGL_SWAP_METHOD_ARB 0x2007
233 #define WGL_NUMBER_OVERLAYS_ARB 0x2008
234 #define WGL_NUMBER_UNDERLAYS_ARB 0x2009
235 #define WGL_TRANSPARENT_ARB 0x200A
236 #define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037
237 #define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038
238 #define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039
239 #define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A
240 #define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B
241 #define WGL_SHARE_DEPTH_ARB 0x200C
242 #define WGL_SHARE_STENCIL_ARB 0x200D
243 #define WGL_SHARE_ACCUM_ARB 0x200E
244 #define WGL_SUPPORT_GDI_ARB 0x200F
245 #define WGL_SUPPORT_OPENGL_ARB 0x2010
246 #define WGL_DOUBLE_BUFFER_ARB 0x2011
247 #define WGL_STEREO_ARB 0x2012
248 #define WGL_PIXEL_TYPE_ARB 0x2013
249 #define WGL_COLOR_BITS_ARB 0x2014
250 #define WGL_RED_BITS_ARB 0x2015
251 #define WGL_RED_SHIFT_ARB 0x2016
252 #define WGL_GREEN_BITS_ARB 0x2017
253 #define WGL_GREEN_SHIFT_ARB 0x2018
254 #define WGL_BLUE_BITS_ARB 0x2019
255 #define WGL_BLUE_SHIFT_ARB 0x201A
256 #define WGL_ALPHA_BITS_ARB 0x201B
257 #define WGL_ALPHA_SHIFT_ARB 0x201C
258 #define WGL_ACCUM_BITS_ARB 0x201D
259 #define WGL_ACCUM_RED_BITS_ARB 0x201E
260 #define WGL_ACCUM_GREEN_BITS_ARB 0x201F
261 #define WGL_ACCUM_BLUE_BITS_ARB 0x2020
262 #define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
263 #define WGL_DEPTH_BITS_ARB 0x2022
264 #define WGL_STENCIL_BITS_ARB 0x2023
265 #define WGL_AUX_BUFFERS_ARB 0x2024
267 #define WGL_NO_ACCELERATION_ARB 0x2025
268 #define WGL_GENERIC_ACCELERATION_ARB 0x2026
269 #define WGL_FULL_ACCELERATION_ARB 0x2027
271 #define WGL_PBUFFER_WIDTH_ARB 0x2034
272 #define WGL_PBUFFER_HEIGHT_ARB 0x2035
273 #define WGL_PBUFFER_LOST_ARB 0x2036
274 #define WGL_DRAW_TO_PBUFFER_ARB 0x202D
275 #define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E
276 #define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F
277 #define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030
278 #define WGL_PBUFFER_LARGEST_ARB 0x2033
280 #define WGL_TYPE_RGBA_ARB 0x202B
281 #define WGL_TYPE_COLORINDEX_ARB 0x202C
283 #define WGL_SAMPLE_BUFFERS_ARB 0x2041
284 #define WGL_SAMPLES_ARB 0x2042
289 /** GetPixelFormat/ChoosePixelFormat */
290 #define WGL_BIND_TO_TEXTURE_RGB_ARB 0x2070
291 #define WGL_BIND_TO_TEXTURE_RGBA_ARB 0x2071
292 /** CreatePbuffer / QueryPbuffer */
293 #define WGL_TEXTURE_FORMAT_ARB 0x2072
294 #define WGL_TEXTURE_TARGET_ARB 0x2073
295 #define WGL_MIPMAP_TEXTURE_ARB 0x2074
296 /** CreatePbuffer / QueryPbuffer */
297 #define WGL_TEXTURE_RGB_ARB 0x2075
298 #define WGL_TEXTURE_RGBA_ARB 0x2076
299 #define WGL_NO_TEXTURE_ARB 0x2077
300 /** CreatePbuffer / QueryPbuffer */
301 #define WGL_TEXTURE_CUBE_MAP_ARB 0x2078
302 #define WGL_TEXTURE_1D_ARB 0x2079
303 #define WGL_TEXTURE_2D_ARB 0x207A
304 #define WGL_NO_TEXTURE_ARB 0x2077
305 /** SetPbufferAttribARB/QueryPbufferARB parameters */
306 #define WGL_MIPMAP_LEVEL_ARB 0x207B
307 #define WGL_CUBE_MAP_FACE_ARB 0x207C
308 /** SetPbufferAttribARB/QueryPbufferARB attribs */
309 #define WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x207D
310 #define WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x207E
311 #define WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x207F
312 #define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x2080
313 #define WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x2081
314 #define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x2082
315 /** BindTexImageARB/ReleaseTexImageARB */
316 #define WGL_FRONT_LEFT_ARB 0x2083
317 #define WGL_FRONT_RIGHT_ARB 0x2084
318 #define WGL_BACK_LEFT_ARB 0x2085
319 #define WGL_BACK_RIGHT_ARB 0x2086
320 #define WGL_AUX0_ARB 0x2087
321 #define WGL_AUX1_ARB 0x2088
322 #define WGL_AUX2_ARB 0x2089
323 #define WGL_AUX3_ARB 0x208A
324 #define WGL_AUX4_ARB 0x208B
325 #define WGL_AUX5_ARB 0x208C
326 #define WGL_AUX6_ARB 0x208D
327 #define WGL_AUX7_ARB 0x208E
328 #define WGL_AUX8_ARB 0x208F
329 #define WGL_AUX9_ARB 0x2090
331 #if 0 /* not used yet */
332 static unsigned ConvertAttribGLXtoWGL(const int* iWGLAttr
, int* oGLXAttr
) {
333 unsigned nAttribs
= 0;
334 FIXME("not yet implemented!\n");
339 static unsigned ConvertAttribWGLtoGLX(const int* iWGLAttr
, int* oGLXAttr
, Wine_GLPBuffer
* pbuf
) {
340 unsigned nAttribs
= 0;
344 while (0 != iWGLAttr
[cur
]) {
345 TRACE("pAttr[%d] = %x\n", cur
, iWGLAttr
[cur
]);
347 switch (iWGLAttr
[cur
]) {
348 case WGL_COLOR_BITS_ARB
:
349 pop
= iWGLAttr
[++cur
];
350 PUSH2(oGLXAttr
, GLX_BUFFER_SIZE
, pop
);
351 TRACE("pAttr[%d] = WGL_COLOR_BITS_ARB: %d\n", cur
, pop
);
353 case WGL_BLUE_BITS_ARB
:
354 pop
= iWGLAttr
[++cur
];
355 PUSH2(oGLXAttr
, GLX_BLUE_SIZE
, pop
);
356 TRACE("pAttr[%d] = GLX_BLUE_SIZE: %d\n", cur
, pop
);
358 case WGL_RED_BITS_ARB
:
359 pop
= iWGLAttr
[++cur
];
360 TRACE("pAttr[%d] = GLX_RED_SIZE: %d\n", cur
, pop
);
361 PUSH2(oGLXAttr
, GLX_RED_SIZE
, pop
);
363 case WGL_GREEN_BITS_ARB
:
364 pop
= iWGLAttr
[++cur
];
365 TRACE("pAttr[%d] = GLX_GREEN_SIZE: %d\n", cur
, pop
);
366 PUSH2(oGLXAttr
, GLX_GREEN_SIZE
, pop
);
368 case WGL_ALPHA_BITS_ARB
:
369 pop
= iWGLAttr
[++cur
];
370 TRACE("pAttr[%d] = GLX_ALPHA_SIZE: %d\n", cur
, pop
);
371 PUSH2(oGLXAttr
, GLX_ALPHA_SIZE
, pop
);
373 case WGL_DEPTH_BITS_ARB
:
374 pop
= iWGLAttr
[++cur
];
375 TRACE("pAttr[%d] = GLX_DEPTH_SIZE: %d\n", cur
, pop
);
376 PUSH2(oGLXAttr
, GLX_DEPTH_SIZE
, pop
);
378 case WGL_STENCIL_BITS_ARB
:
379 pop
= iWGLAttr
[++cur
];
380 PUSH2(oGLXAttr
, GLX_STENCIL_SIZE
, pop
);
381 TRACE("pAttr[%d] = GLX_STENCIL_SIZE: %d\n", cur
, pop
);
383 case WGL_DOUBLE_BUFFER_ARB
:
384 pop
= iWGLAttr
[++cur
];
385 PUSH2(oGLXAttr
, GLX_DOUBLEBUFFER
, pop
);
386 TRACE("pAttr[%d] = GLX_DOUBLEBUFFER: %d\n", cur
, pop
);
389 case WGL_PIXEL_TYPE_ARB
:
390 pop
= iWGLAttr
[++cur
];
392 case WGL_TYPE_RGBA_ARB
: pop
= GLX_RGBA_BIT
; break ;
393 case WGL_TYPE_COLORINDEX_ARB
: pop
= GLX_COLOR_INDEX_BIT
; break ;
395 ERR("unexpected PixelType(%x)\n", pop
);
398 PUSH2(oGLXAttr
, GLX_RENDER_TYPE
, pop
);
399 TRACE("pAttr[%d] = GLX_RENDER_TYPE: %d\n", cur
, pop
);
402 case WGL_SUPPORT_GDI_ARB
:
403 case WGL_DRAW_TO_WINDOW_ARB
:
404 case WGL_DRAW_TO_BITMAP_ARB
:
405 case WGL_DRAW_TO_PBUFFER_ARB
:
406 pop
= iWGLAttr
[++cur
];
407 PUSH2(oGLXAttr
, GLX_X_RENDERABLE
, pop
);
408 TRACE("pAttr[%d] = GLX_RENDERABLE: %d\n", cur
, pop
);
411 case WGL_ACCELERATION_ARB
:
412 case WGL_SUPPORT_OPENGL_ARB
:
413 pop
= iWGLAttr
[++cur
];
414 /** nothing to do, if we are here, supposing support Accelerated OpenGL */
415 TRACE("pAttr[%d] = WGL_SUPPORT_OPENGL_ARB: %d\n", cur
, pop
);
418 case WGL_PBUFFER_LARGEST_ARB
:
419 pop
= iWGLAttr
[++cur
];
420 PUSH2(oGLXAttr
, GLX_LARGEST_PBUFFER
, pop
);
421 TRACE("pAttr[%d] = GLX_LARGEST_PBUFFER: %x\n", cur
, pop
);
424 case WGL_SAMPLE_BUFFERS_ARB
:
425 pop
= iWGLAttr
[++cur
];
426 PUSH2(oGLXAttr
, GLX_SAMPLE_BUFFERS_ARB
, pop
);
427 TRACE("pAttr[%d] = GLX_SAMPLE_BUFFERS_ARB: %x\n", cur
, pop
);
430 case WGL_SAMPLES_ARB
:
431 pop
= iWGLAttr
[++cur
];
432 PUSH2(oGLXAttr
, GLX_SAMPLES_ARB
, pop
);
433 TRACE("pAttr[%d] = GLX_SAMPLES_ARB: %x\n", cur
, pop
);
436 case WGL_TEXTURE_FORMAT_ARB
:
437 case WGL_TEXTURE_TARGET_ARB
:
438 case WGL_MIPMAP_TEXTURE_ARB
:
439 TRACE("WGL_render_texture Attributes: %x as %x\n", iWGLAttr
[cur
], iWGLAttr
[cur
+ 1]);
441 ERR("trying to use GLX_Pbuffer Attributes without Pbuffer (was %x)\n", iWGLAttr
[cur
]);
443 if (!use_render_texture_emulation
) {
444 ERR("trying to use WGL_render_texture Attributes without support (was %x)\n", iWGLAttr
[cur
]);
446 pop
= iWGLAttr
[++cur
];
450 FIXME("unsupported %x WGL Attribute\n", iWGLAttr
[cur
]);
458 GLboolean WINAPI
wglGetPixelFormatAttribivARB(HDC hdc
, int iPixelFormat
, int iLayerPlane
, UINT nAttributes
, const int *piAttributes
, int *piValues
)
460 Display
* display
= get_display( hdc
);
462 GLXFBConfig
* cfgs
= NULL
;
463 GLXFBConfig curCfg
= NULL
;
469 TRACE("(%p, %d, %d, %d, %p, %p)\n", hdc
, iPixelFormat
, iLayerPlane
, nAttributes
, piAttributes
, piValues
);
471 if (0 < iLayerPlane
) {
472 FIXME("unsupported iLayerPlane(%d) > 0, returns FALSE\n", iLayerPlane
);
476 cfgs
= glXGetFBConfigs(display
, DefaultScreen(display
), &nCfgs
);
478 ERR("no FB Configs found for display(%p)\n", display
);
482 for (i
= 0; i
< nAttributes
; ++i
) {
483 const int curWGLAttr
= piAttributes
[i
];
484 TRACE("pAttr[%d] = %x\n", i
, curWGLAttr
);
486 switch (curWGLAttr
) {
487 case WGL_NUMBER_PIXEL_FORMATS_ARB
:
491 case WGL_SUPPORT_OPENGL_ARB
:
492 piValues
[i
] = GL_TRUE
;
495 case WGL_ACCELERATION_ARB
:
496 curGLXAttr
= GLX_CONFIG_CAVEAT
;
497 if (nCfgs
< iPixelFormat
|| 0 >= iPixelFormat
) goto pix_error
;
498 curCfg
= cfgs
[iPixelFormat
- 1];
499 hTest
= glXGetFBConfigAttrib(display
, curCfg
, curGLXAttr
, &tmp
);
500 if (hTest
) goto get_error
;
502 case GLX_NONE
: piValues
[i
] = WGL_FULL_ACCELERATION_ARB
; break;
503 case GLX_SLOW_CONFIG
: piValues
[i
] = WGL_NO_ACCELERATION_ARB
; break;
504 case GLX_NON_CONFORMANT_CONFIG
: piValues
[i
] = WGL_FULL_ACCELERATION_ARB
; break;
506 ERR("unexpected Config Caveat(%x)\n", tmp
);
507 piValues
[i
] = WGL_NO_ACCELERATION_ARB
;
511 case WGL_TRANSPARENT_ARB
:
512 curGLXAttr
= GLX_TRANSPARENT_TYPE
;
513 if (nCfgs
< iPixelFormat
|| 0 >= iPixelFormat
) goto pix_error
;
514 curCfg
= cfgs
[iPixelFormat
- 1];
515 hTest
= glXGetFBConfigAttrib(display
, curCfg
, curGLXAttr
, &tmp
);
516 if (hTest
) goto get_error
;
517 piValues
[i
] = GL_FALSE
;
518 if (GLX_NONE
!= tmp
) piValues
[i
] = GL_TRUE
;
521 case WGL_PIXEL_TYPE_ARB
:
522 curGLXAttr
= GLX_RENDER_TYPE
;
523 if (nCfgs
< iPixelFormat
|| 0 >= iPixelFormat
) goto pix_error
;
524 curCfg
= cfgs
[iPixelFormat
- 1];
525 hTest
= glXGetFBConfigAttrib(display
, curCfg
, curGLXAttr
, &tmp
);
526 if (hTest
) goto get_error
;
528 case GLX_RGBA_BIT
: piValues
[i
] = WGL_TYPE_RGBA_ARB
; break;
529 case GLX_COLOR_INDEX_BIT
: piValues
[i
] = WGL_TYPE_COLORINDEX_ARB
; break ;
531 ERR("unexpected RenderType(%x)\n", tmp
);
532 piValues
[i
] = WGL_TYPE_RGBA_ARB
;
536 case WGL_COLOR_BITS_ARB
:
537 curGLXAttr
= GLX_BUFFER_SIZE
;
539 case WGL_BLUE_BITS_ARB
:
540 curGLXAttr
= GLX_BLUE_SIZE
;
542 case WGL_RED_BITS_ARB
:
543 curGLXAttr
= GLX_RED_SIZE
;
545 case WGL_GREEN_BITS_ARB
:
546 curGLXAttr
= GLX_GREEN_SIZE
;
548 case WGL_ALPHA_BITS_ARB
:
549 curGLXAttr
= GLX_ALPHA_SIZE
;
551 case WGL_DEPTH_BITS_ARB
:
552 curGLXAttr
= GLX_DEPTH_SIZE
;
554 case WGL_STENCIL_BITS_ARB
:
555 curGLXAttr
= GLX_STENCIL_SIZE
;
557 case WGL_DOUBLE_BUFFER_ARB
:
558 curGLXAttr
= GLX_DOUBLEBUFFER
;
561 curGLXAttr
= GLX_STEREO
;
563 case WGL_AUX_BUFFERS_ARB
:
564 curGLXAttr
= GLX_AUX_BUFFERS
;
567 case WGL_SUPPORT_GDI_ARB
:
568 case WGL_DRAW_TO_WINDOW_ARB
:
569 case WGL_DRAW_TO_BITMAP_ARB
:
570 case WGL_DRAW_TO_PBUFFER_ARB
:
571 curGLXAttr
= GLX_X_RENDERABLE
;
574 case WGL_PBUFFER_LARGEST_ARB
:
575 curGLXAttr
= GLX_LARGEST_PBUFFER
;
578 case WGL_SAMPLE_BUFFERS_ARB
:
579 curGLXAttr
= GLX_SAMPLE_BUFFERS_ARB
;
582 case WGL_SAMPLES_ARB
:
583 curGLXAttr
= GLX_SAMPLES_ARB
;
586 case WGL_BIND_TO_TEXTURE_RGB_ARB
:
587 case WGL_BIND_TO_TEXTURE_RGBA_ARB
:
588 if (!use_render_texture_emulation
) {
589 piValues
[i
] = GL_FALSE
;
592 curGLXAttr
= GLX_RENDER_TYPE
;
593 if (nCfgs
< iPixelFormat
|| 0 >= iPixelFormat
) goto pix_error
;
594 curCfg
= cfgs
[iPixelFormat
- 1];
595 hTest
= glXGetFBConfigAttrib(display
, curCfg
, curGLXAttr
, &tmp
);
596 if (hTest
) goto get_error
;
597 if (GLX_COLOR_INDEX_BIT
== tmp
) {
598 piValues
[i
] = GL_FALSE
;
601 curGLXAttr
= GLX_X_RENDERABLE
;
605 FIXME("unsupported %x WGL Attribute\n", curWGLAttr
);
608 if (0 != curGLXAttr
) {
609 if (nCfgs
< iPixelFormat
|| 0 >= iPixelFormat
) goto pix_error
;
610 curCfg
= cfgs
[iPixelFormat
- 1];
611 hTest
= glXGetFBConfigAttrib(display
, curCfg
, curGLXAttr
, piValues
+ i
);
612 if (hTest
) goto get_error
;
614 piValues
[i
] = GL_FALSE
;
621 ERR("(%p): unexpected failure on GetFBConfigAttrib(%x) returns FALSE\n", hdc
, curGLXAttr
);
626 ERR("(%p): unexpected iPixelFormat(%d) vs nFormats(%d), returns FALSE\n", hdc
, iPixelFormat
, nCfgs
);
631 GLboolean WINAPI
wglGetPixelFormatAttribfvARB(HDC hdc
, int iPixelFormat
, int iLayerPlane
, UINT nAttributes
, const int *piAttributes
, FLOAT
*pfValues
)
633 FIXME("(%p, %d, %d, %d, %p, %p): stub\n", hdc
, iPixelFormat
, iLayerPlane
, nAttributes
, piAttributes
, pfValues
);
637 * http://publib.boulder.ibm.com/infocenter/pseries/index.jsp?topic=/com.ibm.aix.doc/libs/openglrf/glXChooseFBConfig.htm
639 GLboolean WINAPI
wglChoosePixelFormatARB(HDC hdc
, const int *piAttribIList
, const FLOAT
*pfAttribFList
, UINT nMaxFormats
, int *piFormats
, UINT
*nNumFormats
)
641 Display
* display
= get_display( hdc
);
644 unsigned nAttribs
= 0;
646 GLXFBConfig
* cfgs
= NULL
;
651 GLXFBConfig
* cfgs_fmt
= NULL
;
658 TRACE("(%p, %p, %p, %d, %p, %p): hackish\n", hdc
, piAttribIList
, pfAttribFList
, nMaxFormats
, piFormats
, nNumFormats
);
659 if (NULL
!= pfAttribFList
) {
660 FIXME("unused pfAttribFList\n");
663 nAttribs
= ConvertAttribWGLtoGLX(piAttribIList
, attribs
, NULL
);
664 PUSH1(attribs
, None
);
666 cfgs
= glXChooseFBConfig(display
, DefaultScreen(display
), attribs
, &nCfgs
);
668 WARN("Compatible Pixel Format not found\n");
672 cfgs_fmt
= glXGetFBConfigs(display
, DefaultScreen(display
), &nCfgs_fmt
);
673 if (NULL
== cfgs_fmt
) {
674 ERR("Failed to get All FB Configs\n");
679 for (it
= 0; it
< nMaxFormats
&& it
< nCfgs
; ++it
) {
680 gl_test
= glXGetFBConfigAttrib(display
, cfgs
[it
], GLX_FBCONFIG_ID
, &fmt_id
);
682 ERR("Failed to retrieve FBCONFIG_ID from GLXFBConfig, expect problems.\n");
685 for (it_fmt
= 0; it_fmt
< nCfgs_fmt
; ++it_fmt
) {
686 gl_test
= glXGetFBConfigAttrib(display
, cfgs_fmt
[it_fmt
], GLX_FBCONFIG_ID
, &tmp_fmt_id
);
688 ERR("Failed to retrieve FBCONFIG_ID from GLXFBConfig, expect problems.\n");
691 if (fmt_id
== tmp_fmt_id
) {
692 piFormats
[pfmt_it
] = it_fmt
+ 1;
697 if (it_fmt
== nCfgs_fmt
) {
698 ERR("Failed to get valid fmt for %d. Try next.\n", it
);
701 TRACE("at %d/%d found FBCONFIG_ID(%d/%d)\n", it
+ 1, nCfgs
, piFormats
[it
], nCfgs_fmt
);
704 *nNumFormats
= pfmt_it
;
711 #define HPBUFFERARB void *
712 HPBUFFERARB WINAPI
wglCreatePbufferARB(HDC hdc
, int iPixelFormat
, int iWidth
, int iHeight
, const int *piAttribList
)
714 Wine_GLPBuffer
* object
= NULL
;
715 Display
* display
= get_display( hdc
);
716 GLXFBConfig
* cfgs
= NULL
;
719 unsigned nAttribs
= 0;
721 TRACE("(%p, %d, %d, %d, %p)\n", hdc
, iPixelFormat
, iWidth
, iHeight
, piAttribList
);
723 if (0 >= iPixelFormat
) {
724 ERR("(%p): unexpected iPixelFormat(%d) <= 0, returns NULL\n", hdc
, iPixelFormat
);
725 SetLastError(ERROR_INVALID_PIXEL_FORMAT
);
726 return NULL
; /* unespected error */
729 cfgs
= glXGetFBConfigs(display
, DefaultScreen(display
), &nCfgs
);
731 if (NULL
== cfgs
|| 0 == nCfgs
) {
732 ERR("(%p): Cannot get FB Configs for iPixelFormat(%d), returns NULL\n", hdc
, iPixelFormat
);
733 SetLastError(ERROR_INVALID_PIXEL_FORMAT
);
734 return NULL
; /* unespected error */
736 if (nCfgs
< iPixelFormat
) {
737 ERR("(%p): unexpected iPixelFormat(%d) > nFormats(%d), returns NULL\n", hdc
, iPixelFormat
, nCfgs
);
738 SetLastError(ERROR_INVALID_PIXEL_FORMAT
);
739 goto create_failed
; /* unespected error */
742 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(Wine_GLPBuffer
));
743 if (NULL
== object
) {
744 SetLastError(ERROR_NO_SYSTEM_RESOURCES
);
745 goto create_failed
; /* unespected error */
748 object
->display
= display
;
749 object
->width
= iWidth
;
750 object
->height
= iHeight
;
751 object
->pixelFormat
= iPixelFormat
;
753 nAttribs
= ConvertAttribWGLtoGLX(piAttribList
, attribs
, object
);
754 PUSH2(attribs
, GLX_PBUFFER_WIDTH
, iWidth
);
755 PUSH2(attribs
, GLX_PBUFFER_HEIGHT
, iHeight
);
756 PUSH1(attribs
, None
);
758 while (0 != *piAttribList
) {
760 switch (*piAttribList
) {
761 case WGL_TEXTURE_FORMAT_ARB
: {
762 if (!use_render_texture_emulation
) {
763 SetLastError(ERROR_INVALID_DATA
);
767 attr_v
= *piAttribList
;
768 TRACE("WGL_render_texture Attribute: WGL_TEXTURE_FORMAT_ARB as %x\n", attr_v
);
770 case WGL_TEXTURE_RGB_ARB
:
771 case WGL_TEXTURE_RGBA_ARB
:
772 case WGL_NO_TEXTURE_ARB
:
775 SetLastError(ERROR_INVALID_DATA
);
781 case WGL_TEXTURE_TARGET_ARB
: {
782 if (!use_render_texture_emulation
) {
783 SetLastError(ERROR_INVALID_DATA
);
787 attr_v
= *piAttribList
;
788 TRACE("WGL_render_texture Attribute: WGL_TEXTURE_TARGET_ARB as %x\n", attr_v
);
790 case WGL_TEXTURE_CUBE_MAP_ARB
: {
791 if (iWidth
!= iHeight
) {
792 SetLastError(ERROR_INVALID_DATA
);
795 object
->texture_target
= GL_TEXTURE_CUBE_MAP
;
796 object
->texture_bind_target
= GL_TEXTURE_CUBE_MAP
;
799 case WGL_TEXTURE_1D_ARB
: {
801 SetLastError(ERROR_INVALID_DATA
);
804 object
->texture_target
= GL_TEXTURE_1D
;
805 object
->texture_bind_target
= GL_TEXTURE_1D
;
808 case WGL_TEXTURE_2D_ARB
: {
809 object
->texture_target
= GL_TEXTURE_2D
;
810 object
->texture_bind_target
= GL_TEXTURE_2D
;
813 case WGL_NO_TEXTURE_ARB
:
816 SetLastError(ERROR_INVALID_DATA
);
822 case WGL_MIPMAP_TEXTURE_ARB
: {
823 if (!use_render_texture_emulation
) {
824 SetLastError(ERROR_INVALID_DATA
);
828 attr_v
= *piAttribList
;
829 TRACE("WGL_render_texture Attribute: WGL_MIPMAP_TEXTURE_ARB as %x\n", attr_v
);
831 SetLastError(ERROR_INVALID_DATA
);
841 object
->drawable
= glXCreatePbuffer(display
, cfgs
[iPixelFormat
- 1], attribs
);
842 TRACE("new Pbuffer drawable as %p\n", (void*) object
->drawable
);
843 if (!object
->drawable
) {
844 SetLastError(ERROR_NO_SYSTEM_RESOURCES
);
845 goto create_failed
; /* unespected error */
847 TRACE("->(%p)\n", object
);
851 return (HPBUFFERARB
) object
;
854 if (NULL
!= cfgs
) XFree(cfgs
);
855 if (NULL
!= object
) HeapFree(GetProcessHeap(), 0, object
);
856 TRACE("->(FAILED)\n");
857 return (HPBUFFERARB
) NULL
;
860 HDC WINAPI
wglGetPbufferDCARB(HPBUFFERARB hPbuffer
)
862 Wine_GLPBuffer
* object
= (Wine_GLPBuffer
*) hPbuffer
;
864 if (NULL
== object
) {
865 SetLastError(ERROR_INVALID_HANDLE
);
868 hDC
= CreateCompatibleDC(object
->hdc
);
869 set_drawable(hDC
, object
->drawable
); /* works ?? */
870 TRACE("(%p)->(%p)\n", hPbuffer
, hDC
);
874 int WINAPI
wglReleasePbufferDCARB(HPBUFFERARB hPbuffer
, HDC hdc
)
876 TRACE("(%p, %p)\n", hPbuffer
, hdc
);
881 GLboolean WINAPI
wglDestroyPbufferARB(HPBUFFERARB hPbuffer
)
883 Wine_GLPBuffer
* object
= (Wine_GLPBuffer
*) hPbuffer
;
884 TRACE("(%p)\n", hPbuffer
);
885 if (NULL
== object
) {
886 SetLastError(ERROR_INVALID_HANDLE
);
889 glXDestroyPbuffer(object
->display
, object
->drawable
);
890 HeapFree(GetProcessHeap(), 0, object
);
894 GLboolean WINAPI
wglQueryPbufferARB(HPBUFFERARB hPbuffer
, int iAttribute
, int *piValue
)
896 Wine_GLPBuffer
* object
= (Wine_GLPBuffer
*) hPbuffer
;
897 TRACE("(%p, 0x%x, %p)\n", hPbuffer
, iAttribute
, piValue
);
898 if (NULL
== object
) {
899 SetLastError(ERROR_INVALID_HANDLE
);
902 switch (iAttribute
) {
903 case WGL_PBUFFER_WIDTH_ARB
:
904 glXQueryDrawable(object
->display
, object
->drawable
, GLX_WIDTH
, (unsigned int*) piValue
);
906 case WGL_PBUFFER_HEIGHT_ARB
:
907 glXQueryDrawable(object
->display
, object
->drawable
, GLX_HEIGHT
, (unsigned int*) piValue
);
910 case WGL_PBUFFER_LOST_ARB
:
911 FIXME("unsupported WGL_PBUFFER_LOST_ARB (need glXSelectEvent/GLX_DAMAGED work)\n");
914 case WGL_TEXTURE_FORMAT_ARB
:
915 case WGL_TEXTURE_TARGET_ARB
:
916 case WGL_MIPMAP_TEXTURE_ARB
:
917 if (!object
->use_render_texture
) {
918 SetLastError(ERROR_INVALID_HANDLE
);
921 if (!use_render_texture_emulation
) {
922 SetLastError(ERROR_INVALID_DATA
);
923 return GL_FALSE
; /** how to FIX ? */
925 FIXME("unsupported WGL_ARB_render_texture attribute query for 0x%x\n", iAttribute
);
929 FIXME("unexpected attribute %x\n", iAttribute
);
936 GLboolean WINAPI
wglBindTexImageARB(HPBUFFERARB hPbuffer
, int iBuffer
)
938 Wine_GLPBuffer
* object
= (Wine_GLPBuffer
*) hPbuffer
;
939 TRACE("(%p, %d)\n", hPbuffer
, iBuffer
);
940 if (NULL
== object
) {
941 SetLastError(ERROR_INVALID_HANDLE
);
944 if (!object
->use_render_texture
) {
945 SetLastError(ERROR_INVALID_HANDLE
);
948 if (1 == use_render_texture_emulation
) {
951 if (NULL
!= p_glXBindTexImageARB
) {
952 return p_glXBindTexImageARB(object
->display
, object
->drawable
, iBuffer
);
957 GLboolean WINAPI
wglReleaseTexImageARB(HPBUFFERARB hPbuffer
, int iBuffer
)
959 Wine_GLPBuffer
* object
= (Wine_GLPBuffer
*) hPbuffer
;
960 TRACE("(%p, %d)\n", hPbuffer
, iBuffer
);
961 if (NULL
== object
) {
962 SetLastError(ERROR_INVALID_HANDLE
);
965 if (!object
->use_render_texture
) {
966 SetLastError(ERROR_INVALID_HANDLE
);
969 if (1 == use_render_texture_emulation
) {
970 GLint prev_binded_tex
;
971 glGetIntegerv(object
->texture_target
, &prev_binded_tex
);
972 glBindTexture(object
->texture_target
, object
->texture
);
973 if (GL_TEXTURE_1D
== object
->texture_target
) {
974 glCopyTexSubImage1D(object
->texture_bind_target
, object
->texture_level
, 0, 0, 0, object
->width
);
976 glCopyTexSubImage2D(object
->texture_bind_target
, object
->texture_level
, 0, 0, 0, 0, object
->width
, object
->height
);
978 glBindTexture(object
->texture_target
, prev_binded_tex
);
981 if (NULL
!= p_glXReleaseTexImageARB
) {
982 return p_glXReleaseTexImageARB(object
->display
, object
->drawable
, iBuffer
);
987 GLboolean WINAPI
wglSetPbufferAttribARB(HPBUFFERARB hPbuffer
, const int *piAttribList
)
989 Wine_GLPBuffer
* object
= (Wine_GLPBuffer
*) hPbuffer
;
990 WARN("(%p, %p): alpha-testing, report any problem\n", hPbuffer
, piAttribList
);
991 if (NULL
== object
) {
992 SetLastError(ERROR_INVALID_HANDLE
);
995 if (!object
->use_render_texture
) {
996 SetLastError(ERROR_INVALID_HANDLE
);
999 if (1 == use_render_texture_emulation
) {
1002 if (NULL
!= p_glXDrawableAttribARB
) {
1003 return p_glXDrawableAttribARB(object
->display
, object
->drawable
, piAttribList
);
1008 static const struct {
1010 BOOL (*query_function
)(glXGetProcAddressARB_t proc
, const char *gl_version
, const char *gl_extensions
,
1011 const char *glx_version
, const char *glx_extensions
,
1012 const char *server_glx_extensions
, const char *client_glx_extensions
);
1013 } extension_list
[] = {
1014 { "WGL_ARB_make_current_read", query_function_make_current_read
},
1015 { "WGL_ARB_multisample", query_function_multisample
},
1016 { "WGL_ARB_pbuffer", query_function_pbuffer
},
1017 { "WGL_ARB_pixel_format" , query_function_pixel_format
},
1018 { "WGL_ARB_render_texture", query_function_render_texture
},
1019 { "WGL_EXT_swap_control", query_function_swap_control
}
1022 /* Used to initialize the WGL extension string at DLL loading */
1023 void wgl_ext_initialize_extensions(Display
*display
, int screen
, glXGetProcAddressARB_t proc
, const char* disabled_extensions
)
1025 int size
= strlen(WGL_extensions_base
);
1026 const char *glx_extensions
= glXQueryExtensionsString(display
, screen
);
1027 const char *server_glx_extensions
= glXQueryServerString(display
, screen
, GLX_EXTENSIONS
);
1028 const char *client_glx_extensions
= glXGetClientString(display
, GLX_EXTENSIONS
);
1029 const char *gl_extensions
= (const char *) glGetString(GL_EXTENSIONS
);
1030 const char *gl_version
= (const char *) glGetString(GL_VERSION
);
1031 const char *glx_version
= glXGetClientString(display
, GLX_VERSION
);
1034 TRACE("GL version : %s.\n", debugstr_a(gl_version
));
1035 TRACE("GL exts : %s.\n", debugstr_a(gl_extensions
));
1036 TRACE("GLX exts : %s.\n", debugstr_a(glx_extensions
));
1037 TRACE("Server GLX exts : %s.\n", debugstr_a(server_glx_extensions
));
1038 TRACE("Client GLX exts : %s.\n", debugstr_a(client_glx_extensions
));
1040 for (i
= 0; i
< (sizeof(extension_list
) / sizeof(extension_list
[0])); i
++) {
1041 if (strstr(disabled_extensions
, extension_list
[i
].name
)) continue ; /* disabled by config, next */
1042 if (extension_list
[i
].query_function(proc
,
1043 gl_version
, gl_extensions
,
1044 glx_version
, glx_extensions
,
1045 server_glx_extensions
, client_glx_extensions
)) {
1046 size
+= strlen(extension_list
[i
].name
) + 1;
1050 /* For the moment, only 'base' extensions are supported. */
1051 WGL_extensions
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, size
+ 1);
1052 if (WGL_extensions
== NULL
) {
1053 WGL_extensions
= (char *) WGL_extensions_base
;
1055 strcpy(WGL_extensions
, WGL_extensions_base
);
1056 for (i
= 0; i
< (sizeof(extension_list
) / sizeof(extension_list
[0])); i
++) {
1057 if (strstr(disabled_extensions
, extension_list
[i
].name
)) continue ; /* disabled by config, next */
1058 if (extension_list
[i
].query_function(proc
,
1059 gl_version
, gl_extensions
,
1060 glx_version
, glx_extensions
,
1061 server_glx_extensions
, client_glx_extensions
)) {
1062 strcat(WGL_extensions
, " ");
1063 strcat(WGL_extensions
, extension_list
[i
].name
);
1068 TRACE("Supporting following WGL extensions : %s.\n", debugstr_a(WGL_extensions
));
1071 void wgl_ext_finalize_extensions(void)
1073 if (WGL_extensions
!= WGL_extensions_base
) {
1074 HeapFree(GetProcessHeap(), 0, WGL_extensions
);
1079 * Putting this at the end to prevent having to write the prototypes :-)
1081 * @WARNING: this list must be ordered by name
1083 * @TODO: real handle caps on providing some func_init functions (third param, ex: to check extensions)
1085 WGL_extension wgl_extension_registry
[] = {
1086 { "wglBindTexImageARB", (void *) wglBindTexImageARB
, NULL
, NULL
},
1087 { "wglChoosePixelFormatARB", (void *) wglChoosePixelFormatARB
, NULL
, NULL
},
1088 { "wglCreatePbufferARB", (void *) wglCreatePbufferARB
, NULL
, NULL
},
1089 { "wglDestroyPbufferARB", (void *) wglDestroyPbufferARB
, NULL
, NULL
},
1090 { "wglGetCurrentReadDCARB", (void *) wglGetCurrentReadDCARB
, NULL
, NULL
},
1091 { "wglGetExtensionsStringARB", (void *) wglGetExtensionsStringARB
, NULL
, NULL
},
1092 { "wglGetExtensionsStringEXT", (void *) wglGetExtensionsStringEXT
, NULL
, NULL
},
1093 { "wglGetPbufferDCARB", (void *) wglGetPbufferDCARB
, NULL
, NULL
},
1094 { "wglGetPixelFormatAttribfvARB", (void *) wglGetPixelFormatAttribfvARB
, NULL
, NULL
},
1095 { "wglGetPixelFormatAttribivARB", (void *) wglGetPixelFormatAttribivARB
, NULL
, NULL
},
1096 { "wglGetSwapIntervalEXT", (void *) wglGetSwapIntervalEXT
, NULL
, NULL
},
1097 { "wglMakeContextCurrentARB", (void *) wglMakeContextCurrentARB
, NULL
, NULL
},
1098 { "wglQueryPbufferARB", (void *) wglQueryPbufferARB
, NULL
, NULL
},
1099 { "wglReleasePbufferDCARB", (void *) wglReleasePbufferDCARB
, NULL
, NULL
},
1100 { "wglReleaseTexImageARB", (void *) wglReleaseTexImageARB
, NULL
, NULL
},
1101 { "wglSetPbufferAttribARB", (void *) wglSetPbufferAttribARB
, NULL
, NULL
},
1102 { "wglSwapIntervalEXT", (void *) wglSwapIntervalEXT
, NULL
, NULL
}
1104 int wgl_extension_registry_size
= sizeof(wgl_extension_registry
) / sizeof(wgl_extension_registry
[0]);