x11drv/opengl: Pixel format rewrite.
[wine/wine64.git] / dlls / opengl32 / wgl_ext.c
blob6ef39786f583bf0719d7486ebc82906e12c85c50
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
22 #include "config.h"
23 #include "wine/port.h"
25 #include <stdarg.h>
26 #include <stdlib.h>
27 #include <string.h>
29 #include "windef.h"
30 #include "winbase.h"
31 #include "winuser.h"
32 #include "winerror.h"
34 #include "gdi.h"
35 #include "wgl_ext.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 )
64 Display *display;
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;
69 return display;
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;
88 /**
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)
121 return TRUE;
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)
138 BOOL bTest = FALSE;
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);
145 if (bTest) {
146 TRACE("Active WGL_render_texture: found GLX_ATI_render_texture extensions\n");
147 use_render_texture_ati = 1;
148 return bTest;
150 bTest = (0 <= strcmp("1.3", glx_version) || NULL != strstr(glx_extensions, "GLX_SGIX_pbuffer"));
151 if (bTest) {
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);
160 } else {
161 TRACE("Active WGL_render_texture: emulation using pbuffers\n");
162 use_render_texture_emulation = 1;
165 return bTest;
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"));
174 if (bTest) {
175 p_glXSwapIntervalSGI = proc( (const GLubyte *) "glXSwapIntervalSGI");
176 bTest = (NULL != p_glXSwapIntervalSGI);
178 return bTest;
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");
211 return TRUE;
214 /***********************************************************************
215 * wglGetSwapIntervalEXT(OPENGL32.@)
217 int WINAPI wglGetSwapIntervalEXT(VOID) {
218 FIXME("(),stub!\n");
219 return swap_interval;
222 typedef struct wine_glpbuffer {
223 Drawable drawable;
224 Display* display;
225 int pixelFormat;
226 int width;
227 int height;
228 int* attribList;
229 HDC hdc;
231 int use_render_texture;
232 GLuint texture_target;
233 GLuint texture_bind_target;
234 GLuint texture;
235 int texture_level;
236 HDC prev_hdc;
237 HGLRC prev_ctx;
238 HDC render_hdc;
239 HGLRC render_ctx;
240 } Wine_GLPBuffer;
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
307 * WGL_render_texture
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
351 /**
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) {
406 int nAttribs = 0;
407 FIXME("not yet implemented!\n");
408 return nAttribs;
410 #endif
412 static int ConvertAttribWGLtoGLX(const int* iWGLAttr, int* oGLXAttr, Wine_GLPBuffer* pbuf) {
413 int nAttribs = 0;
414 unsigned cur = 0;
415 int pop;
416 int isColor = 0;
417 int wantColorBits = 0;
418 int sz_alpha = 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 */
427 break;
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);
432 break;
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);
437 break;
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);
442 break;
443 case WGL_ALPHA_BITS_ARB:
444 pop = iWGLAttr[++cur];
445 sz_alpha = pop;
446 PUSH2(oGLXAttr, GLX_ALPHA_SIZE, pop);
447 TRACE("pAttr[%d] = GLX_ALPHA_SIZE: %d\n", cur, pop);
448 break;
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);
453 break;
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);
458 break;
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);
463 break;
465 case WGL_PIXEL_TYPE_ARB:
466 pop = iWGLAttr[++cur];
467 switch (pop) {
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 ;
471 default:
472 ERR("unexpected PixelType(%x)\n", pop);
473 pop = 0;
475 PUSH2(oGLXAttr, GLX_RENDER_TYPE, pop);
476 TRACE("pAttr[%d] = GLX_RENDER_TYPE: %d\n", cur, pop);
477 break;
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);
483 break;
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);
489 if (pop) {
490 PUSH2(oGLXAttr, GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT);
491 TRACE("pAttr[%d] = GLX_DRAWABLE_TYPE: GLX_PIXMAP_BIT\n", cur);
493 break;
495 case WGL_DRAW_TO_WINDOW_ARB:
496 pop = iWGLAttr[++cur];
497 if (pop) {
498 PUSH2(oGLXAttr, GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT);
499 TRACE("pAttr[%d] = GLX_DRAWABLE_TYPE: GLX_WINDOW_BIT\n", cur);
501 break;
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);
507 if (pop) {
508 PUSH2(oGLXAttr, GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT);
509 TRACE("pAttr[%d] = GLX_DRAWABLE_TYPE: GLX_PBUFFER_BIT\n", cur);
511 break;
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);
518 break;
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);
524 break;
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);
530 break;
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);
536 break;
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];
543 if (NULL == pbuf) {
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 */
553 } else {
554 PUSH2(oGLXAttr, GLX_X_RENDERABLE, pop);
555 PUSH2(oGLXAttr, GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT);
558 break ;
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
567 break ;
569 default:
570 FIXME("unsupported %x WGL Attribute\n", iWGLAttr[cur]);
571 break;
573 ++cur;
577 * Trick as WGL_COLOR_BITS_ARB != GLX_BUFFER_SIZE
578 * WGL_COLOR_BITS_ARB + WGL_ALPHA_BITS_ARB == GLX_BUFFER_SIZE
580 * WGL_COLOR_BITS_ARB
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.
586 * GLX_BUFFER_SIZE
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) {
595 if (!isColor) {
596 wantColorBits += sz_alpha;
598 if (32 < wantColorBits) {
599 ERR("buggy %d GLX_BUFFER_SIZE default to 32\n", wantColorBits);
600 wantColorBits = 32;
602 PUSH2(oGLXAttr, GLX_BUFFER_SIZE, wantColorBits);
603 TRACE("pAttr[%d] = WGL_COLOR_BITS_ARB: %d\n", cur, wantColorBits);
606 return nAttribs;
609 GLboolean WINAPI wglGetPixelFormatAttribivARB(HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues)
611 Display* display = get_display( hdc );
612 UINT i;
613 GLXFBConfig* cfgs = NULL;
614 GLXFBConfig curCfg = NULL;
615 int nCfgs = 0;
616 int hTest;
617 int tmp;
618 int curGLXAttr = 0;
619 int nWGLFormats = 0;
620 int fmt_index = 0;
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);
626 return GL_FALSE;
629 cfgs = glXGetFBConfigs(display, DefaultScreen(display), &nCfgs);
630 if (NULL == cfgs) {
631 ERR("no FB Configs found for display(%p)\n", display);
632 return GL_FALSE;
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;
649 continue ;
651 case WGL_SUPPORT_OPENGL_ARB:
652 piValues[i] = GL_TRUE;
653 continue ;
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;
661 switch (tmp) {
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;
665 default:
666 ERR("unexpected Config Caveat(%x)\n", tmp);
667 piValues[i] = WGL_NO_ACCELERATION_ARB;
669 continue ;
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;
681 continue ;
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; }
696 else {
697 ERR("unexpected RenderType(%x)\n", tmp);
698 piValues[i] = WGL_TYPE_RGBA_ARB;
700 continue ;
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;
715 continue ;
717 case WGL_BIND_TO_TEXTURE_RGB_ARB:
718 if (use_render_texture_ati) {
719 curGLXAttr = GLX_BIND_TO_TEXTURE_RGB_ATI;
720 break;
722 case WGL_BIND_TO_TEXTURE_RGBA_ARB:
723 if (use_render_texture_ati) {
724 curGLXAttr = GLX_BIND_TO_TEXTURE_RGBA_ATI;
725 break;
727 if (!use_render_texture_emulation) {
728 piValues[i] = GL_FALSE;
729 continue ;
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;
740 continue ;
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;
745 continue ;
747 case WGL_BLUE_BITS_ARB:
748 curGLXAttr = GLX_BLUE_SIZE;
749 break;
750 case WGL_RED_BITS_ARB:
751 curGLXAttr = GLX_RED_SIZE;
752 break;
753 case WGL_GREEN_BITS_ARB:
754 curGLXAttr = GLX_GREEN_SIZE;
755 break;
756 case WGL_ALPHA_BITS_ARB:
757 curGLXAttr = GLX_ALPHA_SIZE;
758 break;
759 case WGL_DEPTH_BITS_ARB:
760 curGLXAttr = GLX_DEPTH_SIZE;
761 break;
762 case WGL_STENCIL_BITS_ARB:
763 curGLXAttr = GLX_STENCIL_SIZE;
764 break;
765 case WGL_DOUBLE_BUFFER_ARB:
766 curGLXAttr = GLX_DOUBLEBUFFER;
767 break;
768 case WGL_STEREO_ARB:
769 curGLXAttr = GLX_STEREO;
770 break;
771 case WGL_AUX_BUFFERS_ARB:
772 curGLXAttr = GLX_AUX_BUFFERS;
773 break;
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;
780 break;
782 case WGL_PBUFFER_LARGEST_ARB:
783 curGLXAttr = GLX_LARGEST_PBUFFER;
784 break;
786 case WGL_SAMPLE_BUFFERS_ARB:
787 curGLXAttr = GLX_SAMPLE_BUFFERS_ARB;
788 break;
790 case WGL_SAMPLES_ARB:
791 curGLXAttr = GLX_SAMPLES_ARB;
792 break;
794 default:
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;
805 } else {
806 piValues[i] = GL_FALSE;
810 return GL_TRUE;
812 get_error:
813 ERR("(%p): unexpected failure on GetFBConfigAttrib(%x) returns FALSE\n", hdc, curGLXAttr);
814 XFree(cfgs);
815 return GL_FALSE;
817 pix_error:
818 ERR("(%p): unexpected iPixelFormat(%d) vs nFormats(%d), returns FALSE\n", hdc, iPixelFormat, nCfgs);
819 XFree(cfgs);
820 return GL_FALSE;
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);
826 return GL_FALSE;
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 );
834 int gl_test = 0;
835 int attribs[256];
836 int nAttribs = 0;
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;
843 int nCfgs = 0;
844 UINT it;
845 int fmt_id;
847 GLXFBConfig* cfgs_fmt = NULL;
848 int nCfgs_fmt = 0;
849 UINT it_fmt;
850 int tmp_fmt_id;
851 int tmp_vis_id;
853 int pfmt_it = 0;
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");
864 return GL_FALSE;
866 PUSH1(attribs, None);
868 /* Search for FB configurations matching the requirements in attribs */
869 cfgs = glXChooseFBConfig(display, DefaultScreen(display), attribs, &nCfgs);
870 if (NULL == cfgs) {
871 WARN("Compatible Pixel Format not found\n");
872 return GL_FALSE;
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");
879 XFree(cfgs);
880 return GL_FALSE;
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);
887 if (gl_test) {
888 ERR("Failed to retrieve FBCONFIG_ID from GLXFBConfig, expect problems.\n");
889 continue ;
892 gl_test = glXGetFBConfigAttrib(display, cfgs[it], GLX_VISUAL_ID, &tmp_vis_id);
893 if (gl_test) {
894 ERR("Failed to retrieve VISUAL_ID from GLXFBConfig, expect problems.\n");
895 continue ;
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;
902 ++pfmt_it;
903 res = GL_TRUE;
904 TRACE("Found compatible GLXFBConfig 0x%x with WGL index 1\n", fmt_id);
905 continue;
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);
910 continue;
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);
916 if (gl_test) {
917 ERR("Failed to retrieve FBCONFIG_ID from GLXFBConfig, expect problems.\n");
918 continue ;
920 gl_test = glXGetFBConfigAttrib(display, cfgs[it], GLX_VISUAL_ID, &tmp_vis_id);
921 if (gl_test) {
922 ERR("Failed to retrieve VISUAL_ID from GLXFBConfig, expect problems.\n");
923 continue ;
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. */
929 if(tmp_vis_id == 0)
930 offscreen_index++;
932 /* We have found the format in the table (note the format is offscreen) */
933 if (fmt_id == tmp_fmt_id) {
934 int tmp;
936 piFormats[pfmt_it] = offscreen_index + 1; /* Add 1 to get a one-based index */
937 ++pfmt_it;
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);
940 break ;
943 if (it_fmt == nCfgs_fmt) {
944 ERR("Failed to get valid fmt for %d. Try next.\n", it);
945 continue ;
947 TRACE("at %d/%d found FBCONFIG_ID(%d/%d)\n", it + 1, nCfgs, piFormats[it], nCfgs_fmt);
950 *nNumFormats = pfmt_it;
951 /** free list */
952 XFree(cfgs);
953 XFree(cfgs_fmt);
954 return GL_TRUE;
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;
963 int nCfgs = 0;
964 int attribs[256];
965 unsigned nAttribs = 0;
966 int fmt_index = 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 */
996 object->hdc = hdc;
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");
1004 goto create_failed;
1006 PUSH2(attribs, GLX_PBUFFER_WIDTH, iWidth);
1007 PUSH2(attribs, GLX_PBUFFER_HEIGHT, iHeight);
1008 while (0 != *piAttribList) {
1009 int attr_v;
1010 switch (*piAttribList) {
1011 case WGL_TEXTURE_FORMAT_ARB: {
1012 ++piAttribList;
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) {
1016 int type = 0;
1017 switch (attr_v) {
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 ;
1021 default:
1022 SetLastError(ERROR_INVALID_DATA);
1023 goto create_failed;
1025 object->use_render_texture = 1;
1026 PUSH2(attribs, GLX_TEXTURE_FORMAT_ATI, type);
1027 } else {
1028 if (WGL_NO_TEXTURE_ARB == attr_v) {
1029 object->use_render_texture = 0;
1030 } else {
1031 if (!use_render_texture_emulation) {
1032 SetLastError(ERROR_INVALID_DATA);
1033 goto create_failed;
1035 switch (attr_v) {
1036 case WGL_TEXTURE_RGB_ARB:
1037 object->use_render_texture = GL_RGB;
1038 break;
1039 case WGL_TEXTURE_RGBA_ARB:
1040 object->use_render_texture = GL_RGBA;
1041 break;
1042 default:
1043 SetLastError(ERROR_INVALID_DATA);
1044 goto create_failed;
1048 break;
1051 case WGL_TEXTURE_TARGET_ARB: {
1052 ++piAttribList;
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) {
1056 int type = 0;
1057 switch (attr_v) {
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 ;
1062 default:
1063 SetLastError(ERROR_INVALID_DATA);
1064 goto create_failed;
1066 PUSH2(attribs, GLX_TEXTURE_TARGET_ATI, type);
1067 } else {
1068 if (WGL_NO_TEXTURE_ARB == attr_v) {
1069 object->texture_target = 0;
1070 } else {
1071 if (!use_render_texture_emulation) {
1072 SetLastError(ERROR_INVALID_DATA);
1073 goto create_failed;
1075 switch (attr_v) {
1076 case WGL_TEXTURE_CUBE_MAP_ARB: {
1077 if (iWidth != iHeight) {
1078 SetLastError(ERROR_INVALID_DATA);
1079 goto create_failed;
1081 object->texture_target = GL_TEXTURE_CUBE_MAP;
1082 object->texture_bind_target = GL_TEXTURE_CUBE_MAP;
1083 break;
1085 case WGL_TEXTURE_1D_ARB: {
1086 if (1 != iHeight) {
1087 SetLastError(ERROR_INVALID_DATA);
1088 goto create_failed;
1090 object->texture_target = GL_TEXTURE_1D;
1091 object->texture_bind_target = GL_TEXTURE_1D;
1092 break;
1094 case WGL_TEXTURE_2D_ARB: {
1095 object->texture_target = GL_TEXTURE_2D;
1096 object->texture_bind_target = GL_TEXTURE_2D;
1097 break;
1099 default:
1100 SetLastError(ERROR_INVALID_DATA);
1101 goto create_failed;
1105 break;
1108 case WGL_MIPMAP_TEXTURE_ARB: {
1109 ++piAttribList;
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);
1114 } else {
1115 if (!use_render_texture_emulation) {
1116 SetLastError(ERROR_INVALID_DATA);
1117 goto create_failed;
1120 if (0 != attr_v) {
1121 SetLastError(ERROR_INVALID_DATA);
1122 goto create_failed;
1126 break ;
1129 ++piAttribList;
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);
1141 /** free list */
1142 XFree(cfgs);
1143 return (HPBUFFERARB) object;
1145 create_failed:
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;
1155 HDC hDC;
1156 if (NULL == object) {
1157 SetLastError(ERROR_INVALID_HANDLE);
1158 return NULL;
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);
1167 return hDC;
1170 int WINAPI wglReleasePbufferDCARB(HPBUFFERARB hPbuffer, HDC hdc)
1172 TRACE("(%p, %p)\n", hPbuffer, hdc);
1173 DeleteDC(hdc);
1174 return 0;
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);
1183 return GL_FALSE;
1185 glXDestroyPbuffer(object->display, object->drawable);
1186 HeapFree(GetProcessHeap(), 0, object);
1187 return GL_TRUE;
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);
1196 return GL_FALSE;
1198 switch (iAttribute) {
1199 case WGL_PBUFFER_WIDTH_ARB:
1200 glXQueryDrawable(object->display, object->drawable, GLX_WIDTH, (unsigned int*) piValue);
1201 break;
1202 case WGL_PBUFFER_HEIGHT_ARB:
1203 glXQueryDrawable(object->display, object->drawable, GLX_HEIGHT, (unsigned int*) piValue);
1204 break;
1206 case WGL_PBUFFER_LOST_ARB:
1207 FIXME("unsupported WGL_PBUFFER_LOST_ARB (need glXSelectEvent/GLX_DAMAGED work)\n");
1208 break;
1210 case WGL_TEXTURE_FORMAT_ARB:
1211 if (use_render_texture_ati) {
1212 unsigned int tmp;
1213 int type = WGL_NO_TEXTURE_ARB;
1214 glXQueryDrawable(object->display, object->drawable, GLX_TEXTURE_FORMAT_ATI, &tmp);
1215 switch (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 ;
1220 *piValue = type;
1221 } else {
1222 if (!object->use_render_texture) {
1223 *piValue = WGL_NO_TEXTURE_ARB;
1224 } else {
1225 if (!use_render_texture_emulation) {
1226 SetLastError(ERROR_INVALID_HANDLE);
1227 return GL_FALSE;
1229 if (GL_RGBA == object->use_render_texture) {
1230 *piValue = WGL_TEXTURE_RGBA_ARB;
1231 } else {
1232 *piValue = WGL_TEXTURE_RGB_ARB;
1236 break;
1238 case WGL_TEXTURE_TARGET_ARB:
1239 if (use_render_texture_ati) {
1240 unsigned int tmp;
1241 int type = WGL_NO_TEXTURE_ARB;
1242 glXQueryDrawable(object->display, object->drawable, GLX_TEXTURE_TARGET_ATI, &tmp);
1243 switch (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 ;
1249 *piValue = type;
1250 } else {
1251 if (!object->texture_target) {
1252 *piValue = WGL_NO_TEXTURE_ARB;
1253 } else {
1254 if (!use_render_texture_emulation) {
1255 SetLastError(ERROR_INVALID_DATA);
1256 return GL_FALSE;
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;
1265 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);
1270 } else {
1271 *piValue = GL_FALSE; /** don't support that */
1272 FIXME("unsupported WGL_ARB_render_texture attribute query for 0x%x\n", iAttribute);
1274 break;
1276 default:
1277 FIXME("unexpected attribute %x\n", iAttribute);
1278 break;
1281 return GL_TRUE;
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);
1290 return GL_FALSE;
1292 if (!object->use_render_texture) {
1293 SetLastError(ERROR_INVALID_HANDLE);
1294 return GL_FALSE;
1296 if (!use_render_texture_ati && 1 == use_render_texture_emulation) {
1297 int do_init = 0;
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);
1303 do_init = 1;
1305 object->prev_hdc = wglGetCurrentDC();
1306 object->prev_ctx = wglGetCurrentContext();
1307 wglMakeCurrent(object->render_hdc, object->render_ctx);
1309 if (do_init) {
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);
1313 } else {
1314 glTexImage2D(object->texture_target, 0, GL_RGB8, object->width, object->height, 0, GL_RGB, GL_FLOAT, NULL);
1318 object->texture = prev_binded_tex;
1319 return GL_TRUE;
1321 if (NULL != p_glXBindTexImageARB) {
1322 return p_glXBindTexImageARB(object->display, object->drawable, iBuffer);
1324 return GL_FALSE;
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);
1333 return GL_FALSE;
1335 if (!object->use_render_texture) {
1336 SetLastError(ERROR_INVALID_HANDLE);
1337 return GL_FALSE;
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);
1345 } else {
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);
1354 } else {
1355 glCopyTexSubImage2D(object->texture_target, object->texture_level, 0, 0, 0, 0, object->width, object->height);
1358 wglMakeCurrent(object->prev_hdc, object->prev_ctx);
1359 return GL_TRUE;
1361 if (NULL != p_glXReleaseTexImageARB) {
1362 return p_glXReleaseTexImageARB(object->display, object->drawable, iBuffer);
1364 return GL_FALSE;
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);
1373 return GL_FALSE;
1375 if (!object->use_render_texture) {
1376 SetLastError(ERROR_INVALID_HANDLE);
1377 return GL_FALSE;
1379 if (!use_render_texture_ati && 1 == use_render_texture_emulation) {
1380 return GL_TRUE;
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);
1388 return GL_FALSE;
1391 static const struct {
1392 const char *name;
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);
1416 int i;
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;
1440 } else {
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]);