d3d10/effect: Add a helper to read raw variable values.
[wine.git] / dlls / opengl32 / tests / opengl.c
blob314fa11225de7e6afbf82b526da8d59bb049a433
1 /*
2 * Some tests for OpenGL functions
4 * Copyright (C) 2007-2008 Roderick Colenbrander
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include <windows.h>
22 #include <wingdi.h>
23 #include "wine/test.h"
24 #include "wine/wgl.h"
26 #define MAX_FORMATS 256
28 /* WGL_ARB_create_context */
29 static HGLRC (WINAPI *pwglCreateContextAttribsARB)(HDC hDC, HGLRC hShareContext, const int *attribList);
31 /* WGL_ARB_extensions_string */
32 static const char* (WINAPI *pwglGetExtensionsStringARB)(HDC);
33 static int (WINAPI *pwglReleasePbufferDCARB)(HPBUFFERARB, HDC);
35 /* WGL_ARB_make_current_read */
36 static BOOL (WINAPI *pwglMakeContextCurrentARB)(HDC hdraw, HDC hread, HGLRC hglrc);
37 static HDC (WINAPI *pwglGetCurrentReadDCARB)(void);
39 /* WGL_ARB_pixel_format */
40 static BOOL (WINAPI *pwglChoosePixelFormatARB)(HDC, const int *, const FLOAT *, UINT, int *, UINT *);
41 static BOOL (WINAPI *pwglGetPixelFormatAttribivARB)(HDC, int, int, UINT, const int *, int *);
43 /* WGL_ARB_pbuffer */
44 static HPBUFFERARB (WINAPI *pwglCreatePbufferARB)(HDC, int, int, int, const int *);
45 static HDC (WINAPI *pwglGetPbufferDCARB)(HPBUFFERARB);
47 /* WGL_EXT_swap_control */
48 static BOOL (WINAPI *pwglSwapIntervalEXT)(int interval);
49 static int (WINAPI *pwglGetSwapIntervalEXT)(void);
51 /* GL_ARB_debug_output */
52 static void (WINAPI *pglDebugMessageCallbackARB)(void *, void *);
53 static void (WINAPI *pglDebugMessageControlARB)(GLenum, GLenum, GLenum, GLsizei, const GLuint *, GLboolean);
54 static void (WINAPI *pglDebugMessageInsertARB)(GLenum, GLenum, GLuint, GLenum, GLsizei, const char *);
56 static const char* wgl_extensions = NULL;
58 static void init_functions(void)
60 #define GET_PROC(func) \
61 p ## func = (void*)wglGetProcAddress(#func); \
62 if(!p ## func) \
63 trace("wglGetProcAddress(%s) failed\n", #func);
65 /* WGL_ARB_create_context */
66 GET_PROC(wglCreateContextAttribsARB);
68 /* WGL_ARB_extensions_string */
69 GET_PROC(wglGetExtensionsStringARB)
71 /* WGL_ARB_make_current_read */
72 GET_PROC(wglMakeContextCurrentARB);
73 GET_PROC(wglGetCurrentReadDCARB);
75 /* WGL_ARB_pixel_format */
76 GET_PROC(wglChoosePixelFormatARB)
77 GET_PROC(wglGetPixelFormatAttribivARB)
79 /* WGL_ARB_pbuffer */
80 GET_PROC(wglCreatePbufferARB)
81 GET_PROC(wglGetPbufferDCARB)
82 GET_PROC(wglReleasePbufferDCARB)
84 /* WGL_EXT_swap_control */
85 GET_PROC(wglSwapIntervalEXT)
86 GET_PROC(wglGetSwapIntervalEXT)
88 /* GL_ARB_debug_output */
89 GET_PROC(glDebugMessageCallbackARB)
90 GET_PROC(glDebugMessageControlARB)
91 GET_PROC(glDebugMessageInsertARB)
93 #undef GET_PROC
96 static BOOL gl_extension_supported(const char *extensions, const char *extension_string)
98 size_t ext_str_len = strlen(extension_string);
100 while (*extensions)
102 const char *start;
103 size_t len;
105 while (isspace(*extensions))
106 ++extensions;
107 start = extensions;
108 while (!isspace(*extensions) && *extensions)
109 ++extensions;
111 len = extensions - start;
112 if (!len)
113 continue;
115 if (len == ext_str_len && !memcmp(start, extension_string, ext_str_len))
117 return TRUE;
120 return FALSE;
123 static void test_pbuffers(HDC hdc)
125 const int iAttribList[] = { WGL_DRAW_TO_PBUFFER_ARB, 1, /* Request pbuffer support */
126 0 };
127 int iFormats[MAX_FORMATS];
128 unsigned int nOnscreenFormats;
129 unsigned int nFormats;
130 int i, res;
131 int iPixelFormat = 0;
133 nOnscreenFormats = DescribePixelFormat(hdc, 0, 0, NULL);
135 /* When you want to render to a pbuffer you need to call wglGetPbufferDCARB which
136 * returns a 'magic' HDC which you can then pass to wglMakeCurrent to switch rendering
137 * to the pbuffer. Below some tests are performed on what happens if you use standard WGL calls
138 * on this 'magic' HDC for both a pixelformat that support onscreen and offscreen rendering
139 * and a pixelformat that's only available for offscreen rendering (this means that only
140 * wglChoosePixelFormatARB and friends know about the format.
142 * The first thing we need are pixelformats with pbuffer capabilities.
144 res = pwglChoosePixelFormatARB(hdc, iAttribList, NULL, MAX_FORMATS, iFormats, &nFormats);
145 if(res <= 0)
147 skip("No pbuffer compatible formats found while WGL_ARB_pbuffer is supported\n");
148 return;
150 trace("nOnscreenFormats: %d\n", nOnscreenFormats);
151 trace("Total number of pbuffer capable pixelformats: %d\n", nFormats);
153 /* Try to select an onscreen pixelformat out of the list */
154 for(i=0; i < nFormats; i++)
156 /* Check if the format is onscreen, if it is choose it */
157 if(iFormats[i] <= nOnscreenFormats)
159 iPixelFormat = iFormats[i];
160 trace("Selected iPixelFormat=%d\n", iPixelFormat);
161 break;
165 /* A video driver supports a large number of onscreen and offscreen pixelformats.
166 * The traditional WGL calls only see a subset of the whole pixelformat list. First
167 * of all they only see the onscreen formats (the offscreen formats are at the end of the
168 * pixelformat list) and second extended pixelformat capabilities are hidden from the
169 * standard WGL calls. Only functions that depend on WGL_ARB_pixel_format can see them.
171 * Below we check if the pixelformat is also supported onscreen.
173 if(iPixelFormat != 0)
175 HDC pbuffer_hdc;
176 int attrib = 0;
177 HPBUFFERARB pbuffer = pwglCreatePbufferARB(hdc, iPixelFormat, 640 /* width */, 480 /* height */, &attrib);
178 if(!pbuffer)
179 skip("Pbuffer creation failed!\n");
181 /* Test the pixelformat returned by GetPixelFormat on a pbuffer as the behavior is not clear */
182 pbuffer_hdc = pwglGetPbufferDCARB(pbuffer);
183 res = GetPixelFormat(pbuffer_hdc);
184 ok(res == iPixelFormat, "Unexpected iPixelFormat=%d returned by GetPixelFormat for format %d\n", res, iPixelFormat);
185 trace("iPixelFormat returned by GetPixelFormat: %d\n", res);
186 trace("PixelFormat from wglChoosePixelFormatARB: %d\n", iPixelFormat);
188 pwglReleasePbufferDCARB(pbuffer, pbuffer_hdc);
190 else skip("Pbuffer test for onscreen pixelformat skipped as no onscreen format with pbuffer capabilities have been found\n");
192 /* Search for a real offscreen format */
193 for(i=0, iPixelFormat=0; i<nFormats; i++)
195 if(iFormats[i] > nOnscreenFormats)
197 iPixelFormat = iFormats[i];
198 trace("Selected iPixelFormat: %d\n", iPixelFormat);
199 break;
203 if(iPixelFormat != 0)
205 HDC pbuffer_hdc;
206 HPBUFFERARB pbuffer = pwglCreatePbufferARB(hdc, iPixelFormat, 640 /* width */, 480 /* height */, NULL);
207 if(pbuffer)
209 /* Test the pixelformat returned by GetPixelFormat on a pbuffer as the behavior is not clear */
210 pbuffer_hdc = pwglGetPbufferDCARB(pbuffer);
211 res = GetPixelFormat(pbuffer_hdc);
213 ok(res == 1, "Unexpected iPixelFormat=%d (1 expected) returned by GetPixelFormat for offscreen format %d\n", res, iPixelFormat);
214 trace("iPixelFormat returned by GetPixelFormat: %d\n", res);
215 trace("PixelFormat from wglChoosePixelFormatARB: %d\n", iPixelFormat);
216 pwglReleasePbufferDCARB(pbuffer, hdc);
218 else skip("Pbuffer creation failed!\n");
220 else skip("Pbuffer test for offscreen pixelformat skipped as no offscreen-only format with pbuffer capabilities has been found\n");
223 static int test_pfd(const PIXELFORMATDESCRIPTOR *pfd, PIXELFORMATDESCRIPTOR *fmt)
225 int pf;
226 HDC hdc;
227 HWND hwnd;
229 hwnd = CreateWindowA("static", "Title", WS_OVERLAPPEDWINDOW, 10, 10, 200, 200, NULL, NULL,
230 NULL, NULL);
231 if (!hwnd)
232 return 0;
234 hdc = GetDC( hwnd );
235 pf = ChoosePixelFormat( hdc, pfd );
236 if (pf && fmt)
238 INT ret;
239 memset(fmt, 0, sizeof(*fmt));
240 ret = DescribePixelFormat( hdc, pf, sizeof(*fmt), fmt );
241 ok(ret, "DescribePixelFormat failed with error: %u\n", GetLastError());
243 ReleaseDC( hwnd, hdc );
244 DestroyWindow( hwnd );
246 return pf;
249 static void test_choosepixelformat(void)
251 PIXELFORMATDESCRIPTOR pfd = {
252 sizeof(PIXELFORMATDESCRIPTOR),
253 1, /* version */
254 PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL,
255 PFD_TYPE_RGBA,
256 0, /* color depth */
257 0, 0, 0, 0, 0, 0, /* color bits */
258 0, /* alpha buffer */
259 0, /* shift bit */
260 0, /* accumulation buffer */
261 0, 0, 0, 0, /* accum bits */
262 0, /* z-buffer */
263 0, /* stencil buffer */
264 0, /* auxiliary buffer */
265 PFD_MAIN_PLANE, /* main layer */
266 0, /* reserved */
267 0, 0, 0 /* layer masks */
269 PIXELFORMATDESCRIPTOR ret_fmt;
271 ok( test_pfd(&pfd, NULL), "Simple pfd failed\n" );
272 pfd.dwFlags |= PFD_DOUBLEBUFFER_DONTCARE;
273 ok( test_pfd(&pfd, NULL), "PFD_DOUBLEBUFFER_DONTCARE failed\n" );
274 pfd.dwFlags |= PFD_STEREO_DONTCARE;
275 ok( test_pfd(&pfd, NULL), "PFD_DOUBLEBUFFER_DONTCARE|PFD_STEREO_DONTCARE failed\n" );
276 pfd.dwFlags &= ~PFD_DOUBLEBUFFER_DONTCARE;
277 ok( test_pfd(&pfd, NULL), "PFD_STEREO_DONTCARE failed\n" );
278 pfd.dwFlags &= ~PFD_STEREO_DONTCARE;
279 pfd.iPixelType = 32;
280 ok( test_pfd(&pfd, &ret_fmt), "Invalid pixel format 32 failed\n" );
281 ok( ret_fmt.iPixelType == PFD_TYPE_RGBA, "Expected pixel type PFD_TYPE_RGBA, got %d\n", ret_fmt.iPixelType );
282 pfd.iPixelType = 33;
283 ok( test_pfd(&pfd, &ret_fmt), "Invalid pixel format 33 failed\n" );
284 ok( ret_fmt.iPixelType == PFD_TYPE_RGBA, "Expected pixel type PFD_TYPE_RGBA, got %d\n", ret_fmt.iPixelType );
285 pfd.iPixelType = 15;
286 ok( test_pfd(&pfd, &ret_fmt), "Invalid pixel format 15 failed\n" );
287 ok( ret_fmt.iPixelType == PFD_TYPE_RGBA, "Expected pixel type PFD_TYPE_RGBA, got %d\n", ret_fmt.iPixelType );
288 pfd.iPixelType = PFD_TYPE_RGBA;
290 pfd.cColorBits = 32;
291 ok( test_pfd(&pfd, NULL), "Simple pfd failed\n" );
292 pfd.dwFlags |= PFD_DOUBLEBUFFER_DONTCARE;
293 ok( test_pfd(&pfd, NULL), "PFD_DOUBLEBUFFER_DONTCARE failed\n" );
294 pfd.dwFlags |= PFD_STEREO_DONTCARE;
295 ok( test_pfd(&pfd, NULL), "PFD_DOUBLEBUFFER_DONTCARE|PFD_STEREO_DONTCARE failed\n" );
296 pfd.dwFlags &= ~PFD_DOUBLEBUFFER_DONTCARE;
297 ok( test_pfd(&pfd, NULL), "PFD_STEREO_DONTCARE failed\n" );
298 pfd.dwFlags &= ~PFD_STEREO_DONTCARE;
299 pfd.cColorBits = 0;
301 pfd.cAlphaBits = 8;
302 ok( test_pfd(&pfd, NULL), "Simple pfd failed\n" );
303 pfd.dwFlags |= PFD_DOUBLEBUFFER_DONTCARE;
304 ok( test_pfd(&pfd, NULL), "PFD_DOUBLEBUFFER_DONTCARE failed\n" );
305 pfd.dwFlags |= PFD_STEREO_DONTCARE;
306 ok( test_pfd(&pfd, NULL), "PFD_DOUBLEBUFFER_DONTCARE|PFD_STEREO_DONTCARE failed\n" );
307 pfd.dwFlags &= ~PFD_DOUBLEBUFFER_DONTCARE;
308 ok( test_pfd(&pfd, NULL), "PFD_STEREO_DONTCARE failed\n" );
309 pfd.dwFlags &= ~PFD_STEREO_DONTCARE;
310 pfd.cAlphaBits = 0;
312 pfd.cStencilBits = 8;
313 ok( test_pfd(&pfd, NULL), "Simple pfd failed\n" );
314 pfd.dwFlags |= PFD_DOUBLEBUFFER_DONTCARE;
315 ok( test_pfd(&pfd, NULL), "PFD_DOUBLEBUFFER_DONTCARE failed\n" );
316 pfd.dwFlags |= PFD_STEREO_DONTCARE;
317 ok( test_pfd(&pfd, NULL), "PFD_DOUBLEBUFFER_DONTCARE|PFD_STEREO_DONTCARE failed\n" );
318 pfd.dwFlags &= ~PFD_DOUBLEBUFFER_DONTCARE;
319 ok( test_pfd(&pfd, NULL), "PFD_STEREO_DONTCARE failed\n" );
320 pfd.dwFlags &= ~PFD_STEREO_DONTCARE;
321 pfd.cStencilBits = 0;
323 pfd.cAuxBuffers = 1;
324 ok( test_pfd(&pfd, NULL), "Simple pfd failed\n" );
325 pfd.dwFlags |= PFD_DOUBLEBUFFER_DONTCARE;
326 ok( test_pfd(&pfd, NULL), "PFD_DOUBLEBUFFER_DONTCARE failed\n" );
327 pfd.dwFlags |= PFD_STEREO_DONTCARE;
328 ok( test_pfd(&pfd, NULL), "PFD_DOUBLEBUFFER_DONTCARE|PFD_STEREO_DONTCARE failed\n" );
329 pfd.dwFlags &= ~PFD_DOUBLEBUFFER_DONTCARE;
330 ok( test_pfd(&pfd, NULL), "PFD_STEREO_DONTCARE failed\n" );
331 pfd.dwFlags &= ~PFD_STEREO_DONTCARE;
332 pfd.cAuxBuffers = 0;
334 pfd.dwFlags |= PFD_DEPTH_DONTCARE;
335 pfd.cDepthBits = 24;
336 ok( test_pfd(&pfd, &ret_fmt), "PFD_DEPTH_DONTCARE failed.\n" );
337 ok( !ret_fmt.cDepthBits, "Got unexpected cDepthBits %u.\n", ret_fmt.cDepthBits );
338 pfd.cStencilBits = 8;
339 ok( test_pfd(&pfd, &ret_fmt), "PFD_DEPTH_DONTCARE, depth 24, stencil 8 failed.\n" );
340 ok( !ret_fmt.cDepthBits || ret_fmt.cDepthBits == 24, "Got unexpected cDepthBits %u.\n", ret_fmt.cDepthBits );
341 ok( ret_fmt.cStencilBits == 8, "Got unexpected cStencilBits %u.\n", ret_fmt.cStencilBits );
342 pfd.cDepthBits = 0;
343 pfd.cStencilBits = 0;
344 pfd.dwFlags &= ~PFD_DEPTH_DONTCARE;
347 static void WINAPI gl_debug_message_callback(GLenum source, GLenum type, GLuint id, GLenum severity,
348 GLsizei length, const GLchar *message, const void *userParam)
350 DWORD *count = (DWORD *)userParam;
351 (*count)++;
354 static void test_debug_message_callback(void)
356 static const char testmsg[] = "Hello World";
357 DWORD count;
359 if (!pglDebugMessageCallbackARB)
361 skip("glDebugMessageCallbackARB not supported\n");
362 return;
365 glEnable(GL_DEBUG_OUTPUT);
366 glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
368 pglDebugMessageCallbackARB(gl_debug_message_callback, &count);
369 pglDebugMessageControlARB(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_TRUE);
371 count = 0;
372 pglDebugMessageInsertARB(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_OTHER, 0x42424242,
373 GL_DEBUG_SEVERITY_LOW, sizeof(testmsg), testmsg);
374 ok(count == 1, "expected count == 1, got %u\n", count);
376 glDisable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
377 glDisable(GL_DEBUG_OUTPUT);
380 static void test_setpixelformat(HDC winhdc)
382 int res = 0;
383 int nCfgs;
384 int pf;
385 int i;
386 HWND hwnd;
387 PIXELFORMATDESCRIPTOR pfd = {
388 sizeof(PIXELFORMATDESCRIPTOR),
389 1, /* version */
390 PFD_DRAW_TO_WINDOW |
391 PFD_SUPPORT_OPENGL |
392 PFD_DOUBLEBUFFER,
393 PFD_TYPE_RGBA,
394 24, /* 24-bit color depth */
395 0, 0, 0, 0, 0, 0, /* color bits */
396 0, /* alpha buffer */
397 0, /* shift bit */
398 0, /* accumulation buffer */
399 0, 0, 0, 0, /* accum bits */
400 32, /* z-buffer */
401 0, /* stencil buffer */
402 0, /* auxiliary buffer */
403 PFD_MAIN_PLANE, /* main layer */
404 0, /* reserved */
405 0, 0, 0 /* layer masks */
408 HDC hdc = GetDC(0);
409 ok(hdc != 0, "GetDC(0) failed!\n");
411 /* This should pass even on the main device context */
412 pf = ChoosePixelFormat(hdc, &pfd);
413 ok(pf != 0, "ChoosePixelFormat failed on main device context\n");
415 /* SetPixelFormat on the main device context 'X root window' should fail,
416 * but some broken drivers allow it
418 res = SetPixelFormat(hdc, pf, &pfd);
419 trace("SetPixelFormat on main device context %s\n", res ? "succeeded" : "failed");
421 /* Setting the same format that was set on the HDC is allowed; other
422 formats fail */
423 nCfgs = DescribePixelFormat(winhdc, 0, 0, NULL);
424 pf = GetPixelFormat(winhdc);
425 for(i = 1;i <= nCfgs;i++)
427 int res = SetPixelFormat(winhdc, i, NULL);
428 if(i == pf) ok(res, "Failed to set the same pixel format\n");
429 else ok(!res, "Unexpectedly set an alternate pixel format\n");
432 hwnd = CreateWindowA("static", "Title", WS_OVERLAPPEDWINDOW, 10, 10, 200, 200, NULL, NULL,
433 NULL, NULL);
434 ok(hwnd != NULL, "err: %d\n", GetLastError());
435 if (hwnd)
437 HDC hdc = GetDC( hwnd );
438 pf = ChoosePixelFormat( hdc, &pfd );
439 ok( pf != 0, "ChoosePixelFormat failed\n" );
440 res = SetPixelFormat( hdc, pf, &pfd );
441 ok( res != 0, "SetPixelFormat failed\n" );
442 i = GetPixelFormat( hdc );
443 ok( i == pf, "GetPixelFormat returned wrong format %d/%d\n", i, pf );
444 ReleaseDC( hwnd, hdc );
445 hdc = GetWindowDC( hwnd );
446 i = GetPixelFormat( hdc );
447 ok( i == pf, "GetPixelFormat returned wrong format %d/%d\n", i, pf );
448 ReleaseDC( hwnd, hdc );
449 DestroyWindow( hwnd );
450 /* check various calls with invalid hdc */
451 SetLastError( 0xdeadbeef );
452 i = GetPixelFormat( hdc );
453 ok( i == 0, "GetPixelFormat succeeded\n" );
454 ok( GetLastError() == ERROR_INVALID_PIXEL_FORMAT, "wrong error %u\n", GetLastError() );
455 SetLastError( 0xdeadbeef );
456 res = SetPixelFormat( hdc, pf, &pfd );
457 ok( !res, "SetPixelFormat succeeded\n" );
458 ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError() );
459 SetLastError( 0xdeadbeef );
460 res = DescribePixelFormat( hdc, 0, 0, NULL );
461 ok( !res, "DescribePixelFormat succeeded\n" );
462 ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError() );
463 SetLastError( 0xdeadbeef );
464 pf = ChoosePixelFormat( hdc, &pfd );
465 ok( !pf, "ChoosePixelFormat succeeded\n" );
466 ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError() );
467 SetLastError( 0xdeadbeef );
468 res = SwapBuffers( hdc );
469 ok( !res, "SwapBuffers succeeded\n" );
470 ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError() );
471 SetLastError( 0xdeadbeef );
472 ok( !wglCreateContext( hdc ), "CreateContext succeeded\n" );
473 ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError() );
476 hwnd = CreateWindowA("static", "Title", WS_OVERLAPPEDWINDOW, 10, 10, 200, 200, NULL, NULL,
477 NULL, NULL);
478 ok(hwnd != NULL, "err: %d\n", GetLastError());
479 if (hwnd)
481 HDC hdc = GetWindowDC( hwnd );
482 pf = ChoosePixelFormat( hdc, &pfd );
483 ok( pf != 0, "ChoosePixelFormat failed\n" );
484 res = SetPixelFormat( hdc, pf, &pfd );
485 ok( res != 0, "SetPixelFormat failed\n" );
486 i = GetPixelFormat( hdc );
487 ok( i == pf, "GetPixelFormat returned wrong format %d/%d\n", i, pf );
488 ReleaseDC( hwnd, hdc );
489 DestroyWindow( hwnd );
493 static void test_sharelists(HDC winhdc)
495 HGLRC hglrc1, hglrc2, hglrc3;
496 BOOL res;
498 hglrc1 = wglCreateContext(winhdc);
499 res = wglShareLists(0, 0);
500 ok(res == FALSE, "Sharing display lists for no contexts passed!\n");
502 /* Test 1: Create a context and just share lists without doing anything special */
503 hglrc2 = wglCreateContext(winhdc);
504 if(hglrc2)
506 res = wglShareLists(hglrc1, hglrc2);
507 ok(res, "Sharing of display lists failed\n");
508 wglDeleteContext(hglrc2);
511 /* Test 2: Share display lists with a 'destination' context which has been made current */
512 hglrc2 = wglCreateContext(winhdc);
513 if(hglrc2)
515 res = wglMakeCurrent(winhdc, hglrc2);
516 ok(res, "Make current failed\n");
517 res = wglShareLists(hglrc1, hglrc2);
518 todo_wine ok(res, "Sharing display lists with a destination context which has been made current failed\n");
519 wglMakeCurrent(0, 0);
520 wglDeleteContext(hglrc2);
523 /* Test 3: Share display lists with a context which already shares display lists with another context.
524 * According to MSDN the second parameter cannot share any display lists but some buggy drivers might allow it */
525 hglrc3 = wglCreateContext(winhdc);
526 if(hglrc3)
528 res = wglShareLists(hglrc3, hglrc1);
529 ok(res == FALSE, "Sharing of display lists passed for a context which already shared lists before\n");
530 wglDeleteContext(hglrc3);
533 /* Test 4: Share display lists with a 'source' context which has been made current */
534 hglrc2 = wglCreateContext(winhdc);
535 if(hglrc2)
537 res = wglMakeCurrent(winhdc, hglrc1);
538 ok(res, "Make current failed\n");
539 res = wglShareLists(hglrc1, hglrc2);
540 ok(res, "Sharing display lists with a source context which has been made current failed\n");
541 wglMakeCurrent(0, 0);
542 wglDeleteContext(hglrc2);
546 static void test_makecurrent(HDC winhdc)
548 BOOL ret;
549 HGLRC hglrc;
551 hglrc = wglCreateContext(winhdc);
552 ok( hglrc != 0, "wglCreateContext failed\n" );
554 ret = wglMakeCurrent( winhdc, hglrc );
555 ok( ret, "wglMakeCurrent failed\n" );
557 ok( wglGetCurrentContext() == hglrc, "wrong context\n" );
559 /* set the same context again */
560 ret = wglMakeCurrent( winhdc, hglrc );
561 ok( ret, "wglMakeCurrent failed\n" );
563 /* check wglMakeCurrent(x, y) after another call to wglMakeCurrent(x, y) */
564 ret = wglMakeCurrent( winhdc, NULL );
565 ok( ret, "wglMakeCurrent failed\n" );
567 ret = wglMakeCurrent( winhdc, NULL );
568 ok( ret, "wglMakeCurrent failed\n" );
570 SetLastError( 0xdeadbeef );
571 ret = wglMakeCurrent( NULL, NULL );
572 ok( !ret || broken(ret) /* nt4 */, "wglMakeCurrent succeeded\n" );
573 if (!ret) ok( GetLastError() == ERROR_INVALID_HANDLE,
574 "Expected ERROR_INVALID_HANDLE, got error=%x\n", GetLastError() );
576 ret = wglMakeCurrent( winhdc, NULL );
577 ok( ret, "wglMakeCurrent failed\n" );
579 ret = wglMakeCurrent( winhdc, hglrc );
580 ok( ret, "wglMakeCurrent failed\n" );
582 ret = wglMakeCurrent( NULL, NULL );
583 ok( ret, "wglMakeCurrent failed\n" );
585 ok( wglGetCurrentContext() == NULL, "wrong context\n" );
587 SetLastError( 0xdeadbeef );
588 ret = wglMakeCurrent( NULL, NULL );
589 ok( !ret || broken(ret) /* nt4 */, "wglMakeCurrent succeeded\n" );
590 if (!ret) ok( GetLastError() == ERROR_INVALID_HANDLE,
591 "Expected ERROR_INVALID_HANDLE, got error=%x\n", GetLastError() );
593 ret = wglMakeCurrent( winhdc, hglrc );
594 ok( ret, "wglMakeCurrent failed\n" );
597 static void test_colorbits(HDC hdc)
599 const int iAttribList[] = { WGL_COLOR_BITS_ARB, WGL_RED_BITS_ARB, WGL_GREEN_BITS_ARB,
600 WGL_BLUE_BITS_ARB, WGL_ALPHA_BITS_ARB };
601 int iAttribRet[ARRAY_SIZE(iAttribList)];
602 const int iAttribs[] = { WGL_ALPHA_BITS_ARB, 1, 0 };
603 unsigned int nFormats;
604 BOOL res;
605 int iPixelFormat = 0;
607 if (!pwglChoosePixelFormatARB)
609 win_skip("wglChoosePixelFormatARB is not available\n");
610 return;
613 /* We need a pixel format with at least one bit of alpha */
614 res = pwglChoosePixelFormatARB(hdc, iAttribs, NULL, 1, &iPixelFormat, &nFormats);
615 if(res == FALSE || nFormats == 0)
617 skip("No suitable pixel formats found\n");
618 return;
621 res = pwglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0, ARRAY_SIZE(iAttribList), iAttribList,
622 iAttribRet);
623 if(res == FALSE)
625 skip("wglGetPixelFormatAttribivARB failed\n");
626 return;
628 iAttribRet[1] += iAttribRet[2]+iAttribRet[3]+iAttribRet[4];
629 ok(iAttribRet[0] == iAttribRet[1], "WGL_COLOR_BITS_ARB (%d) does not equal R+G+B+A (%d)!\n",
630 iAttribRet[0], iAttribRet[1]);
633 static void test_gdi_dbuf(HDC hdc)
635 const int iAttribList[] = { WGL_SUPPORT_GDI_ARB, WGL_DOUBLE_BUFFER_ARB };
636 int iAttribRet[ARRAY_SIZE(iAttribList)];
637 unsigned int nFormats;
638 int iPixelFormat;
639 BOOL res;
641 if (!pwglGetPixelFormatAttribivARB)
643 win_skip("wglGetPixelFormatAttribivARB is not available\n");
644 return;
647 nFormats = DescribePixelFormat(hdc, 0, 0, NULL);
648 for(iPixelFormat = 1;iPixelFormat <= nFormats;iPixelFormat++)
650 res = pwglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0, ARRAY_SIZE(iAttribList),
651 iAttribList, iAttribRet);
652 ok(res!=FALSE, "wglGetPixelFormatAttribivARB failed for pixel format %d\n", iPixelFormat);
653 if(res == FALSE)
654 continue;
656 ok(!(iAttribRet[0] && iAttribRet[1]), "GDI support and double buffering on pixel format %d\n", iPixelFormat);
660 static void test_acceleration(HDC hdc)
662 const int iAttribList[] = { WGL_ACCELERATION_ARB };
663 int iAttribRet[ARRAY_SIZE(iAttribList)];
664 unsigned int nFormats;
665 int iPixelFormat;
666 int res;
667 PIXELFORMATDESCRIPTOR pfd;
669 if (!pwglGetPixelFormatAttribivARB)
671 win_skip("wglGetPixelFormatAttribivARB is not available\n");
672 return;
675 nFormats = DescribePixelFormat(hdc, 0, 0, NULL);
676 for(iPixelFormat = 1; iPixelFormat <= nFormats; iPixelFormat++)
678 res = pwglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0, ARRAY_SIZE(iAttribList),
679 iAttribList, iAttribRet);
680 ok(res!=FALSE, "wglGetPixelFormatAttribivARB failed for pixel format %d\n", iPixelFormat);
681 if(res == FALSE)
682 continue;
684 memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
685 DescribePixelFormat(hdc, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
687 switch(iAttribRet[0])
689 case WGL_NO_ACCELERATION_ARB:
690 ok( (pfd.dwFlags & (PFD_GENERIC_FORMAT | PFD_GENERIC_ACCELERATED)) == PFD_GENERIC_FORMAT , "Expected only PFD_GENERIC_FORMAT to be set for WGL_NO_ACCELERATION_ARB!: iPixelFormat=%d, dwFlags=%x!\n", iPixelFormat, pfd.dwFlags);
691 break;
692 case WGL_GENERIC_ACCELERATION_ARB:
693 ok( (pfd.dwFlags & (PFD_GENERIC_FORMAT | PFD_GENERIC_ACCELERATED)) == (PFD_GENERIC_FORMAT | PFD_GENERIC_ACCELERATED), "Expected both PFD_GENERIC_FORMAT and PFD_GENERIC_ACCELERATION to be set for WGL_GENERIC_ACCELERATION_ARB: iPixelFormat=%d, dwFlags=%x!\n", iPixelFormat, pfd.dwFlags);
694 break;
695 case WGL_FULL_ACCELERATION_ARB:
696 ok( (pfd.dwFlags & (PFD_GENERIC_FORMAT | PFD_GENERIC_ACCELERATED)) == 0, "Expected no PFD_GENERIC_FORMAT/_ACCELERATION to be set for WGL_FULL_ACCELERATION_ARB: iPixelFormat=%d, dwFlags=%x!\n", iPixelFormat, pfd.dwFlags);
697 break;
702 static void test_bitmap_rendering( BOOL use_dib )
704 PIXELFORMATDESCRIPTOR pfd;
705 int i, ret, bpp, iPixelFormat=0;
706 unsigned int nFormats;
707 HGLRC hglrc, hglrc2;
708 BITMAPINFO biDst;
709 HBITMAP bmpDst, oldDst, bmp2;
710 HDC hdcDst, hdcScreen;
711 UINT *dstBuffer = NULL;
713 hdcScreen = CreateCompatibleDC(0);
714 hdcDst = CreateCompatibleDC(0);
716 if (use_dib)
718 bpp = 32;
719 memset(&biDst, 0, sizeof(BITMAPINFO));
720 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
721 biDst.bmiHeader.biWidth = 4;
722 biDst.bmiHeader.biHeight = -4;
723 biDst.bmiHeader.biPlanes = 1;
724 biDst.bmiHeader.biBitCount = 32;
725 biDst.bmiHeader.biCompression = BI_RGB;
727 bmpDst = CreateDIBSection(0, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer, NULL, 0);
729 biDst.bmiHeader.biWidth = 12;
730 biDst.bmiHeader.biHeight = -12;
731 biDst.bmiHeader.biBitCount = 16;
732 bmp2 = CreateDIBSection(0, &biDst, DIB_RGB_COLORS, NULL, NULL, 0);
734 else
736 bpp = GetDeviceCaps( hdcScreen, BITSPIXEL );
737 bmpDst = CreateBitmap( 4, 4, 1, bpp, NULL );
738 bmp2 = CreateBitmap( 12, 12, 1, bpp, NULL );
741 oldDst = SelectObject(hdcDst, bmpDst);
743 trace( "testing on %s\n", use_dib ? "DIB" : "DDB" );
745 /* Pick a pixel format by hand because ChoosePixelFormat is unreliable */
746 nFormats = DescribePixelFormat(hdcDst, 0, 0, NULL);
747 for(i=1; i<=nFormats; i++)
749 memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
750 DescribePixelFormat(hdcDst, i, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
752 if((pfd.dwFlags & PFD_DRAW_TO_BITMAP) &&
753 (pfd.dwFlags & PFD_SUPPORT_OPENGL) &&
754 (pfd.cColorBits == bpp) &&
755 (pfd.cAlphaBits == 8) )
757 iPixelFormat = i;
758 break;
762 if(!iPixelFormat)
764 skip("Unable to find a suitable pixel format\n");
766 else
768 ret = SetPixelFormat(hdcDst, iPixelFormat, &pfd);
769 ok( ret, "SetPixelFormat failed\n" );
770 ret = GetPixelFormat( hdcDst );
771 ok( ret == iPixelFormat, "GetPixelFormat returned %d/%d\n", ret, iPixelFormat );
772 ret = SetPixelFormat(hdcDst, iPixelFormat + 1, &pfd);
773 ok( !ret, "SetPixelFormat succeeded\n" );
774 hglrc = wglCreateContext(hdcDst);
775 ok(hglrc != NULL, "Unable to create a context\n");
777 if(hglrc)
779 GLint viewport[4];
780 wglMakeCurrent(hdcDst, hglrc);
781 hglrc2 = wglCreateContext(hdcDst);
782 ok(hglrc2 != NULL, "Unable to create a context\n");
784 /* Note this is RGBA but we read ARGB back */
785 glClearColor((float)0x22/0xff, (float)0x33/0xff, (float)0x44/0xff, (float)0x11/0xff);
786 glClear(GL_COLOR_BUFFER_BIT);
787 glGetIntegerv( GL_VIEWPORT, viewport );
788 glFinish();
790 ok( viewport[0] == 0 && viewport[1] == 0 && viewport[2] == 4 && viewport[3] == 4,
791 "wrong viewport %d,%d,%d,%d\n", viewport[0], viewport[1], viewport[2], viewport[3] );
792 /* Note apparently the alpha channel is not supported by the software renderer (bitmap only works using software) */
793 if (dstBuffer)
794 for (i = 0; i < 16; i++)
795 ok(dstBuffer[i] == 0x223344 || dstBuffer[i] == 0x11223344, "Received color=%x at %u\n",
796 dstBuffer[i], i);
798 SelectObject(hdcDst, bmp2);
799 ret = GetPixelFormat( hdcDst );
800 ok( ret == iPixelFormat, "GetPixelFormat returned %d/%d\n", ret, iPixelFormat );
801 ret = SetPixelFormat(hdcDst, iPixelFormat + 1, &pfd);
802 ok( !ret, "SetPixelFormat succeeded\n" );
804 /* context still uses the old pixel format and viewport */
805 glClearColor((float)0x44/0xff, (float)0x33/0xff, (float)0x22/0xff, (float)0x11/0xff);
806 glClear(GL_COLOR_BUFFER_BIT);
807 glFinish();
808 glGetIntegerv( GL_VIEWPORT, viewport );
809 ok( viewport[0] == 0 && viewport[1] == 0 && viewport[2] == 4 && viewport[3] == 4,
810 "wrong viewport %d,%d,%d,%d\n", viewport[0], viewport[1], viewport[2], viewport[3] );
812 wglMakeCurrent(NULL, NULL);
813 wglMakeCurrent(hdcDst, hglrc);
814 glClearColor((float)0x44/0xff, (float)0x55/0xff, (float)0x66/0xff, (float)0x11/0xff);
815 glClear(GL_COLOR_BUFFER_BIT);
816 glFinish();
817 glGetIntegerv( GL_VIEWPORT, viewport );
818 ok( viewport[0] == 0 && viewport[1] == 0 && viewport[2] == 4 && viewport[3] == 4,
819 "wrong viewport %d,%d,%d,%d\n", viewport[0], viewport[1], viewport[2], viewport[3] );
821 wglMakeCurrent(hdcDst, hglrc2);
822 glGetIntegerv( GL_VIEWPORT, viewport );
823 ok( viewport[0] == 0 && viewport[1] == 0 && viewport[2] == 12 && viewport[3] == 12,
824 "wrong viewport %d,%d,%d,%d\n", viewport[0], viewport[1], viewport[2], viewport[3] );
826 wglMakeCurrent(hdcDst, hglrc);
827 glGetIntegerv( GL_VIEWPORT, viewport );
828 ok( viewport[0] == 0 && viewport[1] == 0 && viewport[2] == 4 && viewport[3] == 4,
829 "wrong viewport %d,%d,%d,%d\n", viewport[0], viewport[1], viewport[2], viewport[3] );
831 SelectObject(hdcDst, bmpDst);
832 ret = GetPixelFormat( hdcDst );
833 ok( ret == iPixelFormat, "GetPixelFormat returned %d/%d\n", ret, iPixelFormat );
834 ret = SetPixelFormat(hdcDst, iPixelFormat + 1, &pfd);
835 ok( !ret, "SetPixelFormat succeeded\n" );
836 wglMakeCurrent(hdcDst, hglrc2);
837 glGetIntegerv( GL_VIEWPORT, viewport );
838 ok( viewport[0] == 0 && viewport[1] == 0 && viewport[2] == 12 && viewport[3] == 12,
839 "wrong viewport %d,%d,%d,%d\n", viewport[0], viewport[1], viewport[2], viewport[3] );
841 wglDeleteContext(hglrc2);
842 wglDeleteContext(hglrc);
846 SelectObject(hdcDst, oldDst);
847 DeleteObject(bmp2);
848 DeleteObject(bmpDst);
849 DeleteDC(hdcDst);
850 DeleteDC(hdcScreen);
853 struct wgl_thread_param
855 HANDLE test_finished;
856 HWND hwnd;
857 HGLRC hglrc;
858 BOOL make_current;
859 BOOL make_current_error;
860 BOOL deleted;
861 DWORD deleted_error;
864 static DWORD WINAPI wgl_thread(void *param)
866 struct wgl_thread_param *p = param;
867 HDC hdc = GetDC( p->hwnd );
869 ok(!glGetString(GL_RENDERER) && !glGetString(GL_VERSION) && !glGetString(GL_VENDOR),
870 "Expected NULL string when no active context is set\n");
872 SetLastError(0xdeadbeef);
873 p->make_current = wglMakeCurrent(hdc, p->hglrc);
874 p->make_current_error = GetLastError();
875 p->deleted = wglDeleteContext(p->hglrc);
876 p->deleted_error = GetLastError();
877 ReleaseDC( p->hwnd, hdc );
878 SetEvent(p->test_finished);
879 return 0;
882 static void test_deletecontext(HWND hwnd, HDC hdc)
884 struct wgl_thread_param thread_params;
885 HGLRC hglrc = wglCreateContext(hdc);
886 HANDLE thread_handle;
887 BOOL res;
888 DWORD tid;
890 SetLastError(0xdeadbeef);
891 res = wglDeleteContext(NULL);
892 ok(res == FALSE, "wglDeleteContext succeeded\n");
893 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected last error to be ERROR_INVALID_HANDLE, got %u\n", GetLastError());
895 if(!hglrc)
897 skip("wglCreateContext failed!\n");
898 return;
901 res = wglMakeCurrent(hdc, hglrc);
902 if(!res)
904 skip("wglMakeCurrent failed!\n");
905 return;
908 /* WGL doesn't allow you to delete a context from a different thread than the one in which it is current.
909 * This differs from GLX which does allow it but it delays actual deletion until the context becomes not current.
911 thread_params.hglrc = hglrc;
912 thread_params.hwnd = hwnd;
913 thread_params.test_finished = CreateEventW(NULL, FALSE, FALSE, NULL);
914 thread_handle = CreateThread(NULL, 0, wgl_thread, &thread_params, 0, &tid);
915 ok(!!thread_handle, "Failed to create thread, last error %#x.\n", GetLastError());
916 if(thread_handle)
918 WaitForSingleObject(thread_handle, INFINITE);
919 ok(!thread_params.make_current, "Attempt to make WGL context from another thread passed\n");
920 ok(thread_params.make_current_error == ERROR_BUSY, "Expected last error to be ERROR_BUSY, got %u\n", thread_params.make_current_error);
921 ok(!thread_params.deleted, "Attempt to delete WGL context from another thread passed\n");
922 ok(thread_params.deleted_error == ERROR_BUSY, "Expected last error to be ERROR_BUSY, got %u\n", thread_params.deleted_error);
924 CloseHandle(thread_params.test_finished);
926 res = wglDeleteContext(hglrc);
927 ok(res == TRUE, "wglDeleteContext failed\n");
929 /* Attempting to delete the same context twice should fail. */
930 SetLastError(0xdeadbeef);
931 res = wglDeleteContext(hglrc);
932 ok(res == FALSE, "wglDeleteContext succeeded\n");
933 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected last error to be ERROR_INVALID_HANDLE, got %u\n", GetLastError());
935 /* WGL makes a context not current when deleting it. This differs from GLX behavior where
936 * deletion takes place when the thread becomes not current. */
937 hglrc = wglGetCurrentContext();
938 ok(hglrc == NULL, "A WGL context is active while none was expected\n");
942 static void test_getprocaddress(HDC hdc)
944 const char *extensions = (const char*)glGetString(GL_EXTENSIONS);
945 PROC func = NULL;
946 HGLRC ctx = wglGetCurrentContext();
948 if (!extensions)
950 skip("skipping wglGetProcAddress tests because no GL extensions supported\n");
951 return;
954 /* Core GL 1.0/1.1 functions should not be loadable through wglGetProcAddress.
955 * Try to load the function with and without a context.
957 func = wglGetProcAddress("glEnable");
958 ok(func == NULL, "Lookup of function glEnable with a context passed, expected a failure\n");
959 wglMakeCurrent(hdc, NULL);
960 func = wglGetProcAddress("glEnable");
961 ok(func == NULL, "Lookup of function glEnable without a context passed, expected a failure\n");
962 wglMakeCurrent(hdc, ctx);
964 /* The goal of the test will be to test behavior of wglGetProcAddress when
965 * no WGL context is active. Before the test we pick an extension (GL_ARB_multitexture)
966 * which any GL >=1.2.1 implementation supports. Unfortunately the GDI renderer doesn't
967 * support it. There aren't any extensions we can use for this test which are supported by
968 * both GDI and real drivers.
969 * Note GDI only has GL_EXT_bgra, GL_EXT_paletted_texture and GL_WIN_swap_hint.
971 if (!gl_extension_supported(extensions, "GL_ARB_multitexture"))
973 skip("skipping test because lack of GL_ARB_multitexture support\n");
974 return;
977 func = wglGetProcAddress("glActiveTextureARB");
978 ok(func != NULL, "Unable to lookup glActiveTextureARB, last error %#x\n", GetLastError());
980 /* Temporarily disable the context, so we can see that we can't retrieve functions now. */
981 wglMakeCurrent(hdc, NULL);
982 func = wglGetProcAddress("glActiveTextureARB");
983 ok(func == NULL, "Function lookup without a context passed, expected a failure; last error %#x\n", GetLastError());
984 wglMakeCurrent(hdc, ctx);
987 static void test_make_current_read(HDC hdc)
989 int res;
990 HDC hread;
991 HGLRC hglrc = wglCreateContext(hdc);
993 if(!hglrc)
995 skip("wglCreateContext failed!\n");
996 return;
999 res = wglMakeCurrent(hdc, hglrc);
1000 if(!res)
1002 skip("wglMakeCurrent failed!\n");
1003 return;
1006 /* Test what wglGetCurrentReadDCARB does for wglMakeCurrent as the spec doesn't mention it */
1007 hread = pwglGetCurrentReadDCARB();
1008 trace("hread %p, hdc %p\n", hread, hdc);
1009 ok(hread == hdc, "wglGetCurrentReadDCARB failed for standard wglMakeCurrent\n");
1011 pwglMakeContextCurrentARB(hdc, hdc, hglrc);
1012 hread = pwglGetCurrentReadDCARB();
1013 ok(hread == hdc, "wglGetCurrentReadDCARB failed for wglMakeContextCurrent\n");
1016 static void test_dc(HWND hwnd, HDC hdc)
1018 int pf1, pf2;
1019 HDC hdc2;
1021 /* Get another DC and make sure it has the same pixel format */
1022 hdc2 = GetDC(hwnd);
1023 if(hdc != hdc2)
1025 pf1 = GetPixelFormat(hdc);
1026 pf2 = GetPixelFormat(hdc2);
1027 ok(pf1 == pf2, "Second DC does not have the same format (%d != %d)\n", pf1, pf2);
1029 else
1030 skip("Could not get a different DC for the window\n");
1032 if(hdc2)
1034 ReleaseDC(hwnd, hdc2);
1035 hdc2 = NULL;
1039 /* Nvidia converts win32 error codes to (0xc007 << 16) | win32_error_code */
1040 #define NVIDIA_HRESULT_FROM_WIN32(x) (HRESULT_FROM_WIN32(x) | 0x40000000)
1041 static void test_opengl3(HDC hdc)
1043 /* Try to create a context compatible with OpenGL 1.x; 1.0-2.1 is allowed */
1045 HGLRC gl3Ctx;
1046 int attribs[] = {WGL_CONTEXT_MAJOR_VERSION_ARB, 1, 0};
1048 gl3Ctx = pwglCreateContextAttribsARB(hdc, 0, attribs);
1049 ok(gl3Ctx != 0, "pwglCreateContextAttribsARB for a 1.x context failed!\n");
1050 wglDeleteContext(gl3Ctx);
1053 /* Try to pass an invalid HDC */
1055 HGLRC gl3Ctx;
1056 DWORD error;
1057 SetLastError(0xdeadbeef);
1058 gl3Ctx = pwglCreateContextAttribsARB((HDC)0xdeadbeef, 0, 0);
1059 ok(gl3Ctx == 0, "pwglCreateContextAttribsARB using an invalid HDC passed\n");
1060 error = GetLastError();
1061 ok(error == ERROR_DC_NOT_FOUND || error == ERROR_INVALID_HANDLE ||
1062 broken(error == ERROR_DS_GENERIC_ERROR) ||
1063 broken(error == NVIDIA_HRESULT_FROM_WIN32(ERROR_INVALID_DATA)), /* Nvidia Vista + Win7 */
1064 "Expected ERROR_DC_NOT_FOUND, got error=%x\n", error);
1065 wglDeleteContext(gl3Ctx);
1068 /* Try to pass an invalid shareList */
1070 HGLRC gl3Ctx;
1071 DWORD error;
1072 SetLastError(0xdeadbeef);
1073 gl3Ctx = pwglCreateContextAttribsARB(hdc, (HGLRC)0xdeadbeef, 0);
1074 ok(gl3Ctx == 0, "pwglCreateContextAttribsARB using an invalid shareList passed\n");
1075 error = GetLastError();
1076 /* The Nvidia implementation seems to return hresults instead of win32 error codes */
1077 ok(error == ERROR_INVALID_OPERATION || error == ERROR_INVALID_DATA ||
1078 error == NVIDIA_HRESULT_FROM_WIN32(ERROR_INVALID_OPERATION), "Expected ERROR_INVALID_OPERATION, got error=%x\n", error);
1079 wglDeleteContext(gl3Ctx);
1082 /* Try to create an OpenGL 3.0 context */
1084 int attribs[] = {WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 0, 0};
1085 HGLRC gl3Ctx = pwglCreateContextAttribsARB(hdc, 0, attribs);
1087 if(gl3Ctx == NULL)
1089 skip("Skipping the rest of the WGL_ARB_create_context test due to lack of OpenGL 3.0\n");
1090 return;
1093 wglDeleteContext(gl3Ctx);
1096 /* Test matching an OpenGL 3.0 context with an older one, OpenGL 3.0 should allow it until the new object model is introduced in a future revision */
1098 HGLRC glCtx = wglCreateContext(hdc);
1100 int attribs[] = {WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 0, 0};
1101 int attribs_future[] = {WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 0, 0};
1103 HGLRC gl3Ctx = pwglCreateContextAttribsARB(hdc, glCtx, attribs);
1104 ok(gl3Ctx != NULL, "Sharing of a display list between OpenGL 3.0 and OpenGL 1.x/2.x failed!\n");
1105 if(gl3Ctx)
1106 wglDeleteContext(gl3Ctx);
1108 gl3Ctx = pwglCreateContextAttribsARB(hdc, glCtx, attribs_future);
1109 ok(gl3Ctx != NULL, "Sharing of a display list between a forward compatible OpenGL 3.0 context and OpenGL 1.x/2.x failed!\n");
1110 if(gl3Ctx)
1111 wglDeleteContext(gl3Ctx);
1113 if(glCtx)
1114 wglDeleteContext(glCtx);
1117 /* Try to create an OpenGL 3.0 context and test windowless rendering */
1119 HGLRC gl3Ctx;
1120 int attribs[] = {WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 0, 0};
1121 BOOL res;
1123 gl3Ctx = pwglCreateContextAttribsARB(hdc, 0, attribs);
1124 ok(gl3Ctx != 0, "pwglCreateContextAttribsARB for a 3.0 context failed!\n");
1126 /* OpenGL 3.0 allows offscreen rendering WITHOUT a drawable
1127 * Neither AMD or Nvidia support it at this point. The WGL_ARB_create_context specs also say that
1128 * it is hard because drivers use the HDC to enter the display driver and it sounds like they don't
1129 * expect drivers to ever offer it.
1131 res = wglMakeCurrent(0, gl3Ctx);
1132 ok(res == FALSE, "Wow, OpenGL 3.0 windowless rendering passed while it was expected not to!\n");
1133 if(res)
1134 wglMakeCurrent(0, 0);
1136 if(gl3Ctx)
1137 wglDeleteContext(gl3Ctx);
1141 static void test_minimized(void)
1143 PIXELFORMATDESCRIPTOR pf_desc =
1145 sizeof(PIXELFORMATDESCRIPTOR),
1146 1, /* version */
1147 PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
1148 PFD_TYPE_RGBA,
1149 24, /* 24-bit color depth */
1150 0, 0, 0, 0, 0, 0, /* color bits */
1151 0, /* alpha buffer */
1152 0, /* shift bit */
1153 0, /* accumulation buffer */
1154 0, 0, 0, 0, /* accum bits */
1155 32, /* z-buffer */
1156 0, /* stencil buffer */
1157 0, /* auxiliary buffer */
1158 PFD_MAIN_PLANE, /* main layer */
1159 0, /* reserved */
1160 0, 0, 0 /* layer masks */
1162 int pixel_format;
1163 HWND window;
1164 LONG style;
1165 HGLRC ctx;
1166 BOOL ret;
1167 HDC dc;
1169 window = CreateWindowA("static", "opengl32_test",
1170 WS_POPUP | WS_MINIMIZE, 0, 0, 640, 480, 0, 0, 0, 0);
1171 ok(!!window, "Failed to create window, last error %#x.\n", GetLastError());
1173 dc = GetDC(window);
1174 ok(!!dc, "Failed to get DC.\n");
1176 pixel_format = ChoosePixelFormat(dc, &pf_desc);
1177 if (!pixel_format)
1179 win_skip("Failed to find pixel format.\n");
1180 ReleaseDC(window, dc);
1181 DestroyWindow(window);
1182 return;
1185 ret = SetPixelFormat(dc, pixel_format, &pf_desc);
1186 ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError());
1188 style = GetWindowLongA(window, GWL_STYLE);
1189 ok(style & WS_MINIMIZE, "Window should be minimized, got style %#x.\n", style);
1191 ctx = wglCreateContext(dc);
1192 ok(!!ctx, "Failed to create GL context, last error %#x.\n", GetLastError());
1194 ret = wglMakeCurrent(dc, ctx);
1195 ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1197 style = GetWindowLongA(window, GWL_STYLE);
1198 ok(style & WS_MINIMIZE, "window should be minimized, got style %#x.\n", style);
1200 ret = wglMakeCurrent(NULL, NULL);
1201 ok(ret, "Failed to clear current context, last error %#x.\n", GetLastError());
1203 ret = wglDeleteContext(ctx);
1204 ok(ret, "Failed to delete GL context, last error %#x.\n", GetLastError());
1206 ReleaseDC(window, dc);
1207 DestroyWindow(window);
1210 static void test_window_dc(void)
1212 PIXELFORMATDESCRIPTOR pf_desc =
1214 sizeof(PIXELFORMATDESCRIPTOR),
1215 1, /* version */
1216 PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
1217 PFD_TYPE_RGBA,
1218 24, /* 24-bit color depth */
1219 0, 0, 0, 0, 0, 0, /* color bits */
1220 0, /* alpha buffer */
1221 0, /* shift bit */
1222 0, /* accumulation buffer */
1223 0, 0, 0, 0, /* accum bits */
1224 32, /* z-buffer */
1225 0, /* stencil buffer */
1226 0, /* auxiliary buffer */
1227 PFD_MAIN_PLANE, /* main layer */
1228 0, /* reserved */
1229 0, 0, 0 /* layer masks */
1231 int pixel_format;
1232 HWND window;
1233 RECT vp, r;
1234 HGLRC ctx;
1235 BOOL ret;
1236 HDC dc;
1238 window = CreateWindowA("static", "opengl32_test",
1239 WS_OVERLAPPEDWINDOW, 0, 0, 640, 480, 0, 0, 0, 0);
1240 ok(!!window, "Failed to create window, last error %#x.\n", GetLastError());
1242 ShowWindow(window, SW_SHOW);
1244 dc = GetWindowDC(window);
1245 ok(!!dc, "Failed to get DC.\n");
1247 pixel_format = ChoosePixelFormat(dc, &pf_desc);
1248 if (!pixel_format)
1250 win_skip("Failed to find pixel format.\n");
1251 ReleaseDC(window, dc);
1252 DestroyWindow(window);
1253 return;
1256 ret = SetPixelFormat(dc, pixel_format, &pf_desc);
1257 ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError());
1259 ctx = wglCreateContext(dc);
1260 ok(!!ctx, "Failed to create GL context, last error %#x.\n", GetLastError());
1262 ret = wglMakeCurrent(dc, ctx);
1263 ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1265 GetClientRect(window, &r);
1266 glGetIntegerv(GL_VIEWPORT, (GLint *)&vp);
1267 ok(EqualRect(&r, &vp), "Viewport not equal to client rect.\n");
1269 ret = wglMakeCurrent(NULL, NULL);
1270 ok(ret, "Failed to clear current context, last error %#x.\n", GetLastError());
1272 ret = wglDeleteContext(ctx);
1273 ok(ret, "Failed to delete GL context, last error %#x.\n", GetLastError());
1275 ReleaseDC(window, dc);
1276 DestroyWindow(window);
1279 static void test_message_window(void)
1281 PIXELFORMATDESCRIPTOR pf_desc =
1283 sizeof(PIXELFORMATDESCRIPTOR),
1284 1, /* version */
1285 PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
1286 PFD_TYPE_RGBA,
1287 24, /* 24-bit color depth */
1288 0, 0, 0, 0, 0, 0, /* color bits */
1289 0, /* alpha buffer */
1290 0, /* shift bit */
1291 0, /* accumulation buffer */
1292 0, 0, 0, 0, /* accum bits */
1293 32, /* z-buffer */
1294 0, /* stencil buffer */
1295 0, /* auxiliary buffer */
1296 PFD_MAIN_PLANE, /* main layer */
1297 0, /* reserved */
1298 0, 0, 0 /* layer masks */
1300 int pixel_format;
1301 HWND window;
1302 RECT vp, r;
1303 HGLRC ctx;
1304 BOOL ret;
1305 HDC dc;
1306 GLenum glerr;
1308 window = CreateWindowA("static", "opengl32_test",
1309 WS_OVERLAPPEDWINDOW, 0, 0, 100, 100, HWND_MESSAGE, 0, 0, 0);
1310 if (!window)
1312 win_skip( "HWND_MESSAGE not supported\n" );
1313 return;
1315 dc = GetDC(window);
1316 ok(!!dc, "Failed to get DC.\n");
1318 pixel_format = ChoosePixelFormat(dc, &pf_desc);
1319 if (!pixel_format)
1321 win_skip("Failed to find pixel format.\n");
1322 ReleaseDC(window, dc);
1323 DestroyWindow(window);
1324 return;
1327 ret = SetPixelFormat(dc, pixel_format, &pf_desc);
1328 ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError());
1330 ctx = wglCreateContext(dc);
1331 ok(!!ctx, "Failed to create GL context, last error %#x.\n", GetLastError());
1333 ret = wglMakeCurrent(dc, ctx);
1334 ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1336 GetClientRect(window, &r);
1337 glGetIntegerv(GL_VIEWPORT, (GLint *)&vp);
1338 ok(EqualRect(&r, &vp), "Viewport not equal to client rect.\n");
1340 glClear(GL_COLOR_BUFFER_BIT);
1341 glFinish();
1342 glerr = glGetError();
1343 ok(glerr == GL_NO_ERROR, "Failed glClear, error %#x.\n", glerr);
1344 ret = SwapBuffers(dc);
1345 ok(ret, "Failed SwapBuffers, error %#x.\n", GetLastError());
1347 ret = wglMakeCurrent(NULL, NULL);
1348 ok(ret, "Failed to clear current context, last error %#x.\n", GetLastError());
1350 ret = wglDeleteContext(ctx);
1351 ok(ret, "Failed to delete GL context, last error %#x.\n", GetLastError());
1353 ReleaseDC(window, dc);
1354 DestroyWindow(window);
1357 static void test_destroy(HDC oldhdc)
1359 PIXELFORMATDESCRIPTOR pf_desc =
1361 sizeof(PIXELFORMATDESCRIPTOR),
1362 1, /* version */
1363 PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
1364 PFD_TYPE_RGBA,
1365 24, /* 24-bit color depth */
1366 0, 0, 0, 0, 0, 0, /* color bits */
1367 0, /* alpha buffer */
1368 0, /* shift bit */
1369 0, /* accumulation buffer */
1370 0, 0, 0, 0, /* accum bits */
1371 32, /* z-buffer */
1372 0, /* stencil buffer */
1373 0, /* auxiliary buffer */
1374 PFD_MAIN_PLANE, /* main layer */
1375 0, /* reserved */
1376 0, 0, 0 /* layer masks */
1378 int pixel_format;
1379 HWND window;
1380 HGLRC ctx;
1381 BOOL ret;
1382 HDC dc;
1383 GLenum glerr;
1384 DWORD err;
1385 HGLRC oldctx = wglGetCurrentContext();
1387 ok(!!oldctx, "Expected to find a valid current context.\n");
1389 window = CreateWindowA("static", "opengl32_test",
1390 WS_POPUP, 0, 0, 640, 480, 0, 0, 0, 0);
1391 ok(!!window, "Failed to create window, last error %#x.\n", GetLastError());
1393 dc = GetDC(window);
1394 ok(!!dc, "Failed to get DC.\n");
1396 pixel_format = ChoosePixelFormat(dc, &pf_desc);
1397 if (!pixel_format)
1399 win_skip("Failed to find pixel format.\n");
1400 ReleaseDC(window, dc);
1401 DestroyWindow(window);
1402 return;
1405 ret = SetPixelFormat(dc, pixel_format, &pf_desc);
1406 ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError());
1408 ctx = wglCreateContext(dc);
1409 ok(!!ctx, "Failed to create GL context, last error %#x.\n", GetLastError());
1411 ret = wglMakeCurrent(dc, ctx);
1412 ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1414 glClear(GL_COLOR_BUFFER_BIT);
1415 glFinish();
1416 glerr = glGetError();
1417 ok(glerr == GL_NO_ERROR, "Failed glClear, error %#x.\n", glerr);
1418 ret = SwapBuffers(dc);
1419 ok(ret, "Failed SwapBuffers, error %#x.\n", GetLastError());
1421 ret = DestroyWindow(window);
1422 ok(ret, "Failed to destroy window, last error %#x.\n", GetLastError());
1424 ok(wglGetCurrentContext() == ctx, "Wrong current context.\n");
1426 SetLastError(0xdeadbeef);
1427 ret = wglMakeCurrent(dc, ctx);
1428 err = GetLastError();
1429 ok(!ret && err == ERROR_INVALID_HANDLE,
1430 "Unexpected behavior when making context current, ret %d, last error %#x.\n", ret, err);
1431 SetLastError(0xdeadbeef);
1432 ret = SwapBuffers(dc);
1433 err = GetLastError();
1434 ok(!ret && err == ERROR_INVALID_HANDLE, "Unexpected behavior with SwapBuffer, last error %#x.\n", err);
1436 ok(wglGetCurrentContext() == ctx, "Wrong current context.\n");
1438 glClear(GL_COLOR_BUFFER_BIT);
1439 glFinish();
1440 glerr = glGetError();
1441 ok(glerr == GL_NO_ERROR, "Failed glClear, error %#x.\n", glerr);
1442 SetLastError(0xdeadbeef);
1443 ret = SwapBuffers(dc);
1444 err = GetLastError();
1445 ok(!ret && err == ERROR_INVALID_HANDLE, "Unexpected behavior with SwapBuffer, last error %#x.\n", err);
1447 ret = wglMakeCurrent(NULL, NULL);
1448 ok(ret, "Failed to clear current context, last error %#x.\n", GetLastError());
1450 glClear(GL_COLOR_BUFFER_BIT);
1451 glFinish();
1452 glerr = glGetError();
1453 ok(glerr == GL_INVALID_OPERATION, "Failed glClear, error %#x.\n", glerr);
1454 SetLastError(0xdeadbeef);
1455 ret = SwapBuffers(dc);
1456 err = GetLastError();
1457 ok(!ret && err == ERROR_INVALID_HANDLE, "Unexpected behavior with SwapBuffer, last error %#x.\n", err);
1459 SetLastError(0xdeadbeef);
1460 ret = wglMakeCurrent(dc, ctx);
1461 err = GetLastError();
1462 ok(!ret && err == ERROR_INVALID_HANDLE,
1463 "Unexpected behavior when making context current, ret %d, last error %#x.\n", ret, err);
1465 ok(wglGetCurrentContext() == NULL, "Wrong current context.\n");
1467 ret = wglMakeCurrent(oldhdc, oldctx);
1468 ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1469 ok(wglGetCurrentContext() == oldctx, "Wrong current context.\n");
1471 SetLastError(0xdeadbeef);
1472 ret = wglMakeCurrent(dc, ctx);
1473 err = GetLastError();
1474 ok(!ret && err == ERROR_INVALID_HANDLE,
1475 "Unexpected behavior when making context current, ret %d, last error %#x.\n", ret, err);
1477 ok(wglGetCurrentContext() == oldctx, "Wrong current context.\n");
1479 ret = wglDeleteContext(ctx);
1480 ok(ret, "Failed to delete GL context, last error %#x.\n", GetLastError());
1482 ReleaseDC(window, dc);
1484 ret = wglMakeCurrent(oldhdc, oldctx);
1485 ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1488 static void test_destroy_read(HDC oldhdc)
1490 PIXELFORMATDESCRIPTOR pf_desc =
1492 sizeof(PIXELFORMATDESCRIPTOR),
1493 1, /* version */
1494 PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
1495 PFD_TYPE_RGBA,
1496 24, /* 24-bit color depth */
1497 0, 0, 0, 0, 0, 0, /* color bits */
1498 0, /* alpha buffer */
1499 0, /* shift bit */
1500 0, /* accumulation buffer */
1501 0, 0, 0, 0, /* accum bits */
1502 32, /* z-buffer */
1503 0, /* stencil buffer */
1504 0, /* auxiliary buffer */
1505 PFD_MAIN_PLANE, /* main layer */
1506 0, /* reserved */
1507 0, 0, 0 /* layer masks */
1509 int pixel_format;
1510 HWND draw_window, read_window;
1511 HGLRC ctx;
1512 BOOL ret;
1513 HDC read_dc, draw_dc;
1514 GLenum glerr;
1515 DWORD err;
1516 HGLRC oldctx = wglGetCurrentContext();
1518 ok(!!oldctx, "Expected to find a valid current context\n");
1520 draw_window = CreateWindowA("static", "opengl32_test",
1521 WS_POPUP, 0, 0, 640, 480, 0, 0, 0, 0);
1522 ok(!!draw_window, "Failed to create window, last error %#x.\n", GetLastError());
1524 draw_dc = GetDC(draw_window);
1525 ok(!!draw_dc, "Failed to get DC.\n");
1527 pixel_format = ChoosePixelFormat(draw_dc, &pf_desc);
1528 if (!pixel_format)
1530 win_skip("Failed to find pixel format.\n");
1531 ReleaseDC(draw_window, draw_dc);
1532 DestroyWindow(draw_window);
1533 return;
1536 ret = SetPixelFormat(draw_dc, pixel_format, &pf_desc);
1537 ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError());
1539 read_window = CreateWindowA("static", "opengl32_test",
1540 WS_POPUP, 0, 0, 640, 480, 0, 0, 0, 0);
1541 ok(!!read_window, "Failed to create window, last error %#x.\n", GetLastError());
1543 read_dc = GetDC(read_window);
1544 ok(!!draw_dc, "Failed to get DC.\n");
1546 pixel_format = ChoosePixelFormat(read_dc, &pf_desc);
1547 if (!pixel_format)
1549 win_skip("Failed to find pixel format.\n");
1550 ReleaseDC(read_window, read_dc);
1551 DestroyWindow(read_window);
1552 ReleaseDC(draw_window, draw_dc);
1553 DestroyWindow(draw_window);
1554 return;
1557 ret = SetPixelFormat(read_dc, pixel_format, &pf_desc);
1558 ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError());
1560 ctx = wglCreateContext(draw_dc);
1561 ok(!!ctx, "Failed to create GL context, last error %#x.\n", GetLastError());
1563 ret = pwglMakeContextCurrentARB(draw_dc, read_dc, ctx);
1564 ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1566 glCopyPixels(0, 0, 640, 480, GL_COLOR);
1567 glFinish();
1568 glerr = glGetError();
1569 ok(glerr == GL_NO_ERROR, "Failed glCopyPixel, error %#x.\n", glerr);
1570 ret = SwapBuffers(draw_dc);
1571 ok(ret, "Failed SwapBuffers, error %#x.\n", GetLastError());
1573 ret = DestroyWindow(read_window);
1574 ok(ret, "Failed to destroy window, last error %#x.\n", GetLastError());
1576 ok(wglGetCurrentContext() == ctx, "Wrong current context.\n");
1578 if (0) /* Crashes on AMD on Windows */
1580 glCopyPixels(0, 0, 640, 480, GL_COLOR);
1581 glFinish();
1582 glerr = glGetError();
1583 ok(glerr == GL_NO_ERROR, "Failed glCopyPixel, error %#x.\n", glerr);
1586 glClear(GL_COLOR_BUFFER_BIT);
1587 glFinish();
1588 glerr = glGetError();
1589 ok(glerr == GL_NO_ERROR, "Failed glClear, error %#x.\n", glerr);
1590 ret = SwapBuffers(draw_dc);
1591 ok(ret, "Failed SwapBuffers, error %#x.\n", GetLastError());
1593 ret = wglMakeCurrent(NULL, NULL);
1594 ok(ret, "Failed to clear current context, last error %#x.\n", GetLastError());
1596 if (0) /* This crashes with Nvidia drivers on Windows. */
1598 SetLastError(0xdeadbeef);
1599 ret = pwglMakeContextCurrentARB(draw_dc, read_dc, ctx);
1600 err = GetLastError();
1601 ok(!ret && err == ERROR_INVALID_HANDLE,
1602 "Unexpected behavior when making context current, ret %d, last error %#x.\n", ret, err);
1605 ret = DestroyWindow(draw_window);
1606 ok(ret, "Failed to destroy window, last error %#x.\n", GetLastError());
1608 glClear(GL_COLOR_BUFFER_BIT);
1609 glFinish();
1610 glerr = glGetError();
1611 ok(glerr == GL_INVALID_OPERATION, "Failed glClear, error %#x.\n", glerr);
1612 SetLastError(0xdeadbeef);
1613 ret = SwapBuffers(draw_dc);
1614 err = GetLastError();
1615 ok(!ret && err == ERROR_INVALID_HANDLE, "Unexpected behavior with SwapBuffer, last error %#x.\n", err);
1617 SetLastError(0xdeadbeef);
1618 ret = pwglMakeContextCurrentARB(draw_dc, read_dc, ctx);
1619 err = GetLastError();
1620 ok(!ret && (err == ERROR_INVALID_HANDLE || err == 0xc0070006),
1621 "Unexpected behavior when making context current, ret %d, last error %#x.\n", ret, err);
1623 ok(wglGetCurrentContext() == NULL, "Wrong current context.\n");
1625 wglMakeCurrent(NULL, NULL);
1627 wglMakeCurrent(oldhdc, oldctx);
1628 ok(wglGetCurrentContext() == oldctx, "Wrong current context.\n");
1630 SetLastError(0xdeadbeef);
1631 ret = pwglMakeContextCurrentARB(draw_dc, read_dc, ctx);
1632 err = GetLastError();
1633 ok(!ret && (err == ERROR_INVALID_HANDLE || err == 0xc0070006),
1634 "Unexpected behavior when making context current, last error %#x.\n", err);
1636 ok(wglGetCurrentContext() == oldctx, "Wrong current context.\n");
1638 ret = wglDeleteContext(ctx);
1639 ok(ret, "Failed to delete GL context, last error %#x.\n", GetLastError());
1641 ReleaseDC(read_window, read_dc);
1642 ReleaseDC(draw_window, draw_dc);
1644 wglMakeCurrent(oldhdc, oldctx);
1647 static void test_swap_control(HDC oldhdc)
1649 PIXELFORMATDESCRIPTOR pf_desc =
1651 sizeof(PIXELFORMATDESCRIPTOR),
1652 1, /* version */
1653 PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
1654 PFD_TYPE_RGBA,
1655 24, /* 24-bit color depth */
1656 0, 0, 0, 0, 0, 0, /* color bits */
1657 0, /* alpha buffer */
1658 0, /* shift bit */
1659 0, /* accumulation buffer */
1660 0, 0, 0, 0, /* accum bits */
1661 32, /* z-buffer */
1662 0, /* stencil buffer */
1663 0, /* auxiliary buffer */
1664 PFD_MAIN_PLANE, /* main layer */
1665 0, /* reserved */
1666 0, 0, 0 /* layer masks */
1668 int pixel_format;
1669 HWND window1, window2, old_parent;
1670 HGLRC ctx1, ctx2, oldctx;
1671 BOOL ret;
1672 HDC dc1, dc2;
1673 int interval;
1675 oldctx = wglGetCurrentContext();
1676 ok(!!oldctx, "Expected to find a valid current context.\n");
1678 window1 = CreateWindowA("static", "opengl32_test",
1679 WS_POPUP, 0, 0, 640, 480, 0, 0, 0, 0);
1680 ok(!!window1, "Failed to create window1, last error %#x.\n", GetLastError());
1682 dc1 = GetDC(window1);
1683 ok(!!dc1, "Failed to get DC.\n");
1685 pixel_format = ChoosePixelFormat(dc1, &pf_desc);
1686 if (!pixel_format)
1688 win_skip("Failed to find pixel format.\n");
1689 ReleaseDC(window1, dc1);
1690 DestroyWindow(window1);
1691 return;
1694 ret = SetPixelFormat(dc1, pixel_format, &pf_desc);
1695 ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError());
1697 ctx1 = wglCreateContext(dc1);
1698 ok(!!ctx1, "Failed to create GL context, last error %#x.\n", GetLastError());
1700 ret = wglMakeCurrent(dc1, ctx1);
1701 ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1703 interval = pwglGetSwapIntervalEXT();
1704 ok(interval == 1, "Expected default swap interval 1, got %d\n", interval);
1706 ret = pwglSwapIntervalEXT(0);
1707 ok(ret, "Failed to set swap interval to 0, last error %#x.\n", GetLastError());
1709 interval = pwglGetSwapIntervalEXT();
1710 ok(interval == 0, "Expected swap interval 0, got %d\n", interval);
1712 /* Check what interval we get on a second context on the same drawable.*/
1713 ctx2 = wglCreateContext(dc1);
1714 ok(!!ctx2, "Failed to create GL context, last error %#x.\n", GetLastError());
1716 ret = wglMakeCurrent(dc1, ctx2);
1717 ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1719 interval = pwglGetSwapIntervalEXT();
1720 ok(interval == 0, "Expected swap interval 0, got %d\n", interval);
1722 /* A second window is created to see whether its swap interval was affected
1723 * by previous calls.
1725 window2 = CreateWindowA("static", "opengl32_test",
1726 WS_POPUP, 0, 0, 640, 480, 0, 0, 0, 0);
1727 ok(!!window2, "Failed to create window2, last error %#x.\n", GetLastError());
1729 dc2 = GetDC(window2);
1730 ok(!!dc2, "Failed to get DC.\n");
1732 ret = SetPixelFormat(dc2, pixel_format, &pf_desc);
1733 ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError());
1735 ret = wglMakeCurrent(dc2, ctx1);
1736 ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1738 /* Since the second window lacks the swap interval, this proves that the interval
1739 * is not global or shared among contexts.
1741 interval = pwglGetSwapIntervalEXT();
1742 ok(interval == 1, "Expected default swap interval 1, got %d\n", interval);
1744 /* Test if setting the parent of a window resets the swap interval. */
1745 ret = wglMakeCurrent(dc1, ctx1);
1746 ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1748 old_parent = SetParent(window1, window2);
1749 ok(!!old_parent, "Failed to make window1 a child of window2, last error %#x.\n", GetLastError());
1751 interval = pwglGetSwapIntervalEXT();
1752 ok(interval == 0, "Expected swap interval 0, got %d\n", interval);
1754 ret = wglDeleteContext(ctx1);
1755 ok(ret, "Failed to delete GL context, last error %#x.\n", GetLastError());
1756 ret = wglDeleteContext(ctx2);
1757 ok(ret, "Failed to delete GL context, last error %#x.\n", GetLastError());
1759 ReleaseDC(window1, dc1);
1760 DestroyWindow(window1);
1761 ReleaseDC(window2, dc2);
1762 DestroyWindow(window2);
1764 wglMakeCurrent(oldhdc, oldctx);
1767 static void test_wglChoosePixelFormatARB(HDC hdc)
1769 static int attrib_list[] =
1771 WGL_DRAW_TO_WINDOW_ARB, 1,
1772 WGL_SUPPORT_OPENGL_ARB, 1,
1776 PIXELFORMATDESCRIPTOR fmt, last_fmt;
1777 BYTE depth, last_depth;
1778 UINT format_count;
1779 int formats[1024];
1780 unsigned int i;
1781 int res;
1783 if (!pwglChoosePixelFormatARB)
1785 skip("wglChoosePixelFormatARB is not available\n");
1786 return;
1789 format_count = 0;
1790 res = pwglChoosePixelFormatARB(hdc, attrib_list, NULL, ARRAY_SIZE(formats), formats, &format_count);
1791 ok(res, "Got unexpected result %d.\n", res);
1793 memset(&last_fmt, 0, sizeof(last_fmt));
1794 last_depth = 0;
1796 for (i = 0; i < format_count; ++i)
1798 memset(&fmt, 0, sizeof(fmt));
1799 if (!DescribePixelFormat(hdc, formats[i], sizeof(fmt), &fmt)
1800 || (fmt.dwFlags & PFD_GENERIC_FORMAT))
1802 memset(&fmt, 0, sizeof(fmt));
1803 continue;
1806 depth = fmt.cDepthBits;
1807 fmt.cDepthBits = 0;
1808 fmt.cStencilBits = 0;
1810 if (memcmp(&fmt, &last_fmt, sizeof(fmt)))
1812 last_fmt = fmt;
1813 last_depth = depth;
1815 else
1817 ok(last_depth <= depth, "Got unexpected depth %u, last_depth %u, i %u, format %u.\n",
1818 depth, last_depth, i, formats[i]);
1823 START_TEST(opengl)
1825 HWND hwnd;
1826 PIXELFORMATDESCRIPTOR pfd = {
1827 sizeof(PIXELFORMATDESCRIPTOR),
1828 1, /* version */
1829 PFD_DRAW_TO_WINDOW |
1830 PFD_SUPPORT_OPENGL |
1831 PFD_DOUBLEBUFFER,
1832 PFD_TYPE_RGBA,
1833 24, /* 24-bit color depth */
1834 0, 0, 0, 0, 0, 0, /* color bits */
1835 0, /* alpha buffer */
1836 0, /* shift bit */
1837 0, /* accumulation buffer */
1838 0, 0, 0, 0, /* accum bits */
1839 32, /* z-buffer */
1840 0, /* stencil buffer */
1841 0, /* auxiliary buffer */
1842 PFD_MAIN_PLANE, /* main layer */
1843 0, /* reserved */
1844 0, 0, 0 /* layer masks */
1847 hwnd = CreateWindowA("static", "Title", WS_OVERLAPPEDWINDOW, 10, 10, 200, 200, NULL, NULL,
1848 NULL, NULL);
1849 ok(hwnd != NULL, "err: %d\n", GetLastError());
1850 if (hwnd)
1852 HDC hdc;
1853 int iPixelFormat, res;
1854 HGLRC hglrc;
1855 DWORD error;
1856 ShowWindow(hwnd, SW_SHOW);
1858 hdc = GetDC(hwnd);
1860 iPixelFormat = ChoosePixelFormat(hdc, &pfd);
1861 if(iPixelFormat == 0)
1863 /* This should never happen as ChoosePixelFormat always returns a closest match, but currently this fails in Wine if we don't have glX */
1864 win_skip("Unable to find pixel format.\n");
1865 goto cleanup;
1868 /* We shouldn't be able to create a context from a hdc which doesn't have a pixel format set */
1869 hglrc = wglCreateContext(hdc);
1870 ok(hglrc == NULL, "wglCreateContext should fail when no pixel format has been set, but it passed\n");
1871 error = GetLastError();
1872 ok(error == ERROR_INVALID_PIXEL_FORMAT, "expected ERROR_INVALID_PIXEL_FORMAT for wglCreateContext without a pixelformat set, but received %#x\n", error);
1874 res = SetPixelFormat(hdc, iPixelFormat, &pfd);
1875 ok(res, "SetPixelformat failed: %x\n", GetLastError());
1877 test_bitmap_rendering( TRUE );
1878 test_bitmap_rendering( FALSE );
1879 test_minimized();
1880 test_window_dc();
1881 test_message_window();
1882 test_dc(hwnd, hdc);
1884 ok(!glGetString(GL_RENDERER) && !glGetString(GL_VERSION) && !glGetString(GL_VENDOR),
1885 "Expected NULL string when no active context is set\n");
1886 hglrc = wglCreateContext(hdc);
1887 res = wglMakeCurrent(hdc, hglrc);
1888 ok(res, "wglMakeCurrent failed!\n");
1889 if(res)
1891 trace("OpenGL renderer: %s\n", glGetString(GL_RENDERER));
1892 trace("OpenGL driver version: %s\n", glGetString(GL_VERSION));
1893 trace("OpenGL vendor: %s\n", glGetString(GL_VENDOR));
1895 else
1897 skip("Skipping OpenGL tests without a current context\n");
1898 return;
1901 /* Initialisation of WGL functions depends on an implicit WGL context. For this reason we can't load them before making
1902 * any WGL call :( On Wine this would work but not on real Windows because there can be different implementations (software, ICD, MCD).
1904 init_functions();
1905 test_getprocaddress(hdc);
1906 test_deletecontext(hwnd, hdc);
1907 test_makecurrent(hdc);
1909 /* The lack of wglGetExtensionsStringARB in general means broken software rendering or the lack of decent OpenGL support, skip tests in such cases */
1910 if (!pwglGetExtensionsStringARB)
1912 win_skip("wglGetExtensionsStringARB is not available\n");
1913 return;
1916 test_choosepixelformat();
1917 test_wglChoosePixelFormatARB(hdc);
1918 test_debug_message_callback();
1919 test_setpixelformat(hdc);
1920 test_destroy(hdc);
1921 test_sharelists(hdc);
1922 test_colorbits(hdc);
1923 test_gdi_dbuf(hdc);
1924 test_acceleration(hdc);
1926 wgl_extensions = pwglGetExtensionsStringARB(hdc);
1927 if(wgl_extensions == NULL) skip("Skipping opengl32 tests because this OpenGL implementation doesn't support WGL extensions!\n");
1929 if(strstr(wgl_extensions, "WGL_ARB_create_context"))
1930 test_opengl3(hdc);
1932 if(strstr(wgl_extensions, "WGL_ARB_make_current_read"))
1934 test_make_current_read(hdc);
1935 test_destroy_read(hdc);
1937 else
1938 skip("WGL_ARB_make_current_read not supported, skipping test\n");
1940 if(strstr(wgl_extensions, "WGL_ARB_pbuffer"))
1941 test_pbuffers(hdc);
1942 else
1943 skip("WGL_ARB_pbuffer not supported, skipping pbuffer test\n");
1945 if(strstr(wgl_extensions, "WGL_EXT_swap_control"))
1946 test_swap_control(hdc);
1947 else
1948 skip("WGL_EXT_swap_control not supported, skipping test\n");
1950 cleanup:
1951 ReleaseDC(hwnd, hdc);
1952 DestroyWindow(hwnd);