Multiple GLX client libraries in the NVIDIA Linux driver installer package

Introduction: Compatibility issues with GLVND in 361.xx

The new GL Vendor Neutral Dispatch (GLVND) [1] infrastructure for Unix OpenGL drivers allows multiple OpenGL implementations to coexist on the same system. This is accomplished through a pluggable architecture whereby a set of vendor-neutral libraries expose the OpenGL API entry points and dispatch API calls to vendor-specific implementation libraries that implement the APIs.

The NVIDIA Linux OpenGL driver added support for GLVND with the release of the 361.16 beta driver. During the beta test phase, it was discovered that several applications relied on behaviors or attributes of the NVIDIA OpenGL driver that fall outside of the Linux OpenGL ABI [2]. As the GLVND-based
libGL.so.1 library does not share these behaviors or attributes with the NVIDIA OpenGL driver, this resulted in incorrect behavior from applications that depend upon them.

Selecting GLVND or non-GLVND at installation time

In order to provide better compatibility with existing applications, the NVIDIA Linux driver installer package will be providing the option to install either a GLVND-based OpenGL driver stack, or a legacy, non-GLVND based stack, beginning with the upcoming 361.28 driver release. The default will be to install a non-GLVND OpenGL driver for the lifetime of the 361.xx series.

A new “–glvnd-glx-client” command line option to nvidia-installer in the NVIDIA Linux .run installer package may be used to override the default installation type, and install a GLVND-based driver. In future releases where GLVND will be the default, “–no-glvnd-glx-client” may be used to force the installation of a non-GLVND-based driver.

Implications for repackagers of the NVIDIA Linux OpenGL driver

As the .run installer package now contains two separate libraries which each have the same SONAME of libGL.so.1, care must be taken such that installers repackaged from the .run package should install only one of these two libraries at a time, and not both of them simultaneously. This section describes the changes that were made to the content of the .run package to support GLVND.

  • libGL.so.1, the GLX client library, is available as GLVND or non-GLVND:
    • Prior to 361.16, the GLX client library did not support GLVND and bore the name libGL.so.$VERSION in the .run package, where $VERSION represents the driver version number.
    • In 361.16 and 361.18, the GLX client library was replaced with its GLVND counterpart, which is named libGL.so.1 in the .run package.
    • .run packages for 361.28 and later include both a non-GLVND libGL, which retains the old name of libGL.so.$VERSION, and a GLVND libGL, which has been renamed to libGL.so.1.0.0.
    • Packages must install either libGL.so.$VERSION or libGL.so.1.0.0, but never both. libGL.so.1.0.0 requires additional GLVND libraries for proper operation
  • 361.16 and later include several GLVND libraries in addition to libGL.so.1. Redistributors may wish to provide these libraries in a separate package built from the upstream GLVND source code, or the unmodified binaries from the .run package may be redistributed if that is more convenient.
    • libGLdispatch.so.0: dispatches OpenGL API calls from application-facing GLVND OpenGL API libraries, such as libGL.so.1, to vendor implementation libraries, such as libGLX_nvidia.so.0.
    • libGLESv1_CM.so.1: a wrapper library providing OpenGL ES v1 entry points, analogous to how libGL.so.1 is a wrapper library for GLX entry points.
    • libGLESv2.so.2: a wrapper library providing OpenGL ES v2 entry points.
    • libGLX.so.0: provides GLX API entry points to applications natively written against GLVND, and support for the libGL.so.1 wrapper library. This library should not be installed in conjunction with the legacy, non-GLVND GLX client library, and should not be confused with libglx.so, which is the GLX server-side loadable extension module for the X.org X server.
    • libOpenGL.so.0: provides window system agnostic OpenGL API entry points to applications natively written against GLVND, and support for GLVND wrapper libraries such as libGL.so.1, libEGL.so.1, and libGLES*.so*.
  • libEGL.so.1, while not a proper GLVND library, depends upon the GLVND infrastructure for proper functionality. Therefore, any driver package which aims to support NVIDIA EGL must provide the GLVND libraries, even if the driver installation uses the non-GLVND GLX client library, in which case the GLVND version of libGL.so.1 and libGLX.so.0 should be omitted.
  • GLVND vendor implementation libraries provide the NVIDIA implementations of the various OpenGL functions supported by the NVIDIA driver. Each of these libraries requires a symbolic link named after its SONAME which points to the installed file, whose name includes the driver version number, which is represented below by the placeholder $VERSION:
    • libEGL_nvidia.so.$VERSION (SONAME libEGL_nvidia.so.0)
    • libGLESv1_CM_nvidia.so.$VERSION (SONAME libGLESv1_CM_nvidia.so.1)
    • libGLESv2_nvidia.so.$VERSION (SONAME libGLESv2_nvidia.so.2)
    • libGLX_nvidia.so.$VERSION (SONAME libGLX_nvidia.so.0); for indirect GLX support, an additional symbolic link libGLX_indirect.so.0 must point to libGLX_nvidia.so.$VERSION. libGLX_nvidia is not a required part of the driver installation if the non-GLVND libGL is used; however, it does not conflict with the non-GLVND libGL. NVIDIA recommends installing this library, even when it is not needed, as doing so will allow NVIDIA GLX to continue working if, e.g. GLVND libraries built from the upstream libglvnd project are installed as a replacement for the existing non-GLVND libGL.

Although nvidia-installer will install the non-GLVND driver by default for the time being, this default will be changed soon, after more problems with existing applications have been identified and addressed. Repackagers of the NVIDIA driver are free to provide either the GLVND or non-GLVND driver, or a choice between the two, at their own discretion. While it may be preferable in the short term to continue shipping the non-GLVND variant to maximize compatibility, repackagers are encouraged to provide GLVND driver packages at the earliest possible opportunity, both to promote adoption of the new driver infrastructure, and to help identify additional problematic applications. Any compatibility problems between OpenGL applications and the libGL.so.1 library as implemented by GLVND should be reported to the application maintainers to let them know that their application will need to be updated in order to ensure compatibility with GLVND.

Library installation recommendations for GLVND and non-GLVND configurations

The following file lists enumerate the libraries that should be installed to support the GLVND and non-GLVND based configurations for GLX. In both cases, some GLVND libraries must be installed to support EGL. Required symbolic links are represented with the convention “link name → target name”, where the final target represents the name of the file as packaged in the .run installer. The string “$VERSION” serves as a placeholder for the driver version number.

On modern systems that support ELF TLS (Thread Local Storage), the NVIDIA TLS library libnvidia-tls.so.$VERSION should be installed from the “tls/” subdirectory of the .run package. Older systems that do not support ELF TLS require the libnvidia-tls.so.$VERSION library which is located at the root level of the extracted .run package. If you are unsure whether your system supports ELF TLS, or wish to support both classic and ELF TLS with the same installer package, you may install both libraries by placing the classic TLS “./libnvidia-tls.so.$VERSION” library (where ./ is relative to the root level of an extracted .run package) in the same directory as the other OpenGL libraries, and the ELF TLS “./tls/libnvidia-tls.so.$VERSION” library in a “tls/” subdirectory relative to the other OpenGL libraries. “(tls/)” prepended to the name of the TLS library indicates the option to choose to install the classic TLS library, the ELF TLS library, or both classic and ELF.

For brevity, only libraries which expose OpenGL APIs and their dependencies are listed below. Additional libraries will be required to fully support all features of the NVIDIA driver. Libraries marked with “(GLVND)” are part of the libglvnd project, and the binaries included in the .run package may be substituted with binaries built from upstream libglvnd, and may be installed from a separate libglvnd package upon which the NVIDIA driver package depends.

Legacy, non-GLVND GLX option

The following libraries are required to support GLX clients using a legacy, non-GLVND OpenGL driver:

  • libGL.so -> libGL.so.1 -> libGL.so.$VERSION
  • libnvidia-glcore.so.$VERSION
  • (tls/)libnvidia-tls.so.$VERSION

The following libraries are not required for a non-GLVND installation, but are recommended, in order to support easily transitioning from a non-GLVND installation to a GLVND one:

  • libGLX_nvidia.so.0 -> libGLX_nvidia.so.$VERSION
  • libGLX_indirect.so.0 -> libGLX_nvidia.so.$VERSION

GLVND GLX option

The following libraries are required to support GLX clients using the newGLVND OpenGL driver:

  • libGL.so -> libGL.so.1 -> libGL.so.1.0.0 (GLVND)
  • libGLX.so -> libGLX.so.0 (GLVND)
  • libOpenGL.so -> libOpenGL.so.0 (GLVND)
  • libGLdispatch.so.0 (GLVND)
  • libGLX_nvidia.so.0 -> libGLX_nvidia.so.$VERSION
  • libGLX_indirect.so.0 -> libGLX_nvidia.so.$VERSION
  • libnvidia-glcore.so.$VERSION
  • (tls/)libnvidia-tls.so.$VERSION

Libraries required for EGL

In addition to installing the libraries as listed under either “Legacy, non-GLVND GLX option” or “GLVND GLX option”, the following libraries are required in order to support EGL:

  • libEGL.so -> libEGL.so.1
  • libGLESv1_CM.so -> libGLESv1_CM.so.1 (GLVND)
  • libGLESv2.so -> libGLESv2.so.2 (GLVND)
  • libOpenGL.so -> libOpenGL.so.0 (GLVND)
  • libGLdispatch.so.0 (GLVND)
  • libEGL_nvidia.so.0 -> libEGL_nvidia.so.$VERSION
  • libGLESv1_CM_nvidia.so.1 -> libGLESv1_CM_nvidia.so.$VERSION
  • libGLESv2_nvidia.so.2 -> libGLESv2_nvidia.so.$VERSION
  • libnvidia-eglcore.so.$VERSION

References

[1] GitHub - NVIDIA/libglvnd: The GL Vendor-Neutral Dispatch library
[2] OpenGL® Application Binary Interface for Linux - The Khronos Group Inc