#include "CL_context.h" #include #ifdef _WIN32 #include #include namespace cl { bool CL_context::create() { cl_int err; cl_uint num_platforms=0; cl_platform_id* platforms, selected_platform; cl_device_id* devices; size_t size; unsigned int i; err = clGetPlatformIDs(0, NULL, &num_platforms); if (err != CL_SUCCESS) { std::cout << "CL_context::create: [WARNING] Could not get platform count!" << std::endl; return false; } //for this: make sure gl context is current cl_context_properties ctx_props[] = {CL_CONTEXT_PLATFORM, (cl_context_properties) 0, CL_WGL_HDC_KHR, (cl_context_properties) wglGetCurrentDC(), CL_GL_CONTEXT_KHR,(cl_context_properties) wglGetCurrentContext(), 0 }; platforms = new cl_platform_id[num_platforms]; err = clGetPlatformIDs(num_platforms, platforms, NULL); for (i=0; i < num_platforms; ++i) { selected_platform = platforms[i]; ctx_props[1] = (cl_context_properties) selected_platform; context_ = clCreateContextFromType(ctx_props, CL_DEVICE_TYPE_GPU, NULL, NULL, &err); if (context_) break; } delete[] platforms; if (err != CL_SUCCESS || context_ == 0) { std::cout << "CL_context::create: [WARNING] Could not create CL context! Error Code: " << err << std::endl; return false; } err = clGetContextInfo(context_, CL_CONTEXT_DEVICES, 0, NULL, &size); if (err != CL_SUCCESS) { std::cout << "CL_context::create: [WARNING] Could not get device count for CL context!" << std::endl; return false; } devices = new cl_device_id[size/sizeof(cl_device_info)]; clGetContextInfo(context_, CL_CONTEXT_DEVICES, size, devices, NULL); //select first/only device device_id_ = devices[0]; delete[] devices; cmd_queue_ = clCreateCommandQueue(context_, device_id_, 0, &err); if (err != CL_SUCCESS || cmd_queue_ == 0) { std::cout << "CL_context::create: [WARNING] Could not create command-queue!" << std::endl; return false; } if (selected_platform != 0) { char buf[2048]; //get some infos clGetPlatformInfo(selected_platform, CL_PLATFORM_VENDOR, 0, NULL, &size); clGetPlatformInfo(selected_platform, CL_PLATFORM_VENDOR, size, buf, &size); vendor_ = buf; clGetPlatformInfo(selected_platform, CL_PLATFORM_NAME, 0, NULL, &size); clGetPlatformInfo(selected_platform, CL_PLATFORM_NAME, size, buf, &size); name_ = buf; clGetPlatformInfo(selected_platform, CL_PLATFORM_VERSION, 0, NULL, &size); clGetPlatformInfo(selected_platform, CL_PLATFORM_VERSION, size, buf, &size); version_ = buf; } return true; } } #elif __linux #include namespace cl { bool CL_context::query_extension(const std::string& extension_name, cl_platform_id* platforms, cl_uint num_platforms) { bool found_extension = false; cl_int error; for (unsigned int i = 0; i < num_platforms; ++i) { size_t extension_buffer_size = 0; error = clGetPlatformInfo(platforms[i], CL_PLATFORM_EXTENSIONS, 0, nullptr, &extension_buffer_size); if (error != CL_SUCCESS) { printf("[ERROR] %s: clGetPlatformInfo failed.\n", __FUNCTION__); break; } char* extension_buffer = (char*)malloc(sizeof(char) * extension_buffer_size); error = clGetPlatformInfo(platforms[i], CL_PLATFORM_EXTENSIONS, extension_buffer_size, extension_buffer, nullptr); if (error != CL_SUCCESS) { printf("[ERROR] %s: clGetPlatformInfo failed.\n", __FUNCTION__); delete extension_buffer; break; } std::string extensions(extension_buffer); if (extensions.find(extension_name) != std::string::npos) { found_extension = true; } delete extension_buffer; } return found_extension; } bool CL_context::create(){ cl_int err; cl_uint num_platforms=0; cl_platform_id* platforms, selected_platform=0; cl_device_id* devices; size_t size; unsigned int i; err = clGetPlatformIDs(0, NULL, &num_platforms); if (err != CL_SUCCESS) { std::cout << "CL_context::create: [ERROR] Could not get platform count! ErrorID " << err << std::endl; return false; } platforms = new cl_platform_id[num_platforms]; err = clGetPlatformIDs(num_platforms, platforms, NULL); if (err != CL_SUCCESS) { std::cout << "CL_context::create: [ERROR] Could not get platform ids! ErrorID " << err << std::endl; return false; } bool cl_has_gl_sharing_extension = query_extension("cl_khr_gl_sharing", platforms, num_platforms); // Desired OpenCL Context Properties std::vector ctx_props = {CL_CONTEXT_PLATFORM, (cl_context_properties) 0}; if (cl_has_gl_sharing_extension) { // If OpenCL supports OpenGL Context Sharing, add it to our desired context properties // For this: make sure gl context is current ctx_props.push_back(CL_GLX_DISPLAY_KHR); ctx_props.push_back((cl_context_properties) glXGetCurrentDisplay()); ctx_props.push_back(CL_GL_CONTEXT_KHR); ctx_props.push_back((cl_context_properties) glXGetCurrentContext()); } // Mark ending of context_properties array ctx_props.push_back(0); for (i = 0; i < num_platforms; ++i) { selected_platform = platforms[i]; ctx_props[1] = (cl_context_properties) selected_platform; context_ = clCreateContextFromType(ctx_props.data(), CL_DEVICE_TYPE_GPU, NULL, NULL, &err); if (context_) break; } delete[] platforms; //context_ = clCreateContextFromType(ctx_props, CL_DEVICE_TYPE_GPU, NULL, NULL, &err); if (err != CL_SUCCESS || context_ == 0) { std::cout << "CL_context::create: [WARNING] Could not create CL context!" << std::endl; return false; } err = clGetContextInfo(context_, CL_CONTEXT_DEVICES, 0, NULL, &size); if (err != CL_SUCCESS) { std::cout << "CL_context::create: [WARNING] Could not get device count for CL context!" << std::endl; return false; } devices = new cl_device_id[size/sizeof(cl_device_info)]; clGetContextInfo(context_, CL_CONTEXT_DEVICES, size, devices, NULL); //select first/only device device_id_ = devices[0]; delete[] devices; cmd_queue_ = clCreateCommandQueue(context_, device_id_, 0, &err); if (err != CL_SUCCESS || cmd_queue_ == 0) { std::cout << "CL_context::create: [WARNING] Could not create command-queue!" << std::endl; return false; } if (selected_platform != 0) { char buf[2048]; //get some infos clGetPlatformInfo(selected_platform, CL_PLATFORM_VENDOR, 0, NULL, &size); clGetPlatformInfo(selected_platform, CL_PLATFORM_VENDOR, size, buf, &size); vendor_ = buf; clGetPlatformInfo(selected_platform, CL_PLATFORM_NAME, 0, NULL, &size); clGetPlatformInfo(selected_platform, CL_PLATFORM_NAME, size, buf, &size); name_ = buf; clGetPlatformInfo(selected_platform, CL_PLATFORM_VERSION, 0, NULL, &size); clGetPlatformInfo(selected_platform, CL_PLATFORM_VERSION, size, buf, &size); version_ = buf; } return true; } } #elif __APPLE__ #include "../glew/include/GL/glew.h" #include #include namespace cl { bool CL_context::query_extension(const std::string& extension_name, cl_platform_id* platforms, cl_uint num_platforms) { bool found_extension = false; cl_int error; for (unsigned int i = 0; i < num_platforms; ++i) { size_t extension_buffer_size = 0; error = clGetPlatformInfo(platforms[i], CL_PLATFORM_EXTENSIONS, 0, nullptr, &extension_buffer_size); if (error != CL_SUCCESS) { printf("[ERROR] %s: clGetPlatformInfo failed.\n", __FUNCTION__); break; } char* extension_buffer = (char*)malloc(sizeof(char) * extension_buffer_size); error = clGetPlatformInfo(platforms[i], CL_PLATFORM_EXTENSIONS, extension_buffer_size, extension_buffer, nullptr); if (error != CL_SUCCESS) { printf("[ERROR] %s: clGetPlatformInfo failed.\n", __FUNCTION__); delete extension_buffer; break; } std::string extensions(extension_buffer); if (extensions.find(extension_name) != std::string::npos) { found_extension = true; } delete extension_buffer; } return found_extension; } bool CL_context::create(){ cl_int err; cl_uint num_platforms=0; cl_platform_id* platforms, selected_platform=0; cl_device_id* devices; size_t size; unsigned int i; err = clGetPlatformIDs(0, NULL, &num_platforms); if (err != CL_SUCCESS) { std::cout << "CL_context::create: [ERROR] Could not get platform count! ErrorID " << err << std::endl; return false; } platforms = new cl_platform_id[num_platforms]; err = clGetPlatformIDs(num_platforms, platforms, NULL); if (err != CL_SUCCESS) { std::cout << "CL_context::create: [ERROR] Could not get platform ids! ErrorID " << err << std::endl; return false; } bool cl_has_gl_sharing_extension = query_extension("cl_khr_gl_sharing", platforms, num_platforms); // Desired OpenCL Context Properties std::vector ctx_props = {CL_CONTEXT_PLATFORM, (cl_context_properties) 0}; if (cl_has_gl_sharing_extension) { // MacOS CGLContextObj kCGLContext = CGLGetCurrentContext(); CGLShareGroupObj kCGLShareGroup = CGLGetShareGroup(kCGLContext); ctx_props.push_back(CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE); ctx_props.push_back((cl_context_properties) kCGLShareGroup); } // Mark ending of context_properties array ctx_props.push_back(0); for (i = 0; i < num_platforms; ++i) { selected_platform = platforms[i]; ctx_props[1] = (cl_context_properties) selected_platform; context_ = clCreateContextFromType(ctx_props.data(), CL_DEVICE_TYPE_GPU, NULL, NULL, &err); if (context_) break; } delete[] platforms; //context_ = clCreateContextFromType(ctx_props, CL_DEVICE_TYPE_GPU, NULL, NULL, &err); if (err != CL_SUCCESS || context_ == 0) { std::cout << "CL_context::create: [WARNING] Could not create CL context!" << std::endl; return false; } err = clGetContextInfo(context_, CL_CONTEXT_DEVICES, 0, NULL, &size); if (err != CL_SUCCESS) { std::cout << "CL_context::create: [WARNING] Could not get device count for CL context!" << std::endl; return false; } devices = new cl_device_id[size/sizeof(cl_device_info)]; clGetContextInfo(context_, CL_CONTEXT_DEVICES, size, devices, NULL); //select first/only device device_id_ = devices[0]; delete[] devices; cmd_queue_ = clCreateCommandQueue(context_, device_id_, 0, &err); if (err != CL_SUCCESS || cmd_queue_ == 0) { std::cout << "CL_context::create: [WARNING] Could not create command-queue!" << std::endl; return false; } if (selected_platform != 0) { char buf[2048]; //get some infos clGetPlatformInfo(selected_platform, CL_PLATFORM_VENDOR, 0, NULL, &size); clGetPlatformInfo(selected_platform, CL_PLATFORM_VENDOR, size, buf, &size); vendor_ = buf; clGetPlatformInfo(selected_platform, CL_PLATFORM_NAME, 0, NULL, &size); clGetPlatformInfo(selected_platform, CL_PLATFORM_NAME, size, buf, &size); name_ = buf; clGetPlatformInfo(selected_platform, CL_PLATFORM_VERSION, 0, NULL, &size); clGetPlatformInfo(selected_platform, CL_PLATFORM_VERSION, size, buf, &size); version_ = buf; } return true; } } #endif