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 skip("Pbuffer creation failed!\n"); 209 210 /* Test the pixelformat returned by GetPixelFormat on a pbuffer as the behavior is not clear */ 211 pbuffer_hdc = pwglGetPbufferDCARB(pbuffer); 212 res = GetPixelFormat(pbuffer_hdc); 213 214 ok(res == 1, "Unexpected iPixelFormat=%d (1 expected) returned by GetPixelFormat for offscreen format %d\n", res, iPixelFormat); 215 trace("iPixelFormat returned by GetPixelFormat: %d\n", res); 216 trace("PixelFormat from wglChoosePixelFormatARB: %d\n", iPixelFormat); 217 pwglReleasePbufferDCARB(pbuffer, hdc); 218 } 219 else skip("Pbuffer test for offscreen pixelformat skipped as no offscreen-only format with pbuffer capabilities has been found\n"); 220 } 221 222 static int test_pfd(const PIXELFORMATDESCRIPTOR *pfd, PIXELFORMATDESCRIPTOR *fmt) 223 { 224 int pf; 225 HDC hdc; 226 HWND hwnd; 227 228 hwnd = CreateWindowA("static", "Title", WS_OVERLAPPEDWINDOW, 10, 10, 200, 200, NULL, NULL, 229 NULL, NULL); 230 if (!hwnd) 231 return 0; 232 233 hdc = GetDC( hwnd ); 234 pf = ChoosePixelFormat( hdc, pfd ); 235 if (pf && fmt) 236 { 237 memset(fmt, 0, sizeof(*fmt)); 238 ok(DescribePixelFormat( hdc, pf, sizeof(*fmt), fmt ), 239 "DescribePixelFormat failed with error: %u\n", GetLastError()); 240 } 241 ReleaseDC( hwnd, hdc ); 242 DestroyWindow( hwnd ); 243 244 return pf; 245 } 246 247 static void test_choosepixelformat(void) 248 { 249 PIXELFORMATDESCRIPTOR pfd = { 250 sizeof(PIXELFORMATDESCRIPTOR), 251 1, /* version */ 252 PFD_DRAW_TO_WINDOW | 253 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[sizeof(iAttribList)/sizeof(iAttribList[0])]; 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, 609 sizeof(iAttribList)/sizeof(iAttribList[0]), iAttribList, 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[sizeof(iAttribList)/sizeof(iAttribList[0])]; 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, 638 sizeof(iAttribList)/sizeof(iAttribList[0]), iAttribList, 639 iAttribRet); 640 ok(res!=FALSE, "wglGetPixelFormatAttribivARB failed for pixel format %d\n", iPixelFormat); 641 if(res == FALSE) 642 continue; 643 644 ok(!(iAttribRet[0] && iAttribRet[1]), "GDI support and double buffering on pixel format %d\n", iPixelFormat); 645 } 646 } 647 648 static void test_acceleration(HDC hdc) 649 { 650 const int iAttribList[] = { WGL_ACCELERATION_ARB }; 651 int iAttribRet[sizeof(iAttribList)/sizeof(iAttribList[0])]; 652 unsigned int nFormats; 653 int iPixelFormat; 654 int res; 655 PIXELFORMATDESCRIPTOR pfd; 656 657 if (!pwglGetPixelFormatAttribivARB) 658 { 659 win_skip("wglGetPixelFormatAttribivARB is not available\n"); 660 return; 661 } 662 663 nFormats = DescribePixelFormat(hdc, 0, 0, NULL); 664 for(iPixelFormat = 1; iPixelFormat <= nFormats; iPixelFormat++) 665 { 666 res = pwglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0, 667 sizeof(iAttribList)/sizeof(iAttribList[0]), iAttribList, 668 iAttribRet); 669 ok(res!=FALSE, "wglGetPixelFormatAttribivARB failed for pixel format %d\n", iPixelFormat); 670 if(res == FALSE) 671 continue; 672 673 memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); 674 DescribePixelFormat(hdc, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd); 675 676 switch(iAttribRet[0]) 677 { 678 case WGL_NO_ACCELERATION_ARB: 679 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); 680 break; 681 case WGL_GENERIC_ACCELERATION_ARB: 682 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); 683 break; 684 case WGL_FULL_ACCELERATION_ARB: 685 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); 686 break; 687 } 688 } 689 } 690 691 static void test_bitmap_rendering( BOOL use_dib ) 692 { 693 PIXELFORMATDESCRIPTOR pfd; 694 int i, ret, bpp, iPixelFormat=0; 695 unsigned int nFormats; 696 HGLRC hglrc, hglrc2; 697 BITMAPINFO biDst; 698 HBITMAP bmpDst, oldDst, bmp2; 699 HDC hdcDst, hdcScreen; 700 UINT *dstBuffer = NULL; 701 702 hdcScreen = CreateCompatibleDC(0); 703 hdcDst = CreateCompatibleDC(0); 704 705 if (use_dib) 706 { 707 bpp = 32; 708 memset(&biDst, 0, sizeof(BITMAPINFO)); 709 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 710 biDst.bmiHeader.biWidth = 4; 711 biDst.bmiHeader.biHeight = -4; 712 biDst.bmiHeader.biPlanes = 1; 713 biDst.bmiHeader.biBitCount = 32; 714 biDst.bmiHeader.biCompression = BI_RGB; 715 716 bmpDst = CreateDIBSection(0, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer, NULL, 0); 717 718 biDst.bmiHeader.biWidth = 12; 719 biDst.bmiHeader.biHeight = -12; 720 biDst.bmiHeader.biBitCount = 16; 721 bmp2 = CreateDIBSection(0, &biDst, DIB_RGB_COLORS, NULL, NULL, 0); 722 } 723 else 724 { 725 bpp = GetDeviceCaps( hdcScreen, BITSPIXEL ); 726 bmpDst = CreateBitmap( 4, 4, 1, bpp, NULL ); 727 bmp2 = CreateBitmap( 12, 12, 1, bpp, NULL ); 728 } 729 730 oldDst = SelectObject(hdcDst, bmpDst); 731 732 trace( "testing on %s\n", use_dib ? "DIB" : "DDB" ); 733 734 /* Pick a pixel format by hand because ChoosePixelFormat is unreliable */ 735 nFormats = DescribePixelFormat(hdcDst, 0, 0, NULL); 736 for(i=1; i<=nFormats; i++) 737 { 738 memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); 739 DescribePixelFormat(hdcDst, i, sizeof(PIXELFORMATDESCRIPTOR), &pfd); 740 741 if((pfd.dwFlags & PFD_DRAW_TO_BITMAP) && 742 (pfd.dwFlags & PFD_SUPPORT_OPENGL) && 743 (pfd.cColorBits == bpp) && 744 (pfd.cAlphaBits == 8) ) 745 { 746 iPixelFormat = i; 747 break; 748 } 749 } 750 751 if(!iPixelFormat) 752 { 753 skip("Unable to find a suitable pixel format\n"); 754 } 755 else 756 { 757 ret = SetPixelFormat(hdcDst, iPixelFormat, &pfd); 758 ok( ret, "SetPixelFormat failed\n" ); 759 ret = GetPixelFormat( hdcDst ); 760 ok( ret == iPixelFormat, "GetPixelFormat returned %d/%d\n", ret, iPixelFormat ); 761 ret = SetPixelFormat(hdcDst, iPixelFormat + 1, &pfd); 762 ok( !ret, "SetPixelFormat succeeded\n" ); 763 hglrc = wglCreateContext(hdcDst); 764 ok(hglrc != NULL, "Unable to create a context\n"); 765 766 if(hglrc) 767 { 768 GLint viewport[4]; 769 wglMakeCurrent(hdcDst, hglrc); 770 hglrc2 = wglCreateContext(hdcDst); 771 ok(hglrc2 != NULL, "Unable to create a context\n"); 772 773 /* Note this is RGBA but we read ARGB back */ 774 glClearColor((float)0x22/0xff, (float)0x33/0xff, (float)0x44/0xff, (float)0x11/0xff); 775 glClear(GL_COLOR_BUFFER_BIT); 776 glGetIntegerv( GL_VIEWPORT, viewport ); 777 glFinish(); 778 779 ok( viewport[0] == 0 && viewport[1] == 0 && viewport[2] == 4 && viewport[3] == 4, 780 "wrong viewport %d,%d,%d,%d\n", viewport[0], viewport[1], viewport[2], viewport[3] ); 781 /* Note apparently the alpha channel is not supported by the software renderer (bitmap only works using software) */ 782 if (dstBuffer) 783 for (i = 0; i < 16; i++) 784 ok(dstBuffer[i] == 0x223344 || dstBuffer[i] == 0x11223344, "Received color=%x at %u\n", 785 dstBuffer[i], i); 786 787 SelectObject(hdcDst, bmp2); 788 ret = GetPixelFormat( hdcDst ); 789 ok( ret == iPixelFormat, "GetPixelFormat returned %d/%d\n", ret, iPixelFormat ); 790 ret = SetPixelFormat(hdcDst, iPixelFormat + 1, &pfd); 791 ok( !ret, "SetPixelFormat succeeded\n" ); 792 793 /* context still uses the old pixel format and viewport */ 794 glClearColor((float)0x44/0xff, (float)0x33/0xff, (float)0x22/0xff, (float)0x11/0xff); 795 glClear(GL_COLOR_BUFFER_BIT); 796 glFinish(); 797 glGetIntegerv( GL_VIEWPORT, viewport ); 798 ok( viewport[0] == 0 && viewport[1] == 0 && viewport[2] == 4 && viewport[3] == 4, 799 "wrong viewport %d,%d,%d,%d\n", viewport[0], viewport[1], viewport[2], viewport[3] ); 800 801 wglMakeCurrent(NULL, NULL); 802 wglMakeCurrent(hdcDst, hglrc); 803 glClearColor((float)0x44/0xff, (float)0x55/0xff, (float)0x66/0xff, (float)0x11/0xff); 804 glClear(GL_COLOR_BUFFER_BIT); 805 glFinish(); 806 glGetIntegerv( GL_VIEWPORT, viewport ); 807 ok( viewport[0] == 0 && viewport[1] == 0 && viewport[2] == 4 && viewport[3] == 4, 808 "wrong viewport %d,%d,%d,%d\n", viewport[0], viewport[1], viewport[2], viewport[3] ); 809 810 wglMakeCurrent(hdcDst, hglrc2); 811 glGetIntegerv( GL_VIEWPORT, viewport ); 812 ok( viewport[0] == 0 && viewport[1] == 0 && viewport[2] == 12 && viewport[3] == 12, 813 "wrong viewport %d,%d,%d,%d\n", viewport[0], viewport[1], viewport[2], viewport[3] ); 814 815 wglMakeCurrent(hdcDst, hglrc); 816 glGetIntegerv( GL_VIEWPORT, viewport ); 817 ok( viewport[0] == 0 && viewport[1] == 0 && viewport[2] == 4 && viewport[3] == 4, 818 "wrong viewport %d,%d,%d,%d\n", viewport[0], viewport[1], viewport[2], viewport[3] ); 819 820 SelectObject(hdcDst, bmpDst); 821 ret = GetPixelFormat( hdcDst ); 822 ok( ret == iPixelFormat, "GetPixelFormat returned %d/%d\n", ret, iPixelFormat ); 823 ret = SetPixelFormat(hdcDst, iPixelFormat + 1, &pfd); 824 ok( !ret, "SetPixelFormat succeeded\n" ); 825 wglMakeCurrent(hdcDst, hglrc2); 826 glGetIntegerv( GL_VIEWPORT, viewport ); 827 ok( viewport[0] == 0 && viewport[1] == 0 && viewport[2] == 12 && viewport[3] == 12, 828 "wrong viewport %d,%d,%d,%d\n", viewport[0], viewport[1], viewport[2], viewport[3] ); 829 830 wglDeleteContext(hglrc2); 831 wglDeleteContext(hglrc); 832 } 833 } 834 835 SelectObject(hdcDst, oldDst); 836 DeleteObject(bmp2); 837 DeleteObject(bmpDst); 838 DeleteDC(hdcDst); 839 DeleteDC(hdcScreen); 840 } 841 842 struct wgl_thread_param 843 { 844 HANDLE test_finished; 845 HWND hwnd; 846 HGLRC hglrc; 847 BOOL make_current; 848 BOOL make_current_error; 849 BOOL deleted; 850 DWORD deleted_error; 851 }; 852 853 static DWORD WINAPI wgl_thread(void *param) 854 { 855 struct wgl_thread_param *p = param; 856 HDC hdc = GetDC( p->hwnd ); 857 858 ok(!glGetString(GL_RENDERER) && !glGetString(GL_VERSION) && !glGetString(GL_VENDOR), 859 "Expected NULL string when no active context is set\n"); 860 861 SetLastError(0xdeadbeef); 862 p->make_current = wglMakeCurrent(hdc, p->hglrc); 863 p->make_current_error = GetLastError(); 864 p->deleted = wglDeleteContext(p->hglrc); 865 p->deleted_error = GetLastError(); 866 ReleaseDC( p->hwnd, hdc ); 867 SetEvent(p->test_finished); 868 return 0; 869 } 870 871 static void test_deletecontext(HWND hwnd, HDC hdc) 872 { 873 struct wgl_thread_param thread_params; 874 HGLRC hglrc = wglCreateContext(hdc); 875 HANDLE thread_handle; 876 BOOL res; 877 DWORD tid; 878 879 SetLastError(0xdeadbeef); 880 res = wglDeleteContext(NULL); 881 ok(res == FALSE, "wglDeleteContext succeeded\n"); 882 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected last error to be ERROR_INVALID_HANDLE, got %u\n", GetLastError()); 883 884 if(!hglrc) 885 { 886 skip("wglCreateContext failed!\n"); 887 return; 888 } 889 890 res = wglMakeCurrent(hdc, hglrc); 891 if(!res) 892 { 893 skip("wglMakeCurrent failed!\n"); 894 return; 895 } 896 897 /* WGL doesn't allow you to delete a context from a different thread than the one in which it is current. 898 * This differs from GLX which does allow it but it delays actual deletion until the context becomes not current. 899 */ 900 thread_params.hglrc = hglrc; 901 thread_params.hwnd = hwnd; 902 thread_params.test_finished = CreateEventW(NULL, FALSE, FALSE, NULL); 903 thread_handle = CreateThread(NULL, 0, wgl_thread, &thread_params, 0, &tid); 904 ok(!!thread_handle, "Failed to create thread, last error %#x.\n", GetLastError()); 905 if(thread_handle) 906 { 907 WaitForSingleObject(thread_handle, INFINITE); 908 ok(!thread_params.make_current, "Attempt to make WGL context from another thread passed\n"); 909 ok(thread_params.make_current_error == ERROR_BUSY, "Expected last error to be ERROR_BUSY, got %u\n", thread_params.make_current_error); 910 ok(!thread_params.deleted, "Attempt to delete WGL context from another thread passed\n"); 911 ok(thread_params.deleted_error == ERROR_BUSY, "Expected last error to be ERROR_BUSY, got %u\n", thread_params.deleted_error); 912 } 913 CloseHandle(thread_params.test_finished); 914 915 res = wglDeleteContext(hglrc); 916 ok(res == TRUE, "wglDeleteContext failed\n"); 917 918 /* Attempting to delete the same context twice should fail. */ 919 SetLastError(0xdeadbeef); 920 res = wglDeleteContext(hglrc); 921 ok(res == FALSE, "wglDeleteContext succeeded\n"); 922 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected last error to be ERROR_INVALID_HANDLE, got %u\n", GetLastError()); 923 924 /* WGL makes a context not current when deleting it. This differs from GLX behavior where 925 * deletion takes place when the thread becomes not current. */ 926 hglrc = wglGetCurrentContext(); 927 ok(hglrc == NULL, "A WGL context is active while none was expected\n"); 928 } 929 930 931 static void test_getprocaddress(HDC hdc) 932 { 933 const char *extensions = (const char*)glGetString(GL_EXTENSIONS); 934 PROC func = NULL; 935 HGLRC ctx = wglGetCurrentContext(); 936 937 if (!extensions) 938 { 939 skip("skipping wglGetProcAddress tests because no GL extensions supported\n"); 940 return; 941 } 942 943 /* Core GL 1.0/1.1 functions should not be loadable through wglGetProcAddress. 944 * Try to load the function with and without a context. 945 */ 946 func = wglGetProcAddress("glEnable"); 947 ok(func == NULL, "Lookup of function glEnable with a context passed, expected a failure\n"); 948 wglMakeCurrent(hdc, NULL); 949 func = wglGetProcAddress("glEnable"); 950 ok(func == NULL, "Lookup of function glEnable without a context passed, expected a failure\n"); 951 wglMakeCurrent(hdc, ctx); 952 953 /* The goal of the test will be to test behavior of wglGetProcAddress when 954 * no WGL context is active. Before the test we pick an extension (GL_ARB_multitexture) 955 * which any GL >=1.2.1 implementation supports. Unfortunately the GDI renderer doesn't 956 * support it. There aren't any extensions we can use for this test which are supported by 957 * both GDI and real drivers. 958 * Note GDI only has GL_EXT_bgra, GL_EXT_paletted_texture and GL_WIN_swap_hint. 959 */ 960 if (!gl_extension_supported(extensions, "GL_ARB_multitexture")) 961 { 962 skip("skipping test because lack of GL_ARB_multitexture support\n"); 963 return; 964 } 965 966 func = wglGetProcAddress("glActiveTextureARB"); 967 ok(func != NULL, "Unable to lookup glActiveTextureARB, last error %#x\n", GetLastError()); 968 969 /* Temporarily disable the context, so we can see that we can't retrieve functions now. */ 970 wglMakeCurrent(hdc, NULL); 971 func = wglGetProcAddress("glActiveTextureARB"); 972 ok(func == NULL, "Function lookup without a context passed, expected a failure; last error %#x\n", GetLastError()); 973 wglMakeCurrent(hdc, ctx); 974 } 975 976 static void test_make_current_read(HDC hdc) 977 { 978 int res; 979 HDC hread; 980 HGLRC hglrc = wglCreateContext(hdc); 981 982 if(!hglrc) 983 { 984 skip("wglCreateContext failed!\n"); 985 return; 986 } 987 988 res = wglMakeCurrent(hdc, hglrc); 989 if(!res) 990 { 991 skip("wglMakeCurrent failed!\n"); 992 return; 993 } 994 995 /* Test what wglGetCurrentReadDCARB does for wglMakeCurrent as the spec doesn't mention it */ 996 hread = pwglGetCurrentReadDCARB(); 997 trace("hread %p, hdc %p\n", hread, hdc); 998 ok(hread == hdc, "wglGetCurrentReadDCARB failed for standard wglMakeCurrent\n"); 999 1000 pwglMakeContextCurrentARB(hdc, hdc, hglrc); 1001 hread = pwglGetCurrentReadDCARB(); 1002 ok(hread == hdc, "wglGetCurrentReadDCARB failed for wglMakeContextCurrent\n"); 1003 } 1004 1005 static void test_dc(HWND hwnd, HDC hdc) 1006 { 1007 int pf1, pf2; 1008 HDC hdc2; 1009 1010 /* Get another DC and make sure it has the same pixel format */ 1011 hdc2 = GetDC(hwnd); 1012 if(hdc != hdc2) 1013 { 1014 pf1 = GetPixelFormat(hdc); 1015 pf2 = GetPixelFormat(hdc2); 1016 ok(pf1 == pf2, "Second DC does not have the same format (%d != %d)\n", pf1, pf2); 1017 } 1018 else 1019 skip("Could not get a different DC for the window\n"); 1020 1021 if(hdc2) 1022 { 1023 ReleaseDC(hwnd, hdc2); 1024 hdc2 = NULL; 1025 } 1026 } 1027 1028 /* Nvidia converts win32 error codes to (0xc007 << 16) | win32_error_code */ 1029 #define NVIDIA_HRESULT_FROM_WIN32(x) (HRESULT_FROM_WIN32(x) | 0x40000000) 1030 static void test_opengl3(HDC hdc) 1031 { 1032 /* Try to create a context compatible with OpenGL 1.x; 1.0-2.1 is allowed */ 1033 { 1034 HGLRC gl3Ctx; 1035 int attribs[] = {WGL_CONTEXT_MAJOR_VERSION_ARB, 1, 0}; 1036 1037 gl3Ctx = pwglCreateContextAttribsARB(hdc, 0, attribs); 1038 ok(gl3Ctx != 0, "pwglCreateContextAttribsARB for a 1.x context failed!\n"); 1039 wglDeleteContext(gl3Ctx); 1040 } 1041 1042 /* Try to pass an invalid HDC */ 1043 { 1044 HGLRC gl3Ctx; 1045 DWORD error; 1046 SetLastError(0xdeadbeef); 1047 gl3Ctx = pwglCreateContextAttribsARB((HDC)0xdeadbeef, 0, 0); 1048 ok(gl3Ctx == 0, "pwglCreateContextAttribsARB using an invalid HDC passed\n"); 1049 error = GetLastError(); 1050 ok(error == ERROR_DC_NOT_FOUND || error == ERROR_INVALID_HANDLE || 1051 broken(error == ERROR_DS_GENERIC_ERROR) || 1052 broken(error == NVIDIA_HRESULT_FROM_WIN32(ERROR_INVALID_DATA)), /* Nvidia Vista + Win7 */ 1053 "Expected ERROR_DC_NOT_FOUND, got error=%x\n", error); 1054 wglDeleteContext(gl3Ctx); 1055 } 1056 1057 /* Try to pass an invalid shareList */ 1058 { 1059 HGLRC gl3Ctx; 1060 DWORD error; 1061 SetLastError(0xdeadbeef); 1062 gl3Ctx = pwglCreateContextAttribsARB(hdc, (HGLRC)0xdeadbeef, 0); 1063 ok(gl3Ctx == 0, "pwglCreateContextAttribsARB using an invalid shareList passed\n"); 1064 error = GetLastError(); 1065 /* The Nvidia implementation seems to return hresults instead of win32 error codes */ 1066 ok(error == ERROR_INVALID_OPERATION || error == ERROR_INVALID_DATA || 1067 error == NVIDIA_HRESULT_FROM_WIN32(ERROR_INVALID_OPERATION), "Expected ERROR_INVALID_OPERATION, got error=%x\n", error); 1068 wglDeleteContext(gl3Ctx); 1069 } 1070 1071 /* Try to create an OpenGL 3.0 context */ 1072 { 1073 int attribs[] = {WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 0, 0}; 1074 HGLRC gl3Ctx = pwglCreateContextAttribsARB(hdc, 0, attribs); 1075 1076 if(gl3Ctx == NULL) 1077 { 1078 skip("Skipping the rest of the WGL_ARB_create_context test due to lack of OpenGL 3.0\n"); 1079 return; 1080 } 1081 1082 wglDeleteContext(gl3Ctx); 1083 } 1084 1085 /* 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 */ 1086 { 1087 HGLRC glCtx = wglCreateContext(hdc); 1088 1089 int attribs[] = {WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 0, 0}; 1090 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}; 1091 1092 HGLRC gl3Ctx = pwglCreateContextAttribsARB(hdc, glCtx, attribs); 1093 ok(gl3Ctx != NULL, "Sharing of a display list between OpenGL 3.0 and OpenGL 1.x/2.x failed!\n"); 1094 if(gl3Ctx) 1095 wglDeleteContext(gl3Ctx); 1096 1097 gl3Ctx = pwglCreateContextAttribsARB(hdc, glCtx, attribs_future); 1098 ok(gl3Ctx != NULL, "Sharing of a display list between a forward compatible OpenGL 3.0 context and OpenGL 1.x/2.x failed!\n"); 1099 if(gl3Ctx) 1100 wglDeleteContext(gl3Ctx); 1101 1102 if(glCtx) 1103 wglDeleteContext(glCtx); 1104 } 1105 1106 /* Try to create an OpenGL 3.0 context and test windowless rendering */ 1107 { 1108 HGLRC gl3Ctx; 1109 int attribs[] = {WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 0, 0}; 1110 BOOL res; 1111 1112 gl3Ctx = pwglCreateContextAttribsARB(hdc, 0, attribs); 1113 ok(gl3Ctx != 0, "pwglCreateContextAttribsARB for a 3.0 context failed!\n"); 1114 1115 /* OpenGL 3.0 allows offscreen rendering WITHOUT a drawable 1116 * Neither AMD or Nvidia support it at this point. The WGL_ARB_create_context specs also say that 1117 * it is hard because drivers use the HDC to enter the display driver and it sounds like they don't 1118 * expect drivers to ever offer it. 1119 */ 1120 res = wglMakeCurrent(0, gl3Ctx); 1121 ok(res == FALSE, "Wow, OpenGL 3.0 windowless rendering passed while it was expected not to!\n"); 1122 if(res) 1123 wglMakeCurrent(0, 0); 1124 1125 if(gl3Ctx) 1126 wglDeleteContext(gl3Ctx); 1127 } 1128 } 1129 1130 static void test_minimized(void) 1131 { 1132 PIXELFORMATDESCRIPTOR pf_desc = 1133 { 1134 sizeof(PIXELFORMATDESCRIPTOR), 1135 1, /* version */ 1136 PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, 1137 PFD_TYPE_RGBA, 1138 24, /* 24-bit color depth */ 1139 0, 0, 0, 0, 0, 0, /* color bits */ 1140 0, /* alpha buffer */ 1141 0, /* shift bit */ 1142 0, /* accumulation buffer */ 1143 0, 0, 0, 0, /* accum bits */ 1144 32, /* z-buffer */ 1145 0, /* stencil buffer */ 1146 0, /* auxiliary buffer */ 1147 PFD_MAIN_PLANE, /* main layer */ 1148 0, /* reserved */ 1149 0, 0, 0 /* layer masks */ 1150 }; 1151 int pixel_format; 1152 HWND window; 1153 LONG style; 1154 HGLRC ctx; 1155 BOOL ret; 1156 HDC dc; 1157 1158 window = CreateWindowA("static", "opengl32_test", 1159 WS_POPUP | WS_MINIMIZE, 0, 0, 640, 480, 0, 0, 0, 0); 1160 ok(!!window, "Failed to create window, last error %#x.\n", GetLastError()); 1161 1162 dc = GetDC(window); 1163 ok(!!dc, "Failed to get DC.\n"); 1164 1165 pixel_format = ChoosePixelFormat(dc, &pf_desc); 1166 if (!pixel_format) 1167 { 1168 win_skip("Failed to find pixel format.\n"); 1169 ReleaseDC(window, dc); 1170 DestroyWindow(window); 1171 return; 1172 } 1173 1174 ret = SetPixelFormat(dc, pixel_format, &pf_desc); 1175 ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError()); 1176 1177 style = GetWindowLongA(window, GWL_STYLE); 1178 ok(style & WS_MINIMIZE, "Window should be minimized, got style %#x.\n", style); 1179 1180 ctx = wglCreateContext(dc); 1181 ok(!!ctx, "Failed to create GL context, last error %#x.\n", GetLastError()); 1182 1183 ret = wglMakeCurrent(dc, ctx); 1184 ok(ret, "Failed to make context current, last error %#x.\n", GetLastError()); 1185 1186 style = GetWindowLongA(window, GWL_STYLE); 1187 ok(style & WS_MINIMIZE, "window should be minimized, got style %#x.\n", style); 1188 1189 ret = wglMakeCurrent(NULL, NULL); 1190 ok(ret, "Failed to clear current context, last error %#x.\n", GetLastError()); 1191 1192 ret = wglDeleteContext(ctx); 1193 ok(ret, "Failed to delete GL context, last error %#x.\n", GetLastError()); 1194 1195 ReleaseDC(window, dc); 1196 DestroyWindow(window); 1197 } 1198 1199 static void test_window_dc(void) 1200 { 1201 PIXELFORMATDESCRIPTOR pf_desc = 1202 { 1203 sizeof(PIXELFORMATDESCRIPTOR), 1204 1, /* version */ 1205 PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, 1206 PFD_TYPE_RGBA, 1207 24, /* 24-bit color depth */ 1208 0, 0, 0, 0, 0, 0, /* color bits */ 1209 0, /* alpha buffer */ 1210 0, /* shift bit */ 1211 0, /* accumulation buffer */ 1212 0, 0, 0, 0, /* accum bits */ 1213 32, /* z-buffer */ 1214 0, /* stencil buffer */ 1215 0, /* auxiliary buffer */ 1216 PFD_MAIN_PLANE, /* main layer */ 1217 0, /* reserved */ 1218 0, 0, 0 /* layer masks */ 1219 }; 1220 int pixel_format; 1221 HWND window; 1222 RECT vp, r; 1223 HGLRC ctx; 1224 BOOL ret; 1225 HDC dc; 1226 1227 window = CreateWindowA("static", "opengl32_test", 1228 WS_OVERLAPPEDWINDOW, 0, 0, 640, 480, 0, 0, 0, 0); 1229 ok(!!window, "Failed to create window, last error %#x.\n", GetLastError()); 1230 1231 ShowWindow(window, SW_SHOW); 1232 1233 dc = GetWindowDC(window); 1234 ok(!!dc, "Failed to get DC.\n"); 1235 1236 pixel_format = ChoosePixelFormat(dc, &pf_desc); 1237 if (!pixel_format) 1238 { 1239 win_skip("Failed to find pixel format.\n"); 1240 ReleaseDC(window, dc); 1241 DestroyWindow(window); 1242 return; 1243 } 1244 1245 ret = SetPixelFormat(dc, pixel_format, &pf_desc); 1246 ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError()); 1247 1248 ctx = wglCreateContext(dc); 1249 ok(!!ctx, "Failed to create GL context, last error %#x.\n", GetLastError()); 1250 1251 ret = wglMakeCurrent(dc, ctx); 1252 ok(ret, "Failed to make context current, last error %#x.\n", GetLastError()); 1253 1254 GetClientRect(window, &r); 1255 glGetIntegerv(GL_VIEWPORT, (GLint *)&vp); 1256 ok(EqualRect(&r, &vp), "Viewport not equal to client rect.\n"); 1257 1258 ret = wglMakeCurrent(NULL, NULL); 1259 ok(ret, "Failed to clear current context, last error %#x.\n", GetLastError()); 1260 1261 ret = wglDeleteContext(ctx); 1262 ok(ret, "Failed to delete GL context, last error %#x.\n", GetLastError()); 1263 1264 ReleaseDC(window, dc); 1265 DestroyWindow(window); 1266 } 1267 1268 static void test_message_window(void) 1269 { 1270 PIXELFORMATDESCRIPTOR pf_desc = 1271 { 1272 sizeof(PIXELFORMATDESCRIPTOR), 1273 1, /* version */ 1274 PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, 1275 PFD_TYPE_RGBA, 1276 24, /* 24-bit color depth */ 1277 0, 0, 0, 0, 0, 0, /* color bits */ 1278 0, /* alpha buffer */ 1279 0, /* shift bit */ 1280 0, /* accumulation buffer */ 1281 0, 0, 0, 0, /* accum bits */ 1282 32, /* z-buffer */ 1283 0, /* stencil buffer */ 1284 0, /* auxiliary buffer */ 1285 PFD_MAIN_PLANE, /* main layer */ 1286 0, /* reserved */ 1287 0, 0, 0 /* layer masks */ 1288 }; 1289 int pixel_format; 1290 HWND window; 1291 RECT vp, r; 1292 HGLRC ctx; 1293 BOOL ret; 1294 HDC dc; 1295 GLenum glerr; 1296 1297 window = CreateWindowA("static", "opengl32_test", 1298 WS_OVERLAPPEDWINDOW, 0, 0, 100, 100, HWND_MESSAGE, 0, 0, 0); 1299 if (!window) 1300 { 1301 win_skip( "HWND_MESSAGE not supported\n" ); 1302 return; 1303 } 1304 dc = GetDC(window); 1305 ok(!!dc, "Failed to get DC.\n"); 1306 1307 pixel_format = ChoosePixelFormat(dc, &pf_desc); 1308 if (!pixel_format) 1309 { 1310 win_skip("Failed to find pixel format.\n"); 1311 ReleaseDC(window, dc); 1312 DestroyWindow(window); 1313 return; 1314 } 1315 1316 ret = SetPixelFormat(dc, pixel_format, &pf_desc); 1317 ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError()); 1318 1319 ctx = wglCreateContext(dc); 1320 ok(!!ctx, "Failed to create GL context, last error %#x.\n", GetLastError()); 1321 1322 ret = wglMakeCurrent(dc, ctx); 1323 ok(ret, "Failed to make context current, last error %#x.\n", GetLastError()); 1324 1325 GetClientRect(window, &r); 1326 glGetIntegerv(GL_VIEWPORT, (GLint *)&vp); 1327 ok(EqualRect(&r, &vp), "Viewport not equal to client rect.\n"); 1328 1329 glClear(GL_COLOR_BUFFER_BIT); 1330 glFinish(); 1331 glerr = glGetError(); 1332 ok(glerr == GL_NO_ERROR, "Failed glClear, error %#x.\n", glerr); 1333 ret = SwapBuffers(dc); 1334 ok(ret, "Failed SwapBuffers, error %#x.\n", GetLastError()); 1335 1336 ret = wglMakeCurrent(NULL, NULL); 1337 ok(ret, "Failed to clear current context, last error %#x.\n", GetLastError()); 1338 1339 ret = wglDeleteContext(ctx); 1340 ok(ret, "Failed to delete GL context, last error %#x.\n", GetLastError()); 1341 1342 ReleaseDC(window, dc); 1343 DestroyWindow(window); 1344 } 1345 1346 static void test_destroy(HDC oldhdc) 1347 { 1348 PIXELFORMATDESCRIPTOR pf_desc = 1349 { 1350 sizeof(PIXELFORMATDESCRIPTOR), 1351 1, /* version */ 1352 PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, 1353 PFD_TYPE_RGBA, 1354 24, /* 24-bit color depth */ 1355 0, 0, 0, 0, 0, 0, /* color bits */ 1356 0, /* alpha buffer */ 1357 0, /* shift bit */ 1358 0, /* accumulation buffer */ 1359 0, 0, 0, 0, /* accum bits */ 1360 32, /* z-buffer */ 1361 0, /* stencil buffer */ 1362 0, /* auxiliary buffer */ 1363 PFD_MAIN_PLANE, /* main layer */ 1364 0, /* reserved */ 1365 0, 0, 0 /* layer masks */ 1366 }; 1367 int pixel_format; 1368 HWND window; 1369 HGLRC ctx; 1370 BOOL ret; 1371 HDC dc; 1372 GLenum glerr; 1373 DWORD err; 1374 HGLRC oldctx = wglGetCurrentContext(); 1375 1376 ok(!!oldctx, "Expected to find a valid current context.\n"); 1377 1378 window = CreateWindowA("static", "opengl32_test", 1379 WS_POPUP, 0, 0, 640, 480, 0, 0, 0, 0); 1380 ok(!!window, "Failed to create window, last error %#x.\n", GetLastError()); 1381 1382 dc = GetDC(window); 1383 ok(!!dc, "Failed to get DC.\n"); 1384 1385 pixel_format = ChoosePixelFormat(dc, &pf_desc); 1386 if (!pixel_format) 1387 { 1388 win_skip("Failed to find pixel format.\n"); 1389 ReleaseDC(window, dc); 1390 DestroyWindow(window); 1391 return; 1392 } 1393 1394 ret = SetPixelFormat(dc, pixel_format, &pf_desc); 1395 ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError()); 1396 1397 ctx = wglCreateContext(dc); 1398 ok(!!ctx, "Failed to create GL context, last error %#x.\n", GetLastError()); 1399 1400 ret = wglMakeCurrent(dc, ctx); 1401 ok(ret, "Failed to make context current, last error %#x.\n", GetLastError()); 1402 1403 glClear(GL_COLOR_BUFFER_BIT); 1404 glFinish(); 1405 glerr = glGetError(); 1406 ok(glerr == GL_NO_ERROR, "Failed glClear, error %#x.\n", glerr); 1407 ret = SwapBuffers(dc); 1408 ok(ret, "Failed SwapBuffers, error %#x.\n", GetLastError()); 1409 1410 ret = DestroyWindow(window); 1411 ok(ret, "Failed to destroy window, last error %#x.\n", GetLastError()); 1412 1413 ok(wglGetCurrentContext() == ctx, "Wrong current context.\n"); 1414 1415 SetLastError(0xdeadbeef); 1416 ret = wglMakeCurrent(dc, ctx); 1417 err = GetLastError(); 1418 ok(!ret && err == ERROR_INVALID_HANDLE, 1419 "Unexpected behavior when making context current, ret %d, last error %#x.\n", ret, err); 1420 SetLastError(0xdeadbeef); 1421 ret = SwapBuffers(dc); 1422 err = GetLastError(); 1423 ok(!ret && err == ERROR_INVALID_HANDLE, "Unexpected behavior with SwapBuffer, last error %#x.\n", err); 1424 1425 ok(wglGetCurrentContext() == ctx, "Wrong current context.\n"); 1426 1427 glClear(GL_COLOR_BUFFER_BIT); 1428 glFinish(); 1429 glerr = glGetError(); 1430 ok(glerr == GL_NO_ERROR, "Failed glClear, error %#x.\n", glerr); 1431 SetLastError(0xdeadbeef); 1432 ret = SwapBuffers(dc); 1433 err = GetLastError(); 1434 ok(!ret && err == ERROR_INVALID_HANDLE, "Unexpected behavior with SwapBuffer, last error %#x.\n", err); 1435 1436 ret = wglMakeCurrent(NULL, NULL); 1437 ok(ret, "Failed to clear current context, last error %#x.\n", GetLastError()); 1438 1439 glClear(GL_COLOR_BUFFER_BIT); 1440 glFinish(); 1441 glerr = glGetError(); 1442 ok(glerr == GL_INVALID_OPERATION, "Failed glClear, error %#x.\n", glerr); 1443 SetLastError(0xdeadbeef); 1444 ret = SwapBuffers(dc); 1445 err = GetLastError(); 1446 ok(!ret && err == ERROR_INVALID_HANDLE, "Unexpected behavior with SwapBuffer, last error %#x.\n", err); 1447 1448 SetLastError(0xdeadbeef); 1449 ret = wglMakeCurrent(dc, ctx); 1450 err = GetLastError(); 1451 ok(!ret && err == ERROR_INVALID_HANDLE, 1452 "Unexpected behavior when making context current, ret %d, last error %#x.\n", ret, err); 1453 1454 ok(wglGetCurrentContext() == NULL, "Wrong current context.\n"); 1455 1456 ret = wglMakeCurrent(oldhdc, oldctx); 1457 ok(ret, "Failed to make context current, last error %#x.\n", GetLastError()); 1458 ok(wglGetCurrentContext() == oldctx, "Wrong current context.\n"); 1459 1460 SetLastError(0xdeadbeef); 1461 ret = wglMakeCurrent(dc, ctx); 1462 err = GetLastError(); 1463 ok(!ret && err == ERROR_INVALID_HANDLE, 1464 "Unexpected behavior when making context current, ret %d, last error %#x.\n", ret, err); 1465 1466 ok(wglGetCurrentContext() == oldctx, "Wrong current context.\n"); 1467 1468 ret = wglDeleteContext(ctx); 1469 ok(ret, "Failed to delete GL context, last error %#x.\n", GetLastError()); 1470 1471 ReleaseDC(window, dc); 1472 1473 ret = wglMakeCurrent(oldhdc, oldctx); 1474 ok(ret, "Failed to make context current, last error %#x.\n", GetLastError()); 1475 } 1476 1477 static void test_destroy_read(HDC oldhdc) 1478 { 1479 PIXELFORMATDESCRIPTOR pf_desc = 1480 { 1481 sizeof(PIXELFORMATDESCRIPTOR), 1482 1, /* version */ 1483 PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, 1484 PFD_TYPE_RGBA, 1485 24, /* 24-bit color depth */ 1486 0, 0, 0, 0, 0, 0, /* color bits */ 1487 0, /* alpha buffer */ 1488 0, /* shift bit */ 1489 0, /* accumulation buffer */ 1490 0, 0, 0, 0, /* accum bits */ 1491 32, /* z-buffer */ 1492 0, /* stencil buffer */ 1493 0, /* auxiliary buffer */ 1494 PFD_MAIN_PLANE, /* main layer */ 1495 0, /* reserved */ 1496 0, 0, 0 /* layer masks */ 1497 }; 1498 int pixel_format; 1499 HWND draw_window, read_window; 1500 HGLRC ctx; 1501 BOOL ret; 1502 HDC read_dc, draw_dc; 1503 GLenum glerr; 1504 DWORD err; 1505 HGLRC oldctx = wglGetCurrentContext(); 1506 1507 ok(!!oldctx, "Expected to find a valid current context\n"); 1508 1509 draw_window = CreateWindowA("static", "opengl32_test", 1510 WS_POPUP, 0, 0, 640, 480, 0, 0, 0, 0); 1511 ok(!!draw_window, "Failed to create window, last error %#x.\n", GetLastError()); 1512 1513 draw_dc = GetDC(draw_window); 1514 ok(!!draw_dc, "Failed to get DC.\n"); 1515 1516 pixel_format = ChoosePixelFormat(draw_dc, &pf_desc); 1517 if (!pixel_format) 1518 { 1519 win_skip("Failed to find pixel format.\n"); 1520 ReleaseDC(draw_window, draw_dc); 1521 DestroyWindow(draw_window); 1522 return; 1523 } 1524 1525 ret = SetPixelFormat(draw_dc, pixel_format, &pf_desc); 1526 ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError()); 1527 1528 read_window = CreateWindowA("static", "opengl32_test", 1529 WS_POPUP, 0, 0, 640, 480, 0, 0, 0, 0); 1530 ok(!!read_window, "Failed to create window, last error %#x.\n", GetLastError()); 1531 1532 read_dc = GetDC(read_window); 1533 ok(!!draw_dc, "Failed to get DC.\n"); 1534 1535 pixel_format = ChoosePixelFormat(read_dc, &pf_desc); 1536 if (!pixel_format) 1537 { 1538 win_skip("Failed to find pixel format.\n"); 1539 ReleaseDC(read_window, read_dc); 1540 DestroyWindow(read_window); 1541 ReleaseDC(draw_window, draw_dc); 1542 DestroyWindow(draw_window); 1543 return; 1544 } 1545 1546 ret = SetPixelFormat(read_dc, pixel_format, &pf_desc); 1547 ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError()); 1548 1549 ctx = wglCreateContext(draw_dc); 1550 ok(!!ctx, "Failed to create GL context, last error %#x.\n", GetLastError()); 1551 1552 ret = pwglMakeContextCurrentARB(draw_dc, read_dc, ctx); 1553 ok(ret, "Failed to make context current, last error %#x.\n", GetLastError()); 1554 1555 glCopyPixels(0, 0, 640, 480, GL_COLOR); 1556 glFinish(); 1557 glerr = glGetError(); 1558 ok(glerr == GL_NO_ERROR, "Failed glCopyPixel, error %#x.\n", glerr); 1559 ret = SwapBuffers(draw_dc); 1560 ok(ret, "Failed SwapBuffers, error %#x.\n", GetLastError()); 1561 1562 ret = DestroyWindow(read_window); 1563 ok(ret, "Failed to destroy window, last error %#x.\n", GetLastError()); 1564 1565 ok(wglGetCurrentContext() == ctx, "Wrong current context.\n"); 1566 1567 if (0) /* Crashes on AMD on Windows */ 1568 { 1569 glCopyPixels(0, 0, 640, 480, GL_COLOR); 1570 glFinish(); 1571 glerr = glGetError(); 1572 ok(glerr == GL_NO_ERROR, "Failed glCopyPixel, error %#x.\n", glerr); 1573 } 1574 1575 glClear(GL_COLOR_BUFFER_BIT); 1576 glFinish(); 1577 glerr = glGetError(); 1578 ok(glerr == GL_NO_ERROR, "Failed glClear, error %#x.\n", glerr); 1579 ret = SwapBuffers(draw_dc); 1580 ok(ret, "Failed SwapBuffers, error %#x.\n", GetLastError()); 1581 1582 ret = wglMakeCurrent(NULL, NULL); 1583 ok(ret, "Failed to clear current context, last error %#x.\n", GetLastError()); 1584 1585 if (0) /* This crashes with Nvidia drivers on Windows. */ 1586 { 1587 SetLastError(0xdeadbeef); 1588 ret = pwglMakeContextCurrentARB(draw_dc, read_dc, ctx); 1589 err = GetLastError(); 1590 ok(!ret && err == ERROR_INVALID_HANDLE, 1591 "Unexpected behavior when making context current, ret %d, last error %#x.\n", ret, err); 1592 } 1593 1594 ret = DestroyWindow(draw_window); 1595 ok(ret, "Failed to destroy window, last error %#x.\n", GetLastError()); 1596 1597 glClear(GL_COLOR_BUFFER_BIT); 1598 glFinish(); 1599 glerr = glGetError(); 1600 ok(glerr == GL_INVALID_OPERATION, "Failed glClear, error %#x.\n", glerr); 1601 SetLastError(0xdeadbeef); 1602 ret = SwapBuffers(draw_dc); 1603 err = GetLastError(); 1604 ok(!ret && err == ERROR_INVALID_HANDLE, "Unexpected behavior with SwapBuffer, last error %#x.\n", err); 1605 1606 SetLastError(0xdeadbeef); 1607 ret = pwglMakeContextCurrentARB(draw_dc, read_dc, ctx); 1608 err = GetLastError(); 1609 ok(!ret && (err == ERROR_INVALID_HANDLE || err == 0xc0070006), 1610 "Unexpected behavior when making context current, ret %d, last error %#x.\n", ret, err); 1611 1612 ok(wglGetCurrentContext() == NULL, "Wrong current context.\n"); 1613 1614 wglMakeCurrent(NULL, NULL); 1615 1616 wglMakeCurrent(oldhdc, oldctx); 1617 ok(wglGetCurrentContext() == oldctx, "Wrong current context.\n"); 1618 1619 SetLastError(0xdeadbeef); 1620 ret = pwglMakeContextCurrentARB(draw_dc, read_dc, ctx); 1621 err = GetLastError(); 1622 ok(!ret && (err == ERROR_INVALID_HANDLE || err == 0xc0070006), 1623 "Unexpected behavior when making context current, last error %#x.\n", err); 1624 1625 ok(wglGetCurrentContext() == oldctx, "Wrong current context.\n"); 1626 1627 ret = wglDeleteContext(ctx); 1628 ok(ret, "Failed to delete GL context, last error %#x.\n", GetLastError()); 1629 1630 ReleaseDC(read_window, read_dc); 1631 ReleaseDC(draw_window, draw_dc); 1632 1633 wglMakeCurrent(oldhdc, oldctx); 1634 } 1635 1636 static void test_swap_control(HDC oldhdc) 1637 { 1638 PIXELFORMATDESCRIPTOR pf_desc = 1639 { 1640 sizeof(PIXELFORMATDESCRIPTOR), 1641 1, /* version */ 1642 PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, 1643 PFD_TYPE_RGBA, 1644 24, /* 24-bit color depth */ 1645 0, 0, 0, 0, 0, 0, /* color bits */ 1646 0, /* alpha buffer */ 1647 0, /* shift bit */ 1648 0, /* accumulation buffer */ 1649 0, 0, 0, 0, /* accum bits */ 1650 32, /* z-buffer */ 1651 0, /* stencil buffer */ 1652 0, /* auxiliary buffer */ 1653 PFD_MAIN_PLANE, /* main layer */ 1654 0, /* reserved */ 1655 0, 0, 0 /* layer masks */ 1656 }; 1657 int pixel_format; 1658 HWND window1, window2, old_parent; 1659 HGLRC ctx1, ctx2, oldctx; 1660 BOOL ret; 1661 HDC dc1, dc2; 1662 int interval; 1663 1664 oldctx = wglGetCurrentContext(); 1665 ok(!!oldctx, "Expected to find a valid current context.\n"); 1666 1667 window1 = CreateWindowA("static", "opengl32_test", 1668 WS_POPUP, 0, 0, 640, 480, 0, 0, 0, 0); 1669 ok(!!window1, "Failed to create window1, last error %#x.\n", GetLastError()); 1670 1671 dc1 = GetDC(window1); 1672 ok(!!dc1, "Failed to get DC.\n"); 1673 1674 pixel_format = ChoosePixelFormat(dc1, &pf_desc); 1675 if (!pixel_format) 1676 { 1677 win_skip("Failed to find pixel format.\n"); 1678 ReleaseDC(window1, dc1); 1679 DestroyWindow(window1); 1680 return; 1681 } 1682 1683 ret = SetPixelFormat(dc1, pixel_format, &pf_desc); 1684 ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError()); 1685 1686 ctx1 = wglCreateContext(dc1); 1687 ok(!!ctx1, "Failed to create GL context, last error %#x.\n", GetLastError()); 1688 1689 ret = wglMakeCurrent(dc1, ctx1); 1690 ok(ret, "Failed to make context current, last error %#x.\n", GetLastError()); 1691 1692 interval = pwglGetSwapIntervalEXT(); 1693 ok(interval == 1, "Expected default swap interval 1, got %d\n", interval); 1694 1695 ret = pwglSwapIntervalEXT(0); 1696 ok(ret, "Failed to set swap interval to 0, last error %#x.\n", GetLastError()); 1697 1698 interval = pwglGetSwapIntervalEXT(); 1699 ok(interval == 0, "Expected swap interval 0, got %d\n", interval); 1700 1701 /* Check what interval we get on a second context on the same drawable.*/ 1702 ctx2 = wglCreateContext(dc1); 1703 ok(!!ctx2, "Failed to create GL context, last error %#x.\n", GetLastError()); 1704 1705 ret = wglMakeCurrent(dc1, ctx2); 1706 ok(ret, "Failed to make context current, last error %#x.\n", GetLastError()); 1707 1708 interval = pwglGetSwapIntervalEXT(); 1709 ok(interval == 0, "Expected swap interval 0, got %d\n", interval); 1710 1711 /* A second window is created to see whether its swap interval was affected 1712 * by previous calls. 1713 */ 1714 window2 = CreateWindowA("static", "opengl32_test", 1715 WS_POPUP, 0, 0, 640, 480, 0, 0, 0, 0); 1716 ok(!!window2, "Failed to create window2, last error %#x.\n", GetLastError()); 1717 1718 dc2 = GetDC(window2); 1719 ok(!!dc2, "Failed to get DC.\n"); 1720 1721 ret = SetPixelFormat(dc2, pixel_format, &pf_desc); 1722 ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError()); 1723 1724 ret = wglMakeCurrent(dc2, ctx1); 1725 ok(ret, "Failed to make context current, last error %#x.\n", GetLastError()); 1726 1727 /* Since the second window lacks the swap interval, this proves that the interval 1728 * is not global or shared among contexts. 1729 */ 1730 interval = pwglGetSwapIntervalEXT(); 1731 ok(interval == 1, "Expected default swap interval 1, got %d\n", interval); 1732 1733 /* Test if setting the parent of a window resets the swap interval. */ 1734 ret = wglMakeCurrent(dc1, ctx1); 1735 ok(ret, "Failed to make context current, last error %#x.\n", GetLastError()); 1736 1737 old_parent = SetParent(window1, window2); 1738 ok(!!old_parent, "Failed to make window1 a child of window2, last error %#x.\n", GetLastError()); 1739 1740 interval = pwglGetSwapIntervalEXT(); 1741 ok(interval == 0, "Expected swap interval 0, got %d\n", interval); 1742 1743 ret = wglDeleteContext(ctx1); 1744 ok(ret, "Failed to delete GL context, last error %#x.\n", GetLastError()); 1745 ret = wglDeleteContext(ctx2); 1746 ok(ret, "Failed to delete GL context, last error %#x.\n", GetLastError()); 1747 1748 ReleaseDC(window1, dc1); 1749 DestroyWindow(window1); 1750 ReleaseDC(window2, dc2); 1751 DestroyWindow(window2); 1752 1753 wglMakeCurrent(oldhdc, oldctx); 1754 } 1755 1756 START_TEST(opengl) 1757 { 1758 HWND hwnd; 1759 PIXELFORMATDESCRIPTOR pfd = { 1760 sizeof(PIXELFORMATDESCRIPTOR), 1761 1, /* version */ 1762 PFD_DRAW_TO_WINDOW | 1763 PFD_SUPPORT_OPENGL | 1764 PFD_DOUBLEBUFFER, 1765 PFD_TYPE_RGBA, 1766 24, /* 24-bit color depth */ 1767 0, 0, 0, 0, 0, 0, /* color bits */ 1768 0, /* alpha buffer */ 1769 0, /* shift bit */ 1770 0, /* accumulation buffer */ 1771 0, 0, 0, 0, /* accum bits */ 1772 32, /* z-buffer */ 1773 0, /* stencil buffer */ 1774 0, /* auxiliary buffer */ 1775 PFD_MAIN_PLANE, /* main layer */ 1776 0, /* reserved */ 1777 0, 0, 0 /* layer masks */ 1778 }; 1779 1780 hwnd = CreateWindowA("static", "Title", WS_OVERLAPPEDWINDOW, 10, 10, 200, 200, NULL, NULL, 1781 NULL, NULL); 1782 ok(hwnd != NULL, "err: %d\n", GetLastError()); 1783 if (hwnd) 1784 { 1785 HDC hdc; 1786 int iPixelFormat, res; 1787 HGLRC hglrc; 1788 DWORD error; 1789 ShowWindow(hwnd, SW_SHOW); 1790 1791 hdc = GetDC(hwnd); 1792 1793 iPixelFormat = ChoosePixelFormat(hdc, &pfd); 1794 if(iPixelFormat == 0) 1795 { 1796 /* This should never happen as ChoosePixelFormat always returns a closest match, but currently this fails in Wine if we don't have glX */ 1797 win_skip("Unable to find pixel format.\n"); 1798 goto cleanup; 1799 } 1800 1801 /* We shouldn't be able to create a context from a hdc which doesn't have a pixel format set */ 1802 hglrc = wglCreateContext(hdc); 1803 ok(hglrc == NULL, "wglCreateContext should fail when no pixel format has been set, but it passed\n"); 1804 error = GetLastError(); 1805 ok(error == ERROR_INVALID_PIXEL_FORMAT, "expected ERROR_INVALID_PIXEL_FORMAT for wglCreateContext without a pixelformat set, but received %#x\n", error); 1806 1807 res = SetPixelFormat(hdc, iPixelFormat, &pfd); 1808 ok(res, "SetPixelformat failed: %x\n", GetLastError()); 1809 1810 test_bitmap_rendering( TRUE ); 1811 test_bitmap_rendering( FALSE ); 1812 test_minimized(); 1813 test_window_dc(); 1814 test_message_window(); 1815 test_dc(hwnd, hdc); 1816 1817 ok(!glGetString(GL_RENDERER) && !glGetString(GL_VERSION) && !glGetString(GL_VENDOR), 1818 "Expected NULL string when no active context is set\n"); 1819 hglrc = wglCreateContext(hdc); 1820 res = wglMakeCurrent(hdc, hglrc); 1821 ok(res, "wglMakeCurrent failed!\n"); 1822 if(res) 1823 { 1824 trace("OpenGL renderer: %s\n", glGetString(GL_RENDERER)); 1825 trace("OpenGL driver version: %s\n", glGetString(GL_VERSION)); 1826 trace("OpenGL vendor: %s\n", glGetString(GL_VENDOR)); 1827 } 1828 else 1829 { 1830 skip("Skipping OpenGL tests without a current context\n"); 1831 return; 1832 } 1833 1834 /* Initialisation of WGL functions depends on an implicit WGL context. For this reason we can't load them before making 1835 * any WGL call :( On Wine this would work but not on real Windows because there can be different implementations (software, ICD, MCD). 1836 */ 1837 init_functions(); 1838 test_getprocaddress(hdc); 1839 test_deletecontext(hwnd, hdc); 1840 test_makecurrent(hdc); 1841 1842 /* The lack of wglGetExtensionsStringARB in general means broken software rendering or the lack of decent OpenGL support, skip tests in such cases */ 1843 if (!pwglGetExtensionsStringARB) 1844 { 1845 win_skip("wglGetExtensionsStringARB is not available\n"); 1846 return; 1847 } 1848 1849 test_choosepixelformat(); 1850 test_debug_message_callback(); 1851 test_setpixelformat(hdc); 1852 test_destroy(hdc); 1853 test_sharelists(hdc); 1854 test_colorbits(hdc); 1855 test_gdi_dbuf(hdc); 1856 test_acceleration(hdc); 1857 1858 wgl_extensions = pwglGetExtensionsStringARB(hdc); 1859 if(wgl_extensions == NULL) skip("Skipping opengl32 tests because this OpenGL implementation doesn't support WGL extensions!\n"); 1860 1861 if(strstr(wgl_extensions, "WGL_ARB_create_context")) 1862 test_opengl3(hdc); 1863 1864 if(strstr(wgl_extensions, "WGL_ARB_make_current_read")) 1865 { 1866 test_make_current_read(hdc); 1867 test_destroy_read(hdc); 1868 } 1869 else 1870 skip("WGL_ARB_make_current_read not supported, skipping test\n"); 1871 1872 if(strstr(wgl_extensions, "WGL_ARB_pbuffer")) 1873 test_pbuffers(hdc); 1874 else 1875 skip("WGL_ARB_pbuffer not supported, skipping pbuffer test\n"); 1876 1877 if(strstr(wgl_extensions, "WGL_EXT_swap_control")) 1878 test_swap_control(hdc); 1879 else 1880 skip("WGL_EXT_swap_control not supported, skipping test\n"); 1881 1882 cleanup: 1883 ReleaseDC(hwnd, hdc); 1884 DestroyWindow(hwnd); 1885 } 1886 } 1887