Bläddra i källkod

Parellel sorting

Panagiotis Christopoulos Charitos 13 år sedan
förälder
incheckning
9dc5a20d0f
3 ändrade filer med 54 tillägg och 50 borttagningar
  1. 6 3
      include/anki/core/ThreadPool.h
  2. 1 3
      include/anki/scene/VisibilityTester.h
  3. 47 44
      src/scene/VisibilityTester.cpp

+ 6 - 3
include/anki/core/ThreadPool.h

@@ -32,10 +32,13 @@ struct ThreadJob
 };
 
 /// A dummy job
-struct ThreadJobDummy
+struct ThreadJobDummy: ThreadJob
 {
-	void operator()()
-	{}
+	void operator()(U threadId, U threadsCount)
+	{
+		(void)threadId;
+		(void)threadsCount;
+	}
 };
 
 /// The thread that executes a ThreadJobCallback

+ 1 - 3
include/anki/scene/VisibilityTester.h

@@ -23,6 +23,7 @@ class VisibilityInfo
 	friend class VisibilityTester;
 	friend class Octree;
 	friend struct VisibilityTestJob;
+	friend struct DistanceSortJob;
 
 public:
 	typedef Vector<SceneNode*> Renderables;
@@ -70,9 +71,6 @@ public:
 	/// - Gets the visible renderables and frustumables
 	/// - For every frustumable perform tests
 	static void test(Frustumable& ref, Scene& scene, Renderer& r);
-
-private:
-	static void testLight(Light& light, Scene& scene);
 };
 /// @}
 

+ 47 - 44
src/scene/VisibilityTester.cpp

@@ -177,6 +177,33 @@ struct VisibilityTestJob: ThreadJob
 	}
 };
 
+//==============================================================================
+struct DistanceSortJob: ThreadJob
+{
+	U nodesCount;
+	VisibilityInfo::Renderables::iterator nodes;
+	Vec3 origin;
+
+	void operator()(U threadId, U threadsCount)
+	{
+		DistanceSortFunctor comp;
+		comp.origin = origin;
+		std::sort(nodes, nodes + nodesCount, comp);
+	}
+};
+
+//==============================================================================
+struct MaterialSortJob: ThreadJob
+{
+	U nodesCount;
+	VisibilityInfo::Renderables::iterator nodes;
+
+	void operator()(U threadId, U threadsCount)
+	{
+		std::sort(nodes, nodes + nodesCount, MaterialSortFunctor());
+	}
+};
+
 //==============================================================================
 VisibilityTester::~VisibilityTester()
 {}
@@ -207,55 +234,31 @@ void VisibilityTester::test(Frustumable& ref, Scene& scene, Renderer& r)
 
 	threadPool.waitForAllJobsToFinish();
 
-	DistanceSortFunctor comp;
-	comp.origin =
-		ref.getSceneNode().getMovable()->getWorldTransform().getOrigin();
-	std::sort(vinfo.lights.begin(), vinfo.lights.end(), comp);
+	// Sort
+	//
 
-	std::sort(vinfo.renderables.begin(), vinfo.renderables.end(), 
-		MaterialSortFunctor());
-}
+	// First renderables
+	MaterialSortJob msjob;
+	msjob.nodes = vinfo.renderables.begin();
+	msjob.nodesCount = vinfo.renderables.size();
+	threadPool.assignNewJob(1, &msjob);
 
-//==============================================================================
-void VisibilityTester::testLight(Light& light, Scene& scene)
-{
-	Frustumable& ref = *light.getFrustumable();
-	ANKI_ASSERT(&ref != nullptr);
-
-	VisibilityInfo& vinfo = ref.getVisibilityInfo();
-	vinfo.renderables.clear();
-	vinfo.lights.clear();
+	// Then lights
+	DistanceSortJob dsjob;
+	dsjob.nodes = vinfo.lights.begin();
+	dsjob.nodesCount = vinfo.lights.size();
+	dsjob.origin =
+		ref.getSceneNode().getMovable()->getWorldTransform().getOrigin();
+	threadPool.assignNewJob(0, &dsjob);
 
-	for(auto it = scene.getAllNodesBegin(); it != scene.getAllNodesEnd(); it++)
+	// The rest of the jobs are dummy
+	ThreadJobDummy dummyjobs[ThreadPool::MAX_THREADS];
+	for(U i = 2; i < threadPool.getThreadsCount(); i++)
 	{
-		SceneNode* node = *it;
-
-		Frustumable* fr = node->getFrustumable();
-		// Wont check the same
-		if(&ref == fr)
-		{
-			continue;
-		}
-
-		Spatial* sp = node->getSpatial();
-		if(!sp)
-		{
-			continue;
-		}
-
-		if(!ref.insideFrustum(*sp))
-		{
-			continue;
-		}
-
-		sp->enableFlag(Spatial::SF_VISIBLE);
-
-		Renderable* r = node->getRenderable();
-		if(r)
-		{
-			vinfo.renderables.push_back(node);
-		}
+		threadPool.assignNewJob(i, &dummyjobs[i - 2]);
 	}
+
+	threadPool.waitForAllJobsToFinish();
 }
 
 } // end namespace anki