Skip to content

Commit d159417

Browse files
committed
Merge pull request opencv#19101 from alalek:issue_5209
2 parents 7631056 + 392991f commit d159417

File tree

3 files changed

+68
-9
lines changed

3 files changed

+68
-9
lines changed

modules/core/include/opencv2/core/ocl.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -720,7 +720,12 @@ class CV_EXPORTS PlatformInfo
720720

721721
String name() const;
722722
String vendor() const;
723+
724+
/// See CL_PLATFORM_VERSION
723725
String version() const;
726+
int versionMajor() const;
727+
int versionMinor() const;
728+
724729
int deviceNumber() const;
725730
void getDevice(Device& device, int d) const;
726731

modules/core/src/ocl.cpp

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1162,25 +1162,27 @@ Platform& Platform::getDefault()
11621162

11631163
/////////////////////////////////////// Device ////////////////////////////////////////////
11641164

1165-
// deviceVersion has format
1165+
// Version has format:
11661166
// OpenCL<space><major_version.minor_version><space><vendor-specific information>
11671167
// by specification
11681168
// http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clGetDeviceInfo.html
11691169
// http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clGetDeviceInfo.html
1170-
static void parseDeviceVersion(const String &deviceVersion, int &major, int &minor)
1170+
// https://www.khronos.org/registry/OpenCL/sdk/1.1/docs/man/xhtml/clGetPlatformInfo.html
1171+
// https://www.khronos.org/registry/OpenCL/sdk/1.2/docs/man/xhtml/clGetPlatformInfo.html
1172+
static void parseOpenCLVersion(const String &version, int &major, int &minor)
11711173
{
11721174
major = minor = 0;
1173-
if (10 >= deviceVersion.length())
1175+
if (10 >= version.length())
11741176
return;
1175-
const char *pstr = deviceVersion.c_str();
1177+
const char *pstr = version.c_str();
11761178
if (0 != strncmp(pstr, "OpenCL ", 7))
11771179
return;
1178-
size_t ppos = deviceVersion.find('.', 7);
1180+
size_t ppos = version.find('.', 7);
11791181
if (String::npos == ppos)
11801182
return;
1181-
String temp = deviceVersion.substr(7, ppos - 7);
1183+
String temp = version.substr(7, ppos - 7);
11821184
major = atoi(temp.c_str());
1183-
temp = deviceVersion.substr(ppos + 1);
1185+
temp = version.substr(ppos + 1);
11841186
minor = atoi(temp.c_str());
11851187
}
11861188

@@ -1203,7 +1205,7 @@ struct Device::Impl
12031205
addressBits_ = getProp<cl_uint, int>(CL_DEVICE_ADDRESS_BITS);
12041206

12051207
String deviceVersion_ = getStrProp(CL_DEVICE_VERSION);
1206-
parseDeviceVersion(deviceVersion_, deviceVersionMajor_, deviceVersionMinor_);
1208+
parseOpenCLVersion(deviceVersion_, deviceVersionMajor_, deviceVersionMinor_);
12071209

12081210
size_t pos = 0;
12091211
while (pos < extensions_.size())
@@ -5967,6 +5969,9 @@ struct PlatformInfo::Impl
59675969
refcount = 1;
59685970
handle = *(cl_platform_id*)id;
59695971
getDevices(devices, handle);
5972+
5973+
version_ = getStrProp(CL_PLATFORM_VERSION);
5974+
parseOpenCLVersion(version_, versionMajor_, versionMinor_);
59705975
}
59715976

59725977
String getStrProp(cl_platform_info prop) const
@@ -5980,6 +5985,10 @@ struct PlatformInfo::Impl
59805985
IMPLEMENT_REFCOUNTABLE();
59815986
std::vector<cl_device_id> devices;
59825987
cl_platform_id handle;
5988+
5989+
String version_;
5990+
int versionMajor_;
5991+
int versionMinor_;
59835992
};
59845993

59855994
PlatformInfo::PlatformInfo()
@@ -6042,7 +6051,19 @@ String PlatformInfo::vendor() const
60426051

60436052
String PlatformInfo::version() const
60446053
{
6045-
return p ? p->getStrProp(CL_PLATFORM_VERSION) : String();
6054+
return p ? p->version_ : String();
6055+
}
6056+
6057+
int PlatformInfo::versionMajor() const
6058+
{
6059+
CV_Assert(p);
6060+
return p->versionMajor_;
6061+
}
6062+
6063+
int PlatformInfo::versionMinor() const
6064+
{
6065+
CV_Assert(p);
6066+
return p->versionMinor_;
60466067
}
60476068

60486069
static void getPlatforms(std::vector<cl_platform_id>& platforms)

modules/core/src/opengl.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1575,6 +1575,7 @@ void cv::ogl::render(const ogl::Arrays& arr, InputArray indices, int mode, Scala
15751575
// CL-GL Interoperability
15761576

15771577
#ifdef HAVE_OPENCL
1578+
# include "opencv2/core/opencl/runtime/opencl_core.hpp"
15781579
# include "opencv2/core/opencl/runtime/opencl_gl.hpp"
15791580
# ifdef cl_khr_gl_sharing
15801581
# define HAVE_OPENCL_OPENGL_SHARING
@@ -1595,6 +1596,34 @@ void cv::ogl::render(const ogl::Arrays& arr, InputArray indices, int mode, Scala
15951596

15961597
namespace cv { namespace ogl {
15971598

1599+
#if defined(HAVE_OPENCL) && defined(HAVE_OPENGL) && defined(HAVE_OPENCL_OPENGL_SHARING)
1600+
// Check to avoid crash in OpenCL runtime: https://github.com/opencv/opencv/issues/5209
1601+
static void checkOpenCLVersion()
1602+
{
1603+
using namespace cv::ocl;
1604+
const Device& device = Device::getDefault();
1605+
//CV_Assert(!device.empty());
1606+
cl_device_id dev = (cl_device_id)device.ptr();
1607+
CV_Assert(dev);
1608+
1609+
cl_platform_id platform_id = 0;
1610+
size_t sz = 0;
1611+
1612+
cl_int status = clGetDeviceInfo(dev, CL_DEVICE_PLATFORM, sizeof(platform_id), &platform_id, &sz);
1613+
CV_Assert(status == CL_SUCCESS && sz == sizeof(cl_platform_id));
1614+
CV_Assert(platform_id);
1615+
1616+
PlatformInfo pi(&platform_id);
1617+
int versionMajor = pi.versionMajor();
1618+
int versionMinor = pi.versionMinor();
1619+
if (versionMajor < 1 || (versionMajor == 1 && versionMinor <= 1))
1620+
CV_Error_(cv::Error::OpenCLApiCallError,
1621+
("OpenCL: clCreateFromGLTexture requires OpenCL 1.2+ version: %d.%d - %s (%s)",
1622+
versionMajor, versionMinor, pi.name().c_str(), pi.version().c_str())
1623+
);
1624+
}
1625+
#endif
1626+
15981627
namespace ocl {
15991628

16001629
Context& initializeContextFromGL()
@@ -1714,6 +1743,8 @@ void convertToGLTexture2D(InputArray src, Texture2D& texture)
17141743
Context& ctx = Context::getDefault();
17151744
cl_context context = (cl_context)ctx.ptr();
17161745

1746+
checkOpenCLVersion(); // clCreateFromGLTexture requires OpenCL 1.2
1747+
17171748
UMat u = src.getUMat();
17181749

17191750
// TODO Add support for roi
@@ -1772,6 +1803,8 @@ void convertFromGLTexture2D(const Texture2D& texture, OutputArray dst)
17721803
Context& ctx = Context::getDefault();
17731804
cl_context context = (cl_context)ctx.ptr();
17741805

1806+
checkOpenCLVersion(); // clCreateFromGLTexture requires OpenCL 1.2
1807+
17751808
// TODO Need to specify ACCESS_WRITE here somehow to prevent useless data copying!
17761809
dst.create(texture.size(), textureType);
17771810
UMat u = dst.getUMat();

0 commit comments

Comments
 (0)