#define CL_HPP_ENABLE_EXCEPTIONS
#define CL_HPP_MINIMUM_OPENCL_VERSION 120
#define CL_HPP_TARGET_OPENCL_VERSION 120
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
#include <CL/cl2.hpp>
#pragma GCC diagnostic pop
#include <sstream>
#include <algorithm>
using namespace cl;
#if defined (OS_MAC)
#include <OpenGL/OpenGL.h>
static const std::string CL_GL_SHARING_EXT = "cl_APPLE_gl_sharing";
#else
static const std::string CL_GL_SHARING_EXT = "cl_khr_gl_sharing";
#endif
bool checkGLInterop(
const cl::Platform &plat,
const cl::Device &pDevice,
const forge::Window &wnd)
{
bool ret_val = false;
std::string exts = pDevice.getInfo<CL_DEVICE_EXTENSIONS>();
std::stringstream ss(exts);
std::string item;
while (std::getline(ss,item,' ')) {
if (item == CL_GL_SHARING_EXT) {
ret_val = true;
break;
}
}
if (!ret_val) return false;
#if !defined(OS_MAC) // Check on Linux, Windows
#if defined(OS_LNX)
cl_context_properties cps[] = {
CL_GL_CONTEXT_KHR, (cl_context_properties)wnd.
context(),
CL_GLX_DISPLAY_KHR, (cl_context_properties)wnd.
display(),
CL_CONTEXT_PLATFORM, (cl_context_properties)plat(),
0
};
#else
cl_context_properties cps[] = {
CL_GL_CONTEXT_KHR, (cl_context_properties)wnd.
context(),
CL_WGL_HDC_KHR, (cl_context_properties)wnd.
display(),
CL_CONTEXT_PLATFORM, (cl_context_properties)plat(),
0
};
#endif
auto func = (clGetGLContextInfoKHR_fn)
clGetExtensionFunctionAddressForPlatform(plat(), "clGetGLContextInfoKHR");
if (!func) return false;
std::vector<cl_device_id> devices(16);
size_t ret = 0;
cl_int err = func(cps,
CL_DEVICES_FOR_GL_CONTEXT_KHR,
devices.size() * sizeof(cl_device_id),
devices.data(),
&ret);
if (err != CL_SUCCESS) return false;
int num = ret / sizeof(cl_device_id);
devices.resize(num);
cl_device_id current_device = pDevice();
auto res = std::find(std::begin(devices), std::end(devices), current_device);
ret_val = res != std::end(devices);
#endif
return ret_val;
}
{
std::vector<cl::Platform> platforms;
Platform::get(&platforms);
for (auto platform : platforms) {
std::vector<cl::Device> devices;
try {
platform.getDevices(CL_DEVICE_TYPE_GPU, &devices);
} catch(const cl::Error &err) {
if (err.err() != CL_DEVICE_NOT_FOUND) {
throw;
} else {
continue;
}
}
for (auto device : devices) {
if (!checkGLInterop(platform, device, wnd)) continue;
#if defined(OS_MAC)
CGLContextObj cgl_current_ctx = CGLGetCurrentContext();
CGLShareGroupObj cgl_share_group = CGLGetShareGroup(cgl_current_ctx);
cl_context_properties cps[] = {
CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE, (cl_context_properties)cgl_share_group,
0
};
#elif defined(OS_LNX)
cl_context_properties cps[] = {
CL_GL_CONTEXT_KHR, (cl_context_properties)wnd.
context(),
CL_GLX_DISPLAY_KHR, (cl_context_properties)wnd.
display(),
CL_CONTEXT_PLATFORM, (cl_context_properties)platform(),
0
};
#else
cl_context_properties cps[] = {
CL_GL_CONTEXT_KHR, (cl_context_properties)wnd.
context(),
CL_WGL_HDC_KHR, (cl_context_properties)wnd.
display(),
CL_CONTEXT_PLATFORM, (cl_context_properties)platform(),
0
};
#endif
std::cout << "Platform: " << platform.getInfo<CL_PLATFORM_NAME>() << std::endl;
std::cout << "Device: " << device.getInfo<CL_DEVICE_NAME>() << std::endl;
return cl::Context(device, cps);
}
}
throw std::runtime_error("No CL-GL sharing contexts found");
}
cl::CommandQueue queue;
cl::Context context;
cl_context getContext()
{
return context();
}
cl_command_queue getCommandQueue()
{
return queue();
}