[Mesa-dev] [PATCH 08/14] i965: Build the driver into a shared mesa_dri_drivers.so .

Eric Anholt eric at anholt.net
Mon Sep 30 13:44:45 PDT 2013


Previously, we've split things such that mesa core is in libdricore,
exposing the whole Mesa core interface in the global namespace, and the
i965_dri.so code all links against that.  Along with polluting application
namespace terribly, it requires extra PLT indirections and prevents LTO.

Instead, we can build all of the driver contents into the same .so with
just a few symbols exposed to be referenced from the actual driver .so
file, allowing LTO and reducing our exposed symbol count massively.
---
 configure.ac                                  | 29 +++++++++++---
 src/mesa/drivers/dri/Makefile.am              | 54 ++++++++++++++++++++++++++-
 src/mesa/drivers/dri/common/Makefile.am       |  3 ++
 src/mesa/drivers/dri/common/dri_util.c        | 10 +++--
 src/mesa/drivers/dri/common/megadriver_stub.c | 41 ++++++++++++++++++++
 src/mesa/drivers/dri/i965/Makefile.am         | 27 +++-----------
 src/mesa/drivers/dri/i965/intel_screen.c      | 16 ++++++--
 src/mesa/drivers/dri/i965/intel_screen.h      |  2 +
 8 files changed, 147 insertions(+), 35 deletions(-)
 create mode 100644 src/mesa/drivers/dri/common/megadriver_stub.c

diff --git a/configure.ac b/configure.ac
index 1f0a646..bc111f3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -705,8 +705,6 @@ fi
 AM_CONDITIONAL(HAVE_DRI_GLX, test "x$enable_glx" = xyes -a \
                                   "x$enable_dri" = xyes)
 AM_CONDITIONAL(HAVE_DRI, test "x$enable_dri" = xyes)
