Browse Source

Switch to the new job manager which is faster for more simple tasks

Panagiotis Christopoulos Charitos 2 years ago
parent
commit
acec49bf01

+ 2 - 0
AnKi/Core/App.cpp

@@ -156,6 +156,7 @@ void App::cleanup()
 	GpuSceneBuffer::freeSingleton();
 	GpuReadbackMemoryPool::freeSingleton();
 	CoreThreadHive::freeSingleton();
+	CoreThreadJobManager::freeSingleton();
 	MaliHwCounters::freeSingleton();
 	GrManager::freeSingleton();
 	Input::freeSingleton();
@@ -282,6 +283,7 @@ Error App::initInternal()
 	//
 	const Bool pinThreads = !ANKI_OS_ANDROID;
 	CoreThreadHive::allocateSingleton(g_jobThreadCountCVar.get(), pinThreads);
+	CoreThreadJobManager::allocateSingleton(g_jobThreadCountCVar.get(), pinThreads);
 
 	//
 	// Graphics API

+ 13 - 0
AnKi/Core/Common.h

@@ -10,6 +10,7 @@
 #include <AnKi/Util/MemoryPool.h>
 #include <AnKi/Util/DynamicArray.h>
 #include <AnKi/Util/ThreadHive.h>
+#include <AnKi/Util/ThreadJobManager.h>
 
 namespace anki {
 
@@ -44,6 +45,18 @@ public:
 	}
 };
 
+class CoreThreadJobManager : public ThreadJobManager, public MakeSingleton<CoreThreadJobManager>
+{
+	template<typename>
+	friend class MakeSingleton;
+
+public:
+	CoreThreadJobManager(U32 threadCount, Bool pinToCores = false)
+		: ThreadJobManager(threadCount, pinToCores)
+	{
+	}
+};
+
 class GlobalFrameIndex : public MakeSingleton<GlobalFrameIndex>
 {
 public:

+ 18 - 27
AnKi/Gr/RenderGraph.cpp

@@ -1251,28 +1251,6 @@ void RenderGraph::runSecondLevel()
 	ANKI_ASSERT(m_ctx);
 
 	StackMemoryPool& pool = *m_ctx->m_rts.getMemoryPool().m_pool;
-	DynamicArray<ThreadHiveTask, MemoryPoolPtrWrapper<StackMemoryPool>> tasks(&pool);
-
-	auto callback = [](void* userData, [[maybe_unused]] U32 threadId, [[maybe_unused]] ThreadHive& hive,
-					   [[maybe_unused]] ThreadHiveSemaphore* signalSemaphore) {
-		RenderPassWorkContext& self = *static_cast<RenderPassWorkContext*>(userData);
-
-		ANKI_TRACE_SCOPED_EVENT(GrExecuteSecondaryCmdb);
-
-		// Create the command buffer in the thread
-		Pass& pass = self.m_rgraph->m_ctx->m_passes[self.m_passIdx];
-		ANKI_ASSERT(!pass.m_secondLevelCmdbs[self.m_currentSecondLevelCommandBufferIndex].isCreated());
-		pass.m_secondLevelCmdbs[self.m_currentSecondLevelCommandBufferIndex] =
-			GrManager::getSingleton().newCommandBuffer(pass.m_secondLevelCmdbInitInfo);
-		self.m_commandBuffer = pass.m_secondLevelCmdbs[self.m_currentSecondLevelCommandBufferIndex].get();
-
-		{
-			ANKI_TRACE_SCOPED_EVENT(GrRenderGraphCallback);
-			pass.m_callback(self);
-		}
-
-		self.m_commandBuffer->flush();
-	};
 
 	// Gather the tasks
 	for(Pass& pass : m_ctx->m_passes)
@@ -1286,14 +1264,27 @@ void RenderGraph::runSecondLevel()
 			ctx->m_passIdx = U32(&pass - &m_ctx->m_passes[0]);
 			ctx->m_batchIdx = pass.m_batchIdx;
 
-			ThreadHiveTask& task = *tasks.emplaceBack();
-			task.m_callback = callback;
-			task.m_argument = ctx;
+			CoreThreadJobManager::getSingleton().dispatchTask([ctx]([[maybe_unused]] U32 tid) {
+				ANKI_TRACE_SCOPED_EVENT(GrExecuteSecondaryCmdb);
+
+				// Create the command buffer in the thread
+				Pass& pass = ctx->m_rgraph->m_ctx->m_passes[ctx->m_passIdx];
+				ANKI_ASSERT(!pass.m_secondLevelCmdbs[ctx->m_currentSecondLevelCommandBufferIndex].isCreated());
+				pass.m_secondLevelCmdbs[ctx->m_currentSecondLevelCommandBufferIndex] =
+					GrManager::getSingleton().newCommandBuffer(pass.m_secondLevelCmdbInitInfo);
+				ctx->m_commandBuffer = pass.m_secondLevelCmdbs[ctx->m_currentSecondLevelCommandBufferIndex].get();
+
+				{
+					ANKI_TRACE_SCOPED_EVENT(GrRenderGraphCallback);
+					pass.m_callback(*ctx);
+				}
+
+				ctx->m_commandBuffer->flush();
+			});
 		}
 	}
 
-	CoreThreadHive::getSingleton().submitTasks(tasks.getBegin(), tasks.getSize());
-	CoreThreadHive::getSingleton().waitAllTasks();
+	CoreThreadJobManager::getSingleton().waitForAllTasksToFinish();
 }
 
 void RenderGraph::run() const

+ 0 - 16
AnKi/Renderer/RendererObject.cpp

@@ -16,22 +16,6 @@ Renderer& RendererObject::getRenderer()
 	return MainRenderer::getSingleton().getOffscreenRenderer();
 }
 
-U32 RendererObject::computeNumberOfSecondLevelCommandBuffers(U32 drawcallCount) const
-{
-	const U32 drawcallsPerThread = drawcallCount / CoreThreadHive::getSingleton().getThreadCount();
-	U32 secondLevelCmdbCount;
-	if(drawcallsPerThread < kMinDrawcallsPerSecondaryCommandBuffer)
-	{
-		secondLevelCmdbCount = max(1u, drawcallCount / kMinDrawcallsPerSecondaryCommandBuffer);
-	}
-	else
-	{
-		secondLevelCmdbCount = CoreThreadHive::getSingleton().getThreadCount();
-	}
-
-	return secondLevelCmdbCount;
-}
-
 void RendererObject::registerDebugRenderTarget(CString rtName)
 {
 	getRenderer().registerDebugRenderTarget(this, rtName);

+ 0 - 2
AnKi/Renderer/RendererObject.h

@@ -38,8 +38,6 @@ public:
 protected:
 	static ANKI_PURE Renderer& getRenderer();
 
-	U32 computeNumberOfSecondLevelCommandBuffers(U32 drawcallCount) const;
-
 	/// Used in fullscreen quad draws.
 	static void drawQuad(CommandBuffer& cmdb)
 	{

+ 20 - 19
AnKi/Renderer/ShadowMapping.cpp

@@ -577,33 +577,34 @@ void ShadowMapping::runShadowMapping(RenderPassWorkContext& rgraphCtx)
 
 	CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
 
-	cmdb.setPolygonOffset(kShadowsPolygonOffsetFactor, kShadowsPolygonOffsetUnits);
+	// Clear the depth buffer
+	cmdb.bindShaderProgram(m_clearDepthGrProg.get());
+	cmdb.setDepthCompareOperation(CompareOperation::kAlways);
 
 	for(ViewportWorkItem& work : m_runCtx.m_workItems)
 	{
-		// Set state
 		cmdb.setViewport(work.m_viewport[0], work.m_viewport[1], work.m_viewport[2], work.m_viewport[3]);
-		cmdb.setScissor(work.m_viewport[0], work.m_viewport[1], work.m_viewport[2], work.m_viewport[3]);
 
-		// Clear the depth buffer
+		if(work.m_clearTileIndirectArgs.m_buffer)
+		{
+			cmdb.drawIndirect(PrimitiveTopology::kTriangles, 1, work.m_clearTileIndirectArgs.m_offset, work.m_clearTileIndirectArgs.m_buffer);
+		}
+		else
 		{
-			cmdb.bindShaderProgram(m_clearDepthGrProg.get());
-			cmdb.setDepthCompareOperation(CompareOperation::kAlways);
-			cmdb.setPolygonOffset(0.0f, 0.0f);
+			cmdb.draw(PrimitiveTopology::kTriangles, 3, 1);
+		}
+	}
 
-			if(work.m_clearTileIndirectArgs.m_buffer)
-			{
-				cmdb.drawIndirect(PrimitiveTopology::kTriangles, 1, work.m_clearTileIndirectArgs.m_offset, work.m_clearTileIndirectArgs.m_buffer);
-			}
-			else
-			{
-				cmdb.draw(PrimitiveTopology::kTriangles, 3, 1);
-			}
+	// Restore state
+	cmdb.setDepthCompareOperation(CompareOperation::kLess);
 
-			// Restore state
-			cmdb.setDepthCompareOperation(CompareOperation::kLess);
-			cmdb.setPolygonOffset(kShadowsPolygonOffsetFactor, kShadowsPolygonOffsetUnits);
-		}
+	// Draw to tiles
+	cmdb.setPolygonOffset(kShadowsPolygonOffsetFactor, kShadowsPolygonOffsetUnits);
+	for(ViewportWorkItem& work : m_runCtx.m_workItems)
+	{
+		// Set state
+		cmdb.setViewport(work.m_viewport[0], work.m_viewport[1], work.m_viewport[2], work.m_viewport[3]);
+		cmdb.setScissor(work.m_viewport[0], work.m_viewport[1], work.m_viewport[2], work.m_viewport[3]);
 
 		RenderableDrawerArguments args;
 		args.m_renderingTechinuqe = RenderingTechnique::kDepth;

+ 7 - 15
AnKi/Scene/SceneGraph.cpp

@@ -75,8 +75,6 @@ constexpr U32 kUpdateNodeBatchSize = 10;
 class SceneGraph::UpdateSceneNodesCtx
 {
 public:
-	SceneGraph* m_scene = nullptr;
-
 	IntrusiveList<SceneNode>::Iterator m_crntNode;
 	SpinLock m_crntNodeLock;
 
@@ -250,28 +248,22 @@ Error SceneGraph::update(Second prevUpdateTime, Second crntTime)
 		ANKI_TRACE_SCOPED_EVENT(SceneNodesUpdate);
 		ANKI_CHECK(m_events.updateAllEvents(prevUpdateTime, crntTime));
 
-		// Then the rest
-		Array<ThreadHiveTask, ThreadHive::kMaxThreads> tasks;
 		UpdateSceneNodesCtx updateCtx;
-		updateCtx.m_scene = this;
 		updateCtx.m_crntNode = m_nodes.getBegin();
 		updateCtx.m_prevUpdateTime = prevUpdateTime;
 		updateCtx.m_crntTime = crntTime;
 
-		for(U i = 0; i < CoreThreadHive::getSingleton().getThreadCount(); i++)
+		for(U i = 0; i < CoreThreadJobManager::getSingleton().getThreadCount(); i++)
 		{
-			tasks[i] = ANKI_THREAD_HIVE_TASK(
+			CoreThreadJobManager::getSingleton().dispatchTask([this, &updateCtx]([[maybe_unused]] U32 tid) {
+				if(updateNodes(updateCtx))
 				{
-					if(self->m_scene->updateNodes(*self))
-					{
-						ANKI_SCENE_LOGF("Will not recover");
-					}
-				},
-				&updateCtx, nullptr, nullptr);
+					ANKI_SCENE_LOGF("Will not recover");
+				}
+			});
 		}
 
-		CoreThreadHive::getSingleton().submitTasks(&tasks[0], CoreThreadHive::getSingleton().getThreadCount());
-		CoreThreadHive::getSingleton().waitAllTasks();
+		CoreThreadJobManager::getSingleton().waitForAllTasksToFinish();
 	}
 
 #define ANKI_CAT_TYPE(arrayName, gpuSceneType, id, cvarName) GpuSceneArrays::arrayName::getSingleton().flush();

+ 5 - 0
AnKi/Util/ThreadJobManager.h

@@ -53,6 +53,11 @@ public:
 		}
 	}
 
+	U32 getThreadCount() const
+	{
+		return m_threads.getSize();
+	}
+
 private:
 	class WorkerThread;