AnsweredAssumed Answered

OpenCL context creation

Question asked by sajis997 on May 9, 2013
Latest reply on May 10, 2013 by himanshu.gautam

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[c]->getState()->getContextID() == ctxID )

              {  

                 ctx = ctxs[c];

              }

           }

      }

      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

Outcomes