-AM_CONDITIONAL(NEED_LIBMESA, test "x$enable_xlib_glx" = xyes -o \
-                                  "x$enable_osmesa" = xyes)
 
 AC_ARG_ENABLE([shared-glapi],
     [AS_HELP_STRING([--enable-shared-glapi],
@@ -858,8 +856,6 @@ AC_SUBST([GLESv1_CM_PC_LIB_PRIV])
 AC_SUBST([GLESv2_LIB_DEPS])
 AC_SUBST([GLESv2_PC_LIB_PRIV])
 
-DRI_LIB_DEPS="\$(top_builddir)/src/mesa/libdricore/libdricore${VERSION}.la"
-
 AC_SUBST([HAVE_XF86VIDMODE])
 
 dnl
@@ -1035,10 +1031,32 @@ if test "x$enable_dri" = xyes; then
 
     DRI_DRIVER_LDFLAGS="-module -avoid-version -shared -Wl,-Bsymbolic"
 fi
-AM_CONDITIONAL(NEED_LIBDRICORE, test -n "$DRI_DIRS")
+
+enable_dricore=no
+enable_megadriver=no
+for driver in $DRI_DIRS; do
+    if test $driver != "i965"; then
+        enable_dricore=yes
+    else
+        enable_megadriver=yes
+    fi
+done
+
+# megadriver wants to use libmesa.la, while non-megadrivers want to
+# automatically get libdricore.  Some day hopefully we'll transition
+# everything to megadriver.
+MEGADRIVER_DRI_LIB_DEPS=$DRI_LIB_DEPS
+DRI_LIB_DEPS="\$(top_builddir)/src/mesa/libdricore/libdricore${VERSION}.la $DRI_LIB_DEPS"
+
+AM_CONDITIONAL(NEED_LIBDRICORE, test "x$enable_dricore" = xyes)
+AM_CONDITIONAL(NEED_MEGADRIVER, test "x$enable_megadriver" = xyes)
+AM_CONDITIONAL(NEED_LIBMESA, test "x$enable_xlib_glx" = xyes -o \
+                                  "x$enable_osmesa" = xyes -o \
+                                  "x$enable_megadriver" = xyes)
 AC_SUBST([EXPAT_INCLUDES])
 AC_SUBST([DRI_LIB_DEPS])
 AC_SUBST([DRI_DRIVER_LDFLAGS])
+AC_SUBST([MEGADRIVER_DRI_LIB_DEPS])
 AC_SUBST([GALLIUM_DRI_LIB_DEPS])
 
 case $DRI_DIRS in
@@ -1951,6 +1969,7 @@ AC_SUBST([ELF_LIB])
 AM_CONDITIONAL(NEED_LIBPROGRAM, test "x$with_gallium_drivers" != x -o \
                                      "x$enable_xlib_glx" = xyes -o \
                                      "x$enable_osmesa" = xyes -o \
+                                     "x$enable_megadriver" = xyes -o \
                                      "x$enable_gallium_osmesa" = xyes)
 AM_CONDITIONAL(HAVE_X11_DRIVER, test "x$enable_xlib_glx" = xyes)
 AM_CONDITIONAL(HAVE_OSMESA, test "x$enable_osmesa" = xyes)
diff --git a/src/mesa/drivers/dri/Makefile.am b/src/mesa/drivers/dri/Makefile.am
index 48d3685..9d15c43 100644
--- a/src/mesa/drivers/dri/Makefile.am
+++ b/src/mesa/drivers/dri/Makefile.am
@@ -1,4 +1,15 @@
+dridir = $(DRI_DRIVER_INSTALL_DIR)
+
+AM_CPPFLAGS = \
+	-I$(top_srcdir)/src/mesa/ \
+	-I$(top_srcdir)/src/mapi/ \
+        -I$(top_srcdir)/src/mesa/drivers/dri/common \
+        $(LIBDRM_CFLAGS) \
+        $()
+
 SUBDIRS =
+MEGADRIVERS =
+MEGADRIVERS_DEPS =
 
 if HAVE_COMMON_DRI
 SUBDIRS+=common
@@ -9,7 +20,9 @@ SUBDIRS+=i915
 endif
 
 if HAVE_I965_DRI
-SUBDIRS+=i965
+SUBDIRS += i965
+MEGADRIVERS_DEPS += i965/libi965_dri.la
+MEGADRIVERS += i965_dri.so
 endif
 
 if HAVE_NOUVEAU_DRI
@@ -33,3 +46,42 @@ pkgconfig_DATA = dri.pc
 
 driincludedir = $(includedir)/GL/internal
 driinclude_HEADERS = $(top_srcdir)/include/GL/internal/dri_interface.h
+
+nodist_EXTRA_mesa_dri_drivers_la_SOURCES = dummy.cpp
+mesa_dri_drivers_la_SOURCES =
+mesa_dri_drivers_la_LDFLAGS = \
+        -module -avoid-version -shared \
+        -Wl,-Bsymbolic \
+        $()
+mesa_dri_drivers_la_LIBADD = \
+        ../../libmesa.la \
+        common/libmegadriver_stub.la \
+        common/libdricommon.la \
+        $(MEGADRIVERS_DEPS) \
+        $(MEGADRIVER_DRI_LIB_DEPS) \
+        $()
+
+if NEED_MEGADRIVER
+dri_LTLIBRARIES = mesa_dri_drivers.la
+
+# Add a link to allow setting LD_LIBRARY_PATH/LIBGL_DRIVERS_PATH to /lib of the build tree.
+all-local: mesa_dri_drivers.la
+	$(MKDIR_P) $(top_builddir)/$(LIB_DIR);
+	$(AM_V_GEN)ln -f .libs/mesa_dri_drivers.so \
+			 $(top_builddir)/$(LIB_DIR)/mesa_dri_drivers.so;
+	$(AM_V_GEN)for i in $(MEGADRIVERS); do \
+		ln -f $(top_builddir)/$(LIB_DIR)/mesa_dri_drivers.so \
+		      $(top_builddir)/$(LIB_DIR)/$$i; \
+	done;
+
+# hardlink each megadriver instance, but don't actually have
+# mesa_dri_drivers.so in the set of final installed files.
+install-data-hook:
+	for i in $(MEGADRIVERS); do \
+		ln -f $(dridir)/mesa_dri_drivers.so \
+		      $(dridir)/$$i; \
+	done;
+	$(RM) -f $(dridir)/mesa_dri_drivers.so
+	$(RM) -f $(dridir)/mesa_dri_drivers.la
+
+endif
diff --git a/src/mesa/drivers/dri/common/Makefile.am b/src/mesa/drivers/dri/common/Makefile.am
index ce4119d..e9c4aca 100644
--- a/src/mesa/drivers/dri/common/Makefile.am
+++ b/src/mesa/drivers/dri/common/Makefile.am
@@ -32,6 +32,7 @@ AM_CFLAGS = \
 
 noinst_LTLIBRARIES = \
 	libdricommon.la \
+	libmegadriver_stub.la \
 	libdri_test_stubs.la
 
 libdricommon_la_SOURCES = \
@@ -43,4 +44,6 @@ libdri_test_stubs_la_SOURCES = \
 	dri_test.c
 libdri_test_stubs_la_CFLAGS = $(AM_CFLAGS) -DNO_MAIN
 
+libmegadriver_stub_la_SOURCES = megadriver_stub.c
+
 sysconf_DATA = drirc
diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c
index 9a99ea9..3126ac8 100644
--- a/src/mesa/drivers/dri/common/dri_util.c
+++ b/src/mesa/drivers/dri/common/dri_util.c
@@ -106,10 +106,12 @@ dri2CreateNewScreen2(int scrn, int fd,
     /* If the driver exposes its vtable through its extensions list
      * (megadrivers), use that instead.
      */
-    for (int i = 0; driver_extensions[i]; i++) {
-       if (strcmp(driver_extensions[i]->name, __DRI_DRIVER_VTABLE) == 0) {
-          psp->driver =
-             ((__DRIDriverVtableExtension *)driver_extensions[i])->vtable;
+    if (driver_extensions) {
+       for (int i = 0; driver_extensions[i]; i++) {
+          if (strcmp(driver_extensions[i]->name, __DRI_DRIVER_VTABLE) == 0) {
+             psp->driver =
+                ((__DRIDriverVtableExtension *)driver_extensions[i])->vtable;
+          }
        }
     }
 
diff --git a/src/mesa/drivers/dri/common/megadriver_stub.c b/src/mesa/drivers/dri/common/megadriver_stub.c
new file mode 100644
index 0000000..6bf5d73
--- /dev/null
+++ b/src/mesa/drivers/dri/common/megadriver_stub.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright © 2013 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <stdio.h>
+#include "dri_util.h"
+
+static const
+__DRIconfig **stub_error_init_screen(__DRIscreen *psp)
+{
+   fprintf(stderr, "An updated DRI driver loader (libGL.so or X Server) is "
+           "required for this Mesa driver.\n");
+   return NULL;
+}
+
+/**
+ * This is a stub driDriverAPI that is referenced by dri_util.c but should
+ * never be used.
+ */
+const struct __DriverAPIRec driDriverAPI = {
+   .InitScreen = stub_error_init_screen,
+};
diff --git a/src/mesa/drivers/dri/i965/Makefile.am b/src/mesa/drivers/dri/i965/Makefile.am
index eb437d3..084b3d1 100644
--- a/src/mesa/drivers/dri/i965/Makefile.am
+++ b/src/mesa/drivers/dri/i965/Makefile.am
@@ -40,30 +40,19 @@ AM_CFLAGS = \
 
 AM_CXXFLAGS = $(AM_CFLAGS)
 
-dridir = $(DRI_DRIVER_INSTALL_DIR)
-
 noinst_LTLIBRARIES = libi965_dri.la
-dri_LTLIBRARIES = i965_dri.la
-
 libi965_dri_la_SOURCES = $(i965_FILES)
+libi965_dri_la_LIBADD = $(INTEL_LIBS)
 
-# list of libs to be linked against by i965_dri.so and i965 test programs.
-COMMON_LIBS = \
+TEST_LIBS = \
 	libi965_dri.la \
 	../common/libdricommon.la \
-	$(DRI_LIB_DEPS) \
-	$(INTEL_LIBS)
-
-TEST_LIBS = \
-	$(COMMON_LIBS) \
+	../common/libmegadriver_stub.la \
+	$(MEGADRIVER_DRI_LIB_DEPS) \
+        ../../../libmesa.la \
         -lrt \
 	../common/libdri_test_stubs.la
 
-i965_dri_la_SOURCES =
-nodist_EXTRA_i965_dri_la_SOURCES = dummy2.cpp
-i965_dri_la_LIBADD = $(COMMON_LIBS)
-i965_dri_la_LDFLAGS = $(DRI_DRIVER_LDFLAGS)
-
 TESTS = \
         test_eu_compact \
         test_vec4_register_coalesce
@@ -80,10 +69,4 @@ test_eu_compact_SOURCES = \
 nodist_EXTRA_test_eu_compact_SOURCES = dummy.cpp
 test_eu_compact_LDADD = $(TEST_LIBS)
 
-# Provide compatibility with scripts for the old Mesa build system for
-# a while by putting a link to the driver into /lib of the build tree.
-all-local: i965_dri.la
-	$(MKDIR_P) $(top_builddir)/$(LIB_DIR);
-	ln -f .libs/i965_dri.so $(top_builddir)/$(LIB_DIR)/i965_dri.so;
-
 endif
diff --git a/src/mesa/drivers/dri/i965/intel_screen.c b/src/mesa/drivers/dri/i965/intel_screen.c
index 7019008..29a4726 100644
--- a/src/mesa/drivers/dri/i965/intel_screen.c
+++ b/src/mesa/drivers/dri/i965/intel_screen.c
@@ -1341,7 +1341,7 @@ intelReleaseBuffer(__DRIscreen *screen, __DRIbuffer *buffer)
 }
 
 
-const struct __DriverAPIRec driDriverAPI = {
+static const struct __DriverAPIRec brw_driver_api = {
    .InitScreen		 = intelInitScreen2,
    .DestroyScreen	 = intelDestroyScreen,
    .CreateContext	 = brwCreateContext,
@@ -1354,10 +1354,20 @@ const struct __DriverAPIRec driDriverAPI = {
    .ReleaseBuffer        = intelReleaseBuffer
 };
 
-/* This is the table of extensions that the loader will dlsym() for. */
-PUBLIC const __DRIextension *__driDriverExtensions[] = {
+static const struct __DRIDriverVtableExtensionRec brw_vtable = {
+   .base = { __DRI_DRIVER_VTABLE, 1 },
+   .vtable = &brw_driver_api,
+};
+
+static const __DRIextension *brw_driver_extensions[] = {
     &driCoreExtension.base,
     &driDRI2Extension.base,
+    &brw_vtable.base,
     &brw_config_options.base,
     NULL
 };
+
+PUBLIC const __DRIextension **__driDriverGetExtensions_i965(void)
+{
+   return brw_driver_extensions;
+}
diff --git a/src/mesa/drivers/dri/i965/intel_screen.h b/src/mesa/drivers/dri/i965/intel_screen.h
index fef17bc..b9cbb94 100644
--- a/src/mesa/drivers/dri/i965/intel_screen.h
+++ b/src/mesa/drivers/dri/i965/intel_screen.h
@@ -72,6 +72,8 @@ extern void intelDestroyContext(__DRIcontext * driContextPriv);
 
 extern GLboolean intelUnbindContext(__DRIcontext * driContextPriv);
 
+PUBLIC const __DRIextension **__driDriverGetExtensions_i965(void);
+
 extern GLboolean
 intelMakeCurrent(__DRIcontext * driContextPriv,
                  __DRIdrawable * driDrawPriv,
-- 
1.8.4.rc3



More information about the mesa-dev mailing list