From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/opengl32/unix_wgl.c | 56 ++++++++++++++++++++++++++++++++++++ include/wine/opengl_driver.h | 10 +++++++ 2 files changed, 66 insertions(+) diff --git a/dlls/opengl32/unix_wgl.c b/dlls/opengl32/unix_wgl.c index 73092486ce8..5e9f6c3f0bf 100644 --- a/dlls/opengl32/unix_wgl.c +++ b/dlls/opengl32/unix_wgl.c @@ -192,6 +192,7 @@ static ULONG_PTR zero_bits; static const struct vulkan_funcs *vk_funcs; static VkInstance vk_instance; static PFN_vkDestroyInstance p_vkDestroyInstance; +static struct opengl_extensions enabled_extensions; static int vk_device_cmp( const void *key, const struct rb_entry *entry ) { @@ -1157,9 +1158,62 @@ static BOOL initialize_vk_device( TEB *teb, struct context *ctx ) return FALSE; } +static void add_extension( struct opengl_extensions *extensions, const char *ext, size_t len, BOOL set ) +{ +#define USE_GL_EXT(x) if (!strncmp( #x, ext, len )) extensions->has_ ## x = set; else + ALL_GL_EXTS + ALL_WGL_EXTS +#undef USE_GL_EXT + WARN( "Extension %s is not supported.\n", debugstr_an( ext, len ) ); +} + +static void parse_extensions( struct opengl_extensions *extensions, const char *ext, BOOL set ) +{ + const char *end; + for (end = ext; *end; end++) + { + if (*end != ' ') continue; + add_extension( extensions, ext, end - ext, set ); + ext = end + 1; + } + if (end > ext) add_extension( extensions, ext, end - ext, set ); +} + +static void dump_extensions( const char *prefix, struct opengl_extensions *extensions ) +{ + if (TRACE_ON(opengl)) + { + TRACE( "%s extensions:\n", prefix ); +#define USE_GL_EXT(x) if (extensions->has_ ## x) TRACE( " - %s\n", #x ); + ALL_GL_EXTS + ALL_WGL_EXTS +#undef USE_GL_EXT + } +} + +static void init_enabled_extensions(void) +{ + char *enabled, *disabled; + + if ((enabled = query_opengl_option( "EnabledExtensions" ))) + parse_extensions( &enabled_extensions, enabled, TRUE ); + else + memset( &enabled_extensions, 0xff, sizeof(enabled_extensions) ); + + if ((disabled = query_opengl_option( "DisabledExtensions" ))) + parse_extensions( &enabled_extensions, disabled, FALSE ); + + if (enabled || disabled) dump_extensions( "Enabled", &enabled_extensions ); + + free( enabled ); + free( disabled ); +} + static void make_context_current( TEB *teb, const struct opengl_funcs *funcs, HDC draw_hdc, HDC read_hdc, HGLRC client_context, struct context *ctx ) { + static pthread_once_t once = PTHREAD_ONCE_INIT; + DWORD tid = HandleToULong(teb->ClientId.UniqueThread); size_t size = ARRAYSIZE(legacy_extensions) - 1, count = 0; const char *version, *rest = "", **extensions; @@ -1173,6 +1227,8 @@ static void make_context_current( TEB *teb, const struct opengl_funcs *funcs, HD teb->glTable = (void *)funcs; pop_default_fbo( teb ); + pthread_once( &once, init_enabled_extensions ); + if (ctx->major_version) return; /* already synced */ version = (const char *)funcs->p_glGetString( GL_VERSION ); diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index 61c006270ba..70cc22f63a9 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -59,6 +59,16 @@ struct wgl_pixel_format int float_components; }; +struct opengl_extensions +{ +#define USE_GL_EXT(x) unsigned has_ ## x : 1; + ALL_GL_EXTS + ALL_WGL_EXTS +#undef USE_GL_EXT +}; + +C_ASSERT( sizeof(struct opengl_extensions) <= 0x80 ); + struct opengl_client_context { struct HGLRC__ obj; /* client object header */ -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9982