diff --git a/doc/make_constants.py b/doc/make_constants.py index 2160c3c607cf5d3ece954339442927b13e97ba5e..91ce242a15689f8ca94d981b422d3b9b6983a105 100644 --- a/doc/make_constants.py +++ b/doc/make_constants.py @@ -1,6 +1,7 @@ import pyopencl as cl ctxp = cl.context_properties +gl_ci = cl.gl_context_info ext_lookup = { ctxp: { ctxp.GL_CONTEXT_KHR: "cl_khr_gl_sharing", @@ -8,6 +9,13 @@ ext_lookup = { ctxp.GLX_DISPLAY_KHR: "cl_khr_gl_sharing", ctxp.WGL_HDC_KHR: "cl_khr_gl_sharing", ctxp.CGL_SHAREGROUP_KHR: "cl_khr_gl_sharing", + }, + gl_ci: { + gl_ci.CURRENT_DEVICE_FOR_GL_CONTEXT_KHR: + "cl_khr_gl_sharing", + + gl_ci.DEVICES_FOR_GL_CONTEXT_KHR: + "cl_khr_gl_sharing", } } diff --git a/doc/source/reference.rst b/doc/source/reference.rst index 108a35431fdbb401fb732c3531dbcafa1b3d1682..4c571896dfd7f0b98e9a39430d93e5e257e6cec2 100644 --- a/doc/source/reference.rst +++ b/doc/source/reference.rst @@ -580,3 +580,11 @@ with GL support. See :func:`have_gl`. .. function:: enqueue_release_gl_objects(queue, mem_objects, wait_for=None) *mem_objects* is a list of :class:`MemoryObject` instances. |std-enqueue-blurb| + +.. function:: get_gl_context_info_khr(properties, param_name) + + Get information on which CL device corresponds to a given + GL/EGL/WGL/CGL device. + + See the :class:`Context` constructor for the meaning of + *properties* and :class:`gl_context_info` for *param_name*. diff --git a/src/wrapper/wrap_cl.cpp b/src/wrapper/wrap_cl.cpp index 250de49b7d0c2cd80c22aeea626f504f23287ae6..161bc16b553a98511607a1a35d74fc2c968c5bfe 100644 --- a/src/wrapper/wrap_cl.cpp +++ b/src/wrapper/wrap_cl.cpp @@ -44,6 +44,7 @@ namespace class device_exec_capabilities { }; class command_queue_properties { }; class context_info { }; + class gl_context_info { }; class context_properties { }; class command_queue_info { }; class mem_flags { }; @@ -214,6 +215,14 @@ BOOST_PYTHON_MODULE(_cl) ADD_ATTR(CONTEXT_, PROPERTIES); } + { + py::class_ cls("gl_context_info", py::no_init); +#if defined(cl_khr_gl_sharing) && (cl_khr_gl_sharing >= 1) + ADD_ATTR(, CURRENT_DEVICE_FOR_GL_CONTEXT_KHR); + ADD_ATTR(, DEVICES_FOR_GL_CONTEXT_KHR); +#endif + } + { py::class_ cls("context_properties", py::no_init); ADD_ATTR(CONTEXT_, PLATFORM); @@ -788,6 +797,9 @@ BOOST_PYTHON_MODULE(_cl) ), py::return_value_policy()); + py::def("get_gl_context_info_khr", get_gl_context_info_khr, + py::args("properties", "param_name")); + #endif // }}} } diff --git a/src/wrapper/wrap_cl.hpp b/src/wrapper/wrap_cl.hpp index d1111747fde3bb906d106d6f2d7bb79b45f769d4..c9fb1eba9a11d5f6c546194305a0e6378b990e01 100644 --- a/src/wrapper/wrap_cl.hpp +++ b/src/wrapper/wrap_cl.hpp @@ -666,7 +666,6 @@ namespace pyopencl context *create_context(py::object py_devices, py::object py_properties, py::object py_dev_type) { - // parse context properties std::vector props = parse_context_properties(py_properties); @@ -2539,8 +2538,75 @@ namespace pyopencl WRAP_GL_ENQUEUE(release, Release); #endif + + + #if defined(cl_khr_gl_sharing) && (cl_khr_gl_sharing >= 1) - + py::object get_gl_context_info_khr( + py::object py_properties, + cl_gl_context_info param_name + ) + { + std::vector props + = parse_context_properties(py_properties); + + + typedef CL_API_ENTRY cl_int CL_API_CALL + (*func_ptr_type)(const cl_context_properties * /* properties */, + cl_gl_context_info /* param_name */, + size_t /* param_value_size */, + void * /* param_value */, + size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; + + func_ptr_type func_ptr + = (func_ptr_type) clGetExtensionFunctionAddress( + "clGetGLContextInfoKHR"); + + if (!func_ptr) + throw error("Context.get_info", CL_INVALID_PLATFORM, + "clGetGLContextInfoKHR extension function not present"); + + cl_context_properties *props_ptr + = props.empty( ) ? NULL : &props.front(); + + switch (param_name) + { + case CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR: + { + cl_device_id param_value; + PYOPENCL_CALL_GUARDED(func_ptr, + (props_ptr, param_name, sizeof(param_value), ¶m_value, 0)); + return py::object(handle_from_new_ptr( \ + new device(param_value, /*retain*/ true))); + } + + case CL_DEVICES_FOR_GL_CONTEXT_KHR: + { + size_t size; + PYOPENCL_CALL_GUARDED(func_ptr, + (props_ptr, param_name, 0, 0, &size)); + + std::vector devices; + + devices.resize(size / sizeof(devices.front())); + + PYOPENCL_CALL_GUARDED(func_ptr, + (props_ptr, param_name, size, + devices.empty( ) ? NULL : &devices.front(), &size)); + + py::list result; + BOOST_FOREACH(cl_device_id did, devices) + result.append(handle_from_new_ptr( + new device(did))); + + return result; + } + + default: + throw error("get_gl_context_info_khr", CL_INVALID_VALUE); + } + } + #endif // }}}