diff --git a/modules/core/src/ocl.cpp b/modules/core/src/ocl.cpp index 708730ee50c4dd62fbfbcd4442a5f9b9bce2f618..9200c29f55c375ffa4cd0e24d737945c4b85278e 100644 --- a/modules/core/src/ocl.cpp +++ b/modules/core/src/ocl.cpp @@ -4650,6 +4650,10 @@ struct Image2D::Impl void init(const UMat &src, bool norm, bool alias) { + if (!haveOpenCL()) + CV_Error(Error::OpenCLApiCallError, "OpenCL runtime not found!"); + + CV_Assert(!src.empty()); CV_Assert(ocl::Device::getDefault().imageSupport()); int err, depth = src.depth(), cn = src.channels(); @@ -4659,6 +4663,9 @@ struct Image2D::Impl if (!isFormatSupported(format)) CV_Error(Error::OpenCLApiCallError, "Image format is not supported"); + if (alias && !src.handle(ACCESS_RW)) + CV_Error(Error::OpenCLApiCallError, "Incorrect UMat, handle is null"); + cl_context context = (cl_context)Context::getDefault().ptr(); cl_command_queue queue = (cl_command_queue)Queue::getDefault().ptr(); @@ -4743,7 +4750,7 @@ bool Image2D::canCreateAlias(const UMat &m) { bool ret = false; const Device & d = ocl::Device::getDefault(); - if (d.imageFromBufferSupport()) + if (d.imageFromBufferSupport() && !m.empty()) { // This is the required pitch alignment in pixels uint pitchAlign = d.imagePitchAlignment(); diff --git a/modules/core/test/ocl/test_image2d.cpp b/modules/core/test/ocl/test_image2d.cpp index 412761a7f8a2e4238b56eff5398df207de9eb93a..dcfc701f11e71d64db7d147b12bdbf97ee04b041 100644 --- a/modules/core/test/ocl/test_image2d.cpp +++ b/modules/core/test/ocl/test_image2d.cpp @@ -13,12 +13,55 @@ namespace cvtest { namespace ocl { -PARAM_TEST_CASE(Image2DBasicTest, int, int) +TEST(Image2D, createAliasEmptyUMat) { - int depth, ch; + if (cv::ocl::haveOpenCL()) + { + UMat um; + EXPECT_FALSE(cv::ocl::Image2D::canCreateAlias(um)); + } + else + std::cout << "OpenCL runtime not found. Test skipped." << std::endl; +} + +TEST(Image2D, createImage2DWithEmptyUMat) +{ + if (cv::ocl::haveOpenCL()) + { + UMat um; + EXPECT_ANY_THROW(cv::ocl::Image2D image(um)); + } + else + std::cout << "OpenCL runtime not found. Test skipped." << std::endl; +} + +TEST(Image2D, createAlias) +{ + if (cv::ocl::haveOpenCL()) + { + const cv::ocl::Device & d = cv::ocl::Device::getDefault(); + int minor = d.deviceVersionMinor(), major = d.deviceVersionMajor(); + // aliases is OpenCL 1.2 extension + if (1 < major || (1 == major && 2 <= minor)) + { + UMat um(128, 128, CV_8UC1); + bool isFormatSupported = false, canCreateAlias = false; -}; + EXPECT_NO_THROW(isFormatSupported = cv::ocl::Image2D::isFormatSupported(CV_8U, 1, false)); + EXPECT_NO_THROW(canCreateAlias = cv::ocl::Image2D::canCreateAlias(um)); + + if (isFormatSupported && canCreateAlias) + { + EXPECT_NO_THROW(cv::ocl::Image2D image(um, false, true)); + } + else + std::cout << "Impossible to create alias for selected image. Test skipped." << std::endl; + } + } + else + std::cout << "OpenCL runtime not found. Test skipped" << std::endl; +} TEST(Image2D, turnOffOpenCL) { @@ -26,16 +69,26 @@ TEST(Image2D, turnOffOpenCL) { // save the current state bool useOCL = cv::ocl::useOpenCL(); + bool isFormatSupported = false; cv::ocl::setUseOpenCL(true); UMat um(128, 128, CV_8UC1); cv::ocl::setUseOpenCL(false); - cv::ocl::Image2D image(um); + EXPECT_NO_THROW(isFormatSupported = cv::ocl::Image2D::isFormatSupported(CV_8U, 1, true)); + + if (isFormatSupported) + { + EXPECT_NO_THROW(cv::ocl::Image2D image(um)); + } + else + std::cout << "CV_8UC1 is not supported for OpenCL images. Test skipped." << std::endl; // reset state to the previous one cv::ocl::setUseOpenCL(useOCL); } + else + std::cout << "OpenCL runtime not found. Test skipped." << std::endl; } } } // namespace cvtest::ocl