Are multiple host threads with OpenCL/OpenGL interop possible?

Working with OpenCL 1.1, I have been trying to run a kernel from a host thread. I’m using the OpenCL/OpenGL interop process and want to reuse GL vertex buffers in my CL kernel.

I do extensive error checking when I set the kernel up and nothing seems to be the problem (This happens on a host process). However when I run my kernel through a host pthread, I get seg-fault on the first clEnqueueAcquireGLObjects(…) function-call in my runKernel() function. If I run it through a host process, it works fine but seg-faults without returning any error if I call it from a host thread. The pthread run() and the runKernel() source-codes are given below. Could anyone tell me if CL/GL interop is at all possible with host threads calling CL kernels? If someone wants the whole source file, I’ll be happy to share, but its a huge file, so I’m not copying the whole code

I’m running Ubuntu 9.10 with a Fermi-based GeForce GTX 480 card.

void MSD_Mesh::run( )

{

	while( true ){

	   // check and wait for semaphore objects

	  _syncControl[ _semPhysicsWaitIndex ].wait( );

	  // write buffer, execute kernel function and read in buffer

	  runKernel( );

	  // release data

	 _syncControl[ _semPhysicsPostIndex ].post( );

  }

}

inline void MSD_Mesh::runKernel( )

{

	// obtain GL objects

#ifndef NDEBUG

	cl_int errNum =

#endif

	 clEnqueueAcquireGLObjects( _clCommands, 2, _clVertexBufferID, 0, 0, NULL );

	 assert( CL_SUCCESS == errNum );

#ifndef NDEBUG

	 errNum |=

#endif

	 clEnqueueAcquireGLObjects( _clCommands, 1, &_clForceTextureID, 0, 0, NULL );

#ifndef NDEBUG

	 errNum |=

#endif

	 clEnqueueAcquireGLObjects( _clCommands, 1, &_clForceTexCoordBufferID, 0, 0, NULL );

	 assert( CL_SUCCESS == errNum );

	  // set source and destination buffer objects

	  if( !_bufferFlag ){

#ifndef NDEBUG

	errNum =

#endif

	clSetKernelArg( _clKernel, 4, sizeof( cl_mem ), ( void* )&( _clVertexBufferID[ 0 ]));

#ifndef NDEBUG

	errNum |=

#endif

	clSetKernelArg( _clKernel, 5, sizeof( cl_mem ), ( void* )&( _clVertexBufferID[ 1 ]));

	_bufferFlag = true;

	  } else {

#ifndef NDEBUG

	errNum =

#endif

	clSetKernelArg( _clKernel, 4, sizeof( cl_mem ), ( void* )&( _clVertexBufferID[ 1 ]));

#ifndef NDEBUG

	errNum |=

#endif

	clSetKernelArg( _clKernel, 5, sizeof( cl_mem ), ( void* )&( _clVertexBufferID[ 0 ]));

	_bufferFlag = false;

	  }

	  assert( CL_SUCCESS == errNum );

	  // run the kernel

#ifndef NDEBUG

	  errNum =

#endif

	  clEnqueueNDRangeKernel( _clCommands, _clKernel, 2, NULL, ( size_t* )_glForceFrameBufferDimensions, NULL, 0, 0, NULL );

	  assert( CL_SUCCESS == errNum );

	  // copy surface vertices from device to host

	  if( !_bufferFlag ){

#ifndef NDEBUG

	errNum =

#endif

	clEnqueueReadBuffer( _clCommands, _clVertexBufferID[ 1 ], CL_TRUE, 0, _numSurfaceVertices*3*sizeof( real ), &( _surfaceVertices[ 0 ]), 0, 0, NULL );

	  } else {

#ifndef NDEBUG

	errNum =

#endif

	clEnqueueReadBuffer( _clCommands, _clVertexBufferID[ 0 ], CL_TRUE, 0, _numSurfaceVertices*3*sizeof( real ), &( _surfaceVertices[ 0 ]), 0, 0, NULL );

	   }

	   assert( CL_SUCCESS == errNum );

	   // release GL objects

#ifndef NDEBUG

	   errNum =

#endif

	   clEnqueueReleaseGLObjects( _clCommands, 1, &_clForceTexCoordBufferID, 0, 0, NULL );

#ifndef NDEBUG

	   errNum |=

#endif

	   clEnqueueReleaseGLObjects( _clCommands, 1, &_clForceTextureID, 0, 0, NULL );

#ifndef NDEBUG

	   errNum |=

#endif

	   clEnqueueReleaseGLObjects( _clCommands, 2, _clVertexBufferID, 0, 0, NULL );

	   assert( CL_SUCCESS == errNum );

	   // finish

	   clFinish( _clCommands );

}

Just wanted to report that I had solved the problem. I just release the GL objects before drawing and reacquire them after rendering is complete. Since these rendering calls happen in the process rather than the thread, it doesn’t throw any error. I can still run my kernel through the host thread.

Just wanted to report that I had solved the problem. I just release the GL objects before drawing and reacquire them after rendering is complete. Since these rendering calls happen in the process rather than the thread, it doesn’t throw any error. I can still run my kernel through the host thread.