core(opencl): add version check before clCreateFromGLTexture() call

pull/19101/head
Alexander Alekhin 4 years ago
parent 1bfc75ac23
commit 392991fa0b
  1. 5
      modules/core/include/opencv2/core/ocl.hpp
  2. 39
      modules/core/src/ocl.cpp
  3. 33
      modules/core/src/opengl.cpp

@ -720,7 +720,12 @@ public:
String name() const; String name() const;
String vendor() const; String vendor() const;
/// See CL_PLATFORM_VERSION
String version() const; String version() const;
int versionMajor() const;
int versionMinor() const;
int deviceNumber() const; int deviceNumber() const;
void getDevice(Device& device, int d) const; void getDevice(Device& device, int d) const;

@ -1162,25 +1162,27 @@ Platform& Platform::getDefault()
/////////////////////////////////////// Device //////////////////////////////////////////// /////////////////////////////////////// Device ////////////////////////////////////////////
// deviceVersion has format // Version has format:
// OpenCL<space><major_version.minor_version><space><vendor-specific information> // OpenCL<space><major_version.minor_version><space><vendor-specific information>
// by specification // by specification
// http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clGetDeviceInfo.html // http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clGetDeviceInfo.html
// http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clGetDeviceInfo.html // http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clGetDeviceInfo.html
static void parseDeviceVersion(const String &deviceVersion, int &major, int &minor) // https://www.khronos.org/registry/OpenCL/sdk/1.1/docs/man/xhtml/clGetPlatformInfo.html
// https://www.khronos.org/registry/OpenCL/sdk/1.2/docs/man/xhtml/clGetPlatformInfo.html
static void parseOpenCLVersion(const String &version, int &major, int &minor)
{ {
major = minor = 0; major = minor = 0;
if (10 >= deviceVersion.length()) if (10 >= version.length())
return; return;
const char *pstr = deviceVersion.c_str(); const char *pstr = version.c_str();
if (0 != strncmp(pstr, "OpenCL ", 7)) if (0 != strncmp(pstr, "OpenCL ", 7))
return; return;
size_t ppos = deviceVersion.find('.', 7); size_t ppos = version.find('.', 7);
if (String::npos == ppos) if (String::npos == ppos)
return; return;
String temp = deviceVersion.substr(7, ppos - 7); String temp = version.substr(7, ppos - 7);
major = atoi(temp.c_str()); major = atoi(temp.c_str());
temp = deviceVersion.substr(ppos + 1); temp = version.substr(ppos + 1);
minor = atoi(temp.c_str()); minor = atoi(temp.c_str());
} }
@ -1203,7 +1205,7 @@ struct Device::Impl
addressBits_ = getProp<cl_uint, int>(CL_DEVICE_ADDRESS_BITS); addressBits_ = getProp<cl_uint, int>(CL_DEVICE_ADDRESS_BITS);
String deviceVersion_ = getStrProp(CL_DEVICE_VERSION); String deviceVersion_ = getStrProp(CL_DEVICE_VERSION);
parseDeviceVersion(deviceVersion_, deviceVersionMajor_, deviceVersionMinor_); parseOpenCLVersion(deviceVersion_, deviceVersionMajor_, deviceVersionMinor_);
size_t pos = 0; size_t pos = 0;
while (pos < extensions_.size()) while (pos < extensions_.size())
@ -5958,6 +5960,9 @@ struct PlatformInfo::Impl
refcount = 1; refcount = 1;
handle = *(cl_platform_id*)id; handle = *(cl_platform_id*)id;
getDevices(devices, handle); getDevices(devices, handle);
version_ = getStrProp(CL_PLATFORM_VERSION);
parseOpenCLVersion(version_, versionMajor_, versionMinor_);
} }
String getStrProp(cl_platform_info prop) const String getStrProp(cl_platform_info prop) const
@ -5971,6 +5976,10 @@ struct PlatformInfo::Impl
IMPLEMENT_REFCOUNTABLE(); IMPLEMENT_REFCOUNTABLE();
std::vector<cl_device_id> devices; std::vector<cl_device_id> devices;
cl_platform_id handle; cl_platform_id handle;
String version_;
int versionMajor_;
int versionMinor_;
}; };
PlatformInfo::PlatformInfo() PlatformInfo::PlatformInfo()
@ -6033,7 +6042,19 @@ String PlatformInfo::vendor() const
String PlatformInfo::version() const String PlatformInfo::version() const
{ {
return p ? p->getStrProp(CL_PLATFORM_VERSION) : String(); return p ? p->version_ : String();
}
int PlatformInfo::versionMajor() const
{
CV_Assert(p);
return p->versionMajor_;
}
int PlatformInfo::versionMinor() const
{
CV_Assert(p);
return p->versionMinor_;
} }
static void getPlatforms(std::vector<cl_platform_id>& platforms) static void getPlatforms(std::vector<cl_platform_id>& platforms)

@ -1575,6 +1575,7 @@ void cv::ogl::render(const ogl::Arrays& arr, InputArray indices, int mode, Scala
// CL-GL Interoperability // CL-GL Interoperability
#ifdef HAVE_OPENCL #ifdef HAVE_OPENCL
# include "opencv2/core/opencl/runtime/opencl_core.hpp"
# include "opencv2/core/opencl/runtime/opencl_gl.hpp" # include "opencv2/core/opencl/runtime/opencl_gl.hpp"
# ifdef cl_khr_gl_sharing # ifdef cl_khr_gl_sharing
# define HAVE_OPENCL_OPENGL_SHARING # define HAVE_OPENCL_OPENGL_SHARING
@ -1595,6 +1596,34 @@ void cv::ogl::render(const ogl::Arrays& arr, InputArray indices, int mode, Scala
namespace cv { namespace ogl { namespace cv { namespace ogl {
#if defined(HAVE_OPENCL) && defined(HAVE_OPENGL) && defined(HAVE_OPENCL_OPENGL_SHARING)
// Check to avoid crash in OpenCL runtime: https://github.com/opencv/opencv/issues/5209
static void checkOpenCLVersion()
{
using namespace cv::ocl;
const Device& device = Device::getDefault();
//CV_Assert(!device.empty());
cl_device_id dev = (cl_device_id)device.ptr();
CV_Assert(dev);
cl_platform_id platform_id = 0;
size_t sz = 0;
cl_int status = clGetDeviceInfo(dev, CL_DEVICE_PLATFORM, sizeof(platform_id), &platform_id, &sz);
CV_Assert(status == CL_SUCCESS && sz == sizeof(cl_platform_id));
CV_Assert(platform_id);
PlatformInfo pi(&platform_id);
int versionMajor = pi.versionMajor();
int versionMinor = pi.versionMinor();
if (versionMajor < 1 || (versionMajor == 1 && versionMinor <= 1))
CV_Error_(cv::Error::OpenCLApiCallError,
("OpenCL: clCreateFromGLTexture requires OpenCL 1.2+ version: %d.%d - %s (%s)",
versionMajor, versionMinor, pi.name().c_str(), pi.version().c_str())
);
}
#endif
namespace ocl { namespace ocl {
Context& initializeContextFromGL() Context& initializeContextFromGL()
@ -1714,6 +1743,8 @@ void convertToGLTexture2D(InputArray src, Texture2D& texture)
Context& ctx = Context::getDefault(); Context& ctx = Context::getDefault();
cl_context context = (cl_context)ctx.ptr(); cl_context context = (cl_context)ctx.ptr();
checkOpenCLVersion(); // clCreateFromGLTexture requires OpenCL 1.2
UMat u = src.getUMat(); UMat u = src.getUMat();
// TODO Add support for roi // TODO Add support for roi
@ -1772,6 +1803,8 @@ void convertFromGLTexture2D(const Texture2D& texture, OutputArray dst)
Context& ctx = Context::getDefault(); Context& ctx = Context::getDefault();
cl_context context = (cl_context)ctx.ptr(); cl_context context = (cl_context)ctx.ptr();
checkOpenCLVersion(); // clCreateFromGLTexture requires OpenCL 1.2
// TODO Need to specify ACCESS_WRITE here somehow to prevent useless data copying! // TODO Need to specify ACCESS_WRITE here somehow to prevent useless data copying!
dst.create(texture.size(), textureType); dst.create(texture.size(), textureType);
UMat u = dst.getUMat(); UMat u = dst.getUMat();

Loading…
Cancel
Save