"Missing GL version" from glewInit() using EGL?
ORIGINAL ANSWER 28th Nov 2017:
I think this is a bug in a recent version of the nvidia package:
https://bugs.launchpad.net/ubuntu/+source/nvidia-graphics-drivers-384/+bug/1731968
Release: Ubuntu 16.04.3 LTS
Package version: 384.90-0ubuntu0.16.04.2
In the latest driver 384.90-0ubuntu0.16.04.2, EGL initialisation is now broken and the GL context returned is inconsistent leading to crashes. I have prepared a minimised testcase that showcases the problem with the latest driver. I have also made sure it works fine with both previous versions 384.90-0ubuntu0.16.04.1 and 384.81-0ubuntu1 in a clean install.
My EGL program works fine for me on my prod server, where I have these nvidia packages:
$ dpkg -l | grep nvidia
ii nvidia-367 375.66-0ubuntu0.16.04.1 amd64 Transitional package for nvidia-375
ii nvidia-375 384.90-0ubuntu0.16.04.1 amd64 Transitional package for nvidia-384
ii nvidia-384 384.90-0ubuntu0.16.04.1 amd64 NVIDIA binary driver - version 384.90
rc nvidia-opencl-icd-375 384.90-0ubuntu0.16.04.1 amd64 Transitional package for nvidia-opencl-icd-384
ii nvidia-opencl-icd-384 384.90-0ubuntu0.16.04.1 amd64 NVIDIA OpenCL ICD
ii nvidia-prime 0.8.2 amd64 Tools to enable NVIDIA's Prime
ii nvidia-settings 361.42-0ubuntu1 amd64 Tool for configuring the NVIDIA graphics driver
But it started failing on my test server after installing updates (apt-get update
followed by apt-get upgrade
), where I then had these nvidia packages:
$ dpkg -l | grep nvidia
ii nvidia-367 375.66-0ubuntu0.16.04.1 amd64 Transitional package for nvidia-375
ii nvidia-375 384.90-0ubuntu0.16.04.2 amd64 Transitional package for nvidia-384
ii nvidia-384 384.90-0ubuntu0.16.04.2 amd64 NVIDIA binary driver - version 384.90
ii nvidia-opencl-icd-384 384.90-0ubuntu0.16.04.2 amd64 NVIDIA OpenCL ICD
ii nvidia-prime 0.8.2 amd64 Tools to enable NVIDIA's Prime
ii nvidia-settings 361.42-0ubuntu1 amd64 Tool for configuring the NVIDIA graphics driver
I downgraded the nvidia-384 package to the older version:
$ sudo apt-get install nvidia-384=384.90-0ubuntu0.16.04.1
Then rebooted. After that I now have this:
$ dpkg -l | grep nvidia
ii nvidia-367 375.66-0ubuntu0.16.04.1 amd64 Transitional package for nvidia-375
ii nvidia-375 384.90-0ubuntu0.16.04.2 amd64 Transitional package for nvidia-384
ii nvidia-384 384.90-0ubuntu0.16.04.1 amd64 NVIDIA binary driver - version 384.90
ii nvidia-opencl-icd-384 384.90-0ubuntu0.16.04.2 amd64 NVIDIA OpenCL ICD
ii nvidia-prime 0.8.2 amd64 Tools to enable NVIDIA's Prime
ii nvidia-settings 361.42-0ubuntu1 amd64 Tool for configuring the NVIDIA graphics driver
And now my EGL program works again!
UPDATE 15th Jan 2018:
A few days ago Ubuntu released the 384.111 update, which contains a fix for one of the Spectre vulnerabilities:
https://bugs.launchpad.net/ubuntu/+source/nvidia-graphics-drivers-384/+bug/1741807
According to http://nvidia.custhelp.com/app/answers/detail/a_id/4611 the NVIDIA driver needs to be updated to 384.111 to fix the Spectre vulnerabilities in the NVIDIA kernel modules (along with the upcoming Kernel security patches).
This update was auto-applied and again broke EGL on my server, with the following packages installed:
$ dpkg -l | grep nvidia
ii nvidia-367 375.66-0ubuntu0.16.04.1 amd64 Transitional package for nvidia-375
ii nvidia-375 384.111-0ubuntu0.16.04.1 amd64 Transitional package for nvidia-384
ii nvidia-384 384.111-0ubuntu0.16.04.1 amd64 NVIDIA binary driver - version 384.111
rc nvidia-opencl-icd-375 384.90-0ubuntu0.16.04.1 amd64 Transitional package for nvidia-opencl-icd-384
ii nvidia-opencl-icd-384 384.111-0ubuntu0.16.04.1 amd64 NVIDIA OpenCL ICD
ii nvidia-prime 0.8.2 amd64 Tools to enable NVIDIA's Prime
ii nvidia-settings 361.42-0ubuntu1 amd64 Tool for configuring the NVIDIA graphics driver
The previous fix to downgrade to 384.90-0ubuntu0.16.04.1 no longer works:
$ sudo apt-get install nvidia-384=384.90-0ubuntu0.16.04.1
Reading package lists... Done
Building dependency tree
Reading state information... Done
E: Version '384.90-0ubuntu0.16.04.1' for 'nvidia-384' was not found
This is because it was superseded and removed on the 10th of Jan 2018:
https://launchpad.net/ubuntu/+source/nvidia-graphics-drivers-384/+publishinghistory
I was able to work around this by removing all NVIDIA packages:
$ sudo apt-get purge nvidia*
And then manually installing the 384.90 driver:
$ wget https://launchpad.net/ubuntu/+archive/primary/+files/nvidia-graphics-drivers-384_384.90.orig.tar.gz
$ tar xzf nvidia-graphics-drivers-384_384.90.orig.tar.gz
$ cd nvidia-graphics-drivers-384_384.90
$ chmod u+x NVIDIA-Linux-x86_64-384.90-no-compat32.run
$ sudo ./NVIDIA-Linux-x86_64-384.90-no-compat32.run
My EGL program now worked again. However note that it is now running an unpatched driver, so this may not be suitable for you as it may open your system to vulnerabilities.
UPDATE 15th Jan 2018 (part 2):
Just for some extra background / reference, I have also tried the beta of 390.12 from here, which was released on the 13th of Jan:
https://launchpad.net/~graphics-drivers/+archive/ubuntu/ppa
I did the following:
$ sudo apt-get purge nvidia*
$ sudo add-apt-repository ppa:graphics-drivers/ppa
$ sudo apt-get update
$ sudo apt-get install nvidia-390
Which results in the following list of installed packages:
$ dpkg -l | grep nvidia
ii nvidia-390 390.12-0ubuntu0~gpu16.04.2 amd64 NVIDIA binary driver - version 390.12
ii nvidia-opencl-icd-390 390.12-0ubuntu0~gpu16.04.2 amd64 NVIDIA OpenCL ICD
ii nvidia-prime 0.8.2 amd64 Tools to enable NVIDIA's Prime
ii nvidia-settings 390.12-0ubuntu0~gpu16.04.1 amd64 Tool for configuring the NVIDIA graphics driver
However EGL still doesn't work.
UPDATE 16th Mar 2018:
The beta of 390.25 was released on the 30th of Jan. To try that I did the following again:
$ sudo apt-get purge nvidia*
$ sudo add-apt-repository ppa:graphics-drivers/ppa
$ sudo apt-get update
$ sudo apt-get install nvidia-390
Which results in the following list of installed packages:
$ dpkg -l | grep nvidia
ii nvidia-390 390.25-0ubuntu0~gpu16.04.1 amd64 NVIDIA binary driver - version 390.25
ii nvidia-opencl-icd-390 390.25-0ubuntu0~gpu16.04.1 amd64 NVIDIA OpenCL ICD
ii nvidia-prime 0.8.2 amd64 Tools to enable NVIDIA's Prime
ii nvidia-settings 390.25-0ubuntu0~gpu16.04.1 amd64 Tool for configuring the NVIDIA graphics driver
However EGL still doesn't work.
UPDATE 17th May 2018:
I was setting up a new server, and so tried this again.
From https://launchpad.net/~graphics-drivers/+archive/ubuntu/ppa the 'long-lived branch release' is now at 390.48 (released 18th April), and the 'short-lived branch release' is now at 396.24 (released 3rd May).
I tried 390.48:
$ sudo apt-get purge nvidia*
$ sudo add-apt-repository ppa:graphics-drivers/ppa
$ sudo apt-get update
$ sudo apt-get install nvidia-390
Which resulted in the following list of installed packages:
$ dpkg -l | grep nvidia
ii nvidia-390 390.48-0ubuntu0~gpu16.04.3 amd64 NVIDIA binary driver - version 390.48
ii nvidia-opencl-icd-390 390.48-0ubuntu0~gpu16.04.3 amd64 NVIDIA OpenCL ICD
ii nvidia-prime 0.8.2 amd64 Tools to enable NVIDIA's Prime
ii nvidia-settings 396.24-0ubuntu0~gpu16.04.1 amd64 Tool for configuring the NVIDIA graphics driver
However EGL still doesn't work.
I tried 396.24:
$ sudo apt-get purge nvidia*
$ sudo add-apt-repository ppa:graphics-drivers/ppa
$ sudo apt-get update
$ sudo apt-get install nvidia-396
Which resulted in the following list of installed packages:
$ dpkg -l | grep nvidia
ii nvidia-396 396.24-0ubuntu0~gpu16.04.1 amd64 NVIDIA binary driver - version 396.24
ii nvidia-opencl-icd-396 396.24-0ubuntu0~gpu16.04.1 amd64 NVIDIA OpenCL ICD
ii nvidia-prime 0.8.2 amd64 Tools to enable NVIDIA's Prime
ii nvidia-settings 396.24-0ubuntu0~gpu16.04.1 amd64 Tool for configuring the NVIDIA graphics driver
However EGL still doesn't work.
Manually installing the 384.90 driver still works.
I had previously been installing on AWS g2.2xlarge servers. This time I was installing on an Azure NC6 server, and I had to disable unified memory or else the installation would fail, ie:
$ sudo apt-get purge nvidia*
$ wget https://launchpad.net/ubuntu/+archive/primary/+files/nvidia-graphics-drivers-384_384.90.orig.tar.gz
$ tar xzf nvidia-graphics-drivers-384_384.90.orig.tar.gz
$ cd nvidia-graphics-drivers-384_384.90
$ chmod u+x NVIDIA-Linux-x86_64-384.90-no-compat32.run
$ sudo ./NVIDIA-Linux-x86_64-384.90-no-compat32.run --no-unified-memory
Note that without unified memory, CUDA is not available.
Also note as mentioned above, this is still an unpatched driver from before the Spectre vulnerability patches.
UPDATE 25th June 2018:
From https://launchpad.net/~graphics-drivers/+archive/ubuntu/ppa the latest versions are now 390.67 (released 7th June), and 396.24.02 (released 4th June).
I tried 390.67:
$ sudo apt-get purge nvidia*
$ sudo add-apt-repository ppa:graphics-drivers/ppa
$ sudo apt-get update
$ sudo apt-get install nvidia-390
$ sudo reboot
[after reboot]
$ dpkg -l | grep nvidia
ii nvidia-390 390.67-0ubuntu0~gpu16.04.1 amd64 NVIDIA binary driver - version 390.67
ii nvidia-opencl-icd-390 390.67-0ubuntu0~gpu16.04.1 amd64 NVIDIA OpenCL ICD
ii nvidia-prime 0.8.2 amd64 Tools to enable NVIDIA's Prime
ii nvidia-settings 396.24-0ubuntu0~gpu16.04.1 amd64 Tool for configuring the NVIDIA graphics driver
EGL still didn't work.
I tried 396.24.02:
$ sudo apt-get purge nvidia*
$ sudo add-apt-repository ppa:graphics-drivers/ppa
$ sudo apt-get update
$ sudo apt-get install nvidia-396
$ sudo reboot
[after reboot]
$ dpkg -l | grep nvidia
ii nvidia-396 396.24.02-0ubuntu0~gpu16.04.1 amd64 NVIDIA binary driver - version 396.24.02
ii nvidia-opencl-icd-396 396.24.02-0ubuntu0~gpu16.04.1 amd64 NVIDIA OpenCL ICD
ii nvidia-prime 0.8.2 amd64 Tools to enable NVIDIA's Prime
ii nvidia-settings 396.24-0ubuntu0~gpu16.04.1 amd64 Tool for configuring the NVIDIA graphics driver
EGL still didn't work.
I also tried 384.130 (released 29th March 2018), which is the "old long-lived branch release":
$ sudo apt-get purge nvidia*
$ sudo add-apt-repository ppa:graphics-drivers/ppa
$ sudo apt-get update
$ sudo apt-get install nvidia-384
$ sudo reboot
[after reboot]
$ dpkg -l | grep nvidia
ii nvidia-384 384.130-0ubuntu0.16.04.1 amd64 NVIDIA binary driver - version 384.130
ii nvidia-opencl-icd-384 384.130-0ubuntu0.16.04.1 amd64 NVIDIA OpenCL ICD
ii nvidia-prime 0.8.2 amd64 Tools to enable NVIDIA's Prime
ii nvidia-settings 396.24-0ubuntu0~gpu16.04.1 amd64 Tool for configuring the NVIDIA graphics driver
EGL still didn't work.
The reason I tried these again today is that EGL stopped working on my server after a reboot.
A manual install of the old 384.90 driver (which had worked for me before as described in the earlier updates) would fail with the following errors in /var/log/nvidia-installer.log:
/tmp/selfgz3957/NVIDIA-Linux-x86_64-384.90-no-compat32/kernel/nvidia/nv.c: In function ‘nv_start_rc_timer’:
/tmp/selfgz3957/NVIDIA-Linux-x86_64-384.90-no-compat32/kernel/nvidia/nv.c:3206:5: error: implicit declaration of function ‘init_timer’ [-Werror=implicit-function-declaration]
init_timer(&nvl->rc_timer);
^
/tmp/selfgz3957/NVIDIA-Linux-x86_64-384.90-no-compat32/kernel/nvidia/nv.c:3207:28: error: assignment from incompatible pointer type [-Werror=incompatible-pointer-types]
nvl->rc_timer.function = nvidia_rc_timer;
^
/tmp/selfgz3957/NVIDIA-Linux-x86_64-384.90-no-compat32/kernel/nvidia/nv.c:3208:18: error: ‘struct timer_list’ has no member named ‘data’
nvl->rc_timer.data = (unsigned long) nvl;
This error was because the Linux timers API was changed in kernel 4.15:
https://lwn.net/Articles/735887/
https://github.com/torvalds/linux/commit/513ae785c63c30741e46f43960213d4ae5382ec0#diff-ba8897e9349509c7ca4d37b0704bee9c
And my server had recently upgraded to kernel 4.15:
$ uname -r
4.15.0-1013-azure
$ grep install /var/log/dpkg.log | grep linux-image
2018-06-18 04:13:09 install linux-image-4.15.0-1013-azure:amd64 <none> 4.15.0-1013.13~16.04.2
2018-06-18 04:13:09 status half-installed linux-image-4.15.0-1013-azure:amd64 4.15.0-1013.13~16.04.2
2018-06-18 04:13:10 status half-installed linux-image-azure:amd64 4.13.0.1018.19
2018-06-18 04:13:10 status half-installed linux-image-azure:amd64 4.13.0.1018.19
2018-06-18 04:13:58 status installed linux-image-4.15.0-1013-azure:amd64 4.15.0-1013.13~16.04.2
2018-06-18 04:13:59 status installed linux-image-azure:amd64 4.15.0.1013.20
2018-06-18 04:14:13 status installed linux-image-4.15.0-1013-azure:amd64 4.15.0-1013.13~16.04.2
To allow the old driver to work, I reverted back to kernel 4.13 by using these instructions to change the grub config. First I checked what grub menu items were available:
$ grep menuentry /boot/grub/grub.cfg
if [ x"${feature_menuentry_id}" = xy ]; then
menuentry_id_option="--id"
menuentry_id_option=""
export menuentry_id_option
menuentry 'Ubuntu' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-simple-dfb884db-c6ad-4c7a-8075-98cf640a2892' {
submenu 'Advanced options for Ubuntu' $menuentry_id_option 'gnulinux-advanced-dfb884db-c6ad-4c7a-8075-98cf640a2892' {
menuentry 'Ubuntu, with Linux 4.15.0-1013-azure' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-4.15.0-1013-azure-advanced-dfb884db-c6ad-4c7a-8075-98cf640a2892' {
menuentry 'Ubuntu, with Linux 4.15.0-1013-azure (upstart)' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-4.15.0-1013-azure-init-upstart-dfb884db-c6ad-4c7a-8075-98cf640a2892' {
menuentry 'Ubuntu, with Linux 4.15.0-1013-azure (recovery mode)' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-4.15.0-1013-azure-recovery-dfb884db-c6ad-4c7a-8075-98cf640a2892' {
menuentry 'Ubuntu, with Linux 4.13.0-1018-azure' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-4.13.0-1018-azure-advanced-dfb884db-c6ad-4c7a-8075-98cf640a2892' {
menuentry 'Ubuntu, with Linux 4.13.0-1018-azure (upstart)' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-4.13.0-1018-azure-init-upstart-dfb884db-c6ad-4c7a-8075-98cf640a2892' {
menuentry 'Ubuntu, with Linux 4.13.0-1018-azure (recovery mode)' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-4.13.0-1018-azure-recovery-dfb884db-c6ad-4c7a-8075-98cf640a2892' {
menuentry 'Ubuntu, with Linux 4.13.0-1016-azure' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-4.13.0-1016-azure-advanced-dfb884db-c6ad-4c7a-8075-98cf640a2892' {
menuentry 'Ubuntu, with Linux 4.13.0-1016-azure (upstart)' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-4.13.0-1016-azure-init-upstart-dfb884db-c6ad-4c7a-8075-98cf640a2892' {
menuentry 'Ubuntu, with Linux 4.13.0-1016-azure (recovery mode)' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-4.13.0-1016-azure-recovery-dfb884db-c6ad-4c7a-8075-98cf640a2892' {
The kernel I wanted was Ubuntu, with Linux 4.13.0-1018-azure
under the Advanced options for Ubuntu
submenu.
So I edited /etc/default/grub to change the GRUB_DEFAULT line to:
GRUB_DEFAULT="Advanced options for Ubuntu>Ubuntu, with Linux 4.13.0-1018-azure"
Then:
$ sudo update-grub
Then reboot, and check the kernel:
$ uname -r
4.13.0-1018-azure
I was then able to get EGL to work again with the old 384.90 driver.
UPDATE 8th January 2019:
From https://launchpad.net/~graphics-drivers/+archive/ubuntu/ppa the latest versions are now 410.78 (long-lived branch, released 26th November 2018), and 415.25 (released 20th December 2018).
I tried 410.78:
$ sudo apt-get purge nvidia*
$ sudo add-apt-repository ppa:graphics-drivers/ppa
$ sudo apt-get update
$ sudo apt-get install nvidia-410
$ sudo reboot
[after reboot]
$ dpkg -l | grep nvidia
ii nvidia-410 410.78-0ubuntu0~gpu16.04.1 amd64 NVIDIA binary driver - version 410.78
ii nvidia-opencl-icd-410 410.78-0ubuntu0~gpu16.04.1 amd64 NVIDIA OpenCL ICD
ii nvidia-prime 0.8.2 amd64 Tools to enable NVIDIA's Prime
ii nvidia-settings 415.25-0ubuntu0~gpu16.04.1 amd64 Tool for configuring the NVIDIA graphics driver
EGL still didn't work.
I tried 415.25:
$ sudo apt-get purge nvidia*
$ sudo add-apt-repository ppa:graphics-drivers/ppa
$ sudo apt-get update
$ sudo apt-get install nvidia-415
$ sudo reboot
[after reboot]
$ dpkg -l | grep nvidia
ii nvidia-415 415.25-0ubuntu0~gpu16.04.1 amd64 NVIDIA binary driver - version 415.25
ii nvidia-opencl-icd-415 415.25-0ubuntu0~gpu16.04.1 amd64 NVIDIA OpenCL ICD
ii nvidia-prime 0.8.2 amd64 Tools to enable NVIDIA's Prime
ii nvidia-settings 415.25-0ubuntu0~gpu16.04.1 amd64 Tool for configuring the NVIDIA graphics driver
EGL still didn't work.
For a different approach, I also tried installing the drivers via the cuda drivers package, based on the steps described at https://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html:
$ sudo apt-get purge nvidia*
$ wget https://developer.nvidia.com/compute/cuda/10.0/Prod/local_installers/cuda-repo-ubuntu1604-10-0-local-10.0.130-410.48_1.0-1_amd64
$ mv cuda-repo-ubuntu1604-10-0-local-10.0.130-410.48_1.0-1_amd64 cuda-repo-ubuntu1604-10-0-local-10.0.130-410.48_1.0-1_amd64.deb
$ sudo dpkg -i cuda-repo-ubuntu1604-10-0-local-10.0.130-410.48_1.0-1_amd64.deb
$ sudo apt-key add /var/cuda-repo-10-0-local-10.0.130-410.48/7fa2af80.pub
$ sudo apt-get update
$ sudo apt-get install cuda
$ sudo reboot
[after reboot]
$ cat /proc/driver/nvidia/version
NVRM version: NVIDIA UNIX x86_64 Kernel Module 410.78 Sat Nov 10 22:09:04 CST 2018
GCC version: gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.10)
$ dpkg -l | grep nvidia
ii nvidia-410 410.78-0ubuntu0~gpu16.04.1 amd64 NVIDIA binary driver - version 410.78
ii nvidia-410-dev 410.78-0ubuntu0~gpu16.04.1 amd64 NVIDIA binary Xorg driver development files
ii nvidia-modprobe 410.48-0ubuntu1 amd64 Load the NVIDIA kernel driver and create device files
ii nvidia-opencl-icd-410 410.78-0ubuntu0~gpu16.04.1 amd64 NVIDIA OpenCL ICD
ii nvidia-prime 0.8.2 amd64 Tools to enable NVIDIA's Prime
ii nvidia-settings 415.25-0ubuntu0~gpu16.04.1 amd64 Tool for configuring the NVIDIA graphics driver
EGL still didn't work.
I did the following to remove the cuda installation:
$ sudo apt-get purge nvidia*
$ sudo apt-get purge cuda*
Manually installing the old 384.90 driver still worked.
A comment from August 2018 on the original bug report says:
Matthew Matl (mmatl) wrote on 2018-08-27:
This works when installing using the runfile method, but fails for the packaged drivers. So it definitely appears to be a packaging issue specific to Ubuntu. Confirmed to work on Fedora and Arch with 390-series drivers as well.
To test this I tried manually installing the latest driver from https://www.nvidia.com/object/unix.html (currently 410.93 on the long-lived branch):
$ wget -L http://us.download.nvidia.com/XFree86/Linux-x86_64/410.93/NVIDIA-Linux-x86_64-410.93.run
$ sudo sh NVIDIA-Linux-x86_64-410.93.run
$ sudo reboot
[after reboot]
$ cat /proc/driver/nvidia/version
NVRM version: NVIDIA UNIX x86_64 Kernel Module 410.93 Thu Dec 20 17:01:16 CST 2018
GCC version: gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.10)
Running the test case from the original bug report now worked!
$ wget https://gist.githubusercontent.com/funchal/bff0a8d6dae5b3ace1a88c392416b5bc/raw/1427821a2390a30779881ab59c55b5550a468919/main.c
$ gcc main.c -lGL -lEGL
$ ./a.out
egl 1.5
renderer: Tesla K80/PCIe/SSE2
version: 4.6.0 NVIDIA 410.93
It even worked when I reinstated the 4.15 kernel that I had previously had to disable.
The following is required to uninstall this manually-installed driver:
$ sudo nvidia-uninstall
For comparison I also tried a manual install of the latest CUDA driver (which includes version 410.48 of the nvidia driver) using the runfile instead of the package method:
$ wget -L https://developer.nvidia.com/compute/cuda/10.0/Prod/local_installers/cuda_10.0.130_410.48_linux
$ mv cuda_10.0.130_410.48_linux cuda_10.0.130_410.48_linux.run
$ sudo sh cuda_10.0.130_410.48_linux.run
Do you accept the previously read EULA?
accept/decline/quit: accept
Install NVIDIA Accelerated Graphics Driver for Linux-x86_64 410.48?
(y)es/(n)o/(q)uit: y
Do you want to install the OpenGL libraries?
(y)es/(n)o/(q)uit [ default is yes ]: y
Do you want to run nvidia-xconfig?
This will update the system X configuration file so that the NVIDIA X driver
is used. The pre-existing X configuration file will be backed up.
This option should not be used on systems that require a custom
X configuration, such as systems with multiple GPU vendors.
(y)es/(n)o/(q)uit [ default is no ]: n
Install the CUDA 10.0 Toolkit?
(y)es/(n)o/(q)uit: n
Install the CUDA 10.0 Samples?
(y)es/(n)o/(q)uit: n
$ sudo reboot
[after reboot]
$ cat /proc/driver/nvidia/version
NVRM version: NVIDIA UNIX x86_64 Kernel Module 410.48 Thu Sep 6 06:36:33 CDT 2018
GCC version: gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.10)
This also worked.
UPDATE 13th February 2019:
I hit the 30,000 character limit for this answer, and had to continue in a separate answer.
UPDATE 13th February 2019:
I hit the 30,000 character limit in my other answer, and so had to post this as a separate answer.
I came across this nvidia blog post on Linking OpenGL for Server-Side Rendering.
This includes the following (emphasis mine):
When the classic OpenGL Application Binary Interface (ABI) was introduced 17 years ago, the only widely adopted windowing and display management system on linux was X11. OpenGL context management, which is not part of OpenGL itself, was therefore synonymous with the glX API. And because the only way to use OpenGL on Linux was via glX, functions for both OpenGL and glX were bundled into the same library, libGL.so.
Linking an OpenGL application was simple: you only needed to link against libGL.so.
Over the years, the situation has changed and a wide range of display managers have emerged. People want to have X11-based display managers on the same system with Wayland, or to use hardware-accelerated OpenGL on the same system with software-emulated OpenGL. This requires a cleaner separation between the OpenGL library and OpenGL context-management libraries.
GLVND, the OpenGL Vendor Neutral Dispatch for Linux, was born to meet this requirement.
To use glX and OpenGL today, you should link against libOpenGL.so as well as libGLX.so. The first contains the OpenGL symbols, the latter the GLX symbols. If you want to use EGL context management instead, link against libOpenGL.so and libEGL.so.
So, this suggests that to use EGL, I should be linking against libOpenGL.so instead of libGL.so.
To test this, I first installed drivers using the package manager:
$ sudo add-apt-repository ppa:graphics-drivers/ppa
$ sudo apt-get update
$ sudo apt-get install nvidia-410
$ sudo reboot
[after reboot]
$ dpkg -l | grep nvidia
ii nvidia-410 410.78-0ubuntu0~gpu16.04.1 amd64 NVIDIA binary driver - version 410.78
ii nvidia-opencl-icd-410 410.78-0ubuntu0~gpu16.04.1 amd64 NVIDIA OpenCL ICD
ii nvidia-prime 0.8.2 amd64 Tools to enable NVIDIA's Prime
ii nvidia-settings 415.27-0ubuntu0~gpu16.04.1 amd64 Tool for configuring the NVIDIA graphics driver
$ cat /proc/driver/nvidia/version
NVRM version: NVIDIA UNIX x86_64 Kernel Module 410.78 Sat Nov 10 22:09:04 CST 2018
GCC version: gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.11)
As seen before, EGL fails with the packaged driver, when linking the test app against libGL.so:
$ wget https://gist.githubusercontent.com/funchal/bff0a8d6dae5b3ace1a88c392416b5bc/raw/1427821a2390a30779881ab59c55b5550a468919/main.c
$ gcc main.c -lGL -lEGL
$ ./a.out
egl 1.5
a.out: main.c:53: main: Assertion `renderer' failed.
Aborted (core dumped)
The machine contains both libGL.so and libOpenGL.so:
$ sudo find /usr -name libGL.so
/usr/lib32/nvidia-410/libGL.so
/usr/lib/nvidia-410/libGL.so
/usr/lib/x86_64-linux-gnu/mesa/libGL.so
/usr/lib/x86_64-linux-gnu/libGL.so
$ sudo find /usr -name libOpenGL.so
/usr/lib32/nvidia-410/libOpenGL.so
/usr/lib/nvidia-410/libOpenGL.so
$ sudo find /usr -name libEGL.so
/usr/lib32/nvidia-410/libEGL.so
/usr/lib/nvidia-410/libEGL.so
/usr/lib/x86_64-linux-gnu/mesa-egl/libEGL.so
/usr/lib/x86_64-linux-gnu/libEGL.so
Linking the test app against libOpenGL.so works!
$ wget https://gist.githubusercontent.com/funchal/bff0a8d6dae5b3ace1a88c392416b5bc/raw/1427821a2390a30779881ab59c55b5550a468919/main.c
$ gcc main.c -L/usr/lib/nvidia-410 -lOpenGL -lEGL
$ ./a.out
egl 1.5
renderer: Tesla K80/PCIe/SSE2
version: 4.6.0 NVIDIA 410.78
I then tested installing the drivers via a run file:
$ wget -L http://us.download.nvidia.com/XFree86/Linux-x86_64/410.93/NVIDIA-Linux-x86_64-410.93.run
$ sudo sh NVIDIA-Linux-x86_64-410.93.run
$ sudo reboot
[after reboot]
$ cat /proc/driver/nvidia/version
NVRM version: NVIDIA UNIX x86_64 Kernel Module 410.93 Thu Dec 20 17:01:16 CST 2018
GCC version: gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.10)
These are the libraries available:
$ sudo find /usr -name libGL.so
/usr/lib32/libGL.so
/usr/lib/x86_64-linux-gnu/libGL.so
$ sudo find /usr -name libOpenGL.so
/usr/lib32/libOpenGL.so
/usr/lib/x86_64-linux-gnu/libOpenGL.so
$ sudo find /usr -name libEGL.so
/usr/lib32/libEGL.so
/usr/lib/x86_64-linux-gnu/libEGL.so
As seen in the previous update from 8th January, with drivers installed by a run file, EGL does work with libGL.so:
$ wget https://gist.githubusercontent.com/funchal/bff0a8d6dae5b3ace1a88c392416b5bc/raw/1427821a2390a30779881ab59c55b5550a468919/main.c
$ gcc main.c -lGL -lEGL
$ ./a.out
egl 1.5
renderer: Tesla K80/PCIe/SSE2
version: 4.6.0 NVIDIA 410.93
EGL also works when linking against libOpenGL.so:
$ wget https://gist.githubusercontent.com/funchal/bff0a8d6dae5b3ace1a88c392416b5bc/raw/1427821a2390a30779881ab59c55b5550a468919/main.c
$ gcc main.c -lOpenGL -lEGL
$ ./a.out
egl 1.5
renderer: Tesla K80/PCIe/SSE2
version: 4.6.0 NVIDIA 410.93
I'm not sure if this is related, but I noticed that the run file and packaged drivers have different dependencies linked into libGL.so. The run file installed drivers have the following dependencies, including libGLX.so:
$ ldd /usr/lib/x86_64-linux-gnu/libGL.so
linux-vdso.so.1 => (0x00007fff28ce5000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fda5af05000)
libGLX.so.0 => /usr/lib/x86_64-linux-gnu/libGLX.so.0 (0x00007fda5acd5000)
libGLdispatch.so.0 => /usr/lib/x86_64-linux-gnu/libGLdispatch.so.0 (0x00007fda5aa02000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fda5a638000)
/lib64/ld-linux-x86-64.so.2 (0x00007fda5b3b2000)
libX11.so.6 => /usr/lib/x86_64-linux-gnu/libX11.so.6 (0x00007fda5a2fe000)
libXext.so.6 => /usr/lib/x86_64-linux-gnu/libXext.so.6 (0x00007fda5a0ec000)
libxcb.so.1 => /usr/lib/x86_64-linux-gnu/libxcb.so.1 (0x00007fda59eca000)
libXau.so.6 => /usr/lib/x86_64-linux-gnu/libXau.so.6 (0x00007fda59cc6000)
libXdmcp.so.6 => /usr/lib/x86_64-linux-gnu/libXdmcp.so.6 (0x00007fda59ac0000)
While the package-installed drivers do not depend on libGLX.so, instead having libnvidia-tls.so and libnvidia-glcore.so as dependencies:
$ ldd /usr/lib/nvidia-410/libGL.so
linux-vdso.so.1 => (0x00007fff139dd000)
libnvidia-tls.so.410.78 => /usr/lib/nvidia-410/tls/libnvidia-tls.so.410.78 (0x00007fed5efef000)
libnvidia-glcore.so.410.78 => /usr/lib/nvidia-410/libnvidia-glcore.so.410.78 (0x00007fed5d414000)
libX11.so.6 => /usr/lib/x86_64-linux-gnu/libX11.so.6 (0x00007fed5d0da000)
libXext.so.6 => /usr/lib/x86_64-linux-gnu/libXext.so.6 (0x00007fed5cec8000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fed5cafe000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fed5c8fa000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fed5c5f1000)
libxcb.so.1 => /usr/lib/x86_64-linux-gnu/libxcb.so.1 (0x00007fed5c3cf000)
/lib64/ld-linux-x86-64.so.2 (0x00007fed5f531000)
libXau.so.6 => /usr/lib/x86_64-linux-gnu/libXau.so.6 (0x00007fed5c1cb000)
libXdmcp.so.6 => /usr/lib/x86_64-linux-gnu/libXdmcp.so.6 (0x00007fed5bfc5000)
To summarize the final fix to this problem:
Link against libOpenGL.so instead of libGL.so!
#define GLEW_EGL
on the gcc command-line so that glew.c
uses eglGetProcAddress()
instead of glXGetProcAddressARB()
:
g++ -DGLEW_EGL -DGLEW_STATIC -Iglew-2.1.0/include main.cpp glew-2.1.0/src/glew.c -lGL -lEGL
^^^^^^^^^^ this is where the magic happens
Building this code with the latest GLEW 2.1.0 tarball:
#include <GL/glew.h>
#include <EGL/egl.h>
#include <iostream>
int main(int argc, char **argv)
{
EGLDisplay display = eglGetDisplay( EGL_DEFAULT_DISPLAY ) ;
if( display == EGL_NO_DISPLAY )
{
std:: cout << "ERROR: EGL could not be initialized"<< std::endl;
exit(EXIT_FAILURE);
}
if( eglInitialize( display, nullptr, nullptr ) != EGL_TRUE )
{
std:: cout << "ERROR: Could not start EGL display connection"<< std::endl;
exit(EXIT_FAILURE);
}
EGLConfig config;
EGLint num_config = 0;
if( eglChooseConfig( display, nullptr, &config, 1, &num_config ) != EGL_TRUE )
{
std:: cout << "ERROR: Configuration selection failed" << std::endl;
exit(EXIT_FAILURE);
}
if( num_config == 0 )
{
std:: cout << "ERROR: No configurations" << std::endl;
exit(EXIT_FAILURE);
}
eglBindAPI( EGL_OPENGL_API );
EGLContext context = eglCreateContext( display, config, EGL_NO_CONTEXT, NULL );
if( eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, context) != EGL_TRUE )
{
std:: cout << "ERROR: Display was not made current one"<< std::endl;
exit(EXIT_FAILURE);
}
GLenum err = glewInit();
if (GLEW_OK != err)
{
std:: cout << "GLEW Error: " << glewGetErrorString(err) << std::endl;
exit(EXIT_FAILURE);
}
std::cout << glGetString( GL_VERSION ) << std::endl;
std::cout << glGetString( GL_VENDOR ) << std::endl;
std::cout << glGetString( GL_RENDERER ) << std::endl;
return 0;
}
...gives me this on my on my Debian Stretch system in X11:
3.0 Mesa 13.0.6
Intel Open Source Technology Center
Mesa DRI Intel(R) Kabylake GT2