[PATCH 0/6] MR10739: opengl32/tests: Test object names allocation and sharing.
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/opengl32/tests/opengl.c | 254 +++++++++++++++-------------------- 1 file changed, 112 insertions(+), 142 deletions(-) diff --git a/dlls/opengl32/tests/opengl.c b/dlls/opengl32/tests/opengl.c index 64434c5143b..54655724d6e 100644 --- a/dlls/opengl32/tests/opengl.c +++ b/dlls/opengl32/tests/opengl.c @@ -56,7 +56,8 @@ static const char *debugstr_ok( const char *cond ) t v = (r); \ ok( v op (e), "%s " f "\n", debugstr_ok( #r ), v, ##__VA_ARGS__ ); \ } while (0) -#define ok_ret( e, r ) ok_ex( r, ==, e, UINT, "%#x" ) +#define ok_ptr( r, op, e ) ok_ex( r, op, e, const void *, "%p" ) +#define ok_ret( e, r ) ok_ex( r, ==, e, UINT_PTR, "%#Ix, error %ld", GetLastError() ) #define check_gl_error(exp) check_gl_error_(__LINE__, exp) static void check_gl_error_( unsigned int line, GLenum exp ) @@ -3558,7 +3559,7 @@ static void test_copy_context(HDC hdc) ok(ret, "wglMakeCurrent failed, last error %#lx.\n", GetLastError()); } -static void test_child_window(HWND hwnd, PIXELFORMATDESCRIPTOR *pfd) +static void test_child_window( HWND hwnd, const PIXELFORMATDESCRIPTOR *pfd ) { int pixel_format; DWORD t1, t; @@ -3881,161 +3882,130 @@ static void test_memory_map( HDC hdc) START_TEST(opengl) { - HWND hwnd; - PIXELFORMATDESCRIPTOR pfd = { - 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 */ + const PIXELFORMATDESCRIPTOR pfd = + { + .nSize = sizeof(PIXELFORMATDESCRIPTOR), + .nVersion = 1, + .dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, + .iPixelType = PFD_TYPE_RGBA, + .cColorBits = 24, }; - hwnd = CreateWindowA("static", "Title", WS_OVERLAPPEDWINDOW, 10, 10, 200, 200, NULL, NULL, - NULL, NULL); - ok(hwnd != NULL, "err: %ld\n", GetLastError()); - if (hwnd) + HMODULE gdi32 = GetModuleHandleA( "gdi32.dll" ); + int format, res; + const char *tmp; + HGLRC hglrc; + HWND hwnd; + HDC hdc; + + pD3DKMTCreateDCFromMemory = (void *)GetProcAddress( gdi32, "D3DKMTCreateDCFromMemory" ); + pD3DKMTDestroyDCFromMemory = (void *)GetProcAddress( gdi32, "D3DKMTDestroyDCFromMemory" ); + + hwnd = CreateWindowW( L"static", NULL, WS_OVERLAPPEDWINDOW | WS_VISIBLE, 10, 10, 200, 200, NULL, NULL, NULL, NULL ); + ok_ptr( hwnd, !=, NULL ); + + check_gl_error( GL_INVALID_OPERATION ); + + hdc = GetDC( hwnd ); + format = ChoosePixelFormat( hdc, &pfd ); + if (!format) { - HMODULE gdi32 = GetModuleHandleA("gdi32.dll"); - HDC hdc; - int iPixelFormat, res; - const char *tmp; - HGLRC hglrc; - DWORD error; + win_skip( "Unable to find pixel format.\n" ); + goto cleanup; + } - pD3DKMTCreateDCFromMemory = (void *)GetProcAddress( gdi32, "D3DKMTCreateDCFromMemory" ); - pD3DKMTDestroyDCFromMemory = (void *)GetProcAddress( gdi32, "D3DKMTDestroyDCFromMemory" ); + hglrc = wglCreateContext( hdc ); + ok_ptr( hglrc, ==, NULL ); + ok_ret( ERROR_INVALID_PIXEL_FORMAT, GetLastError() ); + ok_ret( TRUE, SetPixelFormat( hdc, format, &pfd ) ); + ok_ptr( glGetString( GL_RENDERER ), ==, NULL ); + ok_ptr( glGetString( GL_VERSION ), ==, NULL ); + ok_ptr( glGetString( GL_VENDOR ), ==, NULL ); + + test_bitmap_rendering( TRUE ); + test_bitmap_rendering( FALSE ); + test_16bit_bitmap_rendering(); + test_d3dkmt_rendering(); + test_minimized(); + test_window_dc(); + test_message_window(); + test_dc( hwnd, hdc ); - check_gl_error( GL_INVALID_OPERATION ); - ShowWindow(hwnd, SW_SHOW); + hglrc = wglCreateContext( hdc ); + res = wglMakeCurrent( hdc, hglrc ); + ok( res, "wglMakeCurrent failed!\n" ); + if (!res) + { + skip( "Skipping OpenGL tests without a current context\n" ); + goto cleanup; + } + trace( "OpenGL renderer: %s\n", glGetString( GL_RENDERER ) ); + trace( "OpenGL driver version: %s\n", glGetString( GL_VERSION ) ); + trace( "OpenGL vendor: %s\n", glGetString( GL_VENDOR ) ); - hdc = GetDC(hwnd); + /* Initialisation of WGL functions depends on an implicit WGL context. For this reason we can't load them before making + * any WGL call :( On Wine this would work but not on real Windows because there can be different implementations (software, ICD, MCD). + */ + init_functions(); - iPixelFormat = ChoosePixelFormat(hdc, &pfd); - if(iPixelFormat == 0) - { - /* This should never happen as ChoosePixelFormat always returns a closest match, but currently this fails in Wine if we don't have glX */ - win_skip("Unable to find pixel format.\n"); - goto cleanup; - } + test_getprocaddress( hdc ); + test_deletecontext( hwnd, hdc ); + test_makecurrent( hdc ); + test_copy_context( hdc ); - /* We shouldn't be able to create a context from a hdc which doesn't have a pixel format set */ - hglrc = wglCreateContext(hdc); - ok(hglrc == NULL, "wglCreateContext should fail when no pixel format has been set, but it passed\n"); - error = GetLastError(); - ok(error == ERROR_INVALID_PIXEL_FORMAT, "expected ERROR_INVALID_PIXEL_FORMAT for wglCreateContext without a pixelformat set, but received %#lx\n", error); - - res = SetPixelFormat(hdc, iPixelFormat, &pfd); - ok(res, "SetPixelformat failed: %lx\n", GetLastError()); - - test_bitmap_rendering( TRUE ); - test_bitmap_rendering( FALSE ); - test_16bit_bitmap_rendering(); - test_d3dkmt_rendering(); - test_minimized(); - test_window_dc(); - test_message_window(); - test_dc(hwnd, hdc); - - ok(!glGetString(GL_RENDERER) && !glGetString(GL_VERSION) && !glGetString(GL_VENDOR), - "Expected NULL string when no active context is set\n"); - hglrc = wglCreateContext(hdc); - res = wglMakeCurrent(hdc, hglrc); - ok(res, "wglMakeCurrent failed!\n"); - if(res) - { - trace("OpenGL renderer: %s\n", glGetString(GL_RENDERER)); - trace("OpenGL driver version: %s\n", glGetString(GL_VERSION)); - trace("OpenGL vendor: %s\n", glGetString(GL_VENDOR)); - } - else - { - skip("Skipping OpenGL tests without a current context\n"); - return; - } + /* The lack of wglGetExtensionsStringARB in general means broken software rendering or the lack of decent OpenGL support, skip tests in such cases */ + if (!pwglGetExtensionsStringARB) + { + win_skip( "wglGetExtensionsStringARB is not available\n" ); + goto cleanup; + } - /* Initialisation of WGL functions depends on an implicit WGL context. For this reason we can't load them before making - * 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_choosepixelformat(); + test_choosepixelformat_flag_is_ignored_when_unset( PFD_DRAW_TO_WINDOW ); + test_choosepixelformat_flag_is_ignored_when_unset( PFD_DRAW_TO_BITMAP ); + test_choosepixelformat_flag_is_ignored_when_unset( PFD_SUPPORT_GDI ); + test_choosepixelformat_flag_is_ignored_when_unset( PFD_SUPPORT_OPENGL ); + test_wglChoosePixelFormatARB( hdc ); + test_debug_message_callback(); + test_setpixelformat( hdc ); + test_destroy( hdc ); + test_sharelists( hdc ); + test_colorbits( hdc ); + test_gdi_dbuf( hdc ); + test_acceleration( hdc ); + test_framebuffer(); + test_memory_map( hdc ); + test_gl_error( hdc ); - test_getprocaddress(hdc); - test_deletecontext(hwnd, hdc); - test_makecurrent(hdc); - test_copy_context(hdc); + tmp = pwglGetExtensionsStringEXT(); + ok(tmp && *tmp, "got wgl_extensions %s\n", debugstr_a(tmp)); + wgl_extensions = tmp; - /* The lack of wglGetExtensionsStringARB in general means broken software rendering or the lack of decent OpenGL support, skip tests in such cases */ - if (!pwglGetExtensionsStringARB) - { - win_skip("wglGetExtensionsStringARB is not available\n"); - return; - } + tmp = pwglGetExtensionsStringARB(hdc); + ok(tmp && *tmp, "got wgl_extensions %s\n", debugstr_a(tmp)); + ok(!strcmp(tmp, wgl_extensions), "got wgl_extensions %s\n", debugstr_a(tmp)); - test_choosepixelformat(); - test_choosepixelformat_flag_is_ignored_when_unset(PFD_DRAW_TO_WINDOW); - test_choosepixelformat_flag_is_ignored_when_unset(PFD_DRAW_TO_BITMAP); - test_choosepixelformat_flag_is_ignored_when_unset(PFD_SUPPORT_GDI); - test_choosepixelformat_flag_is_ignored_when_unset(PFD_SUPPORT_OPENGL); - test_wglChoosePixelFormatARB(hdc); - test_debug_message_callback(); - test_setpixelformat(hdc); - test_destroy(hdc); - test_sharelists(hdc); - test_colorbits(hdc); - test_gdi_dbuf(hdc); - test_acceleration(hdc); - test_framebuffer(); - test_memory_map(hdc); - test_gl_error(hdc); - - tmp = pwglGetExtensionsStringEXT(); - ok(tmp && *tmp, "got wgl_extensions %s\n", debugstr_a(tmp)); - wgl_extensions = tmp; - - tmp = pwglGetExtensionsStringARB(hdc); - ok(tmp && *tmp, "got wgl_extensions %s\n", debugstr_a(tmp)); - ok(!strcmp(tmp, wgl_extensions), "got wgl_extensions %s\n", debugstr_a(tmp)); - - if(wgl_extensions == NULL) skip("Skipping opengl32 tests because this OpenGL implementation doesn't support WGL extensions!\n"); - - if(strstr(wgl_extensions, "WGL_ARB_create_context")) - 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"); + if (wgl_extensions == NULL) skip( "Skipping opengl32 tests because this OpenGL implementation " + "doesn't support WGL extensions!\n" ); - if(strstr(wgl_extensions, "WGL_ARB_pbuffer")) - test_pbuffers(hdc); - else - skip("WGL_ARB_pbuffer not supported, skipping pbuffer test\n"); + if (strstr( wgl_extensions, "WGL_ARB_create_context" )) test_opengl3( hdc ); - if(strstr(wgl_extensions, "WGL_EXT_swap_control")) - test_swap_control(hdc); - else - skip("WGL_EXT_swap_control not supported, skipping test\n"); + 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" ); + + if (strstr( wgl_extensions, "WGL_ARB_pbuffer" )) test_pbuffers( hdc ); + else skip( "WGL_ARB_pbuffer not supported, skipping pbuffer test\n" ); - if (winetest_interactive) - test_child_window(hwnd, &pfd); + if (strstr( wgl_extensions, "WGL_EXT_swap_control" )) test_swap_control( hdc ); + else skip( "WGL_EXT_swap_control not supported, skipping test\n" ); + + if (winetest_interactive) test_child_window( hwnd, &pfd ); cleanup: - ReleaseDC(hwnd, hdc); - DestroyWindow(hwnd); - } + ReleaseDC( hwnd, hdc ); + DestroyWindow( hwnd ); } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10739
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/opengl32/tests/opengl.c | 143 +++-------------------------------- 1 file changed, 10 insertions(+), 133 deletions(-) diff --git a/dlls/opengl32/tests/opengl.c b/dlls/opengl32/tests/opengl.c index 54655724d6e..a8df849195c 100644 --- a/dlls/opengl32/tests/opengl.c +++ b/dlls/opengl32/tests/opengl.c @@ -66,72 +66,14 @@ static void check_gl_error_( unsigned int line, GLenum exp ) ok_(__FILE__,line)( err == exp, "glGetError returned %x, expected %x\n", err, exp ); } +#define USE_GL_FUNC( func ) static PFN_ ## func p ## func; +ALL_GL_EXT_FUNCS +ALL_WGL_EXT_FUNCS +#undef USE_GL_FUNC + static NTSTATUS (WINAPI *pD3DKMTCreateDCFromMemory)( D3DKMT_CREATEDCFROMMEMORY *desc ); static NTSTATUS (WINAPI *pD3DKMTDestroyDCFromMemory)( const D3DKMT_DESTROYDCFROMMEMORY *desc ); -/* WGL_ARB_create_context */ -static HGLRC (WINAPI *pwglCreateContextAttribsARB)(HDC hDC, HGLRC hShareContext, const int *attribList); - -/* WGL_ARB_extensions_string */ -static const char* (WINAPI *pwglGetExtensionsStringARB)(HDC); -static const char* (WINAPI *pwglGetExtensionsStringEXT)(void); - -/* WGL_ARB_make_current_read */ -static BOOL (WINAPI *pwglMakeContextCurrentARB)(HDC hdraw, HDC hread, HGLRC hglrc); -static HDC (WINAPI *pwglGetCurrentReadDCARB)(void); - -/* WGL_ARB_pixel_format */ -static BOOL (WINAPI *pwglChoosePixelFormatARB)(HDC, const int *, const FLOAT *, UINT, int *, UINT *); -static BOOL (WINAPI *pwglGetPixelFormatAttribivARB)(HDC, int, int, UINT, const int *, int *); - -/* 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); -static int (WINAPI *pwglGetSwapIntervalEXT)(void); - -/* GL_ARB_debug_output */ -static void (WINAPI *pglDebugMessageCallbackARB)(void *, void *); -static void (WINAPI *pglDebugMessageControlARB)(GLenum, GLenum, GLenum, GLsizei, const GLuint *, GLboolean); -static void (WINAPI *pglDebugMessageInsertARB)(GLenum, GLenum, GLuint, GLenum, GLsizei, const char *); - -/* GL_ARB_framebuffer_object */ -static void (WINAPI *pglBindFramebuffer)(GLenum target, GLuint framebuffer); -static GLenum (WINAPI *pglCheckFramebufferStatus)(GLenum target); - -static PFN_glBindBuffer pglBindBuffer; -static PFN_glBufferData pglBufferData; -static PFN_glBufferStorage pglBufferStorage; -static PFN_glCopyBufferSubData pglCopyBufferSubData; -static PFN_glCopyNamedBufferSubData pglCopyNamedBufferSubData; -static PFN_glCreateBuffers pglCreateBuffers; -static PFN_glDeleteBuffers pglDeleteBuffers; -static PFN_glDeleteSync pglDeleteSync; -static PFN_glFenceSync pglFenceSync; -static PFN_glFlushMappedBufferRange pglFlushMappedBufferRange; -static PFN_glFlushMappedNamedBufferRange pglFlushMappedNamedBufferRange; -static PFN_glGenBuffers pglGenBuffers; -static PFN_glGetStringi pglGetStringi; -static PFN_glIsSync pglIsSync; -static PFN_glMapBuffer pglMapBuffer; -static PFN_glMapBufferRange pglMapBufferRange; -static PFN_glMapNamedBuffer pglMapNamedBuffer; -static PFN_glMapNamedBufferRange pglMapNamedBufferRange; -static PFN_glNamedBufferData pglNamedBufferData; -static PFN_glNamedBufferStorage pglNamedBufferStorage; -static PFN_glUnmapBuffer pglUnmapBuffer; -static PFN_glUnmapNamedBuffer pglUnmapNamedBuffer; - static const char* wgl_extensions = NULL; static void flush_events(void) @@ -153,75 +95,10 @@ static void flush_events(void) static void init_functions(void) { -#define GET_PROC(func) \ - p ## func = (void*)wglGetProcAddress(#func); \ - if(!p ## func) \ - trace("wglGetProcAddress(%s) failed\n", #func); - - /* WGL_ARB_create_context */ - GET_PROC(wglCreateContextAttribsARB); - - /* WGL_ARB_extensions_string */ - GET_PROC(wglGetExtensionsStringARB) - GET_PROC(wglGetExtensionsStringEXT) - - /* WGL_ARB_make_current_read */ - GET_PROC(wglMakeContextCurrentARB); - GET_PROC(wglGetCurrentReadDCARB); - - /* WGL_ARB_pixel_format */ - GET_PROC(wglChoosePixelFormatARB) - GET_PROC(wglGetPixelFormatAttribivARB) - - /* 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) - GET_PROC(wglGetSwapIntervalEXT) - - /* GL_ARB_debug_output */ - GET_PROC(glDebugMessageCallbackARB) - GET_PROC(glDebugMessageControlARB) - GET_PROC(glDebugMessageInsertARB) - - /* GL_ARB_framebuffer_object */ - GET_PROC(glBindFramebuffer) - GET_PROC(glCheckFramebufferStatus) - - GET_PROC(glBindBuffer) - GET_PROC(glBufferData) - GET_PROC(glBufferStorage) - GET_PROC(glCopyBufferSubData) - GET_PROC(glCopyNamedBufferSubData) - GET_PROC(glCreateBuffers) - GET_PROC(glDeleteBuffers) - GET_PROC(glDeleteSync) - GET_PROC(glFenceSync) - GET_PROC(glFlushMappedBufferRange) - GET_PROC(glFlushMappedNamedBufferRange) - GET_PROC(glGenBuffers) - GET_PROC(glGetStringi) - GET_PROC(glIsSync) - GET_PROC(glMapBuffer) - GET_PROC(glMapBufferRange) - GET_PROC(glMapNamedBuffer) - GET_PROC(glMapNamedBufferRange) - GET_PROC(glNamedBufferData) - GET_PROC(glNamedBufferStorage) - GET_PROC(glUnmapBuffer) - GET_PROC(glUnmapNamedBuffer) - -#undef GET_PROC +#define USE_GL_FUNC(func) p ## func = (void *)wglGetProcAddress( #func ); + ALL_GL_EXT_FUNCS + ALL_WGL_EXT_FUNCS +#undef USE_GL_FUNC } static BOOL gl_extension_supported(const char *extensions, const char *extension_string) @@ -1039,7 +916,7 @@ static void WINAPI gl_debug_message_callback(GLenum source, GLenum type, GLuint static void test_debug_message_callback(void) { static const char testmsg[] = "Hello World"; - DWORD count; + DWORD count = 0; if (!pglDebugMessageCallbackARB) { -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10739
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/opengl32/tests/opengl.c | 444 ++++++++++++++++++++++++++++++++++- 1 file changed, 443 insertions(+), 1 deletion(-) diff --git a/dlls/opengl32/tests/opengl.c b/dlls/opengl32/tests/opengl.c index a8df849195c..c45294b134f 100644 --- a/dlls/opengl32/tests/opengl.c +++ b/dlls/opengl32/tests/opengl.c @@ -56,8 +56,10 @@ static const char *debugstr_ok( const char *cond ) t v = (r); \ ok( v op (e), "%s " f "\n", debugstr_ok( #r ), v, ##__VA_ARGS__ ); \ } while (0) +#define ok_u4( r, op, e ) ok_ex( r, op, e, UINT, "%u" ) #define ok_ptr( r, op, e ) ok_ex( r, op, e, const void *, "%p" ) #define ok_ret( e, r ) ok_ex( r, ==, e, UINT_PTR, "%#Ix, error %ld", GetLastError() ) +#define ok_nt( e, r ) ok_ex( r, ==, e, NTSTATUS, "%#lx" ) #define check_gl_error(exp) check_gl_error_(__LINE__, exp) static void check_gl_error_( unsigned int line, GLenum exp ) @@ -1052,6 +1054,442 @@ static void test_setpixelformat(HDC winhdc) } } +enum object_type +{ + OBJ_BUFFER, + OBJ_BUFFER_ARB, + OBJ_COMMAND_LIST_NV, + OBJ_FENCE_APPLE, + OBJ_FENCE_NV, + OBJ_FRAMEBUFFER, + OBJ_FRAMEBUFFER_EXT, + OBJ_DISPLAY_LIST, + OBJ_MEMORY_OBJECT_EXT, + OBJ_OBJECT_BUFFER_ATI, + OBJ_PATH_NV, + OBJ_PROGRAM_ARB, + OBJ_PROGRAM_NV, + OBJ_SHADER_EXT, + OBJ_SHADER_ATI, + OBJ_PROGRAM_OBJECT, + OBJ_PROGRAM_OBJECT_ARB, + OBJ_SHADER_OBJECT, + OBJ_SHADER_OBJECT_ARB, + OBJ_PROGRAM_PIPELINE, + OBJ_QUERY, + OBJ_QUERY_ARB, + OBJ_OCCLUSION_QUERY_NV, + OBJ_RENDERBUFFER, + OBJ_RENDERBUFFER_EXT, + OBJ_SAMPLER, + OBJ_SEMAPHORE_EXT, + OBJ_STATE_NV, + OBJ_TEXTURE, + OBJ_TEXTURE_EXT, + OBJ_TRANSFORM_FEEDBACK, + OBJ_TRANSFORM_FEEDBACK_NV, + OBJ_VERTEX_ARRAY, + OBJ_VERTEX_ARRAY_APPLE, + OBJ_TYPE_COUNT, +}; + +static const char *debugstr_object_type( enum object_type type ) +{ + switch (type) + { + case OBJ_BUFFER: return "buffer"; + case OBJ_BUFFER_ARB: return "buffer_arb"; + case OBJ_COMMAND_LIST_NV: return "command_list_nv"; + case OBJ_FENCE_APPLE: return "fence_apple"; + case OBJ_FENCE_NV: return "fence_nv"; + case OBJ_FRAMEBUFFER: return "framebuffer"; + case OBJ_FRAMEBUFFER_EXT: return "framebuffer_ext"; + case OBJ_DISPLAY_LIST: return "display list"; + case OBJ_MEMORY_OBJECT_EXT: return "memory_object_ext"; + case OBJ_OBJECT_BUFFER_ATI: return "object_buffer_ati"; + case OBJ_PATH_NV: return "path_nv"; + case OBJ_PROGRAM_ARB: return "program_arb"; + case OBJ_PROGRAM_NV: return "program_nv"; + case OBJ_SHADER_EXT: return "shader_ext"; + case OBJ_SHADER_ATI: return "shader_ati"; + case OBJ_PROGRAM_OBJECT: return "program"; + case OBJ_PROGRAM_OBJECT_ARB: return "program_object_arb"; + case OBJ_SHADER_OBJECT: return "shader"; + case OBJ_SHADER_OBJECT_ARB: return "shader_object_arb"; + case OBJ_PROGRAM_PIPELINE: return "program_pipeline"; + case OBJ_QUERY: return "query"; + case OBJ_QUERY_ARB: return "query_arb"; + case OBJ_OCCLUSION_QUERY_NV: return "occlusion_query_nv"; + case OBJ_RENDERBUFFER: return "renderbuffer"; + case OBJ_RENDERBUFFER_EXT: return "renderbuffer_ext"; + case OBJ_SAMPLER: return "sampler"; + case OBJ_SEMAPHORE_EXT: return "semaphore_ext"; + case OBJ_STATE_NV: return "state_nv"; + case OBJ_TEXTURE: return "texture"; + case OBJ_TEXTURE_EXT: return "texture_ext"; + case OBJ_TRANSFORM_FEEDBACK: return "transform_feedback"; + case OBJ_TRANSFORM_FEEDBACK_NV: return "transform_feedback_nv"; + case OBJ_VERTEX_ARRAY: return "vertex_array"; + case OBJ_VERTEX_ARRAY_APPLE: return "vertex_array_apple"; + default: return wine_dbg_sprintf( "%u", type ); + } +} + +static BOOL create_object( enum object_type type, GLuint name, GLuint *obj ) +{ + switch (type) + { + case OBJ_BUFFER: + if (!pglGenBuffers) return FALSE; + if (!(*obj = name)) pglGenBuffers( 1, obj ); + pglBindBuffer( GL_ARRAY_BUFFER, *obj ); + break; + case OBJ_BUFFER_ARB: + if (!pglGenBuffersARB) return FALSE; + if (!(*obj = name)) pglGenBuffersARB( 1, obj ); + pglBindBufferARB( GL_ARRAY_BUFFER, *obj ); + break; + case OBJ_COMMAND_LIST_NV: + if (!pglCreateCommandListsNV) return FALSE; + pglCreateCommandListsNV( 1, obj ); + break; + case OBJ_FENCE_APPLE: + if (!pglGenFencesAPPLE) return FALSE; + if (!(*obj = name)) pglGenFencesAPPLE( 1, obj ); + pglSetFenceAPPLE( *obj ); break; + case OBJ_FENCE_NV: + if (!pglGenFencesNV) return FALSE; + if (!(*obj = name)) pglGenFencesNV( 1, obj ); + pglSetFenceNV( *obj, GL_ALL_COMPLETED_NV ); break; + case OBJ_FRAMEBUFFER: + if (!pglGenFramebuffers) return FALSE; + if (!(*obj = name)) pglGenFramebuffers( 1, obj ); + pglBindFramebuffer( GL_DRAW_FRAMEBUFFER, *obj ); + break; + case OBJ_FRAMEBUFFER_EXT: + if (!pglGenFramebuffersEXT) return FALSE; + if (!(*obj = name)) pglGenFramebuffersEXT( 1, obj ); + pglBindFramebufferEXT( GL_DRAW_FRAMEBUFFER, *obj ); + break; + case OBJ_DISPLAY_LIST: + if (!(*obj = name)) *obj = glGenLists( 1 ); + glNewList( *obj, GL_COMPILE ); + glClear( GL_COLOR_BUFFER_BIT ); + glEndList(); + break; + case OBJ_MEMORY_OBJECT_EXT: + if (!pglCreateMemoryObjectsEXT) return FALSE; + pglCreateMemoryObjectsEXT( 1, obj ); + break; + case OBJ_OBJECT_BUFFER_ATI: + if (!pglNewObjectBufferATI) return FALSE; + *obj = pglNewObjectBufferATI( sizeof(name), &name, GL_STATIC_ATI ); + break; + case OBJ_PATH_NV: + { + static const GLshort coords[2] = {100, 180}; + static const GLubyte cmds[1] = {GL_MOVE_TO_NV}; + + if (!pglGenPathsNV) return FALSE; + if (!(*obj = name)) *obj = pglGenPathsNV( 1 ); + pglPathCommandsNV( *obj, 1, cmds, 2, GL_SHORT, coords ); + break; + } + case OBJ_PROGRAM_ARB: + { + static const GLubyte shader[] = "!!ARBfp1.0\nEND"; + + if (!pglGenProgramsARB) return FALSE; + if (!(*obj = name)) pglGenProgramsARB( 1, obj ); + pglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, *obj ); + pglProgramStringARB( GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, sizeof(shader) - 1, shader); + break; + } + case OBJ_PROGRAM_NV: + { + static const GLubyte shader[] = "!!VP1.0END"; + + if (!pglGenProgramsNV) return FALSE; + if (!(*obj = name)) pglGenProgramsNV( 1, obj ); + pglBindProgramNV( GL_VERTEX_PROGRAM_NV, *obj ); + pglLoadProgramNV( GL_VERTEX_PROGRAM_NV, *obj, sizeof(shader) - 1, shader); + break; + } + case OBJ_SHADER_EXT: + if (!pglGenVertexShadersEXT) return FALSE; + if (!(*obj = name)) *obj = pglGenVertexShadersEXT( 1 ); + pglBindVertexShaderEXT( *obj ); + break; + case OBJ_SHADER_ATI: + if (!pglGenFragmentShadersATI) return FALSE; + if (!(*obj = name)) *obj = pglGenFragmentShadersATI( 1 ); + pglBindFragmentShaderATI( *obj ); + break; + case OBJ_PROGRAM_OBJECT: + if (!pglCreateProgram) return FALSE; + *obj = pglCreateProgram(); + break; + case OBJ_PROGRAM_OBJECT_ARB: + if (!pglCreateProgramObjectARB) return FALSE; + *obj = pglCreateProgramObjectARB(); + break; + case OBJ_SHADER_OBJECT: + if (!pglCreateShader) return FALSE; + *obj = pglCreateShader( GL_VERTEX_SHADER ); + break; + case OBJ_SHADER_OBJECT_ARB: + if (!pglCreateShaderObjectARB) return FALSE; + *obj = pglCreateShaderObjectARB( GL_VERTEX_SHADER_ARB ); + break; + case OBJ_PROGRAM_PIPELINE: + if (!pglGenProgramPipelines) return FALSE; + if (!(*obj = name)) pglGenProgramPipelines( 1, obj ); + pglBindProgramPipeline( *obj ); + break; + case OBJ_QUERY: + if (!pglGenQueries) return FALSE; + if (!(*obj = name)) pglGenQueries( 1, obj ); + pglBeginQuery( GL_SAMPLES_PASSED, *obj ); + pglEndQuery( GL_SAMPLES_PASSED ); + break; + case OBJ_QUERY_ARB: + if (!pglGenQueriesARB) return FALSE; + if (!(*obj = name)) pglGenQueriesARB( 1, obj ); + pglBeginQueryARB( GL_SAMPLES_PASSED_ARB, *obj ); + pglEndQueryARB( GL_SAMPLES_PASSED_ARB ); + break; + case OBJ_OCCLUSION_QUERY_NV: + if (!pglGenOcclusionQueriesNV) return FALSE; + if (!(*obj = name)) pglGenOcclusionQueriesNV( 1, obj ); + pglBeginOcclusionQueryNV( *obj ); + pglEndOcclusionQueryNV(); + break; + case OBJ_RENDERBUFFER: + if (!pglGenRenderbuffers) return FALSE; + if (!(*obj = name)) pglGenRenderbuffers( 1, obj ); + pglBindRenderbuffer( GL_RENDERBUFFER, *obj ); + break; + case OBJ_RENDERBUFFER_EXT: + if (!pglGenRenderbuffersEXT) return FALSE; + if (!(*obj = name)) pglGenRenderbuffersEXT( 1, obj ); + pglBindRenderbufferEXT( GL_RENDERBUFFER_EXT, *obj ); + break; + case OBJ_SAMPLER: + if (!pglGenSamplers) return FALSE; + if (!(*obj = name)) pglGenSamplers( 1, obj ); + pglBindSampler( 0, *obj ); + break; + case OBJ_SEMAPHORE_EXT: + { + D3DKMT_OPENADAPTERFROMGDIDISPLAYNAME open_adapter = {0}; + D3DKMT_DESTROYSYNCHRONIZATIONOBJECT destroy = {0}; + D3DKMT_CREATESYNCHRONIZATIONOBJECT2 create2 = {0}; + D3DKMT_DESTROYDEVICE destroy_device = {0}; + D3DKMT_CREATEDEVICE create_device = {0}; + D3DKMT_CLOSEADAPTER close_adapter = {0}; + NTSTATUS status; + + if (!pglGenSemaphoresEXT) return FALSE; + + wcscpy( open_adapter.DeviceName, L"\\\\.\\DISPLAY1" ); + status = D3DKMTOpenAdapterFromGdiDisplayName( &open_adapter ); + ok_nt( STATUS_SUCCESS, status ); + create_device.hAdapter = open_adapter.hAdapter; + status = D3DKMTCreateDevice( &create_device ); + ok_nt( STATUS_SUCCESS, status ); + + create2.hDevice = create_device.hDevice; + create2.Info.Type = D3DDDI_FENCE; + create2.Info.Flags.Shared = 1; + create2.hSyncObject = create2.Info.SharedHandle = 0x1eadbeed; + status = D3DKMTCreateSynchronizationObject2( &create2 ); + ok_nt( STATUS_SUCCESS, status ); + + if (!(*obj = name)) pglGenSemaphoresEXT( 1, obj ); + pglImportSemaphoreWin32HandleEXT( *obj, GL_HANDLE_TYPE_OPAQUE_WIN32_KMT_EXT, + UlongToHandle( create2.Info.SharedHandle ) ); + + destroy.hSyncObject = create2.hSyncObject; + status = D3DKMTDestroySynchronizationObject( &destroy ); + ok_nt( STATUS_SUCCESS, status ); + destroy_device.hDevice = create_device.hDevice; + status = D3DKMTDestroyDevice( &destroy_device ); + ok_nt( STATUS_SUCCESS, status ); + close_adapter.hAdapter = open_adapter.hAdapter; + status = D3DKMTCloseAdapter( &close_adapter ); + ok_nt( STATUS_SUCCESS, status ); + break; + } + case OBJ_STATE_NV: + if (!pglCreateStatesNV) return FALSE; + pglCreateStatesNV( 1, obj ); + break; + case OBJ_TEXTURE: + if (!(*obj = name)) glGenTextures( 1, obj ); + glBindTexture( GL_TEXTURE_2D, *obj ); + break; + case OBJ_TEXTURE_EXT: + if (!pglGenTexturesEXT) return FALSE; + if (!(*obj = name)) pglGenTexturesEXT( 1, obj ); + pglBindTextureEXT( GL_TEXTURE_2D, *obj ); + break; + case OBJ_TRANSFORM_FEEDBACK: + if (!pglGenTransformFeedbacks) return FALSE; + if (!(*obj = name)) pglGenTransformFeedbacks( 1, obj ); + pglBindTransformFeedback( GL_TRANSFORM_FEEDBACK, *obj ); + break; + case OBJ_TRANSFORM_FEEDBACK_NV: + if (!pglGenTransformFeedbacksNV) return FALSE; + if (!(*obj = name)) pglGenTransformFeedbacksNV( 1, obj ); + pglBindTransformFeedbackNV( GL_TRANSFORM_FEEDBACK_NV, *obj ); + break; + case OBJ_VERTEX_ARRAY: + if (!pglGenVertexArrays) return FALSE; + if (!(*obj = name)) pglGenVertexArrays( 1, obj ); + pglBindVertexArray( *obj ); + break; + case OBJ_VERTEX_ARRAY_APPLE: + if (!pglGenVertexArraysAPPLE) return FALSE; + if (!(*obj = name)) pglGenVertexArraysAPPLE( 1, obj ); + pglBindVertexArrayAPPLE( *obj ); + break; + case OBJ_TYPE_COUNT: return FALSE; + } + + return TRUE; +} + +/* some functions don't allow implicit names even in compat contexts, or even in core contexts */ +static BOOL is_implicit_allowed( enum object_type type, BOOL compat ) +{ + switch (type) + { + case OBJ_BUFFER: return compat; + case OBJ_BUFFER_ARB: return compat; + case OBJ_DISPLAY_LIST: return compat; + case OBJ_OCCLUSION_QUERY_NV: return compat; + case OBJ_QUERY: return compat; + case OBJ_QUERY_ARB: return compat; + case OBJ_TEXTURE: return compat; + case OBJ_TEXTURE_EXT: return compat; + + /* never allow implicit allocation even in compat contexts */ + case OBJ_FRAMEBUFFER: return FALSE; + case OBJ_PROGRAM_PIPELINE: return FALSE; + case OBJ_RENDERBUFFER: return FALSE; + case OBJ_SAMPLER: return FALSE; + case OBJ_TRANSFORM_FEEDBACK: return FALSE; + case OBJ_VERTEX_ARRAY: return FALSE; + + /* always allow implicit allocation even in core contexts */ + case OBJ_FENCE_APPLE: return TRUE; + case OBJ_FENCE_NV: return TRUE; + case OBJ_FRAMEBUFFER_EXT: return TRUE; + case OBJ_PATH_NV: return TRUE; + case OBJ_PROGRAM_ARB: return TRUE; + case OBJ_PROGRAM_NV: return TRUE; + case OBJ_RENDERBUFFER_EXT: return TRUE; + case OBJ_SEMAPHORE_EXT: return TRUE; + case OBJ_SHADER_ATI: return TRUE; + case OBJ_SHADER_EXT: return TRUE; + case OBJ_TRANSFORM_FEEDBACK_NV: return TRUE; + case OBJ_VERTEX_ARRAY_APPLE: return TRUE; + + /* some types are always allocated explicitly */ + case OBJ_COMMAND_LIST_NV: return TRUE; + case OBJ_MEMORY_OBJECT_EXT: return TRUE; + case OBJ_OBJECT_BUFFER_ATI: return TRUE; + case OBJ_PROGRAM_OBJECT: return TRUE; + case OBJ_PROGRAM_OBJECT_ARB: return TRUE; + case OBJ_SHADER_OBJECT: return TRUE; + case OBJ_SHADER_OBJECT_ARB: return TRUE; + case OBJ_STATE_NV: return TRUE; + + default: return FALSE; + } +} + +static void test_object_creation(HDC winhdc) +{ + static const GLint compat_attribs[] = + { + WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, + 0, 0 + }; + static const GLint core_attribs[] = + { + WGL_CONTEXT_MAJOR_VERSION_ARB, 3, + WGL_CONTEXT_MINOR_VERSION_ARB, 3, + WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB, + 0, 0 + }; + + GLuint obj; + HGLRC ctx; + + for (UINT i = 0; i < OBJ_TYPE_COUNT; i++) + { + if (broken( i == OBJ_TRANSFORM_FEEDBACK )) continue; /* NVIDIA / AMD don't agree */ + + winetest_push_context( "%u %s compat", i, debugstr_object_type( i ) ); + + ctx = pwglCreateContextAttribsARB( winhdc, NULL, compat_attribs ); + ok_ptr( ctx, !=, NULL ); + ok_ret( TRUE, wglMakeCurrent( winhdc, ctx ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + + if (!create_object( i, 1, &obj )) + { + skip( "Skipping unsupported object type.\n" ); + goto next; + } + if (!is_implicit_allowed( i, TRUE )) + { + todo_wine_if( i == OBJ_FRAMEBUFFER || i == OBJ_RENDERBUFFER ) + ok_ret( GL_INVALID_OPERATION, glGetError() ); + if (!winetest_platform_is_wine || (i != OBJ_FRAMEBUFFER && i != OBJ_RENDERBUFFER)) + ok_ret( TRUE, create_object( i, 0, &obj ) ); + } + ok_ret( GL_NO_ERROR, glGetError() ); + ok_u4( obj, ==, 1 ); + ok_ret( GL_NO_ERROR, glGetError() ); + + ok_ret( TRUE, wglDeleteContext( ctx ) ); + + winetest_pop_context(); + + + winetest_push_context( "%u %s core", i, debugstr_object_type( i ) ); + + ctx = pwglCreateContextAttribsARB( winhdc, NULL, core_attribs ); + ok_ptr( ctx, !=, NULL ); + ok_ret( TRUE, wglMakeCurrent( winhdc, ctx ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + + ok_ret( TRUE, create_object( i, 1, &obj ) ); + if (!is_implicit_allowed( i, FALSE )) + { + ok_ret( GL_INVALID_OPERATION, glGetError() ); + ok_ret( TRUE, create_object( i, 0, &obj ) ); + } + if (i == OBJ_DISPLAY_LIST) ok_ret( GL_INVALID_OPERATION, glGetError() ); + else + { + /* Wine never allows implicit allocation in core contexts */ + todo_wine_if( i == OBJ_FENCE_APPLE || i == OBJ_FENCE_NV || i == OBJ_FRAMEBUFFER_EXT || i == OBJ_PATH_NV || + i == OBJ_PROGRAM_ARB || i == OBJ_PROGRAM_NV || i == OBJ_SHADER_EXT || i == OBJ_SHADER_ATI || + i == OBJ_RENDERBUFFER_EXT || i == OBJ_SEMAPHORE_EXT || i == OBJ_TRANSFORM_FEEDBACK_NV || + i == OBJ_VERTEX_ARRAY_APPLE ) + ok_ret( GL_NO_ERROR, glGetError() ); + ok_u4( obj, ==, 1 ); + } + +next: + ok_ret( TRUE, wglDeleteContext( ctx ) ); + winetest_pop_context(); + } +} + static void test_sharelists(HDC winhdc) { BOOL res, nvidia, amd, source_current, source_sharing, dest_current, dest_sharing; @@ -3865,7 +4303,11 @@ START_TEST(opengl) if (wgl_extensions == NULL) skip( "Skipping opengl32 tests because this OpenGL implementation " "doesn't support WGL extensions!\n" ); - if (strstr( wgl_extensions, "WGL_ARB_create_context" )) test_opengl3( hdc ); + if (strstr( wgl_extensions, "WGL_ARB_create_context" )) + { + test_opengl3( hdc ); + test_object_creation( hdc ); + } if (strstr( wgl_extensions, "WGL_ARB_make_current_read" )) { -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10739
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/opengl32/tests/opengl.c | 274 ++++++++++++++++++++++++++++++++++- 1 file changed, 273 insertions(+), 1 deletion(-) diff --git a/dlls/opengl32/tests/opengl.c b/dlls/opengl32/tests/opengl.c index c45294b134f..3162dd176c5 100644 --- a/dlls/opengl32/tests/opengl.c +++ b/dlls/opengl32/tests/opengl.c @@ -1490,11 +1490,113 @@ next: } } +static void delete_object( enum object_type type, GLuint name ) +{ + switch (type) + { + case OBJ_BUFFER: pglDeleteBuffers( 1, &name ); break; + case OBJ_BUFFER_ARB: pglDeleteBuffersARB( 1, &name ); break; + case OBJ_COMMAND_LIST_NV: pglDeleteCommandListsNV( 1, &name ); break; + case OBJ_FENCE_APPLE: pglDeleteFencesAPPLE( 1, &name ); break; + case OBJ_FENCE_NV: pglDeleteFencesNV( 1, &name ); break; + case OBJ_FRAMEBUFFER: pglDeleteFramebuffers( 1, &name ); break; + case OBJ_FRAMEBUFFER_EXT: pglDeleteFramebuffersEXT( 1, &name ); break; + case OBJ_DISPLAY_LIST: glDeleteLists( name, 1 ); break; + case OBJ_MEMORY_OBJECT_EXT: pglDeleteMemoryObjectsEXT( 1, &name ); break; + case OBJ_OBJECT_BUFFER_ATI: pglDeleteObjectBufferATI( name ); break; + case OBJ_PATH_NV: pglDeletePathsNV( name, 1 ); break; + case OBJ_PROGRAM_ARB: pglDeleteProgramsARB( 1, &name ); break; + case OBJ_PROGRAM_NV: pglDeleteProgramsNV( 1, &name ); break; + case OBJ_SHADER_EXT: pglDeleteVertexShaderEXT( name ); break; + case OBJ_SHADER_ATI: pglDeleteFragmentShaderATI( name ); break; + case OBJ_PROGRAM_OBJECT: pglDeleteProgram( name ); break; + case OBJ_PROGRAM_OBJECT_ARB: pglDeleteObjectARB( name ); break; + case OBJ_SHADER_OBJECT: pglDeleteShader( name ); break; + case OBJ_SHADER_OBJECT_ARB: pglDeleteObjectARB( name ); break; + case OBJ_PROGRAM_PIPELINE: pglDeleteProgramPipelines( 1, &name ); break; + case OBJ_QUERY: pglDeleteQueries( 1, &name ); break; + case OBJ_QUERY_ARB: pglDeleteQueriesARB( 1, &name ); break; + case OBJ_OCCLUSION_QUERY_NV: pglDeleteOcclusionQueriesNV( 1, &name ); break; + case OBJ_RENDERBUFFER: pglDeleteRenderbuffers( 1, &name ); break; + case OBJ_RENDERBUFFER_EXT: pglDeleteRenderbuffersEXT( 1, &name ); break; + case OBJ_SAMPLER: pglDeleteSamplers( 1, &name ); break; + case OBJ_SEMAPHORE_EXT: pglDeleteSemaphoresEXT( 1, &name ); break; + case OBJ_STATE_NV: pglDeleteStatesNV( 1, &name ); break; + case OBJ_TEXTURE: glDeleteTextures( 1, &name ); break; + case OBJ_TEXTURE_EXT: pglDeleteTexturesEXT( 1, &name ); break; + case OBJ_TRANSFORM_FEEDBACK: pglDeleteTransformFeedbacks( 1, &name ); break; + case OBJ_TRANSFORM_FEEDBACK_NV: pglDeleteTransformFeedbacksNV( 1, &name ); break; + case OBJ_VERTEX_ARRAY: pglDeleteVertexArrays( 1, &name ); break; + case OBJ_VERTEX_ARRAY_APPLE: pglDeleteVertexArraysAPPLE( 1, &name ); break; + case OBJ_TYPE_COUNT: return; + } +} + +static GLboolean GLAPIENTRY is_program_object_arb( GLuint name ) +{ + GLint type = 0xdeadbeef; + pglGetObjectParameterivARB( name, GL_OBJECT_TYPE_ARB, &type ); + if (type != GL_PROGRAM_OBJECT_ARB) glGetError(); /* other glIs* functions don't set error on failure */ + return type == GL_PROGRAM_OBJECT_ARB; +} + +static GLboolean GLAPIENTRY is_shader_object_arb( GLuint name ) +{ + GLint type = 0xdeadbeef; + pglGetObjectParameterivARB( name, GL_OBJECT_TYPE_ARB, &type ); + if (type != GL_SHADER_OBJECT_ARB) glGetError(); /* other glIs* functions don't set error on failure */ + return type == GL_SHADER_OBJECT_ARB; +} + static void test_sharelists(HDC winhdc) { + const struct object_test + { + enum object_type type; + GLboolean (*GLAPIENTRY exists)( GLuint name ); + BOOL shared; + BOOL supported; + } object_tests[] = + { + { OBJ_BUFFER, pglIsBuffer, TRUE, !!pglIsBuffer }, + { OBJ_BUFFER_ARB, pglIsBufferARB, TRUE, !!pglIsBufferARB }, + { OBJ_FRAMEBUFFER, pglIsFramebuffer, TRUE, !!pglIsFramebuffer }, + { OBJ_FRAMEBUFFER_EXT, pglIsFramebufferEXT, TRUE, !!pglIsFramebufferEXT }, + { OBJ_RENDERBUFFER, pglIsRenderbuffer, TRUE, !!pglIsRenderbuffer }, + { OBJ_RENDERBUFFER_EXT, pglIsRenderbufferEXT, TRUE, !!pglIsRenderbufferEXT }, + { OBJ_TEXTURE, glIsTexture, TRUE, TRUE }, + { OBJ_TEXTURE_EXT, pglIsTextureEXT, TRUE, !!pglIsTextureEXT }, + { OBJ_SAMPLER, pglIsSampler, TRUE, !!pglIsSampler }, + { OBJ_DISPLAY_LIST, glIsList, TRUE, TRUE }, + { OBJ_PROGRAM_ARB, pglIsProgramARB, TRUE, !!pglIsProgramARB }, + { OBJ_PROGRAM_NV, pglIsProgramNV, TRUE, !!pglIsProgramNV }, + { OBJ_SEMAPHORE_EXT, pglIsSemaphoreEXT, TRUE, !!pglIsSemaphoreEXT }, + { OBJ_MEMORY_OBJECT_EXT, pglIsMemoryObjectEXT, TRUE, !!pglIsMemoryObjectEXT }, + { OBJ_PATH_NV, pglIsPathNV, TRUE, !!pglIsPathNV }, + { OBJ_PROGRAM_OBJECT, pglIsProgram, TRUE, !!pglIsProgram }, + { OBJ_PROGRAM_OBJECT_ARB, is_program_object_arb, TRUE, !!pglCreateProgramObjectARB }, + { OBJ_SHADER_OBJECT, pglIsShader, TRUE, !!pglIsShader }, + { OBJ_SHADER_OBJECT_ARB, is_shader_object_arb, TRUE, !!pglCreateShaderObjectARB }, + { OBJ_SHADER_EXT, NULL, TRUE, !!pglGenVertexShadersEXT }, + { OBJ_SHADER_ATI, NULL, TRUE, !!pglGenFragmentShadersATI }, + /* non shared objects */ + { OBJ_OBJECT_BUFFER_ATI, pglIsObjectBufferATI, FALSE /* needs confirmation */, !!pglIsObjectBufferATI }, + { OBJ_COMMAND_LIST_NV, pglIsCommandListNV, FALSE, !!pglIsCommandListNV }, + { OBJ_FENCE_APPLE, pglIsFenceAPPLE, FALSE, !!pglIsFenceAPPLE }, + { OBJ_FENCE_NV, pglIsFenceNV, FALSE, !!pglIsFenceNV }, + { OBJ_PROGRAM_PIPELINE, pglIsProgramPipeline, FALSE, !!pglIsProgramPipeline }, + { OBJ_QUERY, pglIsQuery, FALSE, !!pglIsQuery }, + { OBJ_QUERY_ARB, pglIsQueryARB, FALSE, !!pglIsQueryARB }, + { OBJ_OCCLUSION_QUERY_NV, pglIsOcclusionQueryNV, FALSE, !!pglIsOcclusionQueryNV }, + { OBJ_STATE_NV, pglIsStateNV, FALSE, !!pglIsStateNV }, + { OBJ_TRANSFORM_FEEDBACK, pglIsTransformFeedback, FALSE, !!pglIsTransformFeedback }, + { OBJ_TRANSFORM_FEEDBACK_NV, pglIsTransformFeedbackNV, FALSE, !!pglIsTransformFeedbackNV }, + { OBJ_VERTEX_ARRAY, pglIsVertexArray, FALSE, !!pglIsVertexArray }, + { OBJ_VERTEX_ARRAY_APPLE, pglIsVertexArrayAPPLE, FALSE, !!pglIsVertexArrayAPPLE }, + }; BOOL res, nvidia, amd, source_current, source_sharing, dest_current, dest_sharing; const char *extensions = (const char*)glGetString(GL_EXTENSIONS); - HGLRC source, dest, other; + HGLRC source, dest, other, ctx1, ctx2, ctx3; BOOL ms_hint_supported; ms_hint_supported = gl_extension_supported(extensions, "GL_NV_multisample_filter_hint"); @@ -1734,6 +1836,176 @@ static void test_sharelists(HDC winhdc) } } } + + for (UINT i = 0; i < ARRAY_SIZE(object_tests); i++) + { + /* some functions don't allow implicit names even in compat contexts */ + const struct object_test *test = object_tests + i; + GLuint obj1, obj2, obj3; + + if (!test->exists) + { + skip( "Skipping object type %s\n", debugstr_object_type( test->type ) ); + continue; + } + + winetest_push_context( "%u %s", i, debugstr_object_type( test->type ) ); + + 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, test->exists( 1 ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + create_object( test->type, is_implicit_allowed( test->type, TRUE ) ? 1 : 0, &obj1 ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_u4( obj1, ==, 1 ); + ok_ret( TRUE, test->exists( 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, test->exists( 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() ); + if (!test->shared) + { + ok_ret( FALSE, test->exists( obj1 ) ); + ok_ret( TRUE, wglDeleteContext( ctx1 ) ); + ok_ret( TRUE, wglDeleteContext( ctx2 ) ); + ok_ret( TRUE, wglDeleteContext( ctx3 ) ); + winetest_pop_context(); + continue; + } + ok_ret( TRUE, test->exists( 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() ); + ok_ret( FALSE, test->exists( obj1 ) ); + 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, test->exists( 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() ); + ok_ret( TRUE, test->exists( 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, test->exists( 2 ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + create_object( test->type, is_implicit_allowed( test->type, TRUE ) ? 2 : 0, &obj2 ); + ok_ret( GL_NO_ERROR, glGetError() ); + if (obj2 != 2) + { + GLuint tmp = obj2; + create_object( test->type, is_implicit_allowed( test->type, TRUE ) ? 2 : 0, &obj2 ); + delete_object( test->type, tmp ); + } + ok_u4( obj2, ==, 2 ); + ok_ret( TRUE, test->exists( obj2 ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + /* object 1 in invalid in ctx1 */ + ok_ret( FALSE, test->exists( obj1 ) ); + 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() ); + ok_ret( FALSE, wglShareLists( ctx2, ctx1 ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + + /* even after deleting all the objects */ + delete_object( test->type, obj2 ); + ok_ret( FALSE, test->exists( obj2 ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_ret( FALSE, wglShareLists( ctx2, ctx1 ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + + + ok_ret( TRUE, wglMakeCurrent( winhdc, ctx2 ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_ret( TRUE, test->exists( obj1 ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_ret( FALSE, test->exists( obj2 ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_ret( FALSE, test->exists( 3 ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + + /* test creating objects in shared contexts */ + create_object( test->type, is_implicit_allowed( test->type, TRUE ) ? 3 : 0, &obj3 ); + ok_ret( GL_NO_ERROR, glGetError() ); + if (obj3 != 3) + { + GLuint tmp = obj3; + create_object( test->type, is_implicit_allowed( test->type, TRUE ) ? 3 : 0, &obj3 ); + delete_object( test->type, tmp ); + } + ok_u4( obj3, ==, 3 ); + ok_ret( TRUE, wglMakeCurrent( winhdc, ctx3 ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + todo_wine ok_ret( TRUE, test->exists( obj1 ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_ret( FALSE, test->exists( obj2 ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + todo_wine ok_ret( TRUE, test->exists( obj3 ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + + /* test deleting objects in shared contexts */ + delete_object( test->type, obj1 ); + todo_wine_if( test->type == OBJ_PROGRAM_OBJECT || test->type == OBJ_PROGRAM_OBJECT_ARB || + test->type == OBJ_SHADER_OBJECT || test->type == OBJ_SHADER_OBJECT_ARB ) + ok_ret( GL_NO_ERROR, glGetError() ); + ok_ret( TRUE, wglMakeCurrent( winhdc, ctx2 ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + todo_wine ok_ret( FALSE, test->exists( obj1 ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_ret( FALSE, test->exists( obj2 ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_ret( TRUE, test->exists( 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 */ + todo_wine ok_ret( FALSE, test->exists( obj1 ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_ret( FALSE, test->exists( obj2 ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_ret( TRUE, test->exists( 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
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
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/opengl32/tests/opengl.c | 77 ++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/dlls/opengl32/tests/opengl.c b/dlls/opengl32/tests/opengl.c index 7c9c5ebeb55..df116c18881 100644 --- a/dlls/opengl32/tests/opengl.c +++ b/dlls/opengl32/tests/opengl.c @@ -1135,6 +1135,38 @@ static const char *debugstr_object_type( enum object_type type ) } } +static BOOL same_object_type( enum object_type a, enum object_type b ) +{ + if (a == b) return TRUE; + if (a == OBJ_BUFFER && b == OBJ_BUFFER_ARB) return TRUE; + if (b == OBJ_BUFFER && a == OBJ_BUFFER_ARB) return TRUE; + if (a == OBJ_FENCE_APPLE && b == OBJ_FENCE_NV) return TRUE; + if (b == OBJ_FENCE_APPLE && a == OBJ_FENCE_NV) return TRUE; + if (a == OBJ_FRAMEBUFFER && b == OBJ_FRAMEBUFFER_EXT) return TRUE; + if (b == OBJ_FRAMEBUFFER && a == OBJ_FRAMEBUFFER_EXT) return TRUE; + if (a == OBJ_PROGRAM_ARB && b == OBJ_PROGRAM_NV) return TRUE; + if (b == OBJ_PROGRAM_ARB && a == OBJ_PROGRAM_NV) return TRUE; + if (a == OBJ_PROGRAM_OBJECT && b == OBJ_PROGRAM_OBJECT_ARB) return TRUE; + if (b == OBJ_PROGRAM_OBJECT && a == OBJ_PROGRAM_OBJECT_ARB) return TRUE; + if (a == OBJ_QUERY && b == OBJ_QUERY_ARB) return TRUE; + if (b == OBJ_QUERY && a == OBJ_QUERY_ARB) return TRUE; + if (b == OBJ_QUERY && a == OBJ_OCCLUSION_QUERY_NV) return TRUE; + if (a == OBJ_QUERY && b == OBJ_OCCLUSION_QUERY_NV) return TRUE; + if (b == OBJ_QUERY_ARB && a == OBJ_OCCLUSION_QUERY_NV) return TRUE; + if (a == OBJ_QUERY_ARB && b == OBJ_OCCLUSION_QUERY_NV) return TRUE; + if (a == OBJ_RENDERBUFFER && b == OBJ_RENDERBUFFER_EXT) return TRUE; + if (b == OBJ_RENDERBUFFER && a == OBJ_RENDERBUFFER_EXT) return TRUE; + if (a == OBJ_SHADER_OBJECT && b == OBJ_SHADER_OBJECT_ARB) return TRUE; + if (b == OBJ_SHADER_OBJECT && a == OBJ_SHADER_OBJECT_ARB) return TRUE; + if (a == OBJ_TEXTURE && b == OBJ_TEXTURE_EXT) return TRUE; + if (b == OBJ_TEXTURE && a == OBJ_TEXTURE_EXT) return TRUE; + if (a == OBJ_TRANSFORM_FEEDBACK && b == OBJ_TRANSFORM_FEEDBACK_NV) return TRUE; + if (b == OBJ_TRANSFORM_FEEDBACK && a == OBJ_TRANSFORM_FEEDBACK_NV) return TRUE; + if (a == OBJ_VERTEX_ARRAY && b == OBJ_VERTEX_ARRAY_APPLE) return TRUE; + if (b == OBJ_VERTEX_ARRAY && a == OBJ_VERTEX_ARRAY_APPLE) return TRUE; + return FALSE; +} + static BOOL create_object( enum object_type type, GLuint name, GLuint *obj ) { switch (type) @@ -1837,6 +1869,40 @@ static void test_sharelists(HDC winhdc) } } + ctx1 = wglCreateContext( winhdc ); + ok_ptr( ctx1, !=, NULL ); + ok_ret( TRUE, wglMakeCurrent( winhdc, ctx1 ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + + for (UINT i = 0, expect = 1; i < ARRAY_SIZE(object_tests); i++) + { + const struct object_test *test = object_tests + i; + GLuint obj; + + if (!test->supported) + { + skip( "Skipping object type %s\n", debugstr_object_type( test->type ) ); + expect--; + continue; + } + + /* aliased object types share the same namespace */ + if (i > 0 && same_object_type( test->type, test[-1].type )) expect++; + /* shaders and programs share the same namespace */ + else if (test->type == OBJ_SHADER_OBJECT || test->type == OBJ_SHADER_OBJECT_ARB) expect++; + else expect = 1; + + winetest_push_context( "%u %s", i, debugstr_object_type( test->type ) ); + + create_object( test->type, 0, &obj ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_u4( obj, ==, expect ); + + winetest_pop_context(); + } + + ok_ret( TRUE, wglDeleteContext( ctx1 ) ); + for (UINT i = 0; i < ARRAY_SIZE(object_tests); i++) { /* some functions don't allow implicit names even in compat contexts */ @@ -1870,6 +1936,17 @@ static void test_sharelists(HDC winhdc) ok_ret( TRUE, test->exists( obj1 ) ); ok_ret( GL_NO_ERROR, glGetError() ); + for (UINT j = 0; j < ARRAY_SIZE(object_tests); j++) + { + const struct object_test *other = object_tests + j; + BOOL expect = i == j || same_object_type(test->type, other->type); + if (!other->exists) continue; + winetest_push_context( "%u %s", j, debugstr_object_type( other->type ) ); + ok_ret( expect, other->exists( obj1 ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + winetest_pop_context(); + } + /* share ctx1 (lists #1) with ctx2 */ ok_ret( TRUE, wglShareLists( ctx1, ctx2 ) ); ok_ret( GL_NO_ERROR, glGetError() ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10739
Jacek Caban (@jacek) commented about dlls/opengl32/tests/opengl.c:
ok_(__FILE__,line)( err == exp, "glGetError returned %x, expected %x\n", err, exp ); }
+#define USE_GL_FUNC( func ) static PFN_ ## func p ## func; +ALL_GL_EXT_FUNCS +ALL_WGL_EXT_FUNCS +#undef USE_GL_FUNC
This will trigger a ton of `-Wunused-but-set-global` on recent Clang. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10739#note_137608
participants (3)
-
Jacek Caban (@jacek) -
Rémi Bernon -
Rémi Bernon (@rbernon)