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 );
}