Mesa (main): windows: Use TLS context/dispatch with shared-glapi

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Dec 2 03:38:27 UTC 2021


Module: Mesa
Branch: main
Commit: c47fd3dc0062101b3e75a414b17d2765735f7424
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=c47fd3dc0062101b3e75a414b17d2765735f7424

Author: Jesse Natalie <jenatali at microsoft.com>
Date:   Tue Nov  2 11:38:02 2021 -0700

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 at anholt.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13634>

---

 meson.build            | 73 +++++++++++++++++++++++++++-----------------------
 src/mapi/glapi/glapi.h |  5 ++++
 2 files changed, 44 insertions(+), 34 deletions(-)

diff --git a/meson.build b/meson.build
index f5f0f7125bc..7d1a39e131e 100644
--- a/meson.build
+++ b/meson.build
@@ -508,44 +508,49 @@ foreach platform : _platforms
   pre_args += '-DHAVE_ at 0@_PLATFORM'.format(platform.to_upper())
 endforeach
 
-use_elf_tls = false
-if not with_platform_windows or not with_shared_glapi
-  pre_args += '-DUSE_ELF_TLS'
-  use_elf_tls = true
-
-  if with_platform_android and get_option('platform-sdk-version') >= 29
-    # 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 instead.
-    c_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
-  endforeach
-  if not have_mtls_dialect
-    # need .run to check libc support. meson aborts when calling .run when
-    # 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
+use_elf_tls = true
+pre_args += '-DUSE_ELF_TLS'
+
+if with_platform_android and get_option('platform-sdk-version') >= 29
+  # 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 instead.
+  c_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
+endforeach
+if not have_mtls_dialect
+  # need .run to check libc support. meson aborts when calling .run when
+  # 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
 
+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 not (with_platform_x11 and with_any_opengl)
     error('Cannot build GLX support without X11 platform support and at least one OpenGL API')
diff --git a/src/mapi/glapi/glapi.h b/src/mapi/glapi/glapi.h
index 275bc1f3ddc..d0bc5cdda28 100644
--- a/src/mapi/glapi/glapi.h
+++ b/src/mapi/glapi/glapi.h
@@ -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 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_CURRENT_CONTEXT(C)  struct gl_context *C = (struct gl_context *) _glapi_tls_Context
+#endif
 
 #else
 



More information about the mesa-commit mailing list