Hi forum,
For OpenCL - OpenGL interoperability, i believe you need to create the GL context first before initializing the OpenCL context. And i am doing the same , but i failed the create the OpenCL context. I think i am missing something in the process and i need your help here.
this OpenCL context creation is encapsulated into a class structure as an attempt to extend the scene graph system with OpenCL support. Here it goes:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
osgOpenCLContext::osgOpenCLContext(): m_clContext(NULL),
m_clPlatform(NULL),
m_clDevice(NULL),
m_clCommandQueue(NULL)
{
}
osgOpenCLContext::~osgOpenCLContext()
{
if(m_clCommandQueue) clReleaseCommandQueue(m_clCommandQueue);
if(m_clContext) clReleaseContext(m_clContext);
}
bool osgOpenCLContext::setupOsgOpenCLAndViewer(osgViewer::ViewerBase &viewer,
int ctxID /*= -1 */)
{
// You must use single threaded version since osgCompute currently
// does only support single threaded applications.
viewer.setThreadingModel( osgViewer::ViewerBase::SingleThreaded );
// Does create a single OpenGL context
// which is not released at the end of a frame to secure
// CUDA launches everywhere
viewer.setReleaseContextAtEndOfFrameHint(false);
// Create the current OpenGL context and make it current
if( !viewer.isRealized() )
viewer.realize();
osgViewer::ViewerBase::Contexts ctxs;
viewer.getContexts( ctxs, true );
if( ctxs.empty() )
{
osg::notify(osg::FATAL)<< __FUNCTION__ << ": no valid OpenGL context is found."<<std::endl;
return false;
}
osg::GraphicsContext* ctx = NULL;
#ifdef WIN32
osgViewer::GraphicsHandleWin32 *windowsContext = NULL;
#else
osgViewer::GraphicsHandleX11 *linuxContext = NULL;
#endif
if( ctxID != -1 )
{ // Find context with ctxID and make it current.
for( unsigned int c=0; c<ctxs.size(); ++c )
{
if( ctxs
{
ctx = ctxs
}
}
}
else
{
ctx = ctxs.front();
}
if( NULL == ctx )
{
osg::notify(osg::FATAL)<< __FUNCTION__ << ": cannot find valid OpenGL context."<<std::endl;
return false;
}
//platform dependent casting
#ifdef WIN32
windowsContext = dynamic_cast<osgViewer::GraphicsHandleWin32*>(ctx);
if(NULL == windowsContext)
{
osg::notify(osg::FATAL) << "Win32 Graphics Context Casting is unsuccessful" << std::endl;
return false;
}
else
osg::notify(osg::INFO) << "Win32 Graphics Context Casting is successful" << std::endl;
#else
linuxContext = dynamic_cast<osgViewer::GraphicsHandleX11*>(ctx);
if(NULL == linuxContext)
{
osg::notify(osg::FATAL) << "X11 Graphics Context Casting is unsuccessful" << std::endl;
return false;
}
else
osg::notify(osg::INFO) << "X11 Graphics Context Casting is successful" << std::endl;
#endif
cl_uint numPlatforms;
cl_platform_id *platformIDs;
cl_int errNum;
//first query the total number of platforms
errNum = clGetPlatformIDs(0,NULL,&numPlatforms);
if(errNum != CL_SUCCESS || numPlatforms <= 0)
{
osg::notify(osg::FATAL) << "Failed to find any OpenCL platform" << std::endl;
return false;
}
//next, allocate memory for the installed platforms, and query
//to get the list
platformIDs = (cl_platform_id *)alloca(sizeof(cl_platform_id) * numPlatforms);
errNum = clGetPlatformIDs(numPlatforms,platformIDs,NULL);
if(errNum != CL_SUCCESS)
{
osg::notify(osg::FATAL) << "Failed to find any OpenCL platform" << std::endl;
return false;
}
//now choose the very first platform
m_clPlatform = platformIDs[0];
char cBuffer[1024];
//get the platform information from the selected platform
errNum = clGetPlatformInfo(m_clPlatform,CL_PLATFORM_NAME,sizeof(cBuffer),cBuffer,NULL);
if(errNum == CL_SUCCESS)
{
osg::notify(osg::INFO) << "OpenCL platform name: " << cBuffer << std::endl;
}
//by now the graphics context is found
//and the platform id is also found
cl_context_properties contextProperties[] =
{
#ifdef WIN32
CL_GL_CONTEXT_KHR, (cl_context_properties) windowsContext->getWGLContext(),
CL_WGL_HDC_KHR, (cl_context_properties) windowsContext->getHDC(),
#else
CL_GL_CONTEXT_KHR, (cl_context_properties) linuxContext->getContext(),
CL_GLX_DISPLAY_KHR, (intptr_t) linuxContext->getDisplay(),
#endif
CL_CONTEXT_PLATFORM, (cl_context_properties) m_clPlatform,
0
};
//create context with the GPU device only
m_clContext = clCreateContextFromType(contextProperties,CL_DEVICE_TYPE_GPU,NULL,NULL,&errNum);
if(errNum != CL_SUCCESS)
{
std::cout << "Could not create GPU context." << std::endl;
osg::notify(osg::FATAL) << "Could not create GPU context." << std::endl;
return false;
}
else
osg::notify(osg::INFO) << "Context Creation for the GPU is Successful" << std::endl;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
The OpenGL context is created inside the main function as follows:
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int main(int argc, char *argv[])
{
osg::setNotifyLevel( osg::INFO );
//////////////////
// SETUP VIEWER //
//////////////////
osgViewer::Viewer viewer;
viewer.addEventHandler(new osgViewer::StatsHandler);
//viewer.addEventHandler(new osgCuda::StatsHandler);
viewer.addEventHandler(new osgViewer::HelpHandler);
viewer.setUpViewInWindow( 50, 50, 640, 480);
viewer.getCamera()->setClearColor( osg::Vec4(0.15, 0.15, 0.15, 1.0) );
//declare an opencl context
osgOpenCL::osgOpenCLContext clContext;
clContext.setupOsgOpenCLAndViewer(viewer);
return viewer.run();
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
I also print the diagnostics as follows:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
sajjad@sajjad-G74Sx:~/Downloads/OpenSceneGraph/osgCompute/osgCompute$ ./bin/osgOpenCLTexDemo
CullSettings::readEnvironmentalVariables()
DatabasePager::addDatabaseThread() HANDLE_NON_HTTP
DatabasePager::addDatabaseThread() HANDLE_ONLY_HTTP
CullSettings::readEnvironmentalVariables()
CullSettings::readEnvironmentalVariables()
CullSettings::readEnvironmentalVariables()
CullSettings::readEnvironmentalVariables()
ShaderComposer::ShaderComposer() 0x9565c18
CullSettings::readEnvironmentalVariables()
ShaderComposer::ShaderComposer() 0x9569400
CullSettings::readEnvironmentalVariables()
CullSettings::readEnvironmentalVariables()
CullSettings::readEnvironmentalVariables()
CullSettings::readEnvironmentalVariables()
CullSettings::readEnvironmentalVariables()
ShaderComposer::ShaderComposer() 0x956cce0
ShaderComposer::ShaderComposer() 0x956de68
CullSettings::readEnvironmentalVariables()
CullSettings::readEnvironmentalVariables()
CullSettings::readEnvironmentalVariables()
CullSettings::readEnvironmentalVariables()
CullSettings::readEnvironmentalVariables()
ShaderComposer::ShaderComposer() 0x9570f18
ShaderComposer::ShaderComposer() 0x95720a0
GraphicsContext::registerGraphicsContext 0x9573cb8
GraphicsContext::getWindowingSystemInterface() 0x95655e0 0xb7746d68
GraphicsContext::getWindowingSystemInterface() 0x95655e0 0xb7746d68
ShaderComposer::ShaderComposer() 0x9621b00
GraphicsContext::createNewContextID() creating contextID=0
Updating the MaxNumberOfGraphicsContexts to 1
View::setUpViewOnSingleScreen - GraphicsWindow has been created successfully.
osg::State::_maxTexturePoolSize=0
osg::State::_maxBufferObjectPoolSize=0
X11 Graphics Context Casting is successful
OpenCL platform name: NVIDIA CUDA
Segmentation fault (core dumped)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
As you can see from the diagnostics that the OpenGL context creation is successful as we get the output "X11 Graphics Context Casting is successful".
I also get the OpenCL platform info. But i do not get any information about the OpenCL context creation information - success or failure. That is really puzzling. Even if it is a failure it should print it.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
m_clContext = clCreateContextFromType(contextProperties,CL_DEVICE_TYPE_GPU,NULL,NULL,&errNum);
if(errNum != CL_SUCCESS)
{
std::cout << "Could not create GPU context." << std::endl;
osg::notify(osg::FATAL) << "Could not create GPU context." << std::endl;
return false;
}
else
osg::notify(osg::INFO) << "Context Creation for the GPU is Successful" << std::endl;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
What am i missing in the process folks ?
Regards
Sajjadul
Solved! Go to Solution.
Request you to post a simpler case. The code is difficult to follow. And not everyone will have the time to look through and understand what you are doing.
Instead, please post a simple barebones code that shows what is not working.
Also, Please look at error code and try to reason out. That might also help.
Good luck!
Request you to post a simpler case. The code is difficult to follow. And not everyone will have the time to look through and understand what you are doing.
Instead, please post a simple barebones code that shows what is not working.
Also, Please look at error code and try to reason out. That might also help.
Good luck!
The issue has been solved.
Sorry for being so unnecessarily complicated.
My next queries will be more crisp and concise.
Thanks
Sajjadul
Oh! Good to know it got solved. Thanks for getting back to us on this.
Good luck!