• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2013-2014 Kyle Lutz <kyle.r.lutz@gmail.com>
3 //
4 // Distributed under the Boost Software License, Version 1.0
5 // See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt
7 //
8 // See http://boostorg.github.com/compute for more information.
9 //---------------------------------------------------------------------------//
10 
11 #ifndef BOOST_COMPUTE_INTEROP_OPENGL_CONTEXT_HPP
12 #define BOOST_COMPUTE_INTEROP_OPENGL_CONTEXT_HPP
13 
14 #include <boost/throw_exception.hpp>
15 
16 #include <boost/compute/device.hpp>
17 #include <boost/compute/system.hpp>
18 #include <boost/compute/context.hpp>
19 #include <boost/compute/exception/unsupported_extension_error.hpp>
20 #include <boost/compute/interop/opengl/cl_gl.hpp>
21 
22 #ifdef __APPLE__
23 #include <OpenCL/cl_gl_ext.h>
24 #include <OpenGL/OpenGL.h>
25 #endif
26 
27 #ifdef __linux__
28 #include <GL/glx.h>
29 #endif
30 
31 namespace boost {
32 namespace compute {
33 
34 /// Creates a shared OpenCL/OpenGL context for the currently active
35 /// OpenGL context.
36 ///
37 /// Once created, the shared context can be used to create OpenCL memory
38 /// objects which can interact with OpenGL memory objects (e.g. VBOs).
39 ///
40 /// \throws unsupported_extension_error if no CL-GL sharing capable devices
41 ///         are found.
opengl_create_shared_context()42 inline context opengl_create_shared_context()
43 {
44     // name of the OpenGL sharing extension for the system
45 #if defined(__APPLE__)
46     const char *cl_gl_sharing_extension = "cl_APPLE_gl_sharing";
47 #else
48     const char *cl_gl_sharing_extension = "cl_khr_gl_sharing";
49 #endif
50 
51 #if defined(__APPLE__)
52     // get OpenGL share group
53     CGLContextObj cgl_current_context = CGLGetCurrentContext();
54     CGLShareGroupObj cgl_share_group = CGLGetShareGroup(cgl_current_context);
55 
56     cl_context_properties properties[] = {
57         CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE,
58         (cl_context_properties) cgl_share_group,
59         0
60     };
61 
62     cl_int error = 0;
63     cl_context cl_gl_context = clCreateContext(properties, 0, 0, 0, 0, &error);
64     if(!cl_gl_context){
65         BOOST_THROW_EXCEPTION(opencl_error(error));
66     }
67 
68     return context(cl_gl_context, false);
69 #else
70     typedef cl_int(*GetGLContextInfoKHRFunction)(
71         const cl_context_properties*, cl_gl_context_info, size_t, void *, size_t *
72     );
73 
74     std::vector<platform> platforms = system::platforms();
75     for(size_t i = 0; i < platforms.size(); i++){
76         const platform &platform = platforms[i];
77 
78         // check whether this platform supports OpenCL/OpenGL sharing
79         if (!platform.supports_extension(cl_gl_sharing_extension))
80           continue;
81 
82         // load clGetGLContextInfoKHR() extension function
83         GetGLContextInfoKHRFunction GetGLContextInfoKHR =
84             reinterpret_cast<GetGLContextInfoKHRFunction>(
85                 reinterpret_cast<size_t>(
86                     platform.get_extension_function_address("clGetGLContextInfoKHR")
87                 )
88             );
89         if(!GetGLContextInfoKHR){
90             continue;
91         }
92 
93         // create context properties listing the platform and current OpenGL display
94         cl_context_properties properties[] = {
95             CL_CONTEXT_PLATFORM, (cl_context_properties) platform.id(),
96         #if defined(__linux__)
97             CL_GL_CONTEXT_KHR, (cl_context_properties) glXGetCurrentContext(),
98             CL_GLX_DISPLAY_KHR, (cl_context_properties) glXGetCurrentDisplay(),
99         #elif defined(_WIN32)
100             CL_GL_CONTEXT_KHR, (cl_context_properties) wglGetCurrentContext(),
101             CL_WGL_HDC_KHR, (cl_context_properties) wglGetCurrentDC(),
102         #endif
103             0
104         };
105 
106         // lookup current OpenCL device for current OpenGL context
107         cl_device_id gpu_id;
108         cl_int ret = GetGLContextInfoKHR(
109             properties,
110             CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR,
111             sizeof(cl_device_id),
112             &gpu_id,
113             0
114         );
115         if(ret != CL_SUCCESS){
116             continue;
117         }
118 
119         // create device object for the GPU and ensure it supports CL-GL sharing
120         device gpu(gpu_id, false);
121         if(!gpu.supports_extension(cl_gl_sharing_extension)){
122             continue;
123         }
124 
125         // return CL-GL sharing context
126         return context(gpu, properties);
127     }
128 #endif
129 
130     // no CL-GL sharing capable devices found
131     BOOST_THROW_EXCEPTION(
132         unsupported_extension_error(cl_gl_sharing_extension)
133     );
134 }
135 
136 } // end compute namespace
137 } // end boost namespace
138 
139 #endif // BOOST_COMPUTE_INTEROP_OPENGL_CONTEXT_HPP
140