[Mesa-dev] [RFC PATCH] dri megadriver_stub: provide compatibility with older DRI loader

Ian Romanick idr at freedesktop.org
Fri Dec 6 15:50:26 PST 2013


On 12/06/2013 01:12 PM, Jordan Justen wrote:
> On Fri, Dec 6, 2013 at 2:35 AM, Jordan Justen <jordan.l.justen at intel.com> wrote:
>> To help the transition period when DRI loaders are being updated
>> to support the newer __driDriverExtensions_foo mechanism,
>> we populate __DRIextension with the extensions returned
>> by __driDriverExtensions_foo during a library contructor
>> function.
>>
>> We find the driver foo's name by using the dladdr function
>> which gives the path of the dynamic library's name that
>> was being loaded.

I like this approach much better than the one we were discussing in the
office yesterday.  It's much cleaner, and it's not specific to any
particular driver.  I'd really like to hear Eric and / or Keith's opinion

>> Signed-off-by: Jordan Justen <jordan.l.justen at intel.com>
>> Cc: "10.0" <mesa-stable at lists.freedesktop.org>
>> ---
>> Trying to allow Mesa 10 to be loaded by older DRI loaders.
>>
>> This seems to help glxinfo get the i965 driver if Mesa 10's
>> i965_dri.so is added to into a Mesa 9.2 libGL stack.
>>
>> It still needs to be tested more with older X servers.
> 
> I tested mesa master with and without this patch on a system running
> xserver-xorg-core 1.12.4 and gnome-shell.
> 
> Without this change, gnome-shell will fail to load and metacity will
> load as the fallback. Xorg.0.log reports that it can't find the
> __driDriverExtensions symbol in i965_dri.so, as expected.
> 
> With the change gnome-shell starts, and glxinfo reports that it is
> running Mesa i965 from master. I did not see any errors mention in
> Xorg.0.log.
> 
> Is there anything else I should look for?

And I assume that there were no piglit regressions on this
configuration?  Did 'LIBGL_ALWAYS_INDIRECT=y glxgears' run properly?

> -Jordan
> 
>>  src/mesa/drivers/dri/common/megadriver_stub.c | 113 ++++++++++++++++++++++++++
>>  1 file changed, 113 insertions(+)
>>
>> diff --git a/src/mesa/drivers/dri/common/megadriver_stub.c b/src/mesa/drivers/dri/common/megadriver_stub.c
>> index 6bf5d73..79d31a9 100644
>> --- a/src/mesa/drivers/dri/common/megadriver_stub.c
>> +++ b/src/mesa/drivers/dri/common/megadriver_stub.c
>> @@ -23,6 +23,119 @@
>>
>>  #include <stdio.h>
>>  #include "dri_util.h"
>> +#include <dlfcn.h>
>> +#include "main/macros.h"
>> +
>> +/* The extensions that allow the megadriver stub to provide backward
>> + * compatibility for the older DRI driver loader require GNU
>> + * extensions from dlfcn.h.
>> + */
>> +#ifdef _GNU_SOURCE
>> +
>> +#define MEGADRIVER_STUB_MAX_EXTENSIONS 10
>> +
>> +/* This is the table of extensions that the loader will dlsym() for.
>> + *
>> + * Initially it is empty for the megadriver stub, but the library
>> + * contructor may initialize it based on the name of the library that
>> + * is being loaded.
>> + */
>> +PUBLIC const __DRIextension *
>> +__driDriverExtensions[MEGADRIVER_STUB_MAX_EXTENSIONS] = {
>> +   NULL
>> +};
>> +
>> +/**
>> + * This is a contructor function for the megadriver dynamic library.
>> + *
>> + * When the driver is dlopen'ed, this function will run. It will
>> + * search for the name of the foo_dri.so file that was opened using
>> + * the dladdr function.
>> + *
>> + * After finding foo's name, it will call __driDriverGetExtensions_foo
>> + * and use the return to update __driDriverExtensions to achieve
>> + * compatibility with older DRI driver loaders.
>> + */
>> +__attribute__((constructor)) static void
>> +megadriver_stub_init(void)
>> +{
>> +   Dl_info info;
>> +   char *driver_path;
>> +   char *driver_name;
>> +   size_t name_len;
>> +   char *get_extensions_name;
>> +   const __DRIextension **(*get_extensions)(void);
>> +   const __DRIextension **extensions;
>> +   int i;
>> +
>> +   i = dladdr((void*) megadriver_stub_init, &info);
>> +   if (i == 0)
>> +      return;
>> +
>> +   driver_path = strdup(info.dli_fname);
>> +   if (!driver_path)
>> +      return;
>> +
>> +   driver_name = strrchr(driver_path, '/');
>> +   if (driver_name != NULL) {
>> +      /* Skip '/' character */
>> +      driver_name++;
>> +   } else {
>> +      /* Try using the start of the path */
>> +      driver_name = driver_path;
>> +   }
>> +
>> +   /* Make sure the patch ends with _dri.so */
>> +   name_len = strlen(driver_name);
>> +   if (strcmp(driver_name + (name_len - 7), "_dri.so") != 0) {
>> +      free(driver_path);
>> +      return;
>> +   }
>> +
>> +   /* If the path ends with _dri.so, then chop this part of the
>> +    * string off, and then we have the name
>> +    */
>> +   driver_name[name_len - 7] = '\0';
>> +
>> +   i = asprintf(&get_extensions_name, "%s_%s",
>> +                __DRI_DRIVER_GET_EXTENSIONS, driver_name);
>> +   free(driver_path);
>> +   if (i == -1 || !get_extensions_name)
>> +      return;
>> +
>> +   get_extensions = dlsym(RTLD_DEFAULT, get_extensions_name);
>> +   free(get_extensions_name);
>> +   if (!get_extensions)
>> +      return;
>> +
>> +   /* Use the newer DRI loader entrypoint to find extensions.
>> +    * We will then expose these extensions via the older
>> +    * __driDriverExtensions symbol.
>> +    */
>> +   extensions = get_extensions();
>> +
>> +   /* Copy the extensions into the __driDriverExtensions array
>> +    * we declared.
>> +    */
>> +   for (i = 0; i < ARRAY_SIZE(__driDriverExtensions); i++) {
>> +      __driDriverExtensions[i] = extensions[i];
>> +      if (extensions[i] == NULL)
>> +         break;
>> +   }
>> +
>> +   /* If the driver had more extensions that we reserved, then
>> +    * bail out. This will cause the driver to fail to load using
>> +    * the older loader mechanism.
>> +    */
>> +   if (extensions[i] != NULL) {
>> +      __driDriverExtensions[0] = NULL;
>> +      fprintf(stderr, "An updated DRI driver loader (libGL.so or X Server) is "
>> +              "required for this Mesa driver.\n");
>> +      return;
>> +   }
>> +}
>> +
>> +#endif // #ifdef _GNU_SOURCE
>>
>>  static const
>>  __DRIconfig **stub_error_init_screen(__DRIscreen *psp)
>> --
>> 1.8.5.1
>>
>> _______________________________________________
>> mesa-dev mailing list
>> mesa-dev at lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
> 



More information about the mesa-dev mailing list