wined3d: Implement multisample resolve for typed resources.
[wine.git] / dlls / opengl32 / tests / opengl.c
blob8126fbf96dd94e499e0bc3b21dff8e568a10039b
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 static const char* wgl_extensions = NULL;
53 static void init_functions(void)
55 #define GET_PROC(func) \
56 p ## func = (void*)wglGetProcAddress(#func); \
57 if(!p ## func) \
58 trace("wglGetProcAddress(%s) failed\n", #func);
60 /* WGL_ARB_create_context */
61 GET_PROC(wglCreateContextAttribsARB);
63 /* WGL_ARB_extensions_string */
64 GET_PROC(wglGetExtensionsStringARB)
66 /* WGL_ARB_make_current_read */
67 GET_PROC(wglMakeContextCurrentARB);
68 GET_PROC(wglGetCurrentReadDCARB);
70 /* WGL_ARB_pixel_format */
71 GET_PROC(wglChoosePixelFormatARB)
72 GET_PROC(wglGetPixelFormatAttribivARB)
74 /* WGL_ARB_pbuffer */
75 GET_PROC(wglCreatePbufferARB)
76 GET_PROC(wglGetPbufferDCARB)
77 GET_PROC(wglReleasePbufferDCARB)
79 /* WGL_EXT_swap_control */
80 GET_PROC(wglSwapIntervalEXT)
81 GET_PROC(wglGetSwapIntervalEXT)
83 #undef GET_PROC
86 static BOOL gl_extension_supported(const char *extensions, const char *extension_string)
88 size_t ext_str_len = strlen(extension_string);
90 while (*extensions)
92 const char *start;
93 size_t len;
95 while (isspace(*extensions))
96 ++extensions;
97 start = extensions;
98 while (!isspace(*extensions) && *extensions)
99 ++extensions;
101 len = extensions - start;
102 if (!len)
103 continue;
105 if (len == ext_str_len && !memcmp(start, extension_string, ext_str_len))
107 return TRUE;
110 return FALSE;
113 static void test_pbuffers(HDC hdc)
115 const int iAttribList[] = { WGL_DRAW_TO_PBUFFER_ARB, 1, /* Request pbuffer support */
116 0 };
117 int iFormats[MAX_FORMATS];
118 unsigned int nOnscreenFormats;
119 unsigned int nFormats;
120 int i, res;
121 int iPixelFormat = 0;
123 nOnscreenFormats = DescribePixelFormat(hdc, 0, 0, NULL);
125 /* When you want to render to a pbuffer you need to call wglGetPbufferDCARB which
126 * returns a 'magic' HDC which you can then pass to wglMakeCurrent to switch rendering
127 * to the pbuffer. Below some tests are performed on what happens if you use standard WGL calls
128 * on this 'magic' HDC for both a pixelformat that support onscreen and offscreen rendering
129 * and a pixelformat that's only available for offscreen rendering (this means that only
130 * wglChoosePixelFormatARB and friends know about the format.
132 * The first thing we need are pixelformats with pbuffer capabilities.
134 res = pwglChoosePixelFormatARB(hdc, iAttribList, NULL, MAX_FORMATS, iFormats, &nFormats);
135 if(res <= 0)
137 skip("No pbuffer compatible formats found while WGL_ARB_pbuffer is supported\n");
138 return;
140 trace("nOnscreenFormats: %d\n", nOnscreenFormats);
141 trace("Total number of pbuffer capable pixelformats: %d\n", nFormats);
143 /* Try to select an onscreen pixelformat out of the list */
144 for(i=0; i < nFormats; i++)
146 /* Check if the format is onscreen, if it is choose it */
147 if(iFormats[i] <= nOnscreenFormats)
149 iPixelFormat = iFormats[i];
150 trace("Selected iPixelFormat=%d\n", iPixelFormat);
151 break;
155 /* A video driver supports a large number of onscreen and offscreen pixelformats.
156 * The traditional WGL calls only see a subset of the whole pixelformat list. First
157 * of all they only see the onscreen formats (the offscreen formats are at the end of the
158 * pixelformat list) and second extended pixelformat capabilities are hidden from the
159 * standard WGL calls. Only functions that depend on WGL_ARB_pixel_format can see them.
161 * Below we check if the pixelformat is also supported onscreen.
163 if(iPixelFormat != 0)
165 HDC pbuffer_hdc;
166 int attrib = 0;
167 HPBUFFERARB pbuffer = pwglCreatePbufferARB(hdc, iPixelFormat, 640 /* width */, 480 /* height */, &attrib);
168 if(!pbuffer)
169 skip("Pbuffer creation failed!\n");
171 /* Test the pixelformat returned by GetPixelFormat on a pbuffer as the behavior is not clear */
172 pbuffer_hdc = pwglGetPbufferDCARB(pbuffer);
173 res = GetPixelFormat(pbuffer_hdc);
174 ok(res == iPixelFormat, "Unexpected iPixelFormat=%d returned by GetPixelFormat for format %d\n", res, iPixelFormat);
175 trace("iPixelFormat returned by GetPixelFormat: %d\n", res);
176 trace("PixelFormat from wglChoosePixelFormatARB: %d\n", iPixelFormat);
178 pwglReleasePbufferDCARB(pbuffer, pbuffer_hdc);
180 else skip("Pbuffer test for onscreen pixelformat skipped as no onscreen format with pbuffer capabilities have been found\n");
182 /* Search for a real offscreen format */
183 for(i=0, iPixelFormat=0; i<nFormats; i++)
185 if(iFormats[i] > nOnscreenFormats)
187 iPixelFormat = iFormats[i];
188 trace("Selected iPixelFormat: %d\n", iPixelFormat);
189 break;
193 if(iPixelFormat != 0)
195 HDC pbuffer_hdc;
196 HPBUFFERARB pbuffer = pwglCreatePbufferARB(hdc, iPixelFormat, 640 /* width */, 480 /* height */, NULL);
197 if(!pbuffer)
198 skip("Pbuffer creation failed!\n");
200 /* Test the pixelformat returned by GetPixelFormat on a pbuffer as the behavior is not clear */
201 pbuffer_hdc = pwglGetPbufferDCARB(pbuffer);
202 res = GetPixelFormat(pbuffer_hdc);
204 ok(res == 1, "Unexpected iPixelFormat=%d (1 expected) returned by GetPixelFormat for offscreen format %d\n", res, iPixelFormat);
205 trace("iPixelFormat returned by GetPixelFormat: %d\n", res);
206 trace("PixelFormat from wglChoosePixelFormatARB: %d\n", iPixelFormat);
207 pwglReleasePbufferDCARB(pbuffer, hdc);
209 else skip("Pbuffer test for offscreen pixelformat skipped as no offscreen-only format with pbuffer capabilities has been found\n");
212 static int test_pfd(const PIXELFORMATDESCRIPTOR *pfd)
214 int pf;
215 HDC hdc;
216 HWND hwnd;
218 hwnd = CreateWindowA("static", "Title", WS_OVERLAPPEDWINDOW, 10, 10, 200, 200, NULL, NULL,
219 NULL, NULL);
220 if (!hwnd)
221 return 0;
223 hdc = GetDC( hwnd );
224 pf = ChoosePixelFormat( hdc, pfd );
225 ReleaseDC( hwnd, hdc );
226 DestroyWindow( hwnd );
228 return pf;
231 static void test_choosepixelformat(void)
233 PIXELFORMATDESCRIPTOR pfd = {
234 sizeof(PIXELFORMATDESCRIPTOR),
235 1, /* version */
236 PFD_DRAW_TO_WINDOW |
237 PFD_SUPPORT_OPENGL |
238 PFD_TYPE_RGBA,
239 0, /* color depth */
240 0, 0, 0, 0, 0, 0, /* color bits */
241 0, /* alpha buffer */
242 0, /* shift bit */
243 0, /* accumulation buffer */
244 0, 0, 0, 0, /* accum bits */
245 0, /* z-buffer */
246 0, /* stencil buffer */
247 0, /* auxiliary buffer */
248 PFD_MAIN_PLANE, /* main layer */
249 0, /* reserved */
250 0, 0, 0 /* layer masks */
253 ok( test_pfd(&pfd), "Simple pfd failed\n" );
254 pfd.dwFlags |= PFD_DOUBLEBUFFER_DONTCARE;
255 ok( test_pfd(&pfd), "PFD_DOUBLEBUFFER_DONTCARE failed\n" );
256 pfd.dwFlags |= PFD_STEREO_DONTCARE;
257 ok( test_pfd(&pfd), "PFD_DOUBLEBUFFER_DONTCARE|PFD_STEREO_DONTCARE failed\n" );
258 pfd.dwFlags &= ~PFD_DOUBLEBUFFER_DONTCARE;
259 ok( test_pfd(&pfd), "PFD_STEREO_DONTCARE failed\n" );
260 pfd.dwFlags &= ~PFD_STEREO_DONTCARE;
262 pfd.cColorBits = 32;
263 ok( test_pfd(&pfd), "Simple pfd failed\n" );
264 pfd.dwFlags |= PFD_DOUBLEBUFFER_DONTCARE;
265 ok( test_pfd(&pfd), "PFD_DOUBLEBUFFER_DONTCARE failed\n" );
266 pfd.dwFlags |= PFD_STEREO_DONTCARE;
267 ok( test_pfd(&pfd), "PFD_DOUBLEBUFFER_DONTCARE|PFD_STEREO_DONTCARE failed\n" );
268 pfd.dwFlags &= ~PFD_DOUBLEBUFFER_DONTCARE;
269 ok( test_pfd(&pfd), "PFD_STEREO_DONTCARE failed\n" );
270 pfd.dwFlags &= ~PFD_STEREO_DONTCARE;
271 pfd.cColorBits = 0;
273 pfd.cAlphaBits = 8;
274 ok( test_pfd(&pfd), "Simple pfd failed\n" );
275 pfd.dwFlags |= PFD_DOUBLEBUFFER_DONTCARE;
276 ok( test_pfd(&pfd), "PFD_DOUBLEBUFFER_DONTCARE failed\n" );
277 pfd.dwFlags |= PFD_STEREO_DONTCARE;
278 ok( test_pfd(&pfd), "PFD_DOUBLEBUFFER_DONTCARE|PFD_STEREO_DONTCARE failed\n" );
279 pfd.dwFlags &= ~PFD_DOUBLEBUFFER_DONTCARE;
280 ok( test_pfd(&pfd), "PFD_STEREO_DONTCARE failed\n" );
281 pfd.dwFlags &= ~PFD_STEREO_DONTCARE;
282 pfd.cAlphaBits = 0;
284 pfd.cStencilBits = 8;
285 ok( test_pfd(&pfd), "Simple pfd failed\n" );
286 pfd.dwFlags |= PFD_DOUBLEBUFFER_DONTCARE;
287 ok( test_pfd(&pfd), "PFD_DOUBLEBUFFER_DONTCARE failed\n" );
288 pfd.dwFlags |= PFD_STEREO_DONTCARE;
289 ok( test_pfd(&pfd), "PFD_DOUBLEBUFFER_DONTCARE|PFD_STEREO_DONTCARE failed\n" );
290 pfd.dwFlags &= ~PFD_DOUBLEBUFFER_DONTCARE;
291 ok( test_pfd(&pfd), "PFD_STEREO_DONTCARE failed\n" );
292 pfd.dwFlags &= ~PFD_STEREO_DONTCARE;
293 pfd.cStencilBits = 0;
295 pfd.cAuxBuffers = 1;
296 ok( test_pfd(&pfd), "Simple pfd failed\n" );
297 pfd.dwFlags |= PFD_DOUBLEBUFFER_DONTCARE;
298 ok( test_pfd(&pfd), "PFD_DOUBLEBUFFER_DONTCARE failed\n" );
299 pfd.dwFlags |= PFD_STEREO_DONTCARE;
300 ok( test_pfd(&pfd), "PFD_DOUBLEBUFFER_DONTCARE|PFD_STEREO_DONTCARE failed\n" );
301 pfd.dwFlags &= ~PFD_DOUBLEBUFFER_DONTCARE;
302 ok( test_pfd(&pfd), "PFD_STEREO_DONTCARE failed\n" );
303 pfd.dwFlags &= ~PFD_STEREO_DONTCARE;
304 pfd.cAuxBuffers = 0;
307 static void test_setpixelformat(HDC winhdc)
309 int res = 0;
310 int nCfgs;
311 int pf;
312 int i;
313 HWND hwnd;
314 PIXELFORMATDESCRIPTOR pfd = {
315 sizeof(PIXELFORMATDESCRIPTOR),
316 1, /* version */
317 PFD_DRAW_TO_WINDOW |
318 PFD_SUPPORT_OPENGL |
319 PFD_DOUBLEBUFFER,
320 PFD_TYPE_RGBA,
321 24, /* 24-bit color depth */
322 0, 0, 0, 0, 0, 0, /* color bits */
323 0, /* alpha buffer */
324 0, /* shift bit */
325 0, /* accumulation buffer */
326 0, 0, 0, 0, /* accum bits */
327 32, /* z-buffer */
328 0, /* stencil buffer */
329 0, /* auxiliary buffer */
330 PFD_MAIN_PLANE, /* main layer */
331 0, /* reserved */
332 0, 0, 0 /* layer masks */
335 HDC hdc = GetDC(0);
336 ok(hdc != 0, "GetDC(0) failed!\n");
338 /* This should pass even on the main device context */
339 pf = ChoosePixelFormat(hdc, &pfd);
340 ok(pf != 0, "ChoosePixelFormat failed on main device context\n");
342 /* SetPixelFormat on the main device context 'X root window' should fail,
343 * but some broken drivers allow it
345 res = SetPixelFormat(hdc, pf, &pfd);
346 trace("SetPixelFormat on main device context %s\n", res ? "succeeded" : "failed");
348 /* Setting the same format that was set on the HDC is allowed; other
349 formats fail */
350 nCfgs = DescribePixelFormat(winhdc, 0, 0, NULL);
351 pf = GetPixelFormat(winhdc);
352 for(i = 1;i <= nCfgs;i++)
354 int res = SetPixelFormat(winhdc, i, NULL);
355 if(i == pf) ok(res, "Failed to set the same pixel format\n");
356 else ok(!res, "Unexpectedly set an alternate pixel format\n");
359 hwnd = CreateWindowA("static", "Title", WS_OVERLAPPEDWINDOW, 10, 10, 200, 200, NULL, NULL,
360 NULL, NULL);
361 ok(hwnd != NULL, "err: %d\n", GetLastError());
362 if (hwnd)
364 HDC hdc = GetDC( hwnd );
365 pf = ChoosePixelFormat( hdc, &pfd );
366 ok( pf != 0, "ChoosePixelFormat failed\n" );
367 res = SetPixelFormat( hdc, pf, &pfd );
368 ok( res != 0, "SetPixelFormat failed\n" );
369 i = GetPixelFormat( hdc );
370 ok( i == pf, "GetPixelFormat returned wrong format %d/%d\n", i, pf );
371 ReleaseDC( hwnd, hdc );
372 hdc = GetWindowDC( hwnd );
373 i = GetPixelFormat( hdc );
374 ok( i == pf, "GetPixelFormat returned wrong format %d/%d\n", i, pf );
375 ReleaseDC( hwnd, hdc );
376 DestroyWindow( hwnd );
377 /* check various calls with invalid hdc */
378 SetLastError( 0xdeadbeef );
379 i = GetPixelFormat( hdc );
380 ok( i == 0, "GetPixelFormat succeeded\n" );
381 ok( GetLastError() == ERROR_INVALID_PIXEL_FORMAT, "wrong error %u\n", GetLastError() );
382 SetLastError( 0xdeadbeef );
383 res = SetPixelFormat( hdc, pf, &pfd );
384 ok( !res, "SetPixelFormat succeeded\n" );
385 ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError() );
386 SetLastError( 0xdeadbeef );
387 res = DescribePixelFormat( hdc, 0, 0, NULL );
388 ok( !res, "DescribePixelFormat succeeded\n" );
389 ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError() );
390 SetLastError( 0xdeadbeef );
391 pf = ChoosePixelFormat( hdc, &pfd );
392 ok( !pf, "ChoosePixelFormat succeeded\n" );
393 ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError() );
394 SetLastError( 0xdeadbeef );
395 res = SwapBuffers( hdc );
396 ok( !res, "SwapBuffers succeeded\n" );
397 ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError() );
398 SetLastError( 0xdeadbeef );
399 ok( !wglCreateContext( hdc ), "CreateContext succeeded\n" );
400 ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError() );
403 hwnd = CreateWindowA("static", "Title", WS_OVERLAPPEDWINDOW, 10, 10, 200, 200, NULL, NULL,
404 NULL, NULL);
405 ok(hwnd != NULL, "err: %d\n", GetLastError());
406 if (hwnd)
408 HDC hdc = GetWindowDC( hwnd );
409 pf = ChoosePixelFormat( hdc, &pfd );
410 ok( pf != 0, "ChoosePixelFormat failed\n" );
411 res = SetPixelFormat( hdc, pf, &pfd );
412 ok( res != 0, "SetPixelFormat failed\n" );
413 i = GetPixelFormat( hdc );
414 ok( i == pf, "GetPixelFormat returned wrong format %d/%d\n", i, pf );
415 ReleaseDC( hwnd, hdc );
416 DestroyWindow( hwnd );
420 static void test_sharelists(HDC winhdc)
422 HGLRC hglrc1, hglrc2, hglrc3;
423 BOOL res;
425 hglrc1 = wglCreateContext(winhdc);
426 res = wglShareLists(0, 0);
427 ok(res == FALSE, "Sharing display lists for no contexts passed!\n");
429 /* Test 1: Create a context and just share lists without doing anything special */
430 hglrc2 = wglCreateContext(winhdc);
431 if(hglrc2)
433 res = wglShareLists(hglrc1, hglrc2);
434 ok(res, "Sharing of display lists failed\n");
435 wglDeleteContext(hglrc2);
438 /* Test 2: Share display lists with a 'destination' context which has been made current */
439 hglrc2 = wglCreateContext(winhdc);
440 if(hglrc2)
442 res = wglMakeCurrent(winhdc, hglrc2);
443 ok(res, "Make current failed\n");
444 res = wglShareLists(hglrc1, hglrc2);
445 todo_wine ok(res, "Sharing display lists with a destination context which has been made current failed\n");
446 wglMakeCurrent(0, 0);
447 wglDeleteContext(hglrc2);
450 /* Test 3: Share display lists with a context which already shares display lists with another context.
451 * According to MSDN the second parameter cannot share any display lists but some buggy drivers might allow it */
452 hglrc3 = wglCreateContext(winhdc);
453 if(hglrc3)
455 res = wglShareLists(hglrc3, hglrc1);
456 ok(res == FALSE, "Sharing of display lists passed for a context which already shared lists before\n");
457 wglDeleteContext(hglrc3);
460 /* Test 4: Share display lists with a 'source' context which has been made current */
461 hglrc2 = wglCreateContext(winhdc);
462 if(hglrc2)
464 res = wglMakeCurrent(winhdc, hglrc1);
465 ok(res, "Make current failed\n");
466 res = wglShareLists(hglrc1, hglrc2);
467 ok(res, "Sharing display lists with a source context which has been made current failed\n");
468 wglMakeCurrent(0, 0);
469 wglDeleteContext(hglrc2);
473 static void test_makecurrent(HDC winhdc)
475 BOOL ret;
476 HGLRC hglrc;
478 hglrc = wglCreateContext(winhdc);
479 ok( hglrc != 0, "wglCreateContext failed\n" );
481 ret = wglMakeCurrent( winhdc, hglrc );
482 ok( ret, "wglMakeCurrent failed\n" );
484 ok( wglGetCurrentContext() == hglrc, "wrong context\n" );
486 /* set the same context again */
487 ret = wglMakeCurrent( winhdc, hglrc );
488 ok( ret, "wglMakeCurrent failed\n" );
490 /* check wglMakeCurrent(x, y) after another call to wglMakeCurrent(x, y) */
491 ret = wglMakeCurrent( winhdc, NULL );
492 ok( ret, "wglMakeCurrent failed\n" );
494 ret = wglMakeCurrent( winhdc, NULL );
495 ok( ret, "wglMakeCurrent failed\n" );
497 SetLastError( 0xdeadbeef );
498 ret = wglMakeCurrent( NULL, NULL );
499 ok( !ret || broken(ret) /* nt4 */, "wglMakeCurrent succeeded\n" );
500 if (!ret) ok( GetLastError() == ERROR_INVALID_HANDLE,
501 "Expected ERROR_INVALID_HANDLE, got error=%x\n", GetLastError() );
503 ret = wglMakeCurrent( winhdc, NULL );
504 ok( ret, "wglMakeCurrent failed\n" );
506 ret = wglMakeCurrent( winhdc, hglrc );
507 ok( ret, "wglMakeCurrent failed\n" );
509 ret = wglMakeCurrent( NULL, NULL );
510 ok( ret, "wglMakeCurrent failed\n" );
512 ok( wglGetCurrentContext() == NULL, "wrong context\n" );
514 SetLastError( 0xdeadbeef );
515 ret = wglMakeCurrent( NULL, NULL );
516 ok( !ret || broken(ret) /* nt4 */, "wglMakeCurrent succeeded\n" );
517 if (!ret) ok( GetLastError() == ERROR_INVALID_HANDLE,
518 "Expected ERROR_INVALID_HANDLE, got error=%x\n", GetLastError() );
520 ret = wglMakeCurrent( winhdc, hglrc );
521 ok( ret, "wglMakeCurrent failed\n" );
524 static void test_colorbits(HDC hdc)
526 const int iAttribList[] = { WGL_COLOR_BITS_ARB, WGL_RED_BITS_ARB, WGL_GREEN_BITS_ARB,
527 WGL_BLUE_BITS_ARB, WGL_ALPHA_BITS_ARB };
528 int iAttribRet[sizeof(iAttribList)/sizeof(iAttribList[0])];
529 const int iAttribs[] = { WGL_ALPHA_BITS_ARB, 1, 0 };
530 unsigned int nFormats;
531 BOOL res;
532 int iPixelFormat = 0;
534 if (!pwglChoosePixelFormatARB)
536 win_skip("wglChoosePixelFormatARB is not available\n");
537 return;
540 /* We need a pixel format with at least one bit of alpha */
541 res = pwglChoosePixelFormatARB(hdc, iAttribs, NULL, 1, &iPixelFormat, &nFormats);
542 if(res == FALSE || nFormats == 0)
544 skip("No suitable pixel formats found\n");
545 return;
548 res = pwglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0,
549 sizeof(iAttribList)/sizeof(iAttribList[0]), iAttribList, iAttribRet);
550 if(res == FALSE)
552 skip("wglGetPixelFormatAttribivARB failed\n");
553 return;
555 iAttribRet[1] += iAttribRet[2]+iAttribRet[3]+iAttribRet[4];
556 ok(iAttribRet[0] == iAttribRet[1], "WGL_COLOR_BITS_ARB (%d) does not equal R+G+B+A (%d)!\n",
557 iAttribRet[0], iAttribRet[1]);
560 static void test_gdi_dbuf(HDC hdc)
562 const int iAttribList[] = { WGL_SUPPORT_GDI_ARB, WGL_DOUBLE_BUFFER_ARB };
563 int iAttribRet[sizeof(iAttribList)/sizeof(iAttribList[0])];
564 unsigned int nFormats;
565 int iPixelFormat;
566 BOOL res;
568 if (!pwglGetPixelFormatAttribivARB)
570 win_skip("wglGetPixelFormatAttribivARB is not available\n");
571 return;
574 nFormats = DescribePixelFormat(hdc, 0, 0, NULL);
575 for(iPixelFormat = 1;iPixelFormat <= nFormats;iPixelFormat++)
577 res = pwglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0,
578 sizeof(iAttribList)/sizeof(iAttribList[0]), iAttribList,
579 iAttribRet);
580 ok(res!=FALSE, "wglGetPixelFormatAttribivARB failed for pixel format %d\n", iPixelFormat);
581 if(res == FALSE)
582 continue;
584 ok(!(iAttribRet[0] && iAttribRet[1]), "GDI support and double buffering on pixel format %d\n", iPixelFormat);
588 static void test_acceleration(HDC hdc)
590 const int iAttribList[] = { WGL_ACCELERATION_ARB };
591 int iAttribRet[sizeof(iAttribList)/sizeof(iAttribList[0])];
592 unsigned int nFormats;
593 int iPixelFormat;
594 int res;
595 PIXELFORMATDESCRIPTOR pfd;
597 if (!pwglGetPixelFormatAttribivARB)
599 win_skip("wglGetPixelFormatAttribivARB is not available\n");
600 return;
603 nFormats = DescribePixelFormat(hdc, 0, 0, NULL);
604 for(iPixelFormat = 1; iPixelFormat <= nFormats; iPixelFormat++)
606 res = pwglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0,
607 sizeof(iAttribList)/sizeof(iAttribList[0]), iAttribList,
608 iAttribRet);
609 ok(res!=FALSE, "wglGetPixelFormatAttribivARB failed for pixel format %d\n", iPixelFormat);
610 if(res == FALSE)
611 continue;
613 memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
614 DescribePixelFormat(hdc, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
616 switch(iAttribRet[0])
618 case WGL_NO_ACCELERATION_ARB:
619 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);
620 break;
621 case WGL_GENERIC_ACCELERATION_ARB:
622 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);
623 break;
624 case WGL_FULL_ACCELERATION_ARB:
625 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);
626 break;
631 static void test_bitmap_rendering( BOOL use_dib )
633 PIXELFORMATDESCRIPTOR pfd;
634 int i, ret, bpp, iPixelFormat=0;
635 unsigned int nFormats;
636 HGLRC hglrc, hglrc2;
637 BITMAPINFO biDst;
638 HBITMAP bmpDst, oldDst, bmp2;
639 HDC hdcDst, hdcScreen;
640 UINT *dstBuffer = NULL;
642 hdcScreen = CreateCompatibleDC(0);
643 hdcDst = CreateCompatibleDC(0);
645 if (use_dib)
647 bpp = 32;
648 memset(&biDst, 0, sizeof(BITMAPINFO));
649 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
650 biDst.bmiHeader.biWidth = 4;
651 biDst.bmiHeader.biHeight = -4;
652 biDst.bmiHeader.biPlanes = 1;
653 biDst.bmiHeader.biBitCount = 32;
654 biDst.bmiHeader.biCompression = BI_RGB;
656 bmpDst = CreateDIBSection(0, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer, NULL, 0);
658 biDst.bmiHeader.biWidth = 12;
659 biDst.bmiHeader.biHeight = -12;
660 biDst.bmiHeader.biBitCount = 16;
661 bmp2 = CreateDIBSection(0, &biDst, DIB_RGB_COLORS, NULL, NULL, 0);
663 else
665 bpp = GetDeviceCaps( hdcScreen, BITSPIXEL );
666 bmpDst = CreateBitmap( 4, 4, 1, bpp, NULL );
667 bmp2 = CreateBitmap( 12, 12, 1, bpp, NULL );
670 oldDst = SelectObject(hdcDst, bmpDst);
672 trace( "testing on %s\n", use_dib ? "DIB" : "DDB" );
674 /* Pick a pixel format by hand because ChoosePixelFormat is unreliable */
675 nFormats = DescribePixelFormat(hdcDst, 0, 0, NULL);
676 for(i=1; i<=nFormats; i++)
678 memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
679 DescribePixelFormat(hdcDst, i, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
681 if((pfd.dwFlags & PFD_DRAW_TO_BITMAP) &&
682 (pfd.dwFlags & PFD_SUPPORT_OPENGL) &&
683 (pfd.cColorBits == bpp) &&
684 (pfd.cAlphaBits == 8) )
686 iPixelFormat = i;
687 break;
691 if(!iPixelFormat)
693 skip("Unable to find a suitable pixel format\n");
695 else
697 ret = SetPixelFormat(hdcDst, iPixelFormat, &pfd);
698 ok( ret, "SetPixelFormat failed\n" );
699 ret = GetPixelFormat( hdcDst );
700 ok( ret == iPixelFormat, "GetPixelFormat returned %d/%d\n", ret, iPixelFormat );
701 ret = SetPixelFormat(hdcDst, iPixelFormat + 1, &pfd);
702 ok( !ret, "SetPixelFormat succeeded\n" );
703 hglrc = wglCreateContext(hdcDst);
704 ok(hglrc != NULL, "Unable to create a context\n");
706 if(hglrc)
708 GLint viewport[4];
709 wglMakeCurrent(hdcDst, hglrc);
710 hglrc2 = wglCreateContext(hdcDst);
711 ok(hglrc2 != NULL, "Unable to create a context\n");
713 /* Note this is RGBA but we read ARGB back */
714 glClearColor((float)0x22/0xff, (float)0x33/0xff, (float)0x44/0xff, (float)0x11/0xff);
715 glClear(GL_COLOR_BUFFER_BIT);
716 glGetIntegerv( GL_VIEWPORT, viewport );
717 glFinish();
719 ok( viewport[0] == 0 && viewport[1] == 0 && viewport[2] == 4 && viewport[3] == 4,
720 "wrong viewport %d,%d,%d,%d\n", viewport[0], viewport[1], viewport[2], viewport[3] );
721 /* Note apparently the alpha channel is not supported by the software renderer (bitmap only works using software) */
722 if (dstBuffer)
723 for (i = 0; i < 16; i++)
724 ok(dstBuffer[i] == 0x223344 || dstBuffer[i] == 0x11223344, "Received color=%x at %u\n",
725 dstBuffer[i], i);
727 SelectObject(hdcDst, bmp2);
728 ret = GetPixelFormat( hdcDst );
729 ok( ret == iPixelFormat, "GetPixelFormat returned %d/%d\n", ret, iPixelFormat );
730 ret = SetPixelFormat(hdcDst, iPixelFormat + 1, &pfd);
731 ok( !ret, "SetPixelFormat succeeded\n" );
733 /* context still uses the old pixel format and viewport */
734 glClearColor((float)0x44/0xff, (float)0x33/0xff, (float)0x22/0xff, (float)0x11/0xff);
735 glClear(GL_COLOR_BUFFER_BIT);
736 glFinish();
737 glGetIntegerv( GL_VIEWPORT, viewport );
738 ok( viewport[0] == 0 && viewport[1] == 0 && viewport[2] == 4 && viewport[3] == 4,
739 "wrong viewport %d,%d,%d,%d\n", viewport[0], viewport[1], viewport[2], viewport[3] );
741 wglMakeCurrent(NULL, NULL);
742 wglMakeCurrent(hdcDst, hglrc);
743 glClearColor((float)0x44/0xff, (float)0x55/0xff, (float)0x66/0xff, (float)0x11/0xff);
744 glClear(GL_COLOR_BUFFER_BIT);
745 glFinish();
746 glGetIntegerv( GL_VIEWPORT, viewport );
747 ok( viewport[0] == 0 && viewport[1] == 0 && viewport[2] == 4 && viewport[3] == 4,
748 "wrong viewport %d,%d,%d,%d\n", viewport[0], viewport[1], viewport[2], viewport[3] );
750 wglMakeCurrent(hdcDst, hglrc2);
751 glGetIntegerv( GL_VIEWPORT, viewport );
752 ok( viewport[0] == 0 && viewport[1] == 0 && viewport[2] == 12 && viewport[3] == 12,
753 "wrong viewport %d,%d,%d,%d\n", viewport[0], viewport[1], viewport[2], viewport[3] );
755 wglMakeCurrent(hdcDst, hglrc);
756 glGetIntegerv( GL_VIEWPORT, viewport );
757 ok( viewport[0] == 0 && viewport[1] == 0 && viewport[2] == 4 && viewport[3] == 4,
758 "wrong viewport %d,%d,%d,%d\n", viewport[0], viewport[1], viewport[2], viewport[3] );
760 SelectObject(hdcDst, bmpDst);
761 ret = GetPixelFormat( hdcDst );
762 ok( ret == iPixelFormat, "GetPixelFormat returned %d/%d\n", ret, iPixelFormat );
763 ret = SetPixelFormat(hdcDst, iPixelFormat + 1, &pfd);
764 ok( !ret, "SetPixelFormat succeeded\n" );
765 wglMakeCurrent(hdcDst, hglrc2);
766 glGetIntegerv( GL_VIEWPORT, viewport );
767 ok( viewport[0] == 0 && viewport[1] == 0 && viewport[2] == 12 && viewport[3] == 12,
768 "wrong viewport %d,%d,%d,%d\n", viewport[0], viewport[1], viewport[2], viewport[3] );
770 wglDeleteContext(hglrc2);
771 wglDeleteContext(hglrc);
775 SelectObject(hdcDst, oldDst);
776 DeleteObject(bmp2);
777 DeleteObject(bmpDst);
778 DeleteDC(hdcDst);
779 DeleteDC(hdcScreen);
782 struct wgl_thread_param
784 HANDLE test_finished;
785 HWND hwnd;
786 HGLRC hglrc;
787 BOOL make_current;
788 BOOL make_current_error;
789 BOOL deleted;
790 DWORD deleted_error;
793 static DWORD WINAPI wgl_thread(void *param)
795 struct wgl_thread_param *p = param;
796 HDC hdc = GetDC( p->hwnd );
798 ok(!glGetString(GL_RENDERER) && !glGetString(GL_VERSION) && !glGetString(GL_VENDOR),
799 "Expected NULL string when no active context is set\n");
801 SetLastError(0xdeadbeef);
802 p->make_current = wglMakeCurrent(hdc, p->hglrc);
803 p->make_current_error = GetLastError();
804 p->deleted = wglDeleteContext(p->hglrc);
805 p->deleted_error = GetLastError();
806 ReleaseDC( p->hwnd, hdc );
807 SetEvent(p->test_finished);
808 return 0;
811 static void test_deletecontext(HWND hwnd, HDC hdc)
813 struct wgl_thread_param thread_params;
814 HGLRC hglrc = wglCreateContext(hdc);
815 HANDLE thread_handle;
816 BOOL res;
817 DWORD tid;
819 SetLastError(0xdeadbeef);
820 res = wglDeleteContext(NULL);
821 ok(res == FALSE, "wglDeleteContext succeeded\n");
822 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected last error to be ERROR_INVALID_HANDLE, got %u\n", GetLastError());
824 if(!hglrc)
826 skip("wglCreateContext failed!\n");
827 return;
830 res = wglMakeCurrent(hdc, hglrc);
831 if(!res)
833 skip("wglMakeCurrent failed!\n");
834 return;
837 /* WGL doesn't allow you to delete a context from a different thread than the one in which it is current.
838 * This differs from GLX which does allow it but it delays actual deletion until the context becomes not current.
840 thread_params.hglrc = hglrc;
841 thread_params.hwnd = hwnd;
842 thread_params.test_finished = CreateEventW(NULL, FALSE, FALSE, NULL);
843 thread_handle = CreateThread(NULL, 0, wgl_thread, &thread_params, 0, &tid);
844 ok(!!thread_handle, "Failed to create thread, last error %#x.\n", GetLastError());
845 if(thread_handle)
847 WaitForSingleObject(thread_handle, INFINITE);
848 ok(!thread_params.make_current, "Attempt to make WGL context from another thread passed\n");
849 ok(thread_params.make_current_error == ERROR_BUSY, "Expected last error to be ERROR_BUSY, got %u\n", thread_params.make_current_error);
850 ok(!thread_params.deleted, "Attempt to delete WGL context from another thread passed\n");
851 ok(thread_params.deleted_error == ERROR_BUSY, "Expected last error to be ERROR_BUSY, got %u\n", thread_params.deleted_error);
853 CloseHandle(thread_params.test_finished);
855 res = wglDeleteContext(hglrc);
856 ok(res == TRUE, "wglDeleteContext failed\n");
858 /* Attempting to delete the same context twice should fail. */
859 SetLastError(0xdeadbeef);
860 res = wglDeleteContext(hglrc);
861 ok(res == FALSE, "wglDeleteContext succeeded\n");
862 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected last error to be ERROR_INVALID_HANDLE, got %u\n", GetLastError());
864 /* WGL makes a context not current when deleting it. This differs from GLX behavior where
865 * deletion takes place when the thread becomes not current. */
866 hglrc = wglGetCurrentContext();
867 ok(hglrc == NULL, "A WGL context is active while none was expected\n");
871 static void test_getprocaddress(HDC hdc)
873 const char *extensions = (const char*)glGetString(GL_EXTENSIONS);
874 PROC func = NULL;
875 HGLRC ctx = wglGetCurrentContext();
877 if (!extensions)
879 skip("skipping wglGetProcAddress tests because no GL extensions supported\n");
880 return;
883 /* Core GL 1.0/1.1 functions should not be loadable through wglGetProcAddress.
884 * Try to load the function with and without a context.
886 func = wglGetProcAddress("glEnable");
887 ok(func == NULL, "Lookup of function glEnable with a context passed, expected a failure\n");
888 wglMakeCurrent(hdc, NULL);
889 func = wglGetProcAddress("glEnable");
890 ok(func == NULL, "Lookup of function glEnable without a context passed, expected a failure\n");
891 wglMakeCurrent(hdc, ctx);
893 /* The goal of the test will be to test behavior of wglGetProcAddress when
894 * no WGL context is active. Before the test we pick an extension (GL_ARB_multitexture)
895 * which any GL >=1.2.1 implementation supports. Unfortunately the GDI renderer doesn't
896 * support it. There aren't any extensions we can use for this test which are supported by
897 * both GDI and real drivers.
898 * Note GDI only has GL_EXT_bgra, GL_EXT_paletted_texture and GL_WIN_swap_hint.
900 if (!gl_extension_supported(extensions, "GL_ARB_multitexture"))
902 skip("skipping test because lack of GL_ARB_multitexture support\n");
903 return;
906 func = wglGetProcAddress("glActiveTextureARB");
907 ok(func != NULL, "Unable to lookup glActiveTextureARB, last error %#x\n", GetLastError());
909 /* Temporarily disable the context, so we can see that we can't retrieve functions now. */
910 wglMakeCurrent(hdc, NULL);
911 func = wglGetProcAddress("glActiveTextureARB");
912 ok(func == NULL, "Function lookup without a context passed, expected a failure; last error %#x\n", GetLastError());
913 wglMakeCurrent(hdc, ctx);
916 static void test_make_current_read(HDC hdc)
918 int res;
919 HDC hread;
920 HGLRC hglrc = wglCreateContext(hdc);
922 if(!hglrc)
924 skip("wglCreateContext failed!\n");
925 return;
928 res = wglMakeCurrent(hdc, hglrc);
929 if(!res)
931 skip("wglMakeCurrent failed!\n");
932 return;
935 /* Test what wglGetCurrentReadDCARB does for wglMakeCurrent as the spec doesn't mention it */
936 hread = pwglGetCurrentReadDCARB();
937 trace("hread %p, hdc %p\n", hread, hdc);
938 ok(hread == hdc, "wglGetCurrentReadDCARB failed for standard wglMakeCurrent\n");
940 pwglMakeContextCurrentARB(hdc, hdc, hglrc);
941 hread = pwglGetCurrentReadDCARB();
942 ok(hread == hdc, "wglGetCurrentReadDCARB failed for wglMakeContextCurrent\n");
945 static void test_dc(HWND hwnd, HDC hdc)
947 int pf1, pf2;
948 HDC hdc2;
950 /* Get another DC and make sure it has the same pixel format */
951 hdc2 = GetDC(hwnd);
952 if(hdc != hdc2)
954 pf1 = GetPixelFormat(hdc);
955 pf2 = GetPixelFormat(hdc2);
956 ok(pf1 == pf2, "Second DC does not have the same format (%d != %d)\n", pf1, pf2);
958 else
959 skip("Could not get a different DC for the window\n");
961 if(hdc2)
963 ReleaseDC(hwnd, hdc2);
964 hdc2 = NULL;
968 /* Nvidia converts win32 error codes to (0xc007 << 16) | win32_error_code */
969 #define NVIDIA_HRESULT_FROM_WIN32(x) (HRESULT_FROM_WIN32(x) | 0x40000000)
970 static void test_opengl3(HDC hdc)
972 /* Try to create a context compatible with OpenGL 1.x; 1.0-2.1 is allowed */
974 HGLRC gl3Ctx;
975 int attribs[] = {WGL_CONTEXT_MAJOR_VERSION_ARB, 1, 0};
977 gl3Ctx = pwglCreateContextAttribsARB(hdc, 0, attribs);
978 ok(gl3Ctx != 0, "pwglCreateContextAttribsARB for a 1.x context failed!\n");
979 wglDeleteContext(gl3Ctx);
982 /* Try to pass an invalid HDC */
984 HGLRC gl3Ctx;
985 DWORD error;
986 SetLastError(0xdeadbeef);
987 gl3Ctx = pwglCreateContextAttribsARB((HDC)0xdeadbeef, 0, 0);
988 ok(gl3Ctx == 0, "pwglCreateContextAttribsARB using an invalid HDC passed\n");
989 error = GetLastError();
990 ok(error == ERROR_DC_NOT_FOUND || error == ERROR_INVALID_HANDLE ||
991 broken(error == ERROR_DS_GENERIC_ERROR) ||
992 broken(error == NVIDIA_HRESULT_FROM_WIN32(ERROR_INVALID_DATA)), /* Nvidia Vista + Win7 */
993 "Expected ERROR_DC_NOT_FOUND, got error=%x\n", error);
994 wglDeleteContext(gl3Ctx);
997 /* Try to pass an invalid shareList */
999 HGLRC gl3Ctx;
1000 DWORD error;
1001 SetLastError(0xdeadbeef);
1002 gl3Ctx = pwglCreateContextAttribsARB(hdc, (HGLRC)0xdeadbeef, 0);
1003 ok(gl3Ctx == 0, "pwglCreateContextAttribsARB using an invalid shareList passed\n");
1004 error = GetLastError();
1005 /* The Nvidia implementation seems to return hresults instead of win32 error codes */
1006 ok(error == ERROR_INVALID_OPERATION || error == ERROR_INVALID_DATA ||
1007 error == NVIDIA_HRESULT_FROM_WIN32(ERROR_INVALID_OPERATION), "Expected ERROR_INVALID_OPERATION, got error=%x\n", error);
1008 wglDeleteContext(gl3Ctx);
1011 /* Try to create an OpenGL 3.0 context */
1013 int attribs[] = {WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 0, 0};
1014 HGLRC gl3Ctx = pwglCreateContextAttribsARB(hdc, 0, attribs);
1016 if(gl3Ctx == NULL)
1018 skip("Skipping the rest of the WGL_ARB_create_context test due to lack of OpenGL 3.0\n");
1019 return;
1022 wglDeleteContext(gl3Ctx);
1025 /* 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 */
1027 HGLRC glCtx = wglCreateContext(hdc);
1029 int attribs[] = {WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 0, 0};
1030 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};
1032 HGLRC gl3Ctx = pwglCreateContextAttribsARB(hdc, glCtx, attribs);
1033 ok(gl3Ctx != NULL, "Sharing of a display list between OpenGL 3.0 and OpenGL 1.x/2.x failed!\n");
1034 if(gl3Ctx)
1035 wglDeleteContext(gl3Ctx);
1037 gl3Ctx = pwglCreateContextAttribsARB(hdc, glCtx, attribs_future);
1038 ok(gl3Ctx != NULL, "Sharing of a display list between a forward compatible OpenGL 3.0 context and OpenGL 1.x/2.x failed!\n");
1039 if(gl3Ctx)
1040 wglDeleteContext(gl3Ctx);
1042 if(glCtx)
1043 wglDeleteContext(glCtx);
1046 /* Try to create an OpenGL 3.0 context and test windowless rendering */
1048 HGLRC gl3Ctx;
1049 int attribs[] = {WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 0, 0};
1050 BOOL res;
1052 gl3Ctx = pwglCreateContextAttribsARB(hdc, 0, attribs);
1053 ok(gl3Ctx != 0, "pwglCreateContextAttribsARB for a 3.0 context failed!\n");
1055 /* OpenGL 3.0 allows offscreen rendering WITHOUT a drawable
1056 * Neither AMD or Nvidia support it at this point. The WGL_ARB_create_context specs also say that
1057 * it is hard because drivers use the HDC to enter the display driver and it sounds like they don't
1058 * expect drivers to ever offer it.
1060 res = wglMakeCurrent(0, gl3Ctx);
1061 ok(res == FALSE, "Wow, OpenGL 3.0 windowless rendering passed while it was expected not to!\n");
1062 if(res)
1063 wglMakeCurrent(0, 0);
1065 if(gl3Ctx)
1066 wglDeleteContext(gl3Ctx);
1070 static void test_minimized(void)
1072 PIXELFORMATDESCRIPTOR pf_desc =
1074 sizeof(PIXELFORMATDESCRIPTOR),
1075 1, /* version */
1076 PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
1077 PFD_TYPE_RGBA,
1078 24, /* 24-bit color depth */
1079 0, 0, 0, 0, 0, 0, /* color bits */
1080 0, /* alpha buffer */
1081 0, /* shift bit */
1082 0, /* accumulation buffer */
1083 0, 0, 0, 0, /* accum bits */
1084 32, /* z-buffer */
1085 0, /* stencil buffer */
1086 0, /* auxiliary buffer */
1087 PFD_MAIN_PLANE, /* main layer */
1088 0, /* reserved */
1089 0, 0, 0 /* layer masks */
1091 int pixel_format;
1092 HWND window;
1093 LONG style;
1094 HGLRC ctx;
1095 BOOL ret;
1096 HDC dc;
1098 window = CreateWindowA("static", "opengl32_test",
1099 WS_POPUP | WS_MINIMIZE, 0, 0, 640, 480, 0, 0, 0, 0);
1100 ok(!!window, "Failed to create window, last error %#x.\n", GetLastError());
1102 dc = GetDC(window);
1103 ok(!!dc, "Failed to get DC.\n");
1105 pixel_format = ChoosePixelFormat(dc, &pf_desc);
1106 if (!pixel_format)
1108 win_skip("Failed to find pixel format.\n");
1109 ReleaseDC(window, dc);
1110 DestroyWindow(window);
1111 return;
1114 ret = SetPixelFormat(dc, pixel_format, &pf_desc);
1115 ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError());
1117 style = GetWindowLongA(window, GWL_STYLE);
1118 ok(style & WS_MINIMIZE, "Window should be minimized, got style %#x.\n", style);
1120 ctx = wglCreateContext(dc);
1121 ok(!!ctx, "Failed to create GL context, last error %#x.\n", GetLastError());
1123 ret = wglMakeCurrent(dc, ctx);
1124 ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1126 style = GetWindowLongA(window, GWL_STYLE);
1127 ok(style & WS_MINIMIZE, "window should be minimized, got style %#x.\n", style);
1129 ret = wglMakeCurrent(NULL, NULL);
1130 ok(ret, "Failed to clear current context, last error %#x.\n", GetLastError());
1132 ret = wglDeleteContext(ctx);
1133 ok(ret, "Failed to delete GL context, last error %#x.\n", GetLastError());
1135 ReleaseDC(window, dc);
1136 DestroyWindow(window);
1139 static void test_window_dc(void)
1141 PIXELFORMATDESCRIPTOR pf_desc =
1143 sizeof(PIXELFORMATDESCRIPTOR),
1144 1, /* version */
1145 PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
1146 PFD_TYPE_RGBA,
1147 24, /* 24-bit color depth */
1148 0, 0, 0, 0, 0, 0, /* color bits */
1149 0, /* alpha buffer */
1150 0, /* shift bit */
1151 0, /* accumulation buffer */
1152 0, 0, 0, 0, /* accum bits */
1153 32, /* z-buffer */
1154 0, /* stencil buffer */
1155 0, /* auxiliary buffer */
1156 PFD_MAIN_PLANE, /* main layer */
1157 0, /* reserved */
1158 0, 0, 0 /* layer masks */
1160 int pixel_format;
1161 HWND window;
1162 RECT vp, r;
1163 HGLRC ctx;
1164 BOOL ret;
1165 HDC dc;
1167 window = CreateWindowA("static", "opengl32_test",
1168 WS_OVERLAPPEDWINDOW, 0, 0, 640, 480, 0, 0, 0, 0);
1169 ok(!!window, "Failed to create window, last error %#x.\n", GetLastError());
1171 ShowWindow(window, SW_SHOW);
1173 dc = GetWindowDC(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 ctx = wglCreateContext(dc);
1189 ok(!!ctx, "Failed to create GL context, last error %#x.\n", GetLastError());
1191 ret = wglMakeCurrent(dc, ctx);
1192 ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1194 GetClientRect(window, &r);
1195 glGetIntegerv(GL_VIEWPORT, (GLint *)&vp);
1196 ok(EqualRect(&r, &vp), "Viewport not equal to client rect.\n");
1198 ret = wglMakeCurrent(NULL, NULL);
1199 ok(ret, "Failed to clear current context, last error %#x.\n", GetLastError());
1201 ret = wglDeleteContext(ctx);
1202 ok(ret, "Failed to delete GL context, last error %#x.\n", GetLastError());
1204 ReleaseDC(window, dc);
1205 DestroyWindow(window);
1208 static void test_message_window(void)
1210 PIXELFORMATDESCRIPTOR pf_desc =
1212 sizeof(PIXELFORMATDESCRIPTOR),
1213 1, /* version */
1214 PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
1215 PFD_TYPE_RGBA,
1216 24, /* 24-bit color depth */
1217 0, 0, 0, 0, 0, 0, /* color bits */
1218 0, /* alpha buffer */
1219 0, /* shift bit */
1220 0, /* accumulation buffer */
1221 0, 0, 0, 0, /* accum bits */
1222 32, /* z-buffer */
1223 0, /* stencil buffer */
1224 0, /* auxiliary buffer */
1225 PFD_MAIN_PLANE, /* main layer */
1226 0, /* reserved */
1227 0, 0, 0 /* layer masks */
1229 int pixel_format;
1230 HWND window;
1231 RECT vp, r;
1232 HGLRC ctx;
1233 BOOL ret;
1234 HDC dc;
1235 GLenum glerr;
1237 window = CreateWindowA("static", "opengl32_test",
1238 WS_OVERLAPPEDWINDOW, 0, 0, 100, 100, HWND_MESSAGE, 0, 0, 0);
1239 if (!window)
1241 win_skip( "HWND_MESSAGE not supported\n" );
1242 return;
1244 dc = GetDC(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 glClear(GL_COLOR_BUFFER_BIT);
1270 glFinish();
1271 glerr = glGetError();
1272 ok(glerr == GL_NO_ERROR, "Failed glClear, error %#x.\n", glerr);
1273 ret = SwapBuffers(dc);
1274 ok(ret, "Failed SwapBuffers, error %#x.\n", GetLastError());
1276 ret = wglMakeCurrent(NULL, NULL);
1277 ok(ret, "Failed to clear current context, last error %#x.\n", GetLastError());
1279 ret = wglDeleteContext(ctx);
1280 ok(ret, "Failed to delete GL context, last error %#x.\n", GetLastError());
1282 ReleaseDC(window, dc);
1283 DestroyWindow(window);
1286 static void test_destroy(HDC oldhdc)
1288 PIXELFORMATDESCRIPTOR pf_desc =
1290 sizeof(PIXELFORMATDESCRIPTOR),
1291 1, /* version */
1292 PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
1293 PFD_TYPE_RGBA,
1294 24, /* 24-bit color depth */
1295 0, 0, 0, 0, 0, 0, /* color bits */
1296 0, /* alpha buffer */
1297 0, /* shift bit */
1298 0, /* accumulation buffer */
1299 0, 0, 0, 0, /* accum bits */
1300 32, /* z-buffer */
1301 0, /* stencil buffer */
1302 0, /* auxiliary buffer */
1303 PFD_MAIN_PLANE, /* main layer */
1304 0, /* reserved */
1305 0, 0, 0 /* layer masks */
1307 int pixel_format;
1308 HWND window;
1309 HGLRC ctx;
1310 BOOL ret;
1311 HDC dc;
1312 GLenum glerr;
1313 DWORD err;
1314 HGLRC oldctx = wglGetCurrentContext();
1316 ok(!!oldctx, "Expected to find a valid current context.\n");
1318 window = CreateWindowA("static", "opengl32_test",
1319 WS_POPUP, 0, 0, 640, 480, 0, 0, 0, 0);
1320 ok(!!window, "Failed to create window, last error %#x.\n", GetLastError());
1322 dc = GetDC(window);
1323 ok(!!dc, "Failed to get DC.\n");
1325 pixel_format = ChoosePixelFormat(dc, &pf_desc);
1326 if (!pixel_format)
1328 win_skip("Failed to find pixel format.\n");
1329 ReleaseDC(window, dc);
1330 DestroyWindow(window);
1331 return;
1334 ret = SetPixelFormat(dc, pixel_format, &pf_desc);
1335 ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError());
1337 ctx = wglCreateContext(dc);
1338 ok(!!ctx, "Failed to create GL context, last error %#x.\n", GetLastError());
1340 ret = wglMakeCurrent(dc, ctx);
1341 ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1343 glClear(GL_COLOR_BUFFER_BIT);
1344 glFinish();
1345 glerr = glGetError();
1346 ok(glerr == GL_NO_ERROR, "Failed glClear, error %#x.\n", glerr);
1347 ret = SwapBuffers(dc);
1348 ok(ret, "Failed SwapBuffers, error %#x.\n", GetLastError());
1350 ret = DestroyWindow(window);
1351 ok(ret, "Failed to destroy window, last error %#x.\n", GetLastError());
1353 ok(wglGetCurrentContext() == ctx, "Wrong current context.\n");
1355 SetLastError(0xdeadbeef);
1356 ret = wglMakeCurrent(dc, ctx);
1357 err = GetLastError();
1358 ok(!ret && err == ERROR_INVALID_HANDLE,
1359 "Unexpected behavior when making context current, ret %d, last error %#x.\n", ret, err);
1360 SetLastError(0xdeadbeef);
1361 ret = SwapBuffers(dc);
1362 err = GetLastError();
1363 ok(!ret && err == ERROR_INVALID_HANDLE, "Unexpected behavior with SwapBuffer, last error %#x.\n", err);
1365 ok(wglGetCurrentContext() == ctx, "Wrong current context.\n");
1367 glClear(GL_COLOR_BUFFER_BIT);
1368 glFinish();
1369 glerr = glGetError();
1370 ok(glerr == GL_NO_ERROR, "Failed glClear, error %#x.\n", glerr);
1371 SetLastError(0xdeadbeef);
1372 ret = SwapBuffers(dc);
1373 err = GetLastError();
1374 ok(!ret && err == ERROR_INVALID_HANDLE, "Unexpected behavior with SwapBuffer, last error %#x.\n", err);
1376 ret = wglMakeCurrent(NULL, NULL);
1377 ok(ret, "Failed to clear current context, last error %#x.\n", GetLastError());
1379 glClear(GL_COLOR_BUFFER_BIT);
1380 glFinish();
1381 glerr = glGetError();
1382 ok(glerr == GL_INVALID_OPERATION, "Failed glClear, error %#x.\n", glerr);
1383 SetLastError(0xdeadbeef);
1384 ret = SwapBuffers(dc);
1385 err = GetLastError();
1386 ok(!ret && err == ERROR_INVALID_HANDLE, "Unexpected behavior with SwapBuffer, last error %#x.\n", err);
1388 SetLastError(0xdeadbeef);
1389 ret = wglMakeCurrent(dc, ctx);
1390 err = GetLastError();
1391 ok(!ret && err == ERROR_INVALID_HANDLE,
1392 "Unexpected behavior when making context current, ret %d, last error %#x.\n", ret, err);
1394 ok(wglGetCurrentContext() == NULL, "Wrong current context.\n");
1396 ret = wglMakeCurrent(oldhdc, oldctx);
1397 ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1398 ok(wglGetCurrentContext() == oldctx, "Wrong current context.\n");
1400 SetLastError(0xdeadbeef);
1401 ret = wglMakeCurrent(dc, ctx);
1402 err = GetLastError();
1403 ok(!ret && err == ERROR_INVALID_HANDLE,
1404 "Unexpected behavior when making context current, ret %d, last error %#x.\n", ret, err);
1406 ok(wglGetCurrentContext() == oldctx, "Wrong current context.\n");
1408 ret = wglDeleteContext(ctx);
1409 ok(ret, "Failed to delete GL context, last error %#x.\n", GetLastError());
1411 ReleaseDC(window, dc);
1413 ret = wglMakeCurrent(oldhdc, oldctx);
1414 ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1417 static void test_destroy_read(HDC oldhdc)
1419 PIXELFORMATDESCRIPTOR pf_desc =
1421 sizeof(PIXELFORMATDESCRIPTOR),
1422 1, /* version */
1423 PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
1424 PFD_TYPE_RGBA,
1425 24, /* 24-bit color depth */
1426 0, 0, 0, 0, 0, 0, /* color bits */
1427 0, /* alpha buffer */
1428 0, /* shift bit */
1429 0, /* accumulation buffer */
1430 0, 0, 0, 0, /* accum bits */
1431 32, /* z-buffer */
1432 0, /* stencil buffer */
1433 0, /* auxiliary buffer */
1434 PFD_MAIN_PLANE, /* main layer */
1435 0, /* reserved */
1436 0, 0, 0 /* layer masks */
1438 int pixel_format;
1439 HWND draw_window, read_window;
1440 HGLRC ctx;
1441 BOOL ret;
1442 HDC read_dc, draw_dc;
1443 GLenum glerr;
1444 DWORD err;
1445 HGLRC oldctx = wglGetCurrentContext();
1447 ok(!!oldctx, "Expected to find a valid current context\n");
1449 draw_window = CreateWindowA("static", "opengl32_test",
1450 WS_POPUP, 0, 0, 640, 480, 0, 0, 0, 0);
1451 ok(!!draw_window, "Failed to create window, last error %#x.\n", GetLastError());
1453 draw_dc = GetDC(draw_window);
1454 ok(!!draw_dc, "Failed to get DC.\n");
1456 pixel_format = ChoosePixelFormat(draw_dc, &pf_desc);
1457 if (!pixel_format)
1459 win_skip("Failed to find pixel format.\n");
1460 ReleaseDC(draw_window, draw_dc);
1461 DestroyWindow(draw_window);
1462 return;
1465 ret = SetPixelFormat(draw_dc, pixel_format, &pf_desc);
1466 ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError());
1468 read_window = CreateWindowA("static", "opengl32_test",
1469 WS_POPUP, 0, 0, 640, 480, 0, 0, 0, 0);
1470 ok(!!read_window, "Failed to create window, last error %#x.\n", GetLastError());
1472 read_dc = GetDC(read_window);
1473 ok(!!draw_dc, "Failed to get DC.\n");
1475 pixel_format = ChoosePixelFormat(read_dc, &pf_desc);
1476 if (!pixel_format)
1478 win_skip("Failed to find pixel format.\n");
1479 ReleaseDC(read_window, read_dc);
1480 DestroyWindow(read_window);
1481 ReleaseDC(draw_window, draw_dc);
1482 DestroyWindow(draw_window);
1483 return;
1486 ret = SetPixelFormat(read_dc, pixel_format, &pf_desc);
1487 ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError());
1489 ctx = wglCreateContext(draw_dc);
1490 ok(!!ctx, "Failed to create GL context, last error %#x.\n", GetLastError());
1492 ret = pwglMakeContextCurrentARB(draw_dc, read_dc, ctx);
1493 ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1495 glCopyPixels(0, 0, 640, 480, GL_COLOR);
1496 glFinish();
1497 glerr = glGetError();
1498 ok(glerr == GL_NO_ERROR, "Failed glCopyPixel, error %#x.\n", glerr);
1499 ret = SwapBuffers(draw_dc);
1500 ok(ret, "Failed SwapBuffers, error %#x.\n", GetLastError());
1502 ret = DestroyWindow(read_window);
1503 ok(ret, "Failed to destroy window, last error %#x.\n", GetLastError());
1505 ok(wglGetCurrentContext() == ctx, "Wrong current context.\n");
1507 if (0) /* Crashes on AMD on Windows */
1509 glCopyPixels(0, 0, 640, 480, GL_COLOR);
1510 glFinish();
1511 glerr = glGetError();
1512 ok(glerr == GL_NO_ERROR, "Failed glCopyPixel, error %#x.\n", glerr);
1515 glClear(GL_COLOR_BUFFER_BIT);
1516 glFinish();
1517 glerr = glGetError();
1518 ok(glerr == GL_NO_ERROR, "Failed glClear, error %#x.\n", glerr);
1519 ret = SwapBuffers(draw_dc);
1520 ok(ret, "Failed SwapBuffers, error %#x.\n", GetLastError());
1522 ret = wglMakeCurrent(NULL, NULL);
1523 ok(ret, "Failed to clear current context, last error %#x.\n", GetLastError());
1525 if (0) /* This crashes with Nvidia drivers on Windows. */
1527 SetLastError(0xdeadbeef);
1528 ret = pwglMakeContextCurrentARB(draw_dc, read_dc, ctx);
1529 err = GetLastError();
1530 ok(!ret && err == ERROR_INVALID_HANDLE,
1531 "Unexpected behavior when making context current, ret %d, last error %#x.\n", ret, err);
1534 ret = DestroyWindow(draw_window);
1535 ok(ret, "Failed to destroy window, last error %#x.\n", GetLastError());
1537 glClear(GL_COLOR_BUFFER_BIT);
1538 glFinish();
1539 glerr = glGetError();
1540 ok(glerr == GL_INVALID_OPERATION, "Failed glClear, error %#x.\n", glerr);
1541 SetLastError(0xdeadbeef);
1542 ret = SwapBuffers(draw_dc);
1543 err = GetLastError();
1544 ok(!ret && err == ERROR_INVALID_HANDLE, "Unexpected behavior with SwapBuffer, last error %#x.\n", err);
1546 SetLastError(0xdeadbeef);
1547 ret = pwglMakeContextCurrentARB(draw_dc, read_dc, ctx);
1548 err = GetLastError();
1549 ok(!ret && (err == ERROR_INVALID_HANDLE || err == 0xc0070006),
1550 "Unexpected behavior when making context current, ret %d, last error %#x.\n", ret, err);
1552 ok(wglGetCurrentContext() == NULL, "Wrong current context.\n");
1554 wglMakeCurrent(NULL, NULL);
1556 wglMakeCurrent(oldhdc, oldctx);
1557 ok(wglGetCurrentContext() == oldctx, "Wrong current context.\n");
1559 SetLastError(0xdeadbeef);
1560 ret = pwglMakeContextCurrentARB(draw_dc, read_dc, ctx);
1561 err = GetLastError();
1562 ok(!ret && (err == ERROR_INVALID_HANDLE || err == 0xc0070006),
1563 "Unexpected behavior when making context current, last error %#x.\n", err);
1565 ok(wglGetCurrentContext() == oldctx, "Wrong current context.\n");
1567 ret = wglDeleteContext(ctx);
1568 ok(ret, "Failed to delete GL context, last error %#x.\n", GetLastError());
1570 ReleaseDC(read_window, read_dc);
1571 ReleaseDC(draw_window, draw_dc);
1573 wglMakeCurrent(oldhdc, oldctx);
1576 static void test_swap_control(HDC oldhdc)
1578 PIXELFORMATDESCRIPTOR pf_desc =
1580 sizeof(PIXELFORMATDESCRIPTOR),
1581 1, /* version */
1582 PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
1583 PFD_TYPE_RGBA,
1584 24, /* 24-bit color depth */
1585 0, 0, 0, 0, 0, 0, /* color bits */
1586 0, /* alpha buffer */
1587 0, /* shift bit */
1588 0, /* accumulation buffer */
1589 0, 0, 0, 0, /* accum bits */
1590 32, /* z-buffer */
1591 0, /* stencil buffer */
1592 0, /* auxiliary buffer */
1593 PFD_MAIN_PLANE, /* main layer */
1594 0, /* reserved */
1595 0, 0, 0 /* layer masks */
1597 int pixel_format;
1598 HWND window1, window2, old_parent;
1599 HGLRC ctx1, ctx2, oldctx;
1600 BOOL ret;
1601 HDC dc1, dc2;
1602 int interval;
1604 oldctx = wglGetCurrentContext();
1605 ok(!!oldctx, "Expected to find a valid current context.\n");
1607 window1 = CreateWindowA("static", "opengl32_test",
1608 WS_POPUP, 0, 0, 640, 480, 0, 0, 0, 0);
1609 ok(!!window1, "Failed to create window1, last error %#x.\n", GetLastError());
1611 dc1 = GetDC(window1);
1612 ok(!!dc1, "Failed to get DC.\n");
1614 pixel_format = ChoosePixelFormat(dc1, &pf_desc);
1615 if (!pixel_format)
1617 win_skip("Failed to find pixel format.\n");
1618 ReleaseDC(window1, dc1);
1619 DestroyWindow(window1);
1620 return;
1623 ret = SetPixelFormat(dc1, pixel_format, &pf_desc);
1624 ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError());
1626 ctx1 = wglCreateContext(dc1);
1627 ok(!!ctx1, "Failed to create GL context, last error %#x.\n", GetLastError());
1629 ret = wglMakeCurrent(dc1, ctx1);
1630 ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1632 interval = pwglGetSwapIntervalEXT();
1633 ok(interval == 1, "Expected default swap interval 1, got %d\n", interval);
1635 ret = pwglSwapIntervalEXT(0);
1636 ok(ret, "Failed to set swap interval to 0, last error %#x.\n", GetLastError());
1638 interval = pwglGetSwapIntervalEXT();
1639 ok(interval == 0, "Expected swap interval 0, got %d\n", interval);
1641 /* Check what interval we get on a second context on the same drawable.*/
1642 ctx2 = wglCreateContext(dc1);
1643 ok(!!ctx2, "Failed to create GL context, last error %#x.\n", GetLastError());
1645 ret = wglMakeCurrent(dc1, ctx2);
1646 ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1648 interval = pwglGetSwapIntervalEXT();
1649 ok(interval == 0, "Expected swap interval 0, got %d\n", interval);
1651 /* A second window is created to see whether its swap interval was affected
1652 * by previous calls.
1654 window2 = CreateWindowA("static", "opengl32_test",
1655 WS_POPUP, 0, 0, 640, 480, 0, 0, 0, 0);
1656 ok(!!window2, "Failed to create window2, last error %#x.\n", GetLastError());
1658 dc2 = GetDC(window2);
1659 ok(!!dc2, "Failed to get DC.\n");
1661 ret = SetPixelFormat(dc2, pixel_format, &pf_desc);
1662 ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError());
1664 ret = wglMakeCurrent(dc2, ctx1);
1665 ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1667 /* Since the second window lacks the swap interval, this proves that the interval
1668 * is not global or shared among contexts.
1670 interval = pwglGetSwapIntervalEXT();
1671 ok(interval == 1, "Expected default swap interval 1, got %d\n", interval);
1673 /* Test if setting the parent of a window resets the swap interval. */
1674 ret = wglMakeCurrent(dc1, ctx1);
1675 ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1677 old_parent = SetParent(window1, window2);
1678 ok(!!old_parent, "Failed to make window1 a child of window2, last error %#x.\n", GetLastError());
1680 interval = pwglGetSwapIntervalEXT();
1681 ok(interval == 0, "Expected swap interval 0, got %d\n", interval);
1683 ret = wglDeleteContext(ctx1);
1684 ok(ret, "Failed to delete GL context, last error %#x.\n", GetLastError());
1685 ret = wglDeleteContext(ctx2);
1686 ok(ret, "Failed to delete GL context, last error %#x.\n", GetLastError());
1688 ReleaseDC(window1, dc1);
1689 DestroyWindow(window1);
1690 ReleaseDC(window2, dc2);
1691 DestroyWindow(window2);
1693 wglMakeCurrent(oldhdc, oldctx);
1696 START_TEST(opengl)
1698 HWND hwnd;
1699 PIXELFORMATDESCRIPTOR pfd = {
1700 sizeof(PIXELFORMATDESCRIPTOR),
1701 1, /* version */
1702 PFD_DRAW_TO_WINDOW |
1703 PFD_SUPPORT_OPENGL |
1704 PFD_DOUBLEBUFFER,
1705 PFD_TYPE_RGBA,
1706 24, /* 24-bit color depth */
1707 0, 0, 0, 0, 0, 0, /* color bits */
1708 0, /* alpha buffer */
1709 0, /* shift bit */
1710 0, /* accumulation buffer */
1711 0, 0, 0, 0, /* accum bits */
1712 32, /* z-buffer */
1713 0, /* stencil buffer */
1714 0, /* auxiliary buffer */
1715 PFD_MAIN_PLANE, /* main layer */
1716 0, /* reserved */
1717 0, 0, 0 /* layer masks */
1720 hwnd = CreateWindowA("static", "Title", WS_OVERLAPPEDWINDOW, 10, 10, 200, 200, NULL, NULL,
1721 NULL, NULL);
1722 ok(hwnd != NULL, "err: %d\n", GetLastError());
1723 if (hwnd)
1725 HDC hdc;
1726 int iPixelFormat, res;
1727 HGLRC hglrc;
1728 DWORD error;
1729 ShowWindow(hwnd, SW_SHOW);
1731 hdc = GetDC(hwnd);
1733 iPixelFormat = ChoosePixelFormat(hdc, &pfd);
1734 if(iPixelFormat == 0)
1736 /* This should never happen as ChoosePixelFormat always returns a closest match, but currently this fails in Wine if we don't have glX */
1737 win_skip("Unable to find pixel format.\n");
1738 goto cleanup;
1741 /* We shouldn't be able to create a context from a hdc which doesn't have a pixel format set */
1742 hglrc = wglCreateContext(hdc);
1743 ok(hglrc == NULL, "wglCreateContext should fail when no pixel format has been set, but it passed\n");
1744 error = GetLastError();
1745 ok(error == ERROR_INVALID_PIXEL_FORMAT, "expected ERROR_INVALID_PIXEL_FORMAT for wglCreateContext without a pixelformat set, but received %#x\n", error);
1747 res = SetPixelFormat(hdc, iPixelFormat, &pfd);
1748 ok(res, "SetPixelformat failed: %x\n", GetLastError());
1750 test_bitmap_rendering( TRUE );
1751 test_bitmap_rendering( FALSE );
1752 test_minimized();
1753 test_window_dc();
1754 test_message_window();
1755 test_dc(hwnd, hdc);
1757 ok(!glGetString(GL_RENDERER) && !glGetString(GL_VERSION) && !glGetString(GL_VENDOR),
1758 "Expected NULL string when no active context is set\n");
1759 hglrc = wglCreateContext(hdc);
1760 res = wglMakeCurrent(hdc, hglrc);
1761 ok(res, "wglMakeCurrent failed!\n");
1762 if(res)
1764 trace("OpenGL renderer: %s\n", glGetString(GL_RENDERER));
1765 trace("OpenGL driver version: %s\n", glGetString(GL_VERSION));
1766 trace("OpenGL vendor: %s\n", glGetString(GL_VENDOR));
1768 else
1770 skip("Skipping OpenGL tests without a current context\n");
1771 return;
1774 /* Initialisation of WGL functions depends on an implicit WGL context. For this reason we can't load them before making
1775 * any WGL call :( On Wine this would work but not on real Windows because there can be different implementations (software, ICD, MCD).
1777 init_functions();
1778 test_getprocaddress(hdc);
1779 test_deletecontext(hwnd, hdc);
1780 test_makecurrent(hdc);
1782 /* The lack of wglGetExtensionsStringARB in general means broken software rendering or the lack of decent OpenGL support, skip tests in such cases */
1783 if (!pwglGetExtensionsStringARB)
1785 win_skip("wglGetExtensionsStringARB is not available\n");
1786 return;
1789 test_choosepixelformat();
1790 test_setpixelformat(hdc);
1791 test_destroy(hdc);
1792 test_sharelists(hdc);
1793 test_colorbits(hdc);
1794 test_gdi_dbuf(hdc);
1795 test_acceleration(hdc);
1797 wgl_extensions = pwglGetExtensionsStringARB(hdc);
1798 if(wgl_extensions == NULL) skip("Skipping opengl32 tests because this OpenGL implementation doesn't support WGL extensions!\n");
1800 if(strstr(wgl_extensions, "WGL_ARB_create_context"))
1801 test_opengl3(hdc);
1803 if(strstr(wgl_extensions, "WGL_ARB_make_current_read"))
1805 test_make_current_read(hdc);
1806 test_destroy_read(hdc);
1808 else
1809 skip("WGL_ARB_make_current_read not supported, skipping test\n");
1811 if(strstr(wgl_extensions, "WGL_ARB_pbuffer"))
1812 test_pbuffers(hdc);
1813 else
1814 skip("WGL_ARB_pbuffer not supported, skipping pbuffer test\n");
1816 if(strstr(wgl_extensions, "WGL_EXT_swap_control"))
1817 test_swap_control(hdc);
1818 else
1819 skip("WGL_EXT_swap_control not supported, skipping test\n");
1821 cleanup:
1822 ReleaseDC(hwnd, hdc);
1823 DestroyWindow(hwnd);