context.hpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  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. #ifndef BOOST_COMPUTE_INTEROP_OPENGL_CONTEXT_HPP
  11. #define BOOST_COMPUTE_INTEROP_OPENGL_CONTEXT_HPP
  12. #include <boost/throw_exception.hpp>
  13. #include <boost/compute/device.hpp>
  14. #include <boost/compute/system.hpp>
  15. #include <boost/compute/context.hpp>
  16. #include <boost/compute/exception/unsupported_extension_error.hpp>
  17. #include <boost/compute/interop/opengl/cl_gl.hpp>
  18. #ifdef __APPLE__
  19. #include <OpenCL/cl_gl_ext.h>
  20. #include <OpenGL/OpenGL.h>
  21. #endif
  22. #ifdef __linux__
  23. #include <GL/glx.h>
  24. #endif
  25. namespace boost {
  26. namespace compute {
  27. /// Creates a shared OpenCL/OpenGL context for the currently active
  28. /// OpenGL context.
  29. ///
  30. /// Once created, the shared context can be used to create OpenCL memory
  31. /// objects which can interact with OpenGL memory objects (e.g. VBOs).
  32. ///
  33. /// \throws unsupported_extension_error if no CL-GL sharing capable devices
  34. /// are found.
  35. inline context opengl_create_shared_context()
  36. {
  37. // name of the OpenGL sharing extension for the system
  38. #if defined(__APPLE__)
  39. const char *cl_gl_sharing_extension = "cl_APPLE_gl_sharing";
  40. #else
  41. const char *cl_gl_sharing_extension = "cl_khr_gl_sharing";
  42. #endif
  43. #if defined(__APPLE__)
  44. // get OpenGL share group
  45. CGLContextObj cgl_current_context = CGLGetCurrentContext();
  46. CGLShareGroupObj cgl_share_group = CGLGetShareGroup(cgl_current_context);
  47. cl_context_properties properties[] = {
  48. CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE,
  49. (cl_context_properties) cgl_share_group,
  50. 0
  51. };
  52. cl_int error = 0;
  53. cl_context cl_gl_context = clCreateContext(properties, 0, 0, 0, 0, &error);
  54. if(!cl_gl_context){
  55. BOOST_THROW_EXCEPTION(opencl_error(error));
  56. }
  57. return context(cl_gl_context, false);
  58. #else
  59. typedef cl_int(*GetGLContextInfoKHRFunction)(
  60. const cl_context_properties*, cl_gl_context_info, size_t, void *, size_t *
  61. );
  62. std::vector<platform> platforms = system::platforms();
  63. for(size_t i = 0; i < platforms.size(); i++){
  64. const platform &platform = platforms[i];
  65. // check whether this platform supports OpenCL/OpenGL sharing
  66. if (!platform.supports_extension(cl_gl_sharing_extension))
  67. continue;
  68. // load clGetGLContextInfoKHR() extension function
  69. GetGLContextInfoKHRFunction GetGLContextInfoKHR =
  70. reinterpret_cast<GetGLContextInfoKHRFunction>(
  71. reinterpret_cast<size_t>(
  72. platform.get_extension_function_address("clGetGLContextInfoKHR")
  73. )
  74. );
  75. if(!GetGLContextInfoKHR){
  76. continue;
  77. }
  78. // create context properties listing the platform and current OpenGL display
  79. cl_context_properties properties[] = {
  80. CL_CONTEXT_PLATFORM, (cl_context_properties) platform.id(),
  81. #if defined(__linux__)
  82. CL_GL_CONTEXT_KHR, (cl_context_properties) glXGetCurrentContext(),
  83. CL_GLX_DISPLAY_KHR, (cl_context_properties) glXGetCurrentDisplay(),
  84. #elif defined(_WIN32)
  85. CL_GL_CONTEXT_KHR, (cl_context_properties) wglGetCurrentContext(),
  86. CL_WGL_HDC_KHR, (cl_context_properties) wglGetCurrentDC(),
  87. #endif
  88. 0
  89. };
  90. // lookup current OpenCL device for current OpenGL context
  91. cl_device_id gpu_id;
  92. cl_int ret = GetGLContextInfoKHR(
  93. properties,
  94. CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR,
  95. sizeof(cl_device_id),
  96. &gpu_id,
  97. 0
  98. );
  99. if(ret != CL_SUCCESS){
  100. continue;
  101. }
  102. // create device object for the GPU and ensure it supports CL-GL sharing
  103. device gpu(gpu_id, false);
  104. if(!gpu.supports_extension(cl_gl_sharing_extension)){
  105. continue;
  106. }
  107. // return CL-GL sharing context
  108. return context(gpu, properties);
  109. }
  110. #endif
  111. // no CL-GL sharing capable devices found
  112. BOOST_THROW_EXCEPTION(
  113. unsupported_extension_error(cl_gl_sharing_extension)
  114. );
  115. }
  116. } // end compute namespace
  117. } // end boost namespace
  118. #endif // BOOST_COMPUTE_INTEROP_OPENGL_CONTEXT_HPP