Commit 740b1f23 authored by Alexander Alekhin's avatar Alexander Alekhin

ocl: implemented per-thread OpenCL command queue

parent a118577a
...@@ -57,6 +57,10 @@ ...@@ -57,6 +57,10 @@
namespace cv { namespace cv {
namespace ocl { namespace ocl {
#if defined(WIN32)
static bool __termination = false;
#endif
struct __Module struct __Module
{ {
__Module(); __Module();
...@@ -494,6 +498,38 @@ PlatformInfo::PlatformInfo() ...@@ -494,6 +498,38 @@ PlatformInfo::PlatformInfo()
// nothing // nothing
} }
class ContextImpl;
struct CommandQueue
{
ContextImpl* context_;
cl_command_queue clQueue_;
CommandQueue() : context_(NULL), clQueue_(NULL) { }
~CommandQueue() { release(); }
void create(ContextImpl* context_);
void release()
{
#ifdef WIN32
// if process is on termination stage (ExitProcess was called and other threads were terminated)
// then disable command queue release because it may cause program hang
if (!__termination)
#endif
{
if(clQueue_)
{
openCLSafeCall(clReleaseCommandQueue(clQueue_)); // some cleanup problems are here
}
}
clQueue_ = NULL;
context_ = NULL;
}
};
cv::TLSData<CommandQueue> commandQueueTLSData;
//////////////////////////////// OpenCL context //////////////////////// //////////////////////////////// OpenCL context ////////////////////////
//This is a global singleton class used to represent a OpenCL context. //This is a global singleton class used to represent a OpenCL context.
class ContextImpl : public Context class ContextImpl : public Context
...@@ -501,12 +537,11 @@ class ContextImpl : public Context ...@@ -501,12 +537,11 @@ class ContextImpl : public Context
public: public:
const cl_device_id clDeviceID; const cl_device_id clDeviceID;
cl_context clContext; cl_context clContext;
cl_command_queue clCmdQueue;
const DeviceInfo& deviceInfo; const DeviceInfo& deviceInfo;
protected: protected:
ContextImpl(const DeviceInfo& deviceInfo, cl_device_id clDeviceID) ContextImpl(const DeviceInfo& deviceInfo, cl_device_id clDeviceID)
: clDeviceID(clDeviceID), clContext(NULL), clCmdQueue(NULL), deviceInfo(deviceInfo) : clDeviceID(clDeviceID), clContext(NULL), deviceInfo(deviceInfo)
{ {
// nothing // nothing
} }
...@@ -581,7 +616,13 @@ const void* Context::getOpenCLContextPtr() const ...@@ -581,7 +616,13 @@ const void* Context::getOpenCLContextPtr() const
const void* Context::getOpenCLCommandQueuePtr() const const void* Context::getOpenCLCommandQueuePtr() const
{ {
return &(((ContextImpl*)this)->clCmdQueue); ContextImpl* pThis = (ContextImpl*)this;
CommandQueue* commandQueue = commandQueueTLSData.get();
if (commandQueue->context_ != pThis)
{
commandQueue->create(pThis);
}
return &commandQueue->clQueue_;
} }
const void* Context::getOpenCLDeviceIDPtr() const const void* Context::getOpenCLDeviceIDPtr() const
...@@ -607,10 +648,6 @@ bool ContextImpl::supportsFeature(FEATURE_TYPE featureType) const ...@@ -607,10 +648,6 @@ bool ContextImpl::supportsFeature(FEATURE_TYPE featureType) const
return false; return false;
} }
#if defined(WIN32)
static bool __termination = false;
#endif
ContextImpl::~ContextImpl() ContextImpl::~ContextImpl()
{ {
#ifdef WIN32 #ifdef WIN32
...@@ -619,17 +656,11 @@ ContextImpl::~ContextImpl() ...@@ -619,17 +656,11 @@ ContextImpl::~ContextImpl()
if (!__termination) if (!__termination)
#endif #endif
{ {
if(clCmdQueue)
{
openCLSafeCall(clReleaseCommandQueue(clCmdQueue)); // some cleanup problems are here
}
if(clContext) if(clContext)
{ {
openCLSafeCall(clReleaseContext(clContext)); openCLSafeCall(clReleaseContext(clContext));
} }
} }
clCmdQueue = NULL;
clContext = NULL; clContext = NULL;
} }
...@@ -667,12 +698,8 @@ void ContextImpl::setContext(const DeviceInfo* deviceInfo) ...@@ -667,12 +698,8 @@ void ContextImpl::setContext(const DeviceInfo* deviceInfo)
cl_context_properties cps[3] = { CL_CONTEXT_PLATFORM, (cl_context_properties)(infoImpl.platform_id), 0 }; cl_context_properties cps[3] = { CL_CONTEXT_PLATFORM, (cl_context_properties)(infoImpl.platform_id), 0 };
cl_context clContext = clCreateContext(cps, 1, &infoImpl.device_id, NULL, NULL, &status); cl_context clContext = clCreateContext(cps, 1, &infoImpl.device_id, NULL, NULL, &status);
openCLVerifyCall(status); openCLVerifyCall(status);
// TODO add CL_QUEUE_PROFILING_ENABLE
cl_command_queue clCmdQueue = clCreateCommandQueue(clContext, infoImpl.device_id, 0, &status);
openCLVerifyCall(status);
ContextImpl* ctx = new ContextImpl(infoImpl.info, infoImpl.device_id); ContextImpl* ctx = new ContextImpl(infoImpl.info, infoImpl.device_id);
ctx->clCmdQueue = clCmdQueue;
ctx->clContext = clContext; ctx->clContext = clContext;
ContextImpl* old = NULL; ContextImpl* old = NULL;
...@@ -687,6 +714,17 @@ void ContextImpl::setContext(const DeviceInfo* deviceInfo) ...@@ -687,6 +714,17 @@ void ContextImpl::setContext(const DeviceInfo* deviceInfo)
} }
} }
void CommandQueue::create(ContextImpl* context)
{
release();
cl_int status = 0;
// TODO add CL_QUEUE_PROFILING_ENABLE
cl_command_queue clCmdQueue = clCreateCommandQueue(context->clContext, context->clDeviceID, 0, &status);
openCLVerifyCall(status);
context_ = context;
clQueue_ = clCmdQueue;
}
int getOpenCLPlatforms(PlatformsInfo& platforms) int getOpenCLPlatforms(PlatformsInfo& platforms)
{ {
if (!__initialized) if (!__initialized)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment