I’m on ubuntu linux, version 15.10, nvidia drivers 361.28, cuda toolkit 7.5, and have tested the following code on both a GeForce GT 750M & a GeForce GTX TITAN.
When creating an opengl context via EGL according to this blog post:
every CUDA/OpenGL interoperability API function in the CUDA driver API segfaults. Here’s some example code exhibiting the issue (which works if I use a GLX-created opengl context):
#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;
}