From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/opengl32/make_opengl | 5 ++- dlls/opengl32/tests/opengl.c | 51 +++++++++++++++++----- dlls/opengl32/unix_thunks.c | 52 ---------------------- dlls/opengl32/unix_wgl.c | 2 + dlls/opengl32/unixlib.h | 15 ------- dlls/opengl32/wgl.c | 66 ++++++++++++++-------------- dlls/win32u/opengl.c | 81 +++++++++++++---------------------- dlls/wineandroid.drv/opengl.c | 6 +-- dlls/winemac.drv/opengl.c | 33 +++++--------- dlls/winewayland.drv/opengl.c | 2 +- dlls/winex11.drv/opengl.c | 39 ++++++----------- include/wine/opengl_driver.h | 13 +++++- include/wine/wgl.h | 2 + 13 files changed, 151 insertions(+), 216 deletions(-) diff --git a/dlls/opengl32/make_opengl b/dlls/opengl32/make_opengl index 791dabf91c4..e0a1ce85962 100755 --- a/dlls/opengl32/make_opengl +++ b/dlls/opengl32/make_opengl @@ -154,6 +154,8 @@ my %manual_win_functions = "wglGetCurrentDC" => 1, "wglGetCurrentReadDCARB" => 1, "wglGetDefaultProcAddress" => 1, + "wglGetExtensionsStringARB" => 1, + "wglGetExtensionsStringEXT" => 1, "wglGetLayerPaletteEntries" => 1, "wglRealizeLayerPalette" => 1, "wglSetLayerPaletteEntries" => 1, @@ -182,8 +184,6 @@ my %manual_win_thunks = "wglCreatePbufferARB" => 1, "wglDeleteContext" => 1, "wglDestroyPbufferARB" => 1, - "wglGetExtensionsStringARB" => 1, - "wglGetExtensionsStringEXT" => 1, "wglGetPixelFormat" => 1, "wglGetPixelFormatAttribfvARB" => 1, "wglGetPixelFormatAttribivARB" => 1, @@ -1497,6 +1497,7 @@ foreach (sort keys %wgl_extensions) printf HEADER " \\\n USE_GL_EXT(\%s)", $_; } print HEADER "\n\n"; +print HEADER "#define WGL_FIRST_EXTENSION " . (sort keys %wgl_extensions)[0] . "\n\n"; print HEADER "#define ALL_WGL_FUNCS"; foreach (sort keys %wgl_functions) { diff --git a/dlls/opengl32/tests/opengl.c b/dlls/opengl32/tests/opengl.c index ed1138c8327..64434c5143b 100644 --- a/dlls/opengl32/tests/opengl.c +++ b/dlls/opengl32/tests/opengl.c @@ -58,6 +58,13 @@ static const char *debugstr_ok( const char *cond ) } while (0) #define ok_ret( e, r ) ok_ex( r, ==, e, UINT, "%#x" ) +#define check_gl_error(exp) check_gl_error_(__LINE__, exp) +static void check_gl_error_( unsigned int line, GLenum exp ) +{ + GLenum err = glGetError(); + ok_(__FILE__,line)( err == exp, "glGetError returned %x, expected %x\n", err, exp ); +} + static NTSTATUS (WINAPI *pD3DKMTCreateDCFromMemory)( D3DKMT_CREATEDCFROMMEMORY *desc ); static NTSTATUS (WINAPI *pD3DKMTDestroyDCFromMemory)( const D3DKMT_DESTROYDCFROMMEMORY *desc ); @@ -66,6 +73,7 @@ static HGLRC (WINAPI *pwglCreateContextAttribsARB)(HDC hDC, HGLRC hShareContext, /* 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); @@ -108,11 +116,12 @@ 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_glFenceSync pglFenceSync; static PFN_glMapBuffer pglMapBuffer; static PFN_glMapBufferRange pglMapBufferRange; static PFN_glMapNamedBuffer pglMapNamedBuffer; @@ -153,6 +162,7 @@ static void init_functions(void) /* WGL_ARB_extensions_string */ GET_PROC(wglGetExtensionsStringARB) + GET_PROC(wglGetExtensionsStringEXT) /* WGL_ARB_make_current_read */ GET_PROC(wglMakeContextCurrentARB); @@ -195,11 +205,12 @@ static void init_functions(void) 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(glFenceSync) GET_PROC(glMapBuffer) GET_PROC(glMapBufferRange) GET_PROC(glMapNamedBuffer) @@ -1702,6 +1713,11 @@ static void test_bitmap_rendering( BOOL use_dib ) ret = wglMakeCurrent( hdc, hglrc ); ok( ret, "wglMakeCurrent failed, error %lu\n", GetLastError() ); + pwglGetExtensionsStringEXT = (void *)wglGetProcAddress( "wglGetExtensionsStringEXT" ); + todo_wine ok(!pwglGetExtensionsStringEXT, "got wglGetExtensionsStringEXT %p\n", pwglGetExtensionsStringEXT); + pwglGetExtensionsStringARB = (void *)wglGetProcAddress( "wglGetExtensionsStringARB" ); + todo_wine ok(!pwglGetExtensionsStringARB, "got wglGetExtensionsStringARB %p\n", pwglGetExtensionsStringARB); + glGetIntegerv( GL_READ_BUFFER, &object ); ok( object == GL_FRONT, "got %u\n", object ); glGetIntegerv( GL_DRAW_BUFFER, &object ); @@ -2430,6 +2446,8 @@ static void test_opengl3(HDC hdc) { int attribs[] = {WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 0, 0}; HGLRC gl3Ctx = pwglCreateContextAttribsARB(hdc, 0, attribs); + const GLubyte *ext; + GLint num; if(gl3Ctx == NULL) { @@ -2437,6 +2455,18 @@ static void test_opengl3(HDC hdc) return; } + wglMakeCurrent(hdc, gl3Ctx); + + glGetIntegerv(GL_NUM_EXTENSIONS, &num); + ok(num > 0, "got %u\n", num); + check_gl_error(0); + ext = pglGetStringi(GL_EXTENSIONS, 0); + ok(!!ext, "got %p\n", ext); + check_gl_error(0); + ext = pglGetStringi(GL_EXTENSIONS, num); + ok(!ext, "got %p\n", ext); + check_gl_error(GL_INVALID_VALUE); + wglDeleteContext(gl3Ctx); } @@ -3577,13 +3607,6 @@ static void test_child_window(HWND hwnd, PIXELFORMATDESCRIPTOR *pfd) DestroyWindow(child); } -#define check_gl_error(exp) check_gl_error_(__LINE__, exp) -static void check_gl_error_( unsigned int line, GLenum exp ) -{ - GLenum err = glGetError(); - ok_(__FILE__,line)( err == exp, "glGetError returned %x, expected %x\n", err, exp ); -} - static void test_gl_error( HDC hdc ) { HGLRC rc, old_rc; @@ -3888,6 +3911,7 @@ START_TEST(opengl) HMODULE gdi32 = GetModuleHandleA("gdi32.dll"); HDC hdc; int iPixelFormat, res; + const char *tmp; HGLRC hglrc; DWORD error; @@ -3976,7 +4000,14 @@ START_TEST(opengl) test_memory_map(hdc); test_gl_error(hdc); - wgl_extensions = pwglGetExtensionsStringARB(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")) diff --git a/dlls/opengl32/unix_thunks.c b/dlls/opengl32/unix_thunks.c index 75a8baf0e55..164564c951c 100644 --- a/dlls/opengl32/unix_thunks.c +++ b/dlls/opengl32/unix_thunks.c @@ -30407,24 +30407,6 @@ static NTSTATUS ext_wglFreeMemoryNV( void *args ) return STATUS_SUCCESS; } -static NTSTATUS ext_wglGetExtensionsStringARB( void *args ) -{ - struct wglGetExtensionsStringARB_params *params = args; - const struct opengl_funcs *funcs = get_dc_funcs( params->hdc ); - if (!funcs || !funcs->p_wglGetExtensionsStringARB) return STATUS_NOT_IMPLEMENTED; - params->ret = funcs->p_wglGetExtensionsStringARB( params->hdc ); - return STATUS_SUCCESS; -} - -static NTSTATUS ext_wglGetExtensionsStringEXT( void *args ) -{ - struct wglGetExtensionsStringEXT_params *params = args; - const struct opengl_funcs *funcs = params->teb->glTable; - if (!funcs->p_wglGetExtensionsStringEXT) return STATUS_NOT_IMPLEMENTED; - params->ret = funcs->p_wglGetExtensionsStringEXT(); - return STATUS_SUCCESS; -} - static NTSTATUS ext_wglGetPbufferDCARB( void *args ) { struct wglGetPbufferDCARB_params *params = args; @@ -33649,8 +33631,6 @@ const unixlib_entry_t __wine_unix_call_funcs[] = ext_wglCreatePbufferARB, ext_wglDestroyPbufferARB, ext_wglFreeMemoryNV, - ext_wglGetExtensionsStringARB, - ext_wglGetExtensionsStringEXT, ext_wglGetPbufferDCARB, ext_wglGetPixelFormatAttribfvARB, ext_wglGetPixelFormatAttribivARB, @@ -86721,36 +86701,6 @@ static NTSTATUS wow64_ext_wglFreeMemoryNV( void *args ) return STATUS_SUCCESS; } -static NTSTATUS wow64_ext_wglGetExtensionsStringARB( void *args ) -{ - struct - { - PTR32 teb; - PTR32 hdc; - PTR32 ret; - } *params = args; - const char *ret; - const struct opengl_funcs *funcs = get_dc_funcs( ULongToPtr(params->hdc) ); - if (!funcs || !funcs->p_wglGetExtensionsStringARB) return STATUS_NOT_IMPLEMENTED; - ret = funcs->p_wglGetExtensionsStringARB( ULongToPtr(params->hdc) ); - return return_wow64_string( ret, ¶ms->ret ); -} - -static NTSTATUS wow64_ext_wglGetExtensionsStringEXT( void *args ) -{ - struct - { - PTR32 teb; - PTR32 ret; - } *params = args; - TEB *teb = get_teb64( params->teb ); - const char *ret; - const struct opengl_funcs *funcs = teb->glTable; - if (!funcs->p_wglGetExtensionsStringEXT) return STATUS_NOT_IMPLEMENTED; - ret = funcs->p_wglGetExtensionsStringEXT(); - return return_wow64_string( ret, ¶ms->ret ); -} - static NTSTATUS wow64_ext_wglGetPbufferDCARB( void *args ) { struct @@ -90081,8 +90031,6 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] = wow64_ext_wglCreatePbufferARB, wow64_ext_wglDestroyPbufferARB, wow64_ext_wglFreeMemoryNV, - wow64_ext_wglGetExtensionsStringARB, - wow64_ext_wglGetExtensionsStringEXT, wow64_ext_wglGetPbufferDCARB, wow64_ext_wglGetPixelFormatAttribfvARB, wow64_ext_wglGetPixelFormatAttribivARB, diff --git a/dlls/opengl32/unix_wgl.c b/dlls/opengl32/unix_wgl.c index 9fdb63954d6..e21a8452908 100644 --- a/dlls/opengl32/unix_wgl.c +++ b/dlls/opengl32/unix_wgl.c @@ -1199,6 +1199,8 @@ static void make_context_current( TEB *teb, const struct opengl_funcs *funcs, HD if (!client->major_version) client->major_version = 1; TRACE( "context %p version %d.%d\n", ctx, client->major_version, client->minor_version ); + funcs->p_init_extensions( client->extensions ); + if (funcs->p_glImportMemoryWin32HandleEXT) size++; if (funcs->p_glImportSemaphoreWin32HandleEXT) size++; diff --git a/dlls/opengl32/unixlib.h b/dlls/opengl32/unixlib.h index 0731b244c01..bf75c744e0a 100644 --- a/dlls/opengl32/unixlib.h +++ b/dlls/opengl32/unixlib.h @@ -25733,19 +25733,6 @@ struct wglFreeMemoryNV_params void *pointer; }; -struct wglGetExtensionsStringARB_params -{ - TEB *teb; - HDC hdc; - const char *ret; -}; - -struct wglGetExtensionsStringEXT_params -{ - TEB *teb; - const char *ret; -}; - struct wglGetPbufferDCARB_params { TEB *teb; @@ -28975,8 +28962,6 @@ enum unix_funcs unix_wglCreatePbufferARB, unix_wglDestroyPbufferARB, unix_wglFreeMemoryNV, - unix_wglGetExtensionsStringARB, - unix_wglGetExtensionsStringEXT, unix_wglGetPbufferDCARB, unix_wglGetPixelFormatAttribfvARB, unix_wglGetPixelFormatAttribivARB, diff --git a/dlls/opengl32/wgl.c b/dlls/opengl32/wgl.c index 7de83b78a47..acbd13ba856 100644 --- a/dlls/opengl32/wgl.c +++ b/dlls/opengl32/wgl.c @@ -56,6 +56,11 @@ static CRITICAL_SECTION_DEBUG wgl_cs_debug = { 0, 0, { (DWORD_PTR)(__FILE__ ": wgl_cs") } }; static CRITICAL_SECTION wgl_cs = { &wgl_cs_debug, -1, 0, 0, 0, 0 }; +static char *wgl_extensions; + +#define USE_GL_EXT(x) #x +static const char *extension_names[] = { ALL_GL_EXTS ALL_WGL_EXTS }; +#undef USE_GL_EXT #ifndef _WIN64 @@ -97,6 +102,23 @@ static void cleanup_wow64_strings(void) #endif +static void init_wgl_extensions( const BOOLEAN extensions[GL_EXTENSION_COUNT] ) +{ + UINT pos = 0, len = 0, ext; + char *str; + + for (ext = WGL_FIRST_EXTENSION; ext < GL_EXTENSION_COUNT; ext++) + if (extensions[ext]) len += strlen( extension_names[ext] ) + 1; + + if (!(str = malloc( len + 1 ))) return; + + for (ext = WGL_FIRST_EXTENSION; ext < GL_EXTENSION_COUNT; ext++) + if (extensions[ext]) pos += sprintf( str + pos, "%s ", extension_names[ext] ); + str[pos - 1] = 0; + + wgl_extensions = str; +} + struct handle_entry { UINT handle; @@ -1333,14 +1355,24 @@ int WINAPI wglGetLayerPaletteEntries( HDC hdc, int plane, int start, int count, PROC WINAPI wglGetProcAddress( LPCSTR name ) { struct wglGetProcAddress_params args = { .teb = NtCurrentTeb(), .lpszProc = name }; + struct context *ctx; const void *proc; NTSTATUS status; if (!name) return NULL; + if (!(ctx = context_from_handle( NtCurrentTeb()->glCurrentRC ))) return NULL; + if ((status = UNIX_CALL( wglGetProcAddress, &args ))) WARN( "wglGetProcAddress %s returned %#lx\n", debugstr_a(name), status ); if (args.ret == (void *)-1) return NULL; + if (!strncmp( name, "wglGetExtensionsString", 22 )) + { + EnterCriticalSection( &wgl_cs ); + if (!wgl_extensions) init_wgl_extensions( ctx->base.extensions ); + LeaveCriticalSection( &wgl_cs ); + } + proc = extension_procs[(UINT_PTR)args.ret]; TRACE( "returning %s -> %p\n", name, proc ); return proc; @@ -2127,44 +2159,14 @@ void WINAPI glGetIntegerv( GLenum pname, GLint *data ) const char * WINAPI wglGetExtensionsStringARB( HDC hdc ) { - struct wglGetExtensionsStringARB_params args = { .teb = NtCurrentTeb(), .hdc = hdc }; - NTSTATUS status; -#ifndef _WIN64 - char *wow64_str = NULL; -#endif - TRACE( "hdc %p\n", hdc ); - -#ifndef _WIN64 - if (UNIX_CALL( wglGetExtensionsStringARB, &args ) == STATUS_BUFFER_TOO_SMALL) args.ret = wow64_str = malloc( (size_t)args.ret ); -#endif - if ((status = UNIX_CALL( wglGetExtensionsStringARB, &args ))) WARN( "wglGetExtensionsStringARB returned %#lx\n", status ); -#ifndef _WIN64 - if (args.ret != wow64_str) free( wow64_str ); - else if (args.ret) append_wow64_string( wow64_str ); -#endif - return args.ret; + return wgl_extensions; } const char * WINAPI wglGetExtensionsStringEXT(void) { - struct wglGetExtensionsStringEXT_params args = { .teb = NtCurrentTeb() }; - NTSTATUS status; -#ifndef _WIN64 - char *wow64_str = NULL; -#endif - TRACE( "\n" ); - -#ifndef _WIN64 - if (UNIX_CALL( wglGetExtensionsStringEXT, &args ) == STATUS_BUFFER_TOO_SMALL) args.ret = wow64_str = malloc( (size_t)args.ret ); -#endif - if ((status = UNIX_CALL( wglGetExtensionsStringEXT, &args ))) WARN( "wglGetExtensionsStringEXT returned %#lx\n", status ); -#ifndef _WIN64 - if (args.ret != wow64_str) free( wow64_str ); - else if (args.ret) append_wow64_string( wow64_str ); -#endif - return args.ret; + return wgl_extensions; } const GLchar * WINAPI wglQueryCurrentRendererStringWINE( GLenum attribute ) diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 6452ab019ed..28050d9a94c 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -63,9 +63,9 @@ static struct list devices_egl = LIST_INIT( devices_egl ); static struct egl_platform display_egl; static struct opengl_funcs display_funcs; +static BOOLEAN global_extensions[GL_EXTENSION_COUNT]; static struct wgl_pixel_format *pixel_formats; static UINT formats_count, onscreen_count; -static char wgl_extensions[4096]; static BOOL has_extension( const char *list, const char *ext ) { @@ -98,17 +98,6 @@ static void dump_extensions( const char *list ) TRACE( "%s\n", start ); } -static void register_extension( char *list, size_t size, const char *name ) -{ - if (!has_extension( list, name )) - { - size_t len = strlen( list ); - assert( size - len >= strlen( name ) + 1 ); - if (*list) strcat( list + len, " " ); - strcat( list + len, name ); - } -} - void *opengl_drawable_create( UINT size, const struct opengl_drawable_funcs *funcs, int format, struct client_surface *client ) { struct opengl_drawable *drawable; @@ -651,9 +640,8 @@ static BOOL egldrv_describe_pixel_format( int format, struct wgl_pixel_format *d return describe_egl_config( egl->configs[format % count], desc, pixel_format_flags[format / count] ); } -static const char *egldrv_init_wgl_extensions( struct opengl_funcs *funcs ) +static void egldrv_init_extensions( struct opengl_funcs *funcs, BOOLEAN extensions[GL_EXTENSION_COUNT] ) { - return ""; } static BOOL egldrv_surface_create( HWND hwnd, int format, struct opengl_drawable **drawable ) @@ -862,7 +850,7 @@ static const struct opengl_driver_funcs egldrv_funcs = .p_get_proc_address = egldrv_get_proc_address, .p_init_pixel_formats = egldrv_init_pixel_formats, .p_describe_pixel_format = egldrv_describe_pixel_format, - .p_init_wgl_extensions = egldrv_init_wgl_extensions, + .p_init_extensions = egldrv_init_extensions, .p_surface_create = egldrv_surface_create, .p_pbuffer_create = egldrv_pbuffer_create, .p_pbuffer_updated = egldrv_pbuffer_updated, @@ -1268,9 +1256,8 @@ static BOOL nulldrv_describe_pixel_format( int format, struct wgl_pixel_format * return TRUE; } -static const char *nulldrv_init_wgl_extensions( struct opengl_funcs *funcs ) +static void nulldrv_init_extensions( struct opengl_funcs *funcs, BOOLEAN extensions[GL_EXTENSION_COUNT] ) { - return ""; } static BOOL nulldrv_surface_create( HWND hwnd, int format, struct opengl_drawable **drawable ) @@ -1314,7 +1301,7 @@ static const struct opengl_driver_funcs nulldrv_funcs = .p_get_proc_address = nulldrv_get_proc_address, .p_init_pixel_formats = nulldrv_init_pixel_formats, .p_describe_pixel_format = nulldrv_describe_pixel_format, - .p_init_wgl_extensions = nulldrv_init_wgl_extensions, + .p_init_extensions = nulldrv_init_extensions, .p_surface_create = nulldrv_surface_create, .p_pbuffer_create = nulldrv_pbuffer_create, .p_pbuffer_updated = nulldrv_pbuffer_updated, @@ -1324,20 +1311,6 @@ static const struct opengl_driver_funcs nulldrv_funcs = .p_make_current = nulldrv_make_current, }; -static const char *win32u_wglGetExtensionsStringARB( HDC hdc ) -{ - TRACE( "hdc %p\n", hdc ); - if (TRACE_ON(wgl)) dump_extensions( wgl_extensions ); - return wgl_extensions; -} - -static const char *win32u_wglGetExtensionsStringEXT(void) -{ - TRACE( "\n" ); - if (TRACE_ON(wgl)) dump_extensions( wgl_extensions ); - return wgl_extensions; -} - static int win32u_wglGetPixelFormat( HDC hdc ) { BOOL is_display = is_dc_display( hdc ); @@ -1760,6 +1733,11 @@ static PROC win32u_wglGetProcAddress( const char *name ) return ret; } +static void win32u_init_extensions( BOOLEAN extensions[GL_EXTENSION_COUNT] ) +{ + memcpy( extensions, global_extensions, sizeof(global_extensions) ); +} + static void win32u_get_pixel_formats( struct wgl_pixel_format *formats, UINT max_formats, UINT *num_formats, UINT *num_onscreen_formats ) { @@ -2728,9 +2706,10 @@ static void display_funcs_init(void) #undef USE_GL_FUNC display_funcs.p_wglGetProcAddress = win32u_wglGetProcAddress; + display_funcs.p_init_extensions = win32u_init_extensions; display_funcs.p_get_pixel_formats = win32u_get_pixel_formats; - strcpy( wgl_extensions, driver_funcs->p_init_wgl_extensions( &display_funcs ) ); + driver_funcs->p_init_extensions( &display_funcs, global_extensions ); display_funcs.p_wglGetPixelFormat = win32u_wglGetPixelFormat; display_funcs.p_wglSetPixelFormat = win32u_wglSetPixelFormat; @@ -2746,54 +2725,54 @@ static void display_funcs_init(void) display_funcs.p_context_destroy = win32u_context_destroy; display_funcs.p_context_reset = win32u_context_reset; - register_extension( wgl_extensions, ARRAY_SIZE(wgl_extensions), "WGL_ARB_multisample" ); + global_extensions[WGL_ARB_multisample] = 1; - register_extension( wgl_extensions, ARRAY_SIZE(wgl_extensions), "WGL_ARB_pixel_format" ); + global_extensions[WGL_ARB_pixel_format] = 1; display_funcs.p_wglChoosePixelFormatARB = (void *)1; /* never called */ display_funcs.p_wglGetPixelFormatAttribfvARB = (void *)1; /* never called */ display_funcs.p_wglGetPixelFormatAttribivARB = (void *)1; /* never called */ if (display_egl.has_EGL_EXT_pixel_format_float) { - register_extension( wgl_extensions, ARRAY_SIZE(wgl_extensions), "WGL_ARB_pixel_format_float" ); - register_extension( wgl_extensions, ARRAY_SIZE(wgl_extensions), "WGL_ATI_pixel_format_float" ); + global_extensions[WGL_ARB_pixel_format_float] = 1; + global_extensions[WGL_ATI_pixel_format_float] = 1; } - register_extension( wgl_extensions, ARRAY_SIZE(wgl_extensions), "WGL_ARB_extensions_string" ); - display_funcs.p_wglGetExtensionsStringARB = win32u_wglGetExtensionsStringARB; + global_extensions[WGL_ARB_extensions_string] = 1; + display_funcs.p_wglGetExtensionsStringARB = (void *)1 /* never called */; - register_extension( wgl_extensions, ARRAY_SIZE(wgl_extensions), "WGL_EXT_extensions_string" ); - display_funcs.p_wglGetExtensionsStringEXT = win32u_wglGetExtensionsStringEXT; + global_extensions[WGL_EXT_extensions_string] = 1; + display_funcs.p_wglGetExtensionsStringEXT = (void *)1 /* never called */; /* In WineD3D we need the ability to set the pixel format more than once (e.g. after a device reset). * The default wglSetPixelFormat doesn't allow this, so add our own which allows it. */ - register_extension( wgl_extensions, ARRAY_SIZE(wgl_extensions), "WGL_WINE_pixel_format_passthrough" ); + global_extensions[WGL_WINE_pixel_format_passthrough] = 1; display_funcs.p_wglSetPixelFormatWINE = win32u_wglSetPixelFormatWINE; - register_extension( wgl_extensions, ARRAY_SIZE(wgl_extensions), "WGL_ARB_create_context" ); - register_extension( wgl_extensions, ARRAY_SIZE(wgl_extensions), "WGL_ARB_create_context_no_error" ); - register_extension( wgl_extensions, ARRAY_SIZE(wgl_extensions), "WGL_ARB_create_context_profile" ); + global_extensions[WGL_ARB_create_context] = 1; + global_extensions[WGL_ARB_create_context_no_error] = 1; + global_extensions[WGL_ARB_create_context_profile] = 1; display_funcs.p_wglCreateContextAttribsARB = (void *)1; /* never called */ - register_extension( wgl_extensions, ARRAY_SIZE(wgl_extensions), "WGL_ARB_make_current_read" ); + global_extensions[WGL_ARB_make_current_read] = 1; display_funcs.p_wglGetCurrentReadDCARB = (void *)1; /* never called */ display_funcs.p_wglMakeContextCurrentARB = win32u_wglMakeContextCurrentARB; - register_extension( wgl_extensions, ARRAY_SIZE(wgl_extensions), "WGL_ARB_pbuffer" ); + global_extensions[WGL_ARB_pbuffer] = 1; display_funcs.p_wglCreatePbufferARB = win32u_wglCreatePbufferARB; display_funcs.p_wglDestroyPbufferARB = win32u_wglDestroyPbufferARB; display_funcs.p_wglGetPbufferDCARB = win32u_wglGetPbufferDCARB; display_funcs.p_wglReleasePbufferDCARB = win32u_wglReleasePbufferDCARB; display_funcs.p_wglQueryPbufferARB = win32u_wglQueryPbufferARB; - register_extension( wgl_extensions, ARRAY_SIZE(wgl_extensions), "WGL_ARB_render_texture" ); + global_extensions[WGL_ARB_render_texture] = 1; display_funcs.p_wglBindTexImageARB = win32u_wglBindTexImageARB; display_funcs.p_wglReleaseTexImageARB = win32u_wglReleaseTexImageARB; display_funcs.p_wglSetPbufferAttribARB = win32u_wglSetPbufferAttribARB; - register_extension( wgl_extensions, ARRAY_SIZE(wgl_extensions), "WGL_EXT_swap_control" ); - register_extension( wgl_extensions, ARRAY_SIZE(wgl_extensions), "WGL_EXT_swap_control_tear" ); + global_extensions[WGL_EXT_swap_control] = 1; + global_extensions[WGL_EXT_swap_control_tear] = 1; display_funcs.p_wglSwapIntervalEXT = win32u_wglSwapIntervalEXT; display_funcs.p_wglGetSwapIntervalEXT = win32u_wglGetSwapIntervalEXT; @@ -2810,7 +2789,7 @@ static void display_funcs_init(void) if (!list_empty( &devices_egl )) { - register_extension( wgl_extensions, ARRAY_SIZE(wgl_extensions), "WGL_WINE_query_renderer" ); + global_extensions[WGL_WINE_query_renderer] = 1; display_funcs.p_query_renderer = win32u_query_renderer; display_funcs.p_wglQueryCurrentRendererIntegerWINE = win32u_wglQueryCurrentRendererIntegerWINE; display_funcs.p_wglQueryCurrentRendererStringWINE = win32u_wglQueryCurrentRendererStringWINE; diff --git a/dlls/wineandroid.drv/opengl.c b/dlls/wineandroid.drv/opengl.c index 0460dfd50b4..62b4fa7dd6c 100644 --- a/dlls/wineandroid.drv/opengl.c +++ b/dlls/wineandroid.drv/opengl.c @@ -156,16 +156,16 @@ static void android_drawable_flush( struct opengl_drawable *base, UINT flags ) if (flags & GL_FLUSH_INTERVAL) funcs->p_eglSwapInterval( egl->display, abs( base->interval ) ); } -static const char *android_init_wgl_extensions( struct opengl_funcs *funcs ) +static void android_init_extensions( struct opengl_funcs *funcs, BOOLEAN extensions[GL_EXTENSION_COUNT] ) { - return "WGL_EXT_framebuffer_sRGB"; + extensions[WGL_EXT_framebuffer_sRGB] = 1; } static struct opengl_driver_funcs android_driver_funcs = { .p_init_egl_platform = android_init_egl_platform, .p_get_proc_address = android_get_proc_address, - .p_init_wgl_extensions = android_init_wgl_extensions, + .p_init_extensions = android_init_extensions, .p_surface_create = android_surface_create, }; diff --git a/dlls/winemac.drv/opengl.c b/dlls/winemac.drv/opengl.c index 7040bbd5a8d..0af1d3f7192 100644 --- a/dlls/winemac.drv/opengl.c +++ b/dlls/winemac.drv/opengl.c @@ -46,8 +46,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(wgl); struct gl_info { char *glExtensions; - char wglExtensions[4096]; - GLint max_viewport_dims[2]; unsigned int max_major, max_minor; @@ -2542,16 +2540,7 @@ static BOOL macdrv_pbuffer_updated(HDC hdc, struct opengl_drawable *base, GLenum return GL_TRUE; } -static void register_extension(const char *ext) -{ - if (gl_info.wglExtensions[0]) - strcat(gl_info.wglExtensions, " "); - strcat(gl_info.wglExtensions, ext); - - TRACE("'%s'\n", ext); -} - -static const char *macdrv_init_wgl_extensions(struct opengl_funcs *funcs) +static void macdrv_init_extensions(struct opengl_funcs *funcs, BOOLEAN extensions[GL_EXTENSION_COUNT]) { /* * ARB Extensions @@ -2559,42 +2548,40 @@ static const char *macdrv_init_wgl_extensions(struct opengl_funcs *funcs) if (gluCheckExtension((GLubyte*)"GL_ARB_color_buffer_float", (GLubyte*)gl_info.glExtensions)) { - register_extension("WGL_ARB_pixel_format_float"); - register_extension("WGL_ATI_pixel_format_float"); + extensions[WGL_ARB_pixel_format_float] = 1; + extensions[WGL_ATI_pixel_format_float] = 1; } if (gluCheckExtension((GLubyte*)"GL_ARB_multisample", (GLubyte*)gl_info.glExtensions)) - register_extension("WGL_ARB_multisample"); + extensions[WGL_ARB_multisample] = 1; if (gluCheckExtension((GLubyte*)"GL_ARB_framebuffer_sRGB", (GLubyte*)gl_info.glExtensions)) - register_extension("WGL_ARB_framebuffer_sRGB"); + extensions[WGL_ARB_framebuffer_sRGB] = 1; if (gluCheckExtension((GLubyte*)"GL_APPLE_pixel_buffer", (GLubyte*)gl_info.glExtensions)) { if (gluCheckExtension((GLubyte*)"GL_ARB_texture_rectangle", (GLubyte*)gl_info.glExtensions) || gluCheckExtension((GLubyte*)"GL_EXT_texture_rectangle", (GLubyte*)gl_info.glExtensions)) - register_extension("WGL_NV_render_texture_rectangle"); + extensions[WGL_NV_render_texture_rectangle] = 1; } /* Presumably identical to [W]GL_ARB_framebuffer_sRGB, above, but clients may check for either, so register them separately. */ if (gluCheckExtension((GLubyte*)"GL_EXT_framebuffer_sRGB", (GLubyte*)gl_info.glExtensions)) - register_extension("WGL_EXT_framebuffer_sRGB"); + extensions[WGL_EXT_framebuffer_sRGB] = 1; if (gluCheckExtension((GLubyte*)"GL_EXT_packed_float", (GLubyte*)gl_info.glExtensions)) - register_extension("WGL_EXT_pixel_format_packed_float"); + extensions[WGL_EXT_pixel_format_packed_float] = 1; /* * WINE-specific WGL Extensions */ - register_extension("WGL_WINE_query_renderer"); + extensions[WGL_WINE_query_renderer] = 1; funcs->p_wglQueryCurrentRendererIntegerWINE = macdrv_wglQueryCurrentRendererIntegerWINE; funcs->p_wglQueryCurrentRendererStringWINE = macdrv_wglQueryCurrentRendererStringWINE; funcs->p_wglQueryRendererIntegerWINE = macdrv_wglQueryRendererIntegerWINE; funcs->p_wglQueryRendererStringWINE = macdrv_wglQueryRendererStringWINE; - - return gl_info.wglExtensions; } /********************************************************************** @@ -2780,7 +2767,7 @@ static const struct opengl_driver_funcs macdrv_driver_funcs = .p_get_proc_address = macdrv_get_proc_address, .p_init_pixel_formats = macdrv_init_pixel_formats, .p_describe_pixel_format = macdrv_describe_pixel_format, - .p_init_wgl_extensions = macdrv_init_wgl_extensions, + .p_init_extensions = macdrv_init_extensions, .p_surface_create = macdrv_surface_create, .p_context_create = macdrv_context_create, .p_context_destroy = macdrv_context_destroy, diff --git a/dlls/winewayland.drv/opengl.c b/dlls/winewayland.drv/opengl.c index 54ba94fe846..1486e411734 100644 --- a/dlls/winewayland.drv/opengl.c +++ b/dlls/winewayland.drv/opengl.c @@ -258,7 +258,7 @@ UINT WAYLAND_OpenGLInit(UINT version, const struct opengl_funcs *opengl_funcs, c wayland_driver_funcs.p_get_proc_address = (*driver_funcs)->p_get_proc_address; wayland_driver_funcs.p_init_pixel_formats = (*driver_funcs)->p_init_pixel_formats; wayland_driver_funcs.p_describe_pixel_format = (*driver_funcs)->p_describe_pixel_format; - wayland_driver_funcs.p_init_wgl_extensions = (*driver_funcs)->p_init_wgl_extensions; + wayland_driver_funcs.p_init_extensions = (*driver_funcs)->p_init_extensions; wayland_driver_funcs.p_context_create = (*driver_funcs)->p_context_create; wayland_driver_funcs.p_context_destroy = (*driver_funcs)->p_context_destroy; wayland_driver_funcs.p_make_current = (*driver_funcs)->p_make_current; diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index 895d3815e7c..7ebc2c43753 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -180,7 +180,6 @@ typedef XID GLXPbuffer; static const char *glExtensions; static const char *glxExtensions; -static char wglExtensions[4096]; static int glxVersion[2]; static int glx_opcode; @@ -1375,29 +1374,19 @@ static BOOL glxRequireVersion(int requiredVersion) return (requiredVersion <= glxVersion[1]); } -static void register_extension(const char *ext) +static void x11drv_init_extensions( struct opengl_funcs *funcs, BOOLEAN extensions[GL_EXTENSION_COUNT] ) { - if (wglExtensions[0]) - strcat(wglExtensions, " "); - strcat(wglExtensions, ext); - - TRACE("'%s'\n", ext); -} - -static const char *x11drv_init_wgl_extensions( struct opengl_funcs *funcs ) -{ - wglExtensions[0] = 0; - /* ARB Extensions */ - if (has_extension( glxExtensions, "GLX_ARB_multisample")) register_extension( "WGL_ARB_multisample" ); + if (has_extension( glxExtensions, "GLX_ARB_multisample")) + extensions[WGL_ARB_multisample] = 1; - register_extension("WGL_ARB_pixel_format"); + extensions[WGL_ARB_pixel_format] = 1; if (has_extension( glxExtensions, "GLX_ARB_fbconfig_float")) { - register_extension("WGL_ARB_pixel_format_float"); - register_extension("WGL_ATI_pixel_format_float"); + extensions[WGL_ARB_pixel_format_float] = 1; + extensions[WGL_ATI_pixel_format_float] = 1; } /* Support WGL_ARB_render_texture when there's support or pbuffer based emulation */ @@ -1405,20 +1394,20 @@ static const char *x11drv_init_wgl_extensions( struct opengl_funcs *funcs ) { /* The WGL version of GLX_NV_float_buffer requires render_texture */ if (has_extension( glxExtensions, "GLX_NV_float_buffer")) - register_extension("WGL_NV_float_buffer"); + extensions[WGL_NV_float_buffer] = 1; /* Again there's no GLX equivalent for this extension, so depend on the required GL extension */ if (has_extension(glExtensions, "GL_NV_texture_rectangle")) - register_extension("WGL_NV_render_texture_rectangle"); + extensions[WGL_NV_render_texture_rectangle] = 1; } /* EXT Extensions */ if (has_extension( glxExtensions, "GLX_EXT_framebuffer_sRGB")) - register_extension("WGL_EXT_framebuffer_sRGB"); + extensions[WGL_EXT_framebuffer_sRGB] = 1; if (has_extension( glxExtensions, "GLX_EXT_fbconfig_packed_float")) - register_extension("WGL_EXT_pixel_format_packed_float"); + extensions[WGL_EXT_pixel_format_packed_float] = 1; if (has_extension( glxExtensions, "GLX_EXT_swap_control")) { @@ -1437,7 +1426,7 @@ static const char *x11drv_init_wgl_extensions( struct opengl_funcs *funcs ) /* The OpenGL extension GL_NV_vertex_array_range adds wgl/glX functions which aren't exported as 'real' wgl/glX extensions. */ if (has_extension(glExtensions, "GL_NV_vertex_array_range")) { - register_extension( "WGL_NV_vertex_array_range" ); + extensions[WGL_NV_vertex_array_range] = 1; funcs->p_wglAllocateMemoryNV = pglXAllocateMemoryNV; funcs->p_wglFreeMemoryNV = pglXFreeMemoryNV; } @@ -1449,14 +1438,12 @@ static const char *x11drv_init_wgl_extensions( struct opengl_funcs *funcs ) if (has_extension( glxExtensions, "GLX_MESA_query_renderer" )) { - register_extension( "WGL_WINE_query_renderer" ); + extensions[WGL_WINE_query_renderer] = 1; funcs->p_wglQueryCurrentRendererIntegerWINE = X11DRV_wglQueryCurrentRendererIntegerWINE; funcs->p_wglQueryCurrentRendererStringWINE = X11DRV_wglQueryCurrentRendererStringWINE; funcs->p_wglQueryRendererIntegerWINE = X11DRV_wglQueryRendererIntegerWINE; funcs->p_wglQueryRendererStringWINE = X11DRV_wglQueryRendererStringWINE; } - - return wglExtensions; } static BOOL x11drv_surface_swap( struct opengl_drawable *base ) @@ -1524,7 +1511,7 @@ static struct opengl_driver_funcs x11drv_driver_funcs = .p_get_proc_address = x11drv_get_proc_address, .p_init_pixel_formats = x11drv_init_pixel_formats, .p_describe_pixel_format = x11drv_describe_pixel_format, - .p_init_wgl_extensions = x11drv_init_wgl_extensions, + .p_init_extensions = x11drv_init_extensions, .p_surface_create = x11drv_surface_create, .p_context_create = x11drv_context_create, .p_context_destroy = x11drv_context_destroy, diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index 2ba20f799d1..744b79a3525 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -59,6 +59,15 @@ struct wgl_pixel_format int float_components; }; +enum opengl_extension +{ +#define USE_GL_EXT(x) x, + ALL_GL_EXTS + ALL_WGL_EXTS +#undef USE_GL_EXT + GL_EXTENSION_COUNT, +}; + struct opengl_client_context { struct HGLRC__ obj; /* client object header */ @@ -67,6 +76,7 @@ struct opengl_client_context GLenum last_error; int major_version; int minor_version; + BOOLEAN extensions[GL_EXTENSION_COUNT]; /* exposed client extensions */ }; static inline struct opengl_client_context *opengl_client_context_from_client( HGLRC client_context ) @@ -128,6 +138,7 @@ struct opengl_funcs ALL_GL_FUNCS ALL_GL_EXT_FUNCS #undef USE_GL_FUNC + void (*p_init_extensions)( BOOLEAN extensions[GL_EXTENSION_COUNT] ); void (*p_get_pixel_formats)( struct wgl_pixel_format *formats, UINT max_formats, UINT *num_formats, UINT *num_onscreen_formats ); BOOL (*p_query_renderer)( UINT attribute, void *value ); BOOL (*p_context_flush)( struct opengl_context *context, void (*flush)(void), UINT flags ); @@ -223,7 +234,7 @@ struct opengl_driver_funcs void *(*p_get_proc_address)(const char *); UINT (*p_init_pixel_formats)(UINT*); BOOL (*p_describe_pixel_format)(int,struct wgl_pixel_format*); - const char *(*p_init_wgl_extensions)(struct opengl_funcs *funcs); + void (*p_init_extensions)( struct opengl_funcs *funcs, BOOLEAN extensions[GL_EXTENSION_COUNT] ); BOOL (*p_surface_create)( HWND hwnd, int format, struct opengl_drawable **drawable ); BOOL (*p_context_create)( int format, void *share, const int *attribs, void **context ); BOOL (*p_context_destroy)(void*); diff --git a/include/wine/wgl.h b/include/wine/wgl.h index e6d2849f5ce..54165021439 100644 --- a/include/wine/wgl.h +++ b/include/wine/wgl.h @@ -9892,6 +9892,8 @@ typedef BOOL (GLAPIENTRY *PFN_wglSwapIntervalEXT)( int interval ); USE_GL_EXT(WGL_WINE_pixel_format_passthrough) \ USE_GL_EXT(WGL_WINE_query_renderer) +#define WGL_FIRST_EXTENSION WGL_3DFX_multisample + #define ALL_WGL_FUNCS \ USE_GL_FUNC(wglChoosePixelFormat) \ USE_GL_FUNC(wglCopyContext) \ -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10349