Skip to content

Commit dceeb47

Browse files
author
kallaballa
committed
rewrote clgl device discovery
1 parent 28efc21 commit dceeb47

File tree

1 file changed

+96
-57
lines changed

1 file changed

+96
-57
lines changed

modules/core/src/opengl.cpp

Lines changed: 96 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@
4242

4343
#include "precomp.hpp"
4444

45+
#if defined (__APPLE__) || defined(MACOSX)
46+
#define GL_SHARING_EXTENSION "cl_APPLE_gl_sharing"
47+
#else
48+
#define GL_SHARING_EXTENSION "cl_khr_gl_sharing"
49+
#endif
50+
4551
#ifdef HAVE_OPENGL
4652
# include "gl_core_3_1.hpp"
4753
# ifdef HAVE_CUDA
@@ -1636,6 +1642,11 @@ Context& initializeContextFromGL()
16361642
NO_OPENCL_SHARING_ERROR;
16371643
#else
16381644
cl_uint numPlatforms;
1645+
cl_device_id* devices = new cl_device_id[256];
1646+
cl_uint devCnt;
1647+
cl_uint devUsed;
1648+
cl_context context;
1649+
16391650
cl_int status = clGetPlatformIDs(0, NULL, &numPlatforms);
16401651
if (status != CL_SUCCESS)
16411652
CV_Error_(cv::Error::OpenCLInitError, ("OpenCL: Can't get number of platforms: %d", status));
@@ -1645,84 +1656,112 @@ Context& initializeContextFromGL()
16451656
std::vector<cl_platform_id> platforms(numPlatforms);
16461657
status = clGetPlatformIDs(numPlatforms, &platforms[0], NULL);
16471658
if (status != CL_SUCCESS)
1648-
CV_Error_(cv::Error::OpenCLInitError, ("OpenCL: Can't get number of platforms: %d", status));
1659+
CV_Error_(cv::Error::OpenCLInitError, ("OpenCL: Can't get platforms: %d", status));
1660+
16491661

16501662
// TODO Filter platforms by name from OPENCV_OPENCL_DEVICE
1663+
bool sharingSupported = false;
16511664

