windows: Use TLS context/dispatch with shared-glapi
However they have to be called via _glapi_get_dispatch/context. This would be safe to do on any platform, but the extra indirection is only necessary on Windows since TLS vars can't be exported from a DLL. Reviewed-by: Emma Anholt <emma@anholt.net> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13634>
This commit is contained in:
parent
58aad3f403
commit
c47fd3dc00
69
meson.build
69
meson.build
|
@ -508,44 +508,49 @@ foreach platform : _platforms
|
||||||
pre_args += '-DHAVE_@0@_PLATFORM'.format(platform.to_upper())
|
pre_args += '-DHAVE_@0@_PLATFORM'.format(platform.to_upper())
|
||||||
endforeach
|
endforeach
|
||||||
|
|
||||||
use_elf_tls = false
|
use_elf_tls = true
|
||||||
if not with_platform_windows or not with_shared_glapi
|
pre_args += '-DUSE_ELF_TLS'
|
||||||
pre_args += '-DUSE_ELF_TLS'
|
|
||||||
use_elf_tls = true
|
|
||||||
|
|
||||||
if with_platform_android and get_option('platform-sdk-version') >= 29
|
if with_platform_android and get_option('platform-sdk-version') >= 29
|
||||||
# By default the NDK compiler, at least, emits emutls references instead of
|
# By default the NDK compiler, at least, emits emutls references instead of
|
||||||
# ELF TLS, even when building targeting newer API levels. Make it actually do
|
# ELF TLS, even when building targeting newer API levels. Make it actually do
|
||||||
# ELF TLS instead.
|
# ELF TLS instead.
|
||||||
c_args += '-fno-emulated-tls'
|
c_args += '-fno-emulated-tls'
|
||||||
cpp_args += '-fno-emulated-tls'
|
cpp_args += '-fno-emulated-tls'
|
||||||
|
endif
|
||||||
|
|
||||||
|
# -mtls-dialect=gnu2 speeds up non-initial-exec TLS significantly but requires
|
||||||
|
# full toolchain (including libc) support.
|
||||||
|
have_mtls_dialect = false
|
||||||
|
foreach c_arg : get_option('c_args')
|
||||||
|
if c_arg.startswith('-mtls-dialect=')
|
||||||
|
have_mtls_dialect = true
|
||||||
|
break
|
||||||
endif
|
endif
|
||||||
|
endforeach
|
||||||
# -mtls-dialect=gnu2 speeds up non-initial-exec TLS significantly but requires
|
if not have_mtls_dialect
|
||||||
# full toolchain (including libc) support.
|
# need .run to check libc support. meson aborts when calling .run when
|
||||||
have_mtls_dialect = false
|
# cross-compiling, but because this is just an optimization we can skip it
|
||||||
foreach c_arg : get_option('c_args')
|
if meson.is_cross_build()
|
||||||
if c_arg.startswith('-mtls-dialect=')
|
warning('cannot auto-detect -mtls-dialect when cross-compiling, using compiler default')
|
||||||
have_mtls_dialect = true
|
else
|
||||||
break
|
# -fpic to force dynamic tls, otherwise TLS relaxation defeats check
|
||||||
endif
|
gnu2_test = cc.run('int __thread x; int main() { return x; }', args: ['-mtls-dialect=gnu2', '-fpic'], name: '-mtls-dialect=gnu2')
|
||||||
endforeach
|
if gnu2_test.returncode() == 0
|
||||||
if not have_mtls_dialect
|
c_args += '-mtls-dialect=gnu2'
|
||||||
# need .run to check libc support. meson aborts when calling .run when
|
cpp_args += '-mtls-dialect=gnu2'
|
||||||
# cross-compiling, but because this is just an optimization we can skip it
|
|
||||||
if meson.is_cross_build()
|
|
||||||
warning('cannot auto-detect -mtls-dialect when cross-compiling, using compiler default')
|
|
||||||
else
|
|
||||||
# -fpic to force dynamic tls, otherwise TLS relaxation defeats check
|
|
||||||
gnu2_test = cc.run('int __thread x; int main() { return x; }', args: ['-mtls-dialect=gnu2', '-fpic'], name: '-mtls-dialect=gnu2')
|
|
||||||
if gnu2_test.returncode() == 0
|
|
||||||
c_args += '-mtls-dialect=gnu2'
|
|
||||||
cpp_args += '-mtls-dialect=gnu2'
|
|
||||||
endif
|
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if with_platform_windows and with_shared_glapi
|
||||||
|
# Windows doesn't support DLL exports/imports being TLS variables. When using shared
|
||||||
|
# glapi, libglapi.dll hosts the TLS, but other DLLs need to use them. Instead of falling
|
||||||
|
# all the way back to using globals and manual per-thread data, keep using TLS but just
|
||||||
|
# put accesses to it behind a function so the variable doesn't need to be exported.
|
||||||
|
pre_args += '-DUSE_TLS_BEHIND_FUNCTIONS'
|
||||||
|
endif
|
||||||
|
|
||||||
if with_glx != 'disabled'
|
if with_glx != 'disabled'
|
||||||
if not (with_platform_x11 and with_any_opengl)
|
if not (with_platform_x11 and with_any_opengl)
|
||||||
error('Cannot build GLX support without X11 platform support and at least one OpenGL API')
|
error('Cannot build GLX support without X11 platform support and at least one OpenGL API')
|
||||||
|
|
|
@ -91,8 +91,13 @@ _GLAPI_EXPORT extern __THREAD_INITIAL_EXEC void * _glapi_tls_Context;
|
||||||
_GLAPI_EXPORT extern const struct _glapi_table *_glapi_Dispatch;
|
_GLAPI_EXPORT extern const struct _glapi_table *_glapi_Dispatch;
|
||||||
_GLAPI_EXPORT extern const void *_glapi_Context;
|
_GLAPI_EXPORT extern const void *_glapi_Context;
|
||||||
|
|
||||||
|
#if defined (USE_TLS_BEHIND_FUNCTIONS)
|
||||||
|
# define GET_DISPATCH() _glapi_get_dispatch()
|
||||||
|
# define GET_CURRENT_CONTEXT(C) struct gl_context *C = (struct gl_context *) _glapi_get_context()
|
||||||
|
#else
|
||||||
# define GET_DISPATCH() _glapi_tls_Dispatch
|
# define GET_DISPATCH() _glapi_tls_Dispatch
|
||||||
# define GET_CURRENT_CONTEXT(C) struct gl_context *C = (struct gl_context *) _glapi_tls_Context
|
# define GET_CURRENT_CONTEXT(C) struct gl_context *C = (struct gl_context *) _glapi_tls_Context
|
||||||
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue