diff --git a/modules/core/include/opencv2/core/ocl.hpp b/modules/core/include/opencv2/core/ocl.hpp
index fb9f0282b..12c7b8b06 100644
--- a/modules/core/include/opencv2/core/ocl.hpp
+++ b/modules/core/include/opencv2/core/ocl.hpp
@@ -59,6 +59,7 @@ class CV_EXPORTS Kernel;
 class CV_EXPORTS Program;
 class CV_EXPORTS ProgramSource2;
 class CV_EXPORTS Queue;
+class CV_EXPORTS PlatformInfo2;
 
 class CV_EXPORTS Device
 {
@@ -84,6 +85,7 @@ public:
 
     String name() const;
     String extensions() const;
+    String version() const;
     String vendor() const;
     String OpenCL_C_Version() const;
     String OpenCLVersion() const;
@@ -549,9 +551,28 @@ protected:
     Impl* p;
 };
 
+class CV_EXPORTS PlatformInfo2
+{
+public:
+    PlatformInfo2();
+    explicit PlatformInfo2(void* id);
+    ~PlatformInfo2();
+
+    String name() const;
+    String vendor() const;
+    String version() const;
+    int deviceNumber() const;
+    void getDevice(Device& device, int d) const;
+
+protected:
+    struct Impl;
+    Impl* p;
+};
+
 CV_EXPORTS const char* convertTypeStr(int sdepth, int ddepth, int cn, char* buf);
 CV_EXPORTS const char* typeToStr(int t);
 CV_EXPORTS const char* memopTypeToStr(int t);
+CV_EXPORTS void getPlatfomsInfo(std::vector<PlatformInfo2>& platform_info);
 
 }}
 
diff --git a/modules/core/src/ocl.cpp b/modules/core/src/ocl.cpp
index e2f4d2c4b..73980629a 100644
--- a/modules/core/src/ocl.cpp
+++ b/modules/core/src/ocl.cpp
@@ -1693,6 +1693,9 @@ String Device::name() const
 String Device::extensions() const
 { return p ? p->getStrProp(CL_DEVICE_EXTENSIONS) : String(); }
 
+String Device::version() const
+{ return p ? p->getStrProp(CL_DEVICE_VERSION) : String(); }
+
 String Device::vendor() const
 { return p ? p->getStrProp(CL_DEVICE_VENDOR) : String(); }
 
@@ -3621,6 +3624,110 @@ MatAllocator* getOpenCLAllocator()
     return &allocator;
 }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+static void getDevices(std::vector<cl_device_id>& devices,cl_platform_id& platform)
+{
+    cl_int status = CL_SUCCESS;
+    cl_uint numDevices = 0;
+    status = clGetDeviceIDs(platform, (cl_device_type)Device::TYPE_ALL, 0, NULL, &numDevices);
+    CV_Assert(status == CL_SUCCESS);
+    if (numDevices == 0)
+        return;
+    devices.resize((size_t)numDevices);
+    status = clGetDeviceIDs(platform, (cl_device_type)Device::TYPE_ALL, numDevices, &devices[0], &numDevices);
+    CV_Assert(status == CL_SUCCESS);
+    devices.resize(numDevices);
+}
+
+struct PlatformInfo2::Impl
+{
+    Impl(void* id)
+    {
+        handle = *(cl_platform_id*)id;
+        getDevices(devices, handle);
+    }
+
+    String getStrProp(cl_device_info prop) const
+    {
+        char buf[1024];
+        size_t sz=0;
+        return clGetPlatformInfo(handle, prop, sizeof(buf)-16, buf, &sz) >= 0 &&
+            sz < sizeof(buf) ? String(buf) : String();
+    }
+
+    IMPLEMENT_REFCOUNTABLE();
+    std::vector<cl_device_id> devices;
+    cl_platform_id handle;
+};
+
+PlatformInfo2::PlatformInfo2()
+{
+    p = 0;
+}
+
+PlatformInfo2::PlatformInfo2(void* platform_id)
+{
+    p = new Impl(platform_id);
+}
+
+PlatformInfo2::~PlatformInfo2()
+{
+    if(p)
+        p->release();
+}
+
+int PlatformInfo2::deviceNumber() const
+{
+    return p ? (int)p->devices.size() : 0;
+}
+
+void PlatformInfo2::getDevice(Device& device, int d) const
+{
+    CV_Assert(d < (int)p->devices.size() );
+    if(p)
+        device.set(p->devices[d]);
+}
+
+String PlatformInfo2::name() const
+{
+    return p ? p->getStrProp(CL_PLATFORM_NAME) : String();
+}
+
+String PlatformInfo2::vendor() const
+{
+    return p ? p->getStrProp(CL_PLATFORM_VENDOR) : String();
+}
+
+String PlatformInfo2::version() const
+{
+    return p ? p->getStrProp(CL_PLATFORM_VERSION) : String();
+}
+
+static void getPlatforms(std::vector<cl_platform_id>& platforms)
+{
+    cl_int status = CL_SUCCESS;
+    cl_uint numPlatforms = 0;
+    status = clGetPlatformIDs(0, NULL, &numPlatforms);
+    CV_Assert(status == CL_SUCCESS);
+    if (numPlatforms == 0)
+        return;
+    platforms.resize((size_t)numPlatforms);
+    status = clGetPlatformIDs(numPlatforms, &platforms[0], &numPlatforms);
+    CV_Assert(status == CL_SUCCESS);
+    platforms.resize(numPlatforms);
+}
+
+void getPlatfomsInfo(std::vector<PlatformInfo2>& platformsInfo)
+{
+    std::vector<cl_platform_id> platforms;
+    getPlatforms(platforms);
+    for (size_t i = 0; i < platforms.size(); i++)
+    {
+        platformsInfo.push_back( PlatformInfo2((void*)&platforms[i]) );
+    }
+}
+
 const char* typeToStr(int t)
 {
     static const char* tab[]=
diff --git a/modules/ts/include/opencv2/ts/ts_perf.hpp b/modules/ts/include/opencv2/ts/ts_perf.hpp
index fcf3ece44..479e634c1 100644
--- a/modules/ts/include/opencv2/ts/ts_perf.hpp
+++ b/modules/ts/include/opencv2/ts/ts_perf.hpp
@@ -510,6 +510,15 @@ CV_EXPORTS void PrintTo(const Size& sz, ::std::ostream* os);
 #endif
 #endif
 
+#if defined(HAVE_OPENCL) && !defined(CV_BUILD_OCL_MODULE)
+namespace cvtest { namespace ocl {
+void dumpOpenCLDevice();
+}}
+#define TEST_DUMP_OCL_INFO cvtest::ocl::dumpOpenCLDevice();
+#else
+#define TEST_DUMP_OCL_INFO
+#endif
+
 #define CV_PERF_TEST_MAIN_INTERNALS(modulename, impls, ...)	\
     ::perf::Regression::Init(#modulename); \
     ::perf::TestBase::Init(std::vector<std::string>(impls, impls + sizeof impls / sizeof *impls), \
@@ -519,6 +528,7 @@ CV_EXPORTS void PrintTo(const Size& sz, ::std::ostream* os);
     ::testing::Test::RecordProperty("cv_module_name", #modulename); \
     ::perf::TestBase::RecordRunParameters(); \
     __CV_TEST_EXEC_ARGS(__VA_ARGS__) \
+    TEST_DUMP_OCL_INFO \
     return RUN_ALL_TESTS();
 
 // impls must be an array, not a pointer; "plain" should always be one of the implementations
diff --git a/modules/ts/src/ocl_test.cpp b/modules/ts/src/ocl_test.cpp
index 201c5f459..0ad3df693 100644
--- a/modules/ts/src/ocl_test.cpp
+++ b/modules/ts/src/ocl_test.cpp
@@ -98,28 +98,25 @@ void dumpOpenCLDevice()
     using namespace cv::ocl;
     try
     {
-#if 0
-        Platforms platforms;
-        getOpenCLPlatforms(platforms);
+        std::vector<PlatformInfo2> platforms;
+        cv::ocl::getPlatfomsInfo(platforms);
         if (platforms.size() > 0)
         {
             DUMP_MESSAGE_STDOUT("OpenCL Platforms: ");
             for (size_t i = 0; i < platforms.size(); i++)
             {
-                const Platform* platform = platforms.at(i);
+                const PlatformInfo2* platform = &platforms[i];
                 DUMP_MESSAGE_STDOUT("    " << platform->name().c_str());
-                const Devices& devices = platform->devices();
-                for (size_t j = 0; j < devices.size(); j++)
+                Device current_device;
+                for (int j = 0; j < platform->deviceNumber(); j++)
                 {
-                    const Device& current_device = *devices.at(j);
+                    platform->getDevice(current_device, j);
                     const char* deviceTypeStr = current_device.type() == Device::TYPE_CPU
-                                ? ("CPU") : (current_device.type() == Device::TYPE_GPU ? "GPU" : "unknown");
+                        ? ("CPU") : (current_device.type() == Device::TYPE_GPU ? current_device.hostUnifiedMemory() ? "iGPU" : "dGPU" : "unknown");
                     DUMP_MESSAGE_STDOUT( "        " << deviceTypeStr << ": " << current_device.name().c_str() << " (" << current_device.version().c_str() << ")");
-                    DUMP_PROPERTY_XML(cv::format("cv_ocl_platform_%d_device_%d", (int)i, (int)j),
-                            "(Platform=" << current_device.getPlatform().name().c_str()
-                            << ")(Type=" << deviceTypeStr
-                            << ")(Name=" << current_device.name().c_str()
-                            << ")(Version=" << current_device.version().c_str() << ")");
+                    DUMP_PROPERTY_XML( cv::format("cv_ocl_platform_%d_device_%d", (int)i, (int)j ),
+                        cv::format("(Platform=%s)(Type=%s)(Name=%s)(Version=%s)",
+                        platform->name().c_str(), deviceTypeStr, current_device.name().c_str(), current_device.version().c_str()) );
                 }
             }
         }
@@ -129,10 +126,9 @@ void dumpOpenCLDevice()
             DUMP_PROPERTY_XML("cv_ocl", "not available");
             return;
         }
-#endif
-        DUMP_MESSAGE_STDOUT("Current OpenCL device: ");
 
         const Device& device = Device::getDefault();
+        DUMP_MESSAGE_STDOUT("Current OpenCL device: ");
 
 #if 0
         DUMP_MESSAGE_STDOUT("    Platform = "<< device.getPlatform().name());
@@ -140,17 +136,15 @@ void dumpOpenCLDevice()
 #endif
 
         const char* deviceTypeStr = device.type() == Device::TYPE_CPU
-                        ? "CPU" : (device.type() == Device::TYPE_GPU ? "GPU" : "unknown");
+            ? ("CPU") : (device.type() == Device::TYPE_GPU ? device.hostUnifiedMemory() ? "iGPU" : "dGPU" : "unknown");
         DUMP_MESSAGE_STDOUT("    Type = "<< deviceTypeStr);
         DUMP_PROPERTY_XML("cv_ocl_current_deviceType", deviceTypeStr);
 
         DUMP_MESSAGE_STDOUT("    Name = "<< device.name());
         DUMP_PROPERTY_XML("cv_ocl_current_deviceName", device.name());
 
-#if 0
         DUMP_MESSAGE_STDOUT("    Version = " << device.version());
         DUMP_PROPERTY_XML("cv_ocl_current_deviceVersion", device.version());
-#endif
 
         DUMP_MESSAGE_STDOUT("    Compute units = "<< device.maxComputeUnits());
         DUMP_PROPERTY_XML("cv_ocl_current_maxComputeUnits", device.maxComputeUnits());