Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2012-09-03 16:52:21 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2012-09-03 16:52:21 +0400
commitd6ec4b874b99f096ce2aa1c2864609bb2e4b58ad (patch)
treeee1a946ec1c16be728dfe121d66777f53e87c0f3 /source/blender
parent9fbc1c31496f2ac3d8a7e71ef84cd91353c6c7fb (diff)
Compositor: initialize OpenCL only when the option is enabled. This eliminates
error prints or even crashes for poor OpenCL implementations when not using it.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/compositor/intern/COM_WorkScheduler.cpp143
-rw-r--r--source/blender/compositor/intern/COM_WorkScheduler.h4
-rw-r--r--source/blender/compositor/intern/COM_compositor.cpp20
3 files changed, 107 insertions, 60 deletions
diff --git a/source/blender/compositor/intern/COM_WorkScheduler.cpp b/source/blender/compositor/intern/COM_WorkScheduler.cpp
index 5f133fe071f..f9af23faea8 100644
--- a/source/blender/compositor/intern/COM_WorkScheduler.cpp
+++ b/source/blender/compositor/intern/COM_WorkScheduler.cpp
@@ -54,6 +54,7 @@ static vector<CPUDevice *> g_cpudevices;
#if COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE
/// @brief list of all thread for every CPUDevice in cpudevices a thread exists
static ListBase g_cputhreads;
+static bool g_cpuInitialized = false;
/// @brief all scheduled work for the cpu
static ThreadQueue *g_cpuqueue;
static ThreadQueue *g_gpuqueue;
@@ -67,11 +68,13 @@ static ListBase g_gputhreads;
/// @brief all scheduled work for the gpu
#ifdef COM_OPENCL_ENABLED
static bool g_openclActive = false;
+static bool g_openclInitialized = false;
#endif
#endif
#endif
#define MAX_HIGHLIGHT 8
+static bool g_highlightInitialized = false;
extern "C" {
int g_highlightIndex;
void **g_highlightedNodes;
@@ -255,40 +258,59 @@ extern void clContextError(const char *errinfo, const void *private_info, size_t
printf("OPENCL error: %s\n", errinfo);
}
-void WorkScheduler::initialize()
+void WorkScheduler::initialize(bool use_opencl)
{
- if (g_highlightedNodesRead) MEM_freeN(g_highlightedNodesRead);
- if (g_highlightedNodes) MEM_freeN(g_highlightedNodes);
+ /* initialize highlighting */
+ if (!g_highlightInitialized) {
+ if (g_highlightedNodesRead) MEM_freeN(g_highlightedNodesRead);
+ if (g_highlightedNodes) MEM_freeN(g_highlightedNodes);
- g_highlightedNodesRead = NULL;
- g_highlightedNodes = NULL;
+ g_highlightedNodesRead = NULL;
+ g_highlightedNodes = NULL;
+
+ COM_startReadHighlights();
+
+ g_highlightInitialized = true;
+ }
- COM_startReadHighlights();
#if COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE
- int numberOfCPUThreads = BLI_system_thread_count();
+ /* initialize CPU threads */
+ if (!g_cpuInitialized) {
+ int numberOfCPUThreads = BLI_system_thread_count();
- for (int index = 0; index < numberOfCPUThreads; index++) {
- CPUDevice *device = new CPUDevice();
- device->initialize();
- g_cpudevices.push_back(device);
+ for (int index = 0; index < numberOfCPUThreads; index++) {
+ CPUDevice *device = new CPUDevice();
+ device->initialize();
+ g_cpudevices.push_back(device);
+ }
+
+ g_cpuInitialized = true;
}
+
#ifdef COM_OPENCL_ENABLED
- g_context = NULL;
- g_program = NULL;
- if (clCreateContextFromType) {
- cl_uint numberOfPlatforms = 0;
- cl_int error;
- error = clGetPlatformIDs(0, 0, &numberOfPlatforms);
- if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); }
- if (G.f & G_DEBUG) printf("%d number of platforms\n", numberOfPlatforms);
- cl_platform_id *platforms = (cl_platform_id *)MEM_mallocN(sizeof(cl_platform_id) * numberOfPlatforms, __func__);
- error = clGetPlatformIDs(numberOfPlatforms, platforms, 0);
- unsigned int indexPlatform;
- for (indexPlatform = 0; indexPlatform < numberOfPlatforms; indexPlatform++) {
- cl_platform_id platform = platforms[indexPlatform];
- cl_uint numberOfDevices = 0;
- clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 0, 0, &numberOfDevices);
- if (numberOfDevices > 0) {
+ /* deinitialize OpenCL GPU's */
+ if (use_opencl && !g_openclInitialized) {
+ g_context = NULL;
+ g_program = NULL;
+
+ OCL_init(); /* this will check and skip if already initialized */
+
+ if (clCreateContextFromType) {
+ cl_uint numberOfPlatforms = 0;
+ cl_int error;
+ error = clGetPlatformIDs(0, 0, &numberOfPlatforms);
+ if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); }
+ if (G.f & G_DEBUG) printf("%d number of platforms\n", numberOfPlatforms);
+ cl_platform_id *platforms = (cl_platform_id *)MEM_mallocN(sizeof(cl_platform_id) * numberOfPlatforms, __func__);
+ error = clGetPlatformIDs(numberOfPlatforms, platforms, 0);
+ unsigned int indexPlatform;
+ for (indexPlatform = 0; indexPlatform < numberOfPlatforms; indexPlatform++) {
+ cl_platform_id platform = platforms[indexPlatform];
+ cl_uint numberOfDevices = 0;
+ clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 0, 0, &numberOfDevices);
+ if (numberOfDevices <= 0)
+ continue;
+
cl_device_id *cldevices = (cl_device_id *)MEM_mallocN(sizeof(cl_device_id) * numberOfDevices, __func__);
clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, numberOfDevices, cldevices, 0);
@@ -324,8 +346,10 @@ void WorkScheduler::initialize()
}
MEM_freeN(cldevices);
}
+ MEM_freeN(platforms);
}
- MEM_freeN(platforms);
+
+ g_openclInitialized = true;
}
#endif
#endif
@@ -334,37 +358,52 @@ void WorkScheduler::initialize()
void WorkScheduler::deinitialize()
{
#if COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE
- Device *device;
- while (g_cpudevices.size() > 0) {
- device = g_cpudevices.back();
- g_cpudevices.pop_back();
- device->deinitialize();
- delete device;
+ /* deinitialize CPU threads */
+ if (g_cpuInitialized) {
+ Device *device;
+ while (g_cpudevices.size() > 0) {
+ device = g_cpudevices.back();
+ g_cpudevices.pop_back();
+ device->deinitialize();
+ delete device;
+ }
+
+ g_cpuInitialized = false;
}
+
#ifdef COM_OPENCL_ENABLED
- while (g_gpudevices.size() > 0) {
- device = g_gpudevices.back();
- g_gpudevices.pop_back();
- device->deinitialize();
- delete device;
- }
- if (g_program) {
- clReleaseProgram(g_program);
- g_program = NULL;
- }
- if (g_context) {
- clReleaseContext(g_context);
- g_context = NULL;
+ /* deinitialize OpenCL GPU's */
+ if (g_openclInitialized) {
+ Device *device;
+ while (g_gpudevices.size() > 0) {
+ device = g_gpudevices.back();
+ g_gpudevices.pop_back();
+ device->deinitialize();
+ delete device;
+ }
+ if (g_program) {
+ clReleaseProgram(g_program);
+ g_program = NULL;
+ }
+ if (g_context) {
+ clReleaseContext(g_context);
+ g_context = NULL;
+ }
+
+ g_openclInitialized = false;
}
#endif
#endif
- if (g_highlightedNodes) {
- MEM_freeN(g_highlightedNodes);
- }
+ /* deinitialize highlighting */
+ if (g_highlightInitialized) {
+ if (g_highlightedNodes)
+ MEM_freeN(g_highlightedNodes);
- if (g_highlightedNodesRead) {
- MEM_freeN(g_highlightedNodesRead);
+ if (g_highlightedNodesRead)
+ MEM_freeN(g_highlightedNodesRead);
+
+ g_highlightInitialized = false;
}
}
diff --git a/source/blender/compositor/intern/COM_WorkScheduler.h b/source/blender/compositor/intern/COM_WorkScheduler.h
index f56fe94201e..4ab23cf9ae4 100644
--- a/source/blender/compositor/intern/COM_WorkScheduler.h
+++ b/source/blender/compositor/intern/COM_WorkScheduler.h
@@ -74,8 +74,10 @@ public:
* After mutex initialization the system is queried in order to count the number of CPUDevices and GPUDevices to be created.
* For every hardware thread a CPUDevice and for every OpenCL GPU device a OpenCLDevice is created.
* these devices are stored in a separate list (cpudevices & gpudevices)
+ *
+ * This function can be called multiple times to lazily initialize OpenCL.
*/
- static void initialize();
+ static void initialize(bool use_opencl);
/**
* @brief deinitialize the WorkScheduler
diff --git a/source/blender/compositor/intern/COM_compositor.cpp b/source/blender/compositor/intern/COM_compositor.cpp
index 7dcb3572a14..daf48d65caf 100644
--- a/source/blender/compositor/intern/COM_compositor.cpp
+++ b/source/blender/compositor/intern/COM_compositor.cpp
@@ -36,24 +36,29 @@ extern "C" {
static ThreadMutex s_compositorMutex;
static char is_compositorMutex_init = FALSE;
+
void COM_execute(RenderData *rd, bNodeTree *editingtree, int rendering)
{
- if (is_compositorMutex_init == FALSE) { /// TODO: move to blender startup phase
- memset(&s_compositorMutex, 0, sizeof(s_compositorMutex));
+ /* initialize mutex, TODO this mutex init is actually not thread safe and
+ * should be done somewhere as part of blender startup, all the other
+ * initializations can be done lazily */
+ if (is_compositorMutex_init == FALSE) {
BLI_mutex_init(&s_compositorMutex);
- OCL_init();
- WorkScheduler::initialize(); ///TODO: call workscheduler.deinitialize somewhere
is_compositorMutex_init = TRUE;
}
+
BLI_mutex_lock(&s_compositorMutex);
+
if (editingtree->test_break(editingtree->tbh)) {
// during editing multiple calls to this method can be triggered.
// make sure one the last one will be doing the work.
BLI_mutex_unlock(&s_compositorMutex);
return;
-
}
+ /* initialize workscheduler, will check if already done. TODO deinitialize somewhere */
+ bool use_opencl = (editingtree->flag & NTREE_COM_OPENCL);
+ WorkScheduler::initialize(use_opencl);
/* set progress bar to 0% and status to init compositing */
editingtree->progress(editingtree->prh, 0.0);
@@ -83,11 +88,12 @@ void COM_execute(RenderData *rd, bNodeTree *editingtree, int rendering)
void COM_deinitialize()
{
- if (is_compositorMutex_init)
- {
+ if (is_compositorMutex_init) {
BLI_mutex_lock(&s_compositorMutex);
+
deintializeDistortionCache();
WorkScheduler::deinitialize();
+
is_compositorMutex_init = FALSE;
BLI_mutex_unlock(&s_compositorMutex);
BLI_mutex_end(&s_compositorMutex);