libglvnd/src/EGL/icd_enumeration.md

4.9 KiB

EGL ICD enumeration

EGL can't rely on asking an X server for a vendor name like GLX can, so instead, it enumerates and loads every available vendor library. Loading every vendor is also needed to support extensions such as EGL_EXT_device_enumeration.

In order to find the available vendor libraries, each vendor provides a JSON file in a well-known directory, similar to how Vulkan ICDs are loaded.

ICD discovery

  • All environment variables mentioned here are ignored (treated as though they were unset) if the process is setuid.

  • If the environment variable __EGL_VENDOR_LIBRARY_FILENAMES is set, it is a colon-separated list of JSON filenames. The ICDs described in those files are loaded, in the order given. No other ICDs are loaded.

  • Otherwise, if the environment variable __EGL_VENDOR_LIBRARY_DIRS is set, it is a colon-separated list of directories. Each directory in turn is scanned for files named *.json and the ICDs that they describe are loaded. Files in the same directory are loaded in strcmp() order, so 40_myvendor.json is considered to be higher-priority than 50_yourvendor.json.

  • If neither environment variable is set, GLVND behaves as though __EGL_VENDOR_LIBRARY_DIRS had been set to ${sysconfdir}/glvnd/egl_vendor.d:${datadir}/glvnd/egl_vendor.d, replacing ${sysconfdir} and ${datadir} with the values that were set when GLVND was compiled.

  • Each JSON file describing an ICD must have a JSON object at top level.

    • The key file_format_version must have a string value giving the file format major.minor.micro version number. This specification describes version 1.0.0. Versions 1.0.x are required to be compatible with this specification, in the sense that an EGL loader that only implements file format version 1.0.0 will load all version 1.0.x JSON files successfully. Different major and minor versions might require loader changes.
    • The key ICD must have an object value.
      • In the ICD object, the key library_path must have a string value.
        • If the library path is a bare filename with no directory separators, for example libEGL_mesa.so.0, or an absolute path, for example /opt/myvendor/libEGL_myvendor.so, then the loader is expected to pass it directly to dlopen(). See the documentation of dlopen() for full details of how it searches for a library.
        • If the library path is a relative path containing at least one directory separator, for example ./libEGL_myvendor.so, then the loader is expected to treat it as being relative to the directory containing the JSON file.

ICD installation

The JSON files describing ICDs can be installed into ${datadir}/glvnd/egl_vendor.d or ${sysconfdir}/glvnd/egl_vendor.d, where ${datadir} and ${sysconfdir} are the data and system configuration directories with which which GLVND was configured, normally /usr/share and /etc respectively. These paths can be discovered by using pkg-config.

ICDs installed into the same directory hierarchy (prefix) as GLVND itself should normally have their JSON files installed into the ${datadir}.

If a vendor installs ICD libraries into one of the system's default runtime library directories, they must install a JSON file referencing the ICD library by either its absolute path or its bare filename.

If a vendor installs ICD libraries into a non-standard directory, they must install a JSON file referencing the ICD library by its absolute path.

If a vendor installs matching ICD libraries for more than one ABI (for example 32- and 64-bit versions), each library has the same name, and each library is in a directory searched by default by the runtime linker and referenced by its bare filename, then they may install a single JSON file to describe all of those ICD libraries. For example, Mesa on Debian installs /usr/lib/x86_64-linux-gnu/libEGL_mesa.so.0 and /usr/lib/i386-linux-gnu/libEGL_mesa.so.0, which can both be described by a JSON file with "library_path": "libEGL_mesa.so.0". Similarly, Mesa on Arch Linux installs 64-bit /usr/lib/libEGL_mesa.so.0 and 32-bit /usr/lib32/libEGL_mesa.so.0, with a similar JSON file, while some other distributions use lib64 for 64-bit libraries.

Examples

On systems with the Mesa EGL drivers, this file is typically installed at /usr/share/glvnd/egl_vendor.d/50_mesa.json:

{
    "file_format_version" : "1.0.0",
    "ICD" : {
        "library_path" : "libEGL_mesa.so.0"
    }
}

A third-party ICD installed at /opt/myvendor/lib64/libEGL_myvendor.so could install this file in /etc/glvnd/egl_vendor.d/10_myvendor.x86_64.json:

{
    "file_format_version" : "1.0.0",
    "ICD" : {
        "library_path" : "/opt/myvendor/lib64/libEGL_myvendor.so"
    }
}