Merge pull request #19101 from alalek:issue_5209

This commit is contained in:
Alexander Alekhin 2020-12-16 22:13:18 +00:00
commit d159417474
3 changed files with 68 additions and 9 deletions

View File

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

View File

@ -1162,25 +1162,27 @@ Platform& Platform::getDefault()
/////////////////////////////////////// Device ////////////////////////////////////////////
// deviceVersion has format
// Version has format:
// OpenCL<space><major_version.minor_version><space><vendor-specific information>
// by specification
// 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
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;
if (10 >= deviceVersion.length())
if (10 >= version.length())
return;
const char *pstr = deviceVersion.c_str();
const char *pstr = version.c_str();
if (0 != strncmp(pstr, "OpenCL ", 7))
return;
size_t ppos = deviceVersion.find('.', 7);
size_t ppos = version.find('.', 7);
if (String::npos == ppos)
return;
String temp = deviceVersion.substr(7, ppos - 7);
String temp = version.substr(7, ppos - 7);
major = atoi(temp.c_str());
temp = deviceVersion.substr(ppos + 1);
temp = version.substr(ppos + 1);
minor = atoi(temp.c_str());
}
@ -1203,7 +1205,7 @@ struct Device::Impl
addressBits_ = getProp<cl_uint, int>(CL_DEVICE_ADDRESS_BITS);
String deviceVersion_ = getStrProp(CL_DEVICE_VERSION);
parseDeviceVersion(deviceVersion_, deviceVersionMajor_, deviceVersionMinor_);
parseOpenCLVersion(deviceVersion_, deviceVersionMajor_, deviceVersionMinor_);
size_t pos = 0;
while (pos < extensions_.size())
@ -5967,6 +5969,9 @@ struct PlatformInfo::Impl
refcount = 1;
handle = *(cl_platform_id*)id;
getDevices(devices, handle);
version_ = getStrProp(CL_PLATFORM_VERSION);
parseOpenCLVersion(version_, versionMajor_, versionMinor_);
}
String getStrProp(cl_platform_info prop) const
@ -5980,6 +5985,10 @@ struct PlatformInfo::Impl
IMPLEMENT_REFCOUNTABLE();
std::vector<cl_device_id> devices;
cl_platform_id handle;
String version_;
int versionMajor_;
int versionMinor_;
};
PlatformInfo::PlatformInfo()
@ -6042,7 +6051,19 @@ String PlatformInfo::vendor() 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)

View File

@ -1575,6 +1575,7 @@ void cv::ogl::render(const ogl::Arrays& arr, InputArray indices, int mode, Scala
// CL-GL Interoperability
#ifdef HAVE_OPENCL
# include "opencv2/core/opencl/runtime/opencl_core.hpp"
# include "opencv2/core/opencl/runtime/opencl_gl.hpp"
# ifdef cl_khr_gl_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 {
#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 {
Context& initializeContextFromGL()
@ -1714,6 +1743,8 @@ void convertToGLTexture2D(InputArray src, Texture2D& texture)
Context& ctx = Context::getDefault();
cl_context context = (cl_context)ctx.ptr();
checkOpenCLVersion(); // clCreateFromGLTexture requires OpenCL 1.2
UMat u = src.getUMat();
// TODO Add support for roi
@ -1772,6 +1803,8 @@ void convertFromGLTexture2D(const Texture2D& texture, OutputArray dst)
Context& ctx = Context::getDefault();
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!
dst.create(texture.size(), textureType);
UMat u = dst.getUMat();