Avoid unmap an umat(ocl) which hasn't been mapped at all.
authorZhigang Gong <zhigang.gong@intel.com>
Wed, 9 Jul 2014 08:04:22 +0000 (16:04 +0800)
committerZhigang Gong <zhigang.gong@intel.com>
Wed, 9 Jul 2014 08:21:20 +0000 (16:21 +0800)
According to opencl 1.2 spec 5.4.2:
  enqueues a command to unmap a previously mapped region of a memory object.
  ...
  CL_INVALID_VALUE if mapped_ptr is not a valid pointer returned by
  clEnqueueMapBuffer, or clEnqueueMapImage for memobj.

So if the u->data is not from a clEnqueueMapBuffer call, we should not
call clEnqueueUnmapMemObject() unmap it. With this patch, the cases
./opencv_test_video --gtest_filter=OCL_Video/FarnebackOpticalFlow.Mat/*
could work well with beignet 0.9.1, Otherwise, it will get a
CL_INVALID_VALUE at the clEnqueueUnmapMemObject().

Signed-off-by: Zhigang Gong <zhigang.gong@intel.com>
modules/core/include/opencv2/core/mat.hpp
modules/core/include/opencv2/core/mat.inl.hpp
modules/core/src/ocl.cpp

index d399265..945b450 100644 (file)
@@ -360,7 +360,7 @@ struct CV_EXPORTS UMatData
 {
     enum { COPY_ON_MAP=1, HOST_COPY_OBSOLETE=2,
         DEVICE_COPY_OBSOLETE=4, TEMP_UMAT=8, TEMP_COPIED_UMAT=24,
-        USER_ALLOCATED=32 };
+        USER_ALLOCATED=32, DEVICE_MEM_MAPPED=64};
     UMatData(const MatAllocator* allocator);
     ~UMatData();
 
@@ -370,11 +370,13 @@ struct CV_EXPORTS UMatData
 
     bool hostCopyObsolete() const;
     bool deviceCopyObsolete() const;
+    bool deviceMemMapped() const;
     bool copyOnMap() const;
     bool tempUMat() const;
     bool tempCopiedUMat() const;
     void markHostCopyObsolete(bool flag);
     void markDeviceCopyObsolete(bool flag);
+    void markDeviceMemMapped(bool flag);
 
     const MatAllocator* prevAllocator;
     const MatAllocator* currAllocator;
index d463eec..dae0e13 100644 (file)
@@ -3350,10 +3350,19 @@ size_t UMat::total() const
 
 inline bool UMatData::hostCopyObsolete() const { return (flags & HOST_COPY_OBSOLETE) != 0; }
 inline bool UMatData::deviceCopyObsolete() const { return (flags & DEVICE_COPY_OBSOLETE) != 0; }
+inline bool UMatData::deviceMemMapped() const { return (flags & DEVICE_MEM_MAPPED) != 0; }
 inline bool UMatData::copyOnMap() const { return (flags & COPY_ON_MAP) != 0; }
 inline bool UMatData::tempUMat() const { return (flags & TEMP_UMAT) != 0; }
 inline bool UMatData::tempCopiedUMat() const { return (flags & TEMP_COPIED_UMAT) == TEMP_COPIED_UMAT; }
 
+inline void UMatData::markDeviceMemMapped(bool flag)
+{
+  if(flag)
+    flags |= DEVICE_MEM_MAPPED;
+  else
+    flags &= ~DEVICE_MEM_MAPPED;
+}
+
 inline void UMatData::markHostCopyObsolete(bool flag)
 {
     if(flag)
index ed72ffc..11b5f0c 100644 (file)
@@ -3739,6 +3739,7 @@ public:
                 u->handle = clCreateBuffer(ctx_handle, CL_MEM_COPY_HOST_PTR|CL_MEM_READ_WRITE|createFlags,
                                            u->size, u->origdata, &retval);
                 tempUMatFlags = UMatData::TEMP_COPIED_UMAT;
+
             }
             if(!u->handle || retval != CL_SUCCESS)
                 return false;
@@ -3880,6 +3881,7 @@ public:
                 if(u->data && retval == CL_SUCCESS)
                 {
                     u->markHostCopyObsolete(false);
+                    u->markDeviceMemMapped(true);
                     return;
                 }
 
@@ -3908,6 +3910,7 @@ public:
         if(!u)
             return;
 
+
         CV_Assert(u->handle != 0);
 
         UMatDataAutoLock autolock(u);
@@ -3918,8 +3921,10 @@ public:
 
         cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr();
         cl_int retval = 0;
-        if( !u->copyOnMap() && u->data )
+        if( !u->copyOnMap() && u->deviceMemMapped() )
         {
+            CV_Assert(u->data != NULL);
+            u->markDeviceMemMapped(false);
             CV_Assert( (retval = clEnqueueUnmapMemObject(q,
                                 (cl_mem)u->handle, u->data, 0, 0, 0)) == CL_SUCCESS );
             CV_OclDbgAssert(clFinish(q) == CL_SUCCESS);