diff --git a/modules/ocl/include/opencv2/ocl/ocl.hpp b/modules/ocl/include/opencv2/ocl/ocl.hpp index 613179f8b..b46511e9b 100644 --- a/modules/ocl/include/opencv2/ocl/ocl.hpp +++ b/modules/ocl/include/opencv2/ocl/ocl.hpp @@ -155,7 +155,7 @@ namespace cv static Context* getContext(); static void setContext(Info &oclinfo); - enum {CL_DOUBLE, CL_UNIFIED_MEM}; + enum {CL_DOUBLE, CL_UNIFIED_MEM, CL_VER_1_2}; bool supportsFeature(int ftype); size_t computeUnits(); void* oclContext(); diff --git a/modules/ocl/src/initialization.cpp b/modules/ocl/src/initialization.cpp index 856064c32..799c49c50 100644 --- a/modules/ocl/src/initialization.cpp +++ b/modules/ocl/src/initialization.cpp @@ -130,6 +130,7 @@ namespace cv cl_platform_id oclplatform; std::vector devices; std::vector devName; + std::string clVersion; cl_context oclcontext; cl_command_queue clCmdQueue; @@ -304,6 +305,7 @@ namespace cv char deviceName[256]; int devcienums = 0; + char clVersion[256]; for (unsigned i = 0; i < numPlatforms; ++i) { cl_uint numsdev; @@ -319,6 +321,8 @@ namespace cv Info ocltmpinfo; ocltmpinfo.impl->oclplatform = platforms[i]; + openCLSafeCall(clGetPlatformInfo(platforms[i], CL_PLATFORM_VERSION, sizeof(clVersion), clVersion, NULL)); + ocltmpinfo.impl->clVersion = clVersion; for(unsigned j = 0; j < numsdev; ++j) { ocltmpinfo.impl->devices.push_back(devices[j]); @@ -997,6 +1001,8 @@ namespace cv return impl->double_support == 1; case CL_UNIFIED_MEM: return impl->unified_memory == 1; + case CL_VER_1_2: + return impl->clVersion.find("OpenCL 1.2") != string::npos; default: return false; } diff --git a/modules/ocl/src/matrix_operations.cpp b/modules/ocl/src/matrix_operations.cpp index 87d1d375e..268a1fe9b 100644 --- a/modules/ocl/src/matrix_operations.cpp +++ b/modules/ocl/src/matrix_operations.cpp @@ -593,11 +593,16 @@ static void set_to_withoutmask_run(const oclMat &dst, const Scalar &scalar, stri CV_Error(CV_StsUnsupportedFormat, "unknown depth"); } #ifdef CL_VERSION_1_2 - if(dst.offset == 0 && dst.cols == dst.wholecols) + //this enables backwards portability to + //run on OpenCL 1.1 platform if library binaries are compiled with OpenCL 1.2 support + if(Context::getContext()->supportsFeature(Context::CL_VER_1_2) && + dst.offset == 0 && dst.cols == dst.wholecols) { - clEnqueueFillBuffer((cl_command_queue)dst.clCxt->oclCommandQueue(), (cl_mem)dst.data, args[0].second, args[0].first, 0, dst.step * dst.rows, 0, NULL, NULL); + clEnqueueFillBuffer((cl_command_queue)dst.clCxt->oclCommandQueue(), + (cl_mem)dst.data, args[0].second, args[0].first, 0, dst.step * dst.rows, 0, NULL, NULL); } else +#endif { args.push_back( make_pair( sizeof(cl_mem) , (void *)&dst.data )); args.push_back( make_pair( sizeof(cl_int) , (void *)&dst.cols )); @@ -605,17 +610,8 @@ static void set_to_withoutmask_run(const oclMat &dst, const Scalar &scalar, stri args.push_back( make_pair( sizeof(cl_int) , (void *)&step_in_pixel )); args.push_back( make_pair( sizeof(cl_int) , (void *)&offset_in_pixel)); openCLExecuteKernel(dst.clCxt , &operator_setTo, kernelName, globalThreads, - localThreads, args, -1, -1, compile_option); + localThreads, args, -1, -1, compile_option); } -#else - args.push_back( make_pair( sizeof(cl_mem) , (void *)&dst.data )); - args.push_back( make_pair( sizeof(cl_int) , (void *)&dst.cols )); - args.push_back( make_pair( sizeof(cl_int) , (void *)&dst.rows )); - args.push_back( make_pair( sizeof(cl_int) , (void *)&step_in_pixel )); - args.push_back( make_pair( sizeof(cl_int) , (void *)&offset_in_pixel)); - openCLExecuteKernel(dst.clCxt , &operator_setTo, kernelName, globalThreads, - localThreads, args, -1, -1, compile_option); -#endif } static void set_to_withmask_run(const oclMat &dst, const Scalar &scalar, const oclMat &mask, string kernelName) diff --git a/modules/ocl/src/mcwutil.cpp b/modules/ocl/src/mcwutil.cpp index 15df8e044..e56e2f15d 100644 --- a/modules/ocl/src/mcwutil.cpp +++ b/modules/ocl/src/mcwutil.cpp @@ -45,10 +45,6 @@ #include "precomp.hpp" -#ifndef CL_VERSION_1_2 -#define CL_VERSION_1_2 0 -#endif - using namespace std; namespace cv @@ -124,7 +120,7 @@ namespace cv build_options, finish_mode); } - cl_mem bindTexture(const oclMat &mat) + cl_mem bindTexture(const oclMat &mat) { cl_mem texture; cl_image_format format; @@ -162,30 +158,44 @@ namespace cv CV_Error(-1, "Image forma is not supported"); break; } -#if CL_VERSION_1_2 - cl_image_desc desc; - desc.image_type = CL_MEM_OBJECT_IMAGE2D; - desc.image_width = mat.cols; - desc.image_height = mat.rows; - desc.image_depth = 0; - desc.image_array_size = 1; - desc.image_row_pitch = 0; - desc.image_slice_pitch = 0; - desc.buffer = NULL; - desc.num_mip_levels = 0; - desc.num_samples = 0; - texture = clCreateImage((cl_context)mat.clCxt->oclContext(), CL_MEM_READ_WRITE, &format, &desc, NULL, &err); -#else - texture = clCreateImage2D( - (cl_context)mat.clCxt->oclContext(), - CL_MEM_READ_WRITE, - &format, - mat.cols, - mat.rows, - 0, - NULL, - &err); +#ifdef CL_VERSION_1_2 + //this enables backwards portability to + //run on OpenCL 1.1 platform if library binaries are compiled with OpenCL 1.2 support + if(Context::getContext()->supportsFeature(Context::CL_VER_1_2)) + { + cl_image_desc desc; + desc.image_type = CL_MEM_OBJECT_IMAGE2D; + desc.image_width = mat.cols; + desc.image_height = mat.rows; + desc.image_depth = 0; + desc.image_array_size = 1; + desc.image_row_pitch = 0; + desc.image_slice_pitch = 0; + desc.buffer = NULL; + desc.num_mip_levels = 0; + desc.num_samples = 0; + texture = clCreateImage((cl_context)mat.clCxt->oclContext(), CL_MEM_READ_WRITE, &format, &desc, NULL, &err); + } + else #endif + { +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif + texture = clCreateImage2D( + (cl_context)mat.clCxt->oclContext(), + CL_MEM_READ_WRITE, + &format, + mat.cols, + mat.rows, + 0, + NULL, + &err); +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + } size_t origin[] = { 0, 0, 0 }; size_t region[] = { mat.cols, mat.rows, 1 }; @@ -198,7 +208,7 @@ namespace cv clEnqueueCopyBufferRect((cl_command_queue)mat.clCxt->oclCommandQueue(), (cl_mem)mat.data, devData, origin, origin, regin, mat.step, 0, mat.cols * mat.elemSize(), 0, 0, NULL, NULL); clFlush((cl_command_queue)mat.clCxt->oclCommandQueue()); - } + } else { devData = (cl_mem)mat.data; @@ -214,7 +224,6 @@ namespace cv openCLSafeCall(err); return texture; } - void releaseTexture(cl_mem& texture) { openCLFree(texture);