From 5031d0686ae30d8e014d4683f36b762c4a67d95e Mon Sep 17 00:00:00 2001 From: "David G. Yu" Date: Sun, 23 Feb 2014 21:21:25 -0800 Subject: [PATCH] Fixed OpenCL initialization to be slightly more robust. On platforms with multiple devices (e.g. OS X Mavericks with both Intel and Discrete GPU CL devices) we must create the context and command queue with the correct device in order to share resources with GL. --- examples/common/clInit.h | 40 ++++++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/examples/common/clInit.h b/examples/common/clInit.h index 38d353c4..20ef7367 100644 --- a/examples/common/clInit.h +++ b/examples/common/clInit.h @@ -53,8 +53,7 @@ static bool initCL(cl_context *clContext, cl_command_queue *clQueue) printf("No OpenCL platform found.\n"); return false; } - cl_platform_id *clPlatformIDs; - clPlatformIDs = new cl_platform_id[num_platforms]; + cl_platform_id *clPlatformIDs = new cl_platform_id[num_platforms]; ciErrNum = clGetPlatformIDs(num_platforms, clPlatformIDs, NULL); char chBuffer[1024]; for (cl_uint i = 0; i < num_platforms; ++i) { @@ -63,9 +62,6 @@ static bool initCL(cl_context *clContext, cl_command_queue *clQueue) cpPlatform = clPlatformIDs[i]; } } - // ------------- - cl_device_id clDevice; - clGetDeviceIDs(cpPlatform, CL_DEVICE_TYPE_GPU, 1, &clDevice, NULL); #if defined(_WIN32) cl_context_properties props[] = { @@ -91,14 +87,42 @@ static bool initCL(cl_context *clContext, cl_command_queue *clQueue) #endif delete[] clPlatformIDs; - // XXX context creation should be moved to client code - *clContext = clCreateContext(props, 1, &clDevice, NULL, NULL, &ciErrNum); +#if defined(__APPLE__) + *clContext = clCreateContext(props, 0, NULL, clLogMessagesToStdoutAPPLE, NULL, &ciErrNum); if (ciErrNum != CL_SUCCESS) { printf("Error %d in clCreateContext\n", ciErrNum); return false; } - *clQueue = clCreateCommandQueue(*clContext, clDevice, 0, &ciErrNum); + size_t devicesSize = 0; + clGetGLContextInfoAPPLE(*clContext, kCGLContext, CL_CGL_DEVICES_FOR_SUPPORTED_VIRTUAL_SCREENS_APPLE, 0, NULL, &devicesSize); + int numDevices = int(devicesSize / sizeof(cl_device_id)); + if (numDevices == 0) { + printf("No sharable devices.\n"); + return false; + } + cl_device_id *clDevices = new cl_device_id[numDevices]; + clGetGLContextInfoAPPLE(*clContext, kCGLContext, CL_CGL_DEVICES_FOR_SUPPORTED_VIRTUAL_SCREENS_APPLE, numDevices * sizeof(cl_device_id), clDevices, NULL); +#else + cl_uint numDevices = 0; + clGetDeviceIDs(cpPlatform, CL_DEVICE_TYPE_GPU, 0, NULL, &numDevices); + if (numDevices == 0) { + printf("No sharable devices.\n"); + return false; + } + cl_device_id *clDevices = new cl_device_id[numDevices]; + clGetDeviceIDs(cpPlatform, CL_DEVICE_TYPE_GPU, numDevices, clDevices, NULL); + + *clContext = clCreateContext(props, numDevices, clDevices, NULL, NULL, &ciErrNum); + if (ciErrNum != CL_SUCCESS) { + printf("Error %d in clCreateContext\n", ciErrNum); + delete[] clDevices; + return false; + } +#endif + + *clQueue = clCreateCommandQueue(*clContext, clDevices[0], 0, &ciErrNum); + delete[] clDevices; if (ciErrNum != CL_SUCCESS) { printf("Error %d in clCreateCommandQueue\n", ciErrNum); return false;