From: Rémi Bernon rbernon@codeweavers.com
--- dlls/opengl32/tests/opengl.c | 256 +++++++++++++++++++++++------------ 1 file changed, 170 insertions(+), 86 deletions(-)
diff --git a/dlls/opengl32/tests/opengl.c b/dlls/opengl32/tests/opengl.c index 387673481e0..1badada30e5 100644 --- a/dlls/opengl32/tests/opengl.c +++ b/dlls/opengl32/tests/opengl.c @@ -44,7 +44,6 @@ static HGLRC (WINAPI *pwglCreateContextAttribsARB)(HDC hDC, HGLRC hShareContext,
/* WGL_ARB_extensions_string */ static const char* (WINAPI *pwglGetExtensionsStringARB)(HDC); -static int (WINAPI *pwglReleasePbufferDCARB)(HPBUFFERARB, HDC);
/* WGL_ARB_make_current_read */ static BOOL (WINAPI *pwglMakeContextCurrentARB)(HDC hdraw, HDC hread, HGLRC hglrc); @@ -56,7 +55,15 @@ static BOOL (WINAPI *pwglGetPixelFormatAttribivARB)(HDC, int, int, UINT, const i
/* WGL_ARB_pbuffer */ static HPBUFFERARB (WINAPI *pwglCreatePbufferARB)(HDC, int, int, int, const int *); +static BOOL (WINAPI *pwglDestroyPbufferARB)(HPBUFFERARB); static HDC (WINAPI *pwglGetPbufferDCARB)(HPBUFFERARB); +static int (WINAPI *pwglReleasePbufferDCARB)(HPBUFFERARB, HDC); +static BOOL (WINAPI *pwglQueryPbufferARB)(HPBUFFERARB,int,int*); + +/* WGL_ARB_render_texture */ +static BOOL (WINAPI *pwglBindTexImageARB)(HPBUFFERARB,int); +static BOOL (WINAPI *pwglReleaseTexImageARB)(HPBUFFERARB,int); +static BOOL (WINAPI *pwglSetPbufferAttribARB)(HPBUFFERARB,const int*);
/* WGL_EXT_swap_control */ static BOOL (WINAPI *pwglSwapIntervalEXT)(int interval); @@ -113,8 +120,15 @@ static void init_functions(void)
/* WGL_ARB_pbuffer */ GET_PROC(wglCreatePbufferARB) + GET_PROC(wglDestroyPbufferARB) GET_PROC(wglGetPbufferDCARB) GET_PROC(wglReleasePbufferDCARB) + GET_PROC(wglQueryPbufferARB) + + /* WGL_ARB_render_texture */ + GET_PROC(wglBindTexImageARB) + GET_PROC(wglReleaseTexImageARB) + GET_PROC(wglSetPbufferAttribARB)
/* WGL_EXT_swap_control */ GET_PROC(wglSwapIntervalEXT) @@ -159,104 +173,174 @@ static BOOL gl_extension_supported(const char *extensions, const char *extension return FALSE; }
-static void test_pbuffers(HDC hdc) +static void test_pbuffers( HDC hdc ) { - const int iAttribList[] = { WGL_DRAW_TO_PBUFFER_ARB, 1, /* Request pbuffer support */ - 0 }; - int iFormats[MAX_FORMATS]; - unsigned int nOnscreenFormats; - unsigned int nFormats; - int i, res; - int iPixelFormat = 0; - - nOnscreenFormats = DescribePixelFormat(hdc, 0, 0, NULL); + const int attribs[] = { WGL_DRAW_TO_PBUFFER_ARB, 1, 0 }; + int formats[MAX_FORMATS], pbuffer_attribs[3] = {0}; + unsigned int i, count, onscreen; + HDC pbuffer_dc, tmp_dc; + HPBUFFERARB pbuffer; + int res, value; + BOOL ret;
- /* When you want to render to a pbuffer you need to call wglGetPbufferDCARB which - * returns a 'magic' HDC which you can then pass to wglMakeCurrent to switch rendering - * to the pbuffer. Below some tests are performed on what happens if you use standard WGL calls - * on this 'magic' HDC for both a pixelformat that support onscreen and offscreen rendering - * and a pixelformat that's only available for offscreen rendering (this means that only - * wglChoosePixelFormatARB and friends know about the format. - * - * The first thing we need are pixelformats with pbuffer capabilities. - */ - res = pwglChoosePixelFormatARB(hdc, iAttribList, NULL, MAX_FORMATS, iFormats, &nFormats); - if(res <= 0) + onscreen = DescribePixelFormat( hdc, 0, 0, NULL ); + if ((res = pwglChoosePixelFormatARB( hdc, attribs, NULL, MAX_FORMATS, formats, &count )) <= 0) { - skip("No pbuffer compatible formats found while WGL_ARB_pbuffer is supported\n"); + win_skip( "No pixel format with WGL_DRAW_TO_PBUFFER_ARB, skipping tests\n" ); return; } - trace("nOnscreenFormats: %d\n", nOnscreenFormats); - trace("Total number of pbuffer capable pixelformats: %d\n", nFormats);
- /* Try to select an onscreen pixelformat out of the list */ - for(i=0; i < nFormats; i++) + SetLastError( 0xdeadbeef ); + pbuffer = pwglCreatePbufferARB( NULL, formats[0], 100, 100, pbuffer_attribs ); + todo_wine ok( !!pbuffer, "wglCreatePbufferARB returned %p\n", pbuffer ); + ok( (GetLastError() & 0xffff) == ERROR_INVALID_HANDLE, "got %#lx\n", GetLastError() ); + if (pbuffer) pwglDestroyPbufferARB( pbuffer ); + SetLastError( 0xdeadbeef ); + pbuffer = pwglCreatePbufferARB( hdc, 0, 100, 100, pbuffer_attribs ); + ok( !pbuffer, "wglCreatePbufferARB returned %p\n", pbuffer ); + todo_wine ok( (GetLastError() & 0xffff) == ERROR_GEN_FAILURE, "got %#lx\n", GetLastError() ); + if (pbuffer) pwglDestroyPbufferARB( pbuffer ); + SetLastError( 0xdeadbeef ); + pbuffer = pwglCreatePbufferARB( hdc, formats[0], 0, 100, pbuffer_attribs ); + todo_wine ok( !pbuffer, "wglCreatePbufferARB returned %p\n", pbuffer ); + todo_wine ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA, "got %#lx\n", GetLastError() ); + if (pbuffer) pwglDestroyPbufferARB( pbuffer ); + if (!winetest_platform_is_wine) { - /* Check if the format is onscreen, if it is choose it */ - if(iFormats[i] <= nOnscreenFormats) - { - iPixelFormat = iFormats[i]; - trace("Selected iPixelFormat=%d\n", iPixelFormat); - break; - } - } - - /* A video driver supports a large number of onscreen and offscreen pixelformats. - * The traditional WGL calls only see a subset of the whole pixelformat list. First - * of all they only see the onscreen formats (the offscreen formats are at the end of the - * pixelformat list) and second extended pixelformat capabilities are hidden from the - * standard WGL calls. Only functions that depend on WGL_ARB_pixel_format can see them. - * - * Below we check if the pixelformat is also supported onscreen. - */ - if(iPixelFormat != 0) - { - HDC pbuffer_hdc; - int attrib = 0; - HPBUFFERARB pbuffer = pwglCreatePbufferARB(hdc, iPixelFormat, 640 /* width */, 480 /* height */, &attrib); - if(!pbuffer) - skip("Pbuffer creation failed!\n"); - - /* Test the pixelformat returned by GetPixelFormat on a pbuffer as the behavior is not clear */ - pbuffer_hdc = pwglGetPbufferDCARB(pbuffer); - res = GetPixelFormat(pbuffer_hdc); - ok(res == iPixelFormat, "Unexpected iPixelFormat=%d returned by GetPixelFormat for format %d\n", res, iPixelFormat); - trace("iPixelFormat returned by GetPixelFormat: %d\n", res); - trace("PixelFormat from wglChoosePixelFormatARB: %d\n", iPixelFormat); - - pwglReleasePbufferDCARB(pbuffer, pbuffer_hdc); + SetLastError( 0xdeadbeef ); + pbuffer = pwglCreatePbufferARB( hdc, formats[0], -1, 100, pbuffer_attribs ); + ok( !pbuffer, "wglCreatePbufferARB returned %p\n", pbuffer ); + ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA, "got %#lx\n", GetLastError() ); + if (pbuffer) pwglDestroyPbufferARB( pbuffer ); } - else skip("Pbuffer test for onscreen pixelformat skipped as no onscreen format with pbuffer capabilities have been found\n"); - - /* Search for a real offscreen format */ - for(i=0, iPixelFormat=0; i<nFormats; i++) + SetLastError( 0xdeadbeef ); + pbuffer = pwglCreatePbufferARB( hdc, formats[0], 100, 0, pbuffer_attribs ); + todo_wine ok( !pbuffer, "wglCreatePbufferARB returned %p\n", pbuffer ); + todo_wine ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA, "got %#lx\n", GetLastError() ); + if (pbuffer) pwglDestroyPbufferARB( pbuffer ); + if (!winetest_platform_is_wine) { - if(iFormats[i] > nOnscreenFormats) - { - iPixelFormat = iFormats[i]; - trace("Selected iPixelFormat: %d\n", iPixelFormat); - break; - } + SetLastError( 0xdeadbeef ); + pbuffer = pwglCreatePbufferARB( hdc, formats[0], 100, -1, pbuffer_attribs ); + ok( !pbuffer, "wglCreatePbufferARB returned %p\n", pbuffer ); + ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA, "got %#lx\n", GetLastError() ); + if (pbuffer) pwglDestroyPbufferARB( pbuffer ); + } + SetLastError( 0xdeadbeef ); + pbuffer = pwglCreatePbufferARB( hdc, formats[0], 100, 100, NULL ); + ok( !!pbuffer, "wglCreatePbufferARB returned %p\n", pbuffer ); + todo_wine ok( (GetLastError() & 0xffff) == ERROR_INVALID_HANDLE, "got %#lx\n", GetLastError() ); + if (pbuffer) pwglDestroyPbufferARB( pbuffer ); + + for (i = 0; i < count; i++) + { + winetest_push_context( "%u", formats[i] ); + pbuffer = pwglCreatePbufferARB( hdc, formats[i], 640, 480, pbuffer_attribs ); + ok( !!pbuffer, "wglCreatePbufferARB returned %p\n", pbuffer ); + pbuffer_dc = pwglGetPbufferDCARB( pbuffer ); + ok( pbuffer_dc != hdc, "got %p\n", pbuffer_dc ); + res = GetPixelFormat( pbuffer_dc ); + if (formats[i] > onscreen) ok( res == 1, "got format %d\n", res ); + else ok( res == formats[i] || broken( res == 1 ), "got format %d\n", res ); + ret = pwglDestroyPbufferARB( pbuffer ); + ok( ret == 1, "got %u\n", ret ); + winetest_pop_context(); }
- if(iPixelFormat != 0) + pbuffer = pwglCreatePbufferARB( hdc, formats[0], 640, 480, pbuffer_attribs ); + ok( !!pbuffer, "wglCreatePbufferARB returned %p\n", pbuffer ); + + pbuffer_dc = pwglGetPbufferDCARB( pbuffer ); + ok( pbuffer_dc != hdc, "got %p\n", pbuffer_dc ); + + /* wglGetPbufferDCARB returns the same DC every time */ + tmp_dc = pwglGetPbufferDCARB( pbuffer ); + todo_wine ok( tmp_dc == pbuffer_dc, "got %p\n", tmp_dc ); + + /* releasing the wrong DC has no effect */ + SetLastError( 0xdeadbeef ); + ret = pwglReleasePbufferDCARB( pbuffer, hdc ); + todo_wine ok( ret == 1, "got %u\n", ret ); + ok( GetLastError() == 0xdeadbeef, "got %#lx\n", GetLastError() ); + + SetLastError( 0xdeadbeef ); + ret = pwglReleasePbufferDCARB( pbuffer, pbuffer_dc ); + ok( ret == 1, "got %u\n", ret ); + ok( GetLastError() == 0xdeadbeef, "got %#lx\n", GetLastError() ); + SetLastError( 0xdeadbeef ); + ret = pwglReleasePbufferDCARB( pbuffer, pbuffer_dc ); + todo_wine ok( ret == 1, "got %u\n", ret ); + ok( GetLastError() == 0xdeadbeef, "got %#lx\n", GetLastError() ); + /* releasing the DC more than it was acquired has no effect */ + SetLastError( 0xdeadbeef ); + ret = pwglReleasePbufferDCARB( pbuffer, pbuffer_dc ); + todo_wine ok( ret == 1, "got %u\n", ret ); + ok( GetLastError() == 0xdeadbeef, "got %#lx\n", GetLastError() ); + + SetLastError( 0xdeadbeef ); + ret = pwglQueryPbufferARB( NULL, WGL_PBUFFER_WIDTH_ARB, &value ); + ok( ret == 0, "got %u\n", ret ); + ok( (GetLastError() & 0xffff) == ERROR_INVALID_HANDLE, "got %#lx\n", GetLastError() ); + SetLastError( 0xdeadbeef ); + ret = pwglQueryPbufferARB( pbuffer, 0, &value ); + todo_wine ok( ret == 0, "got %u\n", ret ); + todo_wine ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA, "got %#lx\n", GetLastError() ); + SetLastError( 0xdeadbeef ); + ret = pwglQueryPbufferARB( pbuffer, 0xdeadbeef, &value ); + todo_wine ok( ret == 0, "got %u\n", ret ); + todo_wine ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA, "got %#lx\n", GetLastError() ); + + SetLastError( 0xdeadbeef ); + ret = pwglQueryPbufferARB( pbuffer, WGL_PBUFFER_WIDTH_ARB, &value ); + ok( ret == 1, "got %u\n", ret ); + ok( GetLastError() == 0xdeadbeef, "got %#lx\n", GetLastError() ); + SetLastError( 0xdeadbeef ); + ret = pwglQueryPbufferARB( pbuffer, WGL_PBUFFER_HEIGHT_ARB, &value ); + ok( ret == 1, "got %u\n", ret ); + ok( GetLastError() == 0xdeadbeef, "got %#lx\n", GetLastError() ); + SetLastError( 0xdeadbeef ); + ret = pwglQueryPbufferARB( pbuffer, WGL_PBUFFER_LOST_ARB, &value ); + ok( ret == 1, "got %u\n", ret ); + ok( GetLastError() == 0xdeadbeef, "got %#lx\n", GetLastError() ); + SetLastError( 0xdeadbeef ); + ret = pwglQueryPbufferARB( pbuffer, WGL_TEXTURE_FORMAT_ARB, &value ); + todo_wine ok( ret == 0, "got %u\n", ret ); + todo_wine ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA, "got %#lx\n", GetLastError() ); + SetLastError( 0xdeadbeef ); + ret = pwglQueryPbufferARB( pbuffer, WGL_TEXTURE_TARGET_ARB, &value ); + todo_wine ok( ret == 0, "got %u\n", ret ); + todo_wine ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA, "got %#lx\n", GetLastError() ); + SetLastError( 0xdeadbeef ); + ret = pwglQueryPbufferARB( pbuffer, WGL_MIPMAP_TEXTURE_ARB, &value ); + todo_wine ok( ret == 0, "got %u\n", ret ); + todo_wine ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA, "got %#lx\n", GetLastError() ); + + SetLastError( 0xdeadbeef ); + ret = pwglDestroyPbufferARB( pbuffer ); + ok( ret == 1, "got %u\n", ret ); + ok( GetLastError() == 0xdeadbeef, "got %#lx\n", GetLastError() ); + /* destroying the pbuffer multiple times */ + SetLastError( 0xdeadbeef ); + ret = pwglDestroyPbufferARB( pbuffer ); + ok( ret == 0, "got %u\n", ret ); + ok( (GetLastError() & 0xffff) == ERROR_INVALID_HANDLE, "got %#lx\n", GetLastError() ); + + if (!winetest_platform_is_wine) { - HDC pbuffer_hdc; - HPBUFFERARB pbuffer = pwglCreatePbufferARB(hdc, iPixelFormat, 640 /* width */, 480 /* height */, NULL); - if(pbuffer) - { - /* Test the pixelformat returned by GetPixelFormat on a pbuffer as the behavior is not clear */ - pbuffer_hdc = pwglGetPbufferDCARB(pbuffer); - res = GetPixelFormat(pbuffer_hdc); - - ok(res == 1, "Unexpected iPixelFormat=%d (1 expected) returned by GetPixelFormat for offscreen format %d\n", res, iPixelFormat); - trace("iPixelFormat returned by GetPixelFormat: %d\n", res); - trace("PixelFormat from wglChoosePixelFormatARB: %d\n", iPixelFormat); - pwglReleasePbufferDCARB(pbuffer, hdc); - } - else skip("Pbuffer creation failed!\n"); + pbuffer_attribs[0] = WGL_PBUFFER_LARGEST_ARB; + pbuffer_attribs[1] = 1; + pbuffer = pwglCreatePbufferARB( hdc, formats[0], 65535, 65535, pbuffer_attribs ); + ok( !pbuffer, "wglCreatePbufferARB returned %p\n", pbuffer ); + if (pbuffer) pwglDestroyPbufferARB( pbuffer ); + + pbuffer_attribs[0] = WGL_PBUFFER_LARGEST_ARB; + pbuffer_attribs[1] = 0; + SetLastError( 0xdeadbeef ); + pbuffer = pwglCreatePbufferARB( hdc, formats[0], 65535, 65535, pbuffer_attribs ); + ok( !pbuffer, "wglCreatePbufferARB returned %p\n", pbuffer ); + ok( (GetLastError() & 0xffff) == ERROR_GEN_FAILURE, "got %#lx\n", GetLastError() ); + if (pbuffer) pwglDestroyPbufferARB( pbuffer ); } - else skip("Pbuffer test for offscreen pixelformat skipped as no offscreen-only format with pbuffer capabilities has been found\n"); }
static int test_pfd(const PIXELFORMATDESCRIPTOR *pfd, PIXELFORMATDESCRIPTOR *fmt)