1 /*
2 * Some tests for OpenGL functions
3 *
4 * Copyright (C) 2007-2008 Roderick Colenbrander
5 *
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.
10 *
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.
15 *
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
19 */
20
21 #include <windows.h>
22 #include <wingdi.h>
23 #include "wine/test.h"
24 #include "wine/wgl.h"
25
26 #define MAX_FORMATS 256
27
28 /* WGL_ARB_create_context */
29 static HGLRC (WINAPI *pwglCreateContextAttribsARB)(HDC hDC, HGLRC hShareContext, const int *attribList);
30
31 /* WGL_ARB_extensions_string */
32 static const char* (WINAPI *pwglGetExtensionsStringARB)(HDC);
33 static int (WINAPI *pwglReleasePbufferDCARB)(HPBUFFERARB, HDC);
34
35 /* WGL_ARB_make_current_read */
36 static BOOL (WINAPI *pwglMakeContextCurrentARB)(HDC hdraw, HDC hread, HGLRC hglrc);
37 static HDC (WINAPI *pwglGetCurrentReadDCARB)(void);
38
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 *);
42
43 /* WGL_ARB_pbuffer */
44 static HPBUFFERARB (WINAPI *pwglCreatePbufferARB)(HDC, int, int, int, const int *);
45 static HDC (WINAPI *pwglGetPbufferDCARB)(HPBUFFERARB);
46
47 /* WGL_EXT_swap_control */
48 static BOOL (WINAPI *pwglSwapIntervalEXT)(int interval);
49 static int (WINAPI *pwglGetSwapIntervalEXT)(void);
50
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 *);
55
56 static const char* wgl_extensions = NULL;
57
init_functions(void)58 static void init_functions(void)
59 {
60 #define GET_PROC(func) \
61 p ## func = (void*)wglGetProcAddress(#func); \
62 if(!p ## func) \
63 trace("wglGetProcAddress(%s) failed\n", #func);
64
65 /* WGL_ARB_create_context */
66 GET_PROC(wglCreateContextAttribsARB);
67
68 /* WGL_ARB_extensions_string */
69 GET_PROC(wglGetExtensionsStringARB)
70
71 /* WGL_ARB_make_current_read */
72 GET_PROC(wglMakeContextCurrentARB);
73 GET_PROC(wglGetCurrentReadDCARB);
74
75 /* WGL_ARB_pixel_format */
76 GET_PROC(wglChoosePixelFormatARB)
77 GET_PROC(wglGetPixelFormatAttribivARB)
78
79 /* WGL_ARB_pbuffer */
80 GET_PROC(wglCreatePbufferARB)
81 GET_PROC(wglGetPbufferDCARB)
82 GET_PROC(wglReleasePbufferDCARB)
83
84 /* WGL_EXT_swap_control */
85 GET_PROC(wglSwapIntervalEXT)
86 GET_PROC(wglGetSwapIntervalEXT)
87
88 /* GL_ARB_debug_output */
89 GET_PROC(glDebugMessageCallbackARB)
90 GET_PROC(glDebugMessageControlARB)
91 GET_PROC(glDebugMessageInsertARB)
92
93 #undef GET_PROC
94 }
95
gl_extension_supported(const char * extensions,const char * extension_string)96 static BOOL gl_extension_supported(const char *extensions, const char *extension_string)
97 {
98 size_t ext_str_len = strlen(extension_string);
99
100 while (*extensions)
101 {
102 const char *start;
103 size_t len;
104
105 while (isspace(*extensions))
106 ++extensions;
107 start = extensions;
108 while (!isspace(*extensions) && *extensions)
109 ++extensions;
110
111 len = extensions - start;
112 if (!len)
113 continue;
114
115 if (len == ext_str_len && !memcmp(start, extension_string, ext_str_len))
116 {
117 return TRUE;
118 }
119 }
120 return FALSE;
121 }
122
test_pbuffers(HDC hdc)123 static void test_pbuffers(HDC hdc)
124 {
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;
132
133 nOnscreenFormats = DescribePixelFormat(hdc, 0, 0, NULL);
134
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.
141 *
142 * The first thing we need are pixelformats with pbuffer capabilities.
143 */
144 res = pwglChoosePixelFormatARB(hdc, iAttribList, NULL, MAX_FORMATS, iFormats, &nFormats);
145 if(res <= 0)
146 {
147 skip("No pbuffer compatible formats found while WGL_ARB_pbuffer is supported\n");
148 return;
149 }
150 trace("nOnscreenFormats: %d\n", nOnscreenFormats);
151 trace("Total number of pbuffer capable pixelformats: %d\n", nFormats);
152
153 /* Try to select an onscreen pixelformat out of the list */
154 for(i=0; i < nFormats; i++)
155 {
156 /* Check if the format is onscreen, if it is choose it */
157 if(iFormats[i] <= nOnscreenFormats)
158 {
159 iPixelFormat = iFormats[i];
160 trace("Selected iPixelFormat=%d\n", iPixelFormat);
161 break;
162 }
163 }
164
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.
170 *
171 * Below we check if the pixelformat is also supported onscreen.
172 */
173 if(iPixelFormat != 0)
174 {
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");
180
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);
187
188 pwglReleasePbufferDCARB(pbuffer, pbuffer_hdc);
189 }
190 else skip("Pbuffer test for onscreen pixelformat skipped as no onscreen format with pbuffer capabilities have been found\n");
191
192 /* Search for a real offscreen format */
193 for(i=0, iPixelFormat=0; i<nFormats; i++)
194 {
195 if(iFormats[i] > nOnscreenFormats)
196 {
197 iPixelFormat = iFormats[i];
198 trace("Selected iPixelFormat: %d\n", iPixelFormat);
199 break;
200 }
201 }
202
203 if(iPixelFormat != 0)
204 {
205 HDC pbuffer_hdc;
206 HPBUFFERARB pbuffer = pwglCreatePbufferARB(hdc, iPixelFormat, 640 /* width */, 480 /* height */, NULL);
207 if(pbuffer)
208 {
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);
212
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);
217 }
218 else skip("Pbuffer creation failed!\n");
219 }
220 else skip("Pbuffer test for offscreen pixelformat skipped as no offscreen-only format with pbuffer capabilities has been found\n");
221 }
222
test_pfd(const PIXELFORMATDESCRIPTOR * pfd,PIXELFORMATDESCRIPTOR * fmt)223 static int test_pfd(const PIXELFORMATDESCRIPTOR *pfd, PIXELFORMATDESCRIPTOR *fmt)
224 {
225 int pf;
226 HDC hdc;
227 HWND hwnd;
228
229 hwnd = CreateWindowA("static", "Title", WS_OVERLAPPEDWINDOW, 10, 10, 200, 200, NULL, NULL,
230 NULL, NULL);
231 if (!hwnd)
232 return 0;
233
234 hdc = GetDC( hwnd );
235 pf = ChoosePixelFormat( hdc, pfd );
236 if (pf && fmt)
237 {
238 memset(fmt, 0, sizeof(*fmt));
239 ok(DescribePixelFormat( hdc, pf, sizeof(*fmt), fmt ),
240 "DescribePixelFormat failed with error: %u\n", GetLastError());
241 }
242 ReleaseDC( hwnd, hdc );
243 DestroyWindow( hwnd );
244
245 return pf;
246 }
247
test_choosepixelformat(void)248 static void test_choosepixelformat(void)
249 {
250 PIXELFORMATDESCRIPTOR pfd = {
251 sizeof(PIXELFORMATDESCRIPTOR),
252 1, /* version */
253 PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL,
254 PFD_TYPE_RGBA,
255 0, /* color depth */
256 0, 0, 0, 0, 0, 0, /* color bits */
257 0, /* alpha buffer */
258 0, /* shift bit */
259 0, /* accumulation buffer */
260 0, 0, 0, 0, /* accum bits */
261 0, /* z-buffer */
262 0, /* stencil buffer */
263 0, /* auxiliary buffer */
264 PFD_MAIN_PLANE, /* main layer */
265 0, /* reserved */
266 0, 0, 0 /* layer masks */
267 };
268 PIXELFORMATDESCRIPTOR ret_fmt;
269
270 ok( test_pfd(&pfd, NULL), "Simple pfd failed\n" );
271 pfd.dwFlags |= PFD_DOUBLEBUFFER_DONTCARE;
272 ok( test_pfd(&pfd, NULL), "PFD_DOUBLEBUFFER_DONTCARE failed\n" );
273 pfd.dwFlags |= PFD_STEREO_DONTCARE;
274 ok( test_pfd(&pfd, NULL), "PFD_DOUBLEBUFFER_DONTCARE|PFD_STEREO_DONTCARE failed\n" );
275 pfd.dwFlags &= ~PFD_DOUBLEBUFFER_DONTCARE;
276 ok( test_pfd(&pfd, NULL), "PFD_STEREO_DONTCARE failed\n" );
277 pfd.dwFlags &= ~PFD_STEREO_DONTCARE;
278 pfd.iPixelType = 32;
279 ok( test_pfd(&pfd, &ret_fmt), "Invalid pixel format 32 failed\n" );
280 ok( ret_fmt.iPixelType == PFD_TYPE_RGBA, "Expected pixel type PFD_TYPE_RGBA, got %d\n", ret_fmt.iPixelType );
281 pfd.iPixelType = 33;
282 ok( test_pfd(&pfd, &ret_fmt), "Invalid pixel format 33 failed\n" );
283 ok( ret_fmt.iPixelType == PFD_TYPE_RGBA, "Expected pixel type PFD_TYPE_RGBA, got %d\n", ret_fmt.iPixelType );
284 pfd.iPixelType = 15;
285 ok( test_pfd(&pfd, &ret_fmt), "Invalid pixel format 15 failed\n" );
286 ok( ret_fmt.iPixelType == PFD_TYPE_RGBA, "Expected pixel type PFD_TYPE_RGBA, got %d\n", ret_fmt.iPixelType );
287 pfd.iPixelType = PFD_TYPE_RGBA;
288
289 pfd.cColorBits = 32;
290 ok( test_pfd(&pfd, NULL), "Simple pfd failed\n" );
291 pfd.dwFlags |= PFD_DOUBLEBUFFER_DONTCARE;
292 ok( test_pfd(&pfd, NULL), "PFD_DOUBLEBUFFER_DONTCARE failed\n" );
293 pfd.dwFlags |= PFD_STEREO_DONTCARE;
294 ok( test_pfd(&pfd, NULL), "PFD_DOUBLEBUFFER_DONTCARE|PFD_STEREO_DONTCARE failed\n" );
295 pfd.dwFlags &= ~PFD_DOUBLEBUFFER_DONTCARE;
296 ok( test_pfd(&pfd, NULL), "PFD_STEREO_DONTCARE failed\n" );
297 pfd.dwFlags &= ~PFD_STEREO_DONTCARE;
298 pfd.cColorBits = 0;
299
300 pfd.cAlphaBits = 8;
301 ok( test_pfd(&pfd, NULL), "Simple pfd failed\n" );
302 pfd.dwFlags |= PFD_DOUBLEBUFFER_DONTCARE;
303 ok( test_pfd(&pfd, NULL), "PFD_DOUBLEBUFFER_DONTCARE failed\n" );
304 pfd.dwFlags |= PFD_STEREO_DONTCARE;
305 ok( test_pfd(&pfd, NULL), "PFD_DOUBLEBUFFER_DONTCARE|PFD_STEREO_DONTCARE failed\n" );
306 pfd.dwFlags &= ~PFD_DOUBLEBUFFER_DONTCARE;
307 ok( test_pfd(&pfd, NULL), "PFD_STEREO_DONTCARE failed\n" );
308 pfd.dwFlags &= ~PFD_STEREO_DONTCARE;
309 pfd.cAlphaBits = 0;
310
311 pfd.cStencilBits = 8;
312 ok( test_pfd(&pfd, NULL), "Simple pfd failed\n" );
313 pfd.dwFlags |= PFD_DOUBLEBUFFER_DONTCARE;
314 ok( test_pfd(&pfd, NULL), "PFD_DOUBLEBUFFER_DONTCARE failed\n" );
315 pfd.dwFlags |= PFD_STEREO_DONTCARE;
316 ok( test_pfd(&pfd, NULL), "PFD_DOUBLEBUFFER_DONTCARE|PFD_STEREO_DONTCARE failed\n" );
317 pfd.dwFlags &= ~PFD_DOUBLEBUFFER_DONTCARE;
318 ok( test_pfd(&pfd, NULL), "PFD_STEREO_DONTCARE failed\n" );
319 pfd.dwFlags &= ~PFD_STEREO_DONTCARE;
320 pfd.cStencilBits = 0;
321
322 pfd.cAuxBuffers = 1;
323 ok( test_pfd(&pfd, NULL), "Simple pfd failed\n" );
324 pfd.dwFlags |= PFD_DOUBLEBUFFER_DONTCARE;
325 ok( test_pfd(&pfd, NULL), "PFD_DOUBLEBUFFER_DONTCARE failed\n" );
326 pfd.dwFlags |= PFD_STEREO_DONTCARE;
327 ok( test_pfd(&pfd, NULL), "PFD_DOUBLEBUFFER_DONTCARE|PFD_STEREO_DONTCARE failed\n" );
328 pfd.dwFlags &= ~PFD_DOUBLEBUFFER_DONTCARE;
329 ok( test_pfd(&pfd, NULL), "PFD_STEREO_DONTCARE failed\n" );
330 pfd.dwFlags &= ~PFD_STEREO_DONTCARE;
331 pfd.cAuxBuffers = 0;
332 }
333
gl_debug_message_callback(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar * message,const void * userParam)334 static void WINAPI gl_debug_message_callback(GLenum source, GLenum type, GLuint id, GLenum severity,
335 GLsizei length, const GLchar *message, const void *userParam)
336 {
337 DWORD *count = (DWORD *)userParam;
338 (*count)++;
339 }
340
test_debug_message_callback(void)341 static void test_debug_message_callback(void)
342 {
343 static const char testmsg[] = "Hello World";
344 DWORD count;
345
346 if (!pglDebugMessageCallbackARB)
347 {
348 skip("glDebugMessageCallbackARB not supported\n");
349 return;
350 }
351
352 glEnable(GL_DEBUG_OUTPUT);
353 glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
354
355 pglDebugMessageCallbackARB(gl_debug_message_callback, &count);
356 pglDebugMessageControlARB(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_TRUE);
357
358 count = 0;
359 pglDebugMessageInsertARB(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_OTHER, 0x42424242,
360 GL_DEBUG_SEVERITY_LOW, sizeof(testmsg), testmsg);
361 ok(count == 1, "expected count == 1, got %u\n", count);
362
363 glDisable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
364 glDisable(GL_DEBUG_OUTPUT);
365 }
366
test_setpixelformat(HDC winhdc)367 static void test_setpixelformat(HDC winhdc)
368 {
369 int res = 0;
370 int nCfgs;
371 int pf;
372 int i;
373 HWND hwnd;
374 PIXELFORMATDESCRIPTOR pfd = {
375 sizeof(PIXELFORMATDESCRIPTOR),
376 1, /* version */
377 PFD_DRAW_TO_WINDOW |
378 PFD_SUPPORT_OPENGL |
379 PFD_DOUBLEBUFFER,
380 PFD_TYPE_RGBA,
381 24, /* 24-bit color depth */
382 0, 0, 0, 0, 0, 0, /* color bits */
383 0, /* alpha buffer */
384 0, /* shift bit */
385 0, /* accumulation buffer */
386 0, 0, 0, 0, /* accum bits */
387 32, /* z-buffer */
388 0, /* stencil buffer */
389 0, /* auxiliary buffer */
390 PFD_MAIN_PLANE, /* main layer */
391 0, /* reserved */
392 0, 0, 0 /* layer masks */
393 };
394
395 HDC hdc = GetDC(0);
396 ok(hdc != 0, "GetDC(0) failed!\n");
397
398 /* This should pass even on the main device context */
399 pf = ChoosePixelFormat(hdc, &pfd);
400 ok(pf != 0, "ChoosePixelFormat failed on main device context\n");
401
402 /* SetPixelFormat on the main device context 'X root window' should fail,
403 * but some broken drivers allow it
404 */
405 res = SetPixelFormat(hdc, pf, &pfd);
406 trace("SetPixelFormat on main device context %s\n", res ? "succeeded" : "failed");
407
408 /* Setting the same format that was set on the HDC is allowed; other
409 formats fail */
410 nCfgs = DescribePixelFormat(winhdc, 0, 0, NULL);
411 pf = GetPixelFormat(winhdc);
412 for(i = 1;i <= nCfgs;i++)
413 {
414 int res = SetPixelFormat(winhdc, i, NULL);
415 if(i == pf) ok(res, "Failed to set the same pixel format\n");
416 else ok(!res, "Unexpectedly set an alternate pixel format\n");
417 }
418
419 hwnd = CreateWindowA("static", "Title", WS_OVERLAPPEDWINDOW, 10, 10, 200, 200, NULL, NULL,
420 NULL, NULL);
421 ok(hwnd != NULL, "err: %d\n", GetLastError());
422 if (hwnd)
423 {
424 HDC hdc = GetDC( hwnd );
425 pf = ChoosePixelFormat( hdc, &pfd );
426 ok( pf != 0, "ChoosePixelFormat failed\n" );
427 res = SetPixelFormat( hdc, pf, &pfd );
428 ok( res != 0, "SetPixelFormat failed\n" );
429 i = GetPixelFormat( hdc );
430 ok( i == pf, "GetPixelFormat returned wrong format %d/%d\n", i, pf );
431 ReleaseDC( hwnd, hdc );
432 hdc = GetWindowDC( hwnd );
433 i = GetPixelFormat( hdc );
434 ok( i == pf, "GetPixelFormat returned wrong format %d/%d\n", i, pf );
435 ReleaseDC( hwnd, hdc );
436 DestroyWindow( hwnd );
437 /* check various calls with invalid hdc */
438 SetLastError( 0xdeadbeef );
439 i = GetPixelFormat( hdc );
440 ok( i == 0, "GetPixelFormat succeeded\n" );
441 ok( GetLastError() == ERROR_INVALID_PIXEL_FORMAT, "wrong error %u\n", GetLastError() );
442 SetLastError( 0xdeadbeef );
443 res = SetPixelFormat( hdc, pf, &pfd );
444 ok( !res, "SetPixelFormat succeeded\n" );
445 ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError() );
446 SetLastError( 0xdeadbeef );
447 res = DescribePixelFormat( hdc, 0, 0, NULL );
448 ok( !res, "DescribePixelFormat succeeded\n" );
449 ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError() );
450 SetLastError( 0xdeadbeef );
451 pf = ChoosePixelFormat( hdc, &pfd );
452 ok( !pf, "ChoosePixelFormat succeeded\n" );
453 ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError() );
454 SetLastError( 0xdeadbeef );
455 res = SwapBuffers( hdc );
456 ok( !res, "SwapBuffers succeeded\n" );
457 ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError() );
458 SetLastError( 0xdeadbeef );
459 ok( !wglCreateContext( hdc ), "CreateContext succeeded\n" );
460 ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError() );
461 }
462
463 hwnd = CreateWindowA("static", "Title", WS_OVERLAPPEDWINDOW, 10, 10, 200, 200, NULL, NULL,
464 NULL, NULL);
465 ok(hwnd != NULL, "err: %d\n", GetLastError());
466 if (hwnd)
467 {
468 HDC hdc = GetWindowDC( hwnd );
469 pf = ChoosePixelFormat( hdc, &pfd );
470 ok( pf != 0, "ChoosePixelFormat failed\n" );
471 res = SetPixelFormat( hdc, pf, &pfd );
472 ok( res != 0, "SetPixelFormat failed\n" );
473 i = GetPixelFormat( hdc );
474 ok( i == pf, "GetPixelFormat returned wrong format %d/%d\n", i, pf );
475 ReleaseDC( hwnd, hdc );
476 DestroyWindow( hwnd );
477 }
478 }
479
test_sharelists(HDC winhdc)480 static void test_sharelists(HDC winhdc)
481 {
482 HGLRC hglrc1, hglrc2, hglrc3;
483 BOOL res;
484
485 hglrc1 = wglCreateContext(winhdc);
486 res = wglShareLists(0, 0);
487 ok(res == FALSE, "Sharing display lists for no contexts passed!\n");
488
489 /* Test 1: Create a context and just share lists without doing anything special */
490 hglrc2 = wglCreateContext(winhdc);
491 if(hglrc2)
492 {
493 res = wglShareLists(hglrc1, hglrc2);
494 ok(res, "Sharing of display lists failed\n");
495 wglDeleteContext(hglrc2);
496 }
497
498 /* Test 2: Share display lists with a 'destination' context which has been made current */
499 hglrc2 = wglCreateContext(winhdc);
500 if(hglrc2)
501 {
502 res = wglMakeCurrent(winhdc, hglrc2);
503 ok(res, "Make current failed\n");
504 res = wglShareLists(hglrc1, hglrc2);
505 ok(res, "Sharing display lists with a destination context which has been made current failed\n");
506 wglMakeCurrent(0, 0);
507 wglDeleteContext(hglrc2);
508 }
509
510 /* Test 3: Share display lists with a context which already shares display lists with another context.
511 * According to MSDN the second parameter cannot share any display lists but some buggy drivers might allow it */
512 hglrc3 = wglCreateContext(winhdc);
513 if(hglrc3)
514 {
515 res = wglShareLists(hglrc3, hglrc1);
516 ok(res == FALSE, "Sharing of display lists passed for a context which already shared lists before\n");
517 wglDeleteContext(hglrc3);
518 }
519
520 /* Test 4: Share display lists with a 'source' context which has been made current */
521 hglrc2 = wglCreateContext(winhdc);
522 if(hglrc2)
523 {
524 res = wglMakeCurrent(winhdc, hglrc1);
525 ok(res, "Make current failed\n");
526 res = wglShareLists(hglrc1, hglrc2);
527 ok(res, "Sharing display lists with a source context which has been made current failed\n");
528 wglMakeCurrent(0, 0);
529 wglDeleteContext(hglrc2);
530 }
531 }
532
test_makecurrent(HDC winhdc)533 static void test_makecurrent(HDC winhdc)
534 {
535 BOOL ret;
536 HGLRC hglrc;
537
538 hglrc = wglCreateContext(winhdc);
539 ok( hglrc != 0, "wglCreateContext failed\n" );
540
541 ret = wglMakeCurrent( winhdc, hglrc );
542 ok( ret, "wglMakeCurrent failed\n" );
543
544 ok( wglGetCurrentContext() == hglrc, "wrong context\n" );
545
546 /* set the same context again */
547 ret = wglMakeCurrent( winhdc, hglrc );
548 ok( ret, "wglMakeCurrent failed\n" );
549
550 /* check wglMakeCurrent(x, y) after another call to wglMakeCurrent(x, y) */
551 ret = wglMakeCurrent( winhdc, NULL );
552 ok( ret, "wglMakeCurrent failed\n" );
553
554 ret = wglMakeCurrent( winhdc, NULL );
555 ok( ret, "wglMakeCurrent failed\n" );
556
557 SetLastError( 0xdeadbeef );
558 ret = wglMakeCurrent( NULL, NULL );
559 ok( !ret || broken(ret) /* nt4 */, "wglMakeCurrent succeeded\n" );
560 if (!ret) ok( GetLastError() == ERROR_INVALID_HANDLE,
561 "Expected ERROR_INVALID_HANDLE, got error=%x\n", GetLastError() );
562
563 ret = wglMakeCurrent( winhdc, NULL );
564 ok( ret, "wglMakeCurrent failed\n" );
565
566 ret = wglMakeCurrent( winhdc, hglrc );
567 ok( ret, "wglMakeCurrent failed\n" );
568
569 ret = wglMakeCurrent( NULL, NULL );
570 ok( ret, "wglMakeCurrent failed\n" );
571
572 ok( wglGetCurrentContext() == NULL, "wrong context\n" );
573
574 SetLastError( 0xdeadbeef );
575 ret = wglMakeCurrent( NULL, NULL );
576 ok( !ret || broken(ret) /* nt4 */, "wglMakeCurrent succeeded\n" );
577 if (!ret) ok( GetLastError() == ERROR_INVALID_HANDLE,
578 "Expected ERROR_INVALID_HANDLE, got error=%x\n", GetLastError() );
579
580 ret = wglMakeCurrent( winhdc, hglrc );
581 ok( ret, "wglMakeCurrent failed\n" );
582 }
583
test_colorbits(HDC hdc)584 static void test_colorbits(HDC hdc)
585 {
586 const int iAttribList[] = { WGL_COLOR_BITS_ARB, WGL_RED_BITS_ARB, WGL_GREEN_BITS_ARB,
587 WGL_BLUE_BITS_ARB, WGL_ALPHA_BITS_ARB };
588 int iAttribRet[ARRAY_SIZE(iAttribList)];
589 const int iAttribs[] = { WGL_ALPHA_BITS_ARB, 1, 0 };
590 unsigned int nFormats;
591 BOOL res;
592 int iPixelFormat = 0;
593
594 if (!pwglChoosePixelFormatARB)
595 {
596 win_skip("wglChoosePixelFormatARB is not available\n");
597 return;
598 }
599
600 /* We need a pixel format with at least one bit of alpha */
601 res = pwglChoosePixelFormatARB(hdc, iAttribs, NULL, 1, &iPixelFormat, &nFormats);
602 if(res == FALSE || nFormats == 0)
603 {
604 skip("No suitable pixel formats found\n");
605 return;
606 }
607
608 res = pwglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0, ARRAY_SIZE(iAttribList), iAttribList,
609 iAttribRet);
610 if(res == FALSE)
611 {
612 skip("wglGetPixelFormatAttribivARB failed\n");
613 return;
614 }
615 iAttribRet[1] += iAttribRet[2]+iAttribRet[3]+iAttribRet[4];
616 ok(iAttribRet[0] == iAttribRet[1], "WGL_COLOR_BITS_ARB (%d) does not equal R+G+B+A (%d)!\n",
617 iAttribRet[0], iAttribRet[1]);
618 }
619
test_gdi_dbuf(HDC hdc)620 static void test_gdi_dbuf(HDC hdc)
621 {
622 const int iAttribList[] = { WGL_SUPPORT_GDI_ARB, WGL_DOUBLE_BUFFER_ARB };
623 int iAttribRet[ARRAY_SIZE(iAttribList)];
624 unsigned int nFormats;
625 int iPixelFormat;
626 BOOL res;
627
628 if (!pwglGetPixelFormatAttribivARB)
629 {
630 win_skip("wglGetPixelFormatAttribivARB is not available\n");
631 return;
632 }
633
634 nFormats = DescribePixelFormat(hdc, 0, 0, NULL);
635 for(iPixelFormat = 1;iPixelFormat <= nFormats;iPixelFormat++)
636 {
637 res = pwglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0, ARRAY_SIZE(iAttribList),
638 iAttribList, iAttribRet);
639 ok(res!=FALSE, "wglGetPixelFormatAttribivARB failed for pixel format %d\n", iPixelFormat);
640 if(res == FALSE)
641 continue;
642
643 ok(!(iAttribRet[0] && iAttribRet[1]), "GDI support and double buffering on pixel format %d\n", iPixelFormat);
644 }
645 }
646
test_acceleration(HDC hdc)647 static void test_acceleration(HDC hdc)
648 {
649 const int iAttribList[] = { WGL_ACCELERATION_ARB };
650 int iAttribRet[ARRAY_SIZE(iAttribList)];
651 unsigned int nFormats;
652 int iPixelFormat;
653 int res;
654 PIXELFORMATDESCRIPTOR pfd;
655
656 if (!pwglGetPixelFormatAttribivARB)
657 {
658 win_skip("wglGetPixelFormatAttribivARB is not available\n");
659 return;
660 }
661
662 nFormats = DescribePixelFormat(hdc, 0, 0, NULL);
663 for(iPixelFormat = 1; iPixelFormat <= nFormats; iPixelFormat++)
664 {
665 res = pwglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0, ARRAY_SIZE(iAttribList),
666 iAttribList, iAttribRet);
667 ok(res!=FALSE, "wglGetPixelFormatAttribivARB failed for pixel format %d\n", iPixelFormat);
668 if(res == FALSE)
669 continue;
670
671 memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
672 DescribePixelFormat(hdc, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
673
674 switch(iAttribRet[0])
675 {
676 case WGL_NO_ACCELERATION_ARB:
677 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);
678 break;
679 case WGL_GENERIC_ACCELERATION_ARB:
680 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);
681 break;
682 case WGL_FULL_ACCELERATION_ARB:
683 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);
684 break;
685 }
686 }
687 }
688
test_bitmap_rendering(BOOL use_dib)689 static void test_bitmap_rendering( BOOL use_dib )
690 {
691 PIXELFORMATDESCRIPTOR pfd;
692 int i, ret, bpp, iPixelFormat=0;
693 unsigned int nFormats;
694 HGLRC hglrc, hglrc2;
695 BITMAPINFO biDst;
696 HBITMAP bmpDst, oldDst, bmp2;
697 HDC hdcDst, hdcScreen;
698 UINT *dstBuffer = NULL;
699
700 hdcScreen = CreateCompatibleDC(0);
701 hdcDst = CreateCompatibleDC(0);
702
703 if (use_dib)
704 {
705 bpp = 32;
706 memset(&biDst, 0, sizeof(BITMAPINFO));
707 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
708 biDst.bmiHeader.biWidth = 4;
709 biDst.bmiHeader.biHeight = -4;
710 biDst.bmiHeader.biPlanes = 1;
711 biDst.bmiHeader.biBitCount = 32;
712 biDst.bmiHeader.biCompression = BI_RGB;
713
714 bmpDst = CreateDIBSection(0, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer, NULL, 0);
715
716 biDst.bmiHeader.biWidth = 12;
717 biDst.bmiHeader.biHeight = -12;
718 biDst.bmiHeader.biBitCount = 16;
719 bmp2 = CreateDIBSection(0, &biDst, DIB_RGB_COLORS, NULL, NULL, 0);
720 }
721 else
722 {
723 bpp = GetDeviceCaps( hdcScreen, BITSPIXEL );
724 bmpDst = CreateBitmap( 4, 4, 1, bpp, NULL );
725 bmp2 = CreateBitmap( 12, 12, 1, bpp, NULL );
726 }
727
728 oldDst = SelectObject(hdcDst, bmpDst);
729
730 trace( "testing on %s\n", use_dib ? "DIB" : "DDB" );
731
732 /* Pick a pixel format by hand because ChoosePixelFormat is unreliable */
733 nFormats = DescribePixelFormat(hdcDst, 0, 0, NULL);
734 for(i=1; i<=nFormats; i++)
735 {
736 memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
737 DescribePixelFormat(hdcDst, i, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
738
739 if((pfd.dwFlags & PFD_DRAW_TO_BITMAP) &&
740 (pfd.dwFlags & PFD_SUPPORT_OPENGL) &&
741 (pfd.cColorBits == bpp) &&
742 (pfd.cAlphaBits == 8) )
743 {
744 iPixelFormat = i;
745 break;
746 }
747 }
748
749 if(!iPixelFormat)
750 {
751 skip("Unable to find a suitable pixel format\n");
752 }
753 else
754 {
755 ret = SetPixelFormat(hdcDst, iPixelFormat, &pfd);
756 ok( ret, "SetPixelFormat failed\n" );
757 ret = GetPixelFormat( hdcDst );
758 ok( ret == iPixelFormat, "GetPixelFormat returned %d/%d\n", ret, iPixelFormat );
759 ret = SetPixelFormat(hdcDst, iPixelFormat + 1, &pfd);
760 ok( !ret, "SetPixelFormat succeeded\n" );
761 hglrc = wglCreateContext(hdcDst);
762 ok(hglrc != NULL, "Unable to create a context\n");
763
764 if(hglrc)
765 {
766 GLint viewport[4];
767 wglMakeCurrent(hdcDst, hglrc);
768 hglrc2 = wglCreateContext(hdcDst);
769 ok(hglrc2 != NULL, "Unable to create a context\n");
770
771 /* Note this is RGBA but we read ARGB back */
772 glClearColor((float)0x22/0xff, (float)0x33/0xff, (float)0x44/0xff, (float)0x11/0xff);
773 glClear(GL_COLOR_BUFFER_BIT);
774 glGetIntegerv( GL_VIEWPORT, viewport );
775 glFinish();
776
777 ok( viewport[0] == 0 && viewport[1] == 0 && viewport[2] == 4 && viewport[3] == 4,
778 "wrong viewport %d,%d,%d,%d\n", viewport[0], viewport[1], viewport[2], viewport[3] );
779 /* Note apparently the alpha channel is not supported by the software renderer (bitmap only works using software) */
780 if (dstBuffer)
781 for (i = 0; i < 16; i++)
782 ok(dstBuffer[i] == 0x223344 || dstBuffer[i] == 0x11223344, "Received color=%x at %u\n",
783 dstBuffer[i], i);
784
785 SelectObject(hdcDst, bmp2);
786 ret = GetPixelFormat( hdcDst );
787 ok( ret == iPixelFormat, "GetPixelFormat returned %d/%d\n", ret, iPixelFormat );
788 ret = SetPixelFormat(hdcDst, iPixelFormat + 1, &pfd);
789 ok( !ret, "SetPixelFormat succeeded\n" );
790
791 /* context still uses the old pixel format and viewport */
792 glClearColor((float)0x44/0xff, (float)0x33/0xff, (float)0x22/0xff, (float)0x11/0xff);
793 glClear(GL_COLOR_BUFFER_BIT);
794 glFinish();
795 glGetIntegerv( GL_VIEWPORT, viewport );
796 ok( viewport[0] == 0 && viewport[1] == 0 && viewport[2] == 4 && viewport[3] == 4,
797 "wrong viewport %d,%d,%d,%d\n", viewport[0], viewport[1], viewport[2], viewport[3] );
798
799 wglMakeCurrent(NULL, NULL);
800 wglMakeCurrent(hdcDst, hglrc);
801 glClearColor((float)0x44/0xff, (float)0x55/0xff, (float)0x66/0xff, (float)0x11/0xff);
802 glClear(GL_COLOR_BUFFER_BIT);
803 glFinish();
804 glGetIntegerv( GL_VIEWPORT, viewport );
805 ok( viewport[0] == 0 && viewport[1] == 0 && viewport[2] == 4 && viewport[3] == 4,
806 "wrong viewport %d,%d,%d,%d\n", viewport[0], viewport[1], viewport[2], viewport[3] );
807
808 wglMakeCurrent(hdcDst, hglrc2);
809 glGetIntegerv( GL_VIEWPORT, viewport );
810 ok( viewport[0] == 0 && viewport[1] == 0 && viewport[2] == 12 && viewport[3] == 12,
811 "wrong viewport %d,%d,%d,%d\n", viewport[0], viewport[1], viewport[2], viewport[3] );
812
813 wglMakeCurrent(hdcDst, hglrc);
814 glGetIntegerv( GL_VIEWPORT, viewport );
815 ok( viewport[0] == 0 && viewport[1] == 0 && viewport[2] == 4 && viewport[3] == 4,
816 "wrong viewport %d,%d,%d,%d\n", viewport[0], viewport[1], viewport[2], viewport[3] );
817
818 SelectObject(hdcDst, bmpDst);
819 ret = GetPixelFormat( hdcDst );
820 ok( ret == iPixelFormat, "GetPixelFormat returned %d/%d\n", ret, iPixelFormat );
821 ret = SetPixelFormat(hdcDst, iPixelFormat + 1, &pfd);
822 ok( !ret, "SetPixelFormat succeeded\n" );
823 wglMakeCurrent(hdcDst, hglrc2);
824 glGetIntegerv( GL_VIEWPORT, viewport );
825 ok( viewport[0] == 0 && viewport[1] == 0 && viewport[2] == 12 && viewport[3] == 12,
826 "wrong viewport %d,%d,%d,%d\n", viewport[0], viewport[1], viewport[2], viewport[3] );
827
828 wglDeleteContext(hglrc2);
829 wglDeleteContext(hglrc);
830 }
831 }
832
833 SelectObject(hdcDst, oldDst);
834 DeleteObject(bmp2);
835 DeleteObject(bmpDst);
836 DeleteDC(hdcDst);
837 DeleteDC(hdcScreen);
838 }
839
840 struct wgl_thread_param
841 {
842 HANDLE test_finished;
843 HWND hwnd;
844 HGLRC hglrc;
845 BOOL make_current;
846 BOOL make_current_error;
847 BOOL deleted;
848 DWORD deleted_error;
849 };
850
wgl_thread(void * param)851 static DWORD WINAPI wgl_thread(void *param)
852 {
853 struct wgl_thread_param *p = param;
854 HDC hdc = GetDC( p->hwnd );
855
856 ok(!glGetString(GL_RENDERER) && !glGetString(GL_VERSION) && !glGetString(GL_VENDOR),
857 "Expected NULL string when no active context is set\n");
858
859 SetLastError(0xdeadbeef);
860 p->make_current = wglMakeCurrent(hdc, p->hglrc);
861 p->make_current_error = GetLastError();
862 p->deleted = wglDeleteContext(p->hglrc);
863 p->deleted_error = GetLastError();
864 ReleaseDC( p->hwnd, hdc );
865 SetEvent(p->test_finished);
866 return 0;
867 }
868
test_deletecontext(HWND hwnd,HDC hdc)869 static void test_deletecontext(HWND hwnd, HDC hdc)
870 {
871 struct wgl_thread_param thread_params;
872 HGLRC hglrc = wglCreateContext(hdc);
873 HANDLE thread_handle;
874 BOOL res;
875 DWORD tid;
876
877 SetLastError(0xdeadbeef);
878 res = wglDeleteContext(NULL);
879 ok(res == FALSE, "wglDeleteContext succeeded\n");
880 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected last error to be ERROR_INVALID_HANDLE, got %u\n", GetLastError());
881
882 if(!hglrc)
883 {
884 skip("wglCreateContext failed!\n");
885 return;
886 }
887
888 res = wglMakeCurrent(hdc, hglrc);
889 if(!res)
890 {
891 skip("wglMakeCurrent failed!\n");
892 return;
893 }
894
895 /* WGL doesn't allow you to delete a context from a different thread than the one in which it is current.
896 * This differs from GLX which does allow it but it delays actual deletion until the context becomes not current.
897 */
898 thread_params.hglrc = hglrc;
899 thread_params.hwnd = hwnd;
900 thread_params.test_finished = CreateEventW(NULL, FALSE, FALSE, NULL);
901 thread_handle = CreateThread(NULL, 0, wgl_thread, &thread_params, 0, &tid);
902 ok(!!thread_handle, "Failed to create thread, last error %#x.\n", GetLastError());
903 if(thread_handle)
904 {
905 WaitForSingleObject(thread_handle, INFINITE);
906 ok(!thread_params.make_current, "Attempt to make WGL context from another thread passed\n");
907 ok(thread_params.make_current_error == ERROR_BUSY, "Expected last error to be ERROR_BUSY, got %u\n", thread_params.make_current_error);
908 ok(!thread_params.deleted, "Attempt to delete WGL context from another thread passed\n");
909 ok(thread_params.deleted_error == ERROR_BUSY, "Expected last error to be ERROR_BUSY, got %u\n", thread_params.deleted_error);
910 }
911 CloseHandle(thread_params.test_finished);
912
913 res = wglDeleteContext(hglrc);
914 ok(res == TRUE, "wglDeleteContext failed\n");
915
916 /* Attempting to delete the same context twice should fail. */
917 SetLastError(0xdeadbeef);
918 res = wglDeleteContext(hglrc);
919 ok(res == FALSE, "wglDeleteContext succeeded\n");
920 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected last error to be ERROR_INVALID_HANDLE, got %u\n", GetLastError());
921
922 /* WGL makes a context not current when deleting it. This differs from GLX behavior where
923 * deletion takes place when the thread becomes not current. */
924 hglrc = wglGetCurrentContext();
925 ok(hglrc == NULL, "A WGL context is active while none was expected\n");
926 }
927
928
test_getprocaddress(HDC hdc)929 static void test_getprocaddress(HDC hdc)
930 {
931 const char *extensions = (const char*)glGetString(GL_EXTENSIONS);
932 PROC func = NULL;
933 HGLRC ctx = wglGetCurrentContext();
934
935 if (!extensions)
936 {
937 skip("skipping wglGetProcAddress tests because no GL extensions supported\n");
938 return;
939 }
940
941 /* Core GL 1.0/1.1 functions should not be loadable through wglGetProcAddress.
942 * Try to load the function with and without a context.
943 */
944 func = wglGetProcAddress("glEnable");
945 ok(func == NULL, "Lookup of function glEnable with a context passed, expected a failure\n");
946 wglMakeCurrent(hdc, NULL);
947 func = wglGetProcAddress("glEnable");
948 ok(func == NULL, "Lookup of function glEnable without a context passed, expected a failure\n");
949 wglMakeCurrent(hdc, ctx);
950
951 /* The goal of the test will be to test behavior of wglGetProcAddress when
952 * no WGL context is active. Before the test we pick an extension (GL_ARB_multitexture)
953 * which any GL >=1.2.1 implementation supports. Unfortunately the GDI renderer doesn't
954 * support it. There aren't any extensions we can use for this test which are supported by
955 * both GDI and real drivers.
956 * Note GDI only has GL_EXT_bgra, GL_EXT_paletted_texture and GL_WIN_swap_hint.
957 */
958 if (!gl_extension_supported(extensions, "GL_ARB_multitexture"))
959 {
960 skip("skipping test because lack of GL_ARB_multitexture support\n");
961 return;
962 }
963
964 func = wglGetProcAddress("glActiveTextureARB");
965 ok(func != NULL, "Unable to lookup glActiveTextureARB, last error %#x\n", GetLastError());
966
967 /* Temporarily disable the context, so we can see that we can't retrieve functions now. */
968 wglMakeCurrent(hdc, NULL);
969 func = wglGetProcAddress("glActiveTextureARB");
970 ok(func == NULL, "Function lookup without a context passed, expected a failure; last error %#x\n", GetLastError());
971 wglMakeCurrent(hdc, ctx);
972 }
973
test_make_current_read(HDC hdc)974 static void test_make_current_read(HDC hdc)
975 {
976 int res;
977 HDC hread;
978 HGLRC hglrc = wglCreateContext(hdc);
979
980 if(!hglrc)
981 {
982 skip("wglCreateContext failed!\n");
983 return;
984 }
985
986 res = wglMakeCurrent(hdc, hglrc);
987 if(!res)
988 {
989 skip("wglMakeCurrent failed!\n");
990 return;
991 }
992
993 /* Test what wglGetCurrentReadDCARB does for wglMakeCurrent as the spec doesn't mention it */
994 hread = pwglGetCurrentReadDCARB();
995 trace("hread %p, hdc %p\n", hread, hdc);
996 ok(hread == hdc, "wglGetCurrentReadDCARB failed for standard wglMakeCurrent\n");
997
998 pwglMakeContextCurrentARB(hdc, hdc, hglrc);
999 hread = pwglGetCurrentReadDCARB();
1000 ok(hread == hdc, "wglGetCurrentReadDCARB failed for wglMakeContextCurrent\n");
1001 }
1002
test_dc(HWND hwnd,HDC hdc)1003 static void test_dc(HWND hwnd, HDC hdc)
1004 {
1005 int pf1, pf2;
1006 HDC hdc2;
1007
1008 /* Get another DC and make sure it has the same pixel format */
1009 hdc2 = GetDC(hwnd);
1010 if(hdc != hdc2)
1011 {
1012 pf1 = GetPixelFormat(hdc);
1013 pf2 = GetPixelFormat(hdc2);
1014 ok(pf1 == pf2, "Second DC does not have the same format (%d != %d)\n", pf1, pf2);
1015 }
1016 else
1017 skip("Could not get a different DC for the window\n");
1018
1019 if(hdc2)
1020 {
1021 ReleaseDC(hwnd, hdc2);
1022 hdc2 = NULL;
1023 }
1024 }
1025
1026 /* Nvidia converts win32 error codes to (0xc007 << 16) | win32_error_code */
1027 #define NVIDIA_HRESULT_FROM_WIN32(x) (HRESULT_FROM_WIN32(x) | 0x40000000)
test_opengl3(HDC hdc)1028 static void test_opengl3(HDC hdc)
1029 {
1030 /* Try to create a context compatible with OpenGL 1.x; 1.0-2.1 is allowed */
1031 {
1032 HGLRC gl3Ctx;
1033 int attribs[] = {WGL_CONTEXT_MAJOR_VERSION_ARB, 1, 0};
1034
1035 gl3Ctx = pwglCreateContextAttribsARB(hdc, 0, attribs);
1036 ok(gl3Ctx != 0, "pwglCreateContextAttribsARB for a 1.x context failed!\n");
1037 wglDeleteContext(gl3Ctx);
1038 }
1039
1040 /* Try to pass an invalid HDC */
1041 {
1042 HGLRC gl3Ctx;
1043 DWORD error;
1044 SetLastError(0xdeadbeef);
1045 gl3Ctx = pwglCreateContextAttribsARB((HDC)0xdeadbeef, 0, 0);
1046 ok(gl3Ctx == 0, "pwglCreateContextAttribsARB using an invalid HDC passed\n");
1047 error = GetLastError();
1048 ok(error == ERROR_DC_NOT_FOUND || error == ERROR_INVALID_HANDLE ||
1049 broken(error == ERROR_DS_GENERIC_ERROR) ||
1050 broken(error == NVIDIA_HRESULT_FROM_WIN32(ERROR_INVALID_DATA)), /* Nvidia Vista + Win7 */
1051 "Expected ERROR_DC_NOT_FOUND, got error=%x\n", error);
1052 wglDeleteContext(gl3Ctx);
1053 }
1054
1055 /* Try to pass an invalid shareList */
1056 {
1057 HGLRC gl3Ctx;
1058 DWORD error;
1059 SetLastError(0xdeadbeef);
1060 gl3Ctx = pwglCreateContextAttribsARB(hdc, (HGLRC)0xdeadbeef, 0);
1061 ok(gl3Ctx == 0, "pwglCreateContextAttribsARB using an invalid shareList passed\n");
1062 error = GetLastError();
1063 /* The Nvidia implementation seems to return hresults instead of win32 error codes */
1064 ok(error == ERROR_INVALID_OPERATION || error == ERROR_INVALID_DATA ||
1065 error == NVIDIA_HRESULT_FROM_WIN32(ERROR_INVALID_OPERATION), "Expected ERROR_INVALID_OPERATION, got error=%x\n", error);
1066 wglDeleteContext(gl3Ctx);
1067 }
1068
1069 /* Try to create an OpenGL 3.0 context */
1070 {
1071 int attribs[] = {WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 0, 0};
1072 HGLRC gl3Ctx = pwglCreateContextAttribsARB(hdc, 0, attribs);
1073
1074 if(gl3Ctx == NULL)
1075 {
1076 skip("Skipping the rest of the WGL_ARB_create_context test due to lack of OpenGL 3.0\n");
1077 return;
1078 }
1079
1080 wglDeleteContext(gl3Ctx);
1081 }
1082
1083 /* 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 */
1084 {
1085 HGLRC glCtx = wglCreateContext(hdc);
1086
1087 int attribs[] = {WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 0, 0};
1088 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};
1089
1090 HGLRC gl3Ctx = pwglCreateContextAttribsARB(hdc, glCtx, attribs);
1091 ok(gl3Ctx != NULL, "Sharing of a display list between OpenGL 3.0 and OpenGL 1.x/2.x failed!\n");
1092 if(gl3Ctx)
1093 wglDeleteContext(gl3Ctx);
1094
1095 gl3Ctx = pwglCreateContextAttribsARB(hdc, glCtx, attribs_future);
1096 ok(gl3Ctx != NULL, "Sharing of a display list between a forward compatible OpenGL 3.0 context and OpenGL 1.x/2.x failed!\n");
1097 if(gl3Ctx)
1098 wglDeleteContext(gl3Ctx);
1099
1100 if(glCtx)
1101 wglDeleteContext(glCtx);
1102 }
1103
1104 /* Try to create an OpenGL 3.0 context and test windowless rendering */
1105 {
1106 HGLRC gl3Ctx;
1107 int attribs[] = {WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 0, 0};
1108 BOOL res;
1109
1110 gl3Ctx = pwglCreateContextAttribsARB(hdc, 0, attribs);
1111 ok(gl3Ctx != 0, "pwglCreateContextAttribsARB for a 3.0 context failed!\n");
1112
1113 /* OpenGL 3.0 allows offscreen rendering WITHOUT a drawable
1114 * Neither AMD or Nvidia support it at this point. The WGL_ARB_create_context specs also say that
1115 * it is hard because drivers use the HDC to enter the display driver and it sounds like they don't
1116 * expect drivers to ever offer it.
1117 */
1118 res = wglMakeCurrent(0, gl3Ctx);
1119 ok(res == FALSE, "Wow, OpenGL 3.0 windowless rendering passed while it was expected not to!\n");
1120 if(res)
1121 wglMakeCurrent(0, 0);
1122
1123 if(gl3Ctx)
1124 wglDeleteContext(gl3Ctx);
1125 }
1126 }
1127
test_minimized(void)1128 static void test_minimized(void)
1129 {
1130 PIXELFORMATDESCRIPTOR pf_desc =
1131 {
1132 sizeof(PIXELFORMATDESCRIPTOR),
1133 1, /* version */
1134 PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
1135 PFD_TYPE_RGBA,
1136 24, /* 24-bit color depth */
1137 0, 0, 0, 0, 0, 0, /* color bits */
1138 0, /* alpha buffer */
1139 0, /* shift bit */
1140 0, /* accumulation buffer */
1141 0, 0, 0, 0, /* accum bits */
1142 32, /* z-buffer */
1143 0, /* stencil buffer */
1144 0, /* auxiliary buffer */
1145 PFD_MAIN_PLANE, /* main layer */
1146 0, /* reserved */
1147 0, 0, 0 /* layer masks */
1148 };
1149 int pixel_format;
1150 HWND window;
1151 LONG style;
1152 HGLRC ctx;
1153 BOOL ret;
1154 HDC dc;
1155
1156 window = CreateWindowA("static", "opengl32_test",
1157 WS_POPUP | WS_MINIMIZE, 0, 0, 640, 480, 0, 0, 0, 0);
1158 ok(!!window, "Failed to create window, last error %#x.\n", GetLastError());
1159
1160 dc = GetDC(window);
1161 ok(!!dc, "Failed to get DC.\n");
1162
1163 pixel_format = ChoosePixelFormat(dc, &pf_desc);
1164 if (!pixel_format)
1165 {
1166 win_skip("Failed to find pixel format.\n");
1167 ReleaseDC(window, dc);
1168 DestroyWindow(window);
1169 return;
1170 }
1171
1172 ret = SetPixelFormat(dc, pixel_format, &pf_desc);
1173 ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError());
1174
1175 style = GetWindowLongA(window, GWL_STYLE);
1176 ok(style & WS_MINIMIZE, "Window should be minimized, got style %#x.\n", style);
1177
1178 ctx = wglCreateContext(dc);
1179 ok(!!ctx, "Failed to create GL context, last error %#x.\n", GetLastError());
1180
1181 ret = wglMakeCurrent(dc, ctx);
1182 ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1183
1184 style = GetWindowLongA(window, GWL_STYLE);
1185 ok(style & WS_MINIMIZE, "window should be minimized, got style %#x.\n", style);
1186
1187 ret = wglMakeCurrent(NULL, NULL);
1188 ok(ret, "Failed to clear current context, last error %#x.\n", GetLastError());
1189
1190 ret = wglDeleteContext(ctx);
1191 ok(ret, "Failed to delete GL context, last error %#x.\n", GetLastError());
1192
1193 ReleaseDC(window, dc);
1194 DestroyWindow(window);
1195 }
1196
test_window_dc(void)1197 static void test_window_dc(void)
1198 {
1199 PIXELFORMATDESCRIPTOR pf_desc =
1200 {
1201 sizeof(PIXELFORMATDESCRIPTOR),
1202 1, /* version */
1203 PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
1204 PFD_TYPE_RGBA,
1205 24, /* 24-bit color depth */
1206 0, 0, 0, 0, 0, 0, /* color bits */
1207 0, /* alpha buffer */
1208 0, /* shift bit */
1209 0, /* accumulation buffer */
1210 0, 0, 0, 0, /* accum bits */
1211 32, /* z-buffer */
1212 0, /* stencil buffer */
1213 0, /* auxiliary buffer */
1214 PFD_MAIN_PLANE, /* main layer */
1215 0, /* reserved */
1216 0, 0, 0 /* layer masks */
1217 };
1218 int pixel_format;
1219 HWND window;
1220 RECT vp, r;
1221 HGLRC ctx;
1222 BOOL ret;
1223 HDC dc;
1224
1225 window = CreateWindowA("static", "opengl32_test",
1226 WS_OVERLAPPEDWINDOW, 0, 0, 640, 480, 0, 0, 0, 0);
1227 ok(!!window, "Failed to create window, last error %#x.\n", GetLastError());
1228
1229 ShowWindow(window, SW_SHOW);
1230
1231 dc = GetWindowDC(window);
1232 ok(!!dc, "Failed to get DC.\n");
1233
1234 pixel_format = ChoosePixelFormat(dc, &pf_desc);
1235 if (!pixel_format)
1236 {
1237 win_skip("Failed to find pixel format.\n");
1238 ReleaseDC(window, dc);
1239 DestroyWindow(window);
1240 return;
1241 }
1242
1243 ret = SetPixelFormat(dc, pixel_format, &pf_desc);
1244 ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError());
1245
1246 ctx = wglCreateContext(dc);
1247 ok(!!ctx, "Failed to create GL context, last error %#x.\n", GetLastError());
1248
1249 ret = wglMakeCurrent(dc, ctx);
1250 ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1251
1252 GetClientRect(window, &r);
1253 glGetIntegerv(GL_VIEWPORT, (GLint *)&vp);
1254 ok(EqualRect(&r, &vp), "Viewport not equal to client rect.\n");
1255
1256 ret = wglMakeCurrent(NULL, NULL);
1257 ok(ret, "Failed to clear current context, last error %#x.\n", GetLastError());
1258
1259 ret = wglDeleteContext(ctx);
1260 ok(ret, "Failed to delete GL context, last error %#x.\n", GetLastError());
1261
1262 ReleaseDC(window, dc);
1263 DestroyWindow(window);
1264 }
1265
test_message_window(void)1266 static void test_message_window(void)
1267 {
1268 PIXELFORMATDESCRIPTOR pf_desc =
1269 {
1270 sizeof(PIXELFORMATDESCRIPTOR),
1271 1, /* version */
1272 PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
1273 PFD_TYPE_RGBA,
1274 24, /* 24-bit color depth */
1275 0, 0, 0, 0, 0, 0, /* color bits */
1276 0, /* alpha buffer */
1277 0, /* shift bit */
1278 0, /* accumulation buffer */
1279 0, 0, 0, 0, /* accum bits */
1280 32, /* z-buffer */
1281 0, /* stencil buffer */
1282 0, /* auxiliary buffer */
1283 PFD_MAIN_PLANE, /* main layer */
1284 0, /* reserved */
1285 0, 0, 0 /* layer masks */
1286 };
1287 int pixel_format;
1288 HWND window;
1289 RECT vp, r;
1290 HGLRC ctx;
1291 BOOL ret;
1292 HDC dc;
1293 GLenum glerr;
1294
1295 window = CreateWindowA("static", "opengl32_test",
1296 WS_OVERLAPPEDWINDOW, 0, 0, 100, 100, HWND_MESSAGE, 0, 0, 0);
1297 if (!window)
1298 {
1299 win_skip( "HWND_MESSAGE not supported\n" );
1300 return;
1301 }
1302 dc = GetDC(window);
1303 ok(!!dc, "Failed to get DC.\n");
1304
1305 pixel_format = ChoosePixelFormat(dc, &pf_desc);
1306 if (!pixel_format)
1307 {
1308 win_skip("Failed to find pixel format.\n");
1309 ReleaseDC(window, dc);
1310 DestroyWindow(window);
1311 return;
1312 }
1313
1314 ret = SetPixelFormat(dc, pixel_format, &pf_desc);
1315 ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError());
1316
1317 ctx = wglCreateContext(dc);
1318 ok(!!ctx, "Failed to create GL context, last error %#x.\n", GetLastError());
1319
1320 ret = wglMakeCurrent(dc, ctx);
1321 ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1322
1323 GetClientRect(window, &r);
1324 glGetIntegerv(GL_VIEWPORT, (GLint *)&vp);
1325 ok(EqualRect(&r, &vp), "Viewport not equal to client rect.\n");
1326
1327 glClear(GL_COLOR_BUFFER_BIT);
1328 glFinish();
1329 glerr = glGetError();
1330 ok(glerr == GL_NO_ERROR, "Failed glClear, error %#x.\n", glerr);
1331 ret = SwapBuffers(dc);
1332 ok(ret, "Failed SwapBuffers, error %#x.\n", GetLastError());
1333
1334 ret = wglMakeCurrent(NULL, NULL);
1335 ok(ret, "Failed to clear current context, last error %#x.\n", GetLastError());
1336
1337 ret = wglDeleteContext(ctx);
1338 ok(ret, "Failed to delete GL context, last error %#x.\n", GetLastError());
1339
1340 ReleaseDC(window, dc);
1341 DestroyWindow(window);
1342 }
1343
test_destroy(HDC oldhdc)1344 static void test_destroy(HDC oldhdc)
1345 {
1346 PIXELFORMATDESCRIPTOR pf_desc =
1347 {
1348 sizeof(PIXELFORMATDESCRIPTOR),
1349 1, /* version */
1350 PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
1351 PFD_TYPE_RGBA,
1352 24, /* 24-bit color depth */
1353 0, 0, 0, 0, 0, 0, /* color bits */
1354 0, /* alpha buffer */
1355 0, /* shift bit */
1356 0, /* accumulation buffer */
1357 0, 0, 0, 0, /* accum bits */
1358 32, /* z-buffer */
1359 0, /* stencil buffer */
1360 0, /* auxiliary buffer */
1361 PFD_MAIN_PLANE, /* main layer */
1362 0, /* reserved */
1363 0, 0, 0 /* layer masks */
1364 };
1365 int pixel_format;
1366 HWND window;
1367 HGLRC ctx;
1368 BOOL ret;
1369 HDC dc;
1370 GLenum glerr;
1371 DWORD err;
1372 HGLRC oldctx = wglGetCurrentContext();
1373
1374 ok(!!oldctx, "Expected to find a valid current context.\n");
1375
1376 window = CreateWindowA("static", "opengl32_test",
1377 WS_POPUP, 0, 0, 640, 480, 0, 0, 0, 0);
1378 ok(!!window, "Failed to create window, last error %#x.\n", GetLastError());
1379
1380 dc = GetDC(window);
1381 ok(!!dc, "Failed to get DC.\n");
1382
1383 pixel_format = ChoosePixelFormat(dc, &pf_desc);
1384 if (!pixel_format)
1385 {
1386 win_skip("Failed to find pixel format.\n");
1387 ReleaseDC(window, dc);
1388 DestroyWindow(window);
1389 return;
1390 }
1391
1392 ret = SetPixelFormat(dc, pixel_format, &pf_desc);
1393 ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError());
1394
1395 ctx = wglCreateContext(dc);
1396 ok(!!ctx, "Failed to create GL context, last error %#x.\n", GetLastError());
1397
1398 ret = wglMakeCurrent(dc, ctx);
1399 ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1400
1401 glClear(GL_COLOR_BUFFER_BIT);
1402 glFinish();
1403 glerr = glGetError();
1404 ok(glerr == GL_NO_ERROR, "Failed glClear, error %#x.\n", glerr);
1405 ret = SwapBuffers(dc);
1406 ok(ret, "Failed SwapBuffers, error %#x.\n", GetLastError());
1407
1408 ret = DestroyWindow(window);
1409 ok(ret, "Failed to destroy window, last error %#x.\n", GetLastError());
1410
1411 ok(wglGetCurrentContext() == ctx, "Wrong current context.\n");
1412
1413 SetLastError(0xdeadbeef);
1414 ret = wglMakeCurrent(dc, ctx);
1415 err = GetLastError();
1416 ok(!ret && err == ERROR_INVALID_HANDLE,
1417 "Unexpected behavior when making context current, ret %d, last error %#x.\n", ret, err);
1418 SetLastError(0xdeadbeef);
1419 ret = SwapBuffers(dc);
1420 err = GetLastError();
1421 ok(!ret && err == ERROR_INVALID_HANDLE, "Unexpected behavior with SwapBuffer, last error %#x.\n", err);
1422
1423 ok(wglGetCurrentContext() == ctx, "Wrong current context.\n");
1424
1425 glClear(GL_COLOR_BUFFER_BIT);
1426 glFinish();
1427 glerr = glGetError();
1428 ok(glerr == GL_NO_ERROR, "Failed glClear, error %#x.\n", glerr);
1429 SetLastError(0xdeadbeef);
1430 ret = SwapBuffers(dc);
1431 err = GetLastError();
1432 ok(!ret && err == ERROR_INVALID_HANDLE, "Unexpected behavior with SwapBuffer, last error %#x.\n", err);
1433
1434 ret = wglMakeCurrent(NULL, NULL);
1435 ok(ret, "Failed to clear current context, last error %#x.\n", GetLastError());
1436
1437 glClear(GL_COLOR_BUFFER_BIT);
1438 glFinish();
1439 glerr = glGetError();
1440 ok(glerr == GL_INVALID_OPERATION, "Failed glClear, error %#x.\n", glerr);
1441 SetLastError(0xdeadbeef);
1442 ret = SwapBuffers(dc);
1443 err = GetLastError();
1444 ok(!ret && err == ERROR_INVALID_HANDLE, "Unexpected behavior with SwapBuffer, last error %#x.\n", err);
1445
1446 SetLastError(0xdeadbeef);
1447 ret = wglMakeCurrent(dc, ctx);
1448 err = GetLastError();
1449 ok(!ret && err == ERROR_INVALID_HANDLE,
1450 "Unexpected behavior when making context current, ret %d, last error %#x.\n", ret, err);
1451
1452 ok(wglGetCurrentContext() == NULL, "Wrong current context.\n");
1453
1454 ret = wglMakeCurrent(oldhdc, oldctx);
1455 ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1456 ok(wglGetCurrentContext() == oldctx, "Wrong current context.\n");
1457
1458 SetLastError(0xdeadbeef);
1459 ret = wglMakeCurrent(dc, ctx);
1460 err = GetLastError();
1461 ok(!ret && err == ERROR_INVALID_HANDLE,
1462 "Unexpected behavior when making context current, ret %d, last error %#x.\n", ret, err);
1463
1464 ok(wglGetCurrentContext() == oldctx, "Wrong current context.\n");
1465
1466 ret = wglDeleteContext(ctx);
1467 ok(ret, "Failed to delete GL context, last error %#x.\n", GetLastError());
1468
1469 ReleaseDC(window, dc);
1470
1471 ret = wglMakeCurrent(oldhdc, oldctx);
1472 ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1473 }
1474
test_destroy_read(HDC oldhdc)1475 static void test_destroy_read(HDC oldhdc)
1476 {
1477 PIXELFORMATDESCRIPTOR pf_desc =
1478 {
1479 sizeof(PIXELFORMATDESCRIPTOR),
1480 1, /* version */
1481 PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
1482 PFD_TYPE_RGBA,
1483 24, /* 24-bit color depth */
1484 0, 0, 0, 0, 0, 0, /* color bits */
1485 0, /* alpha buffer */
1486 0, /* shift bit */
1487 0, /* accumulation buffer */
1488 0, 0, 0, 0, /* accum bits */
1489 32, /* z-buffer */
1490 0, /* stencil buffer */
1491 0, /* auxiliary buffer */
1492 PFD_MAIN_PLANE, /* main layer */
1493 0, /* reserved */
1494 0, 0, 0 /* layer masks */
1495 };
1496 int pixel_format;
1497 HWND draw_window, read_window;
1498 HGLRC ctx;
1499 BOOL ret;
1500 HDC read_dc, draw_dc;
1501 GLenum glerr;
1502 DWORD err;
1503 HGLRC oldctx = wglGetCurrentContext();
1504
1505 ok(!!oldctx, "Expected to find a valid current context\n");
1506
1507 draw_window = CreateWindowA("static", "opengl32_test",
1508 WS_POPUP, 0, 0, 640, 480, 0, 0, 0, 0);
1509 ok(!!draw_window, "Failed to create window, last error %#x.\n", GetLastError());
1510
1511 draw_dc = GetDC(draw_window);
1512 ok(!!draw_dc, "Failed to get DC.\n");
1513
1514 pixel_format = ChoosePixelFormat(draw_dc, &pf_desc);
1515 if (!pixel_format)
1516 {
1517 win_skip("Failed to find pixel format.\n");
1518 ReleaseDC(draw_window, draw_dc);
1519 DestroyWindow(draw_window);
1520 return;
1521 }
1522
1523 ret = SetPixelFormat(draw_dc, pixel_format, &pf_desc);
1524 ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError());
1525
1526 read_window = CreateWindowA("static", "opengl32_test",
1527 WS_POPUP, 0, 0, 640, 480, 0, 0, 0, 0);
1528 ok(!!read_window, "Failed to create window, last error %#x.\n", GetLastError());
1529
1530 read_dc = GetDC(read_window);
1531 ok(!!draw_dc, "Failed to get DC.\n");
1532
1533 pixel_format = ChoosePixelFormat(read_dc, &pf_desc);
1534 if (!pixel_format)
1535 {
1536 win_skip("Failed to find pixel format.\n");
1537 ReleaseDC(read_window, read_dc);
1538 DestroyWindow(read_window);
1539 ReleaseDC(draw_window, draw_dc);
1540 DestroyWindow(draw_window);
1541 return;
1542 }
1543
1544 ret = SetPixelFormat(read_dc, pixel_format, &pf_desc);
1545 ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError());
1546
1547 ctx = wglCreateContext(draw_dc);
1548 ok(!!ctx, "Failed to create GL context, last error %#x.\n", GetLastError());
1549
1550 ret = pwglMakeContextCurrentARB(draw_dc, read_dc, ctx);
1551 ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1552
1553 glCopyPixels(0, 0, 640, 480, GL_COLOR);
1554 glFinish();
1555 glerr = glGetError();
1556 ok(glerr == GL_NO_ERROR, "Failed glCopyPixel, error %#x.\n", glerr);
1557 ret = SwapBuffers(draw_dc);
1558 ok(ret, "Failed SwapBuffers, error %#x.\n", GetLastError());
1559
1560 ret = DestroyWindow(read_window);
1561 ok(ret, "Failed to destroy window, last error %#x.\n", GetLastError());
1562
1563 ok(wglGetCurrentContext() == ctx, "Wrong current context.\n");
1564
1565 if (0) /* Crashes on AMD on Windows */
1566 {
1567 glCopyPixels(0, 0, 640, 480, GL_COLOR);
1568 glFinish();
1569 glerr = glGetError();
1570 ok(glerr == GL_NO_ERROR, "Failed glCopyPixel, error %#x.\n", glerr);
1571 }
1572
1573 glClear(GL_COLOR_BUFFER_BIT);
1574 glFinish();
1575 glerr = glGetError();
1576 ok(glerr == GL_NO_ERROR, "Failed glClear, error %#x.\n", glerr);
1577 ret = SwapBuffers(draw_dc);
1578 ok(ret, "Failed SwapBuffers, error %#x.\n", GetLastError());
1579
1580 ret = wglMakeCurrent(NULL, NULL);
1581 ok(ret, "Failed to clear current context, last error %#x.\n", GetLastError());
1582
1583 if (0) /* This crashes with Nvidia drivers on Windows. */
1584 {
1585 SetLastError(0xdeadbeef);
1586 ret = pwglMakeContextCurrentARB(draw_dc, read_dc, ctx);
1587 err = GetLastError();
1588 ok(!ret && err == ERROR_INVALID_HANDLE,
1589 "Unexpected behavior when making context current, ret %d, last error %#x.\n", ret, err);
1590 }
1591
1592 ret = DestroyWindow(draw_window);
1593 ok(ret, "Failed to destroy window, last error %#x.\n", GetLastError());
1594
1595 glClear(GL_COLOR_BUFFER_BIT);
1596 glFinish();
1597 glerr = glGetError();
1598 ok(glerr == GL_INVALID_OPERATION, "Failed glClear, error %#x.\n", glerr);
1599 SetLastError(0xdeadbeef);
1600 ret = SwapBuffers(draw_dc);
1601 err = GetLastError();
1602 ok(!ret && err == ERROR_INVALID_HANDLE, "Unexpected behavior with SwapBuffer, last error %#x.\n", err);
1603
1604 SetLastError(0xdeadbeef);
1605 ret = pwglMakeContextCurrentARB(draw_dc, read_dc, ctx);
1606 err = GetLastError();
1607 ok(!ret && (err == ERROR_INVALID_HANDLE || err == 0xc0070006),
1608 "Unexpected behavior when making context current, ret %d, last error %#x.\n", ret, err);
1609
1610 ok(wglGetCurrentContext() == NULL, "Wrong current context.\n");
1611
1612 wglMakeCurrent(NULL, NULL);
1613
1614 wglMakeCurrent(oldhdc, oldctx);
1615 ok(wglGetCurrentContext() == oldctx, "Wrong current context.\n");
1616
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, last error %#x.\n", err);
1622
1623 ok(wglGetCurrentContext() == oldctx, "Wrong current context.\n");
1624
1625 ret = wglDeleteContext(ctx);
1626 ok(ret, "Failed to delete GL context, last error %#x.\n", GetLastError());
1627
1628 ReleaseDC(read_window, read_dc);
1629 ReleaseDC(draw_window, draw_dc);
1630
1631 wglMakeCurrent(oldhdc, oldctx);
1632 }
1633
test_swap_control(HDC oldhdc)1634 static void test_swap_control(HDC oldhdc)
1635 {
1636 PIXELFORMATDESCRIPTOR pf_desc =
1637 {
1638 sizeof(PIXELFORMATDESCRIPTOR),
1639 1, /* version */
1640 PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
1641 PFD_TYPE_RGBA,
1642 24, /* 24-bit color depth */
1643 0, 0, 0, 0, 0, 0, /* color bits */
1644 0, /* alpha buffer */
1645 0, /* shift bit */
1646 0, /* accumulation buffer */
1647 0, 0, 0, 0, /* accum bits */
1648 32, /* z-buffer */
1649 0, /* stencil buffer */
1650 0, /* auxiliary buffer */
1651 PFD_MAIN_PLANE, /* main layer */
1652 0, /* reserved */
1653 0, 0, 0 /* layer masks */
1654 };
1655 int pixel_format;
1656 HWND window1, window2, old_parent;
1657 HGLRC ctx1, ctx2, oldctx;
1658 BOOL ret;
1659 HDC dc1, dc2;
1660 int interval;
1661
1662 oldctx = wglGetCurrentContext();
1663 ok(!!oldctx, "Expected to find a valid current context.\n");
1664
1665 window1 = CreateWindowA("static", "opengl32_test",
1666 WS_POPUP, 0, 0, 640, 480, 0, 0, 0, 0);
1667 ok(!!window1, "Failed to create window1, last error %#x.\n", GetLastError());
1668
1669 dc1 = GetDC(window1);
1670 ok(!!dc1, "Failed to get DC.\n");
1671
1672 pixel_format = ChoosePixelFormat(dc1, &pf_desc);
1673 if (!pixel_format)
1674 {
1675 win_skip("Failed to find pixel format.\n");
1676 ReleaseDC(window1, dc1);
1677 DestroyWindow(window1);
1678 return;
1679 }
1680
1681 ret = SetPixelFormat(dc1, pixel_format, &pf_desc);
1682 ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError());
1683
1684 ctx1 = wglCreateContext(dc1);
1685 ok(!!ctx1, "Failed to create GL context, last error %#x.\n", GetLastError());
1686
1687 ret = wglMakeCurrent(dc1, ctx1);
1688 ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1689
1690 interval = pwglGetSwapIntervalEXT();
1691 ok(interval == 1, "Expected default swap interval 1, got %d\n", interval);
1692
1693 ret = pwglSwapIntervalEXT(0);
1694 ok(ret, "Failed to set swap interval to 0, last error %#x.\n", GetLastError());
1695
1696 interval = pwglGetSwapIntervalEXT();
1697 ok(interval == 0, "Expected swap interval 0, got %d\n", interval);
1698
1699 /* Check what interval we get on a second context on the same drawable.*/
1700 ctx2 = wglCreateContext(dc1);
1701 ok(!!ctx2, "Failed to create GL context, last error %#x.\n", GetLastError());
1702
1703 ret = wglMakeCurrent(dc1, ctx2);
1704 ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1705
1706 interval = pwglGetSwapIntervalEXT();
1707 ok(interval == 0, "Expected swap interval 0, got %d\n", interval);
1708
1709 /* A second window is created to see whether its swap interval was affected
1710 * by previous calls.
1711 */
1712 window2 = CreateWindowA("static", "opengl32_test",
1713 WS_POPUP, 0, 0, 640, 480, 0, 0, 0, 0);
1714 ok(!!window2, "Failed to create window2, last error %#x.\n", GetLastError());
1715
1716 dc2 = GetDC(window2);
1717 ok(!!dc2, "Failed to get DC.\n");
1718
1719 ret = SetPixelFormat(dc2, pixel_format, &pf_desc);
1720 ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError());
1721
1722 ret = wglMakeCurrent(dc2, ctx1);
1723 ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1724
1725 /* Since the second window lacks the swap interval, this proves that the interval
1726 * is not global or shared among contexts.
1727 */
1728 interval = pwglGetSwapIntervalEXT();
1729 ok(interval == 1, "Expected default swap interval 1, got %d\n", interval);
1730
1731 /* Test if setting the parent of a window resets the swap interval. */
1732 ret = wglMakeCurrent(dc1, ctx1);
1733 ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1734
1735 old_parent = SetParent(window1, window2);
1736 ok(!!old_parent, "Failed to make window1 a child of window2, last error %#x.\n", GetLastError());
1737
1738 interval = pwglGetSwapIntervalEXT();
1739 ok(interval == 0, "Expected swap interval 0, got %d\n", interval);
1740
1741 ret = wglDeleteContext(ctx1);
1742 ok(ret, "Failed to delete GL context, last error %#x.\n", GetLastError());
1743 ret = wglDeleteContext(ctx2);
1744 ok(ret, "Failed to delete GL context, last error %#x.\n", GetLastError());
1745
1746 ReleaseDC(window1, dc1);
1747 DestroyWindow(window1);
1748 ReleaseDC(window2, dc2);
1749 DestroyWindow(window2);
1750
1751 wglMakeCurrent(oldhdc, oldctx);
1752 }
1753
START_TEST(opengl)1754 START_TEST(opengl)
1755 {
1756 HWND hwnd;
1757 PIXELFORMATDESCRIPTOR pfd = {
1758 sizeof(PIXELFORMATDESCRIPTOR),
1759 1, /* version */
1760 PFD_DRAW_TO_WINDOW |
1761 PFD_SUPPORT_OPENGL |
1762 PFD_DOUBLEBUFFER,
1763 PFD_TYPE_RGBA,
1764 24, /* 24-bit color depth */
1765 0, 0, 0, 0, 0, 0, /* color bits */
1766 0, /* alpha buffer */
1767 0, /* shift bit */
1768 0, /* accumulation buffer */
1769 0, 0, 0, 0, /* accum bits */
1770 32, /* z-buffer */
1771 0, /* stencil buffer */
1772 0, /* auxiliary buffer */
1773 PFD_MAIN_PLANE, /* main layer */
1774 0, /* reserved */
1775 0, 0, 0 /* layer masks */
1776 };
1777
1778 hwnd = CreateWindowA("static", "Title", WS_OVERLAPPEDWINDOW, 10, 10, 200, 200, NULL, NULL,
1779 NULL, NULL);
1780 ok(hwnd != NULL, "err: %d\n", GetLastError());
1781 if (hwnd)
1782 {
1783 HDC hdc;
1784 int iPixelFormat, res;
1785 HGLRC hglrc;
1786 DWORD error;
1787 ShowWindow(hwnd, SW_SHOW);
1788
1789 hdc = GetDC(hwnd);
1790
1791 iPixelFormat = ChoosePixelFormat(hdc, &pfd);
1792 if(iPixelFormat == 0)
1793 {
1794 /* This should never happen as ChoosePixelFormat always returns a closest match, but currently this fails in Wine if we don't have glX */
1795 win_skip("Unable to find pixel format.\n");
1796 goto cleanup;
1797 }
1798
1799 /* We shouldn't be able to create a context from a hdc which doesn't have a pixel format set */
1800 hglrc = wglCreateContext(hdc);
1801 ok(hglrc == NULL, "wglCreateContext should fail when no pixel format has been set, but it passed\n");
1802 error = GetLastError();
1803 ok(error == ERROR_INVALID_PIXEL_FORMAT, "expected ERROR_INVALID_PIXEL_FORMAT for wglCreateContext without a pixelformat set, but received %#x\n", error);
1804
1805 res = SetPixelFormat(hdc, iPixelFormat, &pfd);
1806 ok(res, "SetPixelformat failed: %x\n", GetLastError());
1807
1808 test_bitmap_rendering( TRUE );
1809 test_bitmap_rendering( FALSE );
1810 test_minimized();
1811 test_window_dc();
1812 test_message_window();
1813 test_dc(hwnd, hdc);
1814
1815 ok(!glGetString(GL_RENDERER) && !glGetString(GL_VERSION) && !glGetString(GL_VENDOR),
1816 "Expected NULL string when no active context is set\n");
1817 hglrc = wglCreateContext(hdc);
1818 res = wglMakeCurrent(hdc, hglrc);
1819 ok(res, "wglMakeCurrent failed!\n");
1820 if(res)
1821 {
1822 trace("OpenGL renderer: %s\n", glGetString(GL_RENDERER));
1823 trace("OpenGL driver version: %s\n", glGetString(GL_VERSION));
1824 trace("OpenGL vendor: %s\n", glGetString(GL_VENDOR));
1825 }
1826 else
1827 {
1828 skip("Skipping OpenGL tests without a current context\n");
1829 return;
1830 }
1831
1832 /* Initialisation of WGL functions depends on an implicit WGL context. For this reason we can't load them before making
1833 * any WGL call :( On Wine this would work but not on real Windows because there can be different implementations (software, ICD, MCD).
1834 */
1835 init_functions();
1836 test_getprocaddress(hdc);
1837 test_deletecontext(hwnd, hdc);
1838 test_makecurrent(hdc);
1839
1840 /* The lack of wglGetExtensionsStringARB in general means broken software rendering or the lack of decent OpenGL support, skip tests in such cases */
1841 if (!pwglGetExtensionsStringARB)
1842 {
1843 win_skip("wglGetExtensionsStringARB is not available\n");
1844 return;
1845 }
1846
1847 test_choosepixelformat();
1848 test_debug_message_callback();
1849 test_setpixelformat(hdc);
1850 test_destroy(hdc);
1851 test_sharelists(hdc);
1852 test_colorbits(hdc);
1853 test_gdi_dbuf(hdc);
1854 test_acceleration(hdc);
1855
1856 wgl_extensions = pwglGetExtensionsStringARB(hdc);
1857 if(wgl_extensions == NULL) skip("Skipping opengl32 tests because this OpenGL implementation doesn't support WGL extensions!\n");
1858
1859 if(strstr(wgl_extensions, "WGL_ARB_create_context"))
1860 test_opengl3(hdc);
1861
1862 if(strstr(wgl_extensions, "WGL_ARB_make_current_read"))
1863 {
1864 test_make_current_read(hdc);
1865 test_destroy_read(hdc);
1866 }
1867 else
1868 skip("WGL_ARB_make_current_read not supported, skipping test\n");
1869
1870 if(strstr(wgl_extensions, "WGL_ARB_pbuffer"))
1871 test_pbuffers(hdc);
1872 else
1873 skip("WGL_ARB_pbuffer not supported, skipping pbuffer test\n");
1874
1875 if(strstr(wgl_extensions, "WGL_EXT_swap_control"))
1876 test_swap_control(hdc);
1877 else
1878 skip("WGL_EXT_swap_control not supported, skipping test\n");
1879
1880 cleanup:
1881 ReleaseDC(hwnd, hdc);
1882 DestroyWindow(hwnd);
1883 }
1884 }
1885