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 static const char* wgl_extensions = NULL; 52 53 static void init_functions(void) 54 { 55 #define GET_PROC(func) \ 56 p ## func = (void*)wglGetProcAddress(#func); \ 57 if(!p ## func) \ 58 trace("wglGetProcAddress(%s) failed\n", #func); 59 60 /* WGL_ARB_create_context */ 61 GET_PROC(wglCreateContextAttribsARB); 62 63 /* WGL_ARB_extensions_string */ 64 GET_PROC(wglGetExtensionsStringARB) 65 66 /* WGL_ARB_make_current_read */ 67 GET_PROC(wglMakeContextCurrentARB); 68 GET_PROC(wglGetCurrentReadDCARB); 69 70 /* WGL_ARB_pixel_format */ 71 GET_PROC(wglChoosePixelFormatARB) 72 GET_PROC(wglGetPixelFormatAttribivARB) 73 74 /* WGL_ARB_pbuffer */ 75 GET_PROC(wglCreatePbufferARB) 76 GET_PROC(wglGetPbufferDCARB) 77 GET_PROC(wglReleasePbufferDCARB) 78 79 /* WGL_EXT_swap_control */ 80 GET_PROC(wglSwapIntervalEXT) 81 GET_PROC(wglGetSwapIntervalEXT) 82 83 #undef GET_PROC 84 } 85 86 static BOOL gl_extension_supported(const char *extensions, const char *extension_string) 87 { 88 size_t ext_str_len = strlen(extension_string); 89 90 while (*extensions) 91 { 92 const char *start; 93 size_t len; 94 95 while (isspace(*extensions)) 96 ++extensions; 97 start = extensions; 98 while (!isspace(*extensions) && *extensions) 99 ++extensions; 100 101 len = extensions - start; 102 if (!len) 103 continue; 104 105 if (len == ext_str_len && !memcmp(start, extension_string, ext_str_len)) 106 { 107 return TRUE; 108 } 109 } 110 return FALSE; 111 } 112 113 static void test_pbuffers(HDC hdc) 114 { 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; 122 123 nOnscreenFormats = DescribePixelFormat(hdc, 0, 0, NULL); 124 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. 131 * 132 * The first thing we need are pixelformats with pbuffer capabilities. 133 */ 134 res = pwglChoosePixelFormatARB(hdc, iAttribList, NULL, MAX_FORMATS, iFormats, &nFormats); 135 if(res <= 0) 136 { 137 skip("No pbuffer compatible formats found while WGL_ARB_pbuffer is supported\n"); 138 return; 139 } 140 trace("nOnscreenFormats: %d\n", nOnscreenFormats); 141 trace("Total number of pbuffer capable pixelformats: %d\n", nFormats); 142 143 /* Try to select an onscreen pixelformat out of the list */ 144 for(i=0; i < nFormats; i++) 145 { 146 /* Check if the format is onscreen, if it is choose it */ 147 if(iFormats[i] <= nOnscreenFormats) 148 { 149 iPixelFormat = iFormats[i]; 150 trace("Selected iPixelFormat=%d\n", iPixelFormat); 151 break; 152 } 153 } 154 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. 160 * 161 * Below we check if the pixelformat is also supported onscreen. 162 */ 163 if(iPixelFormat != 0) 164 { 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"); 170 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); 177 178 pwglReleasePbufferDCARB(pbuffer, pbuffer_hdc); 179 } 180 else skip("Pbuffer test for onscreen pixelformat skipped as no onscreen format with pbuffer capabilities have been found\n"); 181 182 /* Search for a real offscreen format */ 183 for(i=0, iPixelFormat=0; i<nFormats; i++) 184 { 185 if(iFormats[i] > nOnscreenFormats) 186 { 187 iPixelFormat = iFormats[i]; 188 trace("Selected iPixelFormat: %d\n", iPixelFormat); 189 break; 190 } 191 } 192 193 if(iPixelFormat != 0) 194 { 195 HDC pbuffer_hdc; 196 HPBUFFERARB pbuffer = pwglCreatePbufferARB(hdc, iPixelFormat, 640 /* width */, 480 /* height */, NULL); 197 if(!pbuffer) 198 skip("Pbuffer creation failed!\n"); 199 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); 203 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); 208 } 209 else skip("Pbuffer test for offscreen pixelformat skipped as no offscreen-only format with pbuffer capabilities has been found\n"); 210 } 211 212 static int test_pfd(const PIXELFORMATDESCRIPTOR *pfd) 213 { 214 int pf; 215 HDC hdc; 216 HWND hwnd; 217 218 hwnd = CreateWindowA("static", "Title", WS_OVERLAPPEDWINDOW, 10, 10, 200, 200, NULL, NULL, 219 NULL, NULL); 220 if (!hwnd) 221 return 0; 222 223 hdc = GetDC( hwnd ); 224 pf = ChoosePixelFormat( hdc, pfd ); 225 ReleaseDC( hwnd, hdc ); 226 DestroyWindow( hwnd ); 227 228 return pf; 229 } 230 231 static void test_choosepixelformat(void) 232 { 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 */ 251 }; 252 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; 261 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; 272 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; 283 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; 294 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; 305 } 306 307 static void test_setpixelformat(HDC winhdc) 308 { 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 */ 333 }; 334 335 HDC hdc = GetDC(0); 336 ok(hdc != 0, "GetDC(0) failed!\n"); 337 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"); 341 342 /* SetPixelFormat on the main device context 'X root window' should fail, 343 * but some broken drivers allow it 344 */ 345 res = SetPixelFormat(hdc, pf, &pfd); 346 trace("SetPixelFormat on main device context %s\n", res ? "succeeded" : "failed"); 347 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++) 353 { 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"); 357 } 358 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) 363 { 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() ); 401 } 402 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) 407 { 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 ); 417 } 418 } 419 420 static void test_sharelists(HDC winhdc) 421 { 422 HGLRC hglrc1, hglrc2, hglrc3; 423 BOOL res; 424 425 hglrc1 = wglCreateContext(winhdc); 426 res = wglShareLists(0, 0); 427 ok(res == FALSE, "Sharing display lists for no contexts passed!\n"); 428 429 /* Test 1: Create a context and just share lists without doing anything special */ 430 hglrc2 = wglCreateContext(winhdc); 431 if(hglrc2) 432 { 433 res = wglShareLists(hglrc1, hglrc2); 434 ok(res, "Sharing of display lists failed\n"); 435 wglDeleteContext(hglrc2); 436 } 437 438 /* Test 2: Share display lists with a 'destination' context which has been made current */ 439 hglrc2 = wglCreateContext(winhdc); 440 if(hglrc2) 441 { 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); 448 } 449 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) 454 { 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); 458 } 459 460 /* Test 4: Share display lists with a 'source' context which has been made current */ 461 hglrc2 = wglCreateContext(winhdc); 462 if(hglrc2) 463 { 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); 470 } 471 } 472 473 static void test_makecurrent(HDC winhdc) 474 { 475 BOOL ret; 476 HGLRC hglrc; 477 478 hglrc = wglCreateContext(winhdc); 479 ok( hglrc != 0, "wglCreateContext failed\n" ); 480 481 ret = wglMakeCurrent( winhdc, hglrc ); 482 ok( ret, "wglMakeCurrent failed\n" ); 483 484 ok( wglGetCurrentContext() == hglrc, "wrong context\n" ); 485 486 /* set the same context again */ 487 ret = wglMakeCurrent( winhdc, hglrc ); 488 ok( ret, "wglMakeCurrent failed\n" ); 489 490 /* check wglMakeCurrent(x, y) after another call to wglMakeCurrent(x, y) */ 491 ret = wglMakeCurrent( winhdc, NULL ); 492 ok( ret, "wglMakeCurrent failed\n" ); 493 494 ret = wglMakeCurrent( winhdc, NULL ); 495 ok( ret, "wglMakeCurrent failed\n" ); 496 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() ); 502 503 ret = wglMakeCurrent( winhdc, NULL ); 504 ok( ret, "wglMakeCurrent failed\n" ); 505 506 ret = wglMakeCurrent( winhdc, hglrc ); 507 ok( ret, "wglMakeCurrent failed\n" ); 508 509 ret = wglMakeCurrent( NULL, NULL ); 510 ok( ret, "wglMakeCurrent failed\n" ); 511 512 ok( wglGetCurrentContext() == NULL, "wrong context\n" ); 513 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() ); 519 520 ret = wglMakeCurrent( winhdc, hglrc ); 521 ok( ret, "wglMakeCurrent failed\n" ); 522 } 523 524 static void test_colorbits(HDC hdc) 525 { 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; 533 534 if (!pwglChoosePixelFormatARB) 535 { 536 win_skip("wglChoosePixelFormatARB is not available\n"); 537 return; 538 } 539 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) 543 { 544 skip("No suitable pixel formats found\n"); 545 return; 546 } 547 548 res = pwglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0, 549 sizeof(iAttribList)/sizeof(iAttribList[0]), iAttribList, iAttribRet); 550 if(res == FALSE) 551 { 552 skip("wglGetPixelFormatAttribivARB failed\n"); 553 return; 554 } 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]); 558 } 559 560 static void test_gdi_dbuf(HDC hdc) 561 { 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; 567 568 if (!pwglGetPixelFormatAttribivARB) 569 { 570 win_skip("wglGetPixelFormatAttribivARB is not available\n"); 571 return; 572 } 573 574 nFormats = DescribePixelFormat(hdc, 0, 0, NULL); 575 for(iPixelFormat = 1;iPixelFormat <= nFormats;iPixelFormat++) 576 { 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; 583 584 ok(!(iAttribRet[0] && iAttribRet[1]), "GDI support and double buffering on pixel format %d\n", iPixelFormat); 585 } 586 } 587 588 static void test_acceleration(HDC hdc) 589 { 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; 596 597 if (!pwglGetPixelFormatAttribivARB) 598 { 599 win_skip("wglGetPixelFormatAttribivARB is not available\n"); 600 return; 601 } 602 603 nFormats = DescribePixelFormat(hdc, 0, 0, NULL); 604 for(iPixelFormat = 1; iPixelFormat <= nFormats; iPixelFormat++) 605 { 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; 612 613 memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); 614 DescribePixelFormat(hdc, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd); 615 616 switch(iAttribRet[0]) 617 { 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; 627 } 628 } 629 } 630 631 static void test_bitmap_rendering( BOOL use_dib ) 632 { 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; 641 642 hdcScreen = CreateCompatibleDC(0); 643 hdcDst = CreateCompatibleDC(0); 644 645 if (use_dib) 646 { 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; 655 656 bmpDst = CreateDIBSection(0, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer, NULL, 0); 657 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); 662 } 663 else 664 { 665 bpp = GetDeviceCaps( hdcScreen, BITSPIXEL ); 666 bmpDst = CreateBitmap( 4, 4, 1, bpp, NULL ); 667 bmp2 = CreateBitmap( 12, 12, 1, bpp, NULL ); 668 } 669 670 oldDst = SelectObject(hdcDst, bmpDst); 671 672 trace( "testing on %s\n", use_dib ? "DIB" : "DDB" ); 673 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++) 677 { 678 memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); 679 DescribePixelFormat(hdcDst, i, sizeof(PIXELFORMATDESCRIPTOR), &pfd); 680 681 if((pfd.dwFlags & PFD_DRAW_TO_BITMAP) && 682 (pfd.dwFlags & PFD_SUPPORT_OPENGL) && 683 (pfd.cColorBits == bpp) && 684 (pfd.cAlphaBits == 8) ) 685 { 686 iPixelFormat = i; 687 break; 688 } 689 } 690 691 if(!iPixelFormat) 692 { 693 skip("Unable to find a suitable pixel format\n"); 694 } 695 else 696 { 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"); 705 706 if(hglrc) 707 { 708 GLint viewport[4]; 709 wglMakeCurrent(hdcDst, hglrc); 710 hglrc2 = wglCreateContext(hdcDst); 711 ok(hglrc2 != NULL, "Unable to create a context\n"); 712 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(); 718 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); 726 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" ); 732 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] ); 740 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] ); 749 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] ); 754 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] ); 759 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] ); 769 770 wglDeleteContext(hglrc2); 771 wglDeleteContext(hglrc); 772 } 773 } 774 775 SelectObject(hdcDst, oldDst); 776 DeleteObject(bmp2); 777 DeleteObject(bmpDst); 778 DeleteDC(hdcDst); 779 DeleteDC(hdcScreen); 780 } 781 782 struct wgl_thread_param 783 { 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; 791 }; 792 793 static DWORD WINAPI wgl_thread(void *param) 794 { 795 struct wgl_thread_param *p = param; 796 HDC hdc = GetDC( p->hwnd ); 797 798 ok(!glGetString(GL_RENDERER) && !glGetString(GL_VERSION) && !glGetString(GL_VENDOR), 799 "Expected NULL string when no active context is set\n"); 800 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; 809 } 810 811 static void test_deletecontext(HWND hwnd, HDC hdc) 812 { 813 struct wgl_thread_param thread_params; 814 HGLRC hglrc = wglCreateContext(hdc); 815 HANDLE thread_handle; 816 BOOL res; 817 DWORD tid; 818 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()); 823 824 if(!hglrc) 825 { 826 skip("wglCreateContext failed!\n"); 827 return; 828 } 829 830 res = wglMakeCurrent(hdc, hglrc); 831 if(!res) 832 { 833 skip("wglMakeCurrent failed!\n"); 834 return; 835 } 836 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. 839 */ 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) 846 { 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); 852 } 853 CloseHandle(thread_params.test_finished); 854 855 res = wglDeleteContext(hglrc); 856 ok(res == TRUE, "wglDeleteContext failed\n"); 857 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()); 863 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"); 868 } 869 870 871 static void test_getprocaddress(HDC hdc) 872 { 873 const char *extensions = (const char*)glGetString(GL_EXTENSIONS); 874 PROC func = NULL; 875 HGLRC ctx = wglGetCurrentContext(); 876 877 if (!extensions) 878 { 879 skip("skipping wglGetProcAddress tests because no GL extensions supported\n"); 880 return; 881 } 882 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. 885 */ 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); 892 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. 899 */ 900 if (!gl_extension_supported(extensions, "GL_ARB_multitexture")) 901 { 902 skip("skipping test because lack of GL_ARB_multitexture support\n"); 903 return; 904 } 905 906 func = wglGetProcAddress("glActiveTextureARB"); 907 ok(func != NULL, "Unable to lookup glActiveTextureARB, last error %#x\n", GetLastError()); 908 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); 914 } 915 916 static void test_make_current_read(HDC hdc) 917 { 918 int res; 919 HDC hread; 920 HGLRC hglrc = wglCreateContext(hdc); 921 922 if(!hglrc) 923 { 924 skip("wglCreateContext failed!\n"); 925 return; 926 } 927 928 res = wglMakeCurrent(hdc, hglrc); 929 if(!res) 930 { 931 skip("wglMakeCurrent failed!\n"); 932 return; 933 } 934 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"); 939 940 pwglMakeContextCurrentARB(hdc, hdc, hglrc); 941 hread = pwglGetCurrentReadDCARB(); 942 ok(hread == hdc, "wglGetCurrentReadDCARB failed for wglMakeContextCurrent\n"); 943 } 944 945 static void test_dc(HWND hwnd, HDC hdc) 946 { 947 int pf1, pf2; 948 HDC hdc2; 949 950 /* Get another DC and make sure it has the same pixel format */ 951 hdc2 = GetDC(hwnd); 952 if(hdc != hdc2) 953 { 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); 957 } 958 else 959 skip("Could not get a different DC for the window\n"); 960 961 if(hdc2) 962 { 963 ReleaseDC(hwnd, hdc2); 964 hdc2 = NULL; 965 } 966 } 967 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) 971 { 972 /* Try to create a context compatible with OpenGL 1.x; 1.0-2.1 is allowed */ 973 { 974 HGLRC gl3Ctx; 975 int attribs[] = {WGL_CONTEXT_MAJOR_VERSION_ARB, 1, 0}; 976 977 gl3Ctx = pwglCreateContextAttribsARB(hdc, 0, attribs); 978 ok(gl3Ctx != 0, "pwglCreateContextAttribsARB for a 1.x context failed!\n"); 979 wglDeleteContext(gl3Ctx); 980 } 981 982 /* Try to pass an invalid HDC */ 983 { 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); 995 } 996 997 /* Try to pass an invalid shareList */ 998 { 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); 1009 } 1010 1011 /* Try to create an OpenGL 3.0 context */ 1012 { 1013 int attribs[] = {WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 0, 0}; 1014 HGLRC gl3Ctx = pwglCreateContextAttribsARB(hdc, 0, attribs); 1015 1016 if(gl3Ctx == NULL) 1017 { 1018 skip("Skipping the rest of the WGL_ARB_create_context test due to lack of OpenGL 3.0\n"); 1019 return; 1020 } 1021 1022 wglDeleteContext(gl3Ctx); 1023 } 1024 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 */ 1026 { 1027 HGLRC glCtx = wglCreateContext(hdc); 1028 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}; 1031 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); 1036 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); 1041 1042 if(glCtx) 1043 wglDeleteContext(glCtx); 1044 } 1045 1046 /* Try to create an OpenGL 3.0 context and test windowless rendering */ 1047 { 1048 HGLRC gl3Ctx; 1049 int attribs[] = {WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 0, 0}; 1050 BOOL res; 1051 1052 gl3Ctx = pwglCreateContextAttribsARB(hdc, 0, attribs); 1053 ok(gl3Ctx != 0, "pwglCreateContextAttribsARB for a 3.0 context failed!\n"); 1054 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. 1059 */ 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); 1064 1065 if(gl3Ctx) 1066 wglDeleteContext(gl3Ctx); 1067 } 1068 } 1069 1070 static void test_minimized(void) 1071 { 1072 PIXELFORMATDESCRIPTOR pf_desc = 1073 { 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 */ 1090 }; 1091 int pixel_format; 1092 HWND window; 1093 LONG style; 1094 HGLRC ctx; 1095 BOOL ret; 1096 HDC dc; 1097 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()); 1101 1102 dc = GetDC(window); 1103 ok(!!dc, "Failed to get DC.\n"); 1104 1105 pixel_format = ChoosePixelFormat(dc, &pf_desc); 1106 if (!pixel_format) 1107 { 1108 win_skip("Failed to find pixel format.\n"); 1109 ReleaseDC(window, dc); 1110 DestroyWindow(window); 1111 return; 1112 } 1113 1114 ret = SetPixelFormat(dc, pixel_format, &pf_desc); 1115 ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError()); 1116 1117 style = GetWindowLongA(window, GWL_STYLE); 1118 ok(style & WS_MINIMIZE, "Window should be minimized, got style %#x.\n", style); 1119 1120 ctx = wglCreateContext(dc); 1121 ok(!!ctx, "Failed to create GL context, last error %#x.\n", GetLastError()); 1122 1123 ret = wglMakeCurrent(dc, ctx); 1124 ok(ret, "Failed to make context current, last error %#x.\n", GetLastError()); 1125 1126 style = GetWindowLongA(window, GWL_STYLE); 1127 ok(style & WS_MINIMIZE, "window should be minimized, got style %#x.\n", style); 1128 1129 ret = wglMakeCurrent(NULL, NULL); 1130 ok(ret, "Failed to clear current context, last error %#x.\n", GetLastError()); 1131 1132 ret = wglDeleteContext(ctx); 1133 ok(ret, "Failed to delete GL context, last error %#x.\n", GetLastError()); 1134 1135 ReleaseDC(window, dc); 1136 DestroyWindow(window); 1137 } 1138 1139 static void test_window_dc(void) 1140 { 1141 PIXELFORMATDESCRIPTOR pf_desc = 1142 { 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 */ 1159 }; 1160 int pixel_format; 1161 HWND window; 1162 RECT vp, r; 1163 HGLRC ctx; 1164 BOOL ret; 1165 HDC dc; 1166 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()); 1170 1171 ShowWindow(window, SW_SHOW); 1172 1173 dc = GetWindowDC(window); 1174 ok(!!dc, "Failed to get DC.\n"); 1175 1176 pixel_format = ChoosePixelFormat(dc, &pf_desc); 1177 if (!pixel_format) 1178 { 1179 win_skip("Failed to find pixel format.\n"); 1180 ReleaseDC(window, dc); 1181 DestroyWindow(window); 1182 return; 1183 } 1184 1185 ret = SetPixelFormat(dc, pixel_format, &pf_desc); 1186 ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError()); 1187 1188 ctx = wglCreateContext(dc); 1189 ok(!!ctx, "Failed to create GL context, last error %#x.\n", GetLastError()); 1190 1191 ret = wglMakeCurrent(dc, ctx); 1192 ok(ret, "Failed to make context current, last error %#x.\n", GetLastError()); 1193 1194 GetClientRect(window, &r); 1195 glGetIntegerv(GL_VIEWPORT, (GLint *)&vp); 1196 ok(EqualRect(&r, &vp), "Viewport not equal to client rect.\n"); 1197 1198 ret = wglMakeCurrent(NULL, NULL); 1199 ok(ret, "Failed to clear current context, last error %#x.\n", GetLastError()); 1200 1201 ret = wglDeleteContext(ctx); 1202 ok(ret, "Failed to delete GL context, last error %#x.\n", GetLastError()); 1203 1204 ReleaseDC(window, dc); 1205 DestroyWindow(window); 1206 } 1207 1208 static void test_message_window(void) 1209 { 1210 PIXELFORMATDESCRIPTOR pf_desc = 1211 { 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 */ 1228 }; 1229 int pixel_format; 1230 HWND window; 1231 RECT vp, r; 1232 HGLRC ctx; 1233 BOOL ret; 1234 HDC dc; 1235 GLenum glerr; 1236 1237 window = CreateWindowA("static", "opengl32_test", 1238 WS_OVERLAPPEDWINDOW, 0, 0, 100, 100, HWND_MESSAGE, 0, 0, 0); 1239 if (!window) 1240 { 1241 win_skip( "HWND_MESSAGE not supported\n" ); 1242 return; 1243 } 1244 dc = GetDC(window); 1245 ok(!!dc, "Failed to get DC.\n"); 1246 1247 pixel_format = ChoosePixelFormat(dc, &pf_desc); 1248 if (!pixel_format) 1249 { 1250 win_skip("Failed to find pixel format.\n"); 1251 ReleaseDC(window, dc); 1252 DestroyWindow(window); 1253 return; 1254 } 1255 1256 ret = SetPixelFormat(dc, pixel_format, &pf_desc); 1257 ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError()); 1258 1259 ctx = wglCreateContext(dc); 1260 ok(!!ctx, "Failed to create GL context, last error %#x.\n", GetLastError()); 1261 1262 ret = wglMakeCurrent(dc, ctx); 1263 ok(ret, "Failed to make context current, last error %#x.\n", GetLastError()); 1264 1265 GetClientRect(window, &r); 1266 glGetIntegerv(GL_VIEWPORT, (GLint *)&vp); 1267 ok(EqualRect(&r, &vp), "Viewport not equal to client rect.\n"); 1268 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()); 1275 1276 ret = wglMakeCurrent(NULL, NULL); 1277 ok(ret, "Failed to clear current context, last error %#x.\n", GetLastError()); 1278 1279 ret = wglDeleteContext(ctx); 1280 ok(ret, "Failed to delete GL context, last error %#x.\n", GetLastError()); 1281 1282 ReleaseDC(window, dc); 1283 DestroyWindow(window); 1284 } 1285 1286 static void test_destroy(HDC oldhdc) 1287 { 1288 PIXELFORMATDESCRIPTOR pf_desc = 1289 { 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 */ 1306 }; 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(); 1315 1316 ok(!!oldctx, "Expected to find a valid current context.\n"); 1317 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()); 1321 1322 dc = GetDC(window); 1323 ok(!!dc, "Failed to get DC.\n"); 1324 1325 pixel_format = ChoosePixelFormat(dc, &pf_desc); 1326 if (!pixel_format) 1327 { 1328 win_skip("Failed to find pixel format.\n"); 1329 ReleaseDC(window, dc); 1330 DestroyWindow(window); 1331 return; 1332 } 1333 1334 ret = SetPixelFormat(dc, pixel_format, &pf_desc); 1335 ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError()); 1336 1337 ctx = wglCreateContext(dc); 1338 ok(!!ctx, "Failed to create GL context, last error %#x.\n", GetLastError()); 1339 1340 ret = wglMakeCurrent(dc, ctx); 1341 ok(ret, "Failed to make context current, last error %#x.\n", GetLastError()); 1342 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()); 1349 1350 ret = DestroyWindow(window); 1351 ok(ret, "Failed to destroy window, last error %#x.\n", GetLastError()); 1352 1353 ok(wglGetCurrentContext() == ctx, "Wrong current context.\n"); 1354 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); 1364 1365 ok(wglGetCurrentContext() == ctx, "Wrong current context.\n"); 1366 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); 1375 1376 ret = wglMakeCurrent(NULL, NULL); 1377 ok(ret, "Failed to clear current context, last error %#x.\n", GetLastError()); 1378 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); 1387 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); 1393 1394 ok(wglGetCurrentContext() == NULL, "Wrong current context.\n"); 1395 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"); 1399 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); 1405 1406 ok(wglGetCurrentContext() == oldctx, "Wrong current context.\n"); 1407 1408 ret = wglDeleteContext(ctx); 1409 ok(ret, "Failed to delete GL context, last error %#x.\n", GetLastError()); 1410 1411 ReleaseDC(window, dc); 1412 1413 ret = wglMakeCurrent(oldhdc, oldctx); 1414 ok(ret, "Failed to make context current, last error %#x.\n", GetLastError()); 1415 } 1416 1417 static void test_destroy_read(HDC oldhdc) 1418 { 1419 PIXELFORMATDESCRIPTOR pf_desc = 1420 { 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 */ 1437 }; 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(); 1446 1447 ok(!!oldctx, "Expected to find a valid current context\n"); 1448 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()); 1452 1453 draw_dc = GetDC(draw_window); 1454 ok(!!draw_dc, "Failed to get DC.\n"); 1455 1456 pixel_format = ChoosePixelFormat(draw_dc, &pf_desc); 1457 if (!pixel_format) 1458 { 1459 win_skip("Failed to find pixel format.\n"); 1460 ReleaseDC(draw_window, draw_dc); 1461 DestroyWindow(draw_window); 1462 return; 1463 } 1464 1465 ret = SetPixelFormat(draw_dc, pixel_format, &pf_desc); 1466 ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError()); 1467 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()); 1471 1472 read_dc = GetDC(read_window); 1473 ok(!!draw_dc, "Failed to get DC.\n"); 1474 1475 pixel_format = ChoosePixelFormat(read_dc, &pf_desc); 1476 if (!pixel_format) 1477 { 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; 1484 } 1485 1486 ret = SetPixelFormat(read_dc, pixel_format, &pf_desc); 1487 ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError()); 1488 1489 ctx = wglCreateContext(draw_dc); 1490 ok(!!ctx, "Failed to create GL context, last error %#x.\n", GetLastError()); 1491 1492 ret = pwglMakeContextCurrentARB(draw_dc, read_dc, ctx); 1493 ok(ret, "Failed to make context current, last error %#x.\n", GetLastError()); 1494 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()); 1501 1502 ret = DestroyWindow(read_window); 1503 ok(ret, "Failed to destroy window, last error %#x.\n", GetLastError()); 1504 1505 ok(wglGetCurrentContext() == ctx, "Wrong current context.\n"); 1506 1507 if (0) /* Crashes on AMD on Windows */ 1508 { 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); 1513 } 1514 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()); 1521 1522 ret = wglMakeCurrent(NULL, NULL); 1523 ok(ret, "Failed to clear current context, last error %#x.\n", GetLastError()); 1524 1525 if (0) /* This crashes with Nvidia drivers on Windows. */ 1526 { 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); 1532 } 1533 1534 ret = DestroyWindow(draw_window); 1535 ok(ret, "Failed to destroy window, last error %#x.\n", GetLastError()); 1536 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); 1545 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); 1551 1552 ok(wglGetCurrentContext() == NULL, "Wrong current context.\n"); 1553 1554 wglMakeCurrent(NULL, NULL); 1555 1556 wglMakeCurrent(oldhdc, oldctx); 1557 ok(wglGetCurrentContext() == oldctx, "Wrong current context.\n"); 1558 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); 1564 1565 ok(wglGetCurrentContext() == oldctx, "Wrong current context.\n"); 1566 1567 ret = wglDeleteContext(ctx); 1568 ok(ret, "Failed to delete GL context, last error %#x.\n", GetLastError()); 1569 1570 ReleaseDC(read_window, read_dc); 1571 ReleaseDC(draw_window, draw_dc); 1572 1573 wglMakeCurrent(oldhdc, oldctx); 1574 } 1575 1576 static void test_swap_control(HDC oldhdc) 1577 { 1578 PIXELFORMATDESCRIPTOR pf_desc = 1579 { 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 */ 1596 }; 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; 1603 1604 oldctx = wglGetCurrentContext(); 1605 ok(!!oldctx, "Expected to find a valid current context.\n"); 1606 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()); 1610 1611 dc1 = GetDC(window1); 1612 ok(!!dc1, "Failed to get DC.\n"); 1613 1614 pixel_format = ChoosePixelFormat(dc1, &pf_desc); 1615 if (!pixel_format) 1616 { 1617 win_skip("Failed to find pixel format.\n"); 1618 ReleaseDC(window1, dc1); 1619 DestroyWindow(window1); 1620 return; 1621 } 1622 1623 ret = SetPixelFormat(dc1, pixel_format, &pf_desc); 1624 ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError()); 1625 1626 ctx1 = wglCreateContext(dc1); 1627 ok(!!ctx1, "Failed to create GL context, last error %#x.\n", GetLastError()); 1628 1629 ret = wglMakeCurrent(dc1, ctx1); 1630 ok(ret, "Failed to make context current, last error %#x.\n", GetLastError()); 1631 1632 interval = pwglGetSwapIntervalEXT(); 1633 ok(interval == 1, "Expected default swap interval 1, got %d\n", interval); 1634 1635 ret = pwglSwapIntervalEXT(0); 1636 ok(ret, "Failed to set swap interval to 0, last error %#x.\n", GetLastError()); 1637 1638 interval = pwglGetSwapIntervalEXT(); 1639 ok(interval == 0, "Expected swap interval 0, got %d\n", interval); 1640 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()); 1644 1645 ret = wglMakeCurrent(dc1, ctx2); 1646 ok(ret, "Failed to make context current, last error %#x.\n", GetLastError()); 1647 1648 interval = pwglGetSwapIntervalEXT(); 1649 ok(interval == 0, "Expected swap interval 0, got %d\n", interval); 1650 1651 /* A second window is created to see whether its swap interval was affected 1652 * by previous calls. 1653 */ 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()); 1657 1658 dc2 = GetDC(window2); 1659 ok(!!dc2, "Failed to get DC.\n"); 1660 1661 ret = SetPixelFormat(dc2, pixel_format, &pf_desc); 1662 ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError()); 1663 1664 ret = wglMakeCurrent(dc2, ctx1); 1665 ok(ret, "Failed to make context current, last error %#x.\n", GetLastError()); 1666 1667 /* Since the second window lacks the swap interval, this proves that the interval 1668 * is not global or shared among contexts. 1669 */ 1670 interval = pwglGetSwapIntervalEXT(); 1671 ok(interval == 1, "Expected default swap interval 1, got %d\n", interval); 1672 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()); 1676 1677 old_parent = SetParent(window1, window2); 1678 ok(!!old_parent, "Failed to make window1 a child of window2, last error %#x.\n", GetLastError()); 1679 1680 interval = pwglGetSwapIntervalEXT(); 1681 ok(interval == 0, "Expected swap interval 0, got %d\n", interval); 1682 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()); 1687 1688 ReleaseDC(window1, dc1); 1689 DestroyWindow(window1); 1690 ReleaseDC(window2, dc2); 1691 DestroyWindow(window2); 1692 1693 wglMakeCurrent(oldhdc, oldctx); 1694 } 1695 1696 START_TEST(opengl) 1697 { 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 */ 1718 }; 1719 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) 1724 { 1725 HDC hdc; 1726 int iPixelFormat, res; 1727 HGLRC hglrc; 1728 DWORD error; 1729 ShowWindow(hwnd, SW_SHOW); 1730 1731 hdc = GetDC(hwnd); 1732 1733 iPixelFormat = ChoosePixelFormat(hdc, &pfd); 1734 if(iPixelFormat == 0) 1735 { 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; 1739 } 1740 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); 1746 1747 res = SetPixelFormat(hdc, iPixelFormat, &pfd); 1748 ok(res, "SetPixelformat failed: %x\n", GetLastError()); 1749 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); 1756 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) 1763 { 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)); 1767 } 1768 else 1769 { 1770 skip("Skipping OpenGL tests without a current context\n"); 1771 return; 1772 } 1773 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). 1776 */ 1777 init_functions(); 1778 test_getprocaddress(hdc); 1779 test_deletecontext(hwnd, hdc); 1780 test_makecurrent(hdc); 1781 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) 1784 { 1785 win_skip("wglGetExtensionsStringARB is not available\n"); 1786 return; 1787 } 1788 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); 1796 1797 wgl_extensions = pwglGetExtensionsStringARB(hdc); 1798 if(wgl_extensions == NULL) skip("Skipping opengl32 tests because this OpenGL implementation doesn't support WGL extensions!\n"); 1799 1800 if(strstr(wgl_extensions, "WGL_ARB_create_context")) 1801 test_opengl3(hdc); 1802 1803 if(strstr(wgl_extensions, "WGL_ARB_make_current_read")) 1804 { 1805 test_make_current_read(hdc); 1806 test_destroy_read(hdc); 1807 } 1808 else 1809 skip("WGL_ARB_make_current_read not supported, skipping test\n"); 1810 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"); 1815 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"); 1820 1821 cleanup: 1822 ReleaseDC(hwnd, hdc); 1823 DestroyWindow(hwnd); 1824 } 1825 } 1826