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.
This commit is contained in:
David G. Yu 2014-02-23 21:21:25 -08:00
parent ead34f1662
commit 5031d0686a

View File

@ -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;