3 Replies Latest reply on May 10, 2013 5:34 AM by himanshu.gautam

    OpenCL context creation

    sajis997

      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