|
|
@ -42,6 +42,12 @@ |
|
|
|
|
|
|
|
|
|
|
|
#include "precomp.hpp" |
|
|
|
#include "precomp.hpp" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if defined (__APPLE__) || defined(MACOSX) |
|
|
|
|
|
|
|
#define GL_SHARING_EXTENSION "cl_APPLE_gl_sharing" |
|
|
|
|
|
|
|
#else |
|
|
|
|
|
|
|
#define GL_SHARING_EXTENSION "cl_khr_gl_sharing" |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
#ifdef HAVE_OPENGL |
|
|
|
#ifdef HAVE_OPENGL |
|
|
|
# include "gl_core_3_1.hpp" |
|
|
|
# include "gl_core_3_1.hpp" |
|
|
|
# ifdef HAVE_CUDA |
|
|
|
# ifdef HAVE_CUDA |
|
|
@ -1636,6 +1642,11 @@ Context& initializeContextFromGL() |
|
|
|
NO_OPENCL_SHARING_ERROR; |
|
|
|
NO_OPENCL_SHARING_ERROR; |
|
|
|
#else |
|
|
|
#else |
|
|
|
cl_uint numPlatforms; |
|
|
|
cl_uint numPlatforms; |
|
|
|
|
|
|
|
cl_device_id* devices = new cl_device_id[256]; |
|
|
|
|
|
|
|
cl_uint devCnt; |
|
|
|
|
|
|
|
cl_uint devUsed; |
|
|
|
|
|
|
|
cl_context context; |
|
|
|
|
|
|
|
|
|
|
|
cl_int status = clGetPlatformIDs(0, NULL, &numPlatforms); |
|
|
|
cl_int status = clGetPlatformIDs(0, NULL, &numPlatforms); |
|
|
|
if (status != CL_SUCCESS) |
|
|
|
if (status != CL_SUCCESS) |
|
|
|
CV_Error_(cv::Error::OpenCLInitError, ("OpenCL: Can't get number of platforms: %d", status)); |
|
|
|
CV_Error_(cv::Error::OpenCLInitError, ("OpenCL: Can't get number of platforms: %d", status)); |
|
|
@ -1645,84 +1656,112 @@ Context& initializeContextFromGL() |
|
|
|
std::vector<cl_platform_id> platforms(numPlatforms); |
|
|
|
std::vector<cl_platform_id> platforms(numPlatforms); |
|
|
|
status = clGetPlatformIDs(numPlatforms, &platforms[0], NULL); |
|
|
|
status = clGetPlatformIDs(numPlatforms, &platforms[0], NULL); |
|
|
|
if (status != CL_SUCCESS) |
|
|
|
if (status != CL_SUCCESS) |
|
|
|
CV_Error_(cv::Error::OpenCLInitError, ("OpenCL: Can't get number of platforms: %d", status)); |
|
|
|
CV_Error_(cv::Error::OpenCLInitError, ("OpenCL: Can't get platforms: %d", status)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TODO Filter platforms by name from OPENCV_OPENCL_DEVICE
|
|
|
|
// TODO Filter platforms by name from OPENCV_OPENCL_DEVICE
|
|
|
|
|
|
|
|
bool sharingSupported = false; |
|
|
|
|
|
|
|
|
|
|
|
int found = -1; |
|
|
|
for (unsigned int i = 0; (!sharingSupported && (i < numPlatforms)); ++i) { |
|
|
|
cl_device_id device = NULL; |
|
|
|
status = clGetDeviceIDs(platforms[i], CL_DEVICE_TYPE_GPU, 0, NULL, &devCnt); |
|
|
|
cl_context context = NULL; |
|
|
|
if (status != CL_SUCCESS) |
|
|
|
|
|
|
|
CV_Error_(cv::Error::OpenCLInitError, ("OpenCL: No devices available: %d", status)); |
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < (int)numPlatforms; i++) |
|
|
|
status = clGetDeviceIDs(platforms[i], CL_DEVICE_TYPE_GPU, devCnt, devices, NULL); |
|
|
|
{ |
|
|
|
if (status != CL_SUCCESS) |
|
|
|
// query platform extension: presence of "cl_khr_gl_sharing" extension is required
|
|
|
|
CV_Error_(cv::Error::OpenCLInitError, ("OpenCL: Can't get platform devices: %d", status)); |
|
|
|
{ |
|
|
|
|
|
|
|
AutoBuffer<char> extensionStr; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (unsigned int j = 0; (!sharingSupported && (j < devCnt)); ++j) { |
|
|
|
size_t extensionSize; |
|
|
|
size_t extensionSize; |
|
|
|
status = clGetPlatformInfo(platforms[i], CL_PLATFORM_EXTENSIONS, 0, NULL, &extensionSize); |
|
|
|
status = clGetDeviceInfo(devices[j], CL_DEVICE_EXTENSIONS, 0, NULL, &extensionSize ); |
|
|
|
if (status == CL_SUCCESS) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
extensionStr.allocate(extensionSize+1); |
|
|
|
|
|
|
|
status = clGetPlatformInfo(platforms[i], CL_PLATFORM_EXTENSIONS, extensionSize, (char*)extensionStr.data(), NULL); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (status != CL_SUCCESS) |
|
|
|
if (status != CL_SUCCESS) |
|
|
|
CV_Error_(cv::Error::OpenCLInitError, ("OpenCL: Can't get platform extension string: %d", status)); |
|
|
|
CV_Error_(cv::Error::OpenCLInitError, ("OpenCL: No devices available: %d", status)); |
|
|
|
|
|
|
|
|
|
|
|
if (!strstr((const char*)extensionStr.data(), "cl_khr_gl_sharing")) |
|
|
|
if(extensionSize > 0) |
|
|
|
continue; |
|
|
|
{ |
|
|
|
|
|
|
|
char* extensions = (char*)malloc(extensionSize); |
|
|
|
|
|
|
|
status = clGetDeviceInfo(devices[j], CL_DEVICE_EXTENSIONS, extensionSize, extensions, &extensionSize); |
|
|
|
|
|
|
|
if (status != CL_SUCCESS) |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::string stdDevString(extensions); |
|
|
|
|
|
|
|
free(extensions); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
size_t szOldPos = 0; |
|
|
|
|
|
|
|
size_t szSpacePos = stdDevString.find(' ', szOldPos); // extensions string is space delimited
|
|
|
|
|
|
|
|
while (szSpacePos != stdDevString.npos) { |
|
|
|
|
|
|
|
if (strcmp(GL_SHARING_EXTENSION, |
|
|
|
|
|
|
|
stdDevString.substr(szOldPos, szSpacePos - szOldPos).c_str()) |
|
|
|
|
|
|
|
== 0) { |
|
|
|
|
|
|
|
// Device supports context sharing with OpenGL
|
|
|
|
|
|
|
|
devUsed = i; |
|
|
|
|
|
|
|
sharingSupported = true; |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
do { |
|
|
|
|
|
|
|
szOldPos = szSpacePos + 1; |
|
|
|
|
|
|
|
szSpacePos = stdDevString.find(' ', szOldPos); |
|
|
|
|
|
|
|
} while (szSpacePos == szOldPos); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
clGetGLContextInfoKHR_fn clGetGLContextInfoKHR = (clGetGLContextInfoKHR_fn) |
|
|
|
if (!sharingSupported) |
|
|
|
clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetGLContextInfoKHR"); |
|
|
|
CV_Error_(cv::Error::OpenCLInitError, ("OpenCL: OpenGL sharing not supported: %d", status)); |
|
|
|
if (!clGetGLContextInfoKHR) |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cl_context_properties properties[] = |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
#if defined(_WIN32) |
|
|
|
|
|
|
|
CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i], |
|
|
|
|
|
|
|
CL_GL_CONTEXT_KHR, (cl_context_properties)wglGetCurrentContext(), |
|
|
|
|
|
|
|
CL_WGL_HDC_KHR, (cl_context_properties)wglGetCurrentDC(), |
|
|
|
|
|
|
|
#elif defined(__ANDROID__) |
|
|
|
|
|
|
|
CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i], |
|
|
|
|
|
|
|
CL_GL_CONTEXT_KHR, (cl_context_properties)eglGetCurrentContext(), |
|
|
|
|
|
|
|
CL_EGL_DISPLAY_KHR, (cl_context_properties)eglGetCurrentDisplay(), |
|
|
|
|
|
|
|
#elif defined(__linux__) |
|
|
|
|
|
|
|
CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i], |
|
|
|
|
|
|
|
CL_GL_CONTEXT_KHR, (cl_context_properties)glXGetCurrentContext(), |
|
|
|
|
|
|
|
CL_GLX_DISPLAY_KHR, (cl_context_properties)glXGetCurrentDisplay(), |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
0 |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// query device
|
|
|
|
// Define OS-specific context properties and create the OpenCL context
|
|
|
|
device = NULL; |
|
|
|
#if defined (__APPLE__) |
|
|
|
status = clGetGLContextInfoKHR(properties, CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR, sizeof(cl_device_id), (void*)&device, NULL); |
|
|
|
CGLContextObj kCGLContext = CGLGetCurrentContext(); |
|
|
|
if (status != CL_SUCCESS) |
|
|
|
CGLShareGroupObj kCGLShareGroup = CGLGetShareGroup(kCGLContext); |
|
|
|
continue; |
|
|
|
cl_context_properties props[] = |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE, (cl_context_properties)kCGLShareGroup, |
|
|
|
|
|
|
|
0 |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
context = clCreateContext(props, 0,0, NULL, NULL, &ciErrNum); |
|
|
|
|
|
|
|
#elif defined(__ANDROID__) |
|
|
|
|
|
|
|
cl_context_properties props[] = |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
CL_GL_CONTEXT_KHR, (cl_context_properties)glXGetCurrentContext(), |
|
|
|
|
|
|
|
CL_GLX_DISPLAY_KHR, (cl_context_properties)glXGetCurrentDisplay(), |
|
|
|
|
|
|
|
CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i], |
|
|
|
|
|
|
|
0 |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
context = clCreateContext(props, 1, &devices[devUsed], NULL, NULL, &status); |
|
|
|
|
|
|
|
#elif defined(_WIN32) |
|
|
|
|
|
|
|
cl_context_properties props[] = |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
CL_GL_CONTEXT_KHR, (cl_context_properties)wglGetCurrentContext(), |
|
|
|
|
|
|
|
CL_WGL_HDC_KHR, (cl_context_properties)wglGetCurrentDC(), |
|
|
|
|
|
|
|
CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i], |
|
|
|
|
|
|
|
0 |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
context = clCreateContext(props, 1, &devices[devUsed], NULL, NULL, &status); |
|
|
|
|
|
|
|
#elif defined(__linux__) |
|
|
|
|
|
|
|
cl_context_properties props[] = |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
CL_GL_CONTEXT_KHR, (cl_context_properties)glXGetCurrentContext(), |
|
|
|
|
|
|
|
CL_GLX_DISPLAY_KHR, (cl_context_properties)glXGetCurrentDisplay(), |
|
|
|
|
|
|
|
CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i], |
|
|
|
|
|
|
|
0 |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
context = clCreateContext(props, 1, &devices[devUsed], NULL, NULL, &status); |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
// create context
|
|
|
|
|
|
|
|
context = clCreateContext(properties, 1, &device, NULL, NULL, &status); |
|
|
|
|
|
|
|
if (status != CL_SUCCESS) |
|
|
|
if (status != CL_SUCCESS) |
|
|
|
{ |
|
|
|
CV_Error_(cv::Error::OpenCLInitError, ("OpenCL: Can't create context for OpenGL interop: %d", status)); |
|
|
|
clReleaseDevice(device); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
else |
|
|
|
{ |
|
|
|
|
|
|
|
found = i; |
|
|
|
|
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (found < 0) |
|
|
|
|
|
|
|
CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't create context for OpenGL interop"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cl_platform_id platform = platforms[found]; |
|
|
|
cl_platform_id platform = platforms[devUsed]; |
|
|
|
std::string platformName = PlatformInfo(&platform).name(); |
|
|
|
std::string platformName = PlatformInfo(&platform).name(); |
|
|
|
|
|
|
|
|
|
|
|
OpenCLExecutionContext clExecCtx = OpenCLExecutionContext::create(platformName, platform, context, device); |
|
|
|
OpenCLExecutionContext clExecCtx = OpenCLExecutionContext::create(platformName, platform, context, devices[devUsed]); |
|
|
|
clReleaseDevice(device); |
|
|
|
clReleaseDevice(devices[devUsed]); |
|
|
|
clReleaseContext(context); |
|
|
|
clReleaseContext(context); |
|
|
|
clExecCtx.bind(); |
|
|
|
clExecCtx.bind(); |
|
|
|
return const_cast<Context&>(clExecCtx.getContext()); |
|
|
|
return const_cast<Context&>(clExecCtx.getContext()); |
|
|
|