1652-
int found = -1;
1653-
cl_device_id device = NULL;
1654-
cl_context context = NULL;
1665+
for (unsigned int i = 0; (!sharingSupported && (i < numPlatforms)); ++i) {
1666+
status = clGetDeviceIDs(platforms[i], CL_DEVICE_TYPE_GPU, 0, NULL, &devCnt);
1667+
if (status != CL_SUCCESS)
1668+
CV_Error_(cv::Error::OpenCLInitError, ("OpenCL: No devices available: %d", status));
16551669

1656-
for (int i = 0; i < (int)numPlatforms; i++)
1657-
{
1658-
// query platform extension: presence of "cl_khr_gl_sharing" extension is required
1659-
{
1660-
AutoBuffer<char> extensionStr;
1670+
status = clGetDeviceIDs(platforms[i], CL_DEVICE_TYPE_GPU, devCnt, devices, NULL);
1671+
if (status != CL_SUCCESS)
1672+
CV_Error_(cv::Error::OpenCLInitError, ("OpenCL: Can't get platform devices: %d", status));
16611673

1674+
for (unsigned int j = 0; (!sharingSupported && (j < devCnt)); ++j) {
16621675
size_t extensionSize;
1663-
status = clGetPlatformInfo(platforms[i], CL_PLATFORM_EXTENSIONS, 0, NULL, &extensionSize);
1664-
if (status == CL_SUCCESS)
1665-
{
1666-
extensionStr.allocate(extensionSize+1);
1667-
status = clGetPlatformInfo(platforms[i], CL_PLATFORM_EXTENSIONS, extensionSize, (char*)extensionStr.data(), NULL);
1668-
}
1676+
status = clGetDeviceInfo(devices[j], CL_DEVICE_EXTENSIONS, 0, NULL, &extensionSize );
16691677
if (status != CL_SUCCESS)
1670-
CV_Error_(cv::Error::OpenCLInitError, ("OpenCL: Can't get platform extension string: %d", status));
1678+
CV_Error_(cv::Error::OpenCLInitError, ("OpenCL: No devices available: %d", status));
16711679

1672-
if (!strstr((const char*)extensionStr.data(), "cl_khr_gl_sharing"))
1673-
continue;
1680+
if(extensionSize > 0)
1681+
{
1682+
char* extensions = (char*)malloc(extensionSize);
1683+
status = clGetDeviceInfo(devices[j], CL_DEVICE_EXTENSIONS, extensionSize, extensions, &extensionSize);
1684+
if (status != CL_SUCCESS)
1685+
continue;
1686+
1687+
std::string stdDevString(extensions);
1688+
free(extensions);
1689+
1690+
1691+
size_t szOldPos = 0;
1692+
size_t szSpacePos = stdDevString.find(' ', szOldPos); // extensions string is space delimited
1693+
while (szSpacePos != stdDevString.npos) {
1694+
if (strcmp(GL_SHARING_EXTENSION,
1695+
stdDevString.substr(szOldPos, szSpacePos - szOldPos).c_str())
1696+
== 0) {
1697+
// Device supports context sharing with OpenGL
1698+
devUsed = i;
1699+
sharingSupported = true;
1700+
break;
1701+
}
1702+
do {
1703+
szOldPos = szSpacePos + 1;
1704+
szSpacePos = stdDevString.find(' ', szOldPos);
1705+
} while (szSpacePos == szOldPos);
1706+
}
1707+
}
16741708
}
16751709

1676-
clGetGLContextInfoKHR_fn clGetGLContextInfoKHR = (clGetGLContextInfoKHR_fn)
1677-
clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetGLContextInfoKHR");
1678-
if (!clGetGLContextInfoKHR)
1679-
continue;
1710+
if (!sharingSupported)
1711+
CV_Error_(cv::Error::OpenCLInitError, ("OpenCL: OpenGL sharing not supported: %d", status));
16801712

1681-
cl_context_properties properties[] =
1682-
{
1683-
#if defined(_WIN32)
1684-
CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
1685-
CL_GL_CONTEXT_KHR, (cl_context_properties)wglGetCurrentContext(),
1686-
CL_WGL_HDC_KHR, (cl_context_properties)wglGetCurrentDC(),
1687-
#elif defined(__ANDROID__)
1688-
CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
1689-
CL_GL_CONTEXT_KHR, (cl_context_properties)eglGetCurrentContext(),
1690-
CL_EGL_DISPLAY_KHR, (cl_context_properties)eglGetCurrentDisplay(),
1691-
#elif defined(__linux__)
1692-
CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
1693-
CL_GL_CONTEXT_KHR, (cl_context_properties)glXGetCurrentContext(),
1694-
CL_GLX_DISPLAY_KHR, (cl_context_properties)glXGetCurrentDisplay(),
1695-
#endif
1696-
0
1697-
};
16981713

1699-
// query device
1700-
device = NULL;
1701-
status = clGetGLContextInfoKHR(properties, CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR, sizeof(cl_device_id), (void*)&device, NULL);
1702-
if (status != CL_SUCCESS)
1703-
continue;
1714+
// Define OS-specific context properties and create the OpenCL context
1715+
#if defined (__APPLE__)
1716+
CGLContextObj kCGLContext = CGLGetCurrentContext();
1717+
CGLShareGroupObj kCGLShareGroup = CGLGetShareGroup(kCGLContext);
1718+
cl_context_properties props[] =
1719+
{
1720+
CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE, (cl_context_properties)kCGLShareGroup,
1721+
0
1722+
};
1723+
context = clCreateContext(props, 0,0, NULL, NULL, &ciErrNum);
1724+
#elif defined(__ANDROID__)
1725+
cl_context_properties props[] =
1726+
{
1727+
CL_GL_CONTEXT_KHR, (cl_context_properties)glXGetCurrentContext(),
1728+
CL_GLX_DISPLAY_KHR, (cl_context_properties)glXGetCurrentDisplay(),
1729+
CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
1730+
0
1731+
};
1732+
context = clCreateContext(props, 1, &devices[devUsed], NULL, NULL, &status);
1733+
#elif defined(_WIN32)
1734+
cl_context_properties props[] =
1735+
{
1736+
CL_GL_CONTEXT_KHR, (cl_context_properties)wglGetCurrentContext(),
1737+
CL_WGL_HDC_KHR, (cl_context_properties)wglGetCurrentDC(),
1738+
CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
1739+
0
1740+
};
1741+
context = clCreateContext(props, 1, &devices[devUsed], NULL, NULL, &status);
1742+
#elif defined(__linux__)
1743+
cl_context_properties props[] =
1744+
{
1745+
CL_GL_CONTEXT_KHR, (cl_context_properties)glXGetCurrentContext(),
1746+
CL_GLX_DISPLAY_KHR, (cl_context_properties)glXGetCurrentDisplay(),
1747+
CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
1748+
0
1749+
};
1750+
context = clCreateContext(props, 1, &devices[devUsed], NULL, NULL, &status);
1751+
#endif
17041752

1705-
// create context
1706-
context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
17071753
if (status != CL_SUCCESS)
1708-
{
1709-
clReleaseDevice(device);
1710-
}
1754+
CV_Error_(cv::Error::OpenCLInitError, ("OpenCL: Can't create context for OpenGL interop: %d", status));
17111755
else
1712-
{
1713-
found = i;
17141756
break;
1715-
}
17161757
}
17171758

1718-
if (found < 0)
1719-
CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't create context for OpenGL interop");
17201759

1721-
cl_platform_id platform = platforms[found];
1760+
cl_platform_id platform = platforms[devUsed];
17221761
std::string platformName = PlatformInfo(&platform).name();
17231762

1724-
OpenCLExecutionContext clExecCtx = OpenCLExecutionContext::create(platformName, platform, context, device);
1725-
clReleaseDevice(device);
1763+
OpenCLExecutionContext clExecCtx = OpenCLExecutionContext::create(platformName, platform, context, devices[devUsed]);
1764+
clReleaseDevice(devices[devUsed]);
17261765
clReleaseContext(context);
17271766
clExecCtx.bind();
17281767
return const_cast<Context&>(clExecCtx.getContext());

0 commit comments

Comments
 (0)