Browse Source

Make a few more classes singletons singletons

Panagiotis Christopoulos Charitos 2 years ago
parent
commit
f1e88fb461
45 changed files with 258 additions and 309 deletions
  1. 13 2
      AnKi/Config.h.cmake
  2. 18 40
      AnKi/Core/App.cpp
  3. 0 15
      AnKi/Core/App.h
  4. 13 0
      AnKi/Core/Common.h
  5. 16 16
      AnKi/Core/GpuMemoryPools.cpp
  6. 34 18
      AnKi/Core/GpuMemoryPools.h
  7. 8 8
      AnKi/Renderer/ClusterBinning.cpp
  8. 0 5
      AnKi/Renderer/Common.h
  9. 11 13
      AnKi/Renderer/Dbg.cpp
  10. 30 24
      AnKi/Renderer/DebugDrawer.cpp
  11. 11 19
      AnKi/Renderer/DebugDrawer.h
  12. 13 14
      AnKi/Renderer/Drawer.cpp
  13. 0 2
      AnKi/Renderer/Drawer.h
  14. 0 2
      AnKi/Renderer/ForwardShading.cpp
  15. 0 2
      AnKi/Renderer/GBuffer.cpp
  16. 1 1
      AnKi/Renderer/GenericCompute.cpp
  17. 0 4
      AnKi/Renderer/IndirectDiffuseProbes.cpp
  18. 3 4
      AnKi/Renderer/MainRenderer.cpp
  19. 3 4
      AnKi/Renderer/PackVisibleClusteredObjects.cpp
  20. 0 4
      AnKi/Renderer/ProbeReflections.cpp
  21. 4 6
      AnKi/Renderer/Renderer.cpp
  22. 5 5
      AnKi/Renderer/RendererObject.cpp
  23. 5 5
      AnKi/Renderer/RtShadows.cpp
  24. 1 3
      AnKi/Renderer/ShadowMapping.cpp
  25. 0 1
      AnKi/Resource/Common.h
  26. 12 13
      AnKi/Resource/MeshResource.cpp
  27. 0 4
      AnKi/Scene/Common.h
  28. 1 2
      AnKi/Scene/Components/DecalComponent.cpp
  29. 1 2
      AnKi/Scene/Components/FogDensityComponent.cpp
  30. 1 2
      AnKi/Scene/Components/GlobalIlluminationProbeComponent.cpp
  31. 2 4
      AnKi/Scene/Components/LightComponent.cpp
  32. 8 13
      AnKi/Scene/Components/ModelComponent.cpp
  33. 3 3
      AnKi/Scene/Components/ParticleEmitterComponent.cpp
  34. 1 2
      AnKi/Scene/Components/ReflectionProbeComponent.cpp
  35. 0 1
      AnKi/Scene/Components/SceneComponent.h
  36. 5 6
      AnKi/Scene/Components/SkinComponent.cpp
  37. 15 16
      AnKi/Scene/ContiguousArrayAllocator.cpp
  38. 3 3
      AnKi/Scene/ContiguousArrayAllocator.h
  39. 3 4
      AnKi/Scene/SceneGraph.cpp
  40. 1 1
      AnKi/Scene/Visibility.cpp
  41. 5 4
      AnKi/Ui/Canvas.cpp
  42. 0 1
      AnKi/Ui/Common.h
  43. 1 1
      AnKi/Util/Singleton.h
  44. 4 5
      Tests/Gr/Gr.cpp
  45. 3 5
      Tests/Ui/Ui.cpp

+ 13 - 2
AnKi/Config.h.cmake

@@ -175,9 +175,9 @@
 #	define ANKI_PREFETCH_MEMORY(addr) __builtin_prefetch(addr)
 #	define ANKI_PREFETCH_MEMORY(addr) __builtin_prefetch(addr)
 #	define ANKI_CHECK_FORMAT(fmtArgIdx, firstArgIdx) __attribute__((format(printf, fmtArgIdx + 1, firstArgIdx + 1))) // On methods you need to include "this"
 #	define ANKI_CHECK_FORMAT(fmtArgIdx, firstArgIdx) __attribute__((format(printf, fmtArgIdx + 1, firstArgIdx + 1))) // On methods you need to include "this"
 #	define ANKI_PURE __attribute__((pure))
 #	define ANKI_PURE __attribute__((pure))
-#else
+#elif ANKI_COMPILER_MSVC
 #	define ANKI_RESTRICT
 #	define ANKI_RESTRICT
-#	define ANKI_FORCE_INLINE
+#	define ANKI_FORCE_INLINE __forceinline
 #	define ANKI_DONT_INLINE
 #	define ANKI_DONT_INLINE
 #	define ANKI_UNUSED
 #	define ANKI_UNUSED
 #	define ANKI_COLD
 #	define ANKI_COLD
@@ -186,6 +186,17 @@
 #	define ANKI_PREFETCH_MEMORY(addr) (void)(addr)
 #	define ANKI_PREFETCH_MEMORY(addr) (void)(addr)
 #	define ANKI_CHECK_FORMAT(fmtArgIdx, firstArgIdx)
 #	define ANKI_CHECK_FORMAT(fmtArgIdx, firstArgIdx)
 #	define ANKI_PURE
 #	define ANKI_PURE
+#else
+#	define ANKI_RESTRICT
+#	define ANKI_FORCE_INLINE 
+#	define ANKI_DONT_INLINE
+#	define ANKI_UNUSED
+#	define ANKI_COLD
+#	define ANKI_HOT
+#	define ANKI_UNREACHABLE() 
+#	define ANKI_PREFETCH_MEMORY(addr) (void)(addr)
+#	define ANKI_CHECK_FORMAT(fmtArgIdx, firstArgIdx)
+#	define ANKI_PURE
 #endif
 #endif
 
 
 // Pack structs
 // Pack structs

+ 18 - 40
AnKi/Core/App.cpp

@@ -126,21 +126,16 @@ void App::cleanup()
 	m_renderer = nullptr;
 	m_renderer = nullptr;
 	deleteInstance(m_mainPool, m_ui);
 	deleteInstance(m_mainPool, m_ui);
 	m_ui = nullptr;
 	m_ui = nullptr;
-	deleteInstance(m_mainPool, m_gpuSceneMicroPatcher);
-	m_gpuSceneMicroPatcher = nullptr;
+	GpuSceneMicroPatcher::freeSingleton();
 	deleteInstance(m_mainPool, m_resources);
 	deleteInstance(m_mainPool, m_resources);
 	m_resources = nullptr;
 	m_resources = nullptr;
 	deleteInstance(m_mainPool, m_resourceFs);
 	deleteInstance(m_mainPool, m_resourceFs);
 	m_resourceFs = nullptr;
 	m_resourceFs = nullptr;
 	PhysicsWorld::freeSingleton();
 	PhysicsWorld::freeSingleton();
-	deleteInstance(m_mainPool, m_rebarPool);
-	m_rebarPool = nullptr;
-	deleteInstance(m_mainPool, m_unifiedGometryMemPool);
-	m_unifiedGometryMemPool = nullptr;
-	deleteInstance(m_mainPool, m_gpuSceneMemPool);
-	m_gpuSceneMemPool = nullptr;
-	deleteInstance(m_mainPool, m_threadHive);
-	m_threadHive = nullptr;
+	RebarStagingGpuMemoryPool::freeSingleton();
+	UnifiedGeometryMemoryPool::freeSingleton();
+	GpuSceneMemoryPool::freeSingleton();
+	CoreThreadHive::freeSingleton();
 	deleteInstance(m_mainPool, m_maliHwCounters);
 	deleteInstance(m_mainPool, m_maliHwCounters);
 	m_maliHwCounters = nullptr;
 	m_maliHwCounters = nullptr;
 	GrManager::deleteInstance(m_gr);
 	GrManager::deleteInstance(m_gr);
@@ -266,8 +261,8 @@ Error App::initInternal(AllocAlignedCallback allocCb, void* allocCbUserData)
 	// ThreadPool
 	// ThreadPool
 	//
 	//
 	const Bool pinThreads = !ANKI_OS_ANDROID;
 	const Bool pinThreads = !ANKI_OS_ANDROID;
-	m_threadHive =
-		newInstance<ThreadHive>(m_mainPool, ConfigSet::getSingleton().getCoreJobThreadCount(), &m_mainPool, pinThreads);
+	CoreThreadHive::allocateSingleton(ConfigSet::getSingleton().getCoreJobThreadCount(),
+									  &CoreMemoryPool::getSingleton(), pinThreads);
 
 
 	//
 	//
 	// Graphics API
 	// Graphics API
@@ -291,14 +286,9 @@ Error App::initInternal(AllocAlignedCallback allocCb, void* allocCbUserData)
 	//
 	//
 	// GPU mem
 	// GPU mem
 	//
 	//
-	m_unifiedGometryMemPool = newInstance<UnifiedGeometryMemoryPool>(m_mainPool);
-	m_unifiedGometryMemPool->init(&m_mainPool, m_gr);
-
-	m_gpuSceneMemPool = newInstance<GpuSceneMemoryPool>(m_mainPool);
-	m_gpuSceneMemPool->init(&m_mainPool, m_gr);
-
-	m_rebarPool = newInstance<RebarStagingGpuMemoryPool>(m_mainPool);
-	ANKI_CHECK(m_rebarPool->init(m_gr));
+	UnifiedGeometryMemoryPool::allocateSingleton().init(m_gr);
+	GpuSceneMemoryPool::allocateSingleton().init(m_gr);
+	RebarStagingGpuMemoryPool::allocateSingleton().init(m_gr);
 
 
 	//
 	//
 	// Physics
 	// Physics
@@ -331,7 +321,6 @@ Error App::initInternal(AllocAlignedCallback allocCb, void* allocCbUserData)
 	ResourceManagerInitInfo rinit;
 	ResourceManagerInitInfo rinit;
 	rinit.m_grManager = m_gr;
 	rinit.m_grManager = m_gr;
 	rinit.m_resourceFilesystem = m_resourceFs;
 	rinit.m_resourceFilesystem = m_resourceFs;
-	rinit.m_unifiedGometryMemoryPool = m_unifiedGometryMemPool;
 	rinit.m_allocCallback = m_mainPool.getAllocationCallback();
 	rinit.m_allocCallback = m_mainPool.getAllocationCallback();
 	rinit.m_allocCallbackData = m_mainPool.getAllocationCallbackUserData();
 	rinit.m_allocCallbackData = m_mainPool.getAllocationCallbackUserData();
 	m_resources = newInstance<ResourceManager>(m_mainPool);
 	m_resources = newInstance<ResourceManager>(m_mainPool);
@@ -347,15 +336,13 @@ Error App::initInternal(AllocAlignedCallback allocCb, void* allocCbUserData)
 	uiInitInfo.m_grManager = m_gr;
 	uiInitInfo.m_grManager = m_gr;
 	uiInitInfo.m_resourceFilesystem = m_resourceFs;
 	uiInitInfo.m_resourceFilesystem = m_resourceFs;
 	uiInitInfo.m_resourceManager = m_resources;
 	uiInitInfo.m_resourceManager = m_resources;
-	uiInitInfo.m_rebarPool = m_rebarPool;
 	m_ui = newInstance<UiManager>(m_mainPool);
 	m_ui = newInstance<UiManager>(m_mainPool);
 	ANKI_CHECK(m_ui->init(uiInitInfo));
 	ANKI_CHECK(m_ui->init(uiInitInfo));
 
 
 	//
 	//
 	// GPU scene
 	// GPU scene
 	//
 	//
-	m_gpuSceneMicroPatcher = newInstance<GpuSceneMicroPatcher>(m_mainPool);
-	ANKI_CHECK(m_gpuSceneMicroPatcher->init(m_resources));
+	ANKI_CHECK(GpuSceneMicroPatcher::allocateSingleton().init(m_resources));
 
 
 	//
 	//
 	// Renderer
 	// Renderer
@@ -365,15 +352,10 @@ Error App::initInternal(AllocAlignedCallback allocCb, void* allocCbUserData)
 		UVec2(NativeWindow::getSingleton().getWidth(), NativeWindow::getSingleton().getHeight());
 		UVec2(NativeWindow::getSingleton().getWidth(), NativeWindow::getSingleton().getHeight());
 	renderInit.m_allocCallback = m_mainPool.getAllocationCallback();
 	renderInit.m_allocCallback = m_mainPool.getAllocationCallback();
 	renderInit.m_allocCallbackUserData = m_mainPool.getAllocationCallbackUserData();
 	renderInit.m_allocCallbackUserData = m_mainPool.getAllocationCallbackUserData();
-	renderInit.m_threadHive = m_threadHive;
 	renderInit.m_resourceManager = m_resources;
 	renderInit.m_resourceManager = m_resources;
 	renderInit.m_grManager = m_gr;
 	renderInit.m_grManager = m_gr;
-	renderInit.m_rebarStagingPool = m_rebarPool;
 	renderInit.m_uiManager = m_ui;
 	renderInit.m_uiManager = m_ui;
 	renderInit.m_globTimestamp = &m_globalTimestamp;
 	renderInit.m_globTimestamp = &m_globalTimestamp;
-	renderInit.m_gpuScenePool = m_gpuSceneMemPool;
-	renderInit.m_gpuSceneMicroPatcher = m_gpuSceneMicroPatcher;
-	renderInit.m_unifiedGometryMemoryPool = m_unifiedGometryMemPool;
 	m_renderer = newInstance<MainRenderer>(m_mainPool);
 	m_renderer = newInstance<MainRenderer>(m_mainPool);
 	ANKI_CHECK(m_renderer->init(renderInit));
 	ANKI_CHECK(m_renderer->init(renderInit));
 
 
@@ -392,13 +374,9 @@ Error App::initInternal(AllocAlignedCallback allocCb, void* allocCbUserData)
 	sceneInit.m_allocCallback = m_mainPool.getAllocationCallback();
 	sceneInit.m_allocCallback = m_mainPool.getAllocationCallback();
 	sceneInit.m_allocCallbackData = m_mainPool.getAllocationCallbackUserData();
 	sceneInit.m_allocCallbackData = m_mainPool.getAllocationCallbackUserData();
 	sceneInit.m_globalTimestamp = &m_globalTimestamp;
 	sceneInit.m_globalTimestamp = &m_globalTimestamp;
-	sceneInit.m_gpuSceneMemoryPool = m_gpuSceneMemPool;
-	sceneInit.m_gpuSceneMicroPatcher = m_gpuSceneMicroPatcher;
 	sceneInit.m_resourceManager = m_resources;
 	sceneInit.m_resourceManager = m_resources;
 	sceneInit.m_scriptManager = m_script;
 	sceneInit.m_scriptManager = m_script;
-	sceneInit.m_threadHive = m_threadHive;
 	sceneInit.m_uiManager = m_ui;
 	sceneInit.m_uiManager = m_ui;
-	sceneInit.m_unifiedGeometryMemPool = m_unifiedGometryMemPool;
 	sceneInit.m_grManager = m_gr;
 	sceneInit.m_grManager = m_gr;
 	ANKI_CHECK(m_scene->init(sceneInit));
 	ANKI_CHECK(m_scene->init(sceneInit));
 
 
@@ -532,9 +510,9 @@ Error App::mainLoop()
 				grTime = HighRezTimer::getCurrentTime() - grTime;
 				grTime = HighRezTimer::getCurrentTime() - grTime;
 			}
 			}
 
 
-			const PtrSize rebarMemUsed = m_rebarPool->endFrame();
-			m_unifiedGometryMemPool->endFrame();
-			m_gpuSceneMemPool->endFrame();
+			const PtrSize rebarMemUsed = RebarStagingGpuMemoryPool::getSingleton().endFrame();
+			UnifiedGeometryMemoryPool::getSingleton().endFrame();
+			GpuSceneMemoryPool::getSingleton().endFrame();
 
 
 			// Update the trace info with some async loader stats
 			// Update the trace info with some async loader stats
 			U64 asyncTaskCount = m_resources->getAsyncLoader().getCompletedTaskCount();
 			U64 asyncTaskCount = m_resources->getAsyncLoader().getCompletedTaskCount();
@@ -600,10 +578,10 @@ Error App::mainLoop()
 				in.m_cpuFreeCount = m_memStats.m_freeCount.load();
 				in.m_cpuFreeCount = m_memStats.m_freeCount.load();
 
 
 				const GrManagerStats grStats = m_gr->getStats();
 				const GrManagerStats grStats = m_gr->getStats();
-				m_unifiedGometryMemPool->getStats(in.m_unifiedGometryExternalFragmentation,
-												  in.m_unifiedGeometryAllocated, in.m_unifiedGeometryTotal);
-				m_gpuSceneMemPool->getStats(in.m_gpuSceneExternalFragmentation, in.m_gpuSceneAllocated,
-											in.m_gpuSceneTotal);
+				UnifiedGeometryMemoryPool::getSingleton().getStats(
+					in.m_unifiedGometryExternalFragmentation, in.m_unifiedGeometryAllocated, in.m_unifiedGeometryTotal);
+				GpuSceneMemoryPool::getSingleton().getStats(in.m_gpuSceneExternalFragmentation, in.m_gpuSceneAllocated,
+															in.m_gpuSceneTotal);
 				in.m_gpuDeviceMemoryAllocated = grStats.m_deviceMemoryAllocated;
 				in.m_gpuDeviceMemoryAllocated = grStats.m_deviceMemoryAllocated;
 				in.m_gpuDeviceMemoryInUse = grStats.m_deviceMemoryInUse;
 				in.m_gpuDeviceMemoryInUse = grStats.m_deviceMemoryInUse;
 				in.m_reBar = rebarMemUsed;
 				in.m_reBar = rebarMemUsed;

+ 0 - 15
AnKi/Core/App.h

@@ -14,21 +14,16 @@ namespace anki {
 
 
 // Forward
 // Forward
 class CoreTracer;
 class CoreTracer;
-class ThreadHive;
 class GrManager;
 class GrManager;
 class MainRenderer;
 class MainRenderer;
 class SceneGraph;
 class SceneGraph;
 class ScriptManager;
 class ScriptManager;
 class ResourceManager;
 class ResourceManager;
 class ResourceFilesystem;
 class ResourceFilesystem;
-class RebarStagingGpuMemoryPool;
-class UnifiedGeometryMemoryPool;
 class UiManager;
 class UiManager;
 class UiQueueElement;
 class UiQueueElement;
 class RenderQueue;
 class RenderQueue;
 class MaliHwCounters;
 class MaliHwCounters;
-class GpuSceneMemoryPool;
-class GpuSceneMicroPatcher;
 
 
 /// The core class of the engine.
 /// The core class of the engine.
 class App
 class App
@@ -50,11 +45,6 @@ public:
 		return m_cacheDir;
 		return m_cacheDir;
 	}
 	}
 
 
-	ThreadHive& getThreadHive()
-	{
-		return *m_threadHive;
-	}
-
 	HeapMemoryPool& getMemoryPool()
 	HeapMemoryPool& getMemoryPool()
 	{
 	{
 		return m_mainPool;
 		return m_mainPool;
@@ -112,13 +102,8 @@ private:
 #if ANKI_ENABLE_TRACE
 #if ANKI_ENABLE_TRACE
 	CoreTracer* m_coreTracer = nullptr;
 	CoreTracer* m_coreTracer = nullptr;
 #endif
 #endif
-	ThreadHive* m_threadHive = nullptr;
 	GrManager* m_gr = nullptr;
 	GrManager* m_gr = nullptr;
 	MaliHwCounters* m_maliHwCounters = nullptr;
 	MaliHwCounters* m_maliHwCounters = nullptr;
-	UnifiedGeometryMemoryPool* m_unifiedGometryMemPool = nullptr;
-	GpuSceneMemoryPool* m_gpuSceneMemPool = nullptr;
-	GpuSceneMicroPatcher* m_gpuSceneMicroPatcher = nullptr;
-	RebarStagingGpuMemoryPool* m_rebarPool = nullptr;
 	ResourceFilesystem* m_resourceFs = nullptr;
 	ResourceFilesystem* m_resourceFs = nullptr;
 	ResourceManager* m_resources = nullptr;
 	ResourceManager* m_resources = nullptr;
 	UiManager* m_ui = nullptr;
 	UiManager* m_ui = nullptr;

+ 13 - 0
AnKi/Core/Common.h

@@ -8,6 +8,7 @@
 #include <AnKi/Config.h>
 #include <AnKi/Config.h>
 #include <AnKi/Util/StdTypes.h>
 #include <AnKi/Util/StdTypes.h>
 #include <AnKi/Util/MemoryPool.h>
 #include <AnKi/Util/MemoryPool.h>
+#include <AnKi/Util/ThreadHive.h>
 
 
 namespace anki {
 namespace anki {
 
 
@@ -30,6 +31,18 @@ private:
 	~CoreMemoryPool() = default;
 	~CoreMemoryPool() = default;
 };
 };
 
 
+class CoreThreadHive : public ThreadHive, public MakeSingleton<CoreThreadHive>
+{
+	template<typename>
+	friend class MakeSingleton;
+
+public:
+	CoreThreadHive(U32 threadCount, BaseMemoryPool* pool, Bool pinToCores = false)
+		: ThreadHive(threadCount, pool, pinToCores)
+	{
+	}
+};
+
 using CoreString = BaseStringRaii<SingletonMemoryPoolWrapper<CoreMemoryPool>>;
 using CoreString = BaseStringRaii<SingletonMemoryPoolWrapper<CoreMemoryPool>>;
 
 
 } // end namespace anki
 } // end namespace anki

