[Bf-blender-cvs] [8c113a9] master: Make texture node threaded

Sergey Sharybin noreply at git.blender.org
Thu Mar 3 12:02:49 CET 2016


Commit: 8c113a95e3536dfa0be37c9e2e924ea8172bb613
Author: Sergey Sharybin
Date:   Thu Mar 3 15:59:20 2016 +0500
Branches: master
https://developer.blender.org/rB8c113a95e3536dfa0be37c9e2e924ea8172bb613

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

===================================================================

M	source/blender/blenkernel/intern/effect.c
M	source/blender/compositor/intern/COM_CPUDevice.cpp
M	source/blender/compositor/intern/COM_CPUDevice.h
M	source/blender/compositor/intern/COM_WorkScheduler.cpp
M	source/blender/compositor/intern/COM_WorkScheduler.h
M	source/blender/compositor/operations/COM_TextureOperation.cpp
M	source/blender/compositor/operations/COM_TextureOperation.h
M	source/blender/makesrna/intern/rna_texture_api.c
M	source/blender/render/extern/include/RE_shader_ext.h
M	source/blender/render/intern/source/render_texture.c

===================================================================

diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c
index 3069601..12bce70 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 c7c3f77..a5824ec 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 3dc8fff..d126665 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 fc6ea12..4c85f11 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 27afdf6..67d3fc8 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 7d1d24a..665bffc 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 47ef408..4cc203b 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 a27ba6e..ef1ef5e 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 2b07ace..12b97ae 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/ren

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list