10n02

Re-create OpenCL-OpenGL interop

Discussion created by 10n02 on Oct 6, 2011
Latest reply on Nov 28, 2012 by zoomzoom
Problem when create, release and re-create OpenCL-OpenGL context.

Hi everyone,

I have a problem when I create, release and re-create OpenCL-OpenGL context. I have isolated this issue in the program folowing:

The first iteration will succeed, and the second (or the 3rd sometime...) will fail at clCreateFromGLBuffer(), with the CL_INVALID_GL_OBJECT error.

I don't undurstand why because I delete ALL, even the window

Here is the output of the program:

 

===================START ITERATION 0

===================START ITERATION 1

!!! ERROR -60 !!!!!!!!

 

 

If you have any idea, Thx in advance

 

Edit: Here, I do not use GLUT, in order to isolate the problem to the maximum. But Even with GLUT, I have the same problem.

/* additional libraries used: OpenCL.lib Opengl32.lib glew32.lib */ #include <iostream> //std::cout... #include <Windows.h> // wglGetCurrentContext, wglGetCurrentDC... #include <CL/cl.h> #include <CL/cl_gl.h> #include <GL\glew.h>//include GLEW //manage OpenCL errors #define ECL_CHECK(a) { cl_int errorCode = a;\ if ( errorCode != CL_SUCCESS )\ { std::cout<<"ERROR OpenCL, error = "<<\ errorCode<<std::endl; return 0; } } //manage OpenGL errors #define EGL_CHECK() { GLenum glError = glGetError();\ if ( glError != GL_NO_ERROR ) {\ std::cout<<"ERROR OpenGL, error = "<<\ glError<<std::endl; return 0; } } //the simplest window procedure long __stdcall WindowProcedure( HWND window, unsigned int msg, WPARAM wp, LPARAM lp ) { return DefWindowProc( window, msg, wp, lp ) ; } //entry point int main(int nbArg, char** args) { //the first iteration will succeed, //the second will fail with the "!!! ERROR -60 !!!!!!!!" message for(int i=0; i<10; i++) { std::cout<<"===================START ITERATION "<<i<<std::endl; ////// CREATE WINDOW ////////////////////////////// const wchar_t* const myclassName = L"myclass" ; WNDCLASSEX wndclass = { sizeof(WNDCLASSEX), CS_DBLCLKS, WindowProcedure, 0, 0, GetModuleHandle(0), LoadIcon(0,IDI_APPLICATION), LoadCursor(0,IDC_ARROW), HBRUSH(COLOR_WINDOW+1), 0, myclassName, LoadIcon(0,IDI_APPLICATION) } ; if( !RegisterClassEx(&wndclass) ) { std::cout<<"erreur RegisterClassEx"<<std::endl;return 0; } HWND hWnd = CreateWindowEx( 0, myclassName, L"test", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, GetModuleHandle(0), 0 ) ; if ( hWnd == NULL ) { std::cout<<"erreur window"<<std::endl;return 0; } ////// CREATE WINDOW OPENGL CONTEXT ////////////////////////////// HDC windowDC = GetWindowDC(hWnd); PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd 1, // version number PFD_DRAW_TO_WINDOW | // support window PFD_SUPPORT_OPENGL | // support OpenGL PFD_DOUBLEBUFFER, // double buffered PFD_TYPE_RGBA, // RGBA type 24, // 24-bit color depth 0, 0, 0, 0, 0, 0, // color bits ignored 0, // no alpha buffer 0, // shift bit ignored 0, // no accumulation buffer 0, 0, 0, 0, // accum bits ignored 32, // 32-bit z-buffer 0, // no stencil buffer 0, // no auxiliary buffer PFD_MAIN_PLANE, // main layer 0, // reserved 0, 0, 0 // layer masks ignored }; // get the best available match of pixel format for the device context int iPixelFormat = ChoosePixelFormat(windowDC, &pfd); // make that the pixel format of the device context if ( !SetPixelFormat(windowDC, iPixelFormat, &pfd) ) { std::cout<<"error SetPixelFormat"<<std::endl; return 0; } HGLRC windowGLcontext = wglCreateContext(windowDC); // make it the calling thread's current rendering context if ( !wglMakeCurrent (windowDC, windowGLcontext) ) { std::cout<<"error wglMakeCurrent"<<std::endl; return 0; } //init the GLEW if ( glewInit() != GLEW_OK ) { std::cout<<"error glewInit"<<std::endl;return 0; } ////// INIT OPENCL ////////////////////////////// //get the 1st platform cl_platform_id platform; cl_uint platforms; ECL_CHECK(clGetPlatformIDs(1, &platform, &platforms)); //get the CPU device cl_device_id device[1]; cl_uint nbDevicesCPU; ECL_CHECK(clGetDeviceIDs(platform, CL_DEVICE_TYPE_CPU, 1, &(device[0]), &nbDevicesCPU)); if ( nbDevicesCPU != 1 ) {std::cout<<"number of device CPU != 1"<<std::endl;return 0;} ////// CREATE OPENCL interop context ////////////////////////////// //context properties cl_context_properties properties[]= { CL_CONTEXT_PLATFORM, (cl_context_properties)platform, CL_GL_CONTEXT_KHR,(cl_context_properties) windowGLcontext, CL_WGL_HDC_KHR, (cl_context_properties) windowDC, 0 }; cl_device_id deviceUsedForContext[] = { device[0] }; cl_int errorCreateContext; cl_context openCLcontext = clCreateContext(properties, 1, deviceUsedForContext, NULL, NULL, &errorCreateContext); ECL_CHECK(errorCreateContext); ////////// create the interop buffer ////////////////////////////// GLuint bufferOpenGL; glGenBuffers(1,&bufferOpenGL); EGL_CHECK(); glBindBuffer(GL_ARRAY_BUFFER,bufferOpenGL); EGL_CHECK(); glBindBuffer(GL_ARRAY_BUFFER,0); EGL_CHECK(); if ( !glIsBuffer(bufferOpenGL) ) { std::cout<<"error: is NOT buffer"<<std::endl; } cl_int err; cl_mem clMemory = clCreateFromGLBuffer(openCLcontext, CL_MEM_READ_WRITE, bufferOpenGL, &err); // // ----> HERE IS THE ERROR (triggered at the second iteration (or the 3rd sometime...)) <---- // if ( err == CL_INVALID_GL_OBJECT ) { std::cout<<"!!! ERROR -60 !!!!!!!!"<<std::endl; return 0; } ECL_CHECK(err); ////////// RELEASE ALL ////////////////////////////// ECL_CHECK(clReleaseMemObject(clMemory)); glDeleteBuffers(1, &bufferOpenGL); EGL_CHECK(); ECL_CHECK(clReleaseContext(openCLcontext)); if ( 1 != ReleaseDC(hWnd,windowDC)) { std::cout<<"error ReleaseDC"<<std::endl; } if ( !wglMakeCurrent (NULL, NULL) ) { std::cout<<"error make current NULL"<<std::endl; } if ( !wglDeleteContext (windowGLcontext) ) { std::cout<<"error delete context"<<std::endl; } if ( !DestroyWindow(hWnd) ) { std::cout<<"error DestroyWindow"<<std::endl; } if ( !UnregisterClass(myclassName,NULL) ) { std::cout<<"error UnregisterClass"<<std::endl; } } std::cout<<"--- END OF PROGRAM ---"<<std::endl; return 0; }

Outcomes