ocl: workaround for getUMat()
This commit is contained in:
@@ -208,17 +208,14 @@ public:
|
||||
if(!u)
|
||||
return;
|
||||
|
||||
CV_Assert(u->urefcount >= 0);
|
||||
CV_Assert(u->refcount >= 0);
|
||||
if(u->refcount == 0)
|
||||
CV_Assert(u->urefcount == 0);
|
||||
CV_Assert(u->refcount == 0);
|
||||
if( !(u->flags & UMatData::USER_ALLOCATED) )
|
||||
{
|
||||
if( !(u->flags & UMatData::USER_ALLOCATED) )
|
||||
{
|
||||
fastFree(u->origdata);
|
||||
u->origdata = 0;
|
||||
}
|
||||
delete u;
|
||||
fastFree(u->origdata);
|
||||
u->origdata = 0;
|
||||
}
|
||||
delete u;
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -4453,8 +4453,11 @@ public:
|
||||
#endif
|
||||
{
|
||||
tempUMatFlags = UMatData::TEMP_UMAT;
|
||||
handle = clCreateBuffer(ctx_handle, CL_MEM_USE_HOST_PTR|createFlags,
|
||||
u->size, u->origdata, &retval);
|
||||
if (u->origdata == cv::alignPtr(u->origdata, 4)) // There are OpenCL runtime issues for less aligned data
|
||||
{
|
||||
handle = clCreateBuffer(ctx_handle, CL_MEM_USE_HOST_PTR|createFlags,
|
||||
u->size, u->origdata, &retval);
|
||||
}
|
||||
if((!handle || retval < 0) && !(accessFlags & ACCESS_FAST))
|
||||
{
|
||||
handle = clCreateBuffer(ctx_handle, CL_MEM_COPY_HOST_PTR|CL_MEM_READ_WRITE|createFlags,
|
||||
@@ -4510,17 +4513,17 @@ public:
|
||||
if(!u)
|
||||
return;
|
||||
|
||||
CV_Assert(u->urefcount >= 0);
|
||||
CV_Assert(u->refcount >= 0);
|
||||
CV_Assert(u->urefcount == 0);
|
||||
CV_Assert(u->refcount == 0 && "UMat deallocation error: some derived Mat is still alive");
|
||||
|
||||
CV_Assert(u->handle != 0 && u->urefcount == 0);
|
||||
CV_Assert(u->handle != 0);
|
||||
CV_Assert(u->mapcount == 0);
|
||||
if(u->tempUMat())
|
||||
{
|
||||
CV_Assert(u->origdata);
|
||||
// UMatDataAutoLock lock(u);
|
||||
|
||||
if( u->hostCopyObsolete() && u->refcount > 0 )
|
||||
if (u->hostCopyObsolete())
|
||||
{
|
||||
#ifdef HAVE_OPENCL_SVM
|
||||
if ((u->allocatorFlags_ & svm::OPENCL_SVM_BUFFER_MASK) != 0)
|
||||
@@ -4579,7 +4582,12 @@ public:
|
||||
void* data = clEnqueueMapBuffer(q, (cl_mem)u->handle, CL_TRUE,
|
||||
(CL_MAP_READ | CL_MAP_WRITE),
|
||||
0, u->size, 0, 0, 0, &retval);
|
||||
CV_Assert(u->origdata == data);
|
||||
CV_OclDbgAssert(retval == CL_SUCCESS);
|
||||
if (u->originalUMatData)
|
||||
{
|
||||
CV_Assert(u->originalUMatData->data == data);
|
||||
}
|
||||
CV_OclDbgAssert(clEnqueueUnmapMemObject(q, (cl_mem)u->handle, data, 0, 0, 0) == CL_SUCCESS);
|
||||
CV_OclDbgAssert(clFinish(q) == CL_SUCCESS);
|
||||
}
|
||||
@@ -4587,6 +4595,10 @@ public:
|
||||
}
|
||||
u->markHostCopyObsolete(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
// nothing
|
||||
}
|
||||
#ifdef HAVE_OPENCL_SVM
|
||||
if ((u->allocatorFlags_ & svm::OPENCL_SVM_BUFFER_MASK) != 0)
|
||||
{
|
||||
@@ -4612,16 +4624,12 @@ public:
|
||||
if(u->data && u->copyOnMap() && u->data != u->origdata)
|
||||
fastFree(u->data);
|
||||
u->data = u->origdata;
|
||||
if(u->refcount == 0)
|
||||
{
|
||||
u->currAllocator->deallocate(u);
|
||||
u = NULL;
|
||||
}
|
||||
u->currAllocator->deallocate(u);
|
||||
u = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
CV_Assert(u->origdata == NULL);
|
||||
CV_Assert(u->refcount == 0);
|
||||
if(u->data && u->copyOnMap() && u->data != u->origdata)
|
||||
{
|
||||
fastFree(u->data);
|
||||
@@ -4670,17 +4678,13 @@ public:
|
||||
delete u;
|
||||
u = NULL;
|
||||
}
|
||||
CV_Assert(u == NULL || u->refcount);
|
||||
CV_Assert(u == NULL);
|
||||
}
|
||||
|
||||
// synchronized call (external UMatDataAutoLock, see UMat::getMat)
|
||||
void map(UMatData* u, int accessFlags) const
|
||||
{
|
||||
if(!u)
|
||||
return;
|
||||
|
||||
CV_Assert( u->handle != 0 );
|
||||
|
||||
UMatDataAutoLock autolock(u);
|
||||
CV_Assert(u && u->handle);
|
||||
|
||||
if(accessFlags & ACCESS_WRITE)
|
||||
u->markDeviceCopyObsolete(true);
|
||||
|
@@ -67,6 +67,7 @@ UMatData::UMatData(const MatAllocator* allocator)
|
||||
handle = 0;
|
||||
userdata = 0;
|
||||
allocatorFlags_ = 0;
|
||||
originalUMatData = NULL;
|
||||
}
|
||||
|
||||
UMatData::~UMatData()
|
||||
@@ -80,6 +81,50 @@ UMatData::~UMatData()
|
||||
handle = 0;
|
||||
userdata = 0;
|
||||
allocatorFlags_ = 0;
|
||||
if (originalUMatData)
|
||||
{
|
||||
UMatData* u = originalUMatData;
|
||||
CV_XADD(&(u->urefcount), -1);
|
||||
CV_XADD(&(u->refcount), -1);
|
||||
bool showWarn = false;
|
||||
if (u->refcount == 0)
|
||||
{
|
||||
if (u->urefcount > 0)
|
||||
showWarn = true;
|
||||
// simulate Mat::deallocate
|
||||
if (u->mapcount != 0)
|
||||
{
|
||||
(u->currAllocator ? u->currAllocator : /* TODO allocator ? allocator :*/ Mat::getStdAllocator())->unmap(u);
|
||||
}
|
||||
else
|
||||
{
|
||||
// we don't do "map", so we can't do "unmap"
|
||||
}
|
||||
}
|
||||
if (u->refcount == 0 && u->urefcount == 0) // oops, we need to free resources
|
||||
{
|
||||
showWarn = true;
|
||||
// simulate UMat::deallocate
|
||||
u->currAllocator->deallocate(u);
|
||||
}
|
||||
#ifndef NDEBUG
|
||||
if (showWarn)
|
||||
{
|
||||
static int warn_message_showed = 0;
|
||||
if (warn_message_showed++ < 100)
|
||||
{
|
||||
fflush(stdout);
|
||||
fprintf(stderr, "\n! OPENCV warning: getUMat()/getMat() call chain possible problem."
|
||||
"\n! Base object is dead, while nested/derived object is still alive or processed."
|
||||
"\n! Please check lifetime of UMat/Mat objects!\n");
|
||||
fflush(stderr);
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)showWarn;
|
||||
#endif
|
||||
originalUMatData = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void UMatData::lock()
|
||||
@@ -222,20 +267,34 @@ UMat Mat::getUMat(int accessFlags, UMatUsageFlags usageFlags) const
|
||||
UMat hdr;
|
||||
if(!data)
|
||||
return hdr;
|
||||
CV_Assert((!u || u->mapcount==0) && "Don't get UMat from temp-Mat!");
|
||||
Size wholeSize;
|
||||
Point ofs;
|
||||
locateROI(wholeSize, ofs);
|
||||
Size sz(cols, rows);
|
||||
if (ofs.x != 0 || ofs.y != 0)
|
||||
{
|
||||
Mat src = *this;
|
||||
int dtop = ofs.y;
|
||||
int dbottom = wholeSize.height - src.rows - ofs.y;
|
||||
int dleft = ofs.x;
|
||||
int dright = wholeSize.width - src.cols - ofs.x;
|
||||
src.adjustROI(dtop, dbottom, dleft, dright);
|
||||
return src.getUMat(accessFlags, usageFlags)(cv::Rect(ofs.x, ofs.y, sz.width, sz.height));
|
||||
}
|
||||
CV_Assert(data == datastart);
|
||||
|
||||
accessFlags |= ACCESS_RW;
|
||||
UMatData* temp_u = u;
|
||||
if(!temp_u)
|
||||
UMatData* new_u = NULL;
|
||||
{
|
||||
MatAllocator *a = allocator, *a0 = getStdAllocator();
|
||||
if(!a)
|
||||
a = a0;
|
||||
temp_u = a->allocate(dims, size.p, type(), data, step.p, accessFlags, usageFlags);
|
||||
new_u = a->allocate(dims, size.p, type(), data, step.p, accessFlags, usageFlags);
|
||||
}
|
||||
bool allocated = false;
|
||||
try
|
||||
{
|
||||
allocated = UMat::getStdAllocator()->allocate(temp_u, accessFlags, usageFlags);
|
||||
allocated = UMat::getStdAllocator()->allocate(new_u, accessFlags, usageFlags);
|
||||
}
|
||||
catch (const cv::Exception& e)
|
||||
{
|
||||
@@ -243,14 +302,26 @@ UMat Mat::getUMat(int accessFlags, UMatUsageFlags usageFlags) const
|
||||
}
|
||||
if (!allocated)
|
||||
{
|
||||
allocated = getStdAllocator()->allocate(temp_u, accessFlags, usageFlags);
|
||||
allocated = getStdAllocator()->allocate(new_u, accessFlags, usageFlags);
|
||||
CV_Assert(allocated);
|
||||
}
|
||||
if (u != NULL)
|
||||
{
|
||||
#ifdef HAVE_OPENCL
|
||||
if (ocl::useOpenCL() && new_u->currAllocator == ocl::getOpenCLAllocator())
|
||||
{
|
||||
CV_Assert(new_u->tempUMat());
|
||||
}
|
||||
#endif
|
||||
new_u->originalUMatData = u;
|
||||
CV_XADD(&(u->refcount), 1);
|
||||
CV_XADD(&(u->urefcount), 1);
|
||||
}
|
||||
hdr.flags = flags;
|
||||
setSize(hdr, dims, size.p, step.p);
|
||||
finalizeHdr(hdr);
|
||||
hdr.u = temp_u;
|
||||
hdr.offset = data - datastart;
|
||||
hdr.u = new_u;
|
||||
hdr.offset = 0; //data - datastart;
|
||||
hdr.addref();
|
||||
return hdr;
|
||||
}
|
||||
@@ -639,7 +710,6 @@ Mat UMat::getMat(int accessFlags) const
|
||||
{
|
||||
if(!u)
|
||||
return Mat();
|
||||
CV_Assert(!u->tempUMat() && "Don't get Mat from temp UMat! Use copyTo().");
|
||||
// TODO Support ACCESS_READ (ACCESS_WRITE) without unnecessary data transfers
|
||||
accessFlags |= ACCESS_RW;
|
||||
UMatDataAutoLock autolock(u);
|
||||
@@ -668,10 +738,10 @@ void* UMat::handle(int accessFlags) const
|
||||
if( !u )
|
||||
return 0;
|
||||
|
||||
// check flags: if CPU copy is newer, copy it back to GPU.
|
||||
if( u->deviceCopyObsolete() )
|
||||
CV_Assert(u->refcount == 0);
|
||||
CV_Assert(!u->deviceCopyObsolete() || u->copyOnMap());
|
||||
if (u->deviceCopyObsolete())
|
||||
{
|
||||
CV_Assert(u->refcount == 0 || u->origdata);
|
||||
u->currAllocator->unmap(u);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user