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
path: root/source
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2016-03-03 13:59:20 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2016-03-03 14:02:31 +0300
commit8c113a95e3536dfa0be37c9e2e924ea8172bb613 (patch)
treefc71fffa34bc552168f79efccd5bd02b14700556 /source
parentba7eb0c7b9d93987173780d5b819c7f2ec79b96e (diff)
Make texture node threaded
Quite trivial idea -- just pass tread ID to the texture sampling function. Implemented as a TLS to avoid passing huge amount of extra contexts around. Should be working on all platforms, but compilation test is required. Reviewers: juicyfruit, campbellbarton Reviewed By: campbellbarton Differential Revision: https://developer.blender.org/D1831
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/intern/effect.c8
-rw-r--r--source/blender/compositor/intern/COM_CPUDevice.cpp6
-rw-r--r--source/blender/compositor/intern/COM_CPUDevice.h7
-rw-r--r--source/blender/compositor/intern/COM_WorkScheduler.cpp22
-rw-r--r--source/blender/compositor/intern/COM_WorkScheduler.h2
-rw-r--r--source/blender/compositor/operations/COM_TextureOperation.cpp25
-rw-r--r--source/blender/compositor/operations/COM_TextureOperation.h4
-rw-r--r--source/blender/makesrna/intern/rna_texture_api.c2
-rw-r--r--source/blender/render/extern/include/RE_shader_ext.h10
-rw-r--r--source/blender/render/intern/source/render_texture.c23
10 files changed, 81 insertions, 28 deletions
diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c
index 30696012221..12bce70594b 100644
--- a/source/blender/blenkernel/intern/effect.c
+++ b/source/blender/blenkernel/intern/effect.c
@@ -757,7 +757,7 @@ static void do_texture_effector(EffectorCache *eff, EffectorData *efd, EffectedP
scene_color_manage = BKE_scene_check_color_management_enabled(eff->scene);
- hasrgb = multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 0, result, NULL, scene_color_manage, false);
+ hasrgb = multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 0, result, 0, NULL, scene_color_manage, false);
if (hasrgb && mode==PFIELD_TEX_RGB) {
force[0] = (0.5f - result->tr) * strength;
@@ -768,15 +768,15 @@ static void do_texture_effector(EffectorCache *eff, EffectorData *efd, EffectedP
strength/=nabla;
tex_co[0] += nabla;
- multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 0, result+1, NULL, scene_color_manage, false);
+ multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 0, result+1, 0, NULL, scene_color_manage, false);
tex_co[0] -= nabla;
tex_co[1] += nabla;
- multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 0, result+2, NULL, scene_color_manage, false);
+ multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 0, result+2, 0, NULL, scene_color_manage, false);
tex_co[1] -= nabla;
tex_co[2] += nabla;
- multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 0, result+3, NULL, scene_color_manage, false);
+ multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 0, result+3, 0, NULL, scene_color_manage, false);
if (mode == PFIELD_TEX_GRAD || !hasrgb) { /* if we don't have rgb fall back to grad */
/* generate intensity if texture only has rgb value */
diff --git a/source/blender/compositor/intern/COM_CPUDevice.cpp b/source/blender/compositor/intern/COM_CPUDevice.cpp
index c7c3f7769fe..a5824ec5248 100644
--- a/source/blender/compositor/intern/COM_CPUDevice.cpp
+++ b/source/blender/compositor/intern/COM_CPUDevice.cpp
@@ -22,6 +22,12 @@
#include "COM_CPUDevice.h"
+CPUDevice::CPUDevice(int thread_id)
+ : Device(),
+ m_thread_id(thread_id)
+{
+}
+
void CPUDevice::execute(WorkPackage *work)
{
const unsigned int chunkNumber = work->getChunkNumber();
diff --git a/source/blender/compositor/intern/COM_CPUDevice.h b/source/blender/compositor/intern/COM_CPUDevice.h
index 3dc8fff66a3..d12666593d4 100644
--- a/source/blender/compositor/intern/COM_CPUDevice.h
+++ b/source/blender/compositor/intern/COM_CPUDevice.h
@@ -31,11 +31,18 @@
*/
class CPUDevice : public Device {
public:
+ CPUDevice(int thread_id);
+
/**
* @brief execute a WorkPackage
* @param work the WorkPackage to execute
*/
void execute(WorkPackage *work);
+
+ int thread_id() { return m_thread_id; }
+
+protected:
+ int m_thread_id;
};
#endif
diff --git a/source/blender/compositor/intern/COM_WorkScheduler.cpp b/source/blender/compositor/intern/COM_WorkScheduler.cpp
index fc6ea1299cf..4c85f11f655 100644
--- a/source/blender/compositor/intern/COM_WorkScheduler.cpp
+++ b/source/blender/compositor/intern/COM_WorkScheduler.cpp
@@ -50,7 +50,8 @@
/// @brief list of all CPUDevices. for every hardware thread an instance of CPUDevice is created
-static vector<CPUDevice *> g_cpudevices;
+static vector<CPUDevice*> g_cpudevices;
+static ThreadLocal(CPUDevice*) g_thread_device;
#if COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE
/// @brief list of all thread for every CPUDevice in cpudevices a thread exists
@@ -153,9 +154,9 @@ int COM_isHighlightedbNode(bNode *bnode)
#if COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE
void *WorkScheduler::thread_execute_cpu(void *data)
{
- Device *device = (Device *)data;
+ CPUDevice *device = (CPUDevice *)data;
WorkPackage *work;
-
+ BLI_thread_local_set(g_thread_device, device);
while ((work = (WorkPackage *)BLI_thread_queue_pop(g_cpuqueue))) {
HIGHLIGHT(work);
device->execute(work);
@@ -310,18 +311,20 @@ void WorkScheduler::initialize(bool use_opencl, int num_cpu_threads)
device->deinitialize();
delete device;
}
-
+ if (g_cpuInitialized) {
+ BLI_thread_local_delete(g_thread_device);
+ }
g_cpuInitialized = false;
}
/* initialize CPU threads */
if (!g_cpuInitialized) {
for (int index = 0; index < num_cpu_threads; index++) {
- CPUDevice *device = new CPUDevice();
+ CPUDevice *device = new CPUDevice(index);
device->initialize();
g_cpudevices.push_back(device);
}
-
+ BLI_thread_local_create(g_thread_device);
g_cpuInitialized = true;
}
@@ -407,7 +410,7 @@ void WorkScheduler::deinitialize()
device->deinitialize();
delete device;
}
-
+ BLI_thread_local_delete(g_thread_device);
g_cpuInitialized = false;
}
@@ -450,3 +453,8 @@ void WorkScheduler::deinitialize()
}
}
+int WorkScheduler::current_thread_id()
+{
+ CPUDevice *device = (CPUDevice *)BLI_thread_local_get(g_thread_device);
+ return device->thread_id();
+}
diff --git a/source/blender/compositor/intern/COM_WorkScheduler.h b/source/blender/compositor/intern/COM_WorkScheduler.h
index 27afdf6efd0..67d3fc87ce1 100644
--- a/source/blender/compositor/intern/COM_WorkScheduler.h
+++ b/source/blender/compositor/intern/COM_WorkScheduler.h
@@ -113,6 +113,8 @@ public:
*/
static bool hasGPUDevices();
+ static int current_thread_id();
+
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("COM:WorkScheduler")
#endif
diff --git a/source/blender/compositor/operations/COM_TextureOperation.cpp b/source/blender/compositor/operations/COM_TextureOperation.cpp
index 7d1d24a9747..665bffc2c1c 100644
--- a/source/blender/compositor/operations/COM_TextureOperation.cpp
+++ b/source/blender/compositor/operations/COM_TextureOperation.cpp
@@ -21,6 +21,7 @@
*/
#include "COM_TextureOperation.h"
+#include "COM_WorkScheduler.h"
#include "BLI_listbase.h"
#include "BLI_threads.h"
@@ -30,9 +31,7 @@ extern "C" {
#include "BKE_node.h"
}
-static ThreadMutex mutex_lock = BLI_MUTEX_INITIALIZER;
-
-TextureBaseOperation::TextureBaseOperation() : SingleThreadedOperation()
+TextureBaseOperation::TextureBaseOperation() : NodeOperation()
{
this->addInputSocket(COM_DT_VECTOR); //offset
this->addInputSocket(COM_DT_VECTOR); //size
@@ -63,7 +62,7 @@ void TextureBaseOperation::initExecution()
{
ntreeTexBeginExecTree(this->m_texture->nodetree);
}
- SingleThreadedOperation::initExecution();
+ NodeOperation::initExecution();
}
void TextureBaseOperation::deinitExecution()
{
@@ -78,7 +77,7 @@ void TextureBaseOperation::deinitExecution()
{
ntreeTexEndExecTree(this->m_texture->nodetree->execdata);
}
- SingleThreadedOperation::deinitExecution();
+ NodeOperation::deinitExecution();
}
void TextureBaseOperation::determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2])
@@ -121,12 +120,16 @@ void TextureBaseOperation::executePixelSampled(float output[4], float x, float y
vec[1] = textureSize[1] * (v + textureOffset[1]);
vec[2] = textureSize[2] * textureOffset[2];
- /* TODO(sergey): Need to pass thread ID to the multitex code,
- * then we can avoid having mutex here.
- */
- BLI_mutex_lock(&mutex_lock);
- retval = multitex_ext(this->m_texture, vec, NULL, NULL, 0, &texres, m_pool, m_sceneColorManage, false);
- BLI_mutex_unlock(&mutex_lock);
+ const int thread_id = WorkScheduler::current_thread_id();
+ retval = multitex_ext(this->m_texture,
+ vec,
+ NULL, NULL,
+ 0,
+ &texres,
+ thread_id,
+ m_pool,
+ m_sceneColorManage,
+ false);
if (texres.talpha)
output[3] = texres.ta;
diff --git a/source/blender/compositor/operations/COM_TextureOperation.h b/source/blender/compositor/operations/COM_TextureOperation.h
index 47ef40882c5..4cc203b54a2 100644
--- a/source/blender/compositor/operations/COM_TextureOperation.h
+++ b/source/blender/compositor/operations/COM_TextureOperation.h
@@ -24,7 +24,7 @@
#ifndef _COM_TextureOperation_h
#define _COM_TextureOperation_h
-#include "COM_SingleThreadedOperation.h"
+#include "COM_NodeOperation.h"
#include "DNA_texture_types.h"
#include "BLI_listbase.h"
extern "C" {
@@ -39,7 +39,7 @@ extern "C" {
*
* @todo: rename to operation.
*/
-class TextureBaseOperation : public SingleThreadedOperation {
+class TextureBaseOperation : public NodeOperation {
private:
Tex *m_texture;
const RenderData *m_rd;
diff --git a/source/blender/makesrna/intern/rna_texture_api.c b/source/blender/makesrna/intern/rna_texture_api.c
index a27ba6ea06d..ef1ef5e1469 100644
--- a/source/blender/makesrna/intern/rna_texture_api.c
+++ b/source/blender/makesrna/intern/rna_texture_api.c
@@ -74,7 +74,7 @@ static void texture_evaluate(struct Tex *tex, float value[3], float r_color[4])
TexResult texres = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL};
/* TODO(sergey): always use color management now. */
- multitex_ext(tex, value, NULL, NULL, 1, &texres, NULL, true, false);
+ multitex_ext(tex, value, NULL, NULL, 1, &texres, 0, NULL, true, false);
r_color[0] = texres.tr;
r_color[1] = texres.tg;
diff --git a/source/blender/render/extern/include/RE_shader_ext.h b/source/blender/render/extern/include/RE_shader_ext.h
index 2b07ace26db..12b97aedbd3 100644
--- a/source/blender/render/extern/include/RE_shader_ext.h
+++ b/source/blender/render/extern/include/RE_shader_ext.h
@@ -198,7 +198,15 @@ struct ImagePool;
struct Object;
/* this one uses nodes */
-int multitex_ext(struct Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, struct TexResult *texres, struct ImagePool *pool, bool scene_color_manage, const bool skip_load_image);
+int multitex_ext(struct Tex *tex,
+ float texvec[3],
+ float dxt[3], float dyt[3],
+ int osatex,
+ struct TexResult *texres,
+ const short thread,
+ struct ImagePool *pool,
+ bool scene_color_manage,
+ const bool skip_load_image);
/* nodes disabled */
int multitex_ext_safe(struct Tex *tex, float texvec[3], struct TexResult *texres, struct ImagePool *pool, bool scene_color_manage, const bool skip_load_image);
/* only for internal node usage */
diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c
index 172fc999897..193f619c09c 100644
--- a/source/blender/render/intern/source/render_texture.c
+++ b/source/blender/render/intern/source/render_texture.c
@@ -1377,9 +1377,28 @@ static int multitex_mtex(ShadeInput *shi, MTex *mtex, float texvec[3], float dxt
*
* Use it for stuff which is out of render pipeline.
*/
-int multitex_ext(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, TexResult *texres, struct ImagePool *pool, bool scene_color_manage, const bool skip_load_image)
+int multitex_ext(Tex *tex,
+ float texvec[3],
+ float dxt[3], float dyt[3],
+ int osatex,
+ TexResult *texres,
+ const short thread,
+ struct ImagePool *pool,
+ bool scene_color_manage,
+ const bool skip_load_image)
{
- return multitex_nodes_intern(tex, texvec, dxt, dyt, osatex, texres, 0, 0, NULL, NULL, pool, scene_color_manage, skip_load_image, false);
+ return multitex_nodes_intern(tex,
+ texvec,
+ dxt, dyt,
+ osatex,
+ texres,
+ thread,
+ 0,
+ NULL, NULL,
+ pool,
+ scene_color_manage,
+ skip_load_image,
+ false);
}
/* extern-tex doesn't support nodes (ntreeBeginExec() can't be called when rendering is going on)\