Skip to content

Instantly share code, notes, and snippets.

@andrewseidl
Last active July 21, 2016 06:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save andrewseidl/7ff90a7f6675d1419560ef7850176979 to your computer and use it in GitHub Desktop.
Save andrewseidl/7ff90a7f6675d1419560ef7850176979 to your computer and use it in GitHub Desktop.
egl-segfault for NVIDIA/nvidia-docker#146

Demonstrates segfault if libEGL.so does not exist. Creating a symlink pointing to libEGL.so.1 resolves this. Issue appears to be that libcuda dlopens libEGL.so instead of libEGL.so.1.

See: https://devtalk.nvidia.com/default/topic/917987/cuda-opengl-interoperability-segfault-using-egl-opengl-context-egl_platform_device_ext-/

And: NVIDIA/nvidia-docker#146

To compile:

g++ egl-segfault.cpp -o egl-segfault -lEGL -I/usr/local/cuda-8.0/include/ -lcuda

Program should simply exit successfully. Will segfault if libEGL.so does not exist.

#define EGL_EGLEXT_PROTOTYPES // for EGL extensions
#include <GL/gl.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <cuda.h>
#include <cudaGL.h>
static const EGLint configAttribs[] = {
EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, EGL_BLUE_SIZE, 8, EGL_GREEN_SIZE, 8,
EGL_RED_SIZE, 8, EGL_ALPHA_SIZE, 8,
// EGL_DEPTH_SIZE,
// 8,
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, EGL_NONE};
static const int pbufferWidth = 1024;
static const int pbufferHeight = 1024;
static const EGLint pbufferAttribs[] = {
EGL_WIDTH, pbufferWidth, EGL_HEIGHT, pbufferHeight, EGL_NONE,
};
static const EGLint contextAttribs[] = {
EGL_CONTEXT_MAJOR_VERSION, 4,
EGL_CONTEXT_MINOR_VERSION, 5,
EGL_CONTEXT_OPENGL_PROFILE_MASK, EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
EGL_NONE,
};
int main(int argc, char *argv[]) {
// 1. Initialize EGL
static const int MAX_DEVICES = 4;
EGLDeviceEXT eglDevs[MAX_DEVICES];
EGLint numDevices;
PFNEGLQUERYDEVICESEXTPROC eglQueryDevicesEXT =
(PFNEGLQUERYDEVICESEXTPROC)eglGetProcAddress("eglQueryDevicesEXT");
eglQueryDevicesEXT(MAX_DEVICES, eglDevs, &numDevices);
PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT =
(PFNEGLGETPLATFORMDISPLAYEXTPROC)eglGetProcAddress(
"eglGetPlatformDisplayEXT");
EGLDisplay eglDpy =
eglGetPlatformDisplayEXT(EGL_PLATFORM_DEVICE_EXT, eglDevs[0], 0);
PFNEGLQUERYDEVICEATTRIBEXTPROC eglQueryDeviceAttribEXT =
(PFNEGLQUERYDEVICEATTRIBEXTPROC)eglGetProcAddress(
"eglQueryDeviceAttribEXT");
int deviceId = -1;
eglQueryDeviceAttribEXT(eglDevs[0], EGL_CUDA_DEVICE_NV,
reinterpret_cast<EGLAttrib *>(&deviceId));
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, contextAttribs);
eglMakeCurrent(eglDpy, eglSurf, eglSurf, eglCtx);
cuInit(0);
unsigned int cudaDeviceCnt = 0;
unsigned int maxCudaDeviceCnt = 10;
CUdevice cudaDevices[10];
cuGLGetDevices(&cudaDeviceCnt, cudaDevices, maxCudaDeviceCnt,
CU_GL_DEVICE_LIST_ALL);
// the above cuGLGetDevices() call segfaults every time. It works with an
// OpenGL context created via GLX
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment