Author: jgardou Date: Sun Aug 26 09:17:35 2012 New Revision: 57160
URL: http://svn.reactos.org/svn/reactos?rev=57160&view=rev Log: [OPENGL32_WINETEST] - Sync with wine
Modified: trunk/rostests/winetests/opengl32/opengl.c
Modified: trunk/rostests/winetests/opengl32/opengl.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/opengl32/opengl.... ============================================================================== --- trunk/rostests/winetests/opengl32/opengl.c [iso-8859-1] (original) +++ trunk/rostests/winetests/opengl32/opengl.c [iso-8859-1] Sun Aug 26 09:17:35 2012 @@ -24,18 +24,29 @@
void WINAPI glClearColor(float red, float green, float blue, float alpha); void WINAPI glClear(unsigned int mask); +#define GL_COLOR 0x1800 +typedef unsigned int GLenum; +typedef int GLint; +void WINAPI glCopyPixels(int x, int y, int width, int height, GLenum type); void WINAPI glFinish(void); +#define GL_NO_ERROR 0x0 +#define GL_INVALID_OPERATION 0x502 +GLenum WINAPI glGetError(void); #define GL_COLOR_BUFFER_BIT 0x00004000 const unsigned char * WINAPI glGetString(unsigned int); #define GL_VENDOR 0x1F00 #define GL_RENDERER 0x1F01 #define GL_VERSION 0x1F02 +#define GL_EXTENSIONS 0x1F03 + +#define GL_VIEWPORT 0x0ba2 +void WINAPI glGetIntegerv(GLenum pname, GLint *params);
#define MAX_FORMATS 256 typedef void* HPBUFFERARB;
/* WGL_ARB_create_context */ -HGLRC (WINAPI *pwglCreateContextAttribsARB)(HDC hDC, HGLRC hShareContext, const int *attribList); +static HGLRC (WINAPI *pwglCreateContextAttribsARB)(HDC hDC, HGLRC hShareContext, const int *attribList); /* GetLastError */ #define ERROR_INVALID_VERSION_ARB 0x2095 #define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 @@ -106,6 +117,33 @@ #undef GET_PROC }
+static BOOL gl_extension_supported(const char *extensions, const char *extension_string) +{ + size_t ext_str_len = strlen(extension_string); + + while (*extensions) + { + const char *start; + size_t len; + + while (isspace(*extensions)) + ++extensions; + start = extensions; + while (!isspace(*extensions) && *extensions) + ++extensions; + + len = extensions - start; + if (!len) + continue; + + if (len == ext_str_len && !memcmp(start, extension_string, ext_str_len)) + { + return TRUE; + } + } + return FALSE; +} + static void test_pbuffers(HDC hdc) { const int iAttribList[] = { WGL_DRAW_TO_PBUFFER_ARB, 1, /* Request pbuffer support */ @@ -171,7 +209,7 @@ trace("iPixelFormat returned by GetPixelFormat: %d\n", res); trace("PixelFormat from wglChoosePixelFormatARB: %d\n", iPixelFormat);
- pwglReleasePbufferDCARB(pbuffer, hdc); + pwglReleasePbufferDCARB(pbuffer, pbuffer_hdc); } else skip("Pbuffer test for onscreen pixelformat skipped as no onscreen format with pbuffer capabilities have been found\n");
@@ -351,7 +389,6 @@ { BOOL ret; HGLRC hglrc; - DWORD error;
hglrc = wglCreateContext(winhdc); ok( hglrc != 0, "wglCreateContext failed\n" ); @@ -374,9 +411,9 @@
SetLastError( 0xdeadbeef ); ret = wglMakeCurrent( NULL, NULL ); - ok( !ret, "wglMakeCurrent succeeded\n" ); - error = GetLastError(); - ok( error == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got error=%x\n", error); + ok( !ret || broken(ret) /* nt4 */, "wglMakeCurrent succeeded\n" ); + if (!ret) ok( GetLastError() == ERROR_INVALID_HANDLE, + "Expected ERROR_INVALID_HANDLE, got error=%x\n", GetLastError() );
ret = wglMakeCurrent( winhdc, NULL ); ok( ret, "wglMakeCurrent failed\n" ); @@ -387,11 +424,13 @@ ret = wglMakeCurrent( NULL, NULL ); ok( ret, "wglMakeCurrent failed\n" );
+ ok( wglGetCurrentContext() == NULL, "wrong context\n" ); + SetLastError( 0xdeadbeef ); ret = wglMakeCurrent( NULL, NULL ); - ok( !ret, "wglMakeCurrent succeeded\n" ); - error = GetLastError(); - ok( error == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got error=%x\n", error); + ok( !ret || broken(ret) /* nt4 */, "wglMakeCurrent succeeded\n" ); + if (!ret) ok( GetLastError() == ERROR_INVALID_HANDLE, + "Expected ERROR_INVALID_HANDLE, got error=%x\n", GetLastError() );
ret = wglMakeCurrent( winhdc, hglrc ); ok( ret, "wglMakeCurrent failed\n" ); @@ -504,36 +543,48 @@ } }
-static void test_bitmap_rendering(void) +static void test_bitmap_rendering( BOOL use_dib ) { PIXELFORMATDESCRIPTOR pfd; - int i, iPixelFormat=0; + int i, ret, bpp, iPixelFormat=0; unsigned int nFormats; - HGLRC hglrc; + HGLRC hglrc, hglrc2; BITMAPINFO biDst; - HBITMAP bmpDst, oldDst; + HBITMAP bmpDst, oldDst, bmp2; HDC hdcDst, hdcScreen; - UINT32 *dstBuffer; - - memset(&biDst, 0, sizeof(BITMAPINFO)); - biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - biDst.bmiHeader.biWidth = 2; - biDst.bmiHeader.biHeight = -2; - biDst.bmiHeader.biPlanes = 1; - biDst.bmiHeader.biBitCount = 32; - biDst.bmiHeader.biCompression = BI_RGB; + UINT *dstBuffer = NULL;
hdcScreen = CreateCompatibleDC(0); - if(GetDeviceCaps(hdcScreen, BITSPIXEL) != 32) - { - DeleteDC(hdcScreen); - trace("Skipping bitmap rendering test\n"); - return; - } - - hdcDst = CreateCompatibleDC(hdcScreen); - bmpDst = CreateDIBSection(hdcDst, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer, NULL, 0); + hdcDst = CreateCompatibleDC(0); + + if (use_dib) + { + bpp = 32; + memset(&biDst, 0, sizeof(BITMAPINFO)); + biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + biDst.bmiHeader.biWidth = 4; + biDst.bmiHeader.biHeight = -4; + biDst.bmiHeader.biPlanes = 1; + biDst.bmiHeader.biBitCount = 32; + biDst.bmiHeader.biCompression = BI_RGB; + + bmpDst = CreateDIBSection(0, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer, NULL, 0); + + biDst.bmiHeader.biWidth = 12; + biDst.bmiHeader.biHeight = -12; + biDst.bmiHeader.biBitCount = 16; + bmp2 = CreateDIBSection(0, &biDst, DIB_RGB_COLORS, NULL, NULL, 0); + } + else + { + bpp = GetDeviceCaps( hdcScreen, BITSPIXEL ); + bmpDst = CreateBitmap( 4, 4, 1, bpp, NULL ); + bmp2 = CreateBitmap( 12, 12, 1, bpp, NULL ); + } + oldDst = SelectObject(hdcDst, bmpDst); + + trace( "testing on %s\n", use_dib ? "DIB" : "DDB" );
/* Pick a pixel format by hand because ChoosePixelFormat is unreliable */ nFormats = DescribePixelFormat(hdcDst, 0, 0, NULL); @@ -544,7 +595,7 @@
if((pfd.dwFlags & PFD_DRAW_TO_BITMAP) && (pfd.dwFlags & PFD_SUPPORT_OPENGL) && - (pfd.cColorBits == 32) && + (pfd.cColorBits == bpp) && (pfd.cAlphaBits == 8) ) { iPixelFormat = i; @@ -558,58 +609,126 @@ } else { - SetPixelFormat(hdcDst, iPixelFormat, &pfd); + ret = SetPixelFormat(hdcDst, iPixelFormat, &pfd); + ok( ret, "SetPixelFormat failed\n" ); + ret = GetPixelFormat( hdcDst ); + ok( ret == iPixelFormat, "GetPixelFormat returned %d/%d\n", ret, iPixelFormat ); + ret = SetPixelFormat(hdcDst, iPixelFormat + 1, &pfd); + ok( !ret, "SetPixelFormat succeeded\n" ); hglrc = wglCreateContext(hdcDst); - todo_wine ok(hglrc != NULL, "Unable to create a context\n"); + ok(hglrc != NULL, "Unable to create a context\n");
if(hglrc) { + GLint viewport[4]; wglMakeCurrent(hdcDst, hglrc); + hglrc2 = wglCreateContext(hdcDst); + ok(hglrc2 != NULL, "Unable to create a context\n");
/* Note this is RGBA but we read ARGB back */ glClearColor((float)0x22/0xff, (float)0x33/0xff, (float)0x44/0xff, (float)0x11/0xff); glClear(GL_COLOR_BUFFER_BIT); + glGetIntegerv( GL_VIEWPORT, viewport ); glFinish();
+ ok( viewport[0] == 0 && viewport[1] == 0 && viewport[2] == 4 && viewport[3] == 4, + "wrong viewport %d,%d,%d,%d\n", viewport[0], viewport[1], viewport[2], viewport[3] ); /* Note apparently the alpha channel is not supported by the software renderer (bitmap only works using software) */ - ok(dstBuffer[0] == 0x223344, "Expected color=0x223344, received color=%x\n", dstBuffer[0]); + if (dstBuffer) + for (i = 0; i < 16; i++) + ok(dstBuffer[i] == 0x223344 || dstBuffer[i] == 0x11223344, "Received color=%x at %u\n", + dstBuffer[i], i); + + SelectObject(hdcDst, bmp2); + ret = GetPixelFormat( hdcDst ); + ok( ret == iPixelFormat, "GetPixelFormat returned %d/%d\n", ret, iPixelFormat ); + ret = SetPixelFormat(hdcDst, iPixelFormat + 1, &pfd); + ok( !ret, "SetPixelFormat succeeded\n" ); + + /* context still uses the old pixel format and viewport */ + glClearColor((float)0x44/0xff, (float)0x33/0xff, (float)0x22/0xff, (float)0x11/0xff); + glClear(GL_COLOR_BUFFER_BIT); + glFinish(); + glGetIntegerv( GL_VIEWPORT, viewport ); + ok( viewport[0] == 0 && viewport[1] == 0 && viewport[2] == 4 && viewport[3] == 4, + "wrong viewport %d,%d,%d,%d\n", viewport[0], viewport[1], viewport[2], viewport[3] );
wglMakeCurrent(NULL, NULL); - wglDeleteContext(hglrc); + wglMakeCurrent(hdcDst, hglrc); + glClearColor((float)0x44/0xff, (float)0x55/0xff, (float)0x66/0xff, (float)0x11/0xff); + glClear(GL_COLOR_BUFFER_BIT); + glFinish(); + glGetIntegerv( GL_VIEWPORT, viewport ); + ok( viewport[0] == 0 && viewport[1] == 0 && viewport[2] == 4 && viewport[3] == 4, + "wrong viewport %d,%d,%d,%d\n", viewport[0], viewport[1], viewport[2], viewport[3] ); + + wglMakeCurrent(hdcDst, hglrc2); + glGetIntegerv( GL_VIEWPORT, viewport ); + ok( viewport[0] == 0 && viewport[1] == 0 && viewport[2] == 12 && viewport[3] == 12, + "wrong viewport %d,%d,%d,%d\n", viewport[0], viewport[1], viewport[2], viewport[3] ); + + wglMakeCurrent(hdcDst, hglrc); + glGetIntegerv( GL_VIEWPORT, viewport ); + ok( viewport[0] == 0 && viewport[1] == 0 && viewport[2] == 4 && viewport[3] == 4, + "wrong viewport %d,%d,%d,%d\n", viewport[0], viewport[1], viewport[2], viewport[3] ); + + SelectObject(hdcDst, bmpDst); + ret = GetPixelFormat( hdcDst ); + ok( ret == iPixelFormat, "GetPixelFormat returned %d/%d\n", ret, iPixelFormat ); + ret = SetPixelFormat(hdcDst, iPixelFormat + 1, &pfd); + ok( !ret, "SetPixelFormat succeeded\n" ); + wglMakeCurrent(hdcDst, hglrc2); + glGetIntegerv( GL_VIEWPORT, viewport ); + ok( viewport[0] == 0 && viewport[1] == 0 && viewport[2] == 12 && viewport[3] == 12, + "wrong viewport %d,%d,%d,%d\n", viewport[0], viewport[1], viewport[2], viewport[3] ); } }
SelectObject(hdcDst, oldDst); + DeleteObject(bmp2); DeleteObject(bmpDst); DeleteDC(hdcDst); - DeleteDC(hdcScreen); }
struct wgl_thread_param { HANDLE test_finished; + HWND hwnd; HGLRC hglrc; - BOOL hglrc_deleted; + BOOL make_current; + BOOL make_current_error; + BOOL deleted; + DWORD deleted_error; };
static DWORD WINAPI wgl_thread(void *param) { struct wgl_thread_param *p = param; - - p->hglrc_deleted = wglDeleteContext(p->hglrc); + HDC hdc = GetDC( p->hwnd ); + + SetLastError(0xdeadbeef); + p->make_current = wglMakeCurrent(hdc, p->hglrc); + p->make_current_error = GetLastError(); + p->deleted = wglDeleteContext(p->hglrc); + p->deleted_error = GetLastError(); + ReleaseDC( p->hwnd, hdc ); SetEvent(p->test_finished); - return 0; }
-static void test_deletecontext(HDC hdc) +static void test_deletecontext(HWND hwnd, HDC hdc) { struct wgl_thread_param thread_params; HGLRC hglrc = wglCreateContext(hdc); HANDLE thread_handle; DWORD res, tid;
+ SetLastError(0xdeadbeef); + res = wglDeleteContext(NULL); + ok(res == FALSE, "wglDeleteContext succeeded\n"); + ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected last error to be ERROR_INVALID_HANDLE, got %u\n", GetLastError()); + if(!hglrc) { skip("wglCreateContext failed!\n"); @@ -627,23 +746,79 @@ * This differs from GLX which does allow it but it delays actual deletion until the context becomes not current. */ thread_params.hglrc = hglrc; + thread_params.hwnd = hwnd; thread_params.test_finished = CreateEvent(NULL, FALSE, FALSE, NULL); thread_handle = CreateThread(NULL, 0, wgl_thread, &thread_params, 0, &tid); ok(!!thread_handle, "Failed to create thread, last error %#x.\n", GetLastError()); if(thread_handle) { WaitForSingleObject(thread_handle, INFINITE); - ok(thread_params.hglrc_deleted == FALSE, "Attempt to delete WGL context from another thread passed but should fail!\n"); + ok(!thread_params.make_current, "Attempt to make WGL context from another thread passed\n"); + ok(thread_params.make_current_error == ERROR_BUSY, "Expected last error to be ERROR_BUSY, got %u\n", thread_params.make_current_error); + ok(!thread_params.deleted, "Attempt to delete WGL context from another thread passed\n"); + ok(thread_params.deleted_error == ERROR_BUSY, "Expected last error to be ERROR_BUSY, got %u\n", thread_params.deleted_error); } CloseHandle(thread_params.test_finished);
res = wglDeleteContext(hglrc); ok(res == TRUE, "wglDeleteContext failed\n"); + + /* Attempting to delete the same context twice should fail. */ + SetLastError(0xdeadbeef); + res = wglDeleteContext(hglrc); + ok(res == FALSE, "wglDeleteContext succeeded\n"); + ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected last error to be ERROR_INVALID_HANDLE, got %u\n", GetLastError());
/* WGL makes a context not current when deleting it. This differs from GLX behavior where * deletion takes place when the thread becomes not current. */ hglrc = wglGetCurrentContext(); ok(hglrc == NULL, "A WGL context is active while none was expected\n"); +} + + +static void test_getprocaddress(HDC hdc) +{ + const char *extensions = (const char*)glGetString(GL_EXTENSIONS); + PROC func = NULL; + HGLRC ctx = wglGetCurrentContext(); + + if (!extensions) + { + skip("skipping wglGetProcAddress tests because no GL extensions supported\n"); + return; + } + + /* Core GL 1.0/1.1 functions should not be loadable through wglGetProcAddress. + * Try to load the function with and without a context. + */ + func = wglGetProcAddress("glEnable"); + ok(func == NULL, "Lookup of function glEnable with a context passed, expected a failure\n"); + wglMakeCurrent(hdc, NULL); + func = wglGetProcAddress("glEnable"); + ok(func == NULL, "Lookup of function glEnable without a context passed, expected a failure\n"); + wglMakeCurrent(hdc, ctx); + + /* The goal of the test will be to test behavior of wglGetProcAddress when + * no WGL context is active. Before the test we pick an extension (GL_ARB_multitexture) + * which any GL >=1.2.1 implementation supports. Unfortunately the GDI renderer doesn't + * support it. There aren't any extensions we can use for this test which are supported by + * both GDI and real drivers. + * Note GDI only has GL_EXT_bgra, GL_EXT_paletted_texture and GL_WIN_swap_hint. + */ + if (!gl_extension_supported(extensions, "GL_ARB_multitexture")) + { + skip("skipping test because lack of GL_ARB_multitexture support\n"); + return; + } + + func = wglGetProcAddress("glActiveTextureARB"); + ok(func != NULL, "Unable to lookup glActiveTextureARB, last error %#x\n", GetLastError()); + + /* Temporarily disable the context, so we can see that we can't retrieve functions now. */ + wglMakeCurrent(hdc, NULL); + func = wglGetProcAddress("glActiveTextureARB"); + ok(func == NULL, "Function lookup without a context passed, expected a failure; last error %#x\n", GetLastError()); + wglMakeCurrent(hdc, ctx); }
static void test_make_current_read(HDC hdc) @@ -730,7 +905,7 @@ HGLRC gl3Ctx; DWORD error; gl3Ctx = pwglCreateContextAttribsARB(hdc, (HGLRC)0xdeadbeef, 0); - todo_wine ok(gl3Ctx == 0, "pwglCreateContextAttribsARB using an invalid shareList passed\n"); + ok(gl3Ctx == 0, "pwglCreateContextAttribsARB using an invalid shareList passed\n"); error = GetLastError(); /* The Nvidia implementation seems to return hresults instead of win32 error codes */ todo_wine ok(error == ERROR_INVALID_OPERATION || @@ -866,6 +1041,365 @@ DestroyWindow(window); }
+static void test_window_dc(void) +{ + PIXELFORMATDESCRIPTOR pf_desc = + { + sizeof(PIXELFORMATDESCRIPTOR), + 1, /* version */ + PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, + PFD_TYPE_RGBA, + 24, /* 24-bit color depth */ + 0, 0, 0, 0, 0, 0, /* color bits */ + 0, /* alpha buffer */ + 0, /* shift bit */ + 0, /* accumulation buffer */ + 0, 0, 0, 0, /* accum bits */ + 32, /* z-buffer */ + 0, /* stencil buffer */ + 0, /* auxiliary buffer */ + PFD_MAIN_PLANE, /* main layer */ + 0, /* reserved */ + 0, 0, 0 /* layer masks */ + }; + int pixel_format; + HWND window; + RECT vp, r; + HGLRC ctx; + BOOL ret; + HDC dc; + + window = CreateWindowA("static", "opengl32_test", + WS_OVERLAPPEDWINDOW, 0, 0, 640, 480, 0, 0, 0, 0); + ok(!!window, "Failed to create window, last error %#x.\n", GetLastError()); + + ShowWindow(window, SW_SHOW); + + dc = GetWindowDC(window); + ok(!!dc, "Failed to get DC.\n"); + + pixel_format = ChoosePixelFormat(dc, &pf_desc); + if (!pixel_format) + { + win_skip("Failed to find pixel format.\n"); + ReleaseDC(window, dc); + DestroyWindow(window); + return; + } + + ret = SetPixelFormat(dc, pixel_format, &pf_desc); + ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError()); + + ctx = wglCreateContext(dc); + ok(!!ctx, "Failed to create GL context, last error %#x.\n", GetLastError()); + + ret = wglMakeCurrent(dc, ctx); + ok(ret, "Failed to make context current, last error %#x.\n", GetLastError()); + + GetClientRect(window, &r); + glGetIntegerv(GL_VIEWPORT, (GLint *)&vp); + ok(EqualRect(&r, &vp), "Viewport not equal to client rect.\n"); + + ret = wglMakeCurrent(NULL, NULL); + ok(ret, "Failed to clear current context, last error %#x.\n", GetLastError()); + + ret = wglDeleteContext(ctx); + ok(ret, "Failed to delete GL context, last error %#x.\n", GetLastError()); + + ReleaseDC(window, dc); + DestroyWindow(window); +} + +static void test_destroy(HDC oldhdc) +{ + PIXELFORMATDESCRIPTOR pf_desc = + { + sizeof(PIXELFORMATDESCRIPTOR), + 1, /* version */ + PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, + PFD_TYPE_RGBA, + 24, /* 24-bit color depth */ + 0, 0, 0, 0, 0, 0, /* color bits */ + 0, /* alpha buffer */ + 0, /* shift bit */ + 0, /* accumulation buffer */ + 0, 0, 0, 0, /* accum bits */ + 32, /* z-buffer */ + 0, /* stencil buffer */ + 0, /* auxiliary buffer */ + PFD_MAIN_PLANE, /* main layer */ + 0, /* reserved */ + 0, 0, 0 /* layer masks */ + }; + int pixel_format; + HWND window; + HGLRC ctx; + BOOL ret; + HDC dc; + GLenum glerr; + DWORD err; + HGLRC oldctx = wglGetCurrentContext(); + + ok(!!oldctx, "Expected to find a valid current context.\n"); + + window = CreateWindowA("static", "opengl32_test", + WS_POPUP, 0, 0, 640, 480, 0, 0, 0, 0); + ok(!!window, "Failed to create window, last error %#x.\n", GetLastError()); + + dc = GetDC(window); + ok(!!dc, "Failed to get DC.\n"); + + pixel_format = ChoosePixelFormat(dc, &pf_desc); + if (!pixel_format) + { + win_skip("Failed to find pixel format.\n"); + ReleaseDC(window, dc); + DestroyWindow(window); + return; + } + + ret = SetPixelFormat(dc, pixel_format, &pf_desc); + ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError()); + + ctx = wglCreateContext(dc); + ok(!!ctx, "Failed to create GL context, last error %#x.\n", GetLastError()); + + ret = wglMakeCurrent(dc, ctx); + ok(ret, "Failed to make context current, last error %#x.\n", GetLastError()); + + glClear(GL_COLOR_BUFFER_BIT); + glFinish(); + glerr = glGetError(); + ok(glerr == GL_NO_ERROR, "Failed glClear, error %#x.\n", glerr); + ret = SwapBuffers(dc); + ok(ret, "Failed SwapBuffers, error %#x.\n", GetLastError()); + + ret = DestroyWindow(window); + ok(ret, "Failed to destroy window, last error %#x.\n", GetLastError()); + + ok(wglGetCurrentContext() == ctx, "Wrong current context.\n"); + + SetLastError(0xdeadbeef); + ret = wglMakeCurrent(dc, ctx); + err = GetLastError(); + ok(!ret && err == ERROR_INVALID_HANDLE, + "Unexpected behavior when making context current, ret %d, last error %#x.\n", ret, err); + SetLastError(0xdeadbeef); + ret = SwapBuffers(dc); + err = GetLastError(); + ok(!ret && err == ERROR_INVALID_HANDLE, "Unexpected behavior with SwapBuffer, last error %#x.\n", err); + + ok(wglGetCurrentContext() == ctx, "Wrong current context.\n"); + + glClear(GL_COLOR_BUFFER_BIT); + glFinish(); + glerr = glGetError(); + ok(glerr == GL_NO_ERROR, "Failed glClear, error %#x.\n", glerr); + SetLastError(0xdeadbeef); + ret = SwapBuffers(dc); + err = GetLastError(); + ok(!ret && err == ERROR_INVALID_HANDLE, "Unexpected behavior with SwapBuffer, last error %#x.\n", err); + + ret = wglMakeCurrent(NULL, NULL); + ok(ret, "Failed to clear current context, last error %#x.\n", GetLastError()); + + glClear(GL_COLOR_BUFFER_BIT); + glFinish(); + glerr = glGetError(); + ok(glerr == GL_INVALID_OPERATION, "Failed glClear, error %#x.\n", glerr); + SetLastError(0xdeadbeef); + ret = SwapBuffers(dc); + err = GetLastError(); + ok(!ret && err == ERROR_INVALID_HANDLE, "Unexpected behavior with SwapBuffer, last error %#x.\n", err); + + SetLastError(0xdeadbeef); + ret = wglMakeCurrent(dc, ctx); + err = GetLastError(); + ok(!ret && err == ERROR_INVALID_HANDLE, + "Unexpected behavior when making context current, ret %d, last error %#x.\n", ret, err); + + ok(wglGetCurrentContext() == NULL, "Wrong current context.\n"); + + ret = wglMakeCurrent(oldhdc, oldctx); + ok(ret, "Failed to make context current, last error %#x.\n", GetLastError()); + ok(wglGetCurrentContext() == oldctx, "Wrong current context.\n"); + + SetLastError(0xdeadbeef); + ret = wglMakeCurrent(dc, ctx); + err = GetLastError(); + ok(!ret && err == ERROR_INVALID_HANDLE, + "Unexpected behavior when making context current, ret %d, last error %#x.\n", ret, err); + + ok(wglGetCurrentContext() == oldctx, "Wrong current context.\n"); + + ret = wglDeleteContext(ctx); + ok(ret, "Failed to delete GL context, last error %#x.\n", GetLastError()); + + ReleaseDC(window, dc); + + ret = wglMakeCurrent(oldhdc, oldctx); + ok(ret, "Failed to make context current, last error %#x.\n", GetLastError()); +} + +static void test_destroy_read(HDC oldhdc) +{ + PIXELFORMATDESCRIPTOR pf_desc = + { + sizeof(PIXELFORMATDESCRIPTOR), + 1, /* version */ + PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, + PFD_TYPE_RGBA, + 24, /* 24-bit color depth */ + 0, 0, 0, 0, 0, 0, /* color bits */ + 0, /* alpha buffer */ + 0, /* shift bit */ + 0, /* accumulation buffer */ + 0, 0, 0, 0, /* accum bits */ + 32, /* z-buffer */ + 0, /* stencil buffer */ + 0, /* auxiliary buffer */ + PFD_MAIN_PLANE, /* main layer */ + 0, /* reserved */ + 0, 0, 0 /* layer masks */ + }; + int pixel_format; + HWND draw_window, read_window; + HGLRC ctx; + BOOL ret; + HDC read_dc, draw_dc; + GLenum glerr; + DWORD err; + HGLRC oldctx = wglGetCurrentContext(); + + ok(!!oldctx, "Expected to find a valid current context\n"); + + draw_window = CreateWindowA("static", "opengl32_test", + WS_POPUP, 0, 0, 640, 480, 0, 0, 0, 0); + ok(!!draw_window, "Failed to create window, last error %#x.\n", GetLastError()); + + draw_dc = GetDC(draw_window); + ok(!!draw_dc, "Failed to get DC.\n"); + + pixel_format = ChoosePixelFormat(draw_dc, &pf_desc); + if (!pixel_format) + { + win_skip("Failed to find pixel format.\n"); + ReleaseDC(draw_window, draw_dc); + DestroyWindow(draw_window); + return; + } + + ret = SetPixelFormat(draw_dc, pixel_format, &pf_desc); + ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError()); + + read_window = CreateWindowA("static", "opengl32_test", + WS_POPUP, 0, 0, 640, 480, 0, 0, 0, 0); + ok(!!read_window, "Failed to create window, last error %#x.\n", GetLastError()); + + read_dc = GetDC(read_window); + ok(!!draw_dc, "Failed to get DC.\n"); + + pixel_format = ChoosePixelFormat(read_dc, &pf_desc); + if (!pixel_format) + { + win_skip("Failed to find pixel format.\n"); + ReleaseDC(read_window, read_dc); + DestroyWindow(read_window); + ReleaseDC(draw_window, draw_dc); + DestroyWindow(draw_window); + return; + } + + ret = SetPixelFormat(read_dc, pixel_format, &pf_desc); + ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError()); + + ctx = wglCreateContext(draw_dc); + ok(!!ctx, "Failed to create GL context, last error %#x.\n", GetLastError()); + + ret = pwglMakeContextCurrentARB(draw_dc, read_dc, ctx); + ok(ret, "Failed to make context current, last error %#x.\n", GetLastError()); + + glCopyPixels(0, 0, 640, 480, GL_COLOR); + glFinish(); + glerr = glGetError(); + ok(glerr == GL_NO_ERROR, "Failed glCopyPixel, error %#x.\n", glerr); + ret = SwapBuffers(draw_dc); + ok(ret, "Failed SwapBuffers, error %#x.\n", GetLastError()); + + ret = DestroyWindow(read_window); + ok(ret, "Failed to destroy window, last error %#x.\n", GetLastError()); + + ok(wglGetCurrentContext() == ctx, "Wrong current context.\n"); + + if (0) /* Crashes on AMD on Windows */ + { + glCopyPixels(0, 0, 640, 480, GL_COLOR); + glFinish(); + glerr = glGetError(); + ok(glerr == GL_NO_ERROR, "Failed glCopyPixel, error %#x.\n", glerr); + } + + glClear(GL_COLOR_BUFFER_BIT); + glFinish(); + glerr = glGetError(); + ok(glerr == GL_NO_ERROR, "Failed glClear, error %#x.\n", glerr); + ret = SwapBuffers(draw_dc); + ok(ret, "Failed SwapBuffers, error %#x.\n", GetLastError()); + + ret = wglMakeCurrent(NULL, NULL); + ok(ret, "Failed to clear current context, last error %#x.\n", GetLastError()); + + if (0) /* This crashes with Nvidia drivers on Windows. */ + { + SetLastError(0xdeadbeef); + ret = pwglMakeContextCurrentARB(draw_dc, read_dc, ctx); + err = GetLastError(); + ok(!ret && err == ERROR_INVALID_HANDLE, + "Unexpected behavior when making context current, ret %d, last error %#x.\n", ret, err); + } + + ret = DestroyWindow(draw_window); + ok(ret, "Failed to destroy window, last error %#x.\n", GetLastError()); + + glClear(GL_COLOR_BUFFER_BIT); + glFinish(); + glerr = glGetError(); + ok(glerr == GL_INVALID_OPERATION, "Failed glClear, error %#x.\n", glerr); + SetLastError(0xdeadbeef); + ret = SwapBuffers(draw_dc); + err = GetLastError(); + ok(!ret && err == ERROR_INVALID_HANDLE, "Unexpected behavior with SwapBuffer, last error %#x.\n", err); + + SetLastError(0xdeadbeef); + ret = pwglMakeContextCurrentARB(draw_dc, read_dc, ctx); + err = GetLastError(); + ok(!ret && (err == ERROR_INVALID_HANDLE || err == 0xc0070006), + "Unexpected behavior when making context current, ret %d, last error %#x.\n", ret, err); + + ok(wglGetCurrentContext() == NULL, "Wrong current context.\n"); + + wglMakeCurrent(NULL, NULL); + + wglMakeCurrent(oldhdc, oldctx); + ok(wglGetCurrentContext() == oldctx, "Wrong current context.\n"); + + SetLastError(0xdeadbeef); + ret = pwglMakeContextCurrentARB(draw_dc, read_dc, ctx); + err = GetLastError(); + ok(!ret && (err == ERROR_INVALID_HANDLE || err == 0xc0070006), + "Unexpected behavior when making context current, last error %#x.\n", err); + + ok(wglGetCurrentContext() == oldctx, "Wrong current context.\n"); + + ret = wglDeleteContext(ctx); + ok(ret, "Failed to delete GL context, last error %#x.\n", GetLastError()); + + ReleaseDC(read_window, read_dc); + ReleaseDC(draw_window, draw_dc); + + wglMakeCurrent(oldhdc, oldctx); +} + START_TEST(opengl) { HWND hwnd; @@ -920,8 +1454,10 @@ res = SetPixelFormat(hdc, iPixelFormat, &pfd); ok(res, "SetPixelformat failed: %x\n", GetLastError());
- test_bitmap_rendering(); + test_bitmap_rendering( TRUE ); + test_bitmap_rendering( FALSE ); test_minimized(); + test_window_dc(); test_dc(hwnd, hdc);
hglrc = wglCreateContext(hdc); @@ -943,6 +1479,10 @@ * any WGL call :( On Wine this would work but not on real Windows because there can be different implementations (software, ICD, MCD). */ init_functions(); + test_getprocaddress(hdc); + test_deletecontext(hwnd, hdc); + test_makecurrent(hdc); + /* The lack of wglGetExtensionsStringARB in general means broken software rendering or the lack of decent OpenGL support, skip tests in such cases */ if (!pwglGetExtensionsStringARB) { @@ -950,9 +1490,8 @@ return; }
- test_deletecontext(hdc); - test_makecurrent(hdc); test_setpixelformat(hdc); + test_destroy(hdc); test_sharelists(hdc); test_colorbits(hdc); test_gdi_dbuf(hdc); @@ -965,7 +1504,10 @@ test_opengl3(hdc);
if(strstr(wgl_extensions, "WGL_ARB_make_current_read")) + { test_make_current_read(hdc); + test_destroy_read(hdc); + } else skip("WGL_ARB_make_current_read not supported, skipping test\n");