Problem with OpenGL Visualization without an X Server

I want to render with OpenGL without an X Server.

Code taken from here https://devblogs.nvidia.com/egl-eye-opengl-visualization-without-x-server/ and slightly modified:

#include <iostream>
#include <EGL/egl.h>
#include <GL/gl.h>

static const EGLint configAttribs[] = {
    EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
    EGL_BLUE_SIZE, 8,
    EGL_GREEN_SIZE, 8,
    EGL_RED_SIZE, 8,
    EGL_DEPTH_SIZE, 8,
    EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
    EGL_NONE
};        

// static const int pbufferWidth = 9;
// static const int pbufferHeight = 9;

// static const EGLint pbufferAttribs[] = {
//             EGL_WIDTH, pbufferWidth,
//             EGL_HEIGHT, pbufferHeight,
//             EGL_NONE,
// };

int main(int argc, char *argv[])
{
    // 1. Initialize EGL
    EGLDisplay eglDpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);

    EGLint major, minor;

    eglInitialize(eglDpy, &major, &minor);

    // 2. Select an appropriate configuration
    EGLint numConfigs;
    EGLConfig eglCfg;

    eglChooseConfig(eglDpy, configAttribs, &eglCfg, 1, &numConfigs);

    // 3. Create a surface
    // EGLSurface eglSurf = eglCreatePbufferSurface(eglDpy, eglCfg, pbufferAttribs);

    // 4. Bind the API
    eglBindAPI(EGL_OPENGL_API);

    // 5. Create a context and make it current
    EGLContext eglCtx = eglCreateContext(eglDpy, eglCfg, EGL_NO_CONTEXT, NULL);

    // eglMakeCurrent(eglDpy, eglSurf, eglSurf, eglCtx);
    eglMakeCurrent(eglDpy, EGL_NO_SURFACE, EGL_NO_SURFACE, eglCtx);

    int ma = -1;
    int mi = -1;
    eglQueryContext(eglDpy, eglCtx, EGL_CONTEXT_MAJOR_VERSION, &ma);
    eglQueryContext(eglDpy, eglCtx, EGL_CONTEXT_MINOR_VERSION, &mi);
    std::cout << ma << "." << mi << std::endl;

    std::cout << "Error " << (glGetError() != GL_NO_ERROR) << std::endl;

    ma = -1;
    mi = -1;
    glGetIntegerv(GL_MAJOR_VERSION, &ma);
    glGetIntegerv(GL_MINOR_VERSION, &mi);
    std::cout << ma << "." << mi << std::endl;

    std::cout << "Error " << (glGetError() != GL_NO_ERROR) << std::endl;

    int n = -1;
    glGetIntegerv(GL_NUM_EXTENSIONS, &n);
    std::cout << "Extensions " << n << std::endl;

    // 6. Terminate EGL when finished
    eglTerminate(eglDpy);
    return 0;
}

The above code leads to output

4.6
Error 0
-1.-1
Error 0
Extensions -1

Cleary the OpenGL context is not working as expected here!

Any help is appreciated.

My setup is

Linux gpusrv 4.15.0-47-generic #50~16.04.1-Ubuntu SMP Fri Mar 15 16:06:21 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
Ubuntu 16.04.6 LTS \n \l

nvidia-smi outputs

Wed Apr 17 15:44:34 2019
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 410.48                 Driver Version: 410.48                    |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  Tesla V100-SXM2...  Off  | 00000000:04:00.0 Off |                    0 |
| N/A   45C    P0    56W / 300W |      0MiB / 16130MiB |      0%   E. Process |
+-------------------------------+----------------------+----------------------+
|   1  Tesla V100-SXM2...  Off  | 00000000:06:00.0 Off |                    0 |
| N/A   39C    P0    55W / 300W |      0MiB / 16130MiB |      0%   E. Process |
+-------------------------------+----------------------+----------------------+
|   2  Tesla V100-SXM2...  Off  | 00000000:07:00.0 Off |                    0 |
| N/A   37C    P0    53W / 300W |      0MiB / 16130MiB |      0%   E. Process |
+-------------------------------+----------------------+----------------------+
|   3  Tesla V100-SXM2...  Off  | 00000000:08:00.0 Off |                    0 |
| N/A   40C    P0    55W / 300W |      0MiB / 16130MiB |      0%   E. Process |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|  No running processes found                                                 |
+-----------------------------------------------------------------------------+

