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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, 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(wgl
);
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 static 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 static 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 static 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 static 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 static Bool (*p_glXBindTexImageARB
)(Display
*dpy
, GLXPbuffer pbuffer
, int buffer
);
130 static Bool (*p_glXReleaseTexImageARB
)(Display
*dpy
, GLXPbuffer pbuffer
, int buffer
);
131 static Bool (*p_glXDrawableAttribARB
)(Display
*dpy
, GLXDrawable draw
, const int *attribList
);
132 static int use_render_texture_emulation
= 0;
133 static int use_render_texture_ati
= 0;
134 static 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
)
139 if (NULL
!= strstr(glx_extensions
, "GLX_ATI_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
);
146 TRACE("Active WGL_render_texture: found GLX_ATI_render_texture extensions\n");
147 use_render_texture_ati
= 1;
150 bTest
= (0 <= strcmp("1.3", glx_version
) || NULL
!= strstr(glx_extensions
, "GLX_SGIX_pbuffer"));
152 if (NULL
!= strstr(glx_extensions
, "GLX_ARB_render_texture")) {
153 p_glXBindTexImageARB
= proc( (const GLubyte
*) "glXBindTexImageARB");
154 p_glXReleaseTexImageARB
= proc( (const GLubyte
*) "glXReleaseTexImageARB");
155 p_glXDrawableAttribARB
= proc( (const GLubyte
*) "glXDrawableAttribARB");
156 TRACE("glXBindTexImageARB found as %p\n", p_glXBindTexImageARB
);
157 TRACE("glXReleaseTexImageARB found as %p\n", p_glXReleaseTexImageARB
);
158 TRACE("glXDrawableAttribARB found as %p\n", p_glXDrawableAttribARB
);
159 bTest
= (NULL
!= p_glXBindTexImageARB
&& NULL
!= p_glXReleaseTexImageARB
&& NULL
!= p_glXDrawableAttribARB
);
161 TRACE("Active WGL_render_texture: emulation using pbuffers\n");
162 use_render_texture_emulation
= 1;
168 static int (*p_glXSwapIntervalSGI
)(int);
169 static BOOL
query_function_swap_control(glXGetProcAddressARB_t proc
, const char *gl_version
, const char *gl_extensions
,
170 const char* glx_version
, const char *glx_extensions
,
171 const char *server_glx_extensions
, const char *client_glx_extensions
)
173 BOOL bTest
= (0 <= strcmp("1.3", glx_version
) || NULL
!= strstr(glx_extensions
, "GLX_SGI_swap_control"));
175 p_glXSwapIntervalSGI
= proc( (const GLubyte
*) "glXSwapIntervalSGI");
176 bTest
= (NULL
!= p_glXSwapIntervalSGI
);
181 /***********************************************************************
182 * wglGetExtensionsStringEXT(OPENGL32.@)
184 const char * WINAPI
wglGetExtensionsStringEXT(void) {
185 TRACE("() returning \"%s\"\n", WGL_extensions
);
187 return WGL_extensions
;
190 /***********************************************************************
191 * wglGetExtensionsStringARB(OPENGL32.@)
193 const char * WINAPI
wglGetExtensionsStringARB(HDC hdc
) {
194 TRACE("() returning \"%s\"\n", WGL_extensions
);
196 return WGL_extensions
;
199 static int swap_interval
= 1;
201 /***********************************************************************
202 * wglSwapIntervalEXT(OPENGL32.@)
204 BOOL WINAPI
wglSwapIntervalEXT(int interval
) {
205 TRACE("(%d)\n", interval
);
206 swap_interval
= interval
;
207 if (NULL
!= p_glXSwapIntervalSGI
) {
208 return 0 == p_glXSwapIntervalSGI(interval
);
210 WARN("(): GLX_SGI_swap_control extension seems not supported\n");
214 /***********************************************************************
215 * wglGetSwapIntervalEXT(OPENGL32.@)
217 int WINAPI
wglGetSwapIntervalEXT(VOID
) {
219 return swap_interval
;
222 typedef struct wine_glpbuffer
{
231 int use_render_texture
;
232 GLuint texture_target
;
233 GLuint texture_bind_target
;
242 #define PUSH1(attribs,att) attribs[nAttribs++] = (att);
243 #define PUSH2(attribs,att,value) attribs[nAttribs++] = (att); attribs[nAttribs++] = (value);
245 #define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
246 #define WGL_DRAW_TO_WINDOW_ARB 0x2001
247 #define WGL_DRAW_TO_BITMAP_ARB 0x2002
248 #define WGL_ACCELERATION_ARB 0x2003
249 #define WGL_NEED_PALETTE_ARB 0x2004
250 #define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005
251 #define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006
252 #define WGL_SWAP_METHOD_ARB 0x2007
253 #define WGL_NUMBER_OVERLAYS_ARB 0x2008
254 #define WGL_NUMBER_UNDERLAYS_ARB 0x2009
255 #define WGL_TRANSPARENT_ARB 0x200A
256 #define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037
257 #define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038
258 #define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039
259 #define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A
260 #define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B
261 #define WGL_SHARE_DEPTH_ARB 0x200C
262 #define WGL_SHARE_STENCIL_ARB 0x200D
263 #define WGL_SHARE_ACCUM_ARB 0x200E
264 #define WGL_SUPPORT_GDI_ARB 0x200F
265 #define WGL_SUPPORT_OPENGL_ARB 0x2010
266 #define WGL_DOUBLE_BUFFER_ARB 0x2011
267 #define WGL_STEREO_ARB 0x2012
268 #define WGL_PIXEL_TYPE_ARB 0x2013
269 #define WGL_COLOR_BITS_ARB 0x2014
270 #define WGL_RED_BITS_ARB 0x2015
271 #define WGL_RED_SHIFT_ARB 0x2016
272 #define WGL_GREEN_BITS_ARB 0x2017
273 #define WGL_GREEN_SHIFT_ARB 0x2018
274 #define WGL_BLUE_BITS_ARB 0x2019
275 #define WGL_BLUE_SHIFT_ARB 0x201A
276 #define WGL_ALPHA_BITS_ARB 0x201B
277 #define WGL_ALPHA_SHIFT_ARB 0x201C
278 #define WGL_ACCUM_BITS_ARB 0x201D
279 #define WGL_ACCUM_RED_BITS_ARB 0x201E
280 #define WGL_ACCUM_GREEN_BITS_ARB 0x201F
281 #define WGL_ACCUM_BLUE_BITS_ARB 0x2020
282 #define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
283 #define WGL_DEPTH_BITS_ARB 0x2022
284 #define WGL_STENCIL_BITS_ARB 0x2023
285 #define WGL_AUX_BUFFERS_ARB 0x2024
287 #define WGL_NO_ACCELERATION_ARB 0x2025
288 #define WGL_GENERIC_ACCELERATION_ARB 0x2026
289 #define WGL_FULL_ACCELERATION_ARB 0x2027
291 #define WGL_PBUFFER_WIDTH_ARB 0x2034
292 #define WGL_PBUFFER_HEIGHT_ARB 0x2035
293 #define WGL_PBUFFER_LOST_ARB 0x2036
294 #define WGL_DRAW_TO_PBUFFER_ARB 0x202D
295 #define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E
296 #define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F
297 #define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030
298 #define WGL_PBUFFER_LARGEST_ARB 0x2033
300 #define WGL_TYPE_RGBA_ARB 0x202B
301 #define WGL_TYPE_COLORINDEX_ARB 0x202C
303 #define WGL_SAMPLE_BUFFERS_ARB 0x2041
304 #define WGL_SAMPLES_ARB 0x2042
309 /** GetPixelFormat/ChoosePixelFormat */
310 #define WGL_BIND_TO_TEXTURE_RGB_ARB 0x2070
311 #define WGL_BIND_TO_TEXTURE_RGBA_ARB 0x2071
312 /** CreatePbuffer / QueryPbuffer */
313 #define WGL_TEXTURE_FORMAT_ARB 0x2072
314 #define WGL_TEXTURE_TARGET_ARB 0x2073
315 #define WGL_MIPMAP_TEXTURE_ARB 0x2074
316 /** CreatePbuffer / QueryPbuffer */
317 #define WGL_TEXTURE_RGB_ARB 0x2075
318 #define WGL_TEXTURE_RGBA_ARB 0x2076
319 #define WGL_NO_TEXTURE_ARB 0x2077
320 /** CreatePbuffer / QueryPbuffer */
321 #define WGL_TEXTURE_CUBE_MAP_ARB 0x2078
322 #define WGL_TEXTURE_1D_ARB 0x2079
323 #define WGL_TEXTURE_2D_ARB 0x207A
324 #define WGL_NO_TEXTURE_ARB 0x2077
325 /** SetPbufferAttribARB/QueryPbufferARB parameters */
326 #define WGL_MIPMAP_LEVEL_ARB 0x207B
327 #define WGL_CUBE_MAP_FACE_ARB 0x207C
328 /** SetPbufferAttribARB/QueryPbufferARB attribs */
329 #define WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x207D
330 #define WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x207E
331 #define WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x207F
332 #define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x2080
333 #define WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x2081
334 #define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x2082
335 /** BindTexImageARB/ReleaseTexImageARB */
336 #define WGL_FRONT_LEFT_ARB 0x2083
337 #define WGL_FRONT_RIGHT_ARB 0x2084
338 #define WGL_BACK_LEFT_ARB 0x2085
339 #define WGL_BACK_RIGHT_ARB 0x2086
340 #define WGL_AUX0_ARB 0x2087
341 #define WGL_AUX1_ARB 0x2088
342 #define WGL_AUX2_ARB 0x2089
343 #define WGL_AUX3_ARB 0x208A
344 #define WGL_AUX4_ARB 0x208B
345 #define WGL_AUX5_ARB 0x208C
346 #define WGL_AUX6_ARB 0x208D
347 #define WGL_AUX7_ARB 0x208E
348 #define WGL_AUX8_ARB 0x208F
349 #define WGL_AUX9_ARB 0x2090
352 * WGL_ATI_pixel_format_float / WGL_ARB_color_buffer_float
354 #define WGL_TYPE_RGBA_FLOAT_ATI 0x21A0
355 #define GL_RGBA_FLOAT_MODE_ATI 0x8820
356 #define GL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI 0x8835
357 #define GL_CLAMP_VERTEX_COLOR_ARB 0x891A
358 #define GL_CLAMP_FRAGMENT_COLOR_ARB 0x891B
359 #define GL_CLAMP_READ_COLOR_ARB 0x891C
360 /** GLX_ATI_pixel_format_float */
361 #define GLX_RGBA_FLOAT_ATI_BIT 0x00000100
362 /** GLX_ARB_pixel_format_float */
363 #define GLX_RGBA_FLOAT_BIT 0x00000004
364 #define GLX_RGBA_FLOAT_TYPE 0x20B9
365 /** GLX_ATI_render_texture */
366 #define GLX_BIND_TO_TEXTURE_RGB_ATI 0x9800
367 #define GLX_BIND_TO_TEXTURE_RGBA_ATI 0x9801
368 #define GLX_TEXTURE_FORMAT_ATI 0x9802
369 #define GLX_TEXTURE_TARGET_ATI 0x9803
370 #define GLX_MIPMAP_TEXTURE_ATI 0x9804
371 #define GLX_TEXTURE_RGB_ATI 0x9805
372 #define GLX_TEXTURE_RGBA_ATI 0x9806
373 #define GLX_NO_TEXTURE_ATI 0x9807
374 #define GLX_TEXTURE_CUBE_MAP_ATI 0x9808
375 #define GLX_TEXTURE_1D_ATI 0x9809
376 #define GLX_TEXTURE_2D_ATI 0x980A
377 #define GLX_MIPMAP_LEVEL_ATI 0x980B
378 #define GLX_CUBE_MAP_FACE_ATI 0x980C
379 #define GLX_TEXTURE_CUBE_MAP_POSITIVE_X_ATI 0x980D
380 #define GLX_TEXTURE_CUBE_MAP_NEGATIVE_X_ATI 0x980E
381 #define GLX_TEXTURE_CUBE_MAP_POSITIVE_Y_ATI 0x980F
382 #define GLX_TEXTURE_CUBE_MAP_NEGATIVE_Y_ATI 0x9810
383 #define GLX_TEXTURE_CUBE_MAP_POSITIVE_Z_ATI 0x9811
384 #define GLX_TEXTURE_CUBE_MAP_NEGATIVE_Z_ATI 0x9812
385 #define GLX_FRONT_LEFT_ATI 0x9813
386 #define GLX_FRONT_RIGHT_ATI 0x9814
387 #define GLX_BACK_LEFT_ATI 0x9815
388 #define GLX_BACK_RIGHT_ATI 0x9816
389 #define GLX_AUX0_ATI 0x9817
390 #define GLX_AUX1_ATI 0x9818
391 #define GLX_AUX2_ATI 0x9819
392 #define GLX_AUX3_ATI 0x981A
393 #define GLX_AUX4_ATI 0x981B
394 #define GLX_AUX5_ATI 0x981C
395 #define GLX_AUX6_ATI 0x981D
396 #define GLX_AUX7_ATI 0x981E
397 #define GLX_AUX8_ATI 0x981F
398 #define GLX_AUX9_ATI 0x9820
399 #define GLX_BIND_TO_TEXTURE_LUMINANCE_ATI 0x9821
400 #define GLX_BIND_TO_TEXTURE_INTENSITY_ATI 0x9822
404 #if 0 /* not used yet */
405 static int ConvertAttribGLXtoWGL(const int* iWGLAttr
, int* oGLXAttr
) {
407 FIXME("not yet implemented!\n");
412 static int ConvertAttribWGLtoGLX(const int* iWGLAttr
, int* oGLXAttr
, Wine_GLPBuffer
* pbuf
) {
417 int wantColorBits
= 0;
420 while (0 != iWGLAttr
[cur
]) {
421 TRACE("pAttr[%d] = %x\n", cur
, iWGLAttr
[cur
]);
423 switch (iWGLAttr
[cur
]) {
424 case WGL_COLOR_BITS_ARB
:
425 pop
= iWGLAttr
[++cur
];
426 wantColorBits
= pop
; /** see end */
428 case WGL_BLUE_BITS_ARB
:
429 pop
= iWGLAttr
[++cur
];
430 PUSH2(oGLXAttr
, GLX_BLUE_SIZE
, pop
);
431 TRACE("pAttr[%d] = GLX_BLUE_SIZE: %d\n", cur
, pop
);
433 case WGL_RED_BITS_ARB
:
434 pop
= iWGLAttr
[++cur
];
435 PUSH2(oGLXAttr
, GLX_RED_SIZE
, pop
);
436 TRACE("pAttr[%d] = GLX_RED_SIZE: %d\n", cur
, pop
);
438 case WGL_GREEN_BITS_ARB
:
439 pop
= iWGLAttr
[++cur
];
440 PUSH2(oGLXAttr
, GLX_GREEN_SIZE
, pop
);
441 TRACE("pAttr[%d] = GLX_GREEN_SIZE: %d\n", cur
, pop
);
443 case WGL_ALPHA_BITS_ARB
:
444 pop
= iWGLAttr
[++cur
];
446 PUSH2(oGLXAttr
, GLX_ALPHA_SIZE
, pop
);
447 TRACE("pAttr[%d] = GLX_ALPHA_SIZE: %d\n", cur
, pop
);
449 case WGL_DEPTH_BITS_ARB
:
450 pop
= iWGLAttr
[++cur
];
451 PUSH2(oGLXAttr
, GLX_DEPTH_SIZE
, pop
);
452 TRACE("pAttr[%d] = GLX_DEPTH_SIZE: %d\n", cur
, pop
);
454 case WGL_STENCIL_BITS_ARB
:
455 pop
= iWGLAttr
[++cur
];
456 PUSH2(oGLXAttr
, GLX_STENCIL_SIZE
, pop
);
457 TRACE("pAttr[%d] = GLX_STENCIL_SIZE: %d\n", cur
, pop
);
459 case WGL_DOUBLE_BUFFER_ARB
:
460 pop
= iWGLAttr
[++cur
];
461 PUSH2(oGLXAttr
, GLX_DOUBLEBUFFER
, pop
);
462 TRACE("pAttr[%d] = GLX_DOUBLEBUFFER: %d\n", cur
, pop
);
465 case WGL_PIXEL_TYPE_ARB
:
466 pop
= iWGLAttr
[++cur
];
468 case WGL_TYPE_COLORINDEX_ARB
: pop
= GLX_COLOR_INDEX_BIT
; isColor
= 1; break ;
469 case WGL_TYPE_RGBA_ARB
: pop
= GLX_RGBA_BIT
; break ;
470 case WGL_TYPE_RGBA_FLOAT_ATI
: pop
= GLX_RGBA_FLOAT_ATI_BIT
; break ;
472 ERR("unexpected PixelType(%x)\n", pop
);
475 PUSH2(oGLXAttr
, GLX_RENDER_TYPE
, pop
);
476 TRACE("pAttr[%d] = GLX_RENDER_TYPE: %d\n", cur
, pop
);
479 case WGL_SUPPORT_GDI_ARB
:
480 pop
= iWGLAttr
[++cur
];
481 PUSH2(oGLXAttr
, GLX_X_RENDERABLE
, pop
);
482 TRACE("pAttr[%d] = GLX_RENDERABLE: %d\n", cur
, pop
);
485 case WGL_DRAW_TO_BITMAP_ARB
:
486 pop
= iWGLAttr
[++cur
];
487 PUSH2(oGLXAttr
, GLX_X_RENDERABLE
, pop
);
488 TRACE("pAttr[%d] = GLX_RENDERABLE: %d\n", cur
, pop
);
490 PUSH2(oGLXAttr
, GLX_DRAWABLE_TYPE
, GLX_PIXMAP_BIT
);
491 TRACE("pAttr[%d] = GLX_DRAWABLE_TYPE: GLX_PIXMAP_BIT\n", cur
);
495 case WGL_DRAW_TO_WINDOW_ARB
:
496 pop
= iWGLAttr
[++cur
];
498 PUSH2(oGLXAttr
, GLX_DRAWABLE_TYPE
, GLX_WINDOW_BIT
);
499 TRACE("pAttr[%d] = GLX_DRAWABLE_TYPE: GLX_WINDOW_BIT\n", cur
);
503 case WGL_DRAW_TO_PBUFFER_ARB
:
504 pop
= iWGLAttr
[++cur
];
505 PUSH2(oGLXAttr
, GLX_X_RENDERABLE
, pop
);
506 TRACE("pAttr[%d] = GLX_RENDERABLE: %d\n", cur
, pop
);
508 PUSH2(oGLXAttr
, GLX_DRAWABLE_TYPE
, GLX_PBUFFER_BIT
);
509 TRACE("pAttr[%d] = GLX_DRAWABLE_TYPE: GLX_PBUFFER_BIT\n", cur
);
513 case WGL_ACCELERATION_ARB
:
514 case WGL_SUPPORT_OPENGL_ARB
:
515 pop
= iWGLAttr
[++cur
];
516 /** nothing to do, if we are here, supposing support Accelerated OpenGL */
517 TRACE("pAttr[%d] = WGL_SUPPORT_OPENGL_ARB: %d\n", cur
, pop
);
520 case WGL_PBUFFER_LARGEST_ARB
:
521 pop
= iWGLAttr
[++cur
];
522 PUSH2(oGLXAttr
, GLX_LARGEST_PBUFFER
, pop
);
523 TRACE("pAttr[%d] = GLX_LARGEST_PBUFFER: %x\n", cur
, pop
);
526 case WGL_SAMPLE_BUFFERS_ARB
:
527 pop
= iWGLAttr
[++cur
];
528 PUSH2(oGLXAttr
, GLX_SAMPLE_BUFFERS_ARB
, pop
);
529 TRACE("pAttr[%d] = GLX_SAMPLE_BUFFERS_ARB: %x\n", cur
, pop
);
532 case WGL_SAMPLES_ARB
:
533 pop
= iWGLAttr
[++cur
];
534 PUSH2(oGLXAttr
, GLX_SAMPLES_ARB
, pop
);
535 TRACE("pAttr[%d] = GLX_SAMPLES_ARB: %x\n", cur
, pop
);
538 case WGL_TEXTURE_FORMAT_ARB
:
539 case WGL_TEXTURE_TARGET_ARB
:
540 case WGL_MIPMAP_TEXTURE_ARB
:
541 TRACE("WGL_render_texture Attributes: %x as %x\n", iWGLAttr
[cur
], iWGLAttr
[cur
+ 1]);
542 pop
= iWGLAttr
[++cur
];
544 ERR("trying to use GLX_Pbuffer Attributes without Pbuffer (was %x)\n", iWGLAttr
[cur
]);
546 if (use_render_texture_ati
) {
547 /** nothing to do here */
549 else if (!use_render_texture_emulation
) {
550 if (WGL_NO_TEXTURE_ARB
!= pop
) {
551 ERR("trying to use WGL_render_texture Attributes without support (was %x)\n", iWGLAttr
[cur
]);
552 return -1; /** error: don't support it */
554 PUSH2(oGLXAttr
, GLX_X_RENDERABLE
, pop
);
555 PUSH2(oGLXAttr
, GLX_DRAWABLE_TYPE
, GLX_PBUFFER_BIT
);
560 case WGL_BIND_TO_TEXTURE_RGB_ARB
:
561 case WGL_BIND_TO_TEXTURE_RGBA_ARB
:
562 pop
= iWGLAttr
[++cur
];
563 /** cannot be converted, see direct handling on
564 * - wglGetPixelFormatAttribivARB
565 * TODO: wglChoosePixelFormat
570 FIXME("unsupported %x WGL Attribute\n", iWGLAttr
[cur
]);
577 * Trick as WGL_COLOR_BITS_ARB != GLX_BUFFER_SIZE
578 * WGL_COLOR_BITS_ARB + WGL_ALPHA_BITS_ARB == GLX_BUFFER_SIZE
581 * The number of color bitplanes in each color buffer. For RGBA
582 * pixel types, it is the size of the color buffer, excluding the
583 * alpha bitplanes. For color-index pixels, it is the size of the
584 * color index buffer.
587 * This attribute defines the number of bits per color buffer.
588 * For GLX FBConfigs that correspond to a PseudoColor or StaticColor visual,
589 * this is equal to the depth value reported in the X11 visual.
590 * For GLX FBConfigs that correspond to TrueColor or DirectColor visual,
591 * this is the sum of GLX_RED_SIZE, GLX_GREEN_SIZE, GLX_BLUE_SIZE, and GLX_ALPHA_SIZE.
594 if (0 < wantColorBits
) {
596 wantColorBits
+= sz_alpha
;
598 if (32 < wantColorBits
) {
599 ERR("buggy %d GLX_BUFFER_SIZE default to 32\n", wantColorBits
);
602 PUSH2(oGLXAttr
, GLX_BUFFER_SIZE
, wantColorBits
);
603 TRACE("pAttr[%d] = WGL_COLOR_BITS_ARB: %d\n", cur
, wantColorBits
);
609 GLboolean WINAPI
wglGetPixelFormatAttribivARB(HDC hdc
, int iPixelFormat
, int iLayerPlane
, UINT nAttributes
, const int *piAttributes
, int *piValues
)
611 Display
* display
= get_display( hdc
);
613 GLXFBConfig
* cfgs
= NULL
;
614 GLXFBConfig curCfg
= NULL
;
622 TRACE("(%p, %d, %d, %d, %p, %p)\n", hdc
, iPixelFormat
, iLayerPlane
, nAttributes
, piAttributes
, piValues
);
624 if (0 < iLayerPlane
) {
625 FIXME("unsupported iLayerPlane(%d) > 0, returns FALSE\n", iLayerPlane
);
629 cfgs
= glXGetFBConfigs(display
, DefaultScreen(display
), &nCfgs
);
631 ERR("no FB Configs found for display(%p)\n", display
);
635 /* Convert the WGL pixelformat to a GLX one, if this fails then most likely the iPixelFormat isn't supoprted.
636 * We don't have to fail yet as a program can specify an invaled iPixelFormat (lets say 0) if it wants to query
637 * the number of supported WGL formats. Whether the iPixelFormat is valid is handled in the for-loop below. */
638 if(!ConvertPixelFormatWGLtoGLX(display
, iPixelFormat
, &fmt_index
, &nWGLFormats
)) {
639 ERR("Unable to convert iPixelFormat %d to a GLX one, expect problems!\n", iPixelFormat
);
642 for (i
= 0; i
< nAttributes
; ++i
) {
643 const int curWGLAttr
= piAttributes
[i
];
644 TRACE("pAttr[%d] = %x\n", i
, curWGLAttr
);
646 switch (curWGLAttr
) {
647 case WGL_NUMBER_PIXEL_FORMATS_ARB
:
648 piValues
[i
] = nWGLFormats
;
651 case WGL_SUPPORT_OPENGL_ARB
:
652 piValues
[i
] = GL_TRUE
;
655 case WGL_ACCELERATION_ARB
:
656 curGLXAttr
= GLX_CONFIG_CAVEAT
;
657 if (nCfgs
< iPixelFormat
|| 0 >= iPixelFormat
) goto pix_error
;
658 curCfg
= cfgs
[iPixelFormat
- 1];
659 hTest
= glXGetFBConfigAttrib(display
, curCfg
, curGLXAttr
, &tmp
);
660 if (hTest
) goto get_error
;
662 case GLX_NONE
: piValues
[i
] = WGL_FULL_ACCELERATION_ARB
; break;
663 case GLX_SLOW_CONFIG
: piValues
[i
] = WGL_NO_ACCELERATION_ARB
; break;
664 case GLX_NON_CONFORMANT_CONFIG
: piValues
[i
] = WGL_FULL_ACCELERATION_ARB
; break;
666 ERR("unexpected Config Caveat(%x)\n", tmp
);
667 piValues
[i
] = WGL_NO_ACCELERATION_ARB
;
671 case WGL_TRANSPARENT_ARB
:
672 curGLXAttr
= GLX_TRANSPARENT_TYPE
;
673 /* Check if the format is supported by checking if iPixelFormat isn't larger than the max number of
674 * supported WGLFormats and also check if the GLX fmt_index is valid. */
675 if((iPixelFormat
> nWGLFormats
) || (fmt_index
> nCfgs
)) goto pix_error
;
676 curCfg
= cfgs
[fmt_index
];
677 hTest
= glXGetFBConfigAttrib(display
, curCfg
, curGLXAttr
, &tmp
);
678 if (hTest
) goto get_error
;
679 piValues
[i
] = GL_FALSE
;
680 if (GLX_NONE
!= tmp
) piValues
[i
] = GL_TRUE
;
683 case WGL_PIXEL_TYPE_ARB
:
684 curGLXAttr
= GLX_RENDER_TYPE
;
685 /* Check if the format is supported by checking if iPixelFormat isn't larger than the max number of
686 * supported WGLFormats and also check if the GLX fmt_index is valid. */
687 if((iPixelFormat
> nWGLFormats
) || (fmt_index
> nCfgs
)) goto pix_error
;
688 curCfg
= cfgs
[fmt_index
];
689 hTest
= glXGetFBConfigAttrib(display
, curCfg
, curGLXAttr
, &tmp
);
690 if (hTest
) goto get_error
;
691 TRACE("WGL_PIXEL_TYPE_ARB: GLX_RENDER_TYPE = 0x%x\n", tmp
);
692 if (tmp
& GLX_RGBA_BIT
) { piValues
[i
] = WGL_TYPE_RGBA_ARB
; }
693 else if (tmp
& GLX_COLOR_INDEX_BIT
) { piValues
[i
] = WGL_TYPE_COLORINDEX_ARB
; }
694 else if (tmp
& GLX_RGBA_FLOAT_BIT
) { piValues
[i
] = WGL_TYPE_RGBA_FLOAT_ATI
; }
695 else if (tmp
& GLX_RGBA_FLOAT_ATI_BIT
) { piValues
[i
] = WGL_TYPE_RGBA_FLOAT_ATI
; }
697 ERR("unexpected RenderType(%x)\n", tmp
);
698 piValues
[i
] = WGL_TYPE_RGBA_ARB
;
702 case WGL_COLOR_BITS_ARB
:
703 /** see ConvertAttribWGLtoGLX for explain */
704 /* Check if the format is supported by checking if iPixelFormat isn't larger than the max number of
705 * supported WGLFormats and also check if the GLX fmt_index is valid. */
706 if((iPixelFormat
> nWGLFormats
) || (fmt_index
> nCfgs
)) goto pix_error
;
707 curCfg
= cfgs
[fmt_index
];
708 hTest
= glXGetFBConfigAttrib(display
, curCfg
, GLX_BUFFER_SIZE
, piValues
+ i
);
709 if (hTest
) goto get_error
;
710 TRACE("WGL_COLOR_BITS_ARB: GLX_BUFFER_SIZE = %d\n", piValues
[i
]);
711 hTest
= glXGetFBConfigAttrib(display
, curCfg
, GLX_ALPHA_SIZE
, &tmp
);
712 if (hTest
) goto get_error
;
713 TRACE("WGL_COLOR_BITS_ARB: GLX_ALPHA_SIZE = %d\n", tmp
);
714 piValues
[i
] = piValues
[i
] - tmp
;
717 case WGL_BIND_TO_TEXTURE_RGB_ARB
:
718 if (use_render_texture_ati
) {
719 curGLXAttr
= GLX_BIND_TO_TEXTURE_RGB_ATI
;
722 case WGL_BIND_TO_TEXTURE_RGBA_ARB
:
723 if (use_render_texture_ati
) {
724 curGLXAttr
= GLX_BIND_TO_TEXTURE_RGBA_ATI
;
727 if (!use_render_texture_emulation
) {
728 piValues
[i
] = GL_FALSE
;
731 curGLXAttr
= GLX_RENDER_TYPE
;
732 /* Check if the format is supported by checking if iPixelFormat isn't larger than the max number of
733 * supported WGLFormats and also check if the GLX fmt_index is valid. */
734 if((iPixelFormat
> nWGLFormats
) || (fmt_index
> nCfgs
)) goto pix_error
;
735 curCfg
= cfgs
[fmt_index
];
736 hTest
= glXGetFBConfigAttrib(display
, curCfg
, curGLXAttr
, &tmp
);
737 if (hTest
) goto get_error
;
738 if (GLX_COLOR_INDEX_BIT
== tmp
) {
739 piValues
[i
] = GL_FALSE
;
742 hTest
= glXGetFBConfigAttrib(display
, curCfg
, GLX_DRAWABLE_TYPE
, &tmp
);
743 if (hTest
) goto get_error
;
744 piValues
[i
] = (tmp
& GLX_PBUFFER_BIT
) ? GL_TRUE
: GL_FALSE
;
747 case WGL_BLUE_BITS_ARB
:
748 curGLXAttr
= GLX_BLUE_SIZE
;
750 case WGL_RED_BITS_ARB
:
751 curGLXAttr
= GLX_RED_SIZE
;
753 case WGL_GREEN_BITS_ARB
:
754 curGLXAttr
= GLX_GREEN_SIZE
;
756 case WGL_ALPHA_BITS_ARB
:
757 curGLXAttr
= GLX_ALPHA_SIZE
;
759 case WGL_DEPTH_BITS_ARB
:
760 curGLXAttr
= GLX_DEPTH_SIZE
;
762 case WGL_STENCIL_BITS_ARB
:
763 curGLXAttr
= GLX_STENCIL_SIZE
;
765 case WGL_DOUBLE_BUFFER_ARB
:
766 curGLXAttr
= GLX_DOUBLEBUFFER
;
769 curGLXAttr
= GLX_STEREO
;
771 case WGL_AUX_BUFFERS_ARB
:
772 curGLXAttr
= GLX_AUX_BUFFERS
;
775 case WGL_SUPPORT_GDI_ARB
:
776 case WGL_DRAW_TO_WINDOW_ARB
:
777 case WGL_DRAW_TO_BITMAP_ARB
:
778 case WGL_DRAW_TO_PBUFFER_ARB
:
779 curGLXAttr
= GLX_X_RENDERABLE
;
782 case WGL_PBUFFER_LARGEST_ARB
:
783 curGLXAttr
= GLX_LARGEST_PBUFFER
;
786 case WGL_SAMPLE_BUFFERS_ARB
:
787 curGLXAttr
= GLX_SAMPLE_BUFFERS_ARB
;
790 case WGL_SAMPLES_ARB
:
791 curGLXAttr
= GLX_SAMPLES_ARB
;
795 FIXME("unsupported %x WGL Attribute\n", curWGLAttr
);
798 if (0 != curGLXAttr
) {
799 /* Check if the format is supported by checking if iPixelFormat isn't larger than the max number of
800 * supported WGLFormats and also check if the GLX fmt_index is valid. */
801 if((iPixelFormat
> 0) && ((iPixelFormat
> nWGLFormats
) || (fmt_index
> nCfgs
))) goto pix_error
;
802 curCfg
= cfgs
[fmt_index
];
803 hTest
= glXGetFBConfigAttrib(display
, curCfg
, curGLXAttr
, piValues
+ i
);
804 if (hTest
) goto get_error
;
806 piValues
[i
] = GL_FALSE
;
813 ERR("(%p): unexpected failure on GetFBConfigAttrib(%x) returns FALSE\n", hdc
, curGLXAttr
);
818 ERR("(%p): unexpected iPixelFormat(%d) vs nFormats(%d), returns FALSE\n", hdc
, iPixelFormat
, nCfgs
);
823 GLboolean WINAPI
wglGetPixelFormatAttribfvARB(HDC hdc
, int iPixelFormat
, int iLayerPlane
, UINT nAttributes
, const int *piAttributes
, FLOAT
*pfValues
)
825 FIXME("(%p, %d, %d, %d, %p, %p): stub\n", hdc
, iPixelFormat
, iLayerPlane
, nAttributes
, piAttributes
, pfValues
);
829 * http://publib.boulder.ibm.com/infocenter/pseries/index.jsp?topic=/com.ibm.aix.doc/libs/openglrf/glXChooseFBConfig.htm
831 GLboolean WINAPI
wglChoosePixelFormatARB(HDC hdc
, const int *piAttribIList
, const FLOAT
*pfAttribFList
, UINT nMaxFormats
, int *piFormats
, UINT
*nNumFormats
)
833 Display
* display
= get_display( hdc
);
837 GLboolean res
= FALSE
;
839 /* We need the visualid to check if the format is suitable */
840 VisualID visualid
= (VisualID
)GetPropA( GetDesktopWindow(), "__wine_x11_visual_id" );
842 GLXFBConfig
* cfgs
= NULL
;
847 GLXFBConfig
* cfgs_fmt
= NULL
;
854 int offscreen_index
= 1; /* Start at one because we allways have a main visual at iPixelFormat=1 */
856 TRACE("(%p, %p, %p, %d, %p, %p): hackish\n", hdc
, piAttribIList
, pfAttribFList
, nMaxFormats
, piFormats
, nNumFormats
);
857 if (NULL
!= pfAttribFList
) {
858 FIXME("unused pfAttribFList\n");
861 nAttribs
= ConvertAttribWGLtoGLX(piAttribIList
, attribs
, NULL
);
862 if (-1 == nAttribs
) {
863 WARN("Cannot convert WGL to GLX attributes\n");
866 PUSH1(attribs
, None
);
868 /* Search for FB configurations matching the requirements in attribs */
869 cfgs
= glXChooseFBConfig(display
, DefaultScreen(display
), attribs
, &nCfgs
);
871 WARN("Compatible Pixel Format not found\n");
875 /* Get a list of all FB configurations */
876 cfgs_fmt
= glXGetFBConfigs(display
, DefaultScreen(display
), &nCfgs_fmt
);
877 if (NULL
== cfgs_fmt
) {
878 ERR("Failed to get All FB Configs\n");
883 /* Loop through all matching formats and check if they are suitable.
884 * Note that this function should at max return nMaxFormats different formats */
885 for (it
= 0; pfmt_it
< nMaxFormats
&& it
< nCfgs
; ++it
) {
886 gl_test
= glXGetFBConfigAttrib(display
, cfgs
[it
], GLX_FBCONFIG_ID
, &fmt_id
);
888 ERR("Failed to retrieve FBCONFIG_ID from GLXFBConfig, expect problems.\n");
892 gl_test
= glXGetFBConfigAttrib(display
, cfgs
[it
], GLX_VISUAL_ID
, &tmp_vis_id
);
894 ERR("Failed to retrieve VISUAL_ID from GLXFBConfig, expect problems.\n");
898 /* When the visualid of the GLXFBConfig matches the one of the main visual we have found our
899 * only supported onscreen rendering format. This format has a WGL index of 1. */
900 if(tmp_vis_id
== visualid
) {
901 piFormats
[pfmt_it
] = 1;
904 TRACE("Found compatible GLXFBConfig 0x%x with WGL index 1\n", fmt_id
);
907 /* Only continue with this loop for offscreen rendering formats (visualid = 0) */
908 else if(tmp_vis_id
!= 0) {
909 TRACE("Discarded GLXFBConfig %0x with VisualID %x because the visualid is not the same as our main visual (%lx)\n", fmt_id
, tmp_vis_id
, visualid
);
913 /* Find the index of the found format in the whole format table */
914 for (it_fmt
= 0; it_fmt
< nCfgs_fmt
; ++it_fmt
) {
915 gl_test
= glXGetFBConfigAttrib(display
, cfgs_fmt
[it_fmt
], GLX_FBCONFIG_ID
, &tmp_fmt_id
);
917 ERR("Failed to retrieve FBCONFIG_ID from GLXFBConfig, expect problems.\n");
920 gl_test
= glXGetFBConfigAttrib(display
, cfgs
[it
], GLX_VISUAL_ID
, &tmp_vis_id
);
922 ERR("Failed to retrieve VISUAL_ID from GLXFBConfig, expect problems.\n");
925 /* The format of Wine's main visual is stored at index 1 of our WGL format table.
926 * At higher indices we store offscreen rendering formats (visualid=0). Below we calculate
927 * the index of the offscreen format. We do this by counting the number of offscreen formats
928 * which we see upto reaching our target format. */
932 /* We have found the format in the table (note the format is offscreen) */
933 if (fmt_id
== tmp_fmt_id
) {
936 piFormats
[pfmt_it
] = offscreen_index
+ 1; /* Add 1 to get a one-based index */
938 glXGetFBConfigAttrib(display
, cfgs_fmt
[it_fmt
], GLX_ALPHA_SIZE
, &tmp
);
939 TRACE("ALPHA_SIZE of FBCONFIG_ID(%d/%d) found as '%d'\n", it_fmt
+ 1, nCfgs_fmt
, tmp
);
943 if (it_fmt
== nCfgs_fmt
) {
944 ERR("Failed to get valid fmt for %d. Try next.\n", it
);
947 TRACE("at %d/%d found FBCONFIG_ID(%d/%d)\n", it
+ 1, nCfgs
, piFormats
[it
], nCfgs_fmt
);
950 *nNumFormats
= pfmt_it
;
957 #define HPBUFFERARB void *
958 HPBUFFERARB WINAPI
wglCreatePbufferARB(HDC hdc
, int iPixelFormat
, int iWidth
, int iHeight
, const int *piAttribList
)
960 Wine_GLPBuffer
* object
= NULL
;
961 Display
* display
= get_display( hdc
);
962 GLXFBConfig
* cfgs
= NULL
;
965 unsigned nAttribs
= 0;
968 TRACE("(%p, %d, %d, %d, %p)\n", hdc
, iPixelFormat
, iWidth
, iHeight
, piAttribList
);
970 if (0 >= iPixelFormat
) {
971 ERR("(%p): unexpected iPixelFormat(%d) <= 0, returns NULL\n", hdc
, iPixelFormat
);
972 SetLastError(ERROR_INVALID_PIXEL_FORMAT
);
973 return NULL
; /* unexpected error */
976 cfgs
= glXGetFBConfigs(display
, DefaultScreen(display
), &nCfgs
);
978 if (NULL
== cfgs
|| 0 == nCfgs
) {
979 ERR("(%p): Cannot get FB Configs for iPixelFormat(%d), returns NULL\n", hdc
, iPixelFormat
);
980 SetLastError(ERROR_INVALID_PIXEL_FORMAT
);
981 return NULL
; /* unexpected error */
984 /* Convert the WGL pixelformat to a GLX format, if it fails then the format is invalid */
985 if(!ConvertPixelFormatWGLtoGLX(display
, iPixelFormat
, &fmt_index
, &nCfgs
)) {
986 ERR("(%p): unexpected iPixelFormat(%d) > nFormats(%d), returns NULL\n", hdc
, iPixelFormat
, nCfgs
);
987 SetLastError(ERROR_INVALID_PIXEL_FORMAT
);
988 goto create_failed
; /* unexpected error */
991 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(Wine_GLPBuffer
));
992 if (NULL
== object
) {
993 SetLastError(ERROR_NO_SYSTEM_RESOURCES
);
994 goto create_failed
; /* unexpected error */
997 object
->display
= display
;
998 object
->width
= iWidth
;
999 object
->height
= iHeight
;
1001 nAttribs
= ConvertAttribWGLtoGLX(piAttribList
, attribs
, object
);
1002 if (-1 == nAttribs
) {
1003 WARN("Cannot convert WGL to GLX attributes\n");
1006 PUSH2(attribs
, GLX_PBUFFER_WIDTH
, iWidth
);
1007 PUSH2(attribs
, GLX_PBUFFER_HEIGHT
, iHeight
);
1008 while (0 != *piAttribList
) {
1010 switch (*piAttribList
) {
1011 case WGL_TEXTURE_FORMAT_ARB
: {
1013 attr_v
= *piAttribList
;
1014 TRACE("WGL_render_texture Attribute: WGL_TEXTURE_FORMAT_ARB as %x\n", attr_v
);
1015 if (use_render_texture_ati
) {
1018 case WGL_NO_TEXTURE_ARB
: type
= GLX_NO_TEXTURE_ATI
; break ;
1019 case WGL_TEXTURE_RGB_ARB
: type
= GLX_TEXTURE_RGB_ATI
; break ;
1020 case WGL_TEXTURE_RGBA_ARB
: type
= GLX_TEXTURE_RGBA_ATI
; break ;
1022 SetLastError(ERROR_INVALID_DATA
);
1025 object
->use_render_texture
= 1;
1026 PUSH2(attribs
, GLX_TEXTURE_FORMAT_ATI
, type
);
1028 if (WGL_NO_TEXTURE_ARB
== attr_v
) {
1029 object
->use_render_texture
= 0;
1031 if (!use_render_texture_emulation
) {
1032 SetLastError(ERROR_INVALID_DATA
);
1036 case WGL_TEXTURE_RGB_ARB
:
1037 object
->use_render_texture
= GL_RGB
;
1039 case WGL_TEXTURE_RGBA_ARB
:
1040 object
->use_render_texture
= GL_RGBA
;
1043 SetLastError(ERROR_INVALID_DATA
);
1051 case WGL_TEXTURE_TARGET_ARB
: {
1053 attr_v
= *piAttribList
;
1054 TRACE("WGL_render_texture Attribute: WGL_TEXTURE_TARGET_ARB as %x\n", attr_v
);
1055 if (use_render_texture_ati
) {
1058 case WGL_NO_TEXTURE_ARB
: type
= GLX_NO_TEXTURE_ATI
; break ;
1059 case WGL_TEXTURE_CUBE_MAP_ARB
: type
= GLX_TEXTURE_CUBE_MAP_ATI
; break ;
1060 case WGL_TEXTURE_1D_ARB
: type
= GLX_TEXTURE_1D_ATI
; break ;
1061 case WGL_TEXTURE_2D_ARB
: type
= GLX_TEXTURE_2D_ATI
; break ;
1063 SetLastError(ERROR_INVALID_DATA
);
1066 PUSH2(attribs
, GLX_TEXTURE_TARGET_ATI
, type
);
1068 if (WGL_NO_TEXTURE_ARB
== attr_v
) {
1069 object
->texture_target
= 0;
1071 if (!use_render_texture_emulation
) {
1072 SetLastError(ERROR_INVALID_DATA
);
1076 case WGL_TEXTURE_CUBE_MAP_ARB
: {
1077 if (iWidth
!= iHeight
) {
1078 SetLastError(ERROR_INVALID_DATA
);
1081 object
->texture_target
= GL_TEXTURE_CUBE_MAP
;
1082 object
->texture_bind_target
= GL_TEXTURE_CUBE_MAP
;
1085 case WGL_TEXTURE_1D_ARB
: {
1087 SetLastError(ERROR_INVALID_DATA
);
1090 object
->texture_target
= GL_TEXTURE_1D
;
1091 object
->texture_bind_target
= GL_TEXTURE_1D
;
1094 case WGL_TEXTURE_2D_ARB
: {
1095 object
->texture_target
= GL_TEXTURE_2D
;
1096 object
->texture_bind_target
= GL_TEXTURE_2D
;
1100 SetLastError(ERROR_INVALID_DATA
);
1108 case WGL_MIPMAP_TEXTURE_ARB
: {
1110 attr_v
= *piAttribList
;
1111 TRACE("WGL_render_texture Attribute: WGL_MIPMAP_TEXTURE_ARB as %x\n", attr_v
);
1112 if (use_render_texture_ati
) {
1113 PUSH2(attribs
, GLX_MIPMAP_TEXTURE_ATI
, attr_v
);
1115 if (!use_render_texture_emulation
) {
1116 SetLastError(ERROR_INVALID_DATA
);
1121 SetLastError(ERROR_INVALID_DATA);
1132 PUSH1(attribs
, None
);
1133 object
->drawable
= glXCreatePbuffer(display
, cfgs
[fmt_index
], attribs
);
1134 TRACE("new Pbuffer drawable as %p\n", (void*) object
->drawable
);
1135 if (!object
->drawable
) {
1136 SetLastError(ERROR_NO_SYSTEM_RESOURCES
);
1137 goto create_failed
; /* unexpected error */
1139 TRACE("->(%p)\n", object
);
1143 return (HPBUFFERARB
) object
;
1146 if (NULL
!= cfgs
) XFree(cfgs
);
1147 HeapFree(GetProcessHeap(), 0, object
);
1148 TRACE("->(FAILED)\n");
1149 return (HPBUFFERARB
) NULL
;
1152 HDC WINAPI
wglGetPbufferDCARB(HPBUFFERARB hPbuffer
)
1154 Wine_GLPBuffer
* object
= (Wine_GLPBuffer
*) hPbuffer
;
1156 if (NULL
== object
) {
1157 SetLastError(ERROR_INVALID_HANDLE
);
1160 hDC
= CreateCompatibleDC(object
->hdc
);
1162 /* The function wglGetPbufferDCARB returns a DC to which the pbuffer can be connected.
1163 * We only support one onscreen rendering format (the one from the main visual), so use that. */
1164 SetPixelFormat(hDC
, 1, NULL
);
1165 set_drawable(hDC
, object
->drawable
); /* works ?? */
1166 TRACE("(%p)->(%p)\n", hPbuffer
, hDC
);
1170 int WINAPI
wglReleasePbufferDCARB(HPBUFFERARB hPbuffer
, HDC hdc
)
1172 TRACE("(%p, %p)\n", hPbuffer
, hdc
);
1177 GLboolean WINAPI
wglDestroyPbufferARB(HPBUFFERARB hPbuffer
)
1179 Wine_GLPBuffer
* object
= (Wine_GLPBuffer
*) hPbuffer
;
1180 TRACE("(%p)\n", hPbuffer
);
1181 if (NULL
== object
) {
1182 SetLastError(ERROR_INVALID_HANDLE
);
1185 glXDestroyPbuffer(object
->display
, object
->drawable
);
1186 HeapFree(GetProcessHeap(), 0, object
);
1190 GLboolean WINAPI
wglQueryPbufferARB(HPBUFFERARB hPbuffer
, int iAttribute
, int *piValue
)
1192 Wine_GLPBuffer
* object
= (Wine_GLPBuffer
*) hPbuffer
;
1193 TRACE("(%p, 0x%x, %p)\n", hPbuffer
, iAttribute
, piValue
);
1194 if (NULL
== object
) {
1195 SetLastError(ERROR_INVALID_HANDLE
);
1198 switch (iAttribute
) {
1199 case WGL_PBUFFER_WIDTH_ARB
:
1200 glXQueryDrawable(object
->display
, object
->drawable
, GLX_WIDTH
, (unsigned int*) piValue
);
1202 case WGL_PBUFFER_HEIGHT_ARB
:
1203 glXQueryDrawable(object
->display
, object
->drawable
, GLX_HEIGHT
, (unsigned int*) piValue
);
1206 case WGL_PBUFFER_LOST_ARB
:
1207 FIXME("unsupported WGL_PBUFFER_LOST_ARB (need glXSelectEvent/GLX_DAMAGED work)\n");
1210 case WGL_TEXTURE_FORMAT_ARB
:
1211 if (use_render_texture_ati
) {
1213 int type
= WGL_NO_TEXTURE_ARB
;
1214 glXQueryDrawable(object
->display
, object
->drawable
, GLX_TEXTURE_FORMAT_ATI
, &tmp
);
1216 case GLX_NO_TEXTURE_ATI
: type
= WGL_NO_TEXTURE_ARB
; break ;
1217 case GLX_TEXTURE_RGB_ATI
: type
= WGL_TEXTURE_RGB_ARB
; break ;
1218 case GLX_TEXTURE_RGBA_ATI
: type
= WGL_TEXTURE_RGBA_ARB
; break ;
1222 if (!object
->use_render_texture
) {
1223 *piValue
= WGL_NO_TEXTURE_ARB
;
1225 if (!use_render_texture_emulation
) {
1226 SetLastError(ERROR_INVALID_HANDLE
);
1229 if (GL_RGBA
== object
->use_render_texture
) {
1230 *piValue
= WGL_TEXTURE_RGBA_ARB
;
1232 *piValue
= WGL_TEXTURE_RGB_ARB
;
1238 case WGL_TEXTURE_TARGET_ARB
:
1239 if (use_render_texture_ati
) {
1241 int type
= WGL_NO_TEXTURE_ARB
;
1242 glXQueryDrawable(object
->display
, object
->drawable
, GLX_TEXTURE_TARGET_ATI
, &tmp
);
1244 case GLX_NO_TEXTURE_ATI
: type
= WGL_NO_TEXTURE_ARB
; break ;
1245 case GLX_TEXTURE_CUBE_MAP_ATI
: type
= WGL_TEXTURE_CUBE_MAP_ARB
; break ;
1246 case GLX_TEXTURE_1D_ATI
: type
= WGL_TEXTURE_1D_ARB
; break ;
1247 case GLX_TEXTURE_2D_ATI
: type
= WGL_TEXTURE_2D_ARB
; break ;
1251 if (!object
->texture_target
) {
1252 *piValue
= WGL_NO_TEXTURE_ARB
;
1254 if (!use_render_texture_emulation
) {
1255 SetLastError(ERROR_INVALID_DATA
);
1258 switch (object
->texture_target
) {
1259 case GL_TEXTURE_1D
: *piValue
= WGL_TEXTURE_CUBE_MAP_ARB
; break;
1260 case GL_TEXTURE_2D
: *piValue
= WGL_TEXTURE_1D_ARB
; break;
1261 case GL_TEXTURE_CUBE_MAP
: *piValue
= WGL_TEXTURE_2D_ARB
; break;
1267 case WGL_MIPMAP_TEXTURE_ARB
:
1268 if (use_render_texture_ati
) {
1269 glXQueryDrawable(object
->display
, object
->drawable
, GLX_MIPMAP_TEXTURE_ATI
, (unsigned int*) piValue
);
1271 *piValue
= GL_FALSE
; /** don't support that */
1272 FIXME("unsupported WGL_ARB_render_texture attribute query for 0x%x\n", iAttribute
);
1277 FIXME("unexpected attribute %x\n", iAttribute
);
1284 static GLboolean WINAPI
wglBindTexImageARB(HPBUFFERARB hPbuffer
, int iBuffer
)
1286 Wine_GLPBuffer
* object
= (Wine_GLPBuffer
*) hPbuffer
;
1287 TRACE("(%p, %d)\n", hPbuffer
, iBuffer
);
1288 if (NULL
== object
) {
1289 SetLastError(ERROR_INVALID_HANDLE
);
1292 if (!object
->use_render_texture
) {
1293 SetLastError(ERROR_INVALID_HANDLE
);
1296 if (!use_render_texture_ati
&& 1 == use_render_texture_emulation
) {
1298 GLint prev_binded_tex
;
1299 glGetIntegerv(object
->texture_target
, &prev_binded_tex
);
1300 if (NULL
== object
->render_ctx
) {
1301 object
->render_hdc
= wglGetPbufferDCARB(hPbuffer
);
1302 object
->render_ctx
= wglCreateContext(object
->render_hdc
);
1305 object
->prev_hdc
= wglGetCurrentDC();
1306 object
->prev_ctx
= wglGetCurrentContext();
1307 wglMakeCurrent(object
->render_hdc
, object
->render_ctx
);
1310 glBindTexture(object->texture_target, object->texture);
1311 if (GL_RGBA == object->use_render_texture) {
1312 glTexImage2D(object->texture_target, 0, GL_RGBA8, object->width, object->height, 0, GL_RGBA, GL_FLOAT, NULL);
1314 glTexImage2D(object->texture_target, 0, GL_RGB8, object->width, object->height, 0, GL_RGB, GL_FLOAT, NULL);
1318 object
->texture
= prev_binded_tex
;
1321 if (NULL
!= p_glXBindTexImageARB
) {
1322 return p_glXBindTexImageARB(object
->display
, object
->drawable
, iBuffer
);
1327 static GLboolean WINAPI
wglReleaseTexImageARB(HPBUFFERARB hPbuffer
, int iBuffer
)
1329 Wine_GLPBuffer
* object
= (Wine_GLPBuffer
*) hPbuffer
;
1330 TRACE("(%p, %d)\n", hPbuffer
, iBuffer
);
1331 if (NULL
== object
) {
1332 SetLastError(ERROR_INVALID_HANDLE
);
1335 if (!object
->use_render_texture
) {
1336 SetLastError(ERROR_INVALID_HANDLE
);
1339 if (!use_render_texture_ati
&& 1 == use_render_texture_emulation
) {
1341 GLint prev_binded_tex;
1342 glGetIntegerv(object->texture_target, &prev_binded_tex);
1343 if (GL_TEXTURE_1D == object->texture_target) {
1344 glCopyTexSubImage1D(object->texture_target, object->texture_level, 0, 0, 0, object->width);
1346 glCopyTexSubImage2D(object->texture_target, object->texture_level, 0, 0, 0, 0, object->width, object->height);
1348 glBindTexture(object->texture_target, prev_binded_tex);
1349 SwapBuffers(object->render_hdc);
1351 glBindTexture(object
->texture_target
, object
->texture
);
1352 if (GL_TEXTURE_1D
== object
->texture_target
) {
1353 glCopyTexSubImage1D(object
->texture_target
, object
->texture_level
, 0, 0, 0, object
->width
);
1355 glCopyTexSubImage2D(object
->texture_target
, object
->texture_level
, 0, 0, 0, 0, object
->width
, object
->height
);
1358 wglMakeCurrent(object
->prev_hdc
, object
->prev_ctx
);
1361 if (NULL
!= p_glXReleaseTexImageARB
) {
1362 return p_glXReleaseTexImageARB(object
->display
, object
->drawable
, iBuffer
);
1367 static GLboolean WINAPI
wglSetPbufferAttribARB(HPBUFFERARB hPbuffer
, const int *piAttribList
)
1369 Wine_GLPBuffer
* object
= (Wine_GLPBuffer
*) hPbuffer
;
1370 WARN("(%p, %p): alpha-testing, report any problem\n", hPbuffer
, piAttribList
);
1371 if (NULL
== object
) {
1372 SetLastError(ERROR_INVALID_HANDLE
);
1375 if (!object
->use_render_texture
) {
1376 SetLastError(ERROR_INVALID_HANDLE
);
1379 if (!use_render_texture_ati
&& 1 == use_render_texture_emulation
) {
1382 if (NULL
!= p_glXDrawableAttribARB
) {
1383 if (use_render_texture_ati
) {
1384 FIXME("Need conversion for GLX_ATI_render_texture\n");
1386 return p_glXDrawableAttribARB(object
->display
, object
->drawable
, piAttribList
);
1391 static const struct {
1393 BOOL (*query_function
)(glXGetProcAddressARB_t proc
, const char *gl_version
, const char *gl_extensions
,
1394 const char *glx_version
, const char *glx_extensions
,
1395 const char *server_glx_extensions
, const char *client_glx_extensions
);
1396 } extension_list
[] = {
1397 { "WGL_ARB_make_current_read", query_function_make_current_read
},
1398 { "WGL_ARB_multisample", query_function_multisample
},
1399 { "WGL_ARB_pbuffer", query_function_pbuffer
},
1400 { "WGL_ARB_pixel_format" , query_function_pixel_format
},
1401 { "WGL_ARB_render_texture", query_function_render_texture
},
1402 { "WGL_EXT_swap_control", query_function_swap_control
}
1405 /* Used to initialize the WGL extension string at DLL loading */
1406 void wgl_ext_initialize_extensions(Display
*display
, int screen
, glXGetProcAddressARB_t proc
, const char* disabled_extensions
)
1408 int size
= strlen(WGL_extensions_base
);
1409 const char *glx_extensions
= glXQueryExtensionsString(display
, screen
);
1410 const char *server_glx_extensions
= glXQueryServerString(display
, screen
, GLX_EXTENSIONS
);
1411 const char *client_glx_extensions
= glXGetClientString(display
, GLX_EXTENSIONS
);
1412 const char *gl_extensions
= (const char *) glGetString(GL_EXTENSIONS
);
1413 const char *gl_version
= (const char *) glGetString(GL_VERSION
);
1414 const char *server_glx_version
= glXQueryServerString(display
, screen
, GLX_VERSION
);
1415 const char *glx_version
= glXGetClientString(display
, GLX_VERSION
);
1418 TRACE("GL version : %s.\n", debugstr_a(gl_version
));
1419 TRACE("GL exts : %s.\n", debugstr_a(gl_extensions
));
1420 TRACE("GLX exts : %s.\n", debugstr_a(glx_extensions
));
1421 TRACE("Server GLX version : %s.\n", debugstr_a(server_glx_version
));
1422 TRACE("Client GLX version : %s.\n", debugstr_a(glx_version
));
1423 TRACE("Server GLX exts : %s.\n", debugstr_a(server_glx_extensions
));
1424 TRACE("Client GLX exts : %s.\n", debugstr_a(client_glx_extensions
));
1426 for (i
= 0; i
< (sizeof(extension_list
) / sizeof(extension_list
[0])); i
++) {
1427 if (strstr(disabled_extensions
, extension_list
[i
].name
)) continue ; /* disabled by config, next */
1428 if (extension_list
[i
].query_function(proc
,
1429 gl_version
, gl_extensions
,
1430 glx_version
, glx_extensions
,
1431 server_glx_extensions
, client_glx_extensions
)) {
1432 size
+= strlen(extension_list
[i
].name
) + 1;
1436 /* For the moment, only 'base' extensions are supported. */
1437 WGL_extensions
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, size
+ 1);
1438 if (WGL_extensions
== NULL
) {
1439 WGL_extensions
= (char *) WGL_extensions_base
;
1441 strcpy(WGL_extensions
, WGL_extensions_base
);
1442 for (i
= 0; i
< (sizeof(extension_list
) / sizeof(extension_list
[0])); i
++) {
1443 if (strstr(disabled_extensions
, extension_list
[i
].name
)) continue ; /* disabled by config, next */
1444 if (extension_list
[i
].query_function(proc
,
1445 gl_version
, gl_extensions
,
1446 glx_version
, glx_extensions
,
1447 server_glx_extensions
, client_glx_extensions
)) {
1448 strcat(WGL_extensions
, " ");
1449 strcat(WGL_extensions
, extension_list
[i
].name
);
1454 TRACE("Supporting following WGL extensions : %s.\n", debugstr_a(WGL_extensions
));
1457 void wgl_ext_finalize_extensions(void)
1459 if (WGL_extensions
!= WGL_extensions_base
) {
1460 HeapFree(GetProcessHeap(), 0, WGL_extensions
);
1465 /* these are located in wgl.c for convenience of implementation */
1466 BOOL WINAPI
wglMakeContextCurrentARB(HDC
,HDC
,HGLRC
);
1467 HDC WINAPI
wglGetCurrentReadDCARB(void);
1471 * Putting this at the end to prevent having to write the prototypes :-)
1473 * @WARNING: this list must be ordered by name
1475 * @TODO: real handle caps on providing some func_init functions (third param, ex: to check extensions)
1477 WGL_extension wgl_extension_registry
[] = {
1478 { "wglBindTexImageARB", (void *) wglBindTexImageARB
, NULL
, NULL
},
1479 { "wglChoosePixelFormatARB", (void *) wglChoosePixelFormatARB
, NULL
, NULL
},
1480 { "wglCreatePbufferARB", (void *) wglCreatePbufferARB
, NULL
, NULL
},
1481 { "wglDestroyPbufferARB", (void *) wglDestroyPbufferARB
, NULL
, NULL
},
1482 { "wglGetCurrentReadDCARB", (void *) wglGetCurrentReadDCARB
, NULL
, NULL
},
1483 { "wglGetExtensionsStringARB", (void *) wglGetExtensionsStringARB
, NULL
, NULL
},
1484 { "wglGetExtensionsStringEXT", (void *) wglGetExtensionsStringEXT
, NULL
, NULL
},
1485 { "wglGetPbufferDCARB", (void *) wglGetPbufferDCARB
, NULL
, NULL
},
1486 { "wglGetPixelFormatAttribfvARB", (void *) wglGetPixelFormatAttribfvARB
, NULL
, NULL
},
1487 { "wglGetPixelFormatAttribivARB", (void *) wglGetPixelFormatAttribivARB
, NULL
, NULL
},
1488 { "wglGetSwapIntervalEXT", (void *) wglGetSwapIntervalEXT
, NULL
, NULL
},
1489 { "wglMakeContextCurrentARB", (void *) wglMakeContextCurrentARB
, NULL
, NULL
},
1490 { "wglQueryPbufferARB", (void *) wglQueryPbufferARB
, NULL
, NULL
},
1491 { "wglReleasePbufferDCARB", (void *) wglReleasePbufferDCARB
, NULL
, NULL
},
1492 { "wglReleaseTexImageARB", (void *) wglReleaseTexImageARB
, NULL
, NULL
},
1493 { "wglSetPbufferAttribARB", (void *) wglSetPbufferAttribARB
, NULL
, NULL
},
1494 { "wglSwapIntervalEXT", (void *) wglSwapIntervalEXT
, NULL
, NULL
}
1496 int wgl_extension_registry_size
= sizeof(wgl_extension_registry
) / sizeof(wgl_extension_registry
[0]);