From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/opengl32/tests/opengl.c | 157 +++++++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) diff --git a/dlls/opengl32/tests/opengl.c b/dlls/opengl32/tests/opengl.c index 3162dd176c5..7c9c5ebeb55 100644 --- a/dlls/opengl32/tests/opengl.c +++ b/dlls/opengl32/tests/opengl.c @@ -2006,6 +2006,163 @@ static void test_sharelists(HDC winhdc) winetest_pop_context(); } + + /* GLsync are pointers, test them separately */ + if (pglIsSync) + { + GLsync obj1, obj2, obj3; + BOOL ret; + + winetest_push_context( "sync" ); + + ctx1 = wglCreateContext( winhdc ); + ok_ptr( ctx1, !=, NULL ); + ctx2 = wglCreateContext( winhdc ); + ok_ptr( ctx2, !=, NULL ); + ctx3 = wglCreateContext( winhdc ); + ok_ptr( ctx3, !=, NULL ); + + ok_ret( TRUE, wglMakeCurrent( winhdc, ctx1 ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + + /* create object 1 in ctx1 (lists #1) */ + ok_ret( FALSE, pglIsSync( (GLsync)1 ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + obj1 = pglFenceSync( GL_SYNC_GPU_COMMANDS_COMPLETE, 0 ); + ok_ret( GL_NO_ERROR, glGetError() ); + todo_wine ok_ptr( obj1, ==, (GLsync)1 ); + ok_ret( TRUE, pglIsSync( obj1 ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + + /* share ctx1 (lists #1) with ctx2 */ + ok_ret( TRUE, wglShareLists( ctx1, ctx2 ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + /* object 1 is still valid in ctx1 */ + ok_ret( TRUE, pglIsSync( obj1 ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + + /* object 1 is now valid in ctx2 */ + ok_ret( TRUE, wglMakeCurrent( winhdc, ctx2 ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + todo_wine ok_ret( TRUE, pglIsSync( obj1 ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + + /* object 1 is not valid in ctx3 */ + ok_ret( TRUE, wglMakeCurrent( winhdc, ctx3 ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + ret = pglIsSync( obj1 ); + ok( !ret || broken(nvidia), "glIsSync returned %d\n", ret ); + ok_ret( GL_NO_ERROR, glGetError() ); + /* share ctx1 (lists #1) with ctx3 */ + ok_ret( TRUE, wglShareLists( ctx1, ctx3 ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + /* object 1 is now valid there as well */ + todo_wine ok_ret( TRUE, pglIsSync( obj1 ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + + /* object 1 is still valid in ctx2 */ + ok_ret( TRUE, wglMakeCurrent( winhdc, ctx2 ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + todo_wine ok_ret( TRUE, pglIsSync( obj1 ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + + ok_ret( TRUE, wglDeleteContext( ctx1 ) ); + + /* now try the other way around */ + ctx1 = wglCreateContext( winhdc ); + ok_ptr( ctx1, !=, NULL ); + ok_ret( TRUE, wglMakeCurrent( winhdc, ctx1 ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + + /* create object 2 in ctx1 (lists #2) */ + ok_ret( FALSE, pglIsSync( (GLsync)2 ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + obj2 = pglFenceSync( GL_SYNC_GPU_COMMANDS_COMPLETE, 0 ); + ok_ret( GL_NO_ERROR, glGetError() ); + if (obj2 != (GLsync)2) + { + GLsync tmp = obj2; + obj2 = pglFenceSync( GL_SYNC_GPU_COMMANDS_COMPLETE, 0 ); + pglDeleteSync( tmp ); + } + todo_wine ok_ptr( obj2, ==, (GLsync)2 ); + ok_ret( TRUE, pglIsSync( obj2 ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + /* object 1 in invalid in ctx1 */ + ret = pglIsSync( obj1 ); + ok( !ret || broken(nvidia), "glIsSync returned %d\n", ret ); + ok_ret( GL_NO_ERROR, glGetError() ); + + /* cannot overwrite non-empty lists with some other */ + todo_wine ok_ret( FALSE, wglShareLists( ctx1, ctx3 ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + ret = wglShareLists( ctx2, ctx1 ); + ok( !ret || broken(nvidia), "wglShareLists returned %d\n", ret ); + ok_ret( GL_NO_ERROR, glGetError() ); + + /* even after deleting all the objects */ + pglDeleteSync( obj2 ); + ok_ret( FALSE, pglIsSync( obj2 ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + ret = wglShareLists( ctx2, ctx1 ); + ok( !ret || broken(nvidia), "wglShareLists returned %d\n", ret ); + ok_ret( GL_NO_ERROR, glGetError() ); + + + ok_ret( TRUE, wglMakeCurrent( winhdc, ctx2 ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + todo_wine ok_ret( TRUE, pglIsSync( obj1 ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_ret( FALSE, pglIsSync( obj2 ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_ret( FALSE, pglIsSync( (GLsync)3 ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + + /* test creating objects in shared contexts */ + obj3 = pglFenceSync( GL_SYNC_GPU_COMMANDS_COMPLETE, 0 ); + ok_ret( GL_NO_ERROR, glGetError() ); + if (obj3 != (GLsync)3) + { + GLsync tmp = obj3; + obj3 = pglFenceSync( GL_SYNC_GPU_COMMANDS_COMPLETE, 0 ); + pglDeleteSync( tmp ); + } + todo_wine ok_ptr( obj3, ==, (GLsync)3 ); + ok_ret( TRUE, wglMakeCurrent( winhdc, ctx3 ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + todo_wine ok_ret( TRUE, pglIsSync( obj1 ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_ret( FALSE, pglIsSync( obj2 ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + todo_wine ok_ret( TRUE, pglIsSync( obj3 ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + + /* test deleting objects in shared contexts */ + pglDeleteSync( obj1 ); + todo_wine ok_ret( GL_NO_ERROR, glGetError() ); + ok_ret( TRUE, wglMakeCurrent( winhdc, ctx2 ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_ret( FALSE, pglIsSync( obj1 ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + todo_wine ok_ret( FALSE, pglIsSync( obj2 ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_ret( TRUE, pglIsSync( obj3 ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + + ok_ret( TRUE, wglDeleteContext( ctx1 ) ); + ok_ret( TRUE, wglDeleteContext( ctx3 ) ); + + /* objects are still valid after shared context destruction */ + ok_ret( FALSE, pglIsSync( obj1 ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + todo_wine ok_ret( FALSE, pglIsSync( obj2 ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_ret( TRUE, pglIsSync( obj3 ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_ret( TRUE, wglDeleteContext( ctx2 ) ); + + winetest_pop_context(); + } } static void test_makecurrent(HDC winhdc) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10739