nvidia-bug-report.log.gz (1.91 MB)

My guess would be the Matroy server graphics adapter is interfering with that. Maybe also some libs are set to mesa because of it. Tried the multi-gpu sample to list the gpus available?

eglQueryDevicesEXT says 4 devices.

“ldd -r” gives me

linux-vdso.so.1 =>  (0x00007ffd6d3f3000)
	libEGL.so.1 => /usr/lib/nvidia-410/libEGL.so.1 (0x00007fe114410000)
	libGL.so.1 => /usr/lib/nvidia-410/libGL.so.1 (0x00007fe1140d2000)
	libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fe113d50000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe113986000)
	libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fe113782000)
	libGLdispatch.so.0 => /usr/lib/nvidia-410/libGLdispatch.so.0 (0x00007fe1134b4000)
	libnvidia-tls.so.410.48 => /usr/lib/nvidia-410/tls/libnvidia-tls.so.410.48 (0x00007fe1132b0000)
	libnvidia-glcore.so.410.48 => /usr/lib/nvidia-410/libnvidia-glcore.so.410.48 (0x00007fe1116f6000)
	libX11.so.6 => /usr/lib/x86_64-linux-gnu/libX11.so.6 (0x00007fe1113bc000)
	libXext.so.6 => /usr/lib/x86_64-linux-gnu/libXext.so.6 (0x00007fe1111aa000)
	libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fe110ea1000)
	/lib64/ld-linux-x86-64.so.2 (0x00007fe114616000)
	libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fe110c8b000)
	libxcb.so.1 => /usr/lib/x86_64-linux-gnu/libxcb.so.1 (0x00007fe110a69000)
	libXau.so.6 => /usr/lib/x86_64-linux-gnu/libXau.so.6 (0x00007fe110865000)
	libXdmcp.so.6 => /usr/lib/x86_64-linux-gnu/libXdmcp.so.6 (0x00007fe11065f000)

I tried your code and ran it on VT:
EGL/GL switched to nvidia:

4.6
Error 0
4.6
Error 0
Extensions 338

EGL/GL switched to mesa:

-1.-1
Error 0
-1.-1
Error 0
Extensions -1

So maybe there’s something wrong with your glvnd setup. What’s the output of

ls -l /usr/lib/libGL*

In /usr/lib there’s no libGL* library. Here for /usr/lib/x86_64-linux-gnu

ls -l /usr/lib/x86_64-linux-gnu/libGL*                                                                                                                                                            
lrwxrwxrwx 1 root root     13 Jun 14  2018 /usr/lib/x86_64-linux-gnu/libGL.so -> mesa/libGL.so
-rw-r--r-- 1 root root 911218 Okt 23  2015 /usr/lib/x86_64-linux-gnu/libGLU.a
lrwxrwxrwx 1 root root     15 Okt 23  2015 /usr/lib/x86_64-linux-gnu/libGLU.so -> libGLU.so.1.3.1
lrwxrwxrwx 1 root root     15 Okt 23  2015 /usr/lib/x86_64-linux-gnu/libGLU.so.1 -> libGLU.so.1.3.1
-rw-r--r-- 1 root root 453352 Okt 23  2015 /usr/lib/x86_64-linux-gnu/libGLU.so.1.3.1
lrwxrwxrwx 1 root root     37 Sep 12  2018 /usr/lib/x86_64-linux-gnu/libGLX_indirect.so.0 -> ../nvidia-410/libGLX_nvidia.so.410.48
lrwxrwxrwx 1 root root     20 Jän 24 09:29 /usr/lib/x86_64-linux-gnu/libGLX_nvidia.so.0 -> libGLX_indirect.so.0

Ok, my bad, forgot that Ubuntu 16.04 isn’t using glvnd but the alternatives system:
https://devtalk.nvidia.com/default/topic/1023153/linux/opengl-nvidia-and-ubuntu-14-04-issues/post/5206476/#5206476
Switching everything to nvidia would break your Xorg on the Matrox, though.

Thanks, for your effort.

I looked at these settings and they seem to be correct. Right?

root:/usr/lib/nvidia# update-alternatives --list x86_64-linux-gnu_egl_conf
/usr/lib/nvidia-410-prime/ld.so.conf
/usr/lib/nvidia-410/ld.so.conf
/usr/lib/x86_64-linux-gnu/mesa-egl/ld.so.conf
root:/usr/lib/nvidia# update-alternatives --list x86_64-linux-gnu_gl_conf
/usr/lib/nvidia-410-prime/ld.so.conf
/usr/lib/nvidia-410/ld.so.conf
/usr/lib/x86_64-linux-gnu/mesa/ld.so.conf

Those are the possible settings, use the --display option to see what the current setting is.

Ah, okay.
But looks like it points to nvidia.

root:/usr/lib/nvidia# update-alternatives --display x86_64-linux-gnu_egl_conf
x86_64-linux-gnu_egl_conf - auto mode
  link best version is /usr/lib/nvidia-410/ld.so.conf
  link currently points to /usr/lib/nvidia-410/ld.so.conf
  link x86_64-linux-gnu_egl_conf is /etc/ld.so.conf.d/x86_64-linux-gnu_EGL.conf
/usr/lib/nvidia-410-prime/ld.so.conf - priority 8603
/usr/lib/nvidia-410/ld.so.conf - priority 8604
/usr/lib/x86_64-linux-gnu/mesa-egl/ld.so.conf - priority 500
root:/usr/lib/nvidia# update-alternatives --display x86_64-linux-gnu_gl_conf
x86_64-linux-gnu_gl_conf - auto mode
  link best version is /usr/lib/nvidia-410/ld.so.conf
  link currently points to /usr/lib/nvidia-410/ld.so.conf
  link x86_64-linux-gnu_gl_conf is /etc/ld.so.conf.d/x86_64-linux-gnu_GL.conf
  slave x86_64-linux-gnu_alternate-install-present is /usr/lib/nvidia/alternate-install-present
  slave x86_64-linux-gnu_grub_fb_blacklist is /usr/share/grub-gfxpayload-lists/blacklist/10_proprietary-graphics-drivers
  slave x86_64-linux-gnu_libvdpau_nvidia.so is /usr/lib/libvdpau_nvidia.so
  slave x86_64-linux-gnu_libvdpau_nvidia.so.1 is /usr/lib/vdpau/libvdpau_nvidia.so.1
  slave x86_64-linux-gnu_libvdpau_nvidia.so.1_lib32 is /usr/lib32/vdpau/libvdpau_nvidia.so.1
  slave x86_64-linux-gnu_libvdpau_nvidia.so_lib32 is /usr/lib32/libvdpau_nvidia.so
  slave x86_64-linux-gnu_man_nvidiaxconfig.gz is /usr/share/man/man1/nvidia-xconfig.1.gz
  slave x86_64-linux-gnu_man_persistenced.gz is /usr/share/man/man1/nvidia-persistenced.1.gz
  slave x86_64-linux-gnu_nvidia-cuda-mps-control is /usr/bin/nvidia-cuda-mps-control
  slave x86_64-linux-gnu_nvidia-cuda-mps-control.1.gz is /usr/share/man/man1/nvidia-cuda-mps-control.1.gz
  slave x86_64-linux-gnu_nvidia-cuda-mps-server is /usr/bin/nvidia-cuda-mps-server
  slave x86_64-linux-gnu_nvidia-debugdump is /usr/bin/nvidia-debugdump
  slave x86_64-linux-gnu_nvidia-smi.1.gz is /usr/share/man/man1/nvidia-smi.1.gz
  slave x86_64-linux-gnu_nvidia_app_profile is /usr/share/nvidia/nvidia-application-profiles-410.48-rc
  slave x86_64-linux-gnu_nvidia_app_profile_keys is /usr/share/nvidia/nvidia-application-profiles-410.48-key-documentation
  slave x86_64-linux-gnu_nvidia_bug_report is /usr/bin/nvidia-bug-report.sh
  slave x86_64-linux-gnu_nvidia_drv is /usr/lib/xorg/modules/drivers/nvidia_drv.so
  slave x86_64-linux-gnu_nvidia_modconf is /etc/modprobe.d/nvidia-graphics-drivers.conf
  slave x86_64-linux-gnu_nvidia_persistenced is /usr/bin/nvidia-persistenced
  slave x86_64-linux-gnu_nvidia_smi is /usr/bin/nvidia-smi
  slave x86_64-linux-gnu_nvidia_xconfig is /usr/bin/nvidia-xconfig
  slave x86_64-linux-gnu_xorg_extra_modules is /usr/lib/x86_64-linux-gnu/xorg/extra-modules
/usr/lib/nvidia-410-prime/ld.so.conf - priority 8603
  slave x86_64-linux-gnu_man_nvidiaxconfig.gz: /usr/share/man/man1/alt-nvidia-410-xconfig.1.gz
  slave x86_64-linux-gnu_nvidia-debugdump: /usr/lib/nvidia-410/bin/nvidia-debugdump
  slave x86_64-linux-gnu_nvidia-smi.1.gz: /usr/share/man/man1/alt-nvidia-410-smi.1.gz
  slave x86_64-linux-gnu_nvidia_app_profile: /usr/share/nvidia-410/nvidia-application-profiles-410.48-rc
  slave x86_64-linux-gnu_nvidia_app_profile_keys: /usr/share/nvidia-410/nvidia-application-profiles-410.48-key-documentation
  slave x86_64-linux-gnu_nvidia_bug_report: /usr/lib/nvidia-410/bin/nvidia-bug-report.sh
  slave x86_64-linux-gnu_nvidia_modconf: /lib/nvidia-410/modprobe.conf
  slave x86_64-linux-gnu_nvidia_smi: /usr/lib/nvidia-410/bin/nvidia-smi
  slave x86_64-linux-gnu_nvidia_xconfig: /usr/lib/nvidia-410/bin/nvidia-xconfig
