From 212815a10d1a8d9e14cd2a6372a2d4be0fd7769f Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Fri, 15 Jan 2021 17:58:57 +0000 Subject: [PATCH] core(ocl): fix lifetime handling of Image kernel args --- modules/core/src/ocl.cpp | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/modules/core/src/ocl.cpp b/modules/core/src/ocl.cpp index bfdd3bba6d..54192efd3a 100644 --- a/modules/core/src/ocl.cpp +++ b/modules/core/src/ocl.cpp @@ -2802,16 +2802,24 @@ struct Kernel::Impl haveTempSrcUMats = true; // UMat is created on RAW memory (without proper lifetime management, even from Mat) } - void addImage(const Image2D& image) + /// Preserve image lifetime (while it is specified as Kernel argument) + void registerImageArgument(int arg, const Image2D& image) { - images.push_back(image); + CV_CheckGE(arg, 0, ""); + CV_CheckLT(arg, (int)MAX_ARRS, ""); + if (arg < (int)shadow_images.size() && shadow_images[arg].ptr() != image.ptr()) // TODO future: replace ptr => impl (more strong check) + { + CV_Check(arg, !isInProgress, "ocl::Kernel: clearing of pending Image2D arguments is not allowed"); + } + shadow_images.reserve(MAX_ARRS); + shadow_images.resize(std::max(shadow_images.size(), (size_t)arg + 1)); + shadow_images[arg] = image; } void finit(cl_event e) { CV_UNUSED(e); cleanupUMats(); - images.clear(); isInProgress = false; release(); } @@ -2836,7 +2844,7 @@ struct Kernel::Impl bool isInProgress; bool isAsyncRun; // true if kernel was scheduled in async mode int nu; - std::list images; + std::vector shadow_images; bool haveTempDstUMats; bool haveTempSrcUMats; }; @@ -2978,9 +2986,11 @@ int Kernel::set(int i, const void* value, size_t sz) int Kernel::set(int i, const Image2D& image2D) { - p->addImage(image2D); cl_mem h = (cl_mem)image2D.ptr(); - return set(i, &h, sizeof(h)); + int res = set(i, &h, sizeof(h)); + if (res >= 0) + p->registerImageArgument(i, image2D); + return res; } int Kernel::set(int i, const UMat& m)