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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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) 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 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 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 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 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 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 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 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