/usr/lib/nvidia-410/ld.so.conf - priority 8604
  slave x86_64-linux-gnu_alternate-install-present: /usr/lib/nvidia-410/alternate-install-present
  slave x86_64-linux-gnu_grub_fb_blacklist: /usr/share/nvidia-410/nvidia-410.grub-gfxpayload
  slave x86_64-linux-gnu_libvdpau_nvidia.so: /usr/lib/nvidia-410/vdpau/libvdpau_nvidia.so
  slave x86_64-linux-gnu_libvdpau_nvidia.so.1: /usr/lib/nvidia-410/vdpau/libvdpau_nvidia.so.1
  slave x86_64-linux-gnu_libvdpau_nvidia.so.1_lib32: /usr/lib32/nvidia-410/vdpau/libvdpau_nvidia.so.1
  slave x86_64-linux-gnu_libvdpau_nvidia.so_lib32: /usr/lib32/nvidia-410/vdpau/libvdpau_nvidia.so
  slave x86_64-linux-gnu_man_nvidiaxconfig.gz: /usr/share/man/man1/alt-nvidia-410-xconfig.1.gz
  slave x86_64-linux-gnu_man_persistenced.gz: /usr/share/man/man1/alt-nvidia-410-persistenced.1.gz
  slave x86_64-linux-gnu_nvidia-cuda-mps-control: /usr/lib/nvidia-410/bin/nvidia-cuda-mps-control
  slave x86_64-linux-gnu_nvidia-cuda-mps-control.1.gz: /usr/share/man/man1/alt-nvidia-410-cuda-mps-control.1.gz
  slave x86_64-linux-gnu_nvidia-cuda-mps-server: /usr/lib/nvidia-410/bin/nvidia-cuda-mps-server
  slave x86_64-linux-gnu_nvidia-debugdump: /usr/lib/nvidia-410/bin/nvidia-debugdump
  slave x86_64-linux-gnu_nvidia-smi.1.gz: /usr/share/man/man1/alt-nvidia-410-smi.1.gz
  slave x86_64-linux-gnu_nvidia_app_profile: /usr/share/nvidia-410/nvidia-application-profiles-410.48-rc
  slave x86_64-linux-gnu_nvidia_app_profile_keys: /usr/share/nvidia-410/nvidia-application-profiles-410.48-key-documentation
  slave x86_64-linux-gnu_nvidia_bug_report: /usr/lib/nvidia-410/bin/nvidia-bug-report.sh
  slave x86_64-linux-gnu_nvidia_drv: /usr/lib/nvidia-410/xorg/nvidia_drv.so
  slave x86_64-linux-gnu_nvidia_modconf: /lib/nvidia-410/modprobe.conf
  slave x86_64-linux-gnu_nvidia_persistenced: /usr/lib/nvidia-410/bin/nvidia-persistenced
  slave x86_64-linux-gnu_nvidia_smi: /usr/lib/nvidia-410/bin/nvidia-smi
  slave x86_64-linux-gnu_nvidia_xconfig: /usr/lib/nvidia-410/bin/nvidia-xconfig
  slave x86_64-linux-gnu_xorg_extra_modules: /usr/lib/nvidia-410/xorg
/usr/lib/x86_64-linux-gnu/mesa/ld.so.conf - priority 500
  slave x86_64-linux-gnu_xorg_extra_modules: /usr/lib/x86_64-linux-gnu/xorg/x11-extra-modules

Looks correct. Did you check if your application is linked against the correct libs, ldd ?

Yes, that was the output in https://devtalk.nvidia.com/default/topic/1050285/linux/problem-with-opengl-visualization-without-an-x-server/post/5330594/#5330594.

Used a simple CMake project.

cmake_minimum_required (VERSION 3.5)
project(egl)

add_executable(main main.cpp)
include_directories(BEFORE SYSTEM ${CMAKE_SOURCE_DIR})
target_link_libraries(main "/usr/lib/nvidia-410/libEGL.so.410.48" "/usr/lib/nvidia-410/libGL.so.410.48")

Copied headers from khronos (EGL, GL, KHR) directly into src dir.

Everything looks correct. One problem I ran into sometimes was applications ignoring the library path and always loading /usr/lib/libGL.so (in your case /usr/lib/x86_64-linux-gnu/libGL.so) which then points to mesa. Either try linking it to the nvidia libGL.so or use LD_PRELOAD to force the application to load the correct lib.
LD_PRELOAD="/usr/lib/nvidia-410/libGL.so"

I tried to update to the newest version (cuda 10.1), which brings me to “Driver Version: 418.39”.
But same results. Even tried running it as root.

# env LD_PRELOAD=/usr/lib/nvidia-418/libGL.so.418.39 ./main
Detected 4
4.6
Error 0
-1.-1
Error 0
Extensions -1

With help from Peter Messmer I was able to resolve the issue.
Instead of linking against

libGL.so.1 => /usr/lib/nvidia-410/libGL.so.1 (0x00007fe1140d2000)

I now link against

libOpenGL.so.0 => /usr/lib/nvidia-418/libOpenGL.so.0 (0x00007ffa1a91d000)

and everythink works as expected.

Thank you @Thomas5248 @generix this post saved my one week’s effort trying to get the correct link library!!! Thanks!