+ 16 - 16
AnKi/Core/GpuMemoryPools.cpp

@@ -12,9 +12,9 @@
 
 
 namespace anki {
 namespace anki {
 
 
-void UnifiedGeometryMemoryPool::init(HeapMemoryPool* pool, GrManager* gr)
+void UnifiedGeometryMemoryPool::init(GrManager* gr)
 {
 {
-	ANKI_ASSERT(pool && gr);
+	ANKI_ASSERT(gr);
 
 
 	const PtrSize poolSize = ConfigSet::getSingleton().getCoreGlobalVertexMemorySize();
 	const PtrSize poolSize = ConfigSet::getSingleton().getCoreGlobalVertexMemorySize();
 
 
@@ -28,7 +28,7 @@ void UnifiedGeometryMemoryPool::init(HeapMemoryPool* pool, GrManager* gr)
 		buffUsage |= BufferUsageBit::kAccelerationStructureBuild;
 		buffUsage |= BufferUsageBit::kAccelerationStructureBuild;
 	}
 	}
 
 
-	m_pool.init(gr, pool, buffUsage, classes, poolSize, "UnifiedGeometry", false);
+	m_pool.init(gr, &CoreMemoryPool::getSingleton(), buffUsage, classes, poolSize, "UnifiedGeometry", false);
 
 
 	// Allocate something dummy to force creating the GPU buffer
 	// Allocate something dummy to force creating the GPU buffer
 	SegregatedListsGpuMemoryPoolToken token;
 	SegregatedListsGpuMemoryPoolToken token;
@@ -36,9 +36,9 @@ void UnifiedGeometryMemoryPool::init(HeapMemoryPool* pool, GrManager* gr)
 	deferredFree(token);
 	deferredFree(token);
 }
 }
 
 
-void GpuSceneMemoryPool::init(HeapMemoryPool* pool, GrManager* gr)
+void GpuSceneMemoryPool::init(GrManager* gr)
 {
 {
-	ANKI_ASSERT(pool && gr);
+	ANKI_ASSERT(gr);
 
 
 	const PtrSize poolSize = ConfigSet::getSingleton().getCoreGpuSceneInitialSize();
 	const PtrSize poolSize = ConfigSet::getSingleton().getCoreGpuSceneInitialSize();
 
 
@@ -46,7 +46,7 @@ void GpuSceneMemoryPool::init(HeapMemoryPool* pool, GrManager* gr)
 
 
 	BufferUsageBit buffUsage = BufferUsageBit::kAllStorage | BufferUsageBit::kTransferDestination;
 	BufferUsageBit buffUsage = BufferUsageBit::kAllStorage | BufferUsageBit::kTransferDestination;
 
 
-	m_pool.init(gr, pool, buffUsage, classes, poolSize, "GpuScene", true);
+	m_pool.init(gr, &CoreMemoryPool::getSingleton(), buffUsage, classes, poolSize, "GpuScene", true);
 }
 }
 
 
 RebarStagingGpuMemoryPool::~RebarStagingGpuMemoryPool()
 RebarStagingGpuMemoryPool::~RebarStagingGpuMemoryPool()
@@ -59,7 +59,7 @@ RebarStagingGpuMemoryPool::~RebarStagingGpuMemoryPool()
 	m_buffer.reset(nullptr);
 	m_buffer.reset(nullptr);
 }
 }
 
 
-Error RebarStagingGpuMemoryPool::init(GrManager* gr)
+void RebarStagingGpuMemoryPool::init(GrManager* gr)
 {
 {
 	BufferInitInfo buffInit("ReBar");
 	BufferInitInfo buffInit("ReBar");
 	buffInit.m_mapAccess = BufferMapAccessBit::kWrite;
 	buffInit.m_mapAccess = BufferMapAccessBit::kWrite;
@@ -75,8 +75,6 @@ Error RebarStagingGpuMemoryPool::init(GrManager* gr)
 	m_alignment = max(m_alignment, gr->getDeviceCapabilities().m_sbtRecordAlignment);
 	m_alignment = max(m_alignment, gr->getDeviceCapabilities().m_sbtRecordAlignment);
 
 
 	m_mappedMem = static_cast<U8*>(m_buffer->map(0, kMaxPtrSize, BufferMapAccessBit::kWrite));
 	m_mappedMem = static_cast<U8*>(m_buffer->map(0, kMaxPtrSize, BufferMapAccessBit::kWrite));
-
-	return Error::kNone;
 }
 }
 
 
 void* RebarStagingGpuMemoryPool::allocateFrame(PtrSize size, RebarGpuMemoryToken& token)
 void* RebarStagingGpuMemoryPool::allocateFrame(PtrSize size, RebarGpuMemoryToken& token)
@@ -187,8 +185,7 @@ void GpuSceneMicroPatcher::newCopy(StackMemoryPool& frameCpuPool, PtrSize gpuSce
 	}
 	}
 }
 }
 
 
-void GpuSceneMicroPatcher::patchGpuScene(RebarStagingGpuMemoryPool& rebarPool, CommandBuffer& cmdb,
-										 const BufferPtr& gpuSceneBuffer)
+void GpuSceneMicroPatcher::patchGpuScene(CommandBuffer& cmdb)
 {
 {
 	if(m_crntFramePatchHeaders.getSize() == 0)
 	if(m_crntFramePatchHeaders.getSize() == 0)
 	{
 	{
@@ -201,16 +198,19 @@ void GpuSceneMicroPatcher::patchGpuScene(RebarStagingGpuMemoryPool& rebarPool, C
 	ANKI_TRACE_INC_COUNTER(GpuSceneMicroPatchUploadData, m_crntFramePatchData.getSizeInBytes());
 	ANKI_TRACE_INC_COUNTER(GpuSceneMicroPatchUploadData, m_crntFramePatchData.getSizeInBytes());
 
 
 	RebarGpuMemoryToken headersToken;
 	RebarGpuMemoryToken headersToken;
-	void* mapped = rebarPool.allocateFrame(m_crntFramePatchHeaders.getSizeInBytes(), headersToken);
+	void* mapped =
+		RebarStagingGpuMemoryPool::getSingleton().allocateFrame(m_crntFramePatchHeaders.getSizeInBytes(), headersToken);
 	memcpy(mapped, &m_crntFramePatchHeaders[0], m_crntFramePatchHeaders.getSizeInBytes());
 	memcpy(mapped, &m_crntFramePatchHeaders[0], m_crntFramePatchHeaders.getSizeInBytes());
 
 
 	RebarGpuMemoryToken dataToken;
 	RebarGpuMemoryToken dataToken;
-	mapped = rebarPool.allocateFrame(m_crntFramePatchData.getSizeInBytes(), dataToken);
+	mapped = RebarStagingGpuMemoryPool::getSingleton().allocateFrame(m_crntFramePatchData.getSizeInBytes(), dataToken);
 	memcpy(mapped, &m_crntFramePatchData[0], m_crntFramePatchData.getSizeInBytes());
 	memcpy(mapped, &m_crntFramePatchData[0], m_crntFramePatchData.getSizeInBytes());
 
 
-	cmdb.bindStorageBuffer(0, 0, rebarPool.getBuffer(), headersToken.m_offset, headersToken.m_range);
-	cmdb.bindStorageBuffer(0, 1, rebarPool.getBuffer(), dataToken.m_offset, dataToken.m_range);
-	cmdb.bindStorageBuffer(0, 2, gpuSceneBuffer, 0, kMaxPtrSize);
+	cmdb.bindStorageBuffer(0, 0, RebarStagingGpuMemoryPool::getSingleton().getBuffer(), headersToken.m_offset,
+						   headersToken.m_range);
+	cmdb.bindStorageBuffer(0, 1, RebarStagingGpuMemoryPool::getSingleton().getBuffer(), dataToken.m_offset,
+						   dataToken.m_range);
+	cmdb.bindStorageBuffer(0, 2, GpuSceneMemoryPool::getSingleton().getBuffer(), 0, kMaxPtrSize);
 
 
 	cmdb.bindShaderProgram(m_grProgram);
 	cmdb.bindShaderProgram(m_grProgram);
 
 

+ 34 - 18
AnKi/Core/GpuMemoryPools.h

@@ -17,16 +17,17 @@ namespace anki {
 /// @{
 /// @{
 
 
 /// Manages vertex and index memory for the whole application.
 /// Manages vertex and index memory for the whole application.
-class UnifiedGeometryMemoryPool
+class UnifiedGeometryMemoryPool : public MakeSingleton<UnifiedGeometryMemoryPool>
 {
 {
-public:
-	UnifiedGeometryMemoryPool() = default;
+	template<typename>
+	friend class MakeSingleton;
 
 
+public:
 	UnifiedGeometryMemoryPool(const UnifiedGeometryMemoryPool&) = delete; // Non-copyable
 	UnifiedGeometryMemoryPool(const UnifiedGeometryMemoryPool&) = delete; // Non-copyable
 
 
 	UnifiedGeometryMemoryPool& operator=(const UnifiedGeometryMemoryPool&) = delete; // Non-copyable
 	UnifiedGeometryMemoryPool& operator=(const UnifiedGeometryMemoryPool&) = delete; // Non-copyable
 
 
-	void init(HeapMemoryPool* pool, GrManager* gr);
+	void init(GrManager* gr);
 
 
 	void allocate(PtrSize size, U32 alignment, SegregatedListsGpuMemoryPoolToken& token)
 	void allocate(PtrSize size, U32 alignment, SegregatedListsGpuMemoryPoolToken& token)
 	{
 	{
@@ -55,19 +56,24 @@ public:
 
 
 private:
 private:
 	SegregatedListsGpuMemoryPool m_pool;
 	SegregatedListsGpuMemoryPool m_pool;
+
+	UnifiedGeometryMemoryPool() = default;
+
+	~UnifiedGeometryMemoryPool() = default;
 };
 };
 
 
 /// Memory pool for the GPU scene.
 /// Memory pool for the GPU scene.
-class GpuSceneMemoryPool
+class GpuSceneMemoryPool : public MakeSingleton<GpuSceneMemoryPool>
 {
 {
-public:
-	GpuSceneMemoryPool() = default;
+	template<typename>
+	friend class MakeSingleton;
 
 
+public:
 	GpuSceneMemoryPool(const GpuSceneMemoryPool&) = delete; // Non-copyable
 	GpuSceneMemoryPool(const GpuSceneMemoryPool&) = delete; // Non-copyable
 
 
 	GpuSceneMemoryPool& operator=(const GpuSceneMemoryPool&) = delete; // Non-copyable
 	GpuSceneMemoryPool& operator=(const GpuSceneMemoryPool&) = delete; // Non-copyable
 
 
-	void init(HeapMemoryPool* pool, GrManager* gr);
+	void init(GrManager* gr);
 
 
 	void allocate(PtrSize size, U32 alignment, SegregatedListsGpuMemoryPoolToken& token)
 	void allocate(PtrSize size, U32 alignment, SegregatedListsGpuMemoryPoolToken& token)
 	{
 	{
@@ -101,6 +107,10 @@ public:
 
 
 private:
 private:
 	SegregatedListsGpuMemoryPool m_pool;
 	SegregatedListsGpuMemoryPool m_pool;
+
+	GpuSceneMemoryPool() = default;
+
+	~GpuSceneMemoryPool() = default;
 };
 };
 
 
 /// Token that gets returned when requesting for memory to write to a resource.
 /// Token that gets returned when requesting for memory to write to a resource.
@@ -131,18 +141,19 @@ public:
 };
 };
 
 
 /// Manages staging GPU memory.
 /// Manages staging GPU memory.
-class RebarStagingGpuMemoryPool
+class RebarStagingGpuMemoryPool : public MakeSingleton<RebarStagingGpuMemoryPool>
 {
 {
-public:
-	RebarStagingGpuMemoryPool() = default;
+	template<typename>
+	friend class MakeSingleton;
 
 
+public:
 	RebarStagingGpuMemoryPool(const RebarStagingGpuMemoryPool&) = delete; // Non-copyable
 	RebarStagingGpuMemoryPool(const RebarStagingGpuMemoryPool&) = delete; // Non-copyable
 
 
 	~RebarStagingGpuMemoryPool();
 	~RebarStagingGpuMemoryPool();
 
 
 	RebarStagingGpuMemoryPool& operator=(const RebarStagingGpuMemoryPool&) = delete; // Non-copyable
 	RebarStagingGpuMemoryPool& operator=(const RebarStagingGpuMemoryPool&) = delete; // Non-copyable
 
 
-	Error init(GrManager* gr);
+	void init(GrManager* gr);
 
 
 	PtrSize endFrame();
 	PtrSize endFrame();
 
 
@@ -171,18 +182,19 @@ private:
 	Atomic<PtrSize> m_offset = {0};
 	Atomic<PtrSize> m_offset = {0};
 	PtrSize m_previousFrameEndOffset = 0;
 	PtrSize m_previousFrameEndOffset = 0;
 	U32 m_alignment = 0;
 	U32 m_alignment = 0;
+
+	RebarStagingGpuMemoryPool() = default;
 };
 };
 
 
 /// Creates the copy jobs that will patch the GPU Scene.
 /// Creates the copy jobs that will patch the GPU Scene.
-class GpuSceneMicroPatcher
+class GpuSceneMicroPatcher : public MakeSingleton<GpuSceneMicroPatcher>
 {
 {
-public:
-	GpuSceneMicroPatcher() = default;
+	template<typename>
+	friend class MakeSingleton;
 
 
+public:
 	GpuSceneMicroPatcher(const GpuSceneMicroPatcher&) = delete;
 	GpuSceneMicroPatcher(const GpuSceneMicroPatcher&) = delete;
 
 
-	~GpuSceneMicroPatcher();
-
 	GpuSceneMicroPatcher& operator=(const GpuSceneMicroPatcher&) = delete;
 	GpuSceneMicroPatcher& operator=(const GpuSceneMicroPatcher&) = delete;
 
 
 	Error init(ResourceManager* rsrc);
 	Error init(ResourceManager* rsrc);
@@ -200,7 +212,7 @@ public:
 
 
 	/// Copy the data to the GPU scene buffer.
 	/// Copy the data to the GPU scene buffer.
 	/// @note Not thread-safe. Nothing else should be happening before calling it.
 	/// @note Not thread-safe. Nothing else should be happening before calling it.
-	void patchGpuScene(RebarStagingGpuMemoryPool& rebarPool, CommandBuffer& cmdb, const BufferPtr& gpuSceneBuffer);
+	void patchGpuScene(CommandBuffer& cmdb);
 
 
 private:
 private:
 	static constexpr U32 kDwordsPerPatch = 64;
 	static constexpr U32 kDwordsPerPatch = 64;
@@ -213,6 +225,10 @@ private:
 
 
 	ShaderProgramResourcePtr m_copyProgram;
 	ShaderProgramResourcePtr m_copyProgram;
 	ShaderProgramPtr m_grProgram;
 	ShaderProgramPtr m_grProgram;
+
+	GpuSceneMicroPatcher() = default;
+
+	~GpuSceneMicroPatcher();
 };
 };
 /// @}
 /// @}
 
 

+ 8 - 8
AnKi/Renderer/ClusterBinning.cpp

@@ -58,8 +58,8 @@ void ClusterBinning::populateRenderGraph(RenderingContext& ctx)
 	writeClustererBuffers(ctx);
 	writeClustererBuffers(ctx);
 
 
 	m_runCtx.m_rebarHandle = ctx.m_renderGraphDescr.importBuffer(
 	m_runCtx.m_rebarHandle = ctx.m_renderGraphDescr.importBuffer(
-		m_r->getExternalSubsystems().m_rebarStagingPool->getBuffer(), BufferUsageBit::kNone,
-		m_runCtx.m_clustersToken.m_offset, m_runCtx.m_clustersToken.m_range);
+		RebarStagingGpuMemoryPool::getSingleton().getBuffer(), BufferUsageBit::kNone, m_runCtx.m_clustersToken.m_offset,
+		m_runCtx.m_clustersToken.m_range);
 
 
 	const RenderQueue& rqueue = *ctx.m_renderQueue;
 	const RenderQueue& rqueue = *ctx.m_renderQueue;
 	if(rqueue.m_pointLights.getSize() == 0 && rqueue.m_spotLights.getSize() == 0 && rqueue.m_decals.getSize() == 0
 	if(rqueue.m_pointLights.getSize() == 0 && rqueue.m_spotLights.getSize() == 0 && rqueue.m_decals.getSize() == 0
@@ -151,14 +151,14 @@ void ClusterBinning::writeClustererBuffers(RenderingContext& ctx)
 	}
 	}
 
 
 	// Allocate buffers
 	// Allocate buffers
-	RebarStagingGpuMemoryPool& stagingMem = *m_r->getExternalSubsystems().m_rebarStagingPool;
-	stagingMem.allocateFrame(sizeof(ClusteredShadingUniforms), m_runCtx.m_clusteredShadingUniformsToken);
-	stagingMem.allocateFrame(sizeof(Cluster) * m_clusterCount, m_runCtx.m_clustersToken);
+	RebarStagingGpuMemoryPool::getSingleton().allocateFrame(sizeof(ClusteredShadingUniforms),
+															m_runCtx.m_clusteredShadingUniformsToken);
+	RebarStagingGpuMemoryPool::getSingleton().allocateFrame(sizeof(Cluster) * m_clusterCount, m_runCtx.m_clustersToken);
 }
 }
 
 
 void ClusterBinning::writeClusterBuffersAsync()
 void ClusterBinning::writeClusterBuffersAsync()
 {
 {
-	m_r->getExternalSubsystems().m_threadHive->submitTask(
+	CoreThreadHive::getSingleton().submitTask(
 		[](void* userData, [[maybe_unused]] U32 threadId, [[maybe_unused]] ThreadHive& hive,
 		[](void* userData, [[maybe_unused]] U32 threadId, [[maybe_unused]] ThreadHive& hive,
 		   [[maybe_unused]] ThreadHiveSemaphore* signalSemaphore) {
 		   [[maybe_unused]] ThreadHiveSemaphore* signalSemaphore) {
 			static_cast<ClusterBinning*>(userData)->writeClustererBuffersTask();
 			static_cast<ClusterBinning*>(userData)->writeClustererBuffersTask();
@@ -176,7 +176,7 @@ void ClusterBinning::writeClustererBuffersTask()
 	// General uniforms
 	// General uniforms
 	{
 	{
 		ClusteredShadingUniforms& unis = *reinterpret_cast<ClusteredShadingUniforms*>(
 		ClusteredShadingUniforms& unis = *reinterpret_cast<ClusteredShadingUniforms*>(
-			m_r->getExternalSubsystems().m_rebarStagingPool->getBufferMappedAddress()
+			RebarStagingGpuMemoryPool::getSingleton().getBufferMappedAddress()
 			+ m_runCtx.m_clusteredShadingUniformsToken.m_offset);
 			+ m_runCtx.m_clusteredShadingUniformsToken.m_offset);
 
 
 		unis.m_renderingSize = Vec2(F32(m_r->getInternalResolution().x()), F32(m_r->getInternalResolution().y()));
 		unis.m_renderingSize = Vec2(F32(m_r->getInternalResolution().x()), F32(m_r->getInternalResolution().y()));
@@ -249,7 +249,7 @@ void ClusterBinning::writeClustererBuffersTask()
 
 
 	// Zero the memory because atomics will happen
 	// Zero the memory because atomics will happen
 	U8* clustersAddress =
 	U8* clustersAddress =
-		m_r->getExternalSubsystems().m_rebarStagingPool->getBufferMappedAddress() + m_runCtx.m_clustersToken.m_offset;
+		RebarStagingGpuMemoryPool::getSingleton().getBufferMappedAddress() + m_runCtx.m_clustersToken.m_offset;
 	memset(clustersAddress, 0, sizeof(Cluster) * m_clusterCount);
 	memset(clustersAddress, 0, sizeof(Cluster) * m_clusterCount);
 }
 }
 
 

+ 0 - 5
AnKi/Renderer/Common.h

@@ -75,15 +75,10 @@ inline constexpr Array<Format, kGBufferColorRenderTargetCount> kGBufferColorRend
 class RendererExternalSubsystems
 class RendererExternalSubsystems
 {
 {
 public:
 public:
-	ThreadHive* m_threadHive = nullptr;
 	ResourceManager* m_resourceManager = nullptr;
 	ResourceManager* m_resourceManager = nullptr;
 	GrManager* m_grManager = nullptr;
 	GrManager* m_grManager = nullptr;
-	RebarStagingGpuMemoryPool* m_rebarStagingPool = nullptr;
 	UiManager* m_uiManager = nullptr;
 	UiManager* m_uiManager = nullptr;
 	Timestamp* m_globTimestamp = nullptr;
 	Timestamp* m_globTimestamp = nullptr;
-	GpuSceneMemoryPool* m_gpuScenePool = nullptr;
-	GpuSceneMicroPatcher* m_gpuSceneMicroPatcher = nullptr;
-	UnifiedGeometryMemoryPool* m_unifiedGometryMemoryPool = nullptr;
 };
 };
 
 
 /// Rendering context.
 /// Rendering context.

+ 11 - 13
AnKi/Renderer/Dbg.cpp

@@ -79,8 +79,6 @@ void Dbg::run(RenderPassWorkContext& rgraphCtx, const RenderingContext& ctx)
 	U32 start, end;
 	U32 start, end;
 	splitThreadedProblem(threadId, threadCount, problemSize, start, end);
 	splitThreadedProblem(threadId, threadCount, problemSize, start, end);
 
 
-	RebarStagingGpuMemoryPool& rebar = *getExternalSubsystems().m_rebarStagingPool;
-
 	// Renderables
 	// Renderables
 	for(U32 i = start; i < end; ++i)
 	for(U32 i = start; i < end; ++i)
 	{
 	{
@@ -99,7 +97,7 @@ void Dbg::run(RenderPassWorkContext& rgraphCtx, const RenderingContext& ctx)
 
 
 		const Mat4 mvp = ctx.m_matrices.m_viewProjection * Mat4(tsl.xyz1(), Mat3::getIdentity() * nonUniScale, 1.0f);
 		const Mat4 mvp = ctx.m_matrices.m_viewProjection * Mat4(tsl.xyz1(), Mat3::getIdentity() * nonUniScale, 1.0f);
 
 
-		m_drawer.drawCube(mvp, Vec4(1.0f, 0.0f, 1.0f, 1.0f), 2.0f, m_ditheredDepthTestOn, 2.0f, rebar, cmdb);
+		m_drawer.drawCube(mvp, Vec4(1.0f, 0.0f, 1.0f, 1.0f), 2.0f, m_ditheredDepthTestOn, 2.0f, cmdb);
 	}
 	}
 
 
 	// Forward shaded renderables
 	// Forward shaded renderables
@@ -121,7 +119,7 @@ void Dbg::run(RenderPassWorkContext& rgraphCtx, const RenderingContext& ctx)
 			const Mat4 mvp =
 			const Mat4 mvp =
 				ctx.m_matrices.m_viewProjection * Mat4(tsl.xyz1(), Mat3::getIdentity() * nonUniScale, 1.0f);
 				ctx.m_matrices.m_viewProjection * Mat4(tsl.xyz1(), Mat3::getIdentity() * nonUniScale, 1.0f);
 
 
-			m_drawer.drawCube(mvp, Vec4(1.0f, 0.0f, 1.0f, 1.0f), 2.0f, m_ditheredDepthTestOn, 2.0f, rebar, cmdb);
+			m_drawer.drawCube(mvp, Vec4(1.0f, 0.0f, 1.0f, 1.0f), 2.0f, m_ditheredDepthTestOn, 2.0f, cmdb);
 		}
 		}
 	}
 	}
 
 
@@ -142,12 +140,12 @@ void Dbg::run(RenderPassWorkContext& rgraphCtx, const RenderingContext& ctx)
 			const Mat4 mvp = ctx.m_matrices.m_viewProjection * Mat4(tsl.xyz1(), rot, 1.0f);
 			const Mat4 mvp = ctx.m_matrices.m_viewProjection * Mat4(tsl.xyz1(), rot, 1.0f);
 
 
 			m_drawer.drawCubes(ConstWeakArray<Mat4>(&mvp, 1), Vec4(0.729f, 0.635f, 0.196f, 1.0f), 1.0f,
 			m_drawer.drawCubes(ConstWeakArray<Mat4>(&mvp, 1), Vec4(0.729f, 0.635f, 0.196f, 1.0f), 1.0f,
-							   m_ditheredDepthTestOn, 2.0f, rebar, cmdb);
+							   m_ditheredDepthTestOn, 2.0f, cmdb);
 
 
 			m_drawer.drawBillboardTextures(ctx.m_matrices.m_projection, ctx.m_matrices.m_view,
 			m_drawer.drawBillboardTextures(ctx.m_matrices.m_projection, ctx.m_matrices.m_view,
 										   ConstWeakArray<Vec3>(&tsl, 1), Vec4(1.0f), m_ditheredDepthTestOn,
 										   ConstWeakArray<Vec3>(&tsl, 1), Vec4(1.0f), m_ditheredDepthTestOn,
 										   m_giProbeImage->getTextureView(), m_r->getSamplers().m_trilinearRepeatAniso,
 										   m_giProbeImage->getTextureView(), m_r->getSamplers().m_trilinearRepeatAniso,
-										   Vec2(0.75f), rebar, cmdb);
+										   Vec2(0.75f), cmdb);
 		}
 		}
 	}
 	}
 
 
@@ -161,7 +159,7 @@ void Dbg::run(RenderPassWorkContext& rgraphCtx, const RenderingContext& ctx)
 
 
 			m_drawer.drawBillboardTexture(ctx.m_matrices.m_projection, ctx.m_matrices.m_view, el.m_worldPosition,
 			m_drawer.drawBillboardTexture(ctx.m_matrices.m_projection, ctx.m_matrices.m_view, el.m_worldPosition,
 										  color.xyz1(), m_ditheredDepthTestOn, m_pointLightImage->getTextureView(),
 										  color.xyz1(), m_ditheredDepthTestOn, m_pointLightImage->getTextureView(),
-										  m_r->getSamplers().m_trilinearRepeatAniso, Vec2(0.75f), rebar, cmdb);
+										  m_r->getSamplers().m_trilinearRepeatAniso, Vec2(0.75f), cmdb);
 		}
 		}
 
 
 		for(const SpotLightQueueElement& el : ctx.m_renderQueue->m_spotLights)
 		for(const SpotLightQueueElement& el : ctx.m_renderQueue->m_spotLights)
@@ -172,7 +170,7 @@ void Dbg::run(RenderPassWorkContext& rgraphCtx, const RenderingContext& ctx)
 			m_drawer.drawBillboardTexture(ctx.m_matrices.m_projection, ctx.m_matrices.m_view,
 			m_drawer.drawBillboardTexture(ctx.m_matrices.m_projection, ctx.m_matrices.m_view,
 										  el.m_worldTransform.getTranslationPart().xyz(), color.xyz1(),
 										  el.m_worldTransform.getTranslationPart().xyz(), color.xyz1(),
 										  m_ditheredDepthTestOn, m_spotLightImage->getTextureView(),
 										  m_ditheredDepthTestOn, m_spotLightImage->getTextureView(),
-										  m_r->getSamplers().m_trilinearRepeatAniso, Vec2(0.75f), rebar, cmdb);
+										  m_r->getSamplers().m_trilinearRepeatAniso, Vec2(0.75f), cmdb);
 		}
 		}
 	}
 	}
 
 
