]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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. | |
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 | // load clGetGLContextInfoKHR() extension function | |
79 | GetGLContextInfoKHRFunction GetGLContextInfoKHR = | |
80 | reinterpret_cast<GetGLContextInfoKHRFunction>( | |
81 | reinterpret_cast<size_t>( | |
82 | platform.get_extension_function_address("clGetGLContextInfoKHR") | |
83 | ) | |
84 | ); | |
85 | if(!GetGLContextInfoKHR){ | |
86 | continue; | |
87 | } | |
88 | ||
89 | // create context properties listing the platform and current OpenGL display | |
90 | cl_context_properties properties[] = { | |
91 | CL_CONTEXT_PLATFORM, (cl_context_properties) platform.id(), | |
92 | #if defined(__linux__) | |
93 | CL_GL_CONTEXT_KHR, (cl_context_properties) glXGetCurrentContext(), | |
94 | CL_GLX_DISPLAY_KHR, (cl_context_properties) glXGetCurrentDisplay(), | |
95 | #elif defined(WIN32) | |
96 | CL_GL_CONTEXT_KHR, (cl_context_properties) wglGetCurrentContext(), | |
97 | CL_WGL_HDC_KHR, (cl_context_properties) wglGetCurrentDC(), | |
98 | #endif | |
99 | 0 | |
100 | }; | |
101 | ||
102 | // lookup current OpenCL device for current OpenGL context | |
103 | cl_device_id gpu_id; | |
104 | cl_int ret = GetGLContextInfoKHR( | |
105 | properties, | |
106 | CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR, | |
107 | sizeof(cl_device_id), | |
108 | &gpu_id, | |
109 | 0 | |
110 | ); | |
111 | if(ret != CL_SUCCESS){ | |
112 | continue; | |
113 | } | |
114 | ||
115 | // create device object for the GPU and ensure it supports CL-GL sharing | |
116 | device gpu(gpu_id, false); | |
117 | if(!gpu.supports_extension(cl_gl_sharing_extension)){ | |
118 | continue; | |
119 | } | |
120 | ||
121 | // return CL-GL sharing context | |
122 | return context(gpu, properties); | |
123 | } | |
124 | #endif | |
125 | ||
126 | // no CL-GL sharing capable devices found | |
127 | BOOST_THROW_EXCEPTION( | |
128 | unsupported_extension_error(cl_gl_sharing_extension) | |
129 | ); | |
130 | } | |
131 | ||
132 | } // end compute namespace | |
133 | } // end boost namespace | |
134 | ||
135 | #endif // BOOST_COMPUTE_INTEROP_OPENGL_CONTEXT_HPP |