@@ -193,13 +191,13 @@ void Dbg::run(RenderPassWorkContext& rgraphCtx, const RenderingContext& ctx)
 			const Mat4 mvp = ctx.m_matrices.m_viewProjection * Mat4(tsl, rot * nonUniScale, 1.0f);
 			const Mat4 mvp = ctx.m_matrices.m_viewProjection * Mat4(tsl, rot * nonUniScale, 1.0f);
 
 
 			m_drawer.drawCubes(ConstWeakArray<Mat4>(&mvp, 1), Vec4(0.0f, 1.0f, 0.0f, 1.0f), 1.0f, m_ditheredDepthTestOn,
 			m_drawer.drawCubes(ConstWeakArray<Mat4>(&mvp, 1), Vec4(0.0f, 1.0f, 0.0f, 1.0f), 1.0f, m_ditheredDepthTestOn,
-							   2.0f, rebar, cmdb);
+							   2.0f, cmdb);
 
 
 			const Vec3 pos = el.m_obbCenter;
 			const Vec3 pos = el.m_obbCenter;
 			m_drawer.drawBillboardTextures(ctx.m_matrices.m_projection, ctx.m_matrices.m_view,
 			m_drawer.drawBillboardTextures(ctx.m_matrices.m_projection, ctx.m_matrices.m_view,
 										   ConstWeakArray<Vec3>(&pos, 1), Vec4(1.0f), m_ditheredDepthTestOn,
 										   ConstWeakArray<Vec3>(&pos, 1), Vec4(1.0f), m_ditheredDepthTestOn,
 										   m_decalImage->getTextureView(), m_r->getSamplers().m_trilinearRepeatAniso,
 										   m_decalImage->getTextureView(), m_r->getSamplers().m_trilinearRepeatAniso,
-										   Vec2(0.75f), rebar, cmdb);
+										   Vec2(0.75f), cmdb);
 		}
 		}
 	}
 	}
 
 
@@ -220,18 +218,18 @@ void Dbg::run(RenderPassWorkContext& rgraphCtx, const RenderingContext& ctx)
 			const Mat4 mvp = ctx.m_matrices.m_viewProjection * Mat4(tsl.xyz1(), rot, 1.0f);
 			const Mat4 mvp = ctx.m_matrices.m_viewProjection * Mat4(tsl.xyz1(), rot, 1.0f);
 
 
 			m_drawer.drawCubes(ConstWeakArray<Mat4>(&mvp, 1), Vec4(0.0f, 0.0f, 1.0f, 1.0f), 1.0f, m_ditheredDepthTestOn,
 			m_drawer.drawCubes(ConstWeakArray<Mat4>(&mvp, 1), Vec4(0.0f, 0.0f, 1.0f, 1.0f), 1.0f, m_ditheredDepthTestOn,
-							   2.0f, rebar, cmdb);
+							   2.0f, cmdb);
 
 
 			m_drawer.drawBillboardTextures(ctx.m_matrices.m_projection, ctx.m_matrices.m_view,
 			m_drawer.drawBillboardTextures(ctx.m_matrices.m_projection, ctx.m_matrices.m_view,
 										   ConstWeakArray<Vec3>(&el.m_worldPosition, 1), Vec4(1.0f),
 										   ConstWeakArray<Vec3>(&el.m_worldPosition, 1), Vec4(1.0f),
 										   m_ditheredDepthTestOn, m_reflectionImage->getTextureView(),
 										   m_ditheredDepthTestOn, m_reflectionImage->getTextureView(),
-										   m_r->getSamplers().m_trilinearRepeatAniso, Vec2(0.75f), rebar, cmdb);
+										   m_r->getSamplers().m_trilinearRepeatAniso, Vec2(0.75f), cmdb);
 		}
 		}
 	}
 	}
 
 
 	if(threadId == (threadCount - 1) && ConfigSet::getSingleton().getRDbgPhysics())
 	if(threadId == (threadCount - 1) && ConfigSet::getSingleton().getRDbgPhysics())
 	{
 	{
-		m_physicsDrawer.start(ctx.m_matrices.m_viewProjection, cmdb, &rebar);
+		m_physicsDrawer.start(ctx.m_matrices.m_viewProjection, cmdb);
 		m_physicsDrawer.drawWorld(PhysicsWorld::getSingleton());
 		m_physicsDrawer.drawWorld(PhysicsWorld::getSingleton());
 		m_physicsDrawer.end();
 		m_physicsDrawer.end();
 	}
 	}

+ 30 - 24
AnKi/Renderer/DebugDrawer.cpp

@@ -12,10 +12,10 @@
 
 
 namespace anki {
 namespace anki {
 
 
-void allocateAndPopulateDebugBox(RebarStagingGpuMemoryPool& stagingGpuAllocator, RebarGpuMemoryToken& vertsToken,
-								 RebarGpuMemoryToken& indicesToken, U32& indexCount)
+void allocateAndPopulateDebugBox(RebarGpuMemoryToken& vertsToken, RebarGpuMemoryToken& indicesToken, U32& indexCount)
 {
 {
-	Vec3* verts = static_cast<Vec3*>(stagingGpuAllocator.allocateFrame(sizeof(Vec3) * 8, vertsToken));
+	Vec3* verts =
+		static_cast<Vec3*>(RebarStagingGpuMemoryPool::getSingleton().allocateFrame(sizeof(Vec3) * 8, vertsToken));
 
 
 	constexpr F32 kSize = 1.0f;
 	constexpr F32 kSize = 1.0f;
 	verts[0] = Vec3(kSize, kSize, kSize); // front top right
 	verts[0] = Vec3(kSize, kSize, kSize); // front top right
@@ -28,7 +28,8 @@ void allocateAndPopulateDebugBox(RebarStagingGpuMemoryPool& stagingGpuAllocator,
 	verts[7] = Vec3(kSize, -kSize, -kSize); // back bottom right
 	verts[7] = Vec3(kSize, -kSize, -kSize); // back bottom right
 
 
 	constexpr U kIndexCount = 12 * 2;
 	constexpr U kIndexCount = 12 * 2;
-	U16* indices = static_cast<U16*>(stagingGpuAllocator.allocateFrame(sizeof(U16) * kIndexCount, indicesToken));
+	U16* indices = static_cast<U16*>(
+		RebarStagingGpuMemoryPool::getSingleton().allocateFrame(sizeof(U16) * kIndexCount, indicesToken));
 
 
 	U c = 0;
 	U c = 0;
 	indices[c++] = 0;
 	indices[c++] = 0;
@@ -136,12 +137,12 @@ Error DebugDrawer2::init(ResourceManager* rsrcManager, GrManager* gr)
 }
 }
 
 
 void DebugDrawer2::drawCubes(ConstWeakArray<Mat4> mvps, const Vec4& color, F32 lineSize, Bool ditherFailedDepth,
 void DebugDrawer2::drawCubes(ConstWeakArray<Mat4> mvps, const Vec4& color, F32 lineSize, Bool ditherFailedDepth,
-							 F32 cubeSideSize, RebarStagingGpuMemoryPool& stagingGpuAllocator,
-							 CommandBufferPtr& cmdb) const
+							 F32 cubeSideSize, CommandBufferPtr& cmdb) const
 {
 {
 	// Set the uniforms
 	// Set the uniforms
 	RebarGpuMemoryToken unisToken;
 	RebarGpuMemoryToken unisToken;
-	Mat4* pmvps = static_cast<Mat4*>(stagingGpuAllocator.allocateFrame(sizeof(Mat4) * mvps.getSize(), unisToken));
+	Mat4* pmvps = static_cast<Mat4*>(
+		RebarStagingGpuMemoryPool::getSingleton().allocateFrame(sizeof(Mat4) * mvps.getSize(), unisToken));
 
 
 	if(cubeSideSize == 2.0f)
 	if(cubeSideSize == 2.0f)
 	{
 	{
@@ -166,7 +167,8 @@ void DebugDrawer2::drawCubes(ConstWeakArray<Mat4> mvps, const Vec4& color, F32 l
 	cmdb->bindVertexBuffer(0, m_cubePositionsBuffer, 0, sizeof(Vec3));
 	cmdb->bindVertexBuffer(0, m_cubePositionsBuffer, 0, sizeof(Vec3));
 	cmdb->bindIndexBuffer(m_cubeIndicesBuffer, 0, IndexType::kU16);
 	cmdb->bindIndexBuffer(m_cubeIndicesBuffer, 0, IndexType::kU16);
 
 
-	cmdb->bindStorageBuffer(0, 0, stagingGpuAllocator.getBuffer(), unisToken.m_offset, unisToken.m_range);
+	cmdb->bindStorageBuffer(0, 0, RebarStagingGpuMemoryPool::getSingleton().getBuffer(), unisToken.m_offset,
+							unisToken.m_range);
 
 
 	cmdb->setLineWidth(lineSize);
 	cmdb->setLineWidth(lineSize);
 	constexpr U kIndexCount = 12 * 2;
 	constexpr U kIndexCount = 12 * 2;
@@ -174,21 +176,21 @@ void DebugDrawer2::drawCubes(ConstWeakArray<Mat4> mvps, const Vec4& color, F32 l
 }
 }
 
 
 void DebugDrawer2::drawLines(ConstWeakArray<Mat4> mvps, const Vec4& color, F32 lineSize, Bool ditherFailedDepth,
 void DebugDrawer2::drawLines(ConstWeakArray<Mat4> mvps, const Vec4& color, F32 lineSize, Bool ditherFailedDepth,
-							 ConstWeakArray<Vec3> linePositions, RebarStagingGpuMemoryPool& stagingGpuAllocator,
-							 CommandBufferPtr& cmdb) const
+							 ConstWeakArray<Vec3> linePositions, CommandBufferPtr& cmdb) const
 {
 {
 	ANKI_ASSERT(mvps.getSize() > 0);
 	ANKI_ASSERT(mvps.getSize() > 0);
 	ANKI_ASSERT(linePositions.getSize() > 0 && (linePositions.getSize() % 2) == 0);
 	ANKI_ASSERT(linePositions.getSize() > 0 && (linePositions.getSize() % 2) == 0);
 
 
 	// Verts
 	// Verts
 	RebarGpuMemoryToken vertsToken;
 	RebarGpuMemoryToken vertsToken;
-	Vec3* verts =
-		static_cast<Vec3*>(stagingGpuAllocator.allocateFrame(sizeof(Vec3) * linePositions.getSize(), vertsToken));
+	Vec3* verts = static_cast<Vec3*>(
+		RebarStagingGpuMemoryPool::getSingleton().allocateFrame(sizeof(Vec3) * linePositions.getSize(), vertsToken));
 	memcpy(verts, linePositions.getBegin(), linePositions.getSizeInBytes());
 	memcpy(verts, linePositions.getBegin(), linePositions.getSizeInBytes());
 
 
 	// Set the uniforms
 	// Set the uniforms
 	RebarGpuMemoryToken unisToken;
 	RebarGpuMemoryToken unisToken;
-	Mat4* pmvps = static_cast<Mat4*>(stagingGpuAllocator.allocateFrame(sizeof(Mat4) * mvps.getSize(), unisToken));
+	Mat4* pmvps = static_cast<Mat4*>(
+		RebarStagingGpuMemoryPool::getSingleton().allocateFrame(sizeof(Mat4) * mvps.getSize(), unisToken));
 	memcpy(pmvps, &mvps[0], mvps.getSizeInBytes());
 	memcpy(pmvps, &mvps[0], mvps.getSizeInBytes());
 
 
 	// Setup state
 	// Setup state
@@ -202,9 +204,10 @@ void DebugDrawer2::drawLines(ConstWeakArray<Mat4> mvps, const Vec4& color, F32 l
 	cmdb->setPushConstants(&color, sizeof(color));
 	cmdb->setPushConstants(&color, sizeof(color));
 
 
 	cmdb->setVertexAttribute(0, 0, Format::kR32G32B32_Sfloat, 0);
 	cmdb->setVertexAttribute(0, 0, Format::kR32G32B32_Sfloat, 0);
-	cmdb->bindVertexBuffer(0, stagingGpuAllocator.getBuffer(), vertsToken.m_offset, sizeof(Vec3));
+	cmdb->bindVertexBuffer(0, RebarStagingGpuMemoryPool::getSingleton().getBuffer(), vertsToken.m_offset, sizeof(Vec3));
 
 
-	cmdb->bindStorageBuffer(0, 0, stagingGpuAllocator.getBuffer(), unisToken.m_offset, unisToken.m_range);
+	cmdb->bindStorageBuffer(0, 0, RebarStagingGpuMemoryPool::getSingleton().getBuffer(), unisToken.m_offset,
+							unisToken.m_range);
 
 
 	cmdb->setLineWidth(lineSize);
 	cmdb->setLineWidth(lineSize);
 	cmdb->drawArrays(PrimitiveTopology::kLines, linePositions.getSize(), mvps.getSize());
 	cmdb->drawArrays(PrimitiveTopology::kLines, linePositions.getSize(), mvps.getSize());
@@ -212,11 +215,11 @@ void DebugDrawer2::drawLines(ConstWeakArray<Mat4> mvps, const Vec4& color, F32 l
 
 
 void DebugDrawer2::drawBillboardTextures(const Mat4& projMat, const Mat3x4& viewMat, ConstWeakArray<Vec3> positions,
 void DebugDrawer2::drawBillboardTextures(const Mat4& projMat, const Mat3x4& viewMat, ConstWeakArray<Vec3> positions,
 										 const Vec4& color, Bool ditherFailedDepth, TextureViewPtr tex,
 										 const Vec4& color, Bool ditherFailedDepth, TextureViewPtr tex,
-										 SamplerPtr sampler, Vec2 billboardSize,
-										 RebarStagingGpuMemoryPool& stagingGpuAllocator, CommandBufferPtr& cmdb) const
+										 SamplerPtr sampler, Vec2 billboardSize, CommandBufferPtr& cmdb) const
 {
 {
 	RebarGpuMemoryToken positionsToken;
 	RebarGpuMemoryToken positionsToken;
-	Vec3* verts = static_cast<Vec3*>(stagingGpuAllocator.allocateFrame(sizeof(Vec3) * 4, positionsToken));
+	Vec3* verts =
+		static_cast<Vec3*>(RebarStagingGpuMemoryPool::getSingleton().allocateFrame(sizeof(Vec3) * 4, positionsToken));
 
 
 	verts[0] = Vec3(-0.5f, -0.5f, 0.0f);
 	verts[0] = Vec3(-0.5f, -0.5f, 0.0f);
 	verts[1] = Vec3(+0.5f, -0.5f, 0.0f);
 	verts[1] = Vec3(+0.5f, -0.5f, 0.0f);
@@ -224,7 +227,7 @@ void DebugDrawer2::drawBillboardTextures(const Mat4& projMat, const Mat3x4& view
 	verts[3] = Vec3(+0.5f, +0.5f, 0.0f);
 	verts[3] = Vec3(+0.5f, +0.5f, 0.0f);
 
 
 	RebarGpuMemoryToken uvsToken;
 	RebarGpuMemoryToken uvsToken;
-	Vec2* uvs = static_cast<Vec2*>(stagingGpuAllocator.allocateFrame(sizeof(Vec2) * 4, uvsToken));
+	Vec2* uvs = static_cast<Vec2*>(RebarStagingGpuMemoryPool::getSingleton().allocateFrame(sizeof(Vec2) * 4, uvsToken));
 
 
 	uvs[0] = Vec2(0.0f, 0.0f);
 	uvs[0] = Vec2(0.0f, 0.0f);
 	uvs[1] = Vec2(1.0f, 0.0f);
 	uvs[1] = Vec2(1.0f, 0.0f);
@@ -233,7 +236,8 @@ void DebugDrawer2::drawBillboardTextures(const Mat4& projMat, const Mat3x4& view
 
 
 	// Set the uniforms
 	// Set the uniforms
 	RebarGpuMemoryToken unisToken;
 	RebarGpuMemoryToken unisToken;
-	Mat4* pmvps = static_cast<Mat4*>(stagingGpuAllocator.allocateFrame(sizeof(Mat4) * positions.getSize(), unisToken));
+	Mat4* pmvps = static_cast<Mat4*>(
+		RebarStagingGpuMemoryPool::getSingleton().allocateFrame(sizeof(Mat4) * positions.getSize(), unisToken));
 
 
 	const Mat4 camTrf = Mat4(viewMat, Vec4(0.0f, 0.0f, 0.0f, 1.0f)).getInverse();
 	const Mat4 camTrf = Mat4(viewMat, Vec4(0.0f, 0.0f, 0.0f, 1.0f)).getInverse();
 	const Vec3 zAxis = camTrf.getZAxis().xyz().getNormalized();
 	const Vec3 zAxis = camTrf.getZAxis().xyz().getNormalized();
@@ -268,10 +272,12 @@ void DebugDrawer2::drawBillboardTextures(const Mat4& projMat, const Mat3x4& view
 
 
 	cmdb->setVertexAttribute(0, 0, Format::kR32G32B32_Sfloat, 0);
 	cmdb->setVertexAttribute(0, 0, Format::kR32G32B32_Sfloat, 0);
 	cmdb->setVertexAttribute(1, 1, Format::kR32G32_Sfloat, 0);
 	cmdb->setVertexAttribute(1, 1, Format::kR32G32_Sfloat, 0);
-	cmdb->bindVertexBuffer(0, stagingGpuAllocator.getBuffer(), positionsToken.m_offset, sizeof(Vec3));
-	cmdb->bindVertexBuffer(1, stagingGpuAllocator.getBuffer(), uvsToken.m_offset, sizeof(Vec2));
+	cmdb->bindVertexBuffer(0, RebarStagingGpuMemoryPool::getSingleton().getBuffer(), positionsToken.m_offset,
+						   sizeof(Vec3));
+	cmdb->bindVertexBuffer(1, RebarStagingGpuMemoryPool::getSingleton().getBuffer(), uvsToken.m_offset, sizeof(Vec2));
 
 
-	cmdb->bindStorageBuffer(0, 0, stagingGpuAllocator.getBuffer(), unisToken.m_offset, unisToken.m_range);
+	cmdb->bindStorageBuffer(0, 0, RebarStagingGpuMemoryPool::getSingleton().getBuffer(), unisToken.m_offset,
+							unisToken.m_range);
 	cmdb->bindSampler(0, 3, sampler);
 	cmdb->bindSampler(0, 3, sampler);
 	cmdb->bindTexture(0, 4, tex);
 	cmdb->bindTexture(0, 4, tex);
 
 
@@ -303,7 +309,7 @@ void PhysicsDebugDrawer::flush()
 	if(m_vertCount > 0)
 	if(m_vertCount > 0)
 	{
 	{
 		m_dbg->drawLines(ConstWeakArray<Mat4>(&m_mvp, 1), m_currentColor, 2.0f, false,
 		m_dbg->drawLines(ConstWeakArray<Mat4>(&m_mvp, 1), m_currentColor, 2.0f, false,
-						 ConstWeakArray<Vec3>(&m_vertCache[0], m_vertCount), *m_stagingGpuAllocator, m_cmdb);
+						 ConstWeakArray<Vec3>(&m_vertCache[0], m_vertCount), m_cmdb);
 
 
 		m_vertCount = 0;
 		m_vertCount = 0;
 	}
 	}

+ 11 - 19
AnKi/Renderer/DebugDrawer.h

@@ -22,8 +22,7 @@ class RebarGpuMemoryToken;
 /// @{
 /// @{
 
 
 /// Allocate memory for a line cube and populate it.
 /// Allocate memory for a line cube and populate it.
-void allocateAndPopulateDebugBox(RebarStagingGpuMemoryPool& stagingGpuAllocator, RebarGpuMemoryToken& vertsToken,
-								 RebarGpuMemoryToken& indicesToken, U32& indexCount);
+void allocateAndPopulateDebugBox(RebarGpuMemoryToken& vertsToken, RebarGpuMemoryToken& indicesToken, U32& indexCount);
 
 
 /// Debug drawer.
 /// Debug drawer.
 class DebugDrawer2
 class DebugDrawer2
@@ -37,37 +36,34 @@ public:
 	}
 	}
 
 
 	void drawCubes(ConstWeakArray<Mat4> mvps, const Vec4& color, F32 lineSize, Bool ditherFailedDepth, F32 cubeSideSize,
 	void drawCubes(ConstWeakArray<Mat4> mvps, const Vec4& color, F32 lineSize, Bool ditherFailedDepth, F32 cubeSideSize,
-				   RebarStagingGpuMemoryPool& stagingGpuAllocator, CommandBufferPtr& cmdb) const;
+				   CommandBufferPtr& cmdb) const;
 
 
 	void drawCube(const Mat4& mvp, const Vec4& color, F32 lineSize, Bool ditherFailedDepth, F32 cubeSideSize,
 	void drawCube(const Mat4& mvp, const Vec4& color, F32 lineSize, Bool ditherFailedDepth, F32 cubeSideSize,
-				  RebarStagingGpuMemoryPool& stagingGpuAllocator, CommandBufferPtr& cmdb) const
+				  CommandBufferPtr& cmdb) const
 	{
 	{
-		drawCubes(ConstWeakArray<Mat4>(&mvp, 1), color, lineSize, ditherFailedDepth, cubeSideSize, stagingGpuAllocator,
-				  cmdb);
+		drawCubes(ConstWeakArray<Mat4>(&mvp, 1), color, lineSize, ditherFailedDepth, cubeSideSize, cmdb);
 	}
 	}
 
 
 	void drawLines(ConstWeakArray<Mat4> mvps, const Vec4& color, F32 lineSize, Bool ditherFailedDepth,
 	void drawLines(ConstWeakArray<Mat4> mvps, const Vec4& color, F32 lineSize, Bool ditherFailedDepth,
-				   ConstWeakArray<Vec3> linePositions, RebarStagingGpuMemoryPool& stagingGpuAllocator,
-				   CommandBufferPtr& cmdb) const;
+				   ConstWeakArray<Vec3> linePositions, CommandBufferPtr& cmdb) const;
 
 
 	void drawLine(const Mat4& mvp, const Vec4& color, F32 lineSize, Bool ditherFailedDepth, const Vec3& a,
 	void drawLine(const Mat4& mvp, const Vec4& color, F32 lineSize, Bool ditherFailedDepth, const Vec3& a,
-				  const Vec3& b, RebarStagingGpuMemoryPool& stagingGpuAllocator, CommandBufferPtr& cmdb) const
+				  const Vec3& b, CommandBufferPtr& cmdb) const
 	{
 	{
 		Array<Vec3, 2> points = {a, b};
 		Array<Vec3, 2> points = {a, b};
-		drawLines(ConstWeakArray<Mat4>(&mvp, 1), color, lineSize, ditherFailedDepth, points, stagingGpuAllocator, cmdb);
+		drawLines(ConstWeakArray<Mat4>(&mvp, 1), color, lineSize, ditherFailedDepth, points, cmdb);
 	}
 	}
 
 
 	void drawBillboardTextures(const Mat4& projMat, const Mat3x4& viewMat, ConstWeakArray<Vec3> positions,
 	void drawBillboardTextures(const Mat4& projMat, const Mat3x4& viewMat, ConstWeakArray<Vec3> positions,
 							   const Vec4& color, Bool ditherFailedDepth, TextureViewPtr tex, SamplerPtr sampler,
 							   const Vec4& color, Bool ditherFailedDepth, TextureViewPtr tex, SamplerPtr sampler,
-							   Vec2 billboardSize, RebarStagingGpuMemoryPool& stagingGpuAllocator,
-							   CommandBufferPtr& cmdb) const;
+							   Vec2 billboardSize, CommandBufferPtr& cmdb) const;
 
 
 	void drawBillboardTexture(const Mat4& projMat, const Mat3x4& viewMat, Vec3 position, const Vec4& color,
 	void drawBillboardTexture(const Mat4& projMat, const Mat3x4& viewMat, Vec3 position, const Vec4& color,
 							  Bool ditherFailedDepth, TextureViewPtr tex, SamplerPtr sampler, Vec2 billboardSize,
 							  Bool ditherFailedDepth, TextureViewPtr tex, SamplerPtr sampler, Vec2 billboardSize,
-							  RebarStagingGpuMemoryPool& stagingGpuAllocator, CommandBufferPtr& cmdb) const
+							  CommandBufferPtr& cmdb) const
 	{
 	{
 		drawBillboardTextures(projMat, viewMat, ConstWeakArray<Vec3>(&position, 1), color, ditherFailedDepth, tex,
 		drawBillboardTextures(projMat, viewMat, ConstWeakArray<Vec3>(&position, 1), color, ditherFailedDepth, tex,
-							  sampler, billboardSize, stagingGpuAllocator, cmdb);
+							  sampler, billboardSize, cmdb);
 	}
 	}
 
 
 private:
 private:
@@ -85,13 +81,11 @@ public:
 	{
 	{
 	}
 	}
 
 
-	void start(const Mat4& mvp, CommandBufferPtr& cmdb, RebarStagingGpuMemoryPool* stagingGpuAllocator)
+	void start(const Mat4& mvp, CommandBufferPtr& cmdb)
 	{
 	{
-		ANKI_ASSERT(stagingGpuAllocator);
 		ANKI_ASSERT(m_vertCount == 0);
 		ANKI_ASSERT(m_vertCount == 0);
 		m_mvp = mvp;
 		m_mvp = mvp;
 		m_cmdb = cmdb;
 		m_cmdb = cmdb;
-		m_stagingGpuAllocator = stagingGpuAllocator;
 	}
 	}
 
 
 	void drawLines(const Vec3* lines, const U32 vertCount, const Vec4& color) final;
 	void drawLines(const Vec3* lines, const U32 vertCount, const Vec4& color) final;
@@ -100,14 +94,12 @@ public:
 	{
 	{
 		flush();
 		flush();
 		m_cmdb.reset(nullptr); // This is essential!!!
 		m_cmdb.reset(nullptr); // This is essential!!!
-		m_stagingGpuAllocator = nullptr;
 	}
 	}
 
 
 private:
 private:
 	const DebugDrawer2* m_dbg; ///< The debug drawer
 	const DebugDrawer2* m_dbg; ///< The debug drawer
 	Mat4 m_mvp = Mat4::getIdentity();
 	Mat4 m_mvp = Mat4::getIdentity();
 	CommandBufferPtr m_cmdb;
 	CommandBufferPtr m_cmdb;
-	RebarStagingGpuMemoryPool* m_stagingGpuAllocator = nullptr;
 
 
 	// Use a vertex cache because drawLines() is practically called for every line
 	// Use a vertex cache because drawLines() is practically called for every line
 	Array<Vec3, 32> m_vertCache;
 	Array<Vec3, 32> m_vertCache;

+ 13 - 14
AnKi/Renderer/Drawer.cpp

@@ -20,8 +20,6 @@ class RenderableDrawer::Context
 public:
 public:
 	CommandBufferPtr m_commandBuffer;
 	CommandBufferPtr m_commandBuffer;
 
 
-	RebarStagingGpuMemoryPool* m_rebarStagingPool = nullptr;
-
 	Array<const RenderableQueueElement*, kMaxInstanceCount> m_cachedRenderElements;
 	Array<const RenderableQueueElement*, kMaxInstanceCount> m_cachedRenderElements;
 	U32 m_cachedRenderElementCount = 0;
 	U32 m_cachedRenderElementCount = 0;
 	ShaderProgram* m_lastBoundShaderProgram = nullptr;
 	ShaderProgram* m_lastBoundShaderProgram = nullptr;
@@ -40,7 +38,7 @@ void RenderableDrawer::drawRange(const RenderableDrawerArguments& args, const Re
 	{
 	{
 		RebarGpuMemoryToken globalUniformsToken;
 		RebarGpuMemoryToken globalUniformsToken;
 		MaterialGlobalUniforms* globalUniforms =
 		MaterialGlobalUniforms* globalUniforms =
-			static_cast<MaterialGlobalUniforms*>(m_r->getExternalSubsystems().m_rebarStagingPool->allocateFrame(
+			static_cast<MaterialGlobalUniforms*>(RebarStagingGpuMemoryPool::getSingleton().allocateFrame(
 				sizeof(MaterialGlobalUniforms), globalUniformsToken));
 				sizeof(MaterialGlobalUniforms), globalUniformsToken));
 
 
 		globalUniforms->m_viewProjectionMatrix = args.m_viewProjectionMatrix;
 		globalUniforms->m_viewProjectionMatrix = args.m_viewProjectionMatrix;
@@ -51,28 +49,28 @@ void RenderableDrawer::drawRange(const RenderableDrawerArguments& args, const Re
 		memcpy(&globalUniforms->m_cameraTransform, &args.m_cameraTransform, sizeof(args.m_cameraTransform));
 		memcpy(&globalUniforms->m_cameraTransform, &args.m_cameraTransform, sizeof(args.m_cameraTransform));
 
 
 		cmdb->bindUniformBuffer(U32(MaterialSet::kGlobal), U32(MaterialBinding::kGlobalUniforms),
 		cmdb->bindUniformBuffer(U32(MaterialSet::kGlobal), U32(MaterialBinding::kGlobalUniforms),
-								m_r->getExternalSubsystems().m_rebarStagingPool->getBuffer(),
-								globalUniformsToken.m_offset, globalUniformsToken.m_range);
+								RebarStagingGpuMemoryPool::getSingleton().getBuffer(), globalUniformsToken.m_offset,
+								globalUniformsToken.m_range);
 	}
 	}
 
 
 	// More globals
 	// More globals
 	cmdb->bindAllBindless(U32(MaterialSet::kBindless));
 	cmdb->bindAllBindless(U32(MaterialSet::kBindless));
 	cmdb->bindSampler(U32(MaterialSet::kGlobal), U32(MaterialBinding::kTrilinearRepeatSampler), args.m_sampler);
 	cmdb->bindSampler(U32(MaterialSet::kGlobal), U32(MaterialBinding::kTrilinearRepeatSampler), args.m_sampler);
-	cmdb->bindStorageBuffer(U32(MaterialSet::kGlobal), U32(MaterialBinding::kGpuScene), args.m_gpuSceneBuffer, 0,
-							kMaxPtrSize);
+	cmdb->bindStorageBuffer(U32(MaterialSet::kGlobal), U32(MaterialBinding::kGpuScene),
+							GpuSceneMemoryPool::getSingleton().getBuffer(), 0, kMaxPtrSize);
 
 
 #define ANKI_UNIFIED_GEOM_FORMAT(fmt, shaderType) \
 #define ANKI_UNIFIED_GEOM_FORMAT(fmt, shaderType) \
 	cmdb->bindReadOnlyTextureBuffer(U32(MaterialSet::kGlobal), U32(MaterialBinding::kUnifiedGeometry_##fmt), \
 	cmdb->bindReadOnlyTextureBuffer(U32(MaterialSet::kGlobal), U32(MaterialBinding::kUnifiedGeometry_##fmt), \
-									args.m_unifiedGeometryBuffer, 0, kMaxPtrSize, Format::k##fmt);
+									UnifiedGeometryMemoryPool::getSingleton().getBuffer(), 0, kMaxPtrSize, \
+									Format::k##fmt);
 #include <AnKi/Shaders/Include/UnifiedGeometryTypes.defs.h>
 #include <AnKi/Shaders/Include/UnifiedGeometryTypes.defs.h>
 
 
 	// Misc
 	// Misc
 	cmdb->setVertexAttribute(0, 0, Format::kR32G32B32A32_Uint, 0);
 	cmdb->setVertexAttribute(0, 0, Format::kR32G32B32A32_Uint, 0);
-	cmdb->bindIndexBuffer(args.m_unifiedGeometryBuffer, 0, IndexType::kU16);
+	cmdb->bindIndexBuffer(UnifiedGeometryMemoryPool::getSingleton().getBuffer(), 0, IndexType::kU16);
 
 
 	// Set a few things
 	// Set a few things
 	Context ctx;
 	Context ctx;
-	ctx.m_rebarStagingPool = m_r->getExternalSubsystems().m_rebarStagingPool;
 	ctx.m_commandBuffer = cmdb;
 	ctx.m_commandBuffer = cmdb;
 
 
 	for(; begin != end; ++begin)
 	for(; begin != end; ++begin)
@@ -90,8 +88,9 @@ void RenderableDrawer::flushDrawcall(Context& ctx)
 
 
 	// Instance buffer
 	// Instance buffer
 	RebarGpuMemoryToken token;
 	RebarGpuMemoryToken token;
-	GpuSceneRenderablePacked* instances = static_cast<GpuSceneRenderablePacked*>(ctx.m_rebarStagingPool->allocateFrame(
-		sizeof(GpuSceneRenderablePacked) * ctx.m_cachedRenderElementCount, token));
+	GpuSceneRenderablePacked* instances =
+		static_cast<GpuSceneRenderablePacked*>(RebarStagingGpuMemoryPool::getSingleton().allocateFrame(
+			sizeof(GpuSceneRenderablePacked) * ctx.m_cachedRenderElementCount, token));
 	for(U32 i = 0; i < ctx.m_cachedRenderElementCount; ++i)
 	for(U32 i = 0; i < ctx.m_cachedRenderElementCount; ++i)
 	{
 	{
 		GpuSceneRenderable renderable = {};
 		GpuSceneRenderable renderable = {};
@@ -102,8 +101,8 @@ void RenderableDrawer::flushDrawcall(Context& ctx)
 		instances[i] = packGpuSceneRenderable(renderable);
 		instances[i] = packGpuSceneRenderable(renderable);
 	}
 	}
 
 
-	cmdb->bindVertexBuffer(0, ctx.m_rebarStagingPool->getBuffer(), token.m_offset, sizeof(GpuSceneRenderablePacked),
-						   VertexStepRate::kInstance);
+	cmdb->bindVertexBuffer(0, RebarStagingGpuMemoryPool::getSingleton().getBuffer(), token.m_offset,
+						   sizeof(GpuSceneRenderablePacked), VertexStepRate::kInstance);
 
 
 	// Set state
 	// Set state
 	const RenderableQueueElement& firstElement = *ctx.m_cachedRenderElements[0];
 	const RenderableQueueElement& firstElement = *ctx.m_cachedRenderElements[0];

+ 0 - 2
AnKi/Renderer/Drawer.h

@@ -28,8 +28,6 @@ public:
 	Mat4 m_previousViewProjectionMatrix;
 	Mat4 m_previousViewProjectionMatrix;
 
 
 	SamplerPtr m_sampler;
 	SamplerPtr m_sampler;
-	BufferPtr m_gpuSceneBuffer;
-	BufferPtr m_unifiedGeometryBuffer;
 };
 };
 
 
 /// It uses the render queue to batch and render.
 /// It uses the render queue to batch and render.

+ 0 - 2
AnKi/Renderer/ForwardShading.cpp

@@ -62,8 +62,6 @@ void ForwardShading::run(const RenderingContext& ctx, RenderPassWorkContext& rgr
 		args.m_viewProjectionMatrix = ctx.m_matrices.m_viewProjectionJitter;
 		args.m_viewProjectionMatrix = ctx.m_matrices.m_viewProjectionJitter;
 		args.m_previousViewProjectionMatrix = ctx.m_prevMatrices.m_viewProjectionJitter; // Not sure about that
 		args.m_previousViewProjectionMatrix = ctx.m_prevMatrices.m_viewProjectionJitter; // Not sure about that
 		args.m_sampler = m_r->getSamplers().m_trilinearRepeatAnisoResolutionScalingBias;
 		args.m_sampler = m_r->getSamplers().m_trilinearRepeatAnisoResolutionScalingBias;
-		args.m_gpuSceneBuffer = getExternalSubsystems().m_gpuScenePool->getBuffer();
-		args.m_unifiedGeometryBuffer = getExternalSubsystems().m_unifiedGometryMemoryPool->getBuffer();
 
 
 		// Start drawing
 		// Start drawing
 		m_r->getSceneDrawer().drawRange(args, ctx.m_renderQueue->m_forwardShadingRenderables.getBegin() + start,
 		m_r->getSceneDrawer().drawRange(args, ctx.m_renderQueue->m_forwardShadingRenderables.getBegin() + start,

+ 0 - 2
AnKi/Renderer/GBuffer.cpp

@@ -126,8 +126,6 @@ void GBuffer::runInThread(const RenderingContext& ctx, RenderPassWorkContext& rg
 	args.m_viewProjectionMatrix = ctx.m_matrices.m_viewProjectionJitter;
 	args.m_viewProjectionMatrix = ctx.m_matrices.m_viewProjectionJitter;
 	args.m_previousViewProjectionMatrix = ctx.m_matrices.m_jitter * ctx.m_prevMatrices.m_viewProjection;
 	args.m_previousViewProjectionMatrix = ctx.m_matrices.m_jitter * ctx.m_prevMatrices.m_viewProjection;
 	args.m_sampler = m_r->getSamplers().m_trilinearRepeatAnisoResolutionScalingBias;
 	args.m_sampler = m_r->getSamplers().m_trilinearRepeatAnisoResolutionScalingBias;
-	args.m_gpuSceneBuffer = getExternalSubsystems().m_gpuScenePool->getBuffer();
-	args.m_unifiedGeometryBuffer = getExternalSubsystems().m_unifiedGometryMemoryPool->getBuffer();
 
 
 	// First do early Z (if needed)
 	// First do early Z (if needed)
 	if(earlyZStart < earlyZEnd)
 	if(earlyZStart < earlyZEnd)

+ 1 - 1
AnKi/Renderer/GenericCompute.cpp

@@ -36,7 +36,7 @@ void GenericCompute::run(const RenderingContext& ctx, RenderPassWorkContext& rgr
 
 
 	GenericGpuComputeJobQueueElementContext elementCtx;
 	GenericGpuComputeJobQueueElementContext elementCtx;
 	elementCtx.m_commandBuffer = rgraphCtx.m_commandBuffer;
 	elementCtx.m_commandBuffer = rgraphCtx.m_commandBuffer;
-	elementCtx.m_rebarStagingPool = m_r->getExternalSubsystems().m_rebarStagingPool;
+	elementCtx.m_rebarStagingPool = &RebarStagingGpuMemoryPool::getSingleton();
 	elementCtx.m_viewMatrix = ctx.m_matrices.m_view;
 	elementCtx.m_viewMatrix = ctx.m_matrices.m_view;
 	elementCtx.m_viewProjectionMatrix = ctx.m_matrices.m_viewProjection;
 	elementCtx.m_viewProjectionMatrix = ctx.m_matrices.m_viewProjection;
 	elementCtx.m_projectionMatrix = ctx.m_matrices.m_projection;
 	elementCtx.m_projectionMatrix = ctx.m_matrices.m_projection;

+ 0 - 4
AnKi/Renderer/IndirectDiffuseProbes.cpp

@@ -373,8 +373,6 @@ void IndirectDiffuseProbes::runGBufferInThread(RenderPassWorkContext& rgraphCtx,
 			args.m_viewProjectionMatrix = rqueue.m_viewProjectionMatrix;
 			args.m_viewProjectionMatrix = rqueue.m_viewProjectionMatrix;
 			args.m_previousViewProjectionMatrix = Mat4::getIdentity(); // Don't care
 			args.m_previousViewProjectionMatrix = Mat4::getIdentity(); // Don't care
 			args.m_sampler = m_r->getSamplers().m_trilinearRepeat;
 			args.m_sampler = m_r->getSamplers().m_trilinearRepeat;
-			args.m_gpuSceneBuffer = getExternalSubsystems().m_gpuScenePool->getBuffer();
-			args.m_unifiedGeometryBuffer = getExternalSubsystems().m_unifiedGometryMemoryPool->getBuffer();
 
 
 			m_r->getSceneDrawer().drawRange(args, rqueue.m_renderables.getBegin() + localStart,
 			m_r->getSceneDrawer().drawRange(args, rqueue.m_renderables.getBegin() + localStart,
 											rqueue.m_renderables.getBegin() + localEnd, cmdb);
 											rqueue.m_renderables.getBegin() + localEnd, cmdb);
@@ -431,8 +429,6 @@ void IndirectDiffuseProbes::runShadowmappingInThread(RenderPassWorkContext& rgra
 			args.m_viewProjectionMatrix = cascadeRenderQueue.m_viewProjectionMatrix;
 			args.m_viewProjectionMatrix = cascadeRenderQueue.m_viewProjectionMatrix;
 			args.m_previousViewProjectionMatrix = Mat4::getIdentity(); // Don't care
 			args.m_previousViewProjectionMatrix = Mat4::getIdentity(); // Don't care
 			args.m_sampler = m_r->getSamplers().m_trilinearRepeatAniso;
 			args.m_sampler = m_r->getSamplers().m_trilinearRepeatAniso;
-			args.m_gpuSceneBuffer = getExternalSubsystems().m_gpuScenePool->getBuffer();
-			args.m_unifiedGeometryBuffer = getExternalSubsystems().m_unifiedGometryMemoryPool->getBuffer();
 
 
 			m_r->getSceneDrawer().drawRange(args, cascadeRenderQueue.m_renderables.getBegin() + localStart,
 			m_r->getSceneDrawer().drawRange(args, cascadeRenderQueue.m_renderables.getBegin() + localStart,
 											cascadeRenderQueue.m_renderables.getBegin() + localEnd, cmdb);
 											cascadeRenderQueue.m_renderables.getBegin() + localEnd, cmdb);

+ 3 - 4
AnKi/Renderer/MainRenderer.cpp

@@ -141,7 +141,7 @@ Error MainRenderer::render(RenderQueue& rqueue, TexturePtr presentTex)
 
 
 	// Populate the 2nd level command buffers
 	// Populate the 2nd level command buffers
 	Array<ThreadHiveTask, ThreadHive::kMaxThreads> tasks;
 	Array<ThreadHiveTask, ThreadHive::kMaxThreads> tasks;
-	for(U i = 0; i < m_r->getExternalSubsystems().m_threadHive->getThreadCount(); ++i)
+	for(U i = 0; i < CoreThreadHive::getSingleton().getThreadCount(); ++i)
 	{
 	{
 		tasks[i].m_argument = this;
 		tasks[i].m_argument = this;
 		tasks[i].m_callback = [](void* userData, [[maybe_unused]] U32 threadId, [[maybe_unused]] ThreadHive& hive,
 		tasks[i].m_callback = [](void* userData, [[maybe_unused]] U32 threadId, [[maybe_unused]] ThreadHive& hive,
@@ -152,9 +152,8 @@ Error MainRenderer::render(RenderQueue& rqueue, TexturePtr presentTex)
 			self.m_rgraph->runSecondLevel(taskId);
 			self.m_rgraph->runSecondLevel(taskId);
 		};
 		};
 	}
 	}
-	m_r->getExternalSubsystems().m_threadHive->submitTasks(&tasks[0],
-														   m_r->getExternalSubsystems().m_threadHive->getThreadCount());
-	m_r->getExternalSubsystems().m_threadHive->waitAllTasks();
+	CoreThreadHive::getSingleton().submitTasks(&tasks[0], CoreThreadHive::getSingleton().getThreadCount());
+	CoreThreadHive::getSingleton().waitAllTasks();
 
 
 	// Populate 1st level command buffers
 	// Populate 1st level command buffers
 	m_rgraph->run();
 	m_rgraph->run();

+ 3 - 4
AnKi/Renderer/PackVisibleClusteredObjects.cpp

@@ -121,18 +121,17 @@ void PackVisibleClusteredObjects::dispatchType(WeakArray<TRenderQueueElement> ar
 		}
 		}
 	}
 	}
 
 
-	cmdb->bindStorageBuffer(0, 0, getExternalSubsystems().m_gpuScenePool->getBuffer(),
+	cmdb->bindStorageBuffer(0, 0, GpuSceneMemoryPool::getSingleton().getBuffer(),
 							rqueue.m_clustererObjectsArrayOffsets[kType], rqueue.m_clustererObjectsArrayRanges[kType]);
 							rqueue.m_clustererObjectsArrayOffsets[kType], rqueue.m_clustererObjectsArrayRanges[kType]);
 
 
 	cmdb->bindStorageBuffer(0, 1, m_allClustererObjects, m_structureBufferOffsets[kType],
 	cmdb->bindStorageBuffer(0, 1, m_allClustererObjects, m_structureBufferOffsets[kType],
 							array.getSize() * sizeof(TClustererType));
 							array.getSize() * sizeof(TClustererType));
 
 
-	cmdb->bindStorageBuffer(0, 2, getExternalSubsystems().m_rebarStagingPool->getBuffer(), token.m_offset,
-							token.m_range);
+	cmdb->bindStorageBuffer(0, 2, RebarStagingGpuMemoryPool::getSingleton().getBuffer(), token.m_offset, token.m_range);
 
 
 	if constexpr(std::is_same_v<TClustererType, PointLight> || std::is_same_v<TClustererType, SpotLight>)
 	if constexpr(std::is_same_v<TClustererType, PointLight> || std::is_same_v<TClustererType, SpotLight>)
 	{
 	{
-		cmdb->bindStorageBuffer(0, 3, getExternalSubsystems().m_rebarStagingPool->getBuffer(), extrasToken.m_offset,
+		cmdb->bindStorageBuffer(0, 3, RebarStagingGpuMemoryPool::getSingleton().getBuffer(), extrasToken.m_offset,
 								extrasToken.m_range);
 								extrasToken.m_range);
 	}
 	}
 
 

+ 0 - 4
AnKi/Renderer/ProbeReflections.cpp

@@ -229,8 +229,6 @@ void ProbeReflections::runGBuffer(RenderPassWorkContext& rgraphCtx)
 			args.m_viewProjectionMatrix = rqueue.m_viewProjectionMatrix;
 			args.m_viewProjectionMatrix = rqueue.m_viewProjectionMatrix;
 			args.m_previousViewProjectionMatrix = Mat4::getIdentity(); // Don't care about prev mats
 			args.m_previousViewProjectionMatrix = Mat4::getIdentity(); // Don't care about prev mats
 			args.m_sampler = m_r->getSamplers().m_trilinearRepeat;
 			args.m_sampler = m_r->getSamplers().m_trilinearRepeat;
-			args.m_gpuSceneBuffer = getExternalSubsystems().m_gpuScenePool->getBuffer();
-			args.m_unifiedGeometryBuffer = getExternalSubsystems().m_unifiedGometryMemoryPool->getBuffer();
 
 
 			m_r->getSceneDrawer().drawRange(args, rqueue.m_renderables.getBegin() + localStart,
 			m_r->getSceneDrawer().drawRange(args, rqueue.m_renderables.getBegin() + localStart,
 											rqueue.m_renderables.getBegin() + localEnd, cmdb);
 											rqueue.m_renderables.getBegin() + localEnd, cmdb);
@@ -595,8 +593,6 @@ void ProbeReflections::runShadowMapping(RenderPassWorkContext& rgraphCtx)
 			args.m_viewProjectionMatrix = cascadeRenderQueue.m_viewProjectionMatrix;
 			args.m_viewProjectionMatrix = cascadeRenderQueue.m_viewProjectionMatrix;
 			args.m_previousViewProjectionMatrix = Mat4::getIdentity(); // Don't care
 			args.m_previousViewProjectionMatrix = Mat4::getIdentity(); // Don't care
 			args.m_sampler = m_r->getSamplers().m_trilinearRepeatAniso;
 			args.m_sampler = m_r->getSamplers().m_trilinearRepeatAniso;
-			args.m_gpuSceneBuffer = getExternalSubsystems().m_gpuScenePool->getBuffer();
-			args.m_unifiedGeometryBuffer = getExternalSubsystems().m_unifiedGometryMemoryPool->getBuffer();
 
 
 			m_r->getSceneDrawer().drawRange(args, cascadeRenderQueue.m_renderables.getBegin() + localStart,
 			m_r->getSceneDrawer().drawRange(args, cascadeRenderQueue.m_renderables.getBegin() + localStart,
 											cascadeRenderQueue.m_renderables.getBegin() + localEnd, cmdb);
 											cascadeRenderQueue.m_renderables.getBegin() + localEnd, cmdb);

+ 4 - 6
AnKi/Renderer/Renderer.cpp

@@ -695,18 +695,16 @@ void Renderer::gpuSceneCopy(RenderingContext& ctx)
 {
 {
 	RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
 	RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
 
 
-	m_runCtx.m_gpuSceneHandle = rgraph.importBuffer(m_subsystems.m_gpuScenePool->getBuffer(),
-													m_subsystems.m_gpuScenePool->getBuffer()->getBufferUsage());
+	m_runCtx.m_gpuSceneHandle = rgraph.importBuffer(GpuSceneMemoryPool::getSingleton().getBuffer(),
+													GpuSceneMemoryPool::getSingleton().getBuffer()->getBufferUsage());
 
 
-	if(m_subsystems.m_gpuSceneMicroPatcher->patchingIsNeeded())
+	if(GpuSceneMicroPatcher::getSingleton().patchingIsNeeded())
 	{
 	{
 		ComputeRenderPassDescription& rpass = rgraph.newComputeRenderPass("GPU scene patching");
 		ComputeRenderPassDescription& rpass = rgraph.newComputeRenderPass("GPU scene patching");
 		rpass.newBufferDependency(m_runCtx.m_gpuSceneHandle, BufferUsageBit::kStorageComputeWrite);
 		rpass.newBufferDependency(m_runCtx.m_gpuSceneHandle, BufferUsageBit::kStorageComputeWrite);
 
 
 		rpass.setWork([this](RenderPassWorkContext& rgraphCtx) {
 		rpass.setWork([this](RenderPassWorkContext& rgraphCtx) {
-			m_subsystems.m_gpuSceneMicroPatcher->patchGpuScene(*m_subsystems.m_rebarStagingPool,
-															   *rgraphCtx.m_commandBuffer.get(),
-															   m_subsystems.m_gpuScenePool->getBuffer());
+			GpuSceneMicroPatcher::getSingleton().patchGpuScene(*rgraphCtx.m_commandBuffer.get());
 		});
 		});
 	}
 	}
 }
 }

+ 5 - 5
AnKi/Renderer/RendererObject.cpp

@@ -27,14 +27,14 @@ HeapMemoryPool& RendererObject::getMemoryPool() const
 
 
 void* RendererObject::allocateRebarStagingMemory(PtrSize size, RebarGpuMemoryToken& token)
 void* RendererObject::allocateRebarStagingMemory(PtrSize size, RebarGpuMemoryToken& token)
 {
 {
-	return getExternalSubsystems().m_rebarStagingPool->allocateFrame(size, token);
+	return RebarStagingGpuMemoryPool::getSingleton().allocateFrame(size, token);
 }
 }
 
 
 void RendererObject::bindUniforms(CommandBufferPtr& cmdb, U32 set, U32 binding, const RebarGpuMemoryToken& token) const
 void RendererObject::bindUniforms(CommandBufferPtr& cmdb, U32 set, U32 binding, const RebarGpuMemoryToken& token) const
 {
 {
 	if(!token.isUnused())
 	if(!token.isUnused())
 	{
 	{
-		cmdb->bindUniformBuffer(set, binding, getExternalSubsystems().m_rebarStagingPool->getBuffer(), token.m_offset,
+		cmdb->bindUniformBuffer(set, binding, RebarStagingGpuMemoryPool::getSingleton().getBuffer(), token.m_offset,
 								token.m_range);
 								token.m_range);
 	}
 	}
 	else
 	else
@@ -47,7 +47,7 @@ void RendererObject::bindStorage(CommandBufferPtr& cmdb, U32 set, U32 binding, c
 {
 {
 	if(!token.isUnused())
 	if(!token.isUnused())
 	{
 	{
-		cmdb->bindStorageBuffer(set, binding, getExternalSubsystems().m_rebarStagingPool->getBuffer(), token.m_offset,
+		cmdb->bindStorageBuffer(set, binding, RebarStagingGpuMemoryPool::getSingleton().getBuffer(), token.m_offset,
 								token.m_range);
 								token.m_range);
 	}
 	}
 	else
 	else
@@ -58,7 +58,7 @@ void RendererObject::bindStorage(CommandBufferPtr& cmdb, U32 set, U32 binding, c
 
 
 U32 RendererObject::computeNumberOfSecondLevelCommandBuffers(U32 drawcallCount) const
 U32 RendererObject::computeNumberOfSecondLevelCommandBuffers(U32 drawcallCount) const
 {
 {
-	const U32 drawcallsPerThread = drawcallCount / getExternalSubsystems().m_threadHive->getThreadCount();
+	const U32 drawcallsPerThread = drawcallCount / CoreThreadHive::getSingleton().getThreadCount();
 	U32 secondLevelCmdbCount;
 	U32 secondLevelCmdbCount;
 	if(drawcallsPerThread < kMinDrawcallsPerSecondaryCommandBuffer)
 	if(drawcallsPerThread < kMinDrawcallsPerSecondaryCommandBuffer)
 	{
 	{
@@ -66,7 +66,7 @@ U32 RendererObject::computeNumberOfSecondLevelCommandBuffers(U32 drawcallCount)
 	}
 	}
 	else
 	else
 	{
 	{
-		secondLevelCmdbCount = getExternalSubsystems().m_threadHive->getThreadCount();
+		secondLevelCmdbCount = CoreThreadHive::getSingleton().getThreadCount();
 	}
 	}
 
 
 	return secondLevelCmdbCount;
 	return secondLevelCmdbCount;

+ 5 - 5
AnKi/Renderer/RtShadows.cpp

@@ -449,13 +449,13 @@ void RtShadows::run(RenderPassWorkContext& rgraphCtx)
 	{
 	{
 		RebarGpuMemoryToken globalUniformsToken;
 		RebarGpuMemoryToken globalUniformsToken;
 		MaterialGlobalUniforms* globalUniforms =
 		MaterialGlobalUniforms* globalUniforms =
-			static_cast<MaterialGlobalUniforms*>(getExternalSubsystems().m_rebarStagingPool->allocateFrame(
+			static_cast<MaterialGlobalUniforms*>(RebarStagingGpuMemoryPool::getSingleton().allocateFrame(
 				sizeof(MaterialGlobalUniforms), globalUniformsToken));
 				sizeof(MaterialGlobalUniforms), globalUniformsToken));
 
 
 		memset(globalUniforms, 0, sizeof(*globalUniforms)); // Don't care for now
 		memset(globalUniforms, 0, sizeof(*globalUniforms)); // Don't care for now
 
 
 		cmdb->bindUniformBuffer(U32(MaterialSet::kGlobal), U32(MaterialBinding::kGlobalUniforms),
 		cmdb->bindUniformBuffer(U32(MaterialSet::kGlobal), U32(MaterialBinding::kGlobalUniforms),
-								getExternalSubsystems().m_rebarStagingPool->getBuffer(), globalUniformsToken.m_offset,
+								RebarStagingGpuMemoryPool::getSingleton().getBuffer(), globalUniformsToken.m_offset,
 								globalUniformsToken.m_range);
 								globalUniformsToken.m_range);
 	}
 	}
 
 
@@ -464,11 +464,11 @@ void RtShadows::run(RenderPassWorkContext& rgraphCtx)
 	cmdb->bindSampler(U32(MaterialSet::kGlobal), U32(MaterialBinding::kTrilinearRepeatSampler),
 	cmdb->bindSampler(U32(MaterialSet::kGlobal), U32(MaterialBinding::kTrilinearRepeatSampler),
 					  m_r->getSamplers().m_trilinearRepeat);
 					  m_r->getSamplers().m_trilinearRepeat);
 	cmdb->bindStorageBuffer(U32(MaterialSet::kGlobal), U32(MaterialBinding::kGpuScene),
 	cmdb->bindStorageBuffer(U32(MaterialSet::kGlobal), U32(MaterialBinding::kGpuScene),
-							getExternalSubsystems().m_gpuScenePool->getBuffer(), 0, kMaxPtrSize);
+							GpuSceneMemoryPool::getSingleton().getBuffer(), 0, kMaxPtrSize);
 
 
 #define ANKI_UNIFIED_GEOM_FORMAT(fmt, shaderType) \
 #define ANKI_UNIFIED_GEOM_FORMAT(fmt, shaderType) \
 	cmdb->bindReadOnlyTextureBuffer(U32(MaterialSet::kGlobal), U32(MaterialBinding::kUnifiedGeometry_##fmt), \
 	cmdb->bindReadOnlyTextureBuffer(U32(MaterialSet::kGlobal), U32(MaterialBinding::kUnifiedGeometry_##fmt), \
-									getExternalSubsystems().m_unifiedGometryMemoryPool->getBuffer(), 0, kMaxPtrSize, \
+									UnifiedGeometryMemoryPool::getSingleton().getBuffer(), 0, kMaxPtrSize, \
 									Format::k##fmt);
 									Format::k##fmt);
 #include <AnKi/Shaders/Include/UnifiedGeometryTypes.defs.h>
 #include <AnKi/Shaders/Include/UnifiedGeometryTypes.defs.h>
 
 
@@ -637,7 +637,7 @@ void RtShadows::buildSbt(RenderingContext& ctx)
 	RebarGpuMemoryToken token;
 	RebarGpuMemoryToken token;
 	U8* sbt = allocateStorage<U8*>(PtrSize(m_sbtRecordSize) * (instanceCount + extraSbtRecords), token);
 	U8* sbt = allocateStorage<U8*>(PtrSize(m_sbtRecordSize) * (instanceCount + extraSbtRecords), token);
 	[[maybe_unused]] const U8* sbtStart = sbt;
 	[[maybe_unused]] const U8* sbtStart = sbt;
-	m_runCtx.m_sbtBuffer = getExternalSubsystems().m_rebarStagingPool->getBuffer();
+	m_runCtx.m_sbtBuffer = RebarStagingGpuMemoryPool::getSingleton().getBuffer();
 	m_runCtx.m_sbtOffset = token.m_offset;
 	m_runCtx.m_sbtOffset = token.m_offset;
 
 
 	// Set the miss and ray gen handles
 	// Set the miss and ray gen handles

+ 1 - 3
AnKi/Renderer/ShadowMapping.cpp

@@ -119,7 +119,7 @@ void ShadowMapping::populateRenderGraph(RenderingContext& ctx)
 		GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass("ShadowMapping");
 		GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass("ShadowMapping");
 
 
 		pass.setFramebufferInfo(m_fbDescr, {}, m_runCtx.m_rt, {}, minx, miny, width, height);
 		pass.setFramebufferInfo(m_fbDescr, {}, m_runCtx.m_rt, {}, minx, miny, width, height);
-		ANKI_ASSERT(threadCountForPass && threadCountForPass <= getExternalSubsystems().m_threadHive->getThreadCount());
+		ANKI_ASSERT(threadCountForPass && threadCountForPass <= CoreThreadHive::getSingleton().getThreadCount());
 		pass.setWork(threadCountForPass, [this](RenderPassWorkContext& rgraphCtx) {
 		pass.setWork(threadCountForPass, [this](RenderPassWorkContext& rgraphCtx) {
 			runShadowMapping(rgraphCtx);
 			runShadowMapping(rgraphCtx);
 		});
 		});
@@ -615,8 +615,6 @@ void ShadowMapping::runShadowMapping(RenderPassWorkContext& rgraphCtx)
 		args.m_viewProjectionMatrix = work.m_renderQueue->m_viewProjectionMatrix;
 		args.m_viewProjectionMatrix = work.m_renderQueue->m_viewProjectionMatrix;
 		args.m_previousViewProjectionMatrix = Mat4::getIdentity(); // Don't care
 		args.m_previousViewProjectionMatrix = Mat4::getIdentity(); // Don't care
 		args.m_sampler = m_r->getSamplers().m_trilinearRepeatAniso;
 		args.m_sampler = m_r->getSamplers().m_trilinearRepeatAniso;
-		args.m_gpuSceneBuffer = getExternalSubsystems().m_gpuScenePool->getBuffer();
-		args.m_unifiedGeometryBuffer = getExternalSubsystems().m_unifiedGometryMemoryPool->getBuffer();
 
 
 		m_r->getSceneDrawer().drawRange(args,
 		m_r->getSceneDrawer().drawRange(args,
 										work.m_renderQueue->m_renderables.getBegin() + work.m_firstRenderableElement,
 										work.m_renderQueue->m_renderables.getBegin() + work.m_firstRenderableElement,

+ 0 - 1
AnKi/Resource/Common.h

@@ -63,7 +63,6 @@ class ResourceManagerExternalSubsystems
 public:
 public:
 	GrManager* m_grManager = nullptr;
 	GrManager* m_grManager = nullptr;
 	ResourceFilesystem* m_resourceFilesystem = nullptr;
 	ResourceFilesystem* m_resourceFilesystem = nullptr;
-	UnifiedGeometryMemoryPool* m_unifiedGometryMemoryPool = nullptr;
 };
 };
 /// @}
 /// @}
 
 

+ 12 - 13
AnKi/Resource/MeshResource.cpp

@@ -59,12 +59,11 @@ MeshResource::~MeshResource()
 
 
 	for(Lod& lod : m_lods)
 	for(Lod& lod : m_lods)
 	{
 	{
-		getExternalSubsystems().m_unifiedGometryMemoryPool->deferredFree(lod.m_indexBufferAllocationToken);
+		UnifiedGeometryMemoryPool::getSingleton().deferredFree(lod.m_indexBufferAllocationToken);
 
 
 		for(VertexStreamId stream : EnumIterable(VertexStreamId::kMeshRelatedFirst, VertexStreamId::kMeshRelatedCount))
 		for(VertexStreamId stream : EnumIterable(VertexStreamId::kMeshRelatedFirst, VertexStreamId::kMeshRelatedCount))
 		{
 		{
-			getExternalSubsystems().m_unifiedGometryMemoryPool->deferredFree(
-				lod.m_vertexBuffersAllocationToken[stream]);
+			UnifiedGeometryMemoryPool::getSingleton().deferredFree(lod.m_vertexBuffersAllocationToken[stream]);
 		}
 		}
 	}
 	}
 
 
@@ -125,8 +124,8 @@ Error MeshResource::load(const ResourceFilename& filename, Bool async)
 		lod.m_indexCount = header.m_totalIndexCounts[l];
 		lod.m_indexCount = header.m_totalIndexCounts[l];
 		ANKI_ASSERT((lod.m_indexCount % 3) == 0 && "Expecting triangles");
 		ANKI_ASSERT((lod.m_indexCount % 3) == 0 && "Expecting triangles");
 		const PtrSize indexBufferSize = PtrSize(lod.m_indexCount) * getIndexSize(m_indexType);
 		const PtrSize indexBufferSize = PtrSize(lod.m_indexCount) * getIndexSize(m_indexType);
-		getExternalSubsystems().m_unifiedGometryMemoryPool->allocate(indexBufferSize, getIndexSize(m_indexType),
-																	 lod.m_indexBufferAllocationToken);
+		UnifiedGeometryMemoryPool::getSingleton().allocate(indexBufferSize, getIndexSize(m_indexType),
+														   lod.m_indexBufferAllocationToken);
 
 
 		// Vertex stuff
 		// Vertex stuff
 		lod.m_vertexCount = header.m_totalVertexCounts[l];
 		lod.m_vertexCount = header.m_totalVertexCounts[l];
@@ -143,8 +142,8 @@ Error MeshResource::load(const ResourceFilename& filename, Bool async)
 			const U32 alignment = max(4u, nextPowerOfTwo(texelSize));
 			const U32 alignment = max(4u, nextPowerOfTwo(texelSize));
 			const PtrSize vertexBufferSize = PtrSize(lod.m_vertexCount) * texelSize + alignment;
 			const PtrSize vertexBufferSize = PtrSize(lod.m_vertexCount) * texelSize + alignment;
 
 
-			getExternalSubsystems().m_unifiedGometryMemoryPool->allocate(vertexBufferSize, alignment,
-																		 lod.m_vertexBuffersAllocationToken[stream]);
+			UnifiedGeometryMemoryPool::getSingleton().allocate(vertexBufferSize, alignment,
+															   lod.m_vertexBuffersAllocationToken[stream]);
 
 
 			// We need to align the actual offset to the texel size
 			// We need to align the actual offset to the texel size
 			const PtrSize remainder = lod.m_vertexBuffersAllocationToken[stream].m_offset % texelSize;
 			const PtrSize remainder = lod.m_vertexBuffersAllocationToken[stream].m_offset % texelSize;
@@ -165,11 +164,11 @@ Error MeshResource::load(const ResourceFilename& filename, Bool async)
 				StringRaii(&getTempMemoryPool()).sprintf("%s_%s", "Blas", basename.cstr()));
 				StringRaii(&getTempMemoryPool()).sprintf("%s_%s", "Blas", basename.cstr()));
 			inf.m_type = AccelerationStructureType::kBottomLevel;
 			inf.m_type = AccelerationStructureType::kBottomLevel;
 
 
-			inf.m_bottomLevel.m_indexBuffer = getExternalSubsystems().m_unifiedGometryMemoryPool->getBuffer();
+			inf.m_bottomLevel.m_indexBuffer = UnifiedGeometryMemoryPool::getSingleton().getBuffer();
 			inf.m_bottomLevel.m_indexBufferOffset = lod.m_indexBufferAllocationToken.m_offset;
 			inf.m_bottomLevel.m_indexBufferOffset = lod.m_indexBufferAllocationToken.m_offset;
 			inf.m_bottomLevel.m_indexCount = lod.m_indexCount;
 			inf.m_bottomLevel.m_indexCount = lod.m_indexCount;
 			inf.m_bottomLevel.m_indexType = m_indexType;
 			inf.m_bottomLevel.m_indexType = m_indexType;
-			inf.m_bottomLevel.m_positionBuffer = getExternalSubsystems().m_unifiedGometryMemoryPool->getBuffer();
+			inf.m_bottomLevel.m_positionBuffer = UnifiedGeometryMemoryPool::getSingleton().getBuffer();
 			inf.m_bottomLevel.m_positionBufferOffset =
 			inf.m_bottomLevel.m_positionBufferOffset =
 				lod.m_vertexBuffersAllocationToken[VertexStreamId::kPosition].m_offset
 				lod.m_vertexBuffersAllocationToken[VertexStreamId::kPosition].m_offset
 				+ lod.m_fixedUnifiedGeometryBufferOffset[VertexStreamId::kPosition];
 				+ lod.m_fixedUnifiedGeometryBufferOffset[VertexStreamId::kPosition];
@@ -191,7 +190,7 @@ Error MeshResource::load(const ResourceFilename& filename, Bool async)
 
 
 		for(const Lod& lod : m_lods)
 		for(const Lod& lod : m_lods)
 		{
 		{
-			cmdb->fillBuffer(getExternalSubsystems().m_unifiedGometryMemoryPool->getBuffer(),
+			cmdb->fillBuffer(UnifiedGeometryMemoryPool::getSingleton().getBuffer(),
 							 lod.m_indexBufferAllocationToken.m_offset,
 							 lod.m_indexBufferAllocationToken.m_offset,
 							 PtrSize(lod.m_indexCount) * getIndexSize(m_indexType), 0);
 							 PtrSize(lod.m_indexCount) * getIndexSize(m_indexType), 0);
 
 
@@ -200,14 +199,14 @@ Error MeshResource::load(const ResourceFilename& filename, Bool async)
 			{
 			{
 				if(header.m_vertexAttributes[stream].m_format != Format::kNone)
 				if(header.m_vertexAttributes[stream].m_format != Format::kNone)
 				{
 				{
-					cmdb->fillBuffer(getExternalSubsystems().m_unifiedGometryMemoryPool->getBuffer(),
+					cmdb->fillBuffer(UnifiedGeometryMemoryPool::getSingleton().getBuffer(),
 									 lod.m_vertexBuffersAllocationToken[stream].m_offset,
 									 lod.m_vertexBuffersAllocationToken[stream].m_offset,
 									 lod.m_vertexBuffersAllocationToken[stream].m_size, 0);
 									 lod.m_vertexBuffersAllocationToken[stream].m_size, 0);
 				}
 				}
 			}
 			}
 		}
 		}
 
 
-		const BufferBarrierInfo barrier = {getExternalSubsystems().m_unifiedGometryMemoryPool->getBuffer().get(),
+		const BufferBarrierInfo barrier = {UnifiedGeometryMemoryPool::getSingleton().getBuffer().get(),
 										   BufferUsageBit::kTransferDestination, BufferUsageBit::kVertex, 0,
 										   BufferUsageBit::kTransferDestination, BufferUsageBit::kVertex, 0,
 										   kMaxPtrSize};
 										   kMaxPtrSize};
 
 
@@ -239,7 +238,7 @@ Error MeshResource::loadAsync(MeshBinaryLoader& loader) const
 	Array<TransferGpuAllocatorHandle, kMaxLodCount*(U32(VertexStreamId::kMeshRelatedCount) + 1)> handles;
 	Array<TransferGpuAllocatorHandle, kMaxLodCount*(U32(VertexStreamId::kMeshRelatedCount) + 1)> handles;
 	U32 handleCount = 0;
 	U32 handleCount = 0;
 
 
-	BufferPtr unifiedGeometryBuffer = getExternalSubsystems().m_unifiedGometryMemoryPool->getBuffer();
+	BufferPtr unifiedGeometryBuffer = UnifiedGeometryMemoryPool::getSingleton().getBuffer();
 	const BufferUsageBit unifiedGeometryBufferNonTransferUsage =
 	const BufferUsageBit unifiedGeometryBufferNonTransferUsage =
 		unifiedGeometryBuffer->getBufferUsage() ^ BufferUsageBit::kTransferDestination;
 		unifiedGeometryBuffer->getBufferUsage() ^ BufferUsageBit::kTransferDestination;
 
 

+ 0 - 4
AnKi/Scene/Common.h

@@ -45,15 +45,11 @@ class PhysicsWorld;
 class SceneGraphExternalSubsystems
 class SceneGraphExternalSubsystems
 {
 {
 public:
 public:
-	ThreadHive* m_threadHive = nullptr;
 	ResourceManager* m_resourceManager = nullptr;
 	ResourceManager* m_resourceManager = nullptr;
 	ScriptManager* m_scriptManager = nullptr;
 	ScriptManager* m_scriptManager = nullptr;
 	UiManager* m_uiManager = nullptr;
 	UiManager* m_uiManager = nullptr;
 	GrManager* m_grManager = nullptr;
 	GrManager* m_grManager = nullptr;
 	const Timestamp* m_globalTimestamp = nullptr;
 	const Timestamp* m_globalTimestamp = nullptr;
-	UnifiedGeometryMemoryPool* m_unifiedGeometryMemPool = nullptr;
-	GpuSceneMemoryPool* m_gpuSceneMemoryPool = nullptr;
-	GpuSceneMicroPatcher* m_gpuSceneMicroPatcher = nullptr;
 };
 };
 /// @}
 /// @}
 
 

+ 1 - 2
AnKi/Scene/Components/DecalComponent.cpp

@@ -97,8 +97,7 @@ Error DecalComponent::update(SceneComponentUpdateInfo& info, Bool& updated)
 		const PtrSize offset = m_gpuSceneIndex * sizeof(GpuSceneDecal)
 		const PtrSize offset = m_gpuSceneIndex * sizeof(GpuSceneDecal)
 							   + info.m_node->getSceneGraph().getAllGpuSceneContiguousArrays().getArrayBase(
 							   + info.m_node->getSceneGraph().getAllGpuSceneContiguousArrays().getArrayBase(
 								   GpuSceneContiguousArrayType::kDecals);
 								   GpuSceneContiguousArrayType::kDecals);
-		getExternalSubsystems(*info.m_node)
-			.m_gpuSceneMicroPatcher->newCopy(*info.m_framePool, offset, sizeof(gpuDecal), &gpuDecal);
+		GpuSceneMicroPatcher::getSingleton().newCopy(*info.m_framePool, offset, sizeof(gpuDecal), &gpuDecal);
 	}
 	}
 
 
 	const Bool spatialUpdated = m_spatial.update(info.m_node->getSceneGraph().getOctree());
 	const Bool spatialUpdated = m_spatial.update(info.m_node->getSceneGraph().getOctree());

+ 1 - 2
AnKi/Scene/Components/FogDensityComponent.cpp

@@ -64,8 +64,7 @@ Error FogDensityComponent::update(SceneComponentUpdateInfo& info, Bool& updated)
 		const PtrSize offset = m_gpuSceneIndex * sizeof(GpuSceneFogDensityVolume)
 		const PtrSize offset = m_gpuSceneIndex * sizeof(GpuSceneFogDensityVolume)
 							   + info.m_node->getSceneGraph().getAllGpuSceneContiguousArrays().getArrayBase(
 							   + info.m_node->getSceneGraph().getAllGpuSceneContiguousArrays().getArrayBase(
 								   GpuSceneContiguousArrayType::kFogDensityVolumes);
 								   GpuSceneContiguousArrayType::kFogDensityVolumes);
-		getExternalSubsystems(*info.m_node)
-			.m_gpuSceneMicroPatcher->newCopy(*info.m_framePool, offset, sizeof(gpuVolume), &gpuVolume);
+		GpuSceneMicroPatcher::getSingleton().newCopy(*info.m_framePool, offset, sizeof(gpuVolume), &gpuVolume);
 	}
 	}
 
 
 	const Bool spatialUpdated = m_spatial.update(info.m_node->getSceneGraph().getOctree());
 	const Bool spatialUpdated = m_spatial.update(info.m_node->getSceneGraph().getOctree());

+ 1 - 2
AnKi/Scene/Components/GlobalIlluminationProbeComponent.cpp

@@ -131,8 +131,7 @@ Error GlobalIlluminationProbeComponent::update(SceneComponentUpdateInfo& info, B
 		const PtrSize offset = m_gpuSceneIndex * sizeof(GpuSceneGlobalIlluminationProbe)
 		const PtrSize offset = m_gpuSceneIndex * sizeof(GpuSceneGlobalIlluminationProbe)
 							   + info.m_node->getSceneGraph().getAllGpuSceneContiguousArrays().getArrayBase(
 							   + info.m_node->getSceneGraph().getAllGpuSceneContiguousArrays().getArrayBase(
 								   GpuSceneContiguousArrayType::kGlobalIlluminationProbes);
 								   GpuSceneContiguousArrayType::kGlobalIlluminationProbes);
-		getExternalSubsystems(*info.m_node)
-			.m_gpuSceneMicroPatcher->newCopy(*info.m_framePool, offset, sizeof(gpuProbe), &gpuProbe);
+		GpuSceneMicroPatcher::getSingleton().newCopy(*info.m_framePool, offset, sizeof(gpuProbe), &gpuProbe);
 	}
 	}
 
 
 	if(needsRefresh()) [[unlikely]]
 	if(needsRefresh()) [[unlikely]]

+ 2 - 4
AnKi/Scene/Components/LightComponent.cpp

@@ -135,11 +135,10 @@ Error LightComponent::update(SceneComponentUpdateInfo& info, Bool& updated)
 		gpuLight.m_diffuseColor = m_diffColor.xyz();
 		gpuLight.m_diffuseColor = m_diffColor.xyz();
 		gpuLight.m_squareRadiusOverOne = 1.0f / (m_point.m_radius * m_point.m_radius);
 		gpuLight.m_squareRadiusOverOne = 1.0f / (m_point.m_radius * m_point.m_radius);
 		gpuLight.m_shadow = m_shadow;
 		gpuLight.m_shadow = m_shadow;
-		GpuSceneMicroPatcher& gpuScenePatcher = *getExternalSubsystems(*info.m_node).m_gpuSceneMicroPatcher;
 		const PtrSize offset = m_gpuSceneLightIndex * sizeof(GpuScenePointLight)
 		const PtrSize offset = m_gpuSceneLightIndex * sizeof(GpuScenePointLight)
 							   + info.m_node->getSceneGraph().getAllGpuSceneContiguousArrays().getArrayBase(
 							   + info.m_node->getSceneGraph().getAllGpuSceneContiguousArrays().getArrayBase(
 								   GpuSceneContiguousArrayType::kPointLights);
 								   GpuSceneContiguousArrayType::kPointLights);
-		gpuScenePatcher.newCopy(*info.m_framePool, offset, sizeof(gpuLight), &gpuLight);
+		GpuSceneMicroPatcher::getSingleton().newCopy(*info.m_framePool, offset, sizeof(gpuLight), &gpuLight);
 	}
 	}
 	else if(updated && m_type == LightComponentType::kSpot)
 	else if(updated && m_type == LightComponentType::kSpot)
 	{
 	{
@@ -205,11 +204,10 @@ Error LightComponent::update(SceneComponentUpdateInfo& info, Bool& updated)
 		gpuLight.m_shadow = m_shadow;
 		gpuLight.m_shadow = m_shadow;
 		gpuLight.m_outerCos = cos(m_spot.m_outerAngle / 2.0f);
 		gpuLight.m_outerCos = cos(m_spot.m_outerAngle / 2.0f);
 		gpuLight.m_innerCos = cos(m_spot.m_innerAngle / 2.0f);
 		gpuLight.m_innerCos = cos(m_spot.m_innerAngle / 2.0f);
-		GpuSceneMicroPatcher& gpuScenePatcher = *getExternalSubsystems(*info.m_node).m_gpuSceneMicroPatcher;
 		const PtrSize offset = m_gpuSceneLightIndex * sizeof(GpuSceneSpotLight)
 		const PtrSize offset = m_gpuSceneLightIndex * sizeof(GpuSceneSpotLight)
 							   + info.m_node->getSceneGraph().getAllGpuSceneContiguousArrays().getArrayBase(
 							   + info.m_node->getSceneGraph().getAllGpuSceneContiguousArrays().getArrayBase(
 								   GpuSceneContiguousArrayType::kSpotLights);
 								   GpuSceneContiguousArrayType::kSpotLights);
-		gpuScenePatcher.newCopy(*info.m_framePool, offset, sizeof(gpuLight), &gpuLight);
+		GpuSceneMicroPatcher::getSingleton().newCopy(*info.m_framePool, offset, sizeof(gpuLight), &gpuLight);
 	}
 	}
 	else if(m_type == LightComponentType::kDirectional)
 	else if(m_type == LightComponentType::kDirectional)
 	{
 	{

+ 8 - 13
AnKi/Scene/Components/ModelComponent.cpp

@@ -24,8 +24,7 @@ ModelComponent::ModelComponent(SceneNode* node)
 
 
 ModelComponent::~ModelComponent()
 ModelComponent::~ModelComponent()
 {
 {
-	GpuSceneMemoryPool& gpuScene = *getExternalSubsystems(*m_node).m_gpuSceneMemoryPool;
-	gpuScene.deferredFree(m_gpuSceneUniforms);
+	GpuSceneMemoryPool::getSingleton().deferredFree(m_gpuSceneUniforms);
 
 
 	for(const PatchInfo& patch : m_patchInfos)
 	for(const PatchInfo& patch : m_patchInfos)
 	{
 	{
@@ -60,8 +59,6 @@ void ModelComponent::loadModelResource(CString filename)
 	const U32 modelPatchCount = m_model->getModelPatches().getSize();
 	const U32 modelPatchCount = m_model->getModelPatches().getSize();
 
 
 	// GPU scene allocations
 	// GPU scene allocations
-	GpuSceneMemoryPool& gpuScene = *getExternalSubsystems(*m_node).m_gpuSceneMemoryPool;
-
 	for(const PatchInfo& patch : m_patchInfos)
 	for(const PatchInfo& patch : m_patchInfos)
 	{
 	{
 		if(patch.m_gpuSceneMeshLodsIndex != kMaxU32)
 		if(patch.m_gpuSceneMeshLodsIndex != kMaxU32)
@@ -88,8 +85,8 @@ void ModelComponent::loadModelResource(CString filename)
 		uniformsSize += size;
 		uniformsSize += size;
 	}
 	}
 
 
-	gpuScene.deferredFree(m_gpuSceneUniforms);
-	gpuScene.allocate(uniformsSize, 4, m_gpuSceneUniforms);
+	GpuSceneMemoryPool::getSingleton().deferredFree(m_gpuSceneUniforms);
+	GpuSceneMemoryPool::getSingleton().allocate(uniformsSize, 4, m_gpuSceneUniforms);
 
 
 	for(U32 i = 0; i < modelPatchCount; ++i)
 	for(U32 i = 0; i < modelPatchCount; ++i)
 	{
 	{
@@ -129,8 +126,6 @@ Error ModelComponent::update(SceneComponentUpdateInfo& info, Bool& updated)
 	// Upload mesh LODs and uniforms
 	// Upload mesh LODs and uniforms
 	if(resourceUpdated) [[unlikely]]
 	if(resourceUpdated) [[unlikely]]
 	{
 	{
-		GpuSceneMicroPatcher& gpuScenePatcher = *getExternalSubsystems(*info.m_node).m_gpuSceneMicroPatcher;
-
 		// Upload the mesh views
 		// Upload the mesh views
 		const U32 modelPatchCount = m_model->getModelPatches().getSize();
 		const U32 modelPatchCount = m_model->getModelPatches().getSize();
 		for(U32 i = 0; i < modelPatchCount; ++i)
 		for(U32 i = 0; i < modelPatchCount; ++i)
@@ -184,7 +179,8 @@ Error ModelComponent::update(SceneComponentUpdateInfo& info, Bool& updated)
 			const PtrSize offset = m_patchInfos[i].m_gpuSceneMeshLodsIndex * sizeof(meshLods)
 			const PtrSize offset = m_patchInfos[i].m_gpuSceneMeshLodsIndex * sizeof(meshLods)
 								   + info.m_node->getSceneGraph().getAllGpuSceneContiguousArrays().getArrayBase(
 								   + info.m_node->getSceneGraph().getAllGpuSceneContiguousArrays().getArrayBase(
 									   GpuSceneContiguousArrayType::kMeshLods);
 									   GpuSceneContiguousArrayType::kMeshLods);
-			gpuScenePatcher.newCopy(*info.m_framePool, offset, meshLods.getSizeInBytes(), &meshLods[0]);
+			GpuSceneMicroPatcher::getSingleton().newCopy(*info.m_framePool, offset, meshLods.getSizeInBytes(),
+														 &meshLods[0]);
 		}
 		}
 
 
 		// Upload the uniforms
 		// Upload the uniforms
@@ -201,8 +197,8 @@ Error ModelComponent::update(SceneComponentUpdateInfo& info, Bool& updated)
 		}
 		}
 
 
 		ANKI_ASSERT(count * 4 == m_gpuSceneUniforms.m_size);
 		ANKI_ASSERT(count * 4 == m_gpuSceneUniforms.m_size);
-		gpuScenePatcher.newCopy(*info.m_framePool, m_gpuSceneUniforms.m_offset, m_gpuSceneUniforms.m_size,
-								&allUniforms[0]);
+		GpuSceneMicroPatcher::getSingleton().newCopy(*info.m_framePool, m_gpuSceneUniforms.m_offset,
+													 m_gpuSceneUniforms.m_size, &allUniforms[0]);
 	}
 	}
 
 
 	// Upload transforms
 	// Upload transforms
@@ -215,8 +211,7 @@ Error ModelComponent::update(SceneComponentUpdateInfo& info, Bool& updated)
 		const PtrSize offset = m_gpuSceneTransformsIndex * sizeof(trfs)
 		const PtrSize offset = m_gpuSceneTransformsIndex * sizeof(trfs)
 							   + info.m_node->getSceneGraph().getAllGpuSceneContiguousArrays().getArrayBase(
 							   + info.m_node->getSceneGraph().getAllGpuSceneContiguousArrays().getArrayBase(
 								   GpuSceneContiguousArrayType::kTransformPairs);
 								   GpuSceneContiguousArrayType::kTransformPairs);
-		getExternalSubsystems(*info.m_node)
-			.m_gpuSceneMicroPatcher->newCopy(*info.m_framePool, offset, sizeof(trfs), &trfs[0]);
+		GpuSceneMicroPatcher::getSingleton().newCopy(*info.m_framePool, offset, sizeof(trfs), &trfs[0]);
 	}
 	}
 
 
 	// Spatial update
 	// Spatial update

+ 3 - 3
AnKi/Scene/Components/ParticleEmitterComponent.cpp

@@ -205,7 +205,7 @@ ParticleEmitterComponent::~ParticleEmitterComponent()
 	m_simpleParticles.destroy(m_node->getMemoryPool());
 	m_simpleParticles.destroy(m_node->getMemoryPool());
 	m_physicsParticles.destroy(m_node->getMemoryPool());
 	m_physicsParticles.destroy(m_node->getMemoryPool());
 
 
-	GpuSceneMemoryPool& gpuScenePool = *getExternalSubsystems(*m_node).m_gpuSceneMemoryPool;
+	GpuSceneMemoryPool& gpuScenePool = GpuSceneMemoryPool::getSingleton();
 	gpuScenePool.deferredFree(m_gpuScenePositions);
 	gpuScenePool.deferredFree(m_gpuScenePositions);
 	gpuScenePool.deferredFree(m_gpuSceneScales);
 	gpuScenePool.deferredFree(m_gpuSceneScales);
 	gpuScenePool.deferredFree(m_gpuSceneAlphas);
 	gpuScenePool.deferredFree(m_gpuSceneAlphas);
@@ -239,7 +239,7 @@ void ParticleEmitterComponent::loadParticleEmitterResource(CString filename)
 	// Cleanup
 	// Cleanup
 	m_simpleParticles.destroy(m_node->getMemoryPool());
 	m_simpleParticles.destroy(m_node->getMemoryPool());
 	m_physicsParticles.destroy(m_node->getMemoryPool());
 	m_physicsParticles.destroy(m_node->getMemoryPool());
-	GpuSceneMemoryPool& gpuScenePool = *getExternalSubsystems(*m_node).m_gpuSceneMemoryPool;
+	GpuSceneMemoryPool& gpuScenePool = GpuSceneMemoryPool::getSingleton();
 	gpuScenePool.deferredFree(m_gpuScenePositions);
 	gpuScenePool.deferredFree(m_gpuScenePositions);
 	gpuScenePool.deferredFree(m_gpuSceneScales);
 	gpuScenePool.deferredFree(m_gpuSceneScales);
 	gpuScenePool.deferredFree(m_gpuSceneAlphas);
 	gpuScenePool.deferredFree(m_gpuSceneAlphas);
@@ -314,7 +314,7 @@ Error ParticleEmitterComponent::update(SceneComponentUpdateInfo& info, Bool& upd
 	m_spatial.update(info.m_node->getSceneGraph().getOctree());
 	m_spatial.update(info.m_node->getSceneGraph().getOctree());
 
 
 	// Upload to the GPU scene
 	// Upload to the GPU scene
-	GpuSceneMicroPatcher& patcher = *info.m_gpuSceneMicroPatcher;
+	GpuSceneMicroPatcher& patcher = GpuSceneMicroPatcher::getSingleton();
 	if(m_aliveParticleCount > 0)
 	if(m_aliveParticleCount > 0)
 	{
 	{
 		patcher.newCopy(*info.m_framePool, m_gpuScenePositions.m_offset, sizeof(Vec3) * m_aliveParticleCount,
 		patcher.newCopy(*info.m_framePool, m_gpuScenePositions.m_offset, sizeof(Vec3) * m_aliveParticleCount,

+ 1 - 2
AnKi/Scene/Components/ReflectionProbeComponent.cpp

@@ -105,8 +105,7 @@ Error ReflectionProbeComponent::update(SceneComponentUpdateInfo& info, Bool& upd
 		const PtrSize offset = m_gpuSceneIndex * sizeof(GpuSceneReflectionProbe)
 		const PtrSize offset = m_gpuSceneIndex * sizeof(GpuSceneReflectionProbe)
 							   + info.m_node->getSceneGraph().getAllGpuSceneContiguousArrays().getArrayBase(
 							   + info.m_node->getSceneGraph().getAllGpuSceneContiguousArrays().getArrayBase(
 								   GpuSceneContiguousArrayType::kReflectionProbes);
 								   GpuSceneContiguousArrayType::kReflectionProbes);
-		getExternalSubsystems(*info.m_node)
-			.m_gpuSceneMicroPatcher->newCopy(*info.m_framePool, offset, sizeof(gpuProbe), &gpuProbe);
+		GpuSceneMicroPatcher::getSingleton().newCopy(*info.m_framePool, offset, sizeof(gpuProbe), &gpuProbe);
 	}
 	}
 
 
 	// Update spatial and frustums
 	// Update spatial and frustums

+ 0 - 1
AnKi/Scene/Components/SceneComponent.h

@@ -102,7 +102,6 @@ public:
 	const Second m_currentTime;
 	const Second m_currentTime;
 	const Second m_dt;
 	const Second m_dt;
 	StackMemoryPool* m_framePool = nullptr;
 	StackMemoryPool* m_framePool = nullptr;
-	GpuSceneMicroPatcher* m_gpuSceneMicroPatcher = nullptr;
 
 
 	SceneComponentUpdateInfo(Second prevTime, Second crntTime)
 	SceneComponentUpdateInfo(Second prevTime, Second crntTime)
 		: m_previousTime(prevTime)
 		: m_previousTime(prevTime)

+ 5 - 6
AnKi/Scene/Components/SkinComponent.cpp

@@ -25,7 +25,7 @@ SkinComponent::~SkinComponent()
 	m_boneTrfs[1].destroy(m_node->getMemoryPool());
 	m_boneTrfs[1].destroy(m_node->getMemoryPool());
 	m_animationTrfs.destroy(m_node->getMemoryPool());
 	m_animationTrfs.destroy(m_node->getMemoryPool());
 
 
-	getExternalSubsystems(*m_node).m_gpuSceneMemoryPool->deferredFree(m_boneTransformsGpuSceneOffset);
+	GpuSceneMemoryPool::getSingleton().deferredFree(m_boneTransformsGpuSceneOffset);
 }
 }
 
 
 void SkinComponent::loadSkeletonResource(CString fname)
 void SkinComponent::loadSkeletonResource(CString fname)
@@ -46,7 +46,7 @@ void SkinComponent::loadSkeletonResource(CString fname)
 	m_boneTrfs[0].destroy(m_node->getMemoryPool());
 	m_boneTrfs[0].destroy(m_node->getMemoryPool());
 	m_boneTrfs[1].destroy(m_node->getMemoryPool());
 	m_boneTrfs[1].destroy(m_node->getMemoryPool());
 	m_animationTrfs.destroy(m_node->getMemoryPool());
 	m_animationTrfs.destroy(m_node->getMemoryPool());
-	getExternalSubsystems(*m_node).m_gpuSceneMemoryPool->deferredFree(m_boneTransformsGpuSceneOffset);
+	GpuSceneMemoryPool::getSingleton().deferredFree(m_boneTransformsGpuSceneOffset);
 
 
 	// Create
 	// Create
 	const U32 boneCount = m_skeleton->getBones().getSize();
 	const U32 boneCount = m_skeleton->getBones().getSize();
@@ -54,8 +54,7 @@ void SkinComponent::loadSkeletonResource(CString fname)
 	m_boneTrfs[1].create(m_node->getMemoryPool(), boneCount, Mat3x4::getIdentity());
 	m_boneTrfs[1].create(m_node->getMemoryPool(), boneCount, Mat3x4::getIdentity());
 	m_animationTrfs.create(m_node->getMemoryPool(), boneCount, {Vec3(0.0f), Quat::getIdentity(), 1.0f});
 	m_animationTrfs.create(m_node->getMemoryPool(), boneCount, {Vec3(0.0f), Quat::getIdentity(), 1.0f});
 
 
-	getExternalSubsystems(*m_node).m_gpuSceneMemoryPool->allocate(sizeof(Mat4) * boneCount * 2, 4,
-																  m_boneTransformsGpuSceneOffset);
+	GpuSceneMemoryPool::getSingleton().allocate(sizeof(Mat4) * boneCount * 2, 4, m_boneTransformsGpuSceneOffset);
 }
 }
 
 
 void SkinComponent::playAnimation(U32 track, AnimationResourcePtr anim, const AnimationPlayInfo& info)
 void SkinComponent::playAnimation(U32 track, AnimationResourcePtr anim, const AnimationPlayInfo& info)
@@ -205,8 +204,8 @@ Error SkinComponent::update(SceneComponentUpdateInfo& info, Bool& updated)
 			trfs[i * 2 + 0] = getBoneTransforms()[i];
 			trfs[i * 2 + 0] = getBoneTransforms()[i];
 			trfs[i * 2 + 1] = getPreviousFrameBoneTransforms()[i];
 			trfs[i * 2 + 1] = getPreviousFrameBoneTransforms()[i];
 		}
 		}
-		info.m_gpuSceneMicroPatcher->newCopy(*info.m_framePool, m_boneTransformsGpuSceneOffset.m_offset,
-											 trfs.getSizeInBytes(), trfs.getBegin());
+		GpuSceneMicroPatcher::getSingleton().newCopy(*info.m_framePool, m_boneTransformsGpuSceneOffset.m_offset,
+													 trfs.getSizeInBytes(), trfs.getBegin());
 	}
 	}
 	else
 	else
 	{
 	{

+ 15 - 16
AnKi/Scene/ContiguousArrayAllocator.cpp

@@ -10,28 +10,29 @@
 
 
 namespace anki {
 namespace anki {
 
 
-void AllGpuSceneContiguousArrays::ContiguousArrayAllocator::destroy(GpuSceneMemoryPool* gpuScene,
-																	HeapMemoryPool* cpuPool)
+void AllGpuSceneContiguousArrays::ContiguousArrayAllocator::destroy(HeapMemoryPool* cpuPool)
 {
 {
 	for(U32 i = 0; i < kMaxFramesInFlight; ++i)
 	for(U32 i = 0; i < kMaxFramesInFlight; ++i)
 	{
 	{
-		collectGarbage(i, gpuScene, cpuPool);
+		collectGarbage(i, cpuPool);
 	}
 	}
 }
 }
 
 
 AllGpuSceneContiguousArrays::Index
 AllGpuSceneContiguousArrays::Index
-AllGpuSceneContiguousArrays::ContiguousArrayAllocator::allocateObject(GpuSceneMemoryPool* gpuScene,
-																	  HeapMemoryPool* cpuPool)
+AllGpuSceneContiguousArrays::ContiguousArrayAllocator::allocateObject(HeapMemoryPool* cpuPool)
 {
 {
-	ANKI_ASSERT(gpuScene && cpuPool);
+	ANKI_ASSERT(cpuPool);
 
 
 	LockGuard lock(m_mtx);
 	LockGuard lock(m_mtx);
 
 
 	if(m_poolToken.m_offset == kMaxPtrSize)
 	if(m_poolToken.m_offset == kMaxPtrSize)
 	{
 	{
 		// Initialize
 		// Initialize
-		const U32 alignment = gpuScene->getGrManager().getDeviceCapabilities().m_storageBufferBindOffsetAlignment;
-		gpuScene->allocate(m_objectSize * m_initialArraySize, alignment, m_poolToken);
+		const U32 alignment = GpuSceneMemoryPool::getSingleton()
+								  .getGrManager()
+								  .getDeviceCapabilities()
+								  .m_storageBufferBindOffsetAlignment;
+		GpuSceneMemoryPool::getSingleton().allocate(m_objectSize * m_initialArraySize, alignment, m_poolToken);
 		m_nextSlotIndex = 0;
 		m_nextSlotIndex = 0;
 
 
 		m_freeSlotStack.create(*cpuPool, m_initialArraySize);
 		m_freeSlotStack.create(*cpuPool, m_initialArraySize);
@@ -64,11 +65,9 @@ void AllGpuSceneContiguousArrays::ContiguousArrayAllocator::deferredFree(U32 crn
 	m_garbage[crntFrameIdx].emplaceBack(*cpuPool, index);
 	m_garbage[crntFrameIdx].emplaceBack(*cpuPool, index);
 }
 }
 
 
-void AllGpuSceneContiguousArrays::ContiguousArrayAllocator::collectGarbage(U32 newFrameIdx,
-																		   GpuSceneMemoryPool* gpuScene,
-																		   HeapMemoryPool* cpuPool)
+void AllGpuSceneContiguousArrays::ContiguousArrayAllocator::collectGarbage(U32 newFrameIdx, HeapMemoryPool* cpuPool)
 {
 {
-	ANKI_ASSERT(gpuScene && cpuPool);
+	ANKI_ASSERT(cpuPool);
 
 
 	LockGuard lock(m_mtx);
 	LockGuard lock(m_mtx);
 
 
@@ -101,7 +100,7 @@ void AllGpuSceneContiguousArrays::ContiguousArrayAllocator::collectGarbage(U32 n
 	else if(allocatedSlots == 0)
 	else if(allocatedSlots == 0)
 	{
 	{
 		ANKI_ASSERT(m_nextSlotIndex == 0);
 		ANKI_ASSERT(m_nextSlotIndex == 0);
-		gpuScene->deferredFree(m_poolToken);
+		GpuSceneMemoryPool::getSingleton().deferredFree(m_poolToken);
 		m_freeSlotStack.destroy(*cpuPool);
 		m_freeSlotStack.destroy(*cpuPool);
 	}
 	}
 }
 }
@@ -137,13 +136,13 @@ void AllGpuSceneContiguousArrays::destroy()
 {
 {
 	for(GpuSceneContiguousArrayType type : EnumIterable<GpuSceneContiguousArrayType>())
 	for(GpuSceneContiguousArrayType type : EnumIterable<GpuSceneContiguousArrayType>())
 	{
 	{
-		m_allocs[type].destroy(m_scene->m_subsystems.m_gpuSceneMemoryPool, &m_scene->m_pool);
+		m_allocs[type].destroy(&m_scene->m_pool);
 	}
 	}
 }
 }
 
 
 AllGpuSceneContiguousArrays::Index AllGpuSceneContiguousArrays::allocate(GpuSceneContiguousArrayType type)
 AllGpuSceneContiguousArrays::Index AllGpuSceneContiguousArrays::allocate(GpuSceneContiguousArrayType type)
 {
 {
-	const U32 idx = m_allocs[type].allocateObject(m_scene->m_subsystems.m_gpuSceneMemoryPool, &m_scene->m_pool);
+	const U32 idx = m_allocs[type].allocateObject(&m_scene->m_pool);
 	return idx;
 	return idx;
 }
 }
 
 
@@ -158,7 +157,7 @@ void AllGpuSceneContiguousArrays::endFrame()
 
 
 	for(GpuSceneContiguousArrayType type : EnumIterable<GpuSceneContiguousArrayType>())
 	for(GpuSceneContiguousArrayType type : EnumIterable<GpuSceneContiguousArrayType>())
 	{
 	{
-		m_allocs[type].collectGarbage(m_frame, m_scene->m_subsystems.m_gpuSceneMemoryPool, &m_scene->m_pool);
+		m_allocs[type].collectGarbage(m_frame, &m_scene->m_pool);
 	}
 	}
 }
 }
 
 

+ 3 - 3
AnKi/Scene/ContiguousArrayAllocator.h

@@ -94,11 +94,11 @@ private:
 			m_initialArraySize = initialArraySize;
 			m_initialArraySize = initialArraySize;
 		}
 		}
 
 
-		void destroy(GpuSceneMemoryPool* gpuScene, HeapMemoryPool* cpuPool);
+		void destroy(HeapMemoryPool* cpuPool);
 
 
 		/// Allocate a new object and return its index in the array.
 		/// Allocate a new object and return its index in the array.
 		/// @note It's thread-safe against itself, deferredFree and endFrame.
 		/// @note It's thread-safe against itself, deferredFree and endFrame.
-		Index allocateObject(GpuSceneMemoryPool* gpuScene, HeapMemoryPool* cpuPool);
+		Index allocateObject(HeapMemoryPool* cpuPool);
 
 
 		/// Safely free an index allocated by allocateObject.
 		/// Safely free an index allocated by allocateObject.
 		/// @note It's thread-safe against itself, allocateObject and endFrame.
 		/// @note It's thread-safe against itself, allocateObject and endFrame.
@@ -106,7 +106,7 @@ private:
 
 
 		/// Call this every frame.
 		/// Call this every frame.
 		/// @note It's thread-safe against itself, deferredFree and allocateObject.
 		/// @note It's thread-safe against itself, deferredFree and allocateObject.
-		void collectGarbage(U32 newFrameIdx, GpuSceneMemoryPool* gpuScene, HeapMemoryPool* cpuPool);
+		void collectGarbage(U32 newFrameIdx, HeapMemoryPool* cpuPool);
 
 
 		PtrSize getArrayBase() const
 		PtrSize getArrayBase() const
 		{
 		{

+ 3 - 4
AnKi/Scene/SceneGraph.cpp

@@ -201,7 +201,7 @@ Error SceneGraph::update(Second prevUpdateTime, Second crntTime)
 		updateCtx.m_prevUpdateTime = prevUpdateTime;
 		updateCtx.m_prevUpdateTime = prevUpdateTime;
 		updateCtx.m_crntTime = crntTime;
 		updateCtx.m_crntTime = crntTime;
 
 
-		for(U i = 0; i < m_subsystems.m_threadHive->getThreadCount(); i++)
+		for(U i = 0; i < CoreThreadHive::getSingleton().getThreadCount(); i++)
 		{
 		{
 			tasks[i] = ANKI_THREAD_HIVE_TASK(
 			tasks[i] = ANKI_THREAD_HIVE_TASK(
 				{
 				{
@@ -213,8 +213,8 @@ Error SceneGraph::update(Second prevUpdateTime, Second crntTime)
 				&updateCtx, nullptr, nullptr);
 				&updateCtx, nullptr, nullptr);
 		}
 		}
 
 
-		m_subsystems.m_threadHive->submitTasks(&tasks[0], m_subsystems.m_threadHive->getThreadCount());
-		m_subsystems.m_threadHive->waitAllTasks();
+		CoreThreadHive::getSingleton().submitTasks(&tasks[0], CoreThreadHive::getSingleton().getThreadCount());
+		CoreThreadHive::getSingleton().waitAllTasks();
 	}
 	}
 
 
 	m_stats.m_updateTime = HighRezTimer::getCurrentTime() - m_stats.m_updateTime;
 	m_stats.m_updateTime = HighRezTimer::getCurrentTime() - m_stats.m_updateTime;
@@ -237,7 +237,6 @@ Error SceneGraph::updateNode(Second prevTime, Second crntTime, SceneNode& node)
 	// Components update
 	// Components update
 	SceneComponentUpdateInfo componentUpdateInfo(prevTime, crntTime);
 	SceneComponentUpdateInfo componentUpdateInfo(prevTime, crntTime);
 	componentUpdateInfo.m_framePool = &m_framePool;
 	componentUpdateInfo.m_framePool = &m_framePool;
-	componentUpdateInfo.m_gpuSceneMicroPatcher = m_subsystems.m_gpuSceneMicroPatcher;
 
 
 	Bool atLeastOneComponentUpdated = false;
 	Bool atLeastOneComponentUpdated = false;
 	node.iterateComponents([&](SceneComponent& comp) {
 	node.iterateComponents([&](SceneComponent& comp) {

+ 1 - 1
AnKi/Scene/Visibility.cpp

@@ -872,7 +872,7 @@ void SceneGraph::doVisibilityTests(SceneNode& camera, SceneGraph& scene, RenderQ
 {
 {
 	ANKI_TRACE_SCOPED_EVENT(SceneVisTests);
 	ANKI_TRACE_SCOPED_EVENT(SceneVisTests);
 
 
-	ThreadHive& hive = *scene.m_subsystems.m_threadHive;
+	ThreadHive& hive = CoreThreadHive::getSingleton();
 
 
 	VisibilityContext ctx;
 	VisibilityContext ctx;
 	ctx.m_scene = &scene;
 	ctx.m_scene = &scene;

+ 5 - 4
AnKi/Ui/Canvas.cpp

@@ -217,9 +217,9 @@ void Canvas::appendToCommandBufferInternal(CommandBufferPtr& cmdb)
 		}
 		}
 
 
 		ImDrawVert* verts =
 		ImDrawVert* verts =
-			static_cast<ImDrawVert*>(getExternalSubsystems().m_rebarPool->allocateFrame(verticesSize, vertsToken));
+			static_cast<ImDrawVert*>(RebarStagingGpuMemoryPool::getSingleton().allocateFrame(verticesSize, vertsToken));
 		ImDrawIdx* indices =
 		ImDrawIdx* indices =
-			static_cast<ImDrawIdx*>(getExternalSubsystems().m_rebarPool->allocateFrame(indicesSize, indicesToken));
+			static_cast<ImDrawIdx*>(RebarStagingGpuMemoryPool::getSingleton().allocateFrame(indicesSize, indicesToken));
 
 
 		for(I n = 0; n < drawData.CmdListsCount; ++n)
 		for(I n = 0; n < drawData.CmdListsCount; ++n)
 		{
 		{
@@ -238,13 +238,14 @@ void Canvas::appendToCommandBufferInternal(CommandBufferPtr& cmdb)
 	const F32 fbHeight = drawData.DisplaySize.y * drawData.FramebufferScale.y;
 	const F32 fbHeight = drawData.DisplaySize.y * drawData.FramebufferScale.y;
 	cmdb->setViewport(0, 0, U32(fbWidth), U32(fbHeight));
 	cmdb->setViewport(0, 0, U32(fbWidth), U32(fbHeight));
 
 
-	cmdb->bindVertexBuffer(0, getExternalSubsystems().m_rebarPool->getBuffer(), vertsToken.m_offset,
+	cmdb->bindVertexBuffer(0, RebarStagingGpuMemoryPool::getSingleton().getBuffer(), vertsToken.m_offset,
 						   sizeof(ImDrawVert));
 						   sizeof(ImDrawVert));
 	cmdb->setVertexAttribute(0, 0, Format::kR32G32_Sfloat, 0);
 	cmdb->setVertexAttribute(0, 0, Format::kR32G32_Sfloat, 0);
 	cmdb->setVertexAttribute(1, 0, Format::kR8G8B8A8_Unorm, sizeof(Vec2) * 2);
 	cmdb->setVertexAttribute(1, 0, Format::kR8G8B8A8_Unorm, sizeof(Vec2) * 2);
 	cmdb->setVertexAttribute(2, 0, Format::kR32G32_Sfloat, sizeof(Vec2));
 	cmdb->setVertexAttribute(2, 0, Format::kR32G32_Sfloat, sizeof(Vec2));
 
 
-	cmdb->bindIndexBuffer(getExternalSubsystems().m_rebarPool->getBuffer(), indicesToken.m_offset, IndexType::kU16);
+	cmdb->bindIndexBuffer(RebarStagingGpuMemoryPool::getSingleton().getBuffer(), indicesToken.m_offset,
+						  IndexType::kU16);
 
 
 	// Will project scissor/clipping rectangles into framebuffer space
 	// Will project scissor/clipping rectangles into framebuffer space
 	const Vec2 clipOff = drawData.DisplayPos; // (0,0) unless using multi-viewports
 	const Vec2 clipOff = drawData.DisplayPos; // (0,0) unless using multi-viewports

+ 0 - 1
AnKi/Ui/Common.h

@@ -45,7 +45,6 @@ public:
 	ResourceManager* m_resourceManager = nullptr;
 	ResourceManager* m_resourceManager = nullptr;
 	ResourceFilesystem* m_resourceFilesystem = nullptr;
 	ResourceFilesystem* m_resourceFilesystem = nullptr;
 	GrManager* m_grManager = nullptr;
 	GrManager* m_grManager = nullptr;
-	RebarStagingGpuMemoryPool* m_rebarPool = nullptr;
 };
 };
 
 
 inline Vec2 toAnki(const ImVec2& v)
 inline Vec2 toAnki(const ImVec2& v)

+ 1 - 1
AnKi/Util/Singleton.h

@@ -23,7 +23,7 @@ template<typename T>
 class MakeSingleton
 class MakeSingleton
 {
 {
 public:
 public:
-	ANKI_PURE static T& getSingleton()
+	ANKI_FORCE_INLINE static T& getSingleton()
 	{
 	{
 		return *m_global;
 		return *m_global;
 	}
 	}

+ 4 - 5
Tests/Gr/Gr.cpp

@@ -242,11 +242,11 @@ static Input* input = nullptr;
 	cfg.setGrVsync(false); \
 	cfg.setGrVsync(false); \
 	cfg.setGrRayTracing(true); \
 	cfg.setGrRayTracing(true); \
 	cfg.setGrDebugMarkers(true); \
 	cfg.setGrDebugMarkers(true); \
-	stagingMem = new RebarStagingGpuMemoryPool(); \
 	g_win = createWindow(cfg); \
 	g_win = createWindow(cfg); \
 	ANKI_TEST_EXPECT_NO_ERR(Input::allocateSingleton().init()); \
 	ANKI_TEST_EXPECT_NO_ERR(Input::allocateSingleton().init()); \
 	g_gr = createGrManager(g_win); \
 	g_gr = createGrManager(g_win); \
-	ANKI_TEST_EXPECT_NO_ERR(stagingMem->init(g_gr)); \
+	RebarStagingGpuMemoryPool::allocateSingleton().init(g_gr); \
+	stagingMem = &RebarStagingGpuMemoryPool::getSingleton(); \
 	TransferGpuAllocator* transfAlloc = new TransferGpuAllocator(); \
 	TransferGpuAllocator* transfAlloc = new TransferGpuAllocator(); \
 	ANKI_TEST_EXPECT_NO_ERR(transfAlloc->init(128_MB, g_gr, &g_gr->getMemoryPool())); \
 	ANKI_TEST_EXPECT_NO_ERR(transfAlloc->init(128_MB, g_gr, &g_gr->getMemoryPool())); \
 	while(true) \
 	while(true) \
@@ -257,14 +257,13 @@ static Input* input = nullptr;
 	} \
 	} \
 	g_gr->finish(); \
 	g_gr->finish(); \
 	delete transfAlloc; \
 	delete transfAlloc; \
-	delete stagingMem; \
+	RebarStagingGpuMemoryPool::freeSingleton(); \
 	GrManager::deleteInstance(g_gr); \
 	GrManager::deleteInstance(g_gr); \
 	Input::freeSingleton(); \
 	Input::freeSingleton(); \
 	NativeWindow::freeSingleton(); \
 	NativeWindow::freeSingleton(); \
 	ConfigSet::freeSingleton(); \
 	ConfigSet::freeSingleton(); \
 	g_win = nullptr; \
 	g_win = nullptr; \
-	g_gr = nullptr; \
-	stagingMem = nullptr;
+	g_gr = nullptr;
 
 
 static void* setUniforms(PtrSize size, CommandBufferPtr& cmdb, U32 set, U32 binding)
 static void* setUniforms(PtrSize size, CommandBufferPtr& cmdb, U32 set, U32 binding)
 {
 {

+ 3 - 5
Tests/Ui/Ui.cpp

@@ -72,8 +72,7 @@ ANKI_TEST(Ui, Ui)
 	ResourceManager* resource = createResourceManager(gr, fs);
 	ResourceManager* resource = createResourceManager(gr, fs);
 	UiManager* ui = new UiManager();
 	UiManager* ui = new UiManager();
 
 
-	RebarStagingGpuMemoryPool* stagingMem = new RebarStagingGpuMemoryPool();
-	ANKI_TEST_EXPECT_NO_ERR(stagingMem->init(gr));
+	RebarStagingGpuMemoryPool::allocateSingleton().init(gr);
 
 
 	HeapAllocator<U8> alloc(allocAligned, nullptr);
 	HeapAllocator<U8> alloc(allocAligned, nullptr);
 	UiManagerInitInfo uiInitInfo;
 	UiManagerInitInfo uiInitInfo;
@@ -82,7 +81,6 @@ ANKI_TEST(Ui, Ui)
 	uiInitInfo.m_grManager = gr;
 	uiInitInfo.m_grManager = gr;
 	uiInitInfo.m_resourceFilesystem = fs;
 	uiInitInfo.m_resourceFilesystem = fs;
 	uiInitInfo.m_resourceManager = resource;
 	uiInitInfo.m_resourceManager = resource;
-	uiInitInfo.m_rebarPool = stagingMem;
 	ANKI_TEST_EXPECT_NO_ERR(ui->init(uiInitInfo));
 	ANKI_TEST_EXPECT_NO_ERR(ui->init(uiInitInfo));
 
 
 	{
 	{
@@ -147,7 +145,7 @@ ANKI_TEST(Ui, Ui)
 			cmdb->flush();
 			cmdb->flush();
 
 
 			gr->swapBuffers();
 			gr->swapBuffers();
-			stagingMem->endFrame();
+			RebarStagingGpuMemoryPool::getSingleton().endFrame();
 
 
 			timer.stop();
 			timer.stop();
 			const F32 TICK = 1.0f / 30.0f;
 			const F32 TICK = 1.0f / 30.0f;
@@ -159,7 +157,7 @@ ANKI_TEST(Ui, Ui)
 	}
 	}
 
 
 	delete ui;
 	delete ui;
-	delete stagingMem;
+	RebarStagingGpuMemoryPool::freeSingleton();
 	delete resource;
 	delete resource;
 	delete fs;
 	delete fs;
 	GrManager::deleteInstance(gr);
 	GrManager::deleteInstance(gr);