Browse Source

Refactor all Util containers

Panagiotis Christopoulos Charitos 2 years ago
parent
commit
f09b08f441
100 changed files with 974 additions and 1144 deletions
  1. 30 38
      AnKi/Core/App.cpp
  2. 9 8
      AnKi/Core/App.h
  3. 2 2
      AnKi/Core/Common.h
  4. 2 2
      AnKi/Core/ConfigSet.cpp
  5. 4 4
      AnKi/Core/CoreTracer.cpp
  6. 2 2
      AnKi/Core/DeveloperConsole.cpp
  7. 13 2
      AnKi/Core/GpuMemoryPools.cpp
  8. 3 3
      AnKi/Core/GpuMemoryPools.h
  9. 77 51
      AnKi/Gr/RenderGraph.cpp
  10. 26 32
      AnKi/Gr/RenderGraph.h
  11. 11 17
      AnKi/Gr/RenderGraph.inl.h
  12. 4 8
      AnKi/Gr/Utils/SegregatedListsGpuMemoryPool.cpp
  13. 2 1
      AnKi/Gr/Utils/SegregatedListsGpuMemoryPool.h
  14. 1 1
      AnKi/Gr/Utils/StackGpuMemoryPool.cpp
  15. 1 1
      AnKi/Gr/Vulkan/BufferImpl.cpp
  16. 2 2
      AnKi/Gr/Vulkan/CommandBufferFactory.cpp
  17. 4 4
      AnKi/Gr/Vulkan/CommandBufferFactory.h
  18. 3 3
      AnKi/Gr/Vulkan/CommandBufferImpl.cpp
  19. 2 1
      AnKi/Gr/Vulkan/CommandBufferImpl.inl.h
  20. 7 7
      AnKi/Gr/Vulkan/DescriptorSet.cpp
  21. 6 2
      AnKi/Gr/Vulkan/GpuMemoryManager.cpp
  22. 3 2
      AnKi/Gr/Vulkan/GpuMemoryManager.h
  23. 20 15
      AnKi/Gr/Vulkan/GrManagerImpl.cpp
  24. 2 2
      AnKi/Gr/Vulkan/PipelineCache.cpp
  25. 1 1
      AnKi/Gr/Vulkan/ShaderImpl.cpp
  26. 5 3
      AnKi/Gr/Vulkan/ShaderProgramImpl.cpp
  27. 3 3
      AnKi/Gr/Vulkan/SwapchainFactory.cpp
  28. 17 0
      AnKi/Importer/Common.h
  29. 75 74
      AnKi/Importer/GltfImporter.cpp
  30. 26 35
      AnKi/Importer/GltfImporter.h
  31. 21 19
      AnKi/Importer/GltfImporterAnimation.cpp
  32. 42 40
      AnKi/Importer/GltfImporterMaterial.cpp
  33. 42 34
      AnKi/Importer/GltfImporterMesh.cpp
  34. 32 32
      AnKi/Importer/ImageImporter.cpp
  35. 2 2
      AnKi/Math/Axisang.h
  36. 2 2
      AnKi/Math/Euler.h
  37. 4 2
      AnKi/Math/Mat.h
  38. 15 14
      AnKi/Math/Transform.h
  39. 12 6
      AnKi/Math/Vec.h
  40. 2 0
      AnKi/Physics/Common.h
  41. 4 5
      AnKi/Physics/PhysicsTrigger.cpp
  42. 1 1
      AnKi/Physics/PhysicsTrigger.h
  43. 1 1
      AnKi/Renderer/DepthDownscale.cpp
  44. 1 1
      AnKi/Renderer/DownscaleBlur.cpp
  45. 5 1
      AnKi/Renderer/GBuffer.cpp
  46. 4 3
      AnKi/Renderer/ShadowMapping.cpp
  47. 2 1
      AnKi/Renderer/ShadowMapping.h
  48. 2 2
      AnKi/Renderer/TileAllocator.cpp
  49. 6 6
      AnKi/Resource/AnimationResource.cpp
  50. 1 1
      AnKi/Resource/GenericResource.cpp
  51. 3 3
      AnKi/Resource/ImageAtlasResource.cpp
  52. 33 48
      AnKi/Resource/ImageLoader.cpp
  53. 27 21
      AnKi/Resource/ImageLoader.h
  54. 1 1
      AnKi/Resource/ImageResource.cpp
  55. 4 4
      AnKi/Resource/MaterialResource.cpp
  56. 5 9
      AnKi/Resource/MeshBinaryLoader.cpp
  57. 3 4
      AnKi/Resource/MeshBinaryLoader.h
  58. 3 3
      AnKi/Resource/MeshResource.cpp
  59. 2 3
      AnKi/Resource/ModelResource.cpp
  60. 1 1
      AnKi/Resource/ParticleEmitterResource.cpp
  61. 15 16
      AnKi/Resource/ResourceFilesystem.cpp
  62. 1 1
      AnKi/Resource/ResourceFilesystem.h
  63. 1 1
      AnKi/Resource/ResourceObject.cpp
  64. 2 6
      AnKi/Resource/ResourceObject.h
  65. 3 3
      AnKi/Resource/ShaderProgramResource.cpp
  66. 6 6
      AnKi/Resource/ShaderProgramResourceSystem.cpp
  67. 3 3
      AnKi/Resource/SkeletonResource.cpp
  68. 1 1
      AnKi/Resource/SkeletonResource.h
  69. 4 9
      AnKi/Resource/TransferGpuAllocator.cpp
  70. 1 1
      AnKi/Resource/TransferGpuAllocator.h
  71. 9 7
      AnKi/Scene/Components/ModelComponent.cpp
  72. 2 2
      AnKi/Scene/Components/ModelComponent.h
  73. 5 4
      AnKi/Scene/Components/ParticleEmitterComponent.cpp
  74. 1 1
      AnKi/Scene/Components/ParticleEmitterComponent.h
  75. 5 7
      AnKi/Scene/Components/SkinComponent.cpp
  76. 0 1
      AnKi/Scene/Components/SkinComponent.h
  77. 0 1
      AnKi/Scene/Components/SkyboxComponent.cpp
  78. 0 1
      AnKi/Scene/Components/SkyboxComponent.h
  79. 1 1
      AnKi/Scene/Components/UiComponent.cpp
  80. 1 1
      AnKi/Scene/Components/UiComponent.h
  81. 1 1
      AnKi/Scene/ContiguousArrayAllocator.cpp
  82. 1 1
      AnKi/Scene/ContiguousArrayAllocator.h
  83. 2 1
      AnKi/Scene/Events/EventManager.cpp
  84. 1 1
      AnKi/Scene/Events/ScriptEvent.cpp
  85. 0 192
      AnKi/Scene/Octree.cpp
  86. 9 41
      AnKi/Scene/Octree.h
  87. 0 2
      AnKi/Scene/SceneNode.cpp
  88. 3 3
      AnKi/Scene/SceneNode.h
  89. 1 2
      AnKi/Scene/SoftwareRasterizer.cpp
  90. 77 77
      AnKi/Scene/Visibility.cpp
  91. 31 7
      AnKi/Scene/VisibilityInternal.h
  92. 1 1
      AnKi/ShaderCompiler/Common.h
  93. 29 28
      AnKi/ShaderCompiler/Dxc.cpp
  94. 2 2
      AnKi/ShaderCompiler/Dxc.h
  95. 9 9
      AnKi/ShaderCompiler/MaliOfflineCompiler.cpp
  96. 2 2
      AnKi/ShaderCompiler/MaliOfflineCompiler.h
  97. 9 10
      AnKi/ShaderCompiler/RadeonGpuAnalyzer.cpp
  98. 2 3
      AnKi/ShaderCompiler/RadeonGpuAnalyzer.h
  99. 84 89
      AnKi/ShaderCompiler/ShaderProgramCompiler.cpp
  100. 3 3
      AnKi/ShaderCompiler/ShaderProgramCompiler.h

+ 30 - 38
AnKi/Core/App.cpp

@@ -69,42 +69,45 @@ void* App::MemStats::allocCallback(void* userData, void* ptr, PtrSize size, [[ma
 		const PtrSize newSize = sizeof(Header) + size;
 
 		// Allocate
-		MemStats* self = static_cast<MemStats*>(userData);
+		App* self = static_cast<App*>(userData);
 		Header* allocation = static_cast<Header*>(
-			self->m_originalAllocCallback(self->m_originalUserData, nullptr, newSize, newAlignment));
+			self->m_originalAllocCallback(self->m_originalAllocUserData, nullptr, newSize, newAlignment));
 		allocation->m_allocatedSize = size;
 		++allocation;
 		out = static_cast<void*>(allocation);
 
 		// Update stats
-		self->m_allocatedMem.fetchAdd(size);
-		self->m_allocCount.fetchAdd(1);
+		self->m_memStats.m_allocatedMem.fetchAdd(size);
+		self->m_memStats.m_allocCount.fetchAdd(1);
 	}
 	else
 	{
 		// Need to free
 
-		MemStats* self = static_cast<MemStats*>(userData);
+		App* self = static_cast<App*>(userData);
 
 		Header* allocation = static_cast<Header*>(ptr);
 		--allocation;
 		ANKI_ASSERT(allocation->m_allocatedSize > 0);
 
 		// Update stats
-		self->m_freeCount.fetchAdd(1);
-		self->m_allocatedMem.fetchSub(allocation->m_allocatedSize);
+		self->m_memStats.m_freeCount.fetchAdd(1);
+		self->m_memStats.m_allocatedMem.fetchSub(allocation->m_allocatedSize);
 
 		// Free
-		self->m_originalAllocCallback(self->m_originalUserData, allocation, 0, 0);
+		self->m_originalAllocCallback(self->m_originalAllocUserData, allocation, 0, 0);
 	}
 
 	return out;
 }
 
-App::App()
+App::App(AllocAlignedCallback allocCb, void* allocCbUserData)
 {
-	// Config is special
-	ConfigSet::allocateSingleton(allocAligned, nullptr);
+	m_originalAllocCallback = allocCb;
+	m_originalAllocUserData = allocCbUserData;
+
+	// Config set is a bit special so init it ASAP
+	ConfigSet::allocateSingleton(allocCb, allocCbUserData);
 }
 
 App::~App()
@@ -148,9 +151,9 @@ void App::cleanup()
 	DefaultMemoryPool::freeSingleton();
 }
 
-Error App::init(AllocAlignedCallback allocCb, void* allocCbUserData)
+Error App::init()
 {
-	const Error err = initInternal(allocCb, allocCbUserData);
+	const Error err = initInternal();
 	if(err)
 	{
 		ANKI_CORE_LOGE("App initialization failed. Shutting down");
@@ -160,23 +163,17 @@ Error App::init(AllocAlignedCallback allocCb, void* allocCbUserData)
 	return err;
 }
 
-Error App::initInternal(AllocAlignedCallback allocCb, void* allocCbUserData)
+Error App::initInternal()
 {
 	Logger::getSingleton().enableVerbosity(ConfigSet::getSingleton().getCoreVerboseLog());
 
 	setSignalHandlers();
 
+	AllocAlignedCallback allocCb = m_originalAllocCallback;
+	void* allocCbUserData = m_originalAllocUserData;
 	initMemoryCallbacks(allocCb, allocCbUserData);
 
-	if(DefaultMemoryPool::isAllocated())
-	{
-		// Re-cerate it with the new callbacks
-
-		ANKI_ASSERT(DefaultMemoryPool::getSingleton().getAllocationCount() == 0);
-		DefaultMemoryPool::freeSingleton();
-		DefaultMemoryPool::allocateSingleton(allocCb, allocCbUserData);
-	}
-
+	DefaultMemoryPool::allocateSingleton(allocCb, allocCbUserData);
 	CoreMemoryPool::allocateSingleton(allocCb, allocCbUserData);
 
 	ANKI_CHECK(initDirs());
@@ -262,8 +259,7 @@ Error App::initInternal(AllocAlignedCallback allocCb, void* allocCbUserData)
 	// ThreadPool
 	//
 	const Bool pinThreads = !ANKI_OS_ANDROID;
-	CoreThreadHive::allocateSingleton(ConfigSet::getSingleton().getCoreJobThreadCount(),
-									  &CoreMemoryPool::getSingleton(), pinThreads);
+	CoreThreadHive::allocateSingleton(ConfigSet::getSingleton().getCoreJobThreadCount(), pinThreads);
 
 	//
 	// Graphics API
@@ -301,13 +297,13 @@ Error App::initInternal(AllocAlignedCallback allocCb, void* allocCbUserData)
 	//
 #if !ANKI_OS_ANDROID
 	// Add the location of the executable where the shaders are supposed to be
-	StringRaii executableFname(&CoreMemoryPool::getSingleton());
+	String executableFname;
 	ANKI_CHECK(getApplicationPath(executableFname));
 	ANKI_CORE_LOGI("Executable path is: %s", executableFname.cstr());
-	StringRaii shadersPath(&CoreMemoryPool::getSingleton());
+	String shadersPath;
 	getParentFilepath(executableFname, shadersPath);
-	shadersPath.append(":");
-	shadersPath.append(ConfigSet::getSingleton().getRsrcDataPaths());
+	shadersPath += ":";
+	shadersPath += ConfigSet::getSingleton().getRsrcDataPaths();
 	ConfigSet::getSingleton().setRsrcDataPaths(shadersPath);
 #endif
 
@@ -358,7 +354,7 @@ Error App::initDirs()
 {
 	// Settings path
 #if !ANKI_OS_ANDROID
-	StringRaii home(&CoreMemoryPool::getSingleton());
+	String home;
 	ANKI_CHECK(getHomeDirectory(home));
 
 	m_settingsDir.sprintf("%s/.anki", &home[0]);
@@ -383,7 +379,7 @@ Error App::initDirs()
 	if(ConfigSet::getSingleton().getCoreClearCaches() && cacheDirExists)
 	{
 		ANKI_CORE_LOGI("Will delete the cache dir and start fresh: %s", m_cacheDir.cstr());
-		ANKI_CHECK(removeDirectory(m_cacheDir.toCString(), CoreMemoryPool::getSingleton()));
+		ANKI_CHECK(removeDirectory(m_cacheDir.toCString()));
 		ANKI_CHECK(createDirectory(m_cacheDir.toCString()));
 	}
 	else if(!cacheDirExists)
@@ -596,7 +592,7 @@ void App::injectUiElements(CoreDynamicArray<UiQueueElement>& newUiElementArr, Re
 	if(ConfigSet::getSingleton().getCoreDisplayStats() > 0 || m_consoleEnabled)
 	{
 		const U32 extraElements = (ConfigSet::getSingleton().getCoreDisplayStats() > 0) + (m_consoleEnabled != 0);
-		newUiElementArr.create(originalCount + extraElements);
+		newUiElementArr.resize(originalCount + extraElements);
 
 		if(originalCount > 0)
 		{
@@ -630,11 +626,8 @@ void App::initMemoryCallbacks(AllocAlignedCallback& allocCb, void*& allocCbUserD
 {
 	if(ConfigSet::getSingleton().getCoreDisplayStats() > 1)
 	{
-		m_memStats.m_originalAllocCallback = allocCb;
-		m_memStats.m_originalUserData = allocCbUserData;
-
 		allocCb = MemStats::allocCallback;
-		allocCbUserData = &m_memStats;
+		allocCbUserData = this;
 	}
 	else
 	{
@@ -674,8 +667,7 @@ void App::setSignalHandlers()
 
 		U32 count = 0;
 		printf("Backtrace:\n");
-		HeapMemoryPool pool(allocAligned, nullptr);
-		backtrace(pool, [&count](CString symbol) {
+		backtrace([&count](CString symbol) {
 			printf("%.2u: %s\n", count++, symbol.cstr());
 		});
 

+ 9 - 8
AnKi/Core/App.h

@@ -20,18 +20,19 @@ class RenderQueue;
 class App
 {
 public:
-	App();
+	App(AllocAlignedCallback allocCb = allocAligned, void* allocCbUserData = nullptr);
+
 	virtual ~App();
 
 	/// Initialize the application.
-	Error init(AllocAlignedCallback allocCb, void* allocCbUserData);
+	Error init();
 
-	const String& getSettingsDirectory() const
+	CString getSettingsDirectory() const
 	{
 		return m_settingsDir;
 	}
 
-	const String& getCacheDirectory() const
+	CString getCacheDirectory() const
 	{
 		return m_cacheDir;
 	}
@@ -65,6 +66,9 @@ private:
 	CoreString m_cacheDir; ///< This is used as a cache
 	U64 m_resourceCompletedAsyncTaskCount = 0;
 
+	void* m_originalAllocUserData = nullptr;
+	AllocAlignedCallback m_originalAllocCallback = nullptr;
+
 	class MemStats
 	{
 	public:
@@ -72,15 +76,12 @@ private:
 		Atomic<U64> m_allocCount = {0};
 		Atomic<U64> m_freeCount = {0};
 
-		void* m_originalUserData = nullptr;
-		AllocAlignedCallback m_originalAllocCallback = nullptr;
-
 		static void* allocCallback(void* userData, void* ptr, PtrSize size, PtrSize alignment);
 	} m_memStats;
 
 	void initMemoryCallbacks(AllocAlignedCallback& allocCb, void*& allocCbUserData);
 
-	Error initInternal(AllocAlignedCallback allocCb, void* allocCbUserData);
+	Error initInternal();
 
 	Error initDirs();
 	void cleanup();

+ 2 - 2
AnKi/Core/Common.h

@@ -38,8 +38,8 @@ class CoreThreadHive : public ThreadHive, public MakeSingleton<CoreThreadHive>
 	friend class MakeSingleton;
 
 public:
-	CoreThreadHive(U32 threadCount, BaseMemoryPool* pool, Bool pinToCores = false)
-		: ThreadHive(threadCount, pool, pinToCores)
+	CoreThreadHive(U32 threadCount, Bool pinToCores = false)
+		: ThreadHive(threadCount, pinToCores)
 	{
 	}
 };

+ 2 - 2
AnKi/Core/ConfigSet.cpp

@@ -106,7 +106,7 @@ Error ConfigSet::loadFromFile(CString filename)
 	ANKI_ASSERT(isInitialized());
 
 	ANKI_CORE_LOGI("Loading config file %s", filename.cstr());
-	XmlDocument xml(&m_pool);
+	CoreXmlDocument xml;
 	ANKI_CHECK(xml.loadFile(filename));
 
 	XmlElement rootel;
@@ -170,7 +170,7 @@ Error ConfigSet::saveToFile(CString filename) const
 	File file;
 	ANKI_CHECK(file.open(filename, FileOpenFlag::kWrite));
 
-	ANKI_CHECK(file.writeTextf("%s\n<config>\n", XmlDocument::kXmlHeader.cstr()));
+	ANKI_CHECK(file.writeTextf("%s\n<config>\n", CoreXmlDocument::kXmlHeader.cstr()));
 
 #define ANKI_NUMERIC_UINT(name) \
 	ANKI_CHECK(file.writeTextf("\t<!-- %s -->\n", m_##name.m_description.cstr())); \

+ 4 - 4
AnKi/Core/CoreTracer.cpp

@@ -89,7 +89,7 @@ CoreTracer::~CoreTracer()
 
 Error CoreTracer::init(CString directory)
 {
-	Tracer::allocateSingleton(&CoreMemoryPool::getSingleton());
+	Tracer::allocateSingleton();
 	const Bool enableTracer = getenv("ANKI_CORE_TRACER_ENABLED") && getenv("ANKI_CORE_TRACER_ENABLED")[0] == '1';
 	Tracer::getSingleton().setEnabled(enableTracer);
 	ANKI_CORE_LOGI("Tracing is %s from the beginning", (enableTracer) ? "enabled" : "disabled");
@@ -216,7 +216,7 @@ void CoreTracer::gatherCounters(ThreadWorkItem& item)
 		const TracerCounter& counter = mergedCounters[i];
 
 		Bool found = false;
-		for(const String& name : m_counterNames)
+		for(const CoreString& name : m_counterNames)
 		{
 			if(name == counter.m_name)
 			{
@@ -295,13 +295,13 @@ void CoreTracer::flushFrame(U64 frame)
 
 			if(events.getSize() > 0)
 			{
-				item->m_events.create(events.getSize());
+				item->m_events.resize(events.getSize());
 				memcpy(&item->m_events[0], &events[0], events.getSizeInBytes());
 			}
 
 			if(counters.getSize() > 0)
 			{
-				item->m_counters.create(counters.getSize());
+				item->m_counters.resize(counters.getSize());
 				memcpy(&item->m_counters[0], &counters[0], counters.getSizeInBytes());
 			}
 

+ 2 - 2
AnKi/Core/DeveloperConsole.cpp

@@ -134,8 +134,8 @@ void DeveloperConsole::newLogItem(const LoggerMessageInfo& inf)
 	newLogItem->m_file = inf.m_file;
 	newLogItem->m_func = inf.m_func;
 	newLogItem->m_subsystem = inf.m_subsystem;
-	newLogItem->m_threadName.create(inf.m_threadName);
-	newLogItem->m_msg.create(inf.m_msg);
+	newLogItem->m_threadName = inf.m_threadName;
+	newLogItem->m_msg = inf.m_msg;
 	newLogItem->m_line = inf.m_line;
 	newLogItem->m_type = inf.m_type;
 

+ 13 - 2
AnKi/Core/GpuMemoryPools.cpp

@@ -134,6 +134,10 @@ public:
 	U32 m_dstDwordOffset;
 };
 
+GpuSceneMicroPatcher::GpuSceneMicroPatcher()
+{
+}
+
 GpuSceneMicroPatcher::~GpuSceneMicroPatcher()
 {
 	static_assert(sizeof(PatchHeader) == 8);
@@ -165,11 +169,18 @@ void GpuSceneMicroPatcher::newCopy(StackMemoryPool& frameCpuPool, PtrSize gpuSce
 
 	// Break the data into multiple copies
 	LockGuard lock(m_mtx);
+
+	if(m_crntFramePatchHeaders.getSize() == 0)
+	{
+		m_crntFramePatchHeaders = DynamicArray<PatchHeader, MemoryPoolPtrWrapper<StackMemoryPool>>(&frameCpuPool);
+		m_crntFramePatchData = DynamicArray<U32, MemoryPoolPtrWrapper<StackMemoryPool>>(&frameCpuPool);
+	}
+
 	while(patchIt < patchEnd)
 	{
 		const U32 patchDwords = min(kDwordsPerPatch, U32(patchEnd - patchIt));
 
-		PatchHeader& header = *m_crntFramePatchHeaders.emplaceBack(frameCpuPool);
+		PatchHeader& header = *m_crntFramePatchHeaders.emplaceBack();
 		ANKI_ASSERT(((patchDwords - 1) & 0b111111) == (patchDwords - 1));
 		header.m_dwordCountAndSrcDwordOffsetPack = patchDwords - 1;
 		header.m_dwordCountAndSrcDwordOffsetPack <<= 26;
@@ -178,7 +189,7 @@ void GpuSceneMicroPatcher::newCopy(StackMemoryPool& frameCpuPool, PtrSize gpuSce
 		header.m_dstDwordOffset = gpuSceneDestDwordOffset;
 
 		const U32 srcOffset = m_crntFramePatchData.getSize();
-		m_crntFramePatchData.resize(frameCpuPool, srcOffset + patchDwords);
+		m_crntFramePatchData.resize(srcOffset + patchDwords);
 		memcpy(&m_crntFramePatchData[srcOffset], patchIt, patchDwords * 4);
 
 		patchIt += patchDwords;

+ 3 - 3
AnKi/Core/GpuMemoryPools.h

@@ -214,14 +214,14 @@ private:
 
 	class PatchHeader;
 
-	DynamicArray<PatchHeader> m_crntFramePatchHeaders;
-	DynamicArray<U32> m_crntFramePatchData;
+	DynamicArray<PatchHeader, MemoryPoolPtrWrapper<StackMemoryPool>> m_crntFramePatchHeaders;
+	DynamicArray<U32, MemoryPoolPtrWrapper<StackMemoryPool>> m_crntFramePatchData;
 	Mutex m_mtx;
 
 	ShaderProgramResourcePtr m_copyProgram;
 	ShaderProgramPtr m_grProgram;
 
-	GpuSceneMicroPatcher() = default;
+	GpuSceneMicroPatcher();
 
 	~GpuSceneMicroPatcher();
 };

+ 77 - 51
AnKi/Gr/RenderGraph.cpp

@@ -28,10 +28,16 @@ static inline U32 getTextureSurfOrVolCount(const TexturePtr& tex)
 class RenderGraph::RT
 {
 public:
-	DynamicArray<TextureUsageBit> m_surfOrVolUsages;
-	DynamicArray<U16> m_lastBatchThatTransitionedIt;
+	DynamicArray<TextureUsageBit, MemoryPoolPtrWrapper<StackMemoryPool>> m_surfOrVolUsages;
+	DynamicArray<U16, MemoryPoolPtrWrapper<StackMemoryPool>> m_lastBatchThatTransitionedIt;
 	TexturePtr m_texture; ///< Hold a reference.
 	Bool m_imported;
+
+	RT(StackMemoryPool* pool)
+		: m_surfOrVolUsages(pool)
+		, m_lastBatchThatTransitionedIt(pool)
+	{
+	}
 };
 
 /// Same as RT but for buffers.
@@ -109,13 +115,13 @@ class RenderGraph::Pass
 {
 public:
 	// WARNING!!!!!: Whatever you put here needs manual destruction in RenderGraph::reset()
-	DynamicArray<U32> m_dependsOn;
+	DynamicArray<U32, MemoryPoolPtrWrapper<StackMemoryPool>> m_dependsOn;
 
-	DynamicArray<RenderPassDependency::TextureInfo> m_consumedTextures;
+	DynamicArray<RenderPassDependency::TextureInfo, MemoryPoolPtrWrapper<StackMemoryPool>> m_consumedTextures;
 
-	Function<void(RenderPassWorkContext&)> m_callback;
+	Function<void(RenderPassWorkContext&), MemoryPoolPtrWrapper<StackMemoryPool>> m_callback;
 
-	DynamicArray<CommandBufferPtr> m_secondLevelCmdbs;
+	DynamicArray<CommandBufferPtr, MemoryPoolPtrWrapper<StackMemoryPool>> m_secondLevelCmdbs;
 	/// Will reuse the m_secondLevelCmdbInitInfo.m_framebuffer to get the framebuffer.
 	CommandBufferInitInfo m_secondLevelCmdbInitInfo;
 	Array<U32, 4> m_fbRenderArea;
@@ -125,6 +131,13 @@ public:
 	U32 m_batchIdx ANKI_DEBUG_CODE(= kMaxU32);
 	Bool m_drawsToPresentable = false;
 
+	Pass(StackMemoryPool* pool)
+		: m_dependsOn(pool)
+		, m_consumedTextures(pool)
+		, m_secondLevelCmdbs(pool)
+	{
+	}
+
 	FramebufferPtr& fb()
 	{
 		return m_secondLevelCmdbInitInfo.m_framebuffer;
@@ -141,31 +154,43 @@ public:
 class RenderGraph::Batch
 {
 public:
-	DynamicArray<U32> m_passIndices;
-	DynamicArray<TextureBarrier> m_textureBarriersBefore;
-	DynamicArray<BufferBarrier> m_bufferBarriersBefore;
-	DynamicArray<ASBarrier> m_asBarriersBefore;
+	DynamicArray<U32, MemoryPoolPtrWrapper<StackMemoryPool>> m_passIndices;
+	DynamicArray<TextureBarrier, MemoryPoolPtrWrapper<StackMemoryPool>> m_textureBarriersBefore;
+	DynamicArray<BufferBarrier, MemoryPoolPtrWrapper<StackMemoryPool>> m_bufferBarriersBefore;
+	DynamicArray<ASBarrier, MemoryPoolPtrWrapper<StackMemoryPool>> m_asBarriersBefore;
 	CommandBuffer* m_cmdb; ///< Someone else holds the ref already so have a ptr here.
+
+	Batch(StackMemoryPool* pool)
+		: m_passIndices(pool)
+		, m_textureBarriersBefore(pool)
+		, m_bufferBarriersBefore(pool)
+		, m_asBarriersBefore(pool)
+	{
+	}
 };
 
 /// The RenderGraph build context.
 class RenderGraph::BakeContext
 {
 public:
-	StackMemoryPool* m_pool = nullptr;
-	DynamicArray<Pass> m_passes;
+	DynamicArray<Pass, MemoryPoolPtrWrapper<StackMemoryPool>> m_passes;
 	BitSet<kMaxRenderGraphPasses, U64> m_passIsInBatch{false};
-	DynamicArray<Batch> m_batches;
-	DynamicArray<RT> m_rts;
-	DynamicArray<Buffer> m_buffers;
-	DynamicArray<AS> m_as;
+	DynamicArray<Batch, MemoryPoolPtrWrapper<StackMemoryPool>> m_batches;
+	DynamicArray<RT, MemoryPoolPtrWrapper<StackMemoryPool>> m_rts;
+	DynamicArray<Buffer, MemoryPoolPtrWrapper<StackMemoryPool>> m_buffers;
+	DynamicArray<AS, MemoryPoolPtrWrapper<StackMemoryPool>> m_as;
 
-	DynamicArray<CommandBufferPtr> m_graphicsCmdbs;
+	DynamicArray<CommandBufferPtr, MemoryPoolPtrWrapper<StackMemoryPool>> m_graphicsCmdbs;
 
 	Bool m_gatherStatistics = false;
 
 	BakeContext(StackMemoryPool* pool)
-		: m_pool(pool)
+		: m_passes(pool)
+		, m_batches(pool)
+		, m_rts(pool)
+		, m_buffers(pool)
+		, m_as(pool)
+		, m_graphicsCmdbs(pool)
 	{
 	}
 };
@@ -312,7 +337,7 @@ void RenderGraph::reset()
 			{
 				// Not found, create
 				it = m_importedRenderTargets.emplace(hash);
-				it->m_surfOrVolLastUsages.create(surfOrVolumeCount);
+				it->m_surfOrVolLastUsages.resize(surfOrVolumeCount);
 			}
 
 			// Update the usage
@@ -343,11 +368,11 @@ void RenderGraph::reset()
 	for(Pass& p : m_ctx->m_passes)
 	{
 		p.fb().reset(nullptr);
-		p.m_secondLevelCmdbs.destroy(*m_ctx->m_pool);
-		p.m_callback.destroy(*m_ctx->m_pool);
+		p.m_secondLevelCmdbs.destroy();
+		p.m_callback.destroy();
 	}
 
-	m_ctx->m_graphicsCmdbs.destroy(*m_ctx->m_pool);
+	m_ctx->m_graphicsCmdbs.destroy();
 
 	m_ctx = nullptr;
 	++m_version;
@@ -676,10 +701,10 @@ RenderGraph::BakeContext* RenderGraph::newContext(const RenderGraphDescription&
 	BakeContext* ctx = anki::newInstance<BakeContext>(pool, &pool);
 
 	// Init the resources
-	ctx->m_rts.create(pool, descr.m_renderTargets.getSize());
-	for(U32 rtIdx = 0; rtIdx < ctx->m_rts.getSize(); ++rtIdx)
+	ctx->m_rts.resizeStorage(descr.m_renderTargets.getSize());
+	for(U32 rtIdx = 0; rtIdx < descr.m_renderTargets.getSize(); ++rtIdx)
 	{
-		RT& outRt = ctx->m_rts[rtIdx];
+		RT& outRt = *ctx->m_rts.emplaceBack(&pool);
 		const RenderGraphDescription::RT& inRt = descr.m_renderTargets[rtIdx];
 
 		const Bool imported = inRt.m_importedTex.isCreated();
@@ -706,7 +731,7 @@ RenderGraph::BakeContext* RenderGraph::newContext(const RenderGraphDescription&
 
 		// Init the usage
 		const U32 surfOrVolumeCount = getTextureSurfOrVolCount(outRt.m_texture);
-		outRt.m_surfOrVolUsages.create(pool, surfOrVolumeCount, TextureUsageBit::kNone);
+		outRt.m_surfOrVolUsages.resize(surfOrVolumeCount, TextureUsageBit::kNone);
 		if(imported && inRt.m_importedAndUndefinedUsage)
 		{
 			// Get the usage from previous frames
@@ -733,12 +758,12 @@ RenderGraph::BakeContext* RenderGraph::newContext(const RenderGraphDescription&
 			}
 		}
 
-		outRt.m_lastBatchThatTransitionedIt.create(pool, surfOrVolumeCount, kMaxU16);
+		outRt.m_lastBatchThatTransitionedIt.resize(surfOrVolumeCount, kMaxU16);
 		outRt.m_imported = imported;
 	}
 
 	// Buffers
-	ctx->m_buffers.create(pool, descr.m_buffers.getSize());
+	ctx->m_buffers.resize(descr.m_buffers.getSize());
 	for(U32 buffIdx = 0; buffIdx < ctx->m_buffers.getSize(); ++buffIdx)
 	{
 		ctx->m_buffers[buffIdx].m_usage = descr.m_buffers[buffIdx].m_usage;
@@ -749,7 +774,7 @@ RenderGraph::BakeContext* RenderGraph::newContext(const RenderGraphDescription&
 	}
 
 	// AS
-	ctx->m_as.create(pool, descr.m_as.getSize());
+	ctx->m_as.resize(descr.m_as.getSize());
 	for(U32 i = 0; i < descr.m_as.getSize(); ++i)
 	{
 		ctx->m_as[i].m_usage = descr.m_as[i].m_usage;
@@ -762,22 +787,22 @@ RenderGraph::BakeContext* RenderGraph::newContext(const RenderGraphDescription&
 	return ctx;
 }
 
-void RenderGraph::initRenderPassesAndSetDeps(const RenderGraphDescription& descr, StackMemoryPool& pool)
+void RenderGraph::initRenderPassesAndSetDeps(const RenderGraphDescription& descr)
 {
 	BakeContext& ctx = *m_ctx;
 	const U32 passCount = descr.m_passes.getSize();
 	ANKI_ASSERT(passCount > 0);
 
-	ctx.m_passes.create(pool, passCount);
+	ctx.m_passes.resizeStorage(passCount);
 	for(U32 passIdx = 0; passIdx < passCount; ++passIdx)
 	{
 		const RenderPassDescriptionBase& inPass = *descr.m_passes[passIdx];
-		Pass& outPass = ctx.m_passes[passIdx];
+		Pass& outPass = *ctx.m_passes.emplaceBack(ctx.m_as.getMemoryPool().m_pool);
 
-		outPass.m_callback.copy(inPass.m_callback, pool);
+		outPass.m_callback = inPass.m_callback;
 
 		// Create consumer info
-		outPass.m_consumedTextures.resize(pool, inPass.m_rtDeps.getSize());
+		outPass.m_consumedTextures.resize(inPass.m_rtDeps.getSize());
 		for(U32 depIdx = 0; depIdx < inPass.m_rtDeps.getSize(); ++depIdx)
 		{
 			const RenderPassDependency& inDep = inPass.m_rtDeps[depIdx];
@@ -821,7 +846,7 @@ void RenderGraph::initRenderPassesAndSetDeps(const RenderGraphDescription& descr
 			const RenderPassDescriptionBase& prevPass = *descr.m_passes[prevPassIdx];
 			if(passADependsOnB(inPass, prevPass))
 			{
-				outPass.m_dependsOn.emplaceBack(pool, prevPassIdx);
+				outPass.m_dependsOn.emplaceBack(prevPassIdx);
 			}
 		}
 	}
@@ -837,7 +862,7 @@ void RenderGraph::initBatches()
 	Bool setTimestamp = m_ctx->m_gatherStatistics;
 	while(passesAssignedToBatchCount < passCount)
 	{
-		m_ctx->m_batches.emplaceBack(*m_ctx->m_pool);
+		m_ctx->m_batches.emplaceBack(m_ctx->m_as.getMemoryPool().m_pool);
 		Batch& batch = m_ctx->m_batches.getBack();
 
 		Bool drawsToPresentable = false;
@@ -848,7 +873,7 @@ void RenderGraph::initBatches()
 			{
 				// Add to the batch
 				++passesAssignedToBatchCount;
-				batch.m_passIndices.emplaceBack(*m_ctx->m_pool, i);
+				batch.m_passIndices.emplaceBack(i);
 
 				// Will batch draw to the swapchain?
 				drawsToPresentable = drawsToPresentable || m_ctx->m_passes[i].m_drawsToPresentable;
@@ -864,7 +889,7 @@ void RenderGraph::initBatches()
 			cmdbInit.m_flags = CommandBufferFlag::kGeneralWork;
 			CommandBufferPtr cmdb = GrManager::getSingleton().newCommandBuffer(cmdbInit);
 
-			m_ctx->m_graphicsCmdbs.emplaceBack(*m_ctx->m_pool, cmdb);
+			m_ctx->m_graphicsCmdbs.emplaceBack(cmdb);
 
 			batch.m_cmdb = cmdb.get();
 
@@ -895,7 +920,7 @@ void RenderGraph::initBatches()
 	}
 }
 
-void RenderGraph::initGraphicsPasses(const RenderGraphDescription& descr, StackMemoryPool& pool)
+void RenderGraph::initGraphicsPasses(const RenderGraphDescription& descr)
 {
 	BakeContext& ctx = *m_ctx;
 	const U32 passCount = descr.m_passes.getSize();
@@ -939,7 +964,7 @@ void RenderGraph::initGraphicsPasses(const RenderGraphDescription& descr, StackM
 				// Do some pre-work for the second level command buffers
 				if(inPass.m_secondLevelCmdbsCount)
 				{
-					outPass.m_secondLevelCmdbs.create(pool, inPass.m_secondLevelCmdbsCount);
+					outPass.m_secondLevelCmdbs.resize(inPass.m_secondLevelCmdbsCount);
 					CommandBufferInitInfo& cmdbInit = outPass.m_secondLevelCmdbInitInfo;
 					cmdbInit.m_flags = CommandBufferFlag::kGeneralWork | CommandBufferFlag::kSecondLevel;
 					ANKI_ASSERT(cmdbInit.m_framebuffer.isCreated());
@@ -1022,7 +1047,7 @@ void RenderGraph::setTextureBarrier(Batch& batch, const RenderPassDependency& de
 				{
 					// Create a new barrier for this surface
 
-					batch.m_textureBarriersBefore.emplaceBack(*ctx.m_pool, rtIdx, crntUsage, depUsage, surf,
+					batch.m_textureBarriersBefore.emplaceBack(rtIdx, crntUsage, depUsage, surf,
 															  dep.m_texture.m_subresource.m_depthStencilAspect);
 
 					crntUsage = depUsage;
@@ -1037,7 +1062,6 @@ void RenderGraph::setTextureBarrier(Batch& batch, const RenderPassDependency& de
 void RenderGraph::setBatchBarriers(const RenderGraphDescription& descr)
 {
 	BakeContext& ctx = *m_ctx;
-	StackMemoryPool& pool = *ctx.m_pool;
 
 	// For all batches
 	for(Batch& batch : ctx.m_batches)
@@ -1074,7 +1098,7 @@ void RenderGraph::setBatchBarriers(const RenderGraphDescription& descr)
 				{
 					// Buff hasn't had a barrier in this batch, add a new barrier
 
-					batch.m_bufferBarriersBefore.emplaceBack(pool, buffIdx, crntUsage, depUsage);
+					batch.m_bufferBarriersBefore.emplaceBack(buffIdx, crntUsage, depUsage);
 
 					crntUsage = depUsage;
 					buffHasBarrierMask.set(buffIdx);
@@ -1117,7 +1141,7 @@ void RenderGraph::setBatchBarriers(const RenderGraphDescription& descr)
 				{
 					// AS doesn't have a barrier in this batch, create a new one
 
-					batch.m_asBarriersBefore.emplaceBack(pool, asIdx, crntUsage, depUsage);
+					batch.m_asBarriersBefore.emplaceBack(asIdx, crntUsage, depUsage);
 					crntUsage = depUsage;
 					asHasBarrierMask.set(asIdx);
 				}
@@ -1197,13 +1221,13 @@ void RenderGraph::compileNewGraph(const RenderGraphDescription& descr, StackMemo
 	m_ctx = &ctx;
 
 	// Init the passes and find the dependencies between passes
-	initRenderPassesAndSetDeps(descr, pool);
+	initRenderPassesAndSetDeps(descr);
 
 	// Walk the graph and create pass batches
 	initBatches();
 
 	// Now that we know the batches every pass belongs init the graphics passes
-	initGraphicsPasses(descr, pool);
+	initGraphicsPasses(descr);
 
 	// Create barriers between batches
 	setBatchBarriers(descr);
@@ -1273,6 +1297,8 @@ void RenderGraph::run() const
 	ANKI_TRACE_SCOPED_EVENT(GrRenderGraphRun);
 	ANKI_ASSERT(m_ctx);
 
+	StackMemoryPool* pool = m_ctx->m_rts.getMemoryPool().m_pool;
+
 	RenderPassWorkContext ctx;
 	ctx.m_rgraph = this;
 	ctx.m_currentSecondLevelCommandBufferIndex = 0;
@@ -1284,7 +1310,7 @@ void RenderGraph::run() const
 		CommandBufferPtr& cmdb = ctx.m_commandBuffer;
 
 		// Set the barriers
-		DynamicArrayRaii<TextureBarrierInfo> texBarriers(m_ctx->m_pool);
+		DynamicArray<TextureBarrierInfo, MemoryPoolPtrWrapper<StackMemoryPool>> texBarriers(pool);
 		texBarriers.resizeStorage(batch.m_textureBarriersBefore.getSize());
 		for(const TextureBarrier& barrier : batch.m_textureBarriersBefore)
 		{
@@ -1295,7 +1321,7 @@ void RenderGraph::run() const
 			inf.m_subresource.m_depthStencilAspect = barrier.m_dsAspect;
 			inf.m_texture = m_ctx->m_rts[barrier.m_idx].m_texture.get();
 		}
-		DynamicArrayRaii<BufferBarrierInfo> buffBarriers(m_ctx->m_pool);
+		DynamicArray<BufferBarrierInfo, MemoryPoolPtrWrapper<StackMemoryPool>> buffBarriers(pool);
 		buffBarriers.resizeStorage(batch.m_bufferBarriersBefore.getSize());
 		for(const BufferBarrier& barrier : batch.m_bufferBarriersBefore)
 		{
@@ -1306,7 +1332,7 @@ void RenderGraph::run() const
 			inf.m_size = m_ctx->m_buffers[barrier.m_idx].m_range;
 			inf.m_buffer = m_ctx->m_buffers[barrier.m_idx].m_buffer.get();
 		}
-		DynamicArrayRaii<AccelerationStructureBarrierInfo> asBarriers(m_ctx->m_pool);
+		DynamicArray<AccelerationStructureBarrierInfo, MemoryPoolPtrWrapper<StackMemoryPool>> asBarriers(pool);
 		for(const ASBarrier& barrier : batch.m_asBarriersBefore)
 		{
 			AccelerationStructureBarrierInfo& inf = *asBarriers.emplaceBack();
@@ -1338,7 +1364,7 @@ void RenderGraph::run() const
 			}
 			else
 			{
-				DynamicArrayRaii<CommandBuffer*> cmdbs(m_ctx->m_pool);
+				DynamicArray<CommandBuffer*, MemoryPoolPtrWrapper<StackMemoryPool>> cmdbs(pool);
 				cmdbs.resizeStorage(size);
 				for(const CommandBufferPtr& cmdb2nd : pass.m_secondLevelCmdbs)
 				{
@@ -1413,7 +1439,7 @@ void RenderGraph::periodicCleanup()
 			GrDynamicArray<TexturePtr> newArray;
 			if(entry.m_texturesInUse > 0)
 			{
-				newArray.create(entry.m_texturesInUse);
+				newArray.resize(entry.m_texturesInUse);
 			}
 
 			// Populate the new array

+ 26 - 32
AnKi/Gr/RenderGraph.h

@@ -319,20 +319,11 @@ class RenderPassDescriptionBase
 	friend class RenderGraphDescription;
 
 public:
-	virtual ~RenderPassDescriptionBase()
-	{
-		m_name.destroy(*m_pool); // To avoid the assertion
-		m_rtDeps.destroy(*m_pool);
-		m_buffDeps.destroy(*m_pool);
-		m_asDeps.destroy(*m_pool);
-		m_callback.destroy(*m_pool);
-	}
-
 	template<typename TFunc>
 	void setWork(U32 secondLeveCmdbCount, TFunc func)
 	{
 		ANKI_ASSERT(m_type == Type::kGraphics || secondLeveCmdbCount == 0);
-		m_callback.init(*m_pool, func);
+		m_callback = {func, m_rtDeps.getMemoryPool().m_pool};
 		m_secondLevelCmdbsCount = secondLeveCmdbCount;
 	}
 
@@ -373,15 +364,14 @@ protected:
 
 	Type m_type;
 
-	StackMemoryPool* m_pool = nullptr;
 	RenderGraphDescription* m_descr;
 
-	Function<void(RenderPassWorkContext&)> m_callback;
+	Function<void(RenderPassWorkContext&), MemoryPoolPtrWrapper<StackMemoryPool>> m_callback;
 	U32 m_secondLevelCmdbsCount = 0;
 
-	DynamicArray<RenderPassDependency> m_rtDeps;
-	DynamicArray<RenderPassDependency> m_buffDeps;
-	DynamicArray<RenderPassDependency> m_asDeps;
+	DynamicArray<RenderPassDependency, MemoryPoolPtrWrapper<StackMemoryPool>> m_rtDeps;
+	DynamicArray<RenderPassDependency, MemoryPoolPtrWrapper<StackMemoryPool>> m_buffDeps;
+	DynamicArray<RenderPassDependency, MemoryPoolPtrWrapper<StackMemoryPool>> m_asDeps;
 
 	BitSet<kMaxRenderGraphRenderTargets, U64> m_readRtMask{false};
 	BitSet<kMaxRenderGraphRenderTargets, U64> m_writeRtMask{false};
@@ -390,18 +380,22 @@ protected:
 	BitSet<kMaxRenderGraphAccelerationStructures, U32> m_readAsMask{false};
 	BitSet<kMaxRenderGraphAccelerationStructures, U32> m_writeAsMask{false};
 
-	String m_name;
+	BaseString<MemoryPoolPtrWrapper<StackMemoryPool>> m_name;
 
-	RenderPassDescriptionBase(Type t, RenderGraphDescription* descr)
+	RenderPassDescriptionBase(Type t, RenderGraphDescription* descr, StackMemoryPool* pool)
 		: m_type(t)
 		, m_descr(descr)
+		, m_rtDeps(pool)
+		, m_buffDeps(pool)
+		, m_asDeps(pool)
+		, m_name(pool)
 	{
-		ANKI_ASSERT(descr);
+		ANKI_ASSERT(descr && pool);
 	}
 
 	void setName(CString name)
 	{
-		m_name.create(*m_pool, (name.isEmpty()) ? "N/A" : name);
+		m_name = (name.isEmpty()) ? "N/A" : name;
 	}
 
 	void fixSubresource(RenderPassDependency& dep) const;
@@ -463,8 +457,8 @@ class GraphicsRenderPassDescription : public RenderPassDescriptionBase
 	friend class RenderGraph;
 
 public:
-	GraphicsRenderPassDescription(RenderGraphDescription* descr)
-		: RenderPassDescriptionBase(Type::kGraphics, descr)
+	GraphicsRenderPassDescription(RenderGraphDescription* descr, StackMemoryPool* pool)
+		: RenderPassDescriptionBase(Type::kGraphics, descr, pool)
 	{
 		memset(&m_rtHandles[0], 0xFF, sizeof(m_rtHandles));
 	}
@@ -499,8 +493,8 @@ class ComputeRenderPassDescription : public RenderPassDescriptionBase
 	friend class RenderGraphDescription;
 
 public:
-	ComputeRenderPassDescription(RenderGraphDescription* descr)
-		: RenderPassDescriptionBase(Type::kNoGraphics, descr)
+	ComputeRenderPassDescription(RenderGraphDescription* descr, StackMemoryPool* pool)
+		: RenderPassDescriptionBase(Type::kNoGraphics, descr, pool)
 	{
 	}
 };
@@ -592,10 +586,10 @@ private:
 	};
 
 	StackMemoryPool* m_pool = nullptr;
-	DynamicArray<RenderPassDescriptionBase*> m_passes;
-	DynamicArray<RT> m_renderTargets;
-	DynamicArray<Buffer> m_buffers;
-	DynamicArray<AS> m_as;
+	DynamicArray<RenderPassDescriptionBase*, MemoryPoolPtrWrapper<StackMemoryPool>> m_passes{m_pool};
+	DynamicArray<RT, MemoryPoolPtrWrapper<StackMemoryPool>> m_renderTargets{m_pool};
+	DynamicArray<Buffer, MemoryPoolPtrWrapper<StackMemoryPool>> m_buffers{m_pool};
+	DynamicArray<AS, MemoryPoolPtrWrapper<StackMemoryPool>> m_as{m_pool};
 	Bool m_gatherStatistics = false;
 
 	/// Return true if 2 buffer ranges overlap.
@@ -735,9 +729,9 @@ private:
 	[[nodiscard]] static RenderGraph* newInstance();
 
 	BakeContext* newContext(const RenderGraphDescription& descr, StackMemoryPool& pool);
-	void initRenderPassesAndSetDeps(const RenderGraphDescription& descr, StackMemoryPool& pool);
+	void initRenderPassesAndSetDeps(const RenderGraphDescription& descr);
 	void initBatches();
-	void initGraphicsPasses(const RenderGraphDescription& descr, StackMemoryPool& pool);
+	void initGraphicsPasses(const RenderGraphDescription& descr);
 	void setBatchBarriers(const RenderGraphDescription& descr);
 
 	TexturePtr getOrCreateRenderTarget(const TextureInitInfo& initInf, U64 hash);
@@ -764,9 +758,9 @@ private:
 	/// @name Dump the dependency graph into a file.
 	/// @{
 	Error dumpDependencyDotFile(const RenderGraphDescription& descr, const BakeContext& ctx, CString path) const;
-	static StringRaii textureUsageToStr(StackMemoryPool& pool, TextureUsageBit usage);
-	static StringRaii bufferUsageToStr(StackMemoryPool& pool, BufferUsageBit usage);
-	static StringRaii asUsageToStr(StackMemoryPool& pool, AccelerationStructureUsageBit usage);
+	static GrString textureUsageToStr(StackMemoryPool& pool, TextureUsageBit usage);
+	static GrString bufferUsageToStr(StackMemoryPool& pool, BufferUsageBit usage);
+	static GrString asUsageToStr(StackMemoryPool& pool, AccelerationStructureUsageBit usage);
 	/// @}
 
 	TexturePtr getTexture(RenderTargetHandle handle) const;

+ 11 - 17
AnKi/Gr/RenderGraph.inl.h

@@ -128,7 +128,7 @@ inline void RenderPassDescriptionBase::newDependency(const RenderPassDependency&
 
 	if(kType == RenderPassDependency::Type::kTexture)
 	{
-		m_rtDeps.emplaceBack(*m_pool, dep);
+		m_rtDeps.emplaceBack(dep);
 		fixSubresource(m_rtDeps.getBack());
 
 		if(!!(dep.m_texture.m_usage & TextureUsageBit::kAllRead))
@@ -157,7 +157,7 @@ inline void RenderPassDescriptionBase::newDependency(const RenderPassDependency&
 	}
 	else if(kType == RenderPassDependency::Type::kBuffer)
 	{
-		m_buffDeps.emplaceBack(*m_pool, dep);
+		m_buffDeps.emplaceBack(dep);
 
 		if(!!(dep.m_buffer.m_usage & BufferUsageBit::kAllRead))
 		{
@@ -172,7 +172,7 @@ inline void RenderPassDescriptionBase::newDependency(const RenderPassDependency&
 	else
 	{
 		ANKI_ASSERT(kType == RenderPassDependency::Type::kAccelerationStructure);
-		m_asDeps.emplaceBack(*m_pool, dep);
+		m_asDeps.emplaceBack(dep);
 
 		if(!!(dep.m_as.m_usage & AccelerationStructureUsageBit::kAllRead))
 		{
@@ -252,27 +252,21 @@ inline RenderGraphDescription::~RenderGraphDescription()
 	{
 		deleteInstance(*m_pool, pass);
 	}
-	m_passes.destroy(*m_pool);
-	m_renderTargets.destroy(*m_pool);
-	m_buffers.destroy(*m_pool);
-	m_as.destroy(*m_pool);
 }
 
 inline GraphicsRenderPassDescription& RenderGraphDescription::newGraphicsRenderPass(CString name)
 {
-	GraphicsRenderPassDescription* pass = newInstance<GraphicsRenderPassDescription>(*m_pool, this);
-	pass->m_pool = m_pool;
+	GraphicsRenderPassDescription* pass = newInstance<GraphicsRenderPassDescription>(*m_pool, this, m_pool);
 	pass->setName(name);
-	m_passes.emplaceBack(*m_pool, pass);
+	m_passes.emplaceBack(pass);
 	return *pass;
 }
 
 inline ComputeRenderPassDescription& RenderGraphDescription::newComputeRenderPass(CString name)
 {
-	ComputeRenderPassDescription* pass = newInstance<ComputeRenderPassDescription>(*m_pool, this);
-	pass->m_pool = m_pool;
+	ComputeRenderPassDescription* pass = newInstance<ComputeRenderPassDescription>(*m_pool, this, m_pool);
 	pass->setName(name);
-	m_passes.emplaceBack(*m_pool, pass);
+	m_passes.emplaceBack(pass);
 	return *pass;
 }
 
@@ -283,7 +277,7 @@ inline RenderTargetHandle RenderGraphDescription::importRenderTarget(TexturePtr
 		ANKI_ASSERT(rt.m_importedTex != tex && "Already imported");
 	}
 
-	RT& rt = *m_renderTargets.emplaceBack(*m_pool);
+	RT& rt = *m_renderTargets.emplaceBack();
 	rt.m_importedTex = tex;
 	rt.m_importedLastKnownUsage = usage;
 	rt.m_usageDerivedByDeps = TextureUsageBit::kNone;
@@ -306,7 +300,7 @@ inline RenderTargetHandle RenderGraphDescription::newRenderTarget(const RenderTa
 	ANKI_ASSERT(initInf.m_hash && "Forgot to call RenderTargetDescription::bake");
 	ANKI_ASSERT(initInf.m_usage == TextureUsageBit::kNone
 				&& "Don't need to supply the usage. Render grap will find it");
-	RT& rt = *m_renderTargets.emplaceBack(*m_pool);
+	RT& rt = *m_renderTargets.emplaceBack();
 	rt.m_initInfo = initInf;
 	rt.m_hash = initInf.m_hash;
 	rt.m_importedLastKnownUsage = TextureUsageBit::kNone;
@@ -339,7 +333,7 @@ inline BufferHandle RenderGraphDescription::importBuffer(BufferPtr buff, BufferU
 					&& "Range already imported");
 	}
 
-	Buffer& b = *m_buffers.emplaceBack(*m_pool);
+	Buffer& b = *m_buffers.emplaceBack();
 	b.setName(buff->getName());
 	b.m_usage = usage;
 	b.m_importedBuff = std::move(buff);
@@ -359,7 +353,7 @@ RenderGraphDescription::importAccelerationStructure(AccelerationStructurePtr as,
 		ANKI_ASSERT(a.m_importedAs != as && "Already imported");
 	}
 
-	AS& a = *m_as.emplaceBack(*m_pool);
+	AS& a = *m_as.emplaceBack();
 	a.setName(as->getName());
 	a.m_importedAs = std::move(as);
 	a.m_usage = usage;

+ 4 - 8
AnKi/Gr/Utils/SegregatedListsGpuMemoryPool.cpp

@@ -9,7 +9,8 @@
 
 namespace anki {
 
-class SegregatedListsGpuMemoryPool::Chunk : public SegregatedListsAllocatorBuilderChunkBase
+class SegregatedListsGpuMemoryPool::Chunk :
+	public SegregatedListsAllocatorBuilderChunkBase<SingletonMemoryPoolWrapper<GrMemoryPool>>
 {
 public:
 	PtrSize m_offsetInGpuBuffer;
@@ -46,11 +47,6 @@ public:
 	{
 		return 4;
 	}
-
-	BaseMemoryPool& getMemoryPool() const
-	{
-		return GrMemoryPool::getSingleton();
-	}
 	/// @}
 };
 
@@ -63,7 +59,7 @@ void SegregatedListsGpuMemoryPool::init(BufferUsageBit gpuBufferUsage, ConstWeak
 	m_bufferUsage = gpuBufferUsage;
 
 	ANKI_ASSERT(classUpperSizes.getSize() > 0);
-	m_classes.create(classUpperSizes.getSize());
+	m_classes.resize(classUpperSizes.getSize());
 	for(U32 i = 0; i < m_classes.getSize(); ++i)
 	{
 		m_classes[i] = classUpperSizes[i];
@@ -72,7 +68,7 @@ void SegregatedListsGpuMemoryPool::init(BufferUsageBit gpuBufferUsage, ConstWeak
 	ANKI_ASSERT(initialGpuBufferSize > 0);
 	m_initialBufferSize = initialGpuBufferSize;
 
-	m_bufferName.create(bufferName);
+	m_bufferName = bufferName;
 
 	m_builder = newInstance<Builder>(GrMemoryPool::getSingleton());
 	m_builder->getInterface().m_parent = this;

+ 2 - 1
AnKi/Gr/Utils/SegregatedListsGpuMemoryPool.h

@@ -84,7 +84,8 @@ public:
 private:
 	class BuilderInterface;
 	class Chunk;
-	using Builder = SegregatedListsAllocatorBuilder<Chunk, BuilderInterface, DummyMutex>;
+	using Builder =
+		SegregatedListsAllocatorBuilder<Chunk, BuilderInterface, DummyMutex, SingletonMemoryPoolWrapper<GrMemoryPool>>;
 
 	BufferUsageBit m_bufferUsage = BufferUsageBit::kNone;
 	GrDynamicArray<PtrSize> m_classes;

+ 1 - 1
AnKi/Gr/Utils/StackGpuMemoryPool.cpp

@@ -130,7 +130,7 @@ void StackGpuMemoryPool::init(PtrSize initialSize, F64 nextChunkGrowScale, PtrSi
 	inter.m_initialSize = initialSize;
 	inter.m_scale = nextChunkGrowScale;
 	inter.m_bias = nextChunkGrowBias;
-	inter.m_bufferName.create(bufferName);
+	inter.m_bufferName = bufferName;
 	inter.m_alignment = alignment;
 	inter.m_bufferUsage = bufferUsage;
 	inter.m_bufferMap = bufferMapping;

+ 1 - 1
AnKi/Gr/Vulkan/BufferImpl.cpp

@@ -18,7 +18,7 @@ BufferImpl::~BufferImpl()
 
 	if(m_views.getSize())
 	{
-		garbage->m_viewHandles.create(U32(m_views.getSize()));
+		garbage->m_viewHandles.resize(U32(m_views.getSize()));
 
 		U32 count = 0;
 		for(auto it : m_views)

+ 2 - 2
AnKi/Gr/Vulkan/CommandBufferFactory.cpp

@@ -132,9 +132,9 @@ Error CommandBufferThreadAllocator::newCommandBuffer(CommandBufferFlag cmdbFlags
 		newCmdb->m_fastPool.init(GrMemoryPool::getSingleton().getAllocationCallback(),
 								 GrMemoryPool::getSingleton().getAllocationCallbackUserData(), 256_KB, 2.0f);
 
-		for(DynamicArrayRaii<GrObjectPtr>& arr : newCmdb->m_objectRefs)
+		for(DynamicArray<GrObjectPtr, MemoryPoolPtrWrapper<StackMemoryPool>>& arr : newCmdb->m_objectRefs)
 		{
-			arr = DynamicArrayRaii<GrObjectPtr>(&newCmdb->m_fastPool);
+			arr = DynamicArray<GrObjectPtr, MemoryPoolPtrWrapper<StackMemoryPool>>(&newCmdb->m_fastPool);
 		}
 
 		newCmdb->m_handle = cmdb;

+ 4 - 4
AnKi/Gr/Vulkan/CommandBufferFactory.h

@@ -29,9 +29,9 @@ public:
 		: m_threadAlloc(allocator)
 	{
 		ANKI_ASSERT(allocator);
-		for(DynamicArrayRaii<GrObjectPtr>& arr : m_objectRefs)
+		for(DynamicArray<GrObjectPtr, MemoryPoolPtrWrapper<StackMemoryPool>>& arr : m_objectRefs)
 		{
-			arr = DynamicArrayRaii<GrObjectPtr>(&m_fastPool);
+			arr = DynamicArray<GrObjectPtr, MemoryPoolPtrWrapper<StackMemoryPool>>(&m_fastPool);
 		}
 	}
 
@@ -111,7 +111,7 @@ private:
 	VkCommandBuffer m_handle = {};
 
 	MicroFencePtr m_fence;
-	Array<DynamicArrayRaii<GrObjectPtr>, U(GrObjectType::kCount)> m_objectRefs;
+	Array<DynamicArray<GrObjectPtr, MemoryPoolPtrWrapper<StackMemoryPool>>, U(GrObjectType::kCount)> m_objectRefs;
 
 	// Cacheline boundary
 
@@ -122,7 +122,7 @@ private:
 
 	void reset();
 
-	void pushToArray(DynamicArrayRaii<GrObjectPtr>& arr, GrObject* grobj)
+	void pushToArray(DynamicArray<GrObjectPtr, MemoryPoolPtrWrapper<StackMemoryPool>>& arr, GrObject* grobj)
 	{
 		ANKI_ASSERT(grobj);
 

+ 3 - 3
AnKi/Gr/Vulkan/CommandBufferImpl.cpp

@@ -628,9 +628,9 @@ void CommandBufferImpl::setPipelineBarrierInternal(
 {
 	commandCommon();
 
-	DynamicArrayRaii<VkImageMemoryBarrier> imageBarriers(m_pool);
-	DynamicArrayRaii<VkBufferMemoryBarrier> bufferBarriers(m_pool);
-	DynamicArrayRaii<VkMemoryBarrier> genericBarriers(m_pool);
+	DynamicArray<VkImageMemoryBarrier, MemoryPoolPtrWrapper<StackMemoryPool>> imageBarriers(m_pool);
+	DynamicArray<VkBufferMemoryBarrier, MemoryPoolPtrWrapper<StackMemoryPool>> bufferBarriers(m_pool);
+	DynamicArray<VkMemoryBarrier, MemoryPoolPtrWrapper<StackMemoryPool>> genericBarriers(m_pool);
 	VkPipelineStageFlags srcStageMask = 0;
 	VkPipelineStageFlags dstStageMask = 0;
 

+ 2 - 1
AnKi/Gr/Vulkan/CommandBufferImpl.inl.h

@@ -394,7 +394,8 @@ inline void CommandBufferImpl::pushSecondLevelCommandBuffersInternal(ConstWeakAr
 		beginRenderPassInternal();
 	}
 
-	DynamicArrayRaii<VkCommandBuffer> handles(cmdbs.getSize(), m_pool);
+	DynamicArray<VkCommandBuffer, MemoryPoolPtrWrapper<StackMemoryPool>> handles(m_pool);
+	handles.resize(cmdbs.getSize());
 	for(U32 i = 0; i < cmdbs.getSize(); ++i)
 	{
 		ANKI_ASSERT(static_cast<const CommandBufferImpl&>(*cmdbs[i]).m_finalized);

+ 7 - 7
AnKi/Gr/Vulkan/DescriptorSet.cpp

@@ -254,7 +254,7 @@ Error DescriptorSetFactory::BindlessDescriptorSet::init(U32 bindlessTextureCount
 
 	// Init the free arrays
 	{
-		m_freeTexIndices.create(bindlessTextureCount);
+		m_freeTexIndices.resize(bindlessTextureCount);
 		m_freeTexIndexCount = U16(m_freeTexIndices.getSize());
 
 		for(U32 i = 0; i < m_freeTexIndices.getSize(); ++i)
@@ -262,7 +262,7 @@ Error DescriptorSetFactory::BindlessDescriptorSet::init(U32 bindlessTextureCount
 			m_freeTexIndices[i] = U16(m_freeTexIndices.getSize() - i - 1);
 		}
 
-		m_freeTexelBufferIndices.create(bindlessTextureBuffers);
+		m_freeTexelBufferIndices.resize(bindlessTextureBuffers);
 		m_freeTexelBufferIndexCount = U16(m_freeTexelBufferIndices.getSize());
 
 		for(U32 i = 0; i < m_freeTexelBufferIndices.getSize(); ++i)
@@ -507,11 +507,11 @@ Error DescriptorSetFactory::DSAllocator::newSet(U64 hash,
 void DescriptorSetFactory::DSAllocator::writeSet(
 	const Array<AnyBindingExtended, kMaxBindingsPerDescriptorSet>& bindings, const DS& set, StackMemoryPool& tmpPool)
 {
-	DynamicArrayRaii<VkWriteDescriptorSet> writeInfos(&tmpPool);
-	DynamicArrayRaii<VkDescriptorImageInfo> texInfos(&tmpPool);
-	DynamicArrayRaii<VkDescriptorBufferInfo> buffInfos(&tmpPool);
-	DynamicArrayRaii<VkWriteDescriptorSetAccelerationStructureKHR> asInfos(&tmpPool);
-	DynamicArrayRaii<VkBufferView> bufferViews(&tmpPool);
+	DynamicArray<VkWriteDescriptorSet, MemoryPoolPtrWrapper<StackMemoryPool>> writeInfos(&tmpPool);
+	DynamicArray<VkDescriptorImageInfo, MemoryPoolPtrWrapper<StackMemoryPool>> texInfos(&tmpPool);
+	DynamicArray<VkDescriptorBufferInfo, MemoryPoolPtrWrapper<StackMemoryPool>> buffInfos(&tmpPool);
+	DynamicArray<VkWriteDescriptorSetAccelerationStructureKHR, MemoryPoolPtrWrapper<StackMemoryPool>> asInfos(&tmpPool);
+	DynamicArray<VkBufferView, MemoryPoolPtrWrapper<StackMemoryPool>> bufferViews(&tmpPool);
 
 	// First pass: Populate the VkDescriptorImageInfo and VkDescriptorBufferInfo
 	for(U bindingIdx = m_layoutEntry->m_minBinding; bindingIdx <= m_layoutEntry->m_maxBinding; ++bindingIdx)

+ 6 - 2
AnKi/Gr/Vulkan/GpuMemoryManager.cpp

@@ -68,6 +68,10 @@ void GpuMemoryManagerInterface::freeChunk(GpuMemoryManagerChunk* chunk)
 	deleteInstance(GrMemoryPool::getSingleton(), chunk);
 }
 
+GpuMemoryManager::GpuMemoryManager()
+{
+}
+
 GpuMemoryManager::~GpuMemoryManager()
 {
 }
@@ -116,7 +120,7 @@ void GpuMemoryManager::init(Bool exposeBufferGpuAddress)
 
 	vkGetPhysicalDeviceMemoryProperties(getGrManagerImpl().getPhysicalDevice(), &m_memoryProperties);
 
-	m_callocs.create(m_memoryProperties.memoryTypeCount);
+	m_callocs.resize(m_memoryProperties.memoryTypeCount);
 	for(U32 memTypeIdx = 0; memTypeIdx < m_callocs.getSize(); ++memTypeIdx)
 	{
 		GpuMemoryManagerInterface& iface = m_callocs[memTypeIdx].getInterface();
@@ -152,7 +156,7 @@ void GpuMemoryManager::init(Bool exposeBufferGpuAddress)
 		}
 
 		// The interface is initialized, init the builder
-		m_callocs[memTypeIdx].init(&GrMemoryPool::getSingleton());
+		m_callocs[memTypeIdx].init();
 	}
 }
 

+ 3 - 2
AnKi/Gr/Vulkan/GpuMemoryManager.h

@@ -122,7 +122,7 @@ class GpuMemoryManager
 	friend class GpuMemoryManagerInterface;
 
 public:
-	GpuMemoryManager() = default;
+	GpuMemoryManager();
 
 	GpuMemoryManager(const GpuMemoryManager&) = delete; // Non-copyable
 
@@ -153,7 +153,8 @@ public:
 	void getStats(GpuMemoryManagerStats& stats) const;
 
 private:
-	using ClassAllocator = ClassAllocatorBuilder<GpuMemoryManagerChunk, GpuMemoryManagerInterface, Mutex>;
+	using ClassAllocator = ClassAllocatorBuilder<GpuMemoryManagerChunk, GpuMemoryManagerInterface, Mutex,
+												 SingletonMemoryPoolWrapper<GrMemoryPool>>;
 
 	GrDynamicArray<ClassAllocator> m_callocs;
 

+ 20 - 15
AnKi/Gr/Vulkan/GrManagerImpl.cpp

@@ -234,7 +234,8 @@ Error GrManagerImpl::initInstance()
 
 		if(layerCount)
 		{
-			GrDynamicArray<VkLayerProperties> layerProps(layerCount);
+			GrDynamicArray<VkLayerProperties> layerProps;
+			layerProps.resize(layerCount);
 			vkEnumerateInstanceLayerProperties(&layerCount, &layerProps[0]);
 
 			ANKI_VK_LOGV("Found the following instance layers:");
@@ -299,8 +300,8 @@ Error GrManagerImpl::initInstance()
 	vkEnumerateInstanceExtensionProperties(nullptr, &extCount, nullptr);
 	if(extCount)
 	{
-		instExtensions.create(extCount);
-		instExtensionInf.create(extCount);
+		instExtensions.resize(extCount);
+		instExtensionInf.resize(extCount);
 		vkEnumerateInstanceExtensionProperties(nullptr, &extCount, &instExtensionInf[0]);
 
 		ANKI_VK_LOGV("Found the following instance extensions:");
@@ -429,7 +430,8 @@ Error GrManagerImpl::initInstance()
 			return Error::kFunctionFailed;
 		}
 
-		GrDynamicArray<VkPhysicalDevice> physicalDevices(count);
+		GrDynamicArray<VkPhysicalDevice> physicalDevices;
+		physicalDevices.resize(count);
 		ANKI_VK_CHECK(vkEnumeratePhysicalDevices(m_instance, &count, &physicalDevices[0]));
 
 		class Dev
@@ -439,7 +441,8 @@ Error GrManagerImpl::initInstance()
 			VkPhysicalDeviceProperties2 m_vkProps;
 		};
 
-		GrDynamicArray<Dev> devs(count);
+		GrDynamicArray<Dev> devs;
+		devs.resize(count);
 		for(U32 devIdx = 0; devIdx < count; ++devIdx)
 		{
 			devs[devIdx].m_pdev = physicalDevices[devIdx];
@@ -574,7 +577,7 @@ Error GrManagerImpl::initDevice()
 	ANKI_VK_LOGI("Number of queue families: %u", count);
 
 	GrDynamicArray<VkQueueFamilyProperties> queueInfos;
-	queueInfos.create(count);
+	queueInfos.resize(count);
 	vkGetPhysicalDeviceQueueFamilyProperties(m_physicalDevice, &count, &queueInfos[0]);
 
 	const VkQueueFlags GENERAL_QUEUE_FLAGS = VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT;
@@ -647,8 +650,8 @@ Error GrManagerImpl::initDevice()
 	GrDynamicArray<const char*> extensionsToEnable;
 	if(extCount)
 	{
-		extensionInfos.create(extCount);
-		extensionsToEnable.create(extCount);
+		extensionInfos.resize(extCount);
+		extensionsToEnable.resize(extCount);
 		U32 extensionsToEnableCount = 0;
 		vkEnumerateDeviceExtensionProperties(m_physicalDevice, nullptr, &extCount, &extensionInfos[0]);
 
@@ -1513,16 +1516,16 @@ VkBool32 GrManagerImpl::debugReportCallbackEXT(VkDebugUtilsMessageSeverityFlagBi
 		for(U32 i = 0; i < pCallbackData->objectCount; ++i)
 		{
 			const Char* name = pCallbackData->pObjects[i].pObjectName;
-			objectNames.append((name) ? name : "?");
+			objectNames += (name) ? name : "?";
 			if(i < pCallbackData->objectCount - 1)
 			{
-				objectNames.append(", ");
+				objectNames += ", ";
 			}
 		}
 	}
 	else
 	{
-		objectNames.create("N/A");
+		objectNames = "N/A";
 	}
 
 	if(messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT)
@@ -1590,8 +1593,8 @@ Error GrManagerImpl::printPipelineShaderInfoInternal(VkPipeline ppline, CString
 			ANKI_VK_CHECK(m_pfnGetShaderInfoAMD(m_device, ppline, VkShaderStageFlagBits(convertShaderTypeBit(stage)),
 												VK_SHADER_INFO_TYPE_STATISTICS_AMD, &size, &stats));
 
-			str.append(GrString().sprintf("Stage %u: VGRPS %02u, SGRPS %02u ", U32(type),
-										  stats.resourceUsage.numUsedVgprs, stats.resourceUsage.numUsedSgprs));
+			str += GrString().sprintf("Stage %u: VGRPS %02u, SGRPS %02u ", U32(type), stats.resourceUsage.numUsedVgprs,
+									  stats.resourceUsage.numUsedSgprs);
 
 			ANKI_CHECK(m_shaderStatsFile.writeTextf((type != ShaderType::kLast) ? "%u,%u," : "%u,%u\n",
 													stats.resourceUsage.numUsedVgprs,
@@ -1613,7 +1616,8 @@ Error GrManagerImpl::printPipelineShaderInfoInternal(VkPipeline ppline, CString
 		pplineInf.pipeline = ppline;
 		U32 executableCount = 0;
 		ANKI_VK_CHECK(vkGetPipelineExecutablePropertiesKHR(m_device, &pplineInf, &executableCount, nullptr));
-		GrDynamicArray<VkPipelineExecutablePropertiesKHR> executableProps(executableCount);
+		GrDynamicArray<VkPipelineExecutablePropertiesKHR> executableProps;
+		executableProps.resize(executableCount);
 		for(VkPipelineExecutablePropertiesKHR& prop : executableProps)
 		{
 			prop = {};
@@ -1635,7 +1639,8 @@ Error GrManagerImpl::printPipelineShaderInfoInternal(VkPipeline ppline, CString
 			exeInf.pipeline = ppline;
 			U32 statCount = 0;
 			vkGetPipelineExecutableStatisticsKHR(m_device, &exeInf, &statCount, nullptr);
-			GrDynamicArray<VkPipelineExecutableStatisticKHR> stats(statCount);
+			GrDynamicArray<VkPipelineExecutableStatisticKHR> stats;
+			stats.resize(statCount);
 			for(VkPipelineExecutableStatisticKHR& s : stats)
 			{
 				s = {};

+ 2 - 2
AnKi/Gr/Vulkan/PipelineCache.cpp

@@ -44,7 +44,7 @@ Error PipelineCache::init(CString cacheDir)
 			}
 			else
 			{
-				diskDump.create(diskDumpSize - VK_UUID_SIZE);
+				diskDump.resize(diskDumpSize - VK_UUID_SIZE);
 				ANKI_CHECK(file.read(&diskDump[0], diskDumpSize - VK_UUID_SIZE));
 			}
 		}
@@ -93,7 +93,7 @@ Error PipelineCache::destroyInternal()
 		{
 			// Read cache
 			GrDynamicArray<U8, PtrSize> cacheData;
-			cacheData.create(size);
+			cacheData.resize(size);
 			ANKI_VK_CHECK(vkGetPipelineCacheData(getVkDevice(), m_cacheHandle, &size, &cacheData[0]));
 
 			// Write file

+ 1 - 1
AnKi/Gr/Vulkan/ShaderImpl.cpp

@@ -198,7 +198,7 @@ void ShaderImpl::doReflection(ConstWeakArray<U8> spirv, SpecConstsVector& specCo
 	{
 		if(counts[set])
 		{
-			m_bindings[set].create(counts[set]);
+			m_bindings[set].resize(counts[set]);
 			memcpy(&m_bindings[set][0], &descriptors[set][0], counts[set] * sizeof(DescriptorBinding));
 		}
 	}

+ 5 - 3
AnKi/Gr/Vulkan/ShaderProgramImpl.cpp

@@ -259,7 +259,8 @@ Error ShaderProgramImpl::init(const ShaderProgramInitInfo& inf)
 	if(!!(m_stages & ShaderTypeBit::kAllRayTracing))
 	{
 		// Create shaders
-		GrDynamicArray<VkPipelineShaderStageCreateInfo> stages(m_shaders.getSize());
+		GrDynamicArray<VkPipelineShaderStageCreateInfo> stages;
+		stages.resize(m_shaders.getSize());
 		for(U32 i = 0; i < stages.getSize(); ++i)
 		{
 			const ShaderImpl& impl = static_cast<const ShaderImpl&>(*m_shaders[i]);
@@ -284,7 +285,8 @@ Error ShaderProgramImpl::init(const ShaderProgramInitInfo& inf)
 		U32 groupCount = inf.m_rayTracingShaders.m_rayGenShaders.getSize()
 						 + inf.m_rayTracingShaders.m_missShaders.getSize()
 						 + inf.m_rayTracingShaders.m_hitGroups.getSize();
-		GrDynamicArray<VkRayTracingShaderGroupCreateInfoKHR> groups(groupCount, defaultGroup);
+		GrDynamicArray<VkRayTracingShaderGroupCreateInfoKHR> groups;
+		groups.resize(groupCount, defaultGroup);
 
 		// 1st group is the ray gen
 		groupCount = 0;
@@ -342,7 +344,7 @@ Error ShaderProgramImpl::init(const ShaderProgramInitInfo& inf)
 		// Get RT handles
 		const U32 handleArraySize =
 			getGrManagerImpl().getPhysicalDeviceRayTracingProperties().shaderGroupHandleSize * groupCount;
-		m_rt.m_allHandles.create(handleArraySize, 0);
+		m_rt.m_allHandles.resize(handleArraySize, 0_U8);
 		ANKI_VK_CHECK(vkGetRayTracingShaderGroupHandlesKHR(getVkDevice(), m_rt.m_ppline, 0, groupCount, handleArraySize,
 														   &m_rt.m_allHandles[0]));
 	}

+ 3 - 3
AnKi/Gr/Vulkan/SwapchainFactory.cpp

@@ -49,7 +49,7 @@ Error MicroSwapchain::initInternal()
 						 "swapchain targeting the surface");
 			return Error::kFunctionFailed;
 		}
-		m_factory->m_gr->getNativeWindowSize(surfaceWidth, surfaceHeight);
+		getGrManagerImpl().getNativeWindowSize(surfaceWidth, surfaceHeight);
 #else
 		if(surfaceProperties.currentExtent.width == kMaxU32 || surfaceProperties.currentExtent.height == kMaxU32)
 		{
@@ -70,7 +70,7 @@ Error MicroSwapchain::initInternal()
 			vkGetPhysicalDeviceSurfaceFormatsKHR(pdev, getGrManagerImpl().getSurface(), &formatCount, nullptr));
 
 		GrDynamicArray<VkSurfaceFormatKHR> formats;
-		formats.create(formatCount);
+		formats.resize(formatCount);
 		ANKI_VK_CHECK(
 			vkGetPhysicalDeviceSurfaceFormatsKHR(pdev, getGrManagerImpl().getSurface(), &formatCount, &formats[0]));
 
@@ -220,7 +220,7 @@ Error MicroSwapchain::initInternal()
 			ANKI_VK_LOGI("Requested a swapchain with %u images but got one with %u", kMaxFramesInFlight, count);
 		}
 
-		m_textures.create(count);
+		m_textures.resize(count);
 
 		ANKI_VK_LOGI("Created a swapchain. Image count: %u, present mode: %u, size: %ux%u, vsync: %u", count,
 					 presentMode, surfaceWidth, surfaceHeight, U32(m_factory->m_vsync));

+ 17 - 0
AnKi/Importer/Common.h

@@ -4,6 +4,8 @@
 // http://www.anki3d.org/LICENSE
 
 #include <AnKi/Util/Logger.h>
+#include <AnKi/Util/MemoryPool.h>
+#include <AnKi/Util/HashMap.h>
 
 namespace anki {
 
@@ -16,6 +18,21 @@ namespace anki {
 #define ANKI_IMPORTER_LOGW(...) ANKI_LOG("IMPR", kWarning, __VA_ARGS__)
 #define ANKI_IMPORTER_LOGF(...) ANKI_LOG("IMPR", kFatal, __VA_ARGS__)
 
+using ImporterString = BaseString<MemoryPoolPtrWrapper<BaseMemoryPool>>;
+using ImporterStringList = BaseStringList<MemoryPoolPtrWrapper<BaseMemoryPool>>;
+
+template<typename TKey, typename TValue>
+using ImporterHashMap = HashMap<TKey, TValue, DefaultHasher<TKey>, MemoryPoolPtrWrapper<BaseMemoryPool>>;
+
+template<typename T>
+using ImporterDynamicArray = DynamicArray<T, MemoryPoolPtrWrapper<BaseMemoryPool>, U32>;
+
+template<typename T>
+using ImporterDynamicArrayLarge = DynamicArray<T, MemoryPoolPtrWrapper<BaseMemoryPool>, PtrSize>;
+
+template<typename T>
+using ImporterList = List<T, MemoryPoolPtrWrapper<BaseMemoryPool>>;
+
 /// @}
 
 } // end namespace anki

+ 75 - 74
AnKi/Importer/GltfImporter.cpp

@@ -136,7 +136,8 @@ static Error getNodeTransform(const cgltf_node& node, Transform& trf)
 	return Error::kNone;
 }
 
-static Bool stringsExist(const HashMapRaii<CString, StringRaii>& map, const std::initializer_list<CString>& list)
+static Bool stringsExist(const ImporterHashMap<CString, ImporterString>& map,
+						 const std::initializer_list<CString>& list)
 {
 	for(CString item : list)
 	{
@@ -167,13 +168,13 @@ GltfImporter::~GltfImporter()
 
 Error GltfImporter::init(const GltfImporterInitInfo& initInfo)
 {
-	m_inputFname.create(initInfo.m_inputFilename);
-	m_outDir.create(initInfo.m_outDirectory);
-	m_rpath.create(initInfo.m_rpath);
-	m_texrpath.create(initInfo.m_texrpath);
+	m_inputFname = initInfo.m_inputFilename;
+	m_outDir = initInfo.m_outDirectory;
+	m_rpath = initInfo.m_rpath;
+	m_texrpath = initInfo.m_texrpath;
 	m_optimizeMeshes = initInfo.m_optimizeMeshes;
 	m_optimizeAnimations = initInfo.m_optimizeAnimations;
-	m_comment.create(initInfo.m_comment);
+	m_comment = initInfo.m_comment;
 
 	m_lightIntensityScale = max(initInfo.m_lightIntensityScale, kEpsilonf);
 
@@ -211,7 +212,7 @@ Error GltfImporter::init(const GltfImporterInitInfo& initInfo)
 	if(initInfo.m_threadCount > 0)
 	{
 		const U32 threadCount = min(getCpuCoresCount(), initInfo.m_threadCount);
-		m_hive = newInstance<ThreadHive>(*m_pool, threadCount, m_pool, true);
+		m_hive = newInstance<ThreadHive>(*m_pool, threadCount, true);
 	}
 
 	m_importTextures = initInfo.m_importTextures;
@@ -223,7 +224,7 @@ Error GltfImporter::writeAll()
 {
 	populateNodePtrToIdx();
 
-	StringRaii sceneFname(m_pool);
+	ImporterString sceneFname(m_pool);
 	sceneFname.sprintf("%sScene.lua", m_outDir.cstr());
 	ANKI_CHECK(m_sceneFile.open(sceneFname.toCString(), FileOpenFlag::kWrite));
 	ANKI_CHECK(m_sceneFile.writeTextf("-- Generated by: %s\n", m_comment.cstr()));
@@ -234,7 +235,7 @@ Error GltfImporter::writeAll()
 	{
 		for(cgltf_node* const* node = scene->nodes; node < scene->nodes + scene->nodes_count; ++node)
 		{
-			ANKI_CHECK(visitNode(*(*node), Transform::getIdentity(), HashMapRaii<CString, StringRaii>(m_pool)));
+			ANKI_CHECK(visitNode(*(*node), Transform::getIdentity(), ImporterHashMap<CString, ImporterString>(m_pool)));
 		}
 	}
 
@@ -374,7 +375,7 @@ Error GltfImporter::writeAll()
 	return Error::kNone;
 }
 
-Error GltfImporter::getExtras(const cgltf_extras& extras, HashMapRaii<CString, StringRaii>& out) const
+Error GltfImporter::getExtras(const cgltf_extras& extras, ImporterHashMap<CString, ImporterString>& out) const
 {
 	cgltf_size extrasSize;
 	cgltf_copy_extras_json(m_gltf, &extras, nullptr, &extrasSize);
@@ -383,8 +384,8 @@ Error GltfImporter::getExtras(const cgltf_extras& extras, HashMapRaii<CString, S
 		return Error::kNone;
 	}
 
-	DynamicArrayRaii<char, PtrSize> json(m_pool);
-	json.create(extrasSize + 1);
+	ImporterDynamicArrayLarge<char> json(m_pool);
+	json.resize(extrasSize + 1);
 	cgltf_result res = cgltf_copy_extras_json(m_gltf, &extras, &json[0], &extrasSize);
 	if(res != cgltf_result_success)
 	{
@@ -404,14 +405,14 @@ Error GltfImporter::getExtras(const cgltf_extras& extras, HashMapRaii<CString, S
 		return Error::kNone;
 	}
 
-	DynamicArrayRaii<jsmntok_t> tokens(m_pool);
-	tokens.create(U32(tokenCount));
+	ImporterDynamicArray<jsmntok_t> tokens(m_pool);
+	tokens.resize(U32(tokenCount));
 
 	// Get tokens
 	jsmn_init(&parser);
 	jsmn_parse(&parser, jsonTxt.cstr(), jsonTxt.getLength(), &tokens[0], tokens.getSize());
 
-	StringListRaii tokenStrings(m_pool);
+	ImporterStringList tokenStrings(m_pool);
 	for(const jsmntok_t& token : tokens)
 	{
 		if(token.type != JSMN_STRING && token.type != JSMN_PRIMITIVE)
@@ -419,8 +420,7 @@ Error GltfImporter::getExtras(const cgltf_extras& extras, HashMapRaii<CString, S
 			continue;
 		}
 
-		StringRaii tokenStr(m_pool);
-		tokenStr.create(&jsonTxt[token.start], &jsonTxt[token.end]);
+		ImporterString tokenStr(&jsonTxt[token.start], &jsonTxt[token.end], m_pool);
 		tokenStrings.pushBack(tokenStr.toCString());
 	}
 
@@ -437,7 +437,7 @@ Error GltfImporter::getExtras(const cgltf_extras& extras, HashMapRaii<CString, S
 		auto it2 = it;
 		++it2;
 
-		out.emplace(it->toCString(), StringRaii(it2->toCString(), m_pool));
+		out.emplace(it->toCString(), ImporterString(it2->toCString(), m_pool));
 		++it;
 		++it;
 	}
@@ -468,13 +468,13 @@ void GltfImporter::populateNodePtrToIdx()
 	}
 }
 
-StringRaii GltfImporter::getNodeName(const cgltf_node& node) const
+ImporterString GltfImporter::getNodeName(const cgltf_node& node) const
 {
-	StringRaii out(m_pool);
+	ImporterString out(m_pool);
 
 	if(node.name)
 	{
-		out.create(node.name);
+		out = node.name;
 	}
 	else
 	{
@@ -486,12 +486,12 @@ StringRaii GltfImporter::getNodeName(const cgltf_node& node) const
 	return out;
 }
 
-Error GltfImporter::parseArrayOfNumbers(CString str, DynamicArrayRaii<F64>& out, const U32* expectedArraySize)
+Error GltfImporter::parseArrayOfNumbers(CString str, ImporterDynamicArray<F64>& out, const U32* expectedArraySize)
 {
-	StringListRaii list(m_pool);
+	ImporterStringList list(m_pool);
 	list.splitString(str, ' ');
 
-	out.create(U32(list.getSize()));
+	out.resize(U32(list.getSize()));
 
 	Error err = Error::kNone;
 	auto it = list.getBegin();
@@ -518,7 +518,7 @@ Error GltfImporter::parseArrayOfNumbers(CString str, DynamicArrayRaii<F64>& out,
 }
 
 Error GltfImporter::visitNode(const cgltf_node& node, const Transform& parentTrf,
-							  const HashMapRaii<CString, StringRaii>& parentExtras)
+							  const ImporterHashMap<CString, ImporterString>& parentExtras)
 {
 	// Check error from a thread
 	const Error threadErr = m_errorInThread.load();
@@ -528,7 +528,7 @@ Error GltfImporter::visitNode(const cgltf_node& node, const Transform& parentTrf
 		return threadErr;
 	}
 
-	HashMapRaii<CString, StringRaii> outExtras(m_pool);
+	ImporterHashMap<CString, ImporterString> outExtras(m_pool);
 	if(node.light)
 	{
 		ANKI_CHECK(writeLight(node, parentExtras));
@@ -550,15 +550,15 @@ Error GltfImporter::visitNode(const cgltf_node& node, const Transform& parentTrf
 	else if(node.mesh)
 	{
 		// Handle special nodes
-		HashMapRaii<CString, StringRaii> extras(parentExtras);
+		ImporterHashMap<CString, ImporterString> extras(parentExtras);
 		ANKI_CHECK(getExtras(node.mesh->extras, extras));
 		ANKI_CHECK(getExtras(node.extras, extras));
 
-		HashMapRaii<CString, StringRaii>::Iterator it;
+		ImporterHashMap<CString, ImporterString>::Iterator it;
 
 		if((it = extras.find("particles")) != extras.getEnd())
 		{
-			const StringRaii& fname = *it;
+			const ImporterString& fname = *it;
 
 			Bool gpuParticles = false;
 			if((it = extras.find("gpu_particles")) != extras.getEnd() && *it == "true")
@@ -588,7 +588,7 @@ Error GltfImporter::visitNode(const cgltf_node& node, const Transform& parentTrf
 
 			if((it = extras.find("skybox_solid_color")) != extras.getEnd())
 			{
-				StringListRaii tokens(m_pool);
+				ImporterStringList tokens(m_pool);
 				tokens.splitString(*it, ' ');
 				if(tokens.getSize() != 3)
 				{
@@ -656,7 +656,7 @@ Error GltfImporter::visitNode(const cgltf_node& node, const Transform& parentTrf
 			ANKI_CHECK(m_sceneFile.writeTextf("\nnode = scene:newSceneNode(\"%s\")\n", getNodeName(node).cstr()));
 
 			ANKI_CHECK(m_sceneFile.writeText("comp = scene:newBodyComponent()\n"));
-			const StringRaii meshFname = computeMeshResourceFilename(*node.mesh);
+			const ImporterString meshFname = computeMeshResourceFilename(*node.mesh);
 			ANKI_CHECK(m_sceneFile.writeTextf("comp:loadMeshResource(\"%s%s\")\n", m_rpath.cstr(), meshFname.cstr()));
 
 			Transform localTrf;
@@ -722,16 +722,16 @@ Error GltfImporter::visitNode(const cgltf_node& node, const Transform& parentTrf
 		}
 		else if((it = extras.find("decal")) != extras.getEnd() && (*it == "true" || *it == "1"))
 		{
-			StringRaii diffuseAtlas(m_pool);
+			ImporterString diffuseAtlas(m_pool);
 			if((it = extras.find("decal_diffuse_atlas")) != extras.getEnd())
 			{
-				diffuseAtlas.create(it->toCString());
+				diffuseAtlas = *it;
 			}
 
-			StringRaii diffuseSubtexture(m_pool);
+			ImporterString diffuseSubtexture(m_pool);
 			if((it = extras.find("decal_diffuse_sub_texture")) != extras.getEnd())
 			{
-				diffuseSubtexture.create(it->toCString());
+				diffuseSubtexture = *it;
 			}
 
 			F32 diffuseFactor = -1.0f;
@@ -740,16 +740,16 @@ Error GltfImporter::visitNode(const cgltf_node& node, const Transform& parentTrf
 				ANKI_CHECK(it->toNumber(diffuseFactor));
 			}
 
-			StringRaii specularRougnessMetallicAtlas(m_pool);
+			ImporterString specularRougnessMetallicAtlas(m_pool);
 			if((it = extras.find("decal_specular_roughness_metallic_atlas")) != extras.getEnd())
 			{
-				specularRougnessMetallicAtlas.create(it->toCString());
+				specularRougnessMetallicAtlas = *it;
 			}
 
-			StringRaii specularRougnessMetallicSubtexture(m_pool);
+			ImporterString specularRougnessMetallicSubtexture(m_pool);
 			if((it = extras.find("decal_specular_roughness_metallic_sub_texture")) != extras.getEnd())
 			{
-				specularRougnessMetallicSubtexture.create(it->toCString());
+				specularRougnessMetallicSubtexture = *it;
 			}
 
 			F32 specularRougnessMetallicFactor = -1.0f;
@@ -800,7 +800,7 @@ Error GltfImporter::visitNode(const cgltf_node& node, const Transform& parentTrf
 
 			addRequest<const cgltf_mesh*>(node.mesh, m_modelImportRequests);
 
-			HashMapRaii<CString, StringRaii>::Iterator it2;
+			ImporterHashMap<CString, ImporterString>::Iterator it2;
 			const Bool selfCollision = (it2 = extras.find("collision_mesh")) != extras.getEnd() && *it2 == "self";
 
 			ANKI_CHECK(writeModelNode(node, parentExtras));
@@ -813,7 +813,7 @@ Error GltfImporter::visitNode(const cgltf_node& node, const Transform& parentTrf
 			{
 				ANKI_CHECK(m_sceneFile.writeText("comp = node:newBodyComponent()\n"));
 
-				const StringRaii meshFname = computeMeshResourceFilename(*node.mesh);
+				const ImporterString meshFname = computeMeshResourceFilename(*node.mesh);
 
 				ANKI_CHECK(m_sceneFile.writeText("comp:setMeshFromModelComponent()\n"));
 				ANKI_CHECK(m_sceneFile.writeText("comp:teleportTo(trf)\n"));
@@ -866,14 +866,14 @@ Error GltfImporter::writeTransform(const Transform& trf)
 
 Error GltfImporter::writeModel(const cgltf_mesh& mesh) const
 {
-	const StringRaii modelFname = computeModelResourceFilename(mesh);
+	const ImporterString modelFname = computeModelResourceFilename(mesh);
 	ANKI_IMPORTER_LOGV("Importing model %s", modelFname.cstr());
 
-	HashMapRaii<CString, StringRaii> extras(m_pool);
+	ImporterHashMap<CString, ImporterString> extras(m_pool);
 	ANKI_CHECK(getExtras(mesh.extras, extras));
 
 	File file;
-	StringRaii modelFullFname(m_pool);
+	ImporterString modelFullFname(m_pool);
 	modelFullFname.sprintf("%s/%s", m_outDir.cstr(), modelFname.cstr());
 	ANKI_CHECK(file.open(modelFullFname, FileOpenFlag::kWrite));
 
@@ -884,7 +884,7 @@ Error GltfImporter::writeModel(const cgltf_mesh& mesh) const
 	{
 		ANKI_CHECK(file.writeText("\t\t<modelPatch>\n"));
 
-		const StringRaii meshFname = computeMeshResourceFilename(mesh);
+		const ImporterString meshFname = computeMeshResourceFilename(mesh);
 		if(mesh.primitives_count == 1)
 		{
 			ANKI_CHECK(file.writeTextf("\t\t\t<mesh>%s%s</mesh>\n", m_rpath.cstr(), meshFname.cstr()));
@@ -895,7 +895,7 @@ Error GltfImporter::writeModel(const cgltf_mesh& mesh) const
 									   meshFname.cstr()));
 		}
 
-		HashMapRaii<CString, StringRaii> materialExtras(m_pool);
+		ImporterHashMap<CString, ImporterString> materialExtras(m_pool);
 		ANKI_CHECK(getExtras(mesh.primitives[primIdx].material->extras, materialExtras));
 		auto mtlOverride = materialExtras.find("material_override");
 		if(mtlOverride != materialExtras.getEnd())
@@ -904,7 +904,7 @@ Error GltfImporter::writeModel(const cgltf_mesh& mesh) const
 		}
 		else
 		{
-			const StringRaii mtlFname = computeMaterialResourceFilename(*mesh.primitives[primIdx].material);
+			const ImporterString mtlFname = computeMaterialResourceFilename(*mesh.primitives[primIdx].material);
 			ANKI_CHECK(file.writeTextf("\t\t\t<material>%s%s</material>\n", m_rpath.cstr(), mtlFname.cstr()));
 		}
 
@@ -920,12 +920,12 @@ Error GltfImporter::writeModel(const cgltf_mesh& mesh) const
 
 Error GltfImporter::writeSkeleton(const cgltf_skin& skin) const
 {
-	StringRaii fname(m_pool);
+	ImporterString fname(m_pool);
 	fname.sprintf("%s%s", m_outDir.cstr(), computeSkeletonResourceFilename(skin).cstr());
 	ANKI_IMPORTER_LOGV("Importing skeleton %s", fname.cstr());
 
 	// Get matrices
-	DynamicArrayRaii<Mat4> boneMats(m_pool);
+	ImporterDynamicArray<Mat4> boneMats(m_pool);
 	readAccessor(*skin.inverse_bind_matrices, boneMats);
 	if(boneMats.getSize() != skin.joints_count)
 	{
@@ -937,14 +937,15 @@ Error GltfImporter::writeSkeleton(const cgltf_skin& skin) const
 	File file;
 	ANKI_CHECK(file.open(fname.toCString(), FileOpenFlag::kWrite));
 
-	ANKI_CHECK(file.writeTextf("%s\n<skeleton>\n", XmlDocument::kXmlHeader.cstr()));
+	ANKI_CHECK(
+		file.writeTextf("%s\n<skeleton>\n", XmlDocument<MemoryPoolPtrWrapper<BaseMemoryPool>>::kXmlHeader.cstr()));
 	ANKI_CHECK(file.writeTextf("\t<bones>\n"));
 
 	for(U32 i = 0; i < skin.joints_count; ++i)
 	{
 		const cgltf_node& boneNode = *skin.joints[i];
 
-		StringRaii parent(m_pool);
+		ImporterString parent(m_pool);
 
 		// Name & parent
 		ANKI_CHECK(file.writeTextf("\t\t<bone name=\"%s\" ", getNodeName(boneNode).cstr()));
@@ -984,13 +985,13 @@ Error GltfImporter::writeSkeleton(const cgltf_skin& skin) const
 	return Error::kNone;
 }
 
-Error GltfImporter::writeLight(const cgltf_node& node, const HashMapRaii<CString, StringRaii>& parentExtras)
+Error GltfImporter::writeLight(const cgltf_node& node, const ImporterHashMap<CString, ImporterString>& parentExtras)
 {
 	const cgltf_light& light = *node.light;
-	StringRaii nodeName = getNodeName(node);
+	ImporterString nodeName = getNodeName(node);
 	ANKI_IMPORTER_LOGV("Importing light %s", nodeName.cstr());
 
-	HashMapRaii<CString, StringRaii> extras(parentExtras);
+	ImporterHashMap<CString, ImporterString> extras(parentExtras);
 	ANKI_CHECK(getExtras(light.extras, extras));
 	ANKI_CHECK(getExtras(node.extras, extras));
 
@@ -1079,7 +1080,7 @@ Error GltfImporter::writeLight(const cgltf_node& node, const HashMapRaii<CString
 
 		if(lsSpriteSize != extras.getEnd())
 		{
-			DynamicArrayRaii<F64> numbers(m_pool);
+			ImporterDynamicArray<F64> numbers(m_pool);
 			const U32 count = 2;
 			ANKI_CHECK(parseArrayOfNumbers(lsSpriteSize->toCString(), numbers, &count));
 
@@ -1088,7 +1089,7 @@ Error GltfImporter::writeLight(const cgltf_node& node, const HashMapRaii<CString
 
 		if(lsColor != extras.getEnd())
 		{
-			DynamicArrayRaii<F64> numbers(m_pool);
+			ImporterDynamicArray<F64> numbers(m_pool);
 			const U32 count = 4;
 			ANKI_CHECK(parseArrayOfNumbers(lsColor->toCString(), numbers, &count));
 
@@ -1105,7 +1106,7 @@ Error GltfImporter::writeLight(const cgltf_node& node, const HashMapRaii<CString
 
 		if(lightEventIntensity != extras.getEnd())
 		{
-			DynamicArrayRaii<F64> numbers(m_pool);
+			ImporterDynamicArray<F64> numbers(m_pool);
 			const U32 count = 4;
 			ANKI_CHECK(parseArrayOfNumbers(lightEventIntensity->toCString(), numbers, &count));
 			ANKI_CHECK(m_sceneFile.writeTextf("event:setIntensityMultiplier(Vec4.new(%f, %f, %f, %f))\n", numbers[0],
@@ -1114,7 +1115,7 @@ Error GltfImporter::writeLight(const cgltf_node& node, const HashMapRaii<CString
 
 		if(lightEventFrequency != extras.getEnd())
 		{
-			DynamicArrayRaii<F64> numbers(m_pool);
+			ImporterDynamicArray<F64> numbers(m_pool);
 			const U32 count = 2;
 			ANKI_CHECK(parseArrayOfNumbers(lightEventFrequency->toCString(), numbers, &count));
 			ANKI_CHECK(m_sceneFile.writeTextf("event:setFrequency(%f, %f)\n", numbers[0], numbers[1]));
@@ -1125,7 +1126,7 @@ Error GltfImporter::writeLight(const cgltf_node& node, const HashMapRaii<CString
 }
 
 Error GltfImporter::writeCamera(const cgltf_node& node,
-								[[maybe_unused]] const HashMapRaii<CString, StringRaii>& parentExtras)
+								[[maybe_unused]] const ImporterHashMap<CString, ImporterString>& parentExtras)
 {
 	if(node.camera->type != cgltf_camera_type_perspective)
 	{
@@ -1146,14 +1147,14 @@ Error GltfImporter::writeCamera(const cgltf_node& node,
 	return Error::kNone;
 }
 
-Error GltfImporter::writeModelNode(const cgltf_node& node, const HashMapRaii<CString, StringRaii>& parentExtras)
+Error GltfImporter::writeModelNode(const cgltf_node& node, const ImporterHashMap<CString, ImporterString>& parentExtras)
 {
 	ANKI_IMPORTER_LOGV("Importing model node %s", getNodeName(node).cstr());
 
-	HashMapRaii<CString, StringRaii> extras(parentExtras);
+	ImporterHashMap<CString, ImporterString> extras(parentExtras);
 	ANKI_CHECK(getExtras(node.extras, extras));
 
-	const StringRaii modelFname = computeModelResourceFilename(*node.mesh);
+	const ImporterString modelFname = computeModelResourceFilename(*node.mesh);
 
 	ANKI_CHECK(m_sceneFile.writeTextf("\nnode = scene:newSceneNode(\"%s\")\n", getNodeName(node).cstr()));
 	ANKI_CHECK(m_sceneFile.writeTextf("node:newModelComponent():loadModelResource(\"%s%s\")\n", m_rpath.cstr(),
@@ -1168,9 +1169,9 @@ Error GltfImporter::writeModelNode(const cgltf_node& node, const HashMapRaii<CSt
 	return Error::kNone;
 }
 
-StringRaii GltfImporter::computeModelResourceFilename(const cgltf_mesh& mesh) const
+ImporterString GltfImporter::computeModelResourceFilename(const cgltf_mesh& mesh) const
 {
-	StringListRaii list(m_pool);
+	ImporterStringList list(m_pool);
 
 	list.pushBack(mesh.name);
 
@@ -1180,52 +1181,52 @@ StringRaii GltfImporter::computeModelResourceFilename(const cgltf_mesh& mesh) co
 		list.pushBackSprintf("_%s", mtlName);
 	}
 
-	StringRaii joined(m_pool);
+	ImporterString joined(m_pool);
 	list.join("", joined);
 
 	const U64 hash = computeHash(joined.getBegin(), joined.getLength());
 
-	StringRaii out(m_pool);
+	ImporterString out(m_pool);
 	out.sprintf("%.64s_%" PRIx64 ".ankimdl", joined.cstr(), hash); // Limit the filename size
 
 	return out;
 }
 
-StringRaii GltfImporter::computeMeshResourceFilename(const cgltf_mesh& mesh) const
+ImporterString GltfImporter::computeMeshResourceFilename(const cgltf_mesh& mesh) const
 {
 	const U64 hash = computeHash(mesh.name, strlen(mesh.name));
-	StringRaii out(m_pool);
+	ImporterString out(m_pool);
 	out.sprintf("%.64s_%" PRIx64 ".ankimesh", mesh.name, hash); // Limit the filename size
 	return out;
 }
 
-StringRaii GltfImporter::computeMaterialResourceFilename(const cgltf_material& mtl) const
+ImporterString GltfImporter::computeMaterialResourceFilename(const cgltf_material& mtl) const
 {
 	const U64 hash = computeHash(mtl.name, strlen(mtl.name));
 
-	StringRaii out(m_pool);
+	ImporterString out(m_pool);
 
 	out.sprintf("%.64s_%" PRIx64 ".ankimtl", mtl.name, hash); // Limit the filename size
 
 	return out;
 }
 
-StringRaii GltfImporter::computeAnimationResourceFilename(const cgltf_animation& anim) const
+ImporterString GltfImporter::computeAnimationResourceFilename(const cgltf_animation& anim) const
 {
 	const U64 hash = computeHash(anim.name, strlen(anim.name));
 
-	StringRaii out(m_pool);
+	ImporterString out(m_pool);
 
 	out.sprintf("%.64s_%" PRIx64 ".ankianim", anim.name, hash); // Limit the filename size
 
 	return out;
 }
 
-StringRaii GltfImporter::computeSkeletonResourceFilename(const cgltf_skin& skin) const
+ImporterString GltfImporter::computeSkeletonResourceFilename(const cgltf_skin& skin) const
 {
 	const U64 hash = computeHash(skin.name, strlen(skin.name));
 
-	StringRaii out(m_pool);
+	ImporterString out(m_pool);
 
 	out.sprintf("%.64s_%" PRIx64 ".ankiskel", skin.name, hash); // Limit the filename size
 

+ 26 - 35
AnKi/Importer/GltfImporter.h

@@ -50,22 +50,13 @@ public:
 	Error writeAll();
 
 private:
-	class PtrHasher
-	{
-	public:
-		U64 operator()(const void* ptr)
-		{
-			return computeHash(&ptr, sizeof(ptr));
-		}
-	};
-
 	// Data
 	mutable BaseMemoryPool* m_pool = nullptr;
 
-	StringRaii m_inputFname = {m_pool};
-	StringRaii m_outDir = {m_pool};
-	StringRaii m_rpath = {m_pool};
-	StringRaii m_texrpath = {m_pool};
+	ImporterString m_inputFname = {m_pool};
+	ImporterString m_outDir = {m_pool};
+	ImporterString m_rpath = {m_pool};
+	ImporterString m_texrpath = {m_pool};
 
 	cgltf_data* m_gltf = nullptr;
 
@@ -77,14 +68,14 @@ private:
 
 	mutable Atomic<I32> m_errorInThread = {0};
 
-	HashMapRaii<const void*, U32, PtrHasher> m_nodePtrToIdx = {m_pool}; ///< Need an index for the unnamed nodes.
+	ImporterHashMap<const void*, U32> m_nodePtrToIdx = {m_pool}; ///< Need an index for the unnamed nodes.
 
 	F32 m_lodFactor = 1.0f;
 	U32 m_lodCount = 1;
 	F32 m_lightIntensityScale = 1.0f;
 	Bool m_optimizeMeshes = false;
 	Bool m_optimizeAnimations = false;
-	StringRaii m_comment = {m_pool};
+	ImporterString m_comment = {m_pool};
 
 	/// Don't generate LODs for meshes with less vertices than this number.
 	U32 m_skipLodVertexCountThreshold = 256;
@@ -111,14 +102,14 @@ private:
 		}
 	};
 
-	DynamicArrayRaii<ImportRequest<const cgltf_mesh*>> m_meshImportRequests = {m_pool};
-	DynamicArrayRaii<ImportRequest<MaterialImportRequest>> m_materialImportRequests = {m_pool};
-	DynamicArrayRaii<ImportRequest<const cgltf_skin*>> m_skinImportRequests = {m_pool};
-	DynamicArrayRaii<ImportRequest<const cgltf_mesh*>> m_modelImportRequests = {m_pool};
+	ImporterDynamicArray<ImportRequest<const cgltf_mesh*>> m_meshImportRequests = {m_pool};
+	ImporterDynamicArray<ImportRequest<MaterialImportRequest>> m_materialImportRequests = {m_pool};
+	ImporterDynamicArray<ImportRequest<const cgltf_skin*>> m_skinImportRequests = {m_pool};
+	ImporterDynamicArray<ImportRequest<const cgltf_mesh*>> m_modelImportRequests = {m_pool};
 
 	// Misc
 	template<typename T>
-	void addRequest(const T& value, DynamicArrayRaii<ImportRequest<T>>& array) const
+	void addRequest(const T& value, ImporterDynamicArray<ImportRequest<T>>& array) const
 	{
 		Bool found = false;
 		for(const auto& req : array)
@@ -138,26 +129,26 @@ private:
 		}
 	}
 
-	Error getExtras(const cgltf_extras& extras, HashMapRaii<CString, StringRaii>& out) const;
-	Error parseArrayOfNumbers(CString str, DynamicArrayRaii<F64>& out, const U32* expectedArraySize = nullptr);
+	Error getExtras(const cgltf_extras& extras, ImporterHashMap<CString, ImporterString>& out) const;
+	Error parseArrayOfNumbers(CString str, ImporterDynamicArray<F64>& out, const U32* expectedArraySize = nullptr);
 	void populateNodePtrToIdx();
 	void populateNodePtrToIdxInternal(const cgltf_node& node, U32& idx);
-	StringRaii getNodeName(const cgltf_node& node) const;
+	ImporterString getNodeName(const cgltf_node& node) const;
 
 	template<typename T, typename TFunc>
 	static void visitAccessor(const cgltf_accessor& accessor, TFunc func);
 
 	template<typename T>
-	static void readAccessor(const cgltf_accessor& accessor, DynamicArrayRaii<T>& out)
+	static void readAccessor(const cgltf_accessor& accessor, ImporterDynamicArray<T>& out)
 	{
 		visitAccessor<T>(accessor, [&](const T& val) {
 			out.emplaceBack(val);
 		});
 	}
 
-	StringRaii fixFilename(CString in) const
+	ImporterString fixFilename(CString in) const
 	{
-		StringRaii out(in, m_pool);
+		ImporterString out(in, m_pool);
 		out.replaceAll("|", "_");
 		out.replaceAll(" ", "_");
 		return out;
@@ -177,11 +168,11 @@ private:
 	static U32 getMeshTotalVertexCount(const cgltf_mesh& mesh);
 
 	// Compute filenames for various resources. Use a hash to solve the casing issue and remove unwanted special chars
-	StringRaii computeModelResourceFilename(const cgltf_mesh& mesh) const;
-	StringRaii computeMeshResourceFilename(const cgltf_mesh& mesh) const;
-	StringRaii computeMaterialResourceFilename(const cgltf_material& mtl) const;
-	StringRaii computeAnimationResourceFilename(const cgltf_animation& anim) const;
-	StringRaii computeSkeletonResourceFilename(const cgltf_skin& skin) const;
+	ImporterString computeModelResourceFilename(const cgltf_mesh& mesh) const;
+	ImporterString computeMeshResourceFilename(const cgltf_mesh& mesh) const;
+	ImporterString computeMaterialResourceFilename(const cgltf_material& mtl) const;
+	ImporterString computeAnimationResourceFilename(const cgltf_animation& anim) const;
+	ImporterString computeSkeletonResourceFilename(const cgltf_skin& skin) const;
 
 	// Resources
 	Error writeMesh(const cgltf_mesh& mesh) const;
@@ -193,10 +184,10 @@ private:
 	// Scene
 	Error writeTransform(const Transform& trf);
 	Error visitNode(const cgltf_node& node, const Transform& parentTrf,
-					const HashMapRaii<CString, StringRaii>& parentExtras);
-	Error writeLight(const cgltf_node& node, const HashMapRaii<CString, StringRaii>& parentExtras);
-	Error writeCamera(const cgltf_node& node, const HashMapRaii<CString, StringRaii>& parentExtras);
-	Error writeModelNode(const cgltf_node& node, const HashMapRaii<CString, StringRaii>& parentExtras);
+					const ImporterHashMap<CString, ImporterString>& parentExtras);
+	Error writeLight(const cgltf_node& node, const ImporterHashMap<CString, ImporterString>& parentExtras);
+	Error writeCamera(const cgltf_node& node, const ImporterHashMap<CString, ImporterString>& parentExtras);
+	Error writeModelNode(const cgltf_node& node, const ImporterHashMap<CString, ImporterString>& parentExtras);
 };
 /// @}
 

+ 21 - 19
AnKi/Importer/GltfImporterAnimation.cpp

@@ -19,10 +19,10 @@ public:
 class GltfAnimChannel
 {
 public:
-	StringRaii m_name;
-	DynamicArrayRaii<GltfAnimKey<Vec3>> m_positions;
-	DynamicArrayRaii<GltfAnimKey<Quat>> m_rotations;
-	DynamicArrayRaii<GltfAnimKey<F32>> m_scales;
+	ImporterString m_name;
+	ImporterDynamicArray<GltfAnimKey<Vec3>> m_positions;
+	ImporterDynamicArray<GltfAnimKey<Quat>> m_rotations;
+	ImporterDynamicArray<GltfAnimKey<F32>> m_scales;
 	const cgltf_node* m_targetNode;
 
 	GltfAnimChannel(BaseMemoryPool* pool)
@@ -36,7 +36,7 @@ public:
 
 /// Optimize out same animation keys.
 template<typename T, typename TZeroFunc, typename TLerpFunc>
-static void optimizeChannel(DynamicArrayRaii<GltfAnimKey<T>>& arr, const T& identity, TZeroFunc isZeroFunc,
+static void optimizeChannel(ImporterDynamicArray<GltfAnimKey<T>>& arr, const T& identity, TZeroFunc isZeroFunc,
 							TLerpFunc lerpFunc)
 {
 	constexpr F32 kMinSkippedToTotalRatio = 0.1f;
@@ -49,7 +49,7 @@ static void optimizeChannel(DynamicArrayRaii<GltfAnimKey<T>>& arr, const T& iden
 			break;
 		}
 
-		DynamicArrayRaii<GltfAnimKey<T>> newArr(&arr.getMemoryPool());
+		ImporterDynamicArray<GltfAnimKey<T>> newArr(&arr.getMemoryPool());
 		U32 it = 0;
 		while(true)
 		{
@@ -117,19 +117,19 @@ static void optimizeChannel(DynamicArrayRaii<GltfAnimKey<T>>& arr, const T& iden
 
 Error GltfImporter::writeAnimation(const cgltf_animation& anim)
 {
-	StringRaii fname(m_pool);
-	StringRaii animFname = computeAnimationResourceFilename(anim);
+	ImporterString fname(m_pool);
+	ImporterString animFname = computeAnimationResourceFilename(anim);
 	fname.sprintf("%s%s", m_outDir.cstr(), animFname.cstr());
 	fname = fixFilename(fname);
 	ANKI_IMPORTER_LOGV("Importing animation %s", fname.cstr());
 
 	// Gather the channels
-	HashMapRaii<CString, Array<const cgltf_animation_channel*, 3>> channelMap(m_pool);
+	ImporterHashMap<CString, Array<const cgltf_animation_channel*, 3>> channelMap(m_pool);
 	U32 channelCount = 0;
 	for(U i = 0; i < anim.channels_count; ++i)
 	{
 		const cgltf_animation_channel& channel = anim.channels[i];
-		const StringRaii channelName = getNodeName(*channel.target_node);
+		const ImporterString channelName = getNodeName(*channel.target_node);
 
 		U idx;
 		switch(channel.target_path)
@@ -163,13 +163,14 @@ Error GltfImporter::writeAnimation(const cgltf_animation& anim)
 	}
 
 	// Gather the keys
-	DynamicArrayRaii<GltfAnimChannel> tempChannels(channelCount, m_pool, m_pool);
+	ImporterDynamicArray<GltfAnimChannel> tempChannels;
+	tempChannels.resize(channelCount, m_pool);
 	channelCount = 0;
 	for(auto it = channelMap.getBegin(); it != channelMap.getEnd(); ++it)
 	{
 		Array<const cgltf_animation_channel*, 3> arr = *it;
 		const cgltf_animation_channel& anyChannel = (arr[0]) ? *arr[0] : ((arr[1]) ? *arr[1] : *arr[2]);
-		const StringRaii channelName = getNodeName(*anyChannel.target_node);
+		const ImporterString channelName = getNodeName(*anyChannel.target_node);
 
 		tempChannels[channelCount].m_name = channelName;
 		tempChannels[channelCount].m_targetNode = anyChannel.target_node;
@@ -178,9 +179,9 @@ Error GltfImporter::writeAnimation(const cgltf_animation& anim)
 		if(arr[0])
 		{
 			const cgltf_animation_channel& channel = *arr[0];
-			DynamicArrayRaii<F32> keys(m_pool);
+			ImporterDynamicArray<F32> keys(m_pool);
 			readAccessor(*channel.sampler->input, keys);
-			DynamicArrayRaii<Vec3> positions(m_pool);
+			ImporterDynamicArray<Vec3> positions(m_pool);
 			readAccessor(*channel.sampler->output, positions);
 			if(keys.getSize() != positions.getSize())
 			{
@@ -202,9 +203,9 @@ Error GltfImporter::writeAnimation(const cgltf_animation& anim)
 		if(arr[1])
 		{
 			const cgltf_animation_channel& channel = *arr[1];
-			DynamicArrayRaii<F32> keys(m_pool);
+			ImporterDynamicArray<F32> keys(m_pool);
 			readAccessor(*channel.sampler->input, keys);
-			DynamicArrayRaii<Quat> rotations(m_pool);
+			ImporterDynamicArray<Quat> rotations(m_pool);
 			readAccessor(*channel.sampler->output, rotations);
 			if(keys.getSize() != rotations.getSize())
 			{
@@ -226,9 +227,9 @@ Error GltfImporter::writeAnimation(const cgltf_animation& anim)
 		if(arr[2])
 		{
 			const cgltf_animation_channel& channel = *arr[2];
-			DynamicArrayRaii<F32> keys(m_pool);
+			ImporterDynamicArray<F32> keys(m_pool);
 			readAccessor(*channel.sampler->input, keys);
-			DynamicArrayRaii<Vec3> scales(m_pool);
+			ImporterDynamicArray<Vec3> scales(m_pool);
 			readAccessor(*channel.sampler->output, scales);
 			if(keys.getSize() != scales.getSize())
 			{
@@ -306,7 +307,8 @@ Error GltfImporter::writeAnimation(const cgltf_animation& anim)
 	File file;
 	ANKI_CHECK(file.open(fname.toCString(), FileOpenFlag::kWrite));
 
-	ANKI_CHECK(file.writeTextf("%s\n<animation>\n", XmlDocument::kXmlHeader.cstr()));
+	ANKI_CHECK(
+		file.writeTextf("%s\n<animation>\n", XmlDocument<MemoryPoolPtrWrapper<BaseMemoryPool>>::kXmlHeader.cstr()));
 	ANKI_CHECK(file.writeText("\t<channels>\n"));
 
 	for(const GltfAnimChannel& channel : tempChannels)

+ 42 - 40
AnKi/Importer/GltfImporterMaterial.cpp

@@ -114,7 +114,7 @@ static Error importImage(BaseMemoryPool& pool, CString in, CString out, Bool alp
 	config.m_minMipmapDimension = 8;
 	config.m_noAlpha = !alpha;
 
-	StringRaii tmp(&pool);
+	String tmp;
 	if(getTempDirectory(tmp))
 	{
 		ANKI_IMPORTER_LOGE("getTempDirectory() failed");
@@ -141,7 +141,7 @@ static Error importImage(BaseMemoryPool& pool, CString in, CString out, Bool alp
 	return Error::kNone;
 }
 
-static void fixImageUri(StringRaii& uri)
+static void fixImageUri(ImporterString& uri)
 {
 	uri.replaceAll(".tga", ".ankitex");
 	uri.replaceAll(".png", ".ankitex");
@@ -151,7 +151,7 @@ static void fixImageUri(StringRaii& uri)
 
 Error GltfImporter::writeMaterial(const cgltf_material& mtl, Bool writeRayTracing) const
 {
-	StringRaii fname(m_pool);
+	ImporterString fname(m_pool);
 	fname.sprintf("%s%s", m_outDir.cstr(), computeMaterialResourceFilename(mtl).cstr());
 	ANKI_IMPORTER_LOGV("Importing material %s", fname.cstr());
 
@@ -161,13 +161,13 @@ Error GltfImporter::writeMaterial(const cgltf_material& mtl, Bool writeRayTracin
 		return Error::kUserData;
 	}
 
-	HashMapRaii<CString, StringRaii> extras(m_pool);
+	ImporterHashMap<CString, ImporterString> extras(m_pool);
 	ANKI_CHECK(getExtras(mtl.extras, extras));
 
-	StringRaii xml(m_pool);
-	xml.append(XmlDocument::kXmlHeader);
-	xml.append("\n");
-	xml.append(kMaterialTemplate);
+	ImporterString xml(m_pool);
+	xml += XmlDocument<MemoryPoolPtrWrapper<BaseMemoryPool>>::kXmlHeader;
+	xml += "\n";
+	xml += kMaterialTemplate;
 
 	if(writeRayTracing)
 	{
@@ -180,10 +180,11 @@ Error GltfImporter::writeMaterial(const cgltf_material& mtl, Bool writeRayTracin
 	{
 		const CString fname = getTextureUri(mtl.pbr_metallic_roughness.base_color_texture);
 
-		StringRaii uri(m_pool);
+		ImporterString uri(m_pool);
 		uri.sprintf("%s%s", m_texrpath.cstr(), fname.cstr());
 
-		xml.replaceAll("%diff%", StringRaii(m_pool).sprintf("<input name=\"m_diffTex\" value=\"%s\"/>", uri.cstr()));
+		xml.replaceAll("%diff%",
+					   ImporterString(m_pool).sprintf("<input name=\"m_diffTex\" value=\"%s\"/>", uri.cstr()));
 		xml.replaceAll("%diffTexMutator%", "1");
 
 		Vec4 constantColor;
@@ -195,8 +196,8 @@ Error GltfImporter::writeMaterial(const cgltf_material& mtl, Bool writeRayTracin
 
 		if(m_importTextures)
 		{
-			StringRaii out = m_outDir;
-			out.append(fname);
+			ImporterString out = m_outDir;
+			out += fname;
 			fixImageUri(out);
 			ANKI_CHECK(importImage(*m_pool, fname, out, !constantAlpha));
 		}
@@ -205,8 +206,8 @@ Error GltfImporter::writeMaterial(const cgltf_material& mtl, Bool writeRayTracin
 	{
 		const F32* diffCol = &mtl.pbr_metallic_roughness.base_color_factor[0];
 
-		xml.replaceAll("%diff%", StringRaii(m_pool).sprintf("<input name=\"m_diffColor\" value=\"%f %f %f\"/>",
-															diffCol[0], diffCol[1], diffCol[2]));
+		xml.replaceAll("%diff%", ImporterString(m_pool).sprintf("<input name=\"m_diffColor\" value=\"%f %f %f\"/>",
+																diffCol[0], diffCol[1], diffCol[2]));
 
 		xml.replaceAll("%diffTexMutator%", "0");
 		xml.replaceAll("%alphaTestMutator%", "0");
@@ -220,7 +221,7 @@ Error GltfImporter::writeMaterial(const cgltf_material& mtl, Bool writeRayTracin
 		auto it = extras.find("specular");
 		if(it != extras.getEnd())
 		{
-			StringListRaii tokens(m_pool);
+			ImporterStringList tokens(m_pool);
 			tokens.splitString(it->toCString(), ' ');
 			if(tokens.getSize() != 3)
 			{
@@ -240,8 +241,8 @@ Error GltfImporter::writeMaterial(const cgltf_material& mtl, Bool writeRayTracin
 			specular = Vec3(0.04f);
 		}
 
-		xml.replaceAll("%spec%", StringRaii(m_pool).sprintf("<input name=\"m_specColor\" value=\"%f %f %f\"/>",
-															specular.x(), specular.y(), specular.z()));
+		xml.replaceAll("%spec%", ImporterString(m_pool).sprintf("<input name=\"m_specColor\" value=\"%f %f %f\"/>",
+																specular.x(), specular.y(), specular.z()));
 
 		xml.replaceAll("%specTexMutator%", "0");
 	}
@@ -262,12 +263,12 @@ Error GltfImporter::writeMaterial(const cgltf_material& mtl, Bool writeRayTracin
 	Bool bRoughnessMetalicTexture = false;
 	if(mtl.pbr_metallic_roughness.metallic_roughness_texture.texture && constantRoughness < 0.0f)
 	{
-		StringRaii uri(m_pool);
+		ImporterString uri(m_pool);
 		uri.sprintf("%s%s", m_texrpath.cstr(),
 					getTextureUri(mtl.pbr_metallic_roughness.metallic_roughness_texture).cstr());
 
 		xml.replaceAll("%roughness%",
-					   StringRaii(m_pool).sprintf("<input name=\"m_roughnessTex\" value=\"%s\"/>", uri.cstr()));
+					   ImporterString(m_pool).sprintf("<input name=\"m_roughnessTex\" value=\"%s\"/>", uri.cstr()));
 
 		xml.replaceAll("%roughnessTexMutator%", "1");
 
@@ -280,7 +281,7 @@ Error GltfImporter::writeMaterial(const cgltf_material& mtl, Bool writeRayTracin
 								  : mtl.pbr_metallic_roughness.roughness_factor;
 
 		xml.replaceAll("%roughness%",
-					   StringRaii(m_pool).sprintf("<input name=\"m_roughness\" value=\"%f\"/>", roughness));
+					   ImporterString(m_pool).sprintf("<input name=\"m_roughness\" value=\"%f\"/>", roughness));
 
 		xml.replaceAll("%roughnessTexMutator%", "0");
 	}
@@ -288,12 +289,12 @@ Error GltfImporter::writeMaterial(const cgltf_material& mtl, Bool writeRayTracin
 	// Metallic
 	if(mtl.pbr_metallic_roughness.metallic_roughness_texture.texture && constantMetaliness < 0.0f)
 	{
-		StringRaii uri(m_pool);
+		ImporterString uri(m_pool);
 		uri.sprintf("%s%s", m_texrpath.cstr(),
 					getTextureUri(mtl.pbr_metallic_roughness.metallic_roughness_texture).cstr());
 
 		xml.replaceAll("%metallic%",
-					   StringRaii(m_pool).sprintf("<input name=\"m_metallicTex\" value=\"%s\"/>", uri.cstr()));
+					   ImporterString(m_pool).sprintf("<input name=\"m_metallicTex\" value=\"%s\"/>", uri.cstr()));
 
 		xml.replaceAll("%metalTexMutator%", "1");
 
@@ -306,7 +307,7 @@ Error GltfImporter::writeMaterial(const cgltf_material& mtl, Bool writeRayTracin
 								  : mtl.pbr_metallic_roughness.metallic_factor;
 
 		xml.replaceAll("%metallic%",
-					   StringRaii(m_pool).sprintf("<input name=\"m_metallic\" value=\"%f\"/>", metalines));
+					   ImporterString(m_pool).sprintf("<input name=\"m_metallic\" value=\"%f\"/>", metalines));
 
 		xml.replaceAll("%metalTexMutator%", "0");
 	}
@@ -314,8 +315,8 @@ Error GltfImporter::writeMaterial(const cgltf_material& mtl, Bool writeRayTracin
 	if(bRoughnessMetalicTexture && m_importTextures)
 	{
 		CString in = getTextureUri(mtl.pbr_metallic_roughness.metallic_roughness_texture);
-		StringRaii out = m_outDir;
-		out.append(in);
+		ImporterString out = m_outDir;
+		out += in;
 		fixImageUri(out);
 		ANKI_CHECK(importImage(*m_pool, in, out, false));
 	}
@@ -327,19 +328,19 @@ Error GltfImporter::writeMaterial(const cgltf_material& mtl, Bool writeRayTracin
 		ANKI_CHECK(findConstantColorsInImage(getTextureUri(mtl.normal_texture).cstr(), constantColor, *m_pool));
 		if(constantColor.xyz() == -1.0f)
 		{
-			StringRaii uri(m_pool);
+			ImporterString uri(m_pool);
 			uri.sprintf("%s%s", m_texrpath.cstr(), getTextureUri(mtl.normal_texture).cstr());
 
 			xml.replaceAll("%normal%",
-						   StringRaii(m_pool).sprintf("<input name=\"m_normalTex\" value=\"%s\"/>", uri.cstr()));
+						   ImporterString(m_pool).sprintf("<input name=\"m_normalTex\" value=\"%s\"/>", uri.cstr()));
 
 			xml.replaceAll("%normalTexMutator%", "1");
 
 			if(m_importTextures)
 			{
 				CString in = getTextureUri(mtl.normal_texture);
-				StringRaii out = m_outDir;
-				out.append(in);
+				ImporterString out = m_outDir;
+				out += in;
 				fixImageUri(out);
 				ANKI_CHECK(importImage(*m_pool, in, out, false));
 			}
@@ -359,19 +360,19 @@ Error GltfImporter::writeMaterial(const cgltf_material& mtl, Bool writeRayTracin
 	// Emissive texture
 	if(mtl.emissive_texture.texture)
 	{
-		StringRaii uri(m_pool);
+		ImporterString uri(m_pool);
 		uri.sprintf("%s%s", m_texrpath.cstr(), getTextureUri(mtl.emissive_texture).cstr());
 
 		xml.replaceAll("%emission%",
-					   StringRaii(m_pool).sprintf("<input name=\"m_emissiveTex\" value=\"%s\"/>", uri.cstr()));
+					   ImporterString(m_pool).sprintf("<input name=\"m_emissiveTex\" value=\"%s\"/>", uri.cstr()));
 
 		xml.replaceAll("%emissiveTexMutator%", "1");
 
 		if(m_importTextures)
 		{
 			CString in = getTextureUri(mtl.emissive_texture);
-			StringRaii out = m_outDir;
-			out.append(in);
+			ImporterString out = m_outDir;
+			out += in;
 			fixImageUri(out);
 			ANKI_CHECK(importImage(*m_pool, in, out, false));
 		}
@@ -380,8 +381,8 @@ Error GltfImporter::writeMaterial(const cgltf_material& mtl, Bool writeRayTracin
 	{
 		const F32* emissionCol = &mtl.emissive_factor[0];
 
-		xml.replaceAll("%emission%", StringRaii(m_pool).sprintf("<input name=\"m_emission\" value=\"%f %f %f\"/>",
-																emissionCol[0], emissionCol[1], emissionCol[2]));
+		xml.replaceAll("%emission%", ImporterString(m_pool).sprintf("<input name=\"m_emission\" value=\"%f %f %f\"/>",
+																	emissionCol[0], emissionCol[1], emissionCol[2]));
 
 		xml.replaceAll("%emissiveTexMutator%", "0");
 	}
@@ -400,19 +401,20 @@ Error GltfImporter::writeMaterial(const cgltf_material& mtl, Bool writeRayTracin
 		}
 
 		xml.replaceAll("%subsurface%",
-					   StringRaii(m_pool).sprintf("<input name=\"m_subsurface\" value=\"%f\"/>", subsurface));
+					   ImporterString(m_pool).sprintf("<input name=\"m_subsurface\" value=\"%f\"/>", subsurface));
 	}
 
 	// Height texture
 	auto it = extras.find("height_map");
 	if(it != extras.getEnd())
 	{
-		StringRaii uri(m_pool);
+		ImporterString uri(m_pool);
 		uri.sprintf("%s%s", m_texrpath.cstr(), it->cstr());
 
-		xml.replaceAll("%height%", StringRaii(m_pool).sprintf("<input name=\"m_heightTex\" value=\"%s\" \"/>\n"
-															  "\t\t<input name=\"m_heightmapScale\" value=\"0.05\"/>",
-															  uri.cstr()));
+		xml.replaceAll("%height%",
+					   ImporterString(m_pool).sprintf("<input name=\"m_heightTex\" value=\"%s\" \"/>\n"
+													  "\t\t<input name=\"m_heightmapScale\" value=\"0.05\"/>",
+													  uri.cstr()));
 
 		xml.replaceAll("%parallaxMutator%", "1");
 	}

+ 42 - 34
AnKi/Importer/GltfImporterMesh.cpp

@@ -115,8 +115,8 @@ static_assert(sizeof(TempVertex) == 5 * sizeof(Vec4), "Will be hashed");
 class SubMesh
 {
 public:
-	DynamicArrayRaii<TempVertex> m_verts;
-	DynamicArrayRaii<U32> m_indices;
+	ImporterDynamicArray<TempVertex> m_verts;
+	ImporterDynamicArray<U32> m_indices;
 
 	Vec3 m_aabbMin = Vec3(kMaxF32);
 	Vec3 m_aabbMax = Vec3(kMinF32);
@@ -135,16 +135,16 @@ static void reindexSubmesh(SubMesh& submesh, BaseMemoryPool* pool)
 {
 	const U32 vertSize = sizeof(submesh.m_verts[0]);
 
-	DynamicArrayRaii<U32> remap(pool);
-	remap.create(submesh.m_verts.getSize(), 0);
+	ImporterDynamicArray<U32> remap(pool);
+	remap.resize(submesh.m_verts.getSize(), 0);
 
 	const U32 vertCount = U32(meshopt_generateVertexRemap(&remap[0], &submesh.m_indices[0], submesh.m_indices.getSize(),
 														  &submesh.m_verts[0], submesh.m_verts.getSize(), vertSize));
 
-	DynamicArrayRaii<U32> newIdxArray(pool);
-	newIdxArray.create(submesh.m_indices.getSize(), 0);
-	DynamicArrayRaii<TempVertex> newVertArray(pool);
-	newVertArray.create(vertCount);
+	ImporterDynamicArray<U32> newIdxArray(pool);
+	newIdxArray.resize(submesh.m_indices.getSize(), 0);
+	ImporterDynamicArray<TempVertex> newVertArray(pool);
+	newVertArray.resize(vertCount);
 
 	meshopt_remapIndexBuffer(&newIdxArray[0], &submesh.m_indices[0], submesh.m_indices.getSize(), &remap[0]);
 	meshopt_remapVertexBuffer(&newVertArray[0], &submesh.m_verts[0], submesh.m_verts.getSize(), vertSize, &remap[0]);
@@ -160,8 +160,8 @@ static void optimizeSubmesh(SubMesh& submesh, BaseMemoryPool* pool)
 
 	// Vert cache
 	{
-		DynamicArrayRaii<U32> newIdxArray(pool);
-		newIdxArray.create(submesh.m_indices.getSize(), 0);
+		ImporterDynamicArray<U32> newIdxArray(pool);
+		newIdxArray.resize(submesh.m_indices.getSize(), 0);
 
 		meshopt_optimizeVertexCache(&newIdxArray[0], &submesh.m_indices[0], submesh.m_indices.getSize(),
 									submesh.m_verts.getSize());
@@ -171,8 +171,8 @@ static void optimizeSubmesh(SubMesh& submesh, BaseMemoryPool* pool)
 
 	// Overdraw
 	{
-		DynamicArrayRaii<U32> newIdxArray(pool);
-		newIdxArray.create(submesh.m_indices.getSize(), 0);
+		ImporterDynamicArray<U32> newIdxArray(pool);
+		newIdxArray.resize(submesh.m_indices.getSize(), 0);
 
 		meshopt_optimizeOverdraw(&newIdxArray[0], &submesh.m_indices[0], submesh.m_indices.getSize(),
 								 &submesh.m_verts[0].m_position.x(), submesh.m_verts.getSize(), vertSize, 1.05f);
@@ -182,8 +182,8 @@ static void optimizeSubmesh(SubMesh& submesh, BaseMemoryPool* pool)
 
 	// Vert fetch
 	{
-		DynamicArrayRaii<TempVertex> newVertArray(pool);
-		newVertArray.create(submesh.m_verts.getSize());
+		ImporterDynamicArray<TempVertex> newVertArray(pool);
+		newVertArray.resize(submesh.m_verts.getSize());
 
 		const U32 newVertCount = U32(meshopt_optimizeVertexFetch(&newVertArray[0],
 																 &submesh.m_indices[0], // Inplace
@@ -211,15 +211,15 @@ static void decimateSubmesh(F32 factor, SubMesh& submesh, BaseMemoryPool* pool)
 	}
 
 	// Decimate
-	DynamicArrayRaii<U32> newIndices(submesh.m_indices.getSize(), pool);
+	ImporterDynamicArray<U32> newIndices(pool);
 	newIndices.resize(U32(meshopt_simplify(&newIndices[0], &submesh.m_indices[0], submesh.m_indices.getSize(),
 										   &submesh.m_verts[0].m_position.x(), submesh.m_verts.getSize(),
 										   sizeof(TempVertex), targetIndexCount, 1e-2f)));
 
 	// Re-pack
-	DynamicArrayRaii<U32> reindexedIndices(pool);
-	DynamicArrayRaii<TempVertex> newVerts(pool);
-	HashMapRaii<U32, U32> vertexStored(pool);
+	ImporterDynamicArray<U32> reindexedIndices(pool);
+	ImporterDynamicArray<TempVertex> newVerts(pool);
+	ImporterHashMap<U32, U32> vertexStored(pool);
 	for(U32 idx = 0; idx < newIndices.getSize(); ++idx)
 	{
 		U32 newIdx;
@@ -283,9 +283,9 @@ static void fixNormals(const F32 normalsMergeAngle, SubMesh& submesh)
 
 static void computeTangents(SubMesh& submesh)
 {
-	DynamicArrayRaii<Vec3> bitangents(&submesh.m_verts.getMemoryPool());
+	ImporterDynamicArray<Vec3> bitangents(&submesh.m_verts.getMemoryPool());
 	const U32 vertCount = submesh.m_verts.getSize();
-	bitangents.create(vertCount, Vec3(0.0f));
+	bitangents.resize(vertCount, Vec3(0.0f));
 
 	for(U32 i = 0; i < submesh.m_indices.getSize(); i += 3)
 	{
@@ -364,7 +364,7 @@ static void computeTangents(SubMesh& submesh)
 	}
 }
 
-static Bool isConvex(const List<SubMesh>& submeshes)
+static Bool isConvex(const ImporterList<SubMesh>& submeshes)
 {
 	Bool convex = true;
 	for(const SubMesh& submesh : submeshes)
@@ -444,12 +444,12 @@ U32 GltfImporter::getMeshTotalVertexCount(const cgltf_mesh& mesh)
 
 Error GltfImporter::writeMesh(const cgltf_mesh& mesh) const
 {
-	StringRaii meshName = computeMeshResourceFilename(mesh);
-	StringRaii fname(m_pool);
+	ImporterString meshName = computeMeshResourceFilename(mesh);
+	ImporterString fname(m_pool);
 	fname.sprintf("%s%s", m_outDir.cstr(), meshName.cstr());
 	ANKI_IMPORTER_LOGV("Importing mesh (%s): %s", (m_optimizeMeshes) ? "optimize" : "WON'T optimize", fname.cstr());
 
-	Array<ListRaii<SubMesh>, kMaxLodCount> submeshes = {{{m_pool}, {m_pool}, {m_pool}}};
+	Array<ImporterList<SubMesh>, kMaxLodCount> submeshes = {{{m_pool}, {m_pool}, {m_pool}}};
 	Vec3 aabbMin(kMaxF32);
 	Vec3 aabbMax(kMinF32);
 	Bool hasBoneWeights = false;
@@ -482,7 +482,7 @@ Error GltfImporter::writeMesh(const cgltf_mesh& mesh) const
 		}
 
 		U32 vertCount = U32(primitive->attributes[0].data->count);
-		submesh.m_verts.create(vertCount);
+		submesh.m_verts.resize(vertCount);
 
 		//
 		// Gather positions + normals + UVs
@@ -567,7 +567,7 @@ Error GltfImporter::writeMesh(const cgltf_mesh& mesh) const
 				ANKI_IMPORTER_LOGE("Incorect index count: %lu", primitive->indices->count);
 				return Error::kUserData;
 			}
-			submesh.m_indices.create(U32(primitive->indices->count));
+			submesh.m_indices.resize(U32(primitive->indices->count));
 			const U8* base = static_cast<const U8*>(primitive->indices->buffer_view->buffer->data)
 							 + primitive->indices->offset + primitive->indices->buffer_view->offset;
 			for(U32 i = 0; i < primitive->indices->count; ++i)
@@ -679,7 +679,8 @@ Error GltfImporter::writeMesh(const cgltf_mesh& mesh) const
 	}
 
 	// Write sub meshes
-	DynamicArrayRaii<MeshBinarySubMesh> outSubmeshes(U32(submeshes[0].getSize()), m_pool);
+	ImporterDynamicArray<MeshBinarySubMesh> outSubmeshes(m_pool);
+	outSubmeshes.resize(U32(submeshes[0].getSize()));
 
 	for(U32 submeshIdx = 0; submeshIdx < outSubmeshes.getSize(); ++submeshIdx)
 	{
@@ -714,7 +715,8 @@ Error GltfImporter::writeMesh(const cgltf_mesh& mesh) const
 		U32 vertCount = 0;
 		for(const SubMesh& submesh : submeshes[lod])
 		{
-			DynamicArrayRaii<U16> indices(submesh.m_indices.getSize(), m_pool);
+			ImporterDynamicArray<U16> indices(m_pool);
+			indices.resize(submesh.m_indices.getSize());
 			for(U32 i = 0; i < indices.getSize(); ++i)
 			{
 				const U32 idx = submesh.m_indices[i] + vertCount;
@@ -734,7 +736,8 @@ Error GltfImporter::writeMesh(const cgltf_mesh& mesh) const
 		// Write positions
 		for(const SubMesh& submesh : submeshes[lod])
 		{
-			DynamicArrayRaii<U16Vec4> positions(submesh.m_verts.getSize(), m_pool);
+			ImporterDynamicArray<U16Vec4> positions(m_pool);
+			positions.resize(submesh.m_verts.getSize());
 			for(U32 v = 0; v < submesh.m_verts.getSize(); ++v)
 			{
 				Vec3 localPos = (submesh.m_verts[v].m_position + posTranslation) * posScale;
@@ -750,7 +753,8 @@ Error GltfImporter::writeMesh(const cgltf_mesh& mesh) const
 		// Write normals
 		for(const SubMesh& submesh : submeshes[lod])
 		{
-			DynamicArrayRaii<U32> normals(submesh.m_verts.getSize(), m_pool);
+			ImporterDynamicArray<U32> normals(m_pool);
+			normals.resize(submesh.m_verts.getSize());
 			for(U32 v = 0; v < submesh.m_verts.getSize(); ++v)
 			{
 				normals[v] = packSnorm4x8(submesh.m_verts[v].m_normal.xyz0());
@@ -762,7 +766,8 @@ Error GltfImporter::writeMesh(const cgltf_mesh& mesh) const
 		// Write tangent
 		for(const SubMesh& submesh : submeshes[lod])
 		{
-			DynamicArrayRaii<U32> tangents(submesh.m_verts.getSize(), m_pool);
+			ImporterDynamicArray<U32> tangents(m_pool);
+			tangents.resize(submesh.m_verts.getSize());
 			for(U32 v = 0; v < submesh.m_verts.getSize(); ++v)
 			{
 				tangents[v] = packSnorm4x8(submesh.m_verts[v].m_tangent);
@@ -774,7 +779,8 @@ Error GltfImporter::writeMesh(const cgltf_mesh& mesh) const
 		// Write UV
 		for(const SubMesh& submesh : submeshes[lod])
 		{
-			DynamicArrayRaii<Vec2> uvs(submesh.m_verts.getSize(), m_pool);
+			ImporterDynamicArray<Vec2> uvs(m_pool);
+			uvs.resize(submesh.m_verts.getSize());
 			for(U32 v = 0; v < submesh.m_verts.getSize(); ++v)
 			{
 				uvs[v] = submesh.m_verts[v].m_uv;
@@ -788,7 +794,8 @@ Error GltfImporter::writeMesh(const cgltf_mesh& mesh) const
 			// Bone IDs
 			for(const SubMesh& submesh : submeshes[lod])
 			{
-				DynamicArrayRaii<U8Vec4> boneids(submesh.m_verts.getSize(), m_pool);
+				ImporterDynamicArray<U8Vec4> boneids(m_pool);
+				boneids.resize(submesh.m_verts.getSize());
 				for(U32 v = 0; v < submesh.m_verts.getSize(); ++v)
 				{
 					boneids[v] = U8Vec4(submesh.m_verts[v].m_boneIds);
@@ -800,7 +807,8 @@ Error GltfImporter::writeMesh(const cgltf_mesh& mesh) const
 			// Bone weights
 			for(const SubMesh& submesh : submeshes[lod])
 			{
-				DynamicArrayRaii<U32> boneWeights(submesh.m_verts.getSize(), m_pool);
+				ImporterDynamicArray<U32> boneWeights(m_pool);
+				boneWeights.resize(submesh.m_verts.getSize());
 				for(U32 v = 0; v < submesh.m_verts.getSize(); ++v)
 				{
 					boneWeights[v] = packSnorm4x8(submesh.m_verts[v].m_boneWeights);

+ 32 - 32
AnKi/Importer/ImageImporter.cpp

@@ -20,9 +20,9 @@ namespace {
 class SurfaceOrVolumeData
 {
 public:
-	DynamicArrayRaii<U8, PtrSize> m_pixels;
-	DynamicArrayRaii<U8, PtrSize> m_s3tcPixels;
-	DynamicArrayRaii<U8, PtrSize> m_astcPixels;
+	ImporterDynamicArrayLarge<U8> m_pixels;
+	ImporterDynamicArrayLarge<U8> m_s3tcPixels;
+	ImporterDynamicArrayLarge<U8> m_astcPixels;
 
 	SurfaceOrVolumeData(BaseMemoryPool* pool)
 		: m_pixels(pool)
@@ -36,7 +36,7 @@ class Mipmap
 {
 public:
 	/// One surface for each layer ore one per face or a single volume if it's a 3D texture.
-	DynamicArrayRaii<SurfaceOrVolumeData> m_surfacesOrVolume;
+	ImporterDynamicArray<SurfaceOrVolumeData> m_surfacesOrVolume;
 
 	Mipmap(BaseMemoryPool* pool)
 		: m_surfacesOrVolume(pool)
@@ -48,7 +48,7 @@ public:
 class ImageImporterContext
 {
 public:
-	DynamicArrayRaii<Mipmap> m_mipmaps;
+	ImporterDynamicArray<Mipmap> m_mipmaps;
 	U32 m_width = 0;
 	U32 m_height = 0;
 	U32 m_depth = 0;
@@ -250,7 +250,7 @@ static Error checkInputImages(const ImageImporterConfig& config, U32& width, U32
 }
 
 static Error resizeImage(CString inImageFilename, U32 outWidth, U32 outHeight, CString tempDirectory,
-						 BaseMemoryPool& pool, StringRaii& tmpFilename)
+						 BaseMemoryPool& pool, ImporterString& tmpFilename)
 {
 	U32 inWidth, inHeight, channelCount;
 	Bool hdr;
@@ -277,7 +277,7 @@ static Error resizeImage(CString inImageFilename, U32 outWidth, U32 outHeight, C
 
 	// Resize
 	I ok;
-	DynamicArrayRaii<U8> outPixels(&pool);
+	ImporterDynamicArray<U8> outPixels(&pool);
 	if(!hdr)
 	{
 		outPixels.resize(outWidth * outHeight * channelCount);
@@ -407,19 +407,19 @@ static Error loadFirstMipmap(const ImageImporterConfig& config, ImageImporterCon
 
 	if(ctx.m_depth > 1)
 	{
-		mip0.m_surfacesOrVolume.create(1, &pool);
-		mip0.m_surfacesOrVolume[0].m_pixels.create(ctx.m_pixelSize * ctx.m_width * ctx.m_height * ctx.m_depth);
+		mip0.m_surfacesOrVolume.resize(1, &pool);
+		mip0.m_surfacesOrVolume[0].m_pixels.resize(ctx.m_pixelSize * ctx.m_width * ctx.m_height * ctx.m_depth);
 	}
 	else
 	{
-		mip0.m_surfacesOrVolume.create(ctx.m_faceCount * ctx.m_layerCount, &pool);
+		mip0.m_surfacesOrVolume.resize(ctx.m_faceCount * ctx.m_layerCount, &pool);
 		ANKI_ASSERT(mip0.m_surfacesOrVolume.getSize() == config.m_inputFilenames.getSize());
 
 		for(U32 f = 0; f < ctx.m_faceCount; ++f)
 		{
 			for(U32 l = 0; l < ctx.m_layerCount; ++l)
 			{
-				mip0.m_surfacesOrVolume[l * ctx.m_faceCount + f].m_pixels.create(ctx.m_pixelSize * ctx.m_width
+				mip0.m_surfacesOrVolume[l * ctx.m_faceCount + f].m_pixels.resize(ctx.m_pixelSize * ctx.m_width
 																				 * ctx.m_height);
 			}
 		}
@@ -593,7 +593,7 @@ static Error compressS3tc(BaseMemoryPool& pool, CString tempDirectory, CString c
 				== PtrSize((hdr || channelCount == 4) ? 16 : 8) * (inWidth / 4) * (inHeight / 4));
 
 	// Create a PNG image to feed to the compressor
-	StringRaii tmpFilename(&pool);
+	ImporterString tmpFilename(&pool);
 	tmpFilename.sprintf("%s/AnKiImageImporter_%u.%s", tempDirectory.cstr(), g_tempFileIndex.fetchAdd(1),
 						(hdr) ? "exr" : "png");
 	ANKI_IMPORTER_LOGV("Will store: %s", tmpFilename.cstr());
@@ -615,10 +615,10 @@ static Error compressS3tc(BaseMemoryPool& pool, CString tempDirectory, CString c
 		ANKI_IMPORTER_LOGE("Failed to create: %s", tmpFilename.cstr());
 		return Error::kFunctionFailed;
 	}
-	CleanupFile tmpCleanup(&pool, tmpFilename);
+	CleanupFile tmpCleanup(tmpFilename);
 
 	// Invoke the compressor process
-	StringRaii ddsFilename(&pool);
+	ImporterString ddsFilename(&pool);
 	ddsFilename.sprintf("%s/AnKiImageImporter_%u.dds", tempDirectory.cstr(), g_tempFileIndex.fetchAdd(1));
 	Process proc;
 	Array<CString, 5> args;
@@ -632,14 +632,14 @@ static Error compressS3tc(BaseMemoryPool& pool, CString tempDirectory, CString c
 	ANKI_IMPORTER_LOGV("Will invoke process: %s %s %s %s %s %s", compressonatorFilename.cstr(), args[0].cstr(),
 					   args[1].cstr(), args[2].cstr(), args[3].cstr(), args[4].cstr());
 	ANKI_CHECK(proc.start(compressonatorFilename, args));
-	CleanupFile ddsCleanup(&pool, ddsFilename);
+	CleanupFile ddsCleanup(ddsFilename);
 	ProcessStatus status;
 	I32 exitCode;
 	ANKI_CHECK(proc.wait(60.0_sec, &status, &exitCode));
 
 	if(!(status == ProcessStatus::kNotRunning && exitCode == 0))
 	{
-		StringRaii errStr(&pool);
+		String errStr;
 		if(exitCode != 0)
 		{
 			ANKI_CHECK(proc.readFromStdout(errStr));
@@ -706,7 +706,7 @@ static Error compressAstc(BaseMemoryPool& pool, CString tempDirectory, CString a
 	ANKI_ASSERT(outPixels.getSizeInBytes() == blockBytes * (inWidth / blockSize.x()) * (inHeight / blockSize.y()));
 
 	// Create a BMP image to feed to the astcebc
-	StringRaii tmpFilename(&pool);
+	ImporterString tmpFilename(&pool);
 	tmpFilename.sprintf("%s/AnKiImageImporter_%u.%s", tempDirectory.cstr(), g_tempFileIndex.fetchAdd(1),
 						(hdr) ? "exr" : "png");
 	ANKI_IMPORTER_LOGV("Will store: %s", tmpFilename.cstr());
@@ -728,12 +728,12 @@ static Error compressAstc(BaseMemoryPool& pool, CString tempDirectory, CString a
 		ANKI_IMPORTER_LOGE("Failed to create: %s", tmpFilename.cstr());
 		return Error::kFunctionFailed;
 	}
-	CleanupFile pngCleanup(&pool, tmpFilename);
+	CleanupFile pngCleanup(tmpFilename);
 
 	// Invoke the compressor process
-	StringRaii astcFilename(&pool);
+	ImporterString astcFilename(&pool);
 	astcFilename.sprintf("%s/AnKiImageImporter_%u.astc", tempDirectory.cstr(), g_tempFileIndex.fetchAdd(1));
-	StringRaii blockStr(&pool);
+	ImporterString blockStr(&pool);
 	blockStr.sprintf("%ux%u", blockSize.x(), blockSize.y());
 	Process proc;
 	Array<CString, 5> args;
@@ -748,14 +748,14 @@ static Error compressAstc(BaseMemoryPool& pool, CString tempDirectory, CString a
 					   args[2].cstr(), args[3].cstr(), args[4].cstr());
 	ANKI_CHECK(proc.start(astcencFilename, args));
 
-	CleanupFile astcCleanup(&pool, astcFilename);
+	CleanupFile astcCleanup(astcFilename);
 	ProcessStatus status;
 	I32 exitCode;
 	ANKI_CHECK(proc.wait(60.0_sec, &status, &exitCode));
 
 	if(!(status == ProcessStatus::kNotRunning && exitCode == 0))
 	{
-		StringRaii errStr(&pool);
+		String errStr;
 		if(exitCode != 0)
 		{
 			ANKI_CHECK(proc.readFromStdout(errStr));
@@ -836,7 +836,7 @@ static Error storeAnkiImage(const ImageImporterConfig& config, const ImageImport
 	}
 	header.m_compressionMask = config.m_compressions;
 	header.m_isNormal = false;
-	header.m_mipmapCount = ctx.m_mipmaps.getSize();
+	header.m_mipmapCount = U32(ctx.m_mipmaps.getSize());
 	header.m_astcBlockSizeX = config.m_astcBlockSize.x();
 	header.m_astcBlockSizeY = config.m_astcBlockSize.y();
 	ANKI_CHECK(outFile.write(&header, sizeof(header)));
@@ -923,9 +923,9 @@ static Error importImageInternal(const ImageImporterConfig& configOriginal)
 	ANKI_CHECK(checkInputImages(config, width, height, channelCount, isHdr));
 
 	// Resize
-	DynamicArrayRaii<StringRaii> newFilenames(&pool);
-	DynamicArrayRaii<CString> newFilenamesCString(&pool);
-	DynamicArrayRaii<CleanupFile> resizedImagesCleanup(&pool);
+	ImporterDynamicArray<ImporterString> newFilenames(&pool);
+	ImporterDynamicArray<CString> newFilenamesCString(&pool);
+	ImporterDynamicArray<CleanupFile> resizedImagesCleanup(&pool);
 	if(width < config.m_minMipmapDimension || height < config.m_minMipmapDimension)
 	{
 		const U32 newWidth = max(width, config.m_minMipmapDimension);
@@ -934,7 +934,7 @@ static Error importImageInternal(const ImageImporterConfig& configOriginal)
 		ANKI_IMPORTER_LOGV("Image is smaller than the min mipmap dimension. Will resize it to %ux%u", newWidth,
 						   newHeight);
 
-		newFilenames.resize(config.m_inputFilenames.getSize(), StringRaii(&pool));
+		newFilenames.resize(config.m_inputFilenames.getSize(), ImporterString(&pool));
 		newFilenamesCString.resize(config.m_inputFilenames.getSize());
 
 		for(U32 i = 0; i < config.m_inputFilenames.getSize(); ++i)
@@ -943,7 +943,7 @@ static Error importImageInternal(const ImageImporterConfig& configOriginal)
 								   newFilenames[i]));
 
 			newFilenamesCString[i] = newFilenames[i];
-			resizedImagesCleanup.emplaceBack(&pool, newFilenames[i]);
+			resizedImagesCleanup.emplaceBack(newFilenames[i]);
 		}
 
 		// Override config
@@ -1016,7 +1016,7 @@ static Error importImageInternal(const ImageImporterConfig& configOriginal)
 
 		if(config.m_type != ImageBinaryType::k3D)
 		{
-			ctx.m_mipmaps[mip].m_surfacesOrVolume.create(ctx.m_faceCount * ctx.m_layerCount, &pool);
+			ctx.m_mipmaps[mip].m_surfacesOrVolume.resize(ctx.m_faceCount * ctx.m_layerCount, &pool);
 			for(U32 l = 0; l < ctx.m_layerCount; ++l)
 			{
 				for(U32 f = 0; f < ctx.m_faceCount; ++f)
@@ -1024,7 +1024,7 @@ static Error importImageInternal(const ImageImporterConfig& configOriginal)
 					const U32 idx = l * ctx.m_faceCount + f;
 					const SurfaceOrVolumeData& inSurface = ctx.m_mipmaps[mip - 1].m_surfacesOrVolume[idx];
 					SurfaceOrVolumeData& outSurface = ctx.m_mipmaps[mip].m_surfacesOrVolume[idx];
-					outSurface.m_pixels.create((ctx.m_width >> mip) * (ctx.m_height >> mip) * ctx.m_pixelSize);
+					outSurface.m_pixels.resize((ctx.m_width >> mip) * (ctx.m_height >> mip) * ctx.m_pixelSize);
 
 					if(ctx.m_channelCount == 3)
 					{
@@ -1086,7 +1086,7 @@ static Error importImageInternal(const ImageImporterConfig& configOriginal)
 					const PtrSize blockSize = (ctx.m_hdr || ctx.m_channelCount == 4) ? 16 : 8;
 					const PtrSize s3tcImageSize = blockSize * (width / 4) * (height / 4);
 
-					surface.m_s3tcPixels.create(s3tcImageSize);
+					surface.m_s3tcPixels.resize(s3tcImageSize);
 
 					ANKI_CHECK(compressS3tc(pool, config.m_tempDirectory, config.m_compressonatorFilename,
 											ConstWeakArray<U8, PtrSize>(surface.m_pixels), width, height,
@@ -1116,7 +1116,7 @@ static Error importImageInternal(const ImageImporterConfig& configOriginal)
 					const PtrSize astcImageSize =
 						blockSize * (width / config.m_astcBlockSize.x()) * (height / config.m_astcBlockSize.y());
 
-					surface.m_astcPixels.create(astcImageSize);
+					surface.m_astcPixels.resize(astcImageSize);
 
 					ANKI_CHECK(compressAstc(pool, config.m_tempDirectory, config.m_astcencFilename,
 											ConstWeakArray<U8, PtrSize>(surface.m_pixels), width, height,

+ 2 - 2
AnKi/Math/Axisang.h

@@ -186,9 +186,9 @@ public:
 	/// @name Other
 	/// @{
 	ANKI_ENABLE_METHOD(std::is_floating_point<T>::value)
-	void toString(StringRaii& str) const
+	String toString() const
 	{
-		str.sprintf("%f %f %f | %f", m_axis.x(), m_axis.y(), m_axis.z(), m_ang);
+		return String().sprintf("%f %f %f | %f", m_axis.x(), m_axis.y(), m_axis.z(), m_ang);
 	}
 	/// @}
 

+ 2 - 2
AnKi/Math/Euler.h

@@ -146,9 +146,9 @@ public:
 	/// @name Other
 	/// @{
 	ANKI_ENABLE_METHOD(std::is_floating_point<T>::value)
-	void toString(StringRaii& str) const
+	String toString() const
 	{
-		str.sprintf("%f %f %f", m_vec.m_x, m_vec.m_y, m_vec.m_z);
+		return String().sprintf("%f %f %f", m_vec.m_x, m_vec.m_y, m_vec.m_z);
 	}
 	/// @}
 

+ 4 - 2
AnKi/Math/Mat.h

@@ -1453,8 +1453,9 @@ public:
 	}
 
 	ANKI_ENABLE_METHOD(std::is_floating_point<T>::value)
-	void toString(StringRaii& str) const
+	String toString() const
 	{
+		String str;
 		for(U j = 0; j < kTRowCount; ++j)
 		{
 			for(U i = 0; i < kTColumnCount; ++i)
@@ -1472,9 +1473,10 @@ public:
 				{
 					fmt = "%f ";
 				}
-				str.append(StringRaii(str.getMemoryPool()).sprintf(fmt, m_arr2[j][i]));
+				str += String().sprintf(fmt, m_arr2[j][i]);
 			}
 		}
+		return str;
 	}
 	/// @}
 

+ 15 - 14
AnKi/Math/Transform.h

@@ -224,21 +224,22 @@ public:
 		return *this;
 	}
 
-	ANKI_ENABLE_METHOD(std::is_floating_point<T>::value) void toString(StringRaii& str) const
+	ANKI_ENABLE_METHOD(std::is_floating_point<T>::value)
+	String toString() const
 	{
-		StringRaii b(str.getMemoryPool());
-		m_origin.toString(b);
-		str.append(b);
-		str.append("\n");
-
-		b.destroy();
-		m_rotation.toString(b);
-		str.append(b);
-		str.append("\n");
-
-		b.destroy();
-		b.sprintf("%f", m_scale);
-		str.append(b);
+		String str;
+		String b = m_origin.toString();
+		str += b;
+		str += "\n";
+
+		b = m_rotation.toString();
+		str += b;
+		str += "\n";
+
+		b = String().sprintf("%f", m_scale);
+		str += b;
+
+		return str;
 	}
 	/// @}
 

+ 12 - 6
AnKi/Math/Vec.h

@@ -3291,32 +3291,38 @@ public:
 	}
 
 	ANKI_ENABLE_METHOD(std::is_floating_point<T>::value)
-	void toString(StringRaii& str) const
+	String toString() const
 	{
+		String str;
 		for(U i = 0; i < kTComponentCount; ++i)
 		{
-			str.append(StringRaii(str.getMemoryPool()).sprintf((i < i - kTComponentCount) ? "%f " : "%f", m_arr[i]));
+			str += String().sprintf((i < i - kTComponentCount) ? "%f " : "%f", m_arr[i]);
 		}
+		return str;
 	}
 
 	static constexpr Bool kClangWorkaround = std::is_integral<T>::value && std::is_unsigned<T>::value;
 	ANKI_ENABLE_METHOD(kClangWorkaround)
-	void toString(StringRaii& str) const
+	String toString() const
 	{
+		String str;
 		for(U i = 0; i < kTComponentCount; ++i)
 		{
-			str.append(StringRaii(str.getMemoryPool()).sprintf((i < i - kTComponentCount) ? "%u " : "%u", m_arr[i]));
+			str += String().sprintf((i < i - kTComponentCount) ? "%u " : "%u", m_arr[i]);
 		}
+		return str;
 	}
 
 	static constexpr Bool kClangWorkaround2 = std::is_integral<T>::value && std::is_signed<T>::value;
 	ANKI_ENABLE_METHOD(kClangWorkaround2)
-	void toString(StringRaii& str) const
+	String toString() const
 	{
+		String str;
 		for(U i = 0; i < kTComponentCount; ++i)
 		{
-			str.append(StringRaii(str.getMemoryPool()).sprintf((i < i - kTComponentCount) ? "%d " : "%d", m_arr[i]));
+			str += String().sprintf((i < i - kTComponentCount) ? "%d " : "%d", m_arr[i]);
 		}
+		return str;
 	}
 	/// @}
 

+ 2 - 0
AnKi/Physics/Common.h

@@ -59,6 +59,8 @@ private:
 	~PhysicsMemoryPool() = default;
 };
 
+ANKI_DEFINE_SUBMODULE_UTIL_CONTAINERS(Physics, PhysicsMemoryPool)
+
 // Forward
 class PhysicsObject;
 class PhysicsFilteredObject;

+ 4 - 5
AnKi/Physics/PhysicsTrigger.cpp

@@ -42,8 +42,6 @@ PhysicsTrigger::~PhysicsTrigger()
 		}
 	}
 
-	m_pairs.destroy(PhysicsMemoryPool::getSingleton());
-
 	m_ghostShape.destroy();
 }
 
@@ -63,12 +61,13 @@ void PhysicsTrigger::processContacts()
 
 	if(m_contactCallback == nullptr)
 	{
-		m_pairs.destroy(PhysicsMemoryPool::getSingleton());
+		m_pairs.destroy();
 		return;
 	}
 
 	// Gather the new pairs
-	DynamicArrayRaii<PhysicsTriggerFilteredPair*> newPairs(&PhysicsWorld::getSingleton().getTempMemoryPool());
+	DynamicArray<PhysicsTriggerFilteredPair*, MemoryPoolPtrWrapper<StackMemoryPool>> newPairs(
+		&PhysicsWorld::getSingleton().getTempMemoryPool());
 	newPairs.resizeStorage(m_ghostShape->getOverlappingPairs().size());
 	for(U32 i = 0; i < U32(m_ghostShape->getOverlappingPairs().size()); ++i)
 	{
@@ -125,7 +124,7 @@ void PhysicsTrigger::processContacts()
 	}
 
 	// Store the new contacts
-	m_pairs.resize(PhysicsMemoryPool::getSingleton(), newPairs.getSize());
+	m_pairs.resize(newPairs.getSize());
 	if(m_pairs.getSize())
 	{
 		memcpy(&m_pairs[0], &newPairs[0], m_pairs.getSizeInBytes());

+ 1 - 1
AnKi/Physics/PhysicsTrigger.h

@@ -61,7 +61,7 @@ private:
 	PhysicsCollisionShapePtr m_shape;
 	ClassWrapper<btGhostObject> m_ghostShape;
 
-	DynamicArray<PhysicsTriggerFilteredPair*> m_pairs;
+	PhysicsDynamicArray<PhysicsTriggerFilteredPair*> m_pairs;
 
 	PhysicsTriggerProcessContactCallback* m_contactCallback = nullptr;
 

+ 1 - 1
AnKi/Renderer/DepthDownscale.cpp

@@ -139,7 +139,7 @@ Error DepthDownscale::initInternal()
 
 	if(!preferCompute)
 	{
-		m_fbDescrs.create(m_mipCount);
+		m_fbDescrs.resize(m_mipCount);
 		for(U32 mip = 0; mip < m_mipCount; ++mip)
 		{
 			FramebufferDescription& fbDescr = m_fbDescrs[mip];

+ 1 - 1
AnKi/Renderer/DownscaleBlur.cpp

@@ -51,7 +51,7 @@ Error DownscaleBlur::initInternal()
 	// FB descr
 	if(!preferCompute)
 	{
-		m_fbDescrs.create(m_passCount);
+		m_fbDescrs.resize(m_passCount);
 		for(U32 pass = 0; pass < m_passCount; ++pass)
 		{
 			m_fbDescrs[pass].m_colorAttachmentCount = 1;

+ 5 - 1
AnKi/Renderer/GBuffer.cpp

@@ -100,7 +100,11 @@ void GBuffer::runInThread(const RenderingContext& ctx, RenderPassWorkContext& rg
 	const U32 problemSize = ctx.m_renderQueue->m_renderables.getSize() + earlyZCount;
 	U32 start, end;
 	splitThreadedProblem(threadId, threadCount, problemSize, start, end);
-	ANKI_ASSERT(end != start);
+
+	if(end == start) [[unlikely]]
+	{
+		return;
+	}
 
 	// Set some state, leave the rest to default
 	cmdb->setViewport(0, 0, getRenderer().getInternalResolution().x(), getRenderer().getInternalResolution().y());

+ 4 - 3
AnKi/Renderer/ShadowMapping.cpp

@@ -239,8 +239,9 @@ Bool ShadowMapping::allocateAtlasTiles(U64 lightUuid, U32 faceCount, const U64*
 	return true;
 }
 
+template<typename TMemoryPool>
 void ShadowMapping::newWorkItems(const UVec4& atlasViewport, RenderQueue* lightRenderQueue, U32 renderQueueElementsLod,
-								 DynamicArrayRaii<LightToRenderTempInfo>& workItems, U32& drawcallCount) const
+								 DynamicArray<LightToRenderTempInfo, TMemoryPool>& workItems, U32& drawcallCount) const
 {
 	LightToRenderTempInfo toRender;
 	toRender.m_renderQueue = lightRenderQueue;
@@ -258,7 +259,7 @@ void ShadowMapping::processLights(RenderingContext& ctx, U32& threadCountForPass
 
 	// Vars
 	const Vec4 cameraOrigin = ctx.m_renderQueue->m_cameraTransform.getTranslationPart().xyz0();
-	DynamicArrayRaii<LightToRenderTempInfo> lightsToRender(ctx.m_tempPool);
+	DynamicArray<LightToRenderTempInfo, MemoryPoolPtrWrapper<StackMemoryPool>> lightsToRender(ctx.m_tempPool);
 	U32 drawcallCount = 0;
 
 	// First thing, allocate an empty tile for empty faces of point lights
@@ -513,7 +514,7 @@ void ShadowMapping::processLights(RenderingContext& ctx, U32& threadCountForPass
 	// Split the work that will happen in the scratch buffer
 	if(lightsToRender.getSize())
 	{
-		DynamicArrayRaii<ThreadWorkItem> workItems(ctx.m_tempPool);
+		DynamicArray<ThreadWorkItem, MemoryPoolPtrWrapper<StackMemoryPool>> workItems(ctx.m_tempPool);
 		LightToRenderTempInfo* lightToRender = lightsToRender.getBegin();
 		U32 lightToRenderDrawcallCount = lightToRender->m_drawcallCount;
 		const LightToRenderTempInfo* lightToRenderEnd = lightsToRender.getEnd();

+ 2 - 1
AnKi/Renderer/ShadowMapping.h

@@ -78,8 +78,9 @@ private:
 	void chooseDetail(const Vec4& cameraOrigin, const SpotLightQueueElement& light, U32& tileAllocatorHierarchy,
 					  U32& renderQueueElementsLod) const;
 
+	template<typename TMemoryPool>
 	void newWorkItems(const UVec4& atlasViewport, RenderQueue* lightRenderQueue, U32 renderQueueElementsLod,
-					  DynamicArrayRaii<LightToRenderTempInfo>& workItems, U32& drawcallCount) const;
+					  DynamicArray<LightToRenderTempInfo, TMemoryPool>& workItems, U32& drawcallCount) const;
 
 	void runShadowMapping(RenderPassWorkContext& rgraphCtx);
 };

+ 2 - 2
AnKi/Renderer/TileAllocator.cpp

@@ -53,7 +53,7 @@ void TileAllocator::init(U32 tileCountX, U32 tileCountY, U32 hierarchyCount, Boo
 	m_tileCountY = U16(tileCountY);
 	m_hierarchyCount = U8(hierarchyCount);
 	m_cachingEnabled = enableCaching;
-	m_firstTileIdxOfHierarchy.create(hierarchyCount + 1);
+	m_firstTileIdxOfHierarchy.resize(hierarchyCount + 1);
 
 	// Create the tile array & index ranges
 	U32 tileCount = 0;
@@ -71,7 +71,7 @@ void TileAllocator::init(U32 tileCountX, U32 tileCountY, U32 hierarchyCount, Boo
 		tileCount += hierarchyTileCountX * hierarchyTileCountY;
 	}
 	ANKI_ASSERT(tileCount >= tileCountX * tileCountY);
-	m_allTiles.create(tileCount);
+	m_allTiles.resize(tileCount);
 	m_firstTileIdxOfHierarchy[hierarchyCount] = tileCount - 1;
 
 	// Init the tiles

+ 6 - 6
AnKi/Resource/AnimationResource.cpp

@@ -16,7 +16,7 @@ Error AnimationResource::load(const ResourceFilename& filename, [[maybe_unused]]
 	Second maxTime = kMinSecond;
 
 	// Document
-	XmlDocument doc(&ResourceMemoryPool::getSingleton());
+	ResourceXmlDocument doc;
 	ANKI_CHECK(openFileParseXml(filename, doc));
 	XmlElement rootel;
 	ANKI_CHECK(doc.getChildElement("animation", rootel));
@@ -40,7 +40,7 @@ Error AnimationResource::load(const ResourceFilename& filename, [[maybe_unused]]
 		ANKI_RESOURCE_LOGE("Didn't found any channels");
 		return Error::kUserData;
 	}
-	m_channels.create(channelCount);
+	m_channels.resize(channelCount);
 
 	// For all channels
 	channelCount = 0;
@@ -51,7 +51,7 @@ Error AnimationResource::load(const ResourceFilename& filename, [[maybe_unused]]
 		// <name>
 		CString strtmp;
 		ANKI_CHECK(chEl.getAttributeText("name", strtmp));
-		ch.m_name.create(strtmp);
+		ch.m_name = strtmp;
 
 		XmlElement keysEl, keyEl;
 
@@ -64,7 +64,7 @@ Error AnimationResource::load(const ResourceFilename& filename, [[maybe_unused]]
 			U32 count = 0;
 			ANKI_CHECK(keyEl.getSiblingElementsCount(count));
 			++count;
-			ch.m_positions.create(count);
+			ch.m_positions.resize(count);
 
 			count = 0;
 			do
@@ -99,7 +99,7 @@ Error AnimationResource::load(const ResourceFilename& filename, [[maybe_unused]]
 			U32 count = 0;
 			ANKI_CHECK(keyEl.getSiblingElementsCount(count));
 			++count;
-			ch.m_rotations.create(count);
+			ch.m_rotations.resize(count);
 
 			count = 0;
 			do
@@ -134,7 +134,7 @@ Error AnimationResource::load(const ResourceFilename& filename, [[maybe_unused]]
 			U32 count = 0;
 			ANKI_CHECK(keyEl.getSiblingElementsCount(count));
 			++count;
-			ch.m_scales.create(count);
+			ch.m_scales.resize(count);
 
 			count = 0;
 			do

+ 1 - 1
AnKi/Resource/GenericResource.cpp

@@ -13,7 +13,7 @@ Error GenericResource::load(const ResourceFilename& filename, [[maybe_unused]] B
 	ANKI_CHECK(openFile(filename, file));
 
 	const U32 size = U32(file->getSize());
-	m_data.create(size);
+	m_data.resize(size);
 	ANKI_CHECK(file->read(&m_data[0], size));
 
 	return Error::kNone;

+ 3 - 3
AnKi/Resource/ImageAtlasResource.cpp

@@ -11,7 +11,7 @@ namespace anki {
 
 Error ImageAtlasResource::load(const ResourceFilename& filename, Bool async)
 {
-	XmlDocument doc(&ResourceMemoryPool::getSingleton());
+	ResourceXmlDocument doc;
 	ANKI_CHECK(openFileParseXml(filename, doc));
 
 	XmlElement rootel, el;
@@ -74,8 +74,8 @@ Error ImageAtlasResource::load(const ResourceFilename& filename, Bool async)
 	} while(subTexEl);
 
 	// Allocate
-	m_subTexNames.create(namesSize);
-	m_subTexes.create(subTexesCount);
+	m_subTexNames.resize(namesSize);
+	m_subTexes.resize(subTexesCount);
 
 	// Iterate again and populate
 	subTexesCount = 0;

+ 33 - 48
AnKi/Resource/ImageLoader.cpp

@@ -234,7 +234,7 @@ public:
 };
 
 Error ImageLoader::loadUncompressedTga(FileInterface& fs, U32& width, U32& height, U32& bpp,
-									   DynamicArray<U8, PtrSize>& data, BaseMemoryPool& pool)
+									   DynamicArray<U8, MemoryPoolPtrWrapper<BaseMemoryPool>, PtrSize>& data)
 {
 	Array<U8, 6> header6;
 
@@ -254,7 +254,7 @@ Error ImageLoader::loadUncompressedTga(FileInterface& fs, U32& width, U32& heigh
 	// Read the data
 	const PtrSize bytesPerPxl = (bpp / 8);
 	const PtrSize imageSize = bytesPerPxl * width * height;
-	data.create(pool, imageSize);
+	data.resize(imageSize);
 
 	ANKI_CHECK(fs.read(reinterpret_cast<char*>(&data[0]), imageSize));
 
@@ -270,7 +270,7 @@ Error ImageLoader::loadUncompressedTga(FileInterface& fs, U32& width, U32& heigh
 }
 
 Error ImageLoader::loadCompressedTga(FileInterface& fs, U32& width, U32& height, U32& bpp,
-									 DynamicArray<U8, PtrSize>& data, BaseMemoryPool& pool)
+									 DynamicArray<U8, MemoryPoolPtrWrapper<BaseMemoryPool>, PtrSize>& data)
 {
 	Array<U8, 6> header6;
 	ANKI_CHECK(fs.read(&header6[0], sizeof(header6)));
@@ -287,7 +287,7 @@ Error ImageLoader::loadCompressedTga(FileInterface& fs, U32& width, U32& height,
 
 	const PtrSize bytesPerPxl = (bpp / 8);
 	const PtrSize imageSize = bytesPerPxl * width * height;
-	data.create(pool, imageSize);
+	data.resize(imageSize);
 
 	const PtrSize pixelCount = height * width;
 	PtrSize currentPixel = 0;
@@ -348,7 +348,7 @@ Error ImageLoader::loadCompressedTga(FileInterface& fs, U32& width, U32& height,
 				if(currentPixel > pixelCount)
 				{
 					ANKI_RESOURCE_LOGE("Too many pixels read");
-					data.destroy(pool);
+					data.destroy();
 					return Error::kUserData;
 				}
 			}
@@ -358,8 +358,8 @@ Error ImageLoader::loadCompressedTga(FileInterface& fs, U32& width, U32& height,
 	return Error::kNone;
 }
 
-Error ImageLoader::loadTga(FileInterface& fs, U32& width, U32& height, U32& bpp, DynamicArray<U8, PtrSize>& data,
-						   BaseMemoryPool& pool)
+Error ImageLoader::loadTga(FileInterface& fs, U32& width, U32& height, U32& bpp,
+						   DynamicArray<U8, MemoryPoolPtrWrapper<BaseMemoryPool>, PtrSize>& data)
 {
 	Array<Char, 12> myTgaHeader;
 
@@ -367,11 +367,11 @@ Error ImageLoader::loadTga(FileInterface& fs, U32& width, U32& height, U32& bpp,
 
 	if(memcmp(kTgaHeaderUncompressed, &myTgaHeader[0], sizeof(myTgaHeader)) == 0)
 	{
-		ANKI_CHECK(loadUncompressedTga(fs, width, height, bpp, data, pool));
+		ANKI_CHECK(loadUncompressedTga(fs, width, height, bpp, data));
 	}
 	else if(std::memcmp(kTgaHeaderCompressed, &myTgaHeader[0], sizeof(myTgaHeader)) == 0)
 	{
-		ANKI_CHECK(loadCompressedTga(fs, width, height, bpp, data, pool));
+		ANKI_CHECK(loadCompressedTga(fs, width, height, bpp, data));
 	}
 	else
 	{
@@ -390,10 +390,10 @@ Error ImageLoader::loadTga(FileInterface& fs, U32& width, U32& height, U32& bpp,
 
 Error ImageLoader::loadAnkiImage(FileInterface& file, U32 maxImageSize,
 								 ImageBinaryDataCompression& preferredCompression,
-								 DynamicArray<ImageLoaderSurface>& surfaces, DynamicArray<ImageLoaderVolume>& volumes,
-								 BaseMemoryPool& pool, U32& width, U32& height, U32& depth, U32& layerCount,
-								 U32& mipCount, ImageBinaryType& imageType, ImageBinaryColorFormat& colorFormat,
-								 UVec2& astcBlockSize)
+								 DynamicArray<ImageLoaderSurface, MemoryPoolPtrWrapper<BaseMemoryPool>>& surfaces,
+								 DynamicArray<ImageLoaderVolume, MemoryPoolPtrWrapper<BaseMemoryPool>>& volumes,
+								 U32& width, U32& height, U32& depth, U32& layerCount, U32& mipCount,
+								 ImageBinaryType& imageType, ImageBinaryColorFormat& colorFormat, UVec2& astcBlockSize)
 {
 	//
 	// Read and check the header
@@ -571,11 +571,11 @@ Error ImageLoader::loadAnkiImage(FileInterface& file, U32 maxImageSize,
 					// Check if this mipmap can be skipped because of size
 					if(max(mipWidth, mipHeight) <= maxImageSize || mip == header.m_mipmapCount - 1)
 					{
-						ImageLoaderSurface& surf = *surfaces.emplaceBack(pool);
+						ImageLoaderSurface& surf = *surfaces.emplaceBack(surfaces.getMemoryPool());
 						surf.m_width = mipWidth;
 						surf.m_height = mipHeight;
 
-						surf.m_data.create(pool, dataSize);
+						surf.m_data.resize(dataSize);
 						ANKI_CHECK(file.read(&surf.m_data[0], dataSize));
 
 						mipCount = max(header.m_mipmapCount - mip, mipCount);
@@ -608,12 +608,12 @@ Error ImageLoader::loadAnkiImage(FileInterface& file, U32 maxImageSize,
 			// Check if this mipmap can be skipped because of size
 			if(max(max(mipWidth, mipHeight), mipDepth) <= maxImageSize || mip == header.m_mipmapCount - 1)
 			{
-				ImageLoaderVolume& vol = *volumes.emplaceBack(pool);
+				ImageLoaderVolume& vol = *volumes.emplaceBack(surfaces.getMemoryPool());
 				vol.m_width = mipWidth;
 				vol.m_height = mipHeight;
 				vol.m_depth = mipDepth;
 
-				vol.m_data.create(pool, dataSize);
+				vol.m_data.resize(dataSize);
 				ANKI_CHECK(file.read(&vol.m_data[0], dataSize));
 
 				mipCount = max(header.m_mipmapCount - mip, mipCount);
@@ -636,13 +636,13 @@ Error ImageLoader::loadAnkiImage(FileInterface& file, U32 maxImageSize,
 	return Error::kNone;
 }
 
-Error ImageLoader::loadStb(Bool isFloat, FileInterface& fs, U32& width, U32& height, DynamicArray<U8, PtrSize>& data,
-						   BaseMemoryPool& pool)
+Error ImageLoader::loadStb(Bool isFloat, FileInterface& fs, U32& width, U32& height,
+						   DynamicArray<U8, MemoryPoolPtrWrapper<BaseMemoryPool>, PtrSize>& data)
 {
 	// Read the file
-	DynamicArrayRaii<U8, PtrSize> fileData(&pool);
+	DynamicArray<U8, MemoryPoolPtrWrapper<BaseMemoryPool>, PtrSize> fileData(data.getMemoryPool());
 	const PtrSize fileSize = fs.getSize();
-	fileData.create(fileSize);
+	fileData.resize(fileSize);
 	ANKI_CHECK(fs.read(&fileData[0], fileSize));
 
 	// Use STB to read the image
@@ -668,7 +668,7 @@ Error ImageLoader::loadStb(Bool isFloat, FileInterface& fs, U32& width, U32& hei
 	width = U32(stbw);
 	height = U32(stbh);
 	const U32 componentSize = (isFloat) ? sizeof(F32) : sizeof(U8);
-	data.create(pool, width * height * 4 * componentSize);
+	data.resize(width * height * 4 * componentSize);
 	memcpy(&data[0], stbdata, data.getSize());
 
 	// Cleanup
@@ -708,7 +708,7 @@ Error ImageLoader::load(const CString& filename, U32 maxImageSize)
 Error ImageLoader::loadInternal(FileInterface& file, const CString& filename, U32 maxImageSize)
 {
 	// get the extension
-	StringRaii ext(m_pool);
+	String ext;
 	getFilepathExtension(filename, ext);
 
 	if(ext.isEmpty())
@@ -717,19 +717,21 @@ Error ImageLoader::loadInternal(FileInterface& file, const CString& filename, U3
 		return Error::kUserData;
 	}
 
+	MemoryPoolPtrWrapper<BaseMemoryPool> pool = m_surfaces.getMemoryPool();
+
 	// load from this extension
 	m_imageType = ImageBinaryType::k2D;
 	m_compression = ImageBinaryDataCompression::kRaw;
 
 	if(ext == "tga")
 	{
-		m_surfaces.create(*m_pool, 1);
+		m_surfaces.resize(1, pool);
 
 		m_mipmapCount = 1;
 		m_depth = 1;
 		m_layerCount = 1;
 		U32 bpp = 0;
-		ANKI_CHECK(loadTga(file, m_surfaces[0].m_width, m_surfaces[0].m_height, bpp, m_surfaces[0].m_data, *m_pool));
+		ANKI_CHECK(loadTga(file, m_surfaces[0].m_width, m_surfaces[0].m_height, bpp, m_surfaces[0].m_data));
 
 		m_width = m_surfaces[0].m_width;
 		m_height = m_surfaces[0].m_height;
@@ -755,33 +757,33 @@ Error ImageLoader::loadInternal(FileInterface& file, const CString& filename, U3
 		m_compression = ImageBinaryDataCompression::kS3tc;
 #endif
 
-		ANKI_CHECK(loadAnkiImage(file, maxImageSize, m_compression, m_surfaces, m_volumes, *m_pool, m_width, m_height,
-								 m_depth, m_layerCount, m_mipmapCount, m_imageType, m_colorFormat, m_astcBlockSize));
+		ANKI_CHECK(loadAnkiImage(file, maxImageSize, m_compression, m_surfaces, m_volumes, m_width, m_height, m_depth,
+								 m_layerCount, m_mipmapCount, m_imageType, m_colorFormat, m_astcBlockSize));
 	}
 	else if(ext == "png" || ext == "jpg")
 	{
-		m_surfaces.create(*m_pool, 1);
+		m_surfaces.resize(1, pool);
 
 		m_mipmapCount = 1;
 		m_depth = 1;
 		m_layerCount = 1;
 		m_colorFormat = ImageBinaryColorFormat::kRgba8;
 
-		ANKI_CHECK(loadStb(false, file, m_surfaces[0].m_width, m_surfaces[0].m_height, m_surfaces[0].m_data, *m_pool));
+		ANKI_CHECK(loadStb(false, file, m_surfaces[0].m_width, m_surfaces[0].m_height, m_surfaces[0].m_data));
 
 		m_width = m_surfaces[0].m_width;
 		m_height = m_surfaces[0].m_height;
 	}
 	else if(ext == "hdr")
 	{
-		m_surfaces.create(*m_pool, 1);
+		m_surfaces.resize(1, pool);
 
 		m_mipmapCount = 1;
 		m_depth = 1;
 		m_layerCount = 1;
 		m_colorFormat = ImageBinaryColorFormat::kRgbaFloat;
 
-		ANKI_CHECK(loadStb(true, file, m_surfaces[0].m_width, m_surfaces[0].m_height, m_surfaces[0].m_data, *m_pool));
+		ANKI_CHECK(loadStb(true, file, m_surfaces[0].m_width, m_surfaces[0].m_height, m_surfaces[0].m_data));
 
 		m_width = m_surfaces[0].m_width;
 		m_height = m_surfaces[0].m_height;
@@ -829,21 +831,4 @@ const ImageLoaderVolume& ImageLoader::getVolume(U32 level) const
 	return m_volumes[level];
 }
 
-void ImageLoader::destroy()
-{
-	for(ImageLoaderSurface& surf : m_surfaces)
-	{
-		surf.m_data.destroy(*m_pool);
-	}
-
-	m_surfaces.destroy(*m_pool);
-
-	for(ImageLoaderVolume& v : m_volumes)
-	{
-		v.m_data.destroy(*m_pool);
-	}
-
-	m_volumes.destroy(*m_pool);
-}
-
 } // end namespace anki

+ 27 - 21
AnKi/Resource/ImageLoader.h

@@ -18,7 +18,12 @@ class ImageLoaderSurface
 public:
 	U32 m_width;
 	U32 m_height;
-	DynamicArray<U8, PtrSize> m_data;
+	DynamicArray<U8, MemoryPoolPtrWrapper<BaseMemoryPool>, PtrSize> m_data;
+
+	ImageLoaderSurface(MemoryPoolPtrWrapper<BaseMemoryPool> pool)
+		: m_data(pool)
+	{
+	}
 };
 
 /// An image volume
@@ -29,7 +34,12 @@ public:
 	U32 m_width;
 	U32 m_height;
 	U32 m_depth;
-	DynamicArray<U8, PtrSize> m_data;
+	DynamicArray<U8, MemoryPoolPtrWrapper<BaseMemoryPool>, PtrSize> m_data;
+
+	ImageLoaderVolume(MemoryPoolPtrWrapper<BaseMemoryPool> pool)
+		: m_data(pool)
+	{
+	}
 };
 
 /// Loads bitmaps from regular system files or resource files. Supported formats are .tga and .ankitex.
@@ -37,15 +47,13 @@ class ImageLoader
 {
 public:
 	ImageLoader(BaseMemoryPool* pool)
-		: m_pool(pool)
+		: m_surfaces(pool)
+		, m_volumes(pool)
 	{
 		ANKI_ASSERT(pool);
 	}
 
-	~ImageLoader()
-	{
-		destroy();
-	}
+	~ImageLoader() = default;
 
 	ImageBinaryColorFormat getColorFormat() const
 	{
@@ -115,13 +123,11 @@ private:
 	class RsrcFile;
 	class SystemFile;
 
-	BaseMemoryPool* m_pool = nullptr;
-
 	/// [mip][depth or face or layer]. Loader doesn't support cube arrays ATM so face and layer won't be used at the
 	/// same time.
-	DynamicArray<ImageLoaderSurface> m_surfaces;
+	DynamicArray<ImageLoaderSurface, MemoryPoolPtrWrapper<BaseMemoryPool>> m_surfaces;
 
-	DynamicArray<ImageLoaderVolume> m_volumes;
+	DynamicArray<ImageLoaderVolume, MemoryPoolPtrWrapper<BaseMemoryPool>> m_volumes;
 
 	U32 m_mipmapCount = 0;
 	U32 m_width = 0;
@@ -136,22 +142,22 @@ private:
 	void destroy();
 
 	static Error loadUncompressedTga(FileInterface& fs, U32& width, U32& height, U32& bpp,
-									 DynamicArray<U8, PtrSize>& data, BaseMemoryPool& pool);
+									 DynamicArray<U8, MemoryPoolPtrWrapper<BaseMemoryPool>, PtrSize>& data);
 
 	static Error loadCompressedTga(FileInterface& fs, U32& width, U32& height, U32& bpp,
-								   DynamicArray<U8, PtrSize>& data, BaseMemoryPool& pool);
+								   DynamicArray<U8, MemoryPoolPtrWrapper<BaseMemoryPool>, PtrSize>& data);
 
-	static Error loadTga(FileInterface& fs, U32& width, U32& height, U32& bpp, DynamicArray<U8, PtrSize>& data,
-						 BaseMemoryPool& pool);
+	static Error loadTga(FileInterface& fs, U32& width, U32& height, U32& bpp,
+						 DynamicArray<U8, MemoryPoolPtrWrapper<BaseMemoryPool>, PtrSize>& data);
 
-	static Error loadStb(Bool isFloat, FileInterface& fs, U32& width, U32& height, DynamicArray<U8, PtrSize>& data,
-						 BaseMemoryPool& pool);
+	static Error loadStb(Bool isFloat, FileInterface& fs, U32& width, U32& height,
+						 DynamicArray<U8, MemoryPoolPtrWrapper<BaseMemoryPool>, PtrSize>& data);
 
 	static Error loadAnkiImage(FileInterface& file, U32 maxImageSize, ImageBinaryDataCompression& preferredCompression,
-							   DynamicArray<ImageLoaderSurface>& surfaces, DynamicArray<ImageLoaderVolume>& volumes,
-							   BaseMemoryPool& pool, U32& width, U32& height, U32& depth, U32& layerCount,
-							   U32& mipCount, ImageBinaryType& imageType, ImageBinaryColorFormat& colorFormat,
-							   UVec2& astcBlockSize);
+							   DynamicArray<ImageLoaderSurface, MemoryPoolPtrWrapper<BaseMemoryPool>>& surfaces,
+							   DynamicArray<ImageLoaderVolume, MemoryPoolPtrWrapper<BaseMemoryPool>>& volumes,
+							   U32& width, U32& height, U32& depth, U32& layerCount, U32& mipCount,
+							   ImageBinaryType& imageType, ImageBinaryColorFormat& colorFormat, UVec2& astcBlockSize);
 
 	Error loadInternal(FileInterface& file, const CString& filename, U32 maxImageSize);
 };

+ 1 - 1
AnKi/Resource/ImageResource.cpp

@@ -56,7 +56,7 @@ Error ImageResource::load(const ResourceFilename& filename, Bool async)
 	}
 	ImageLoader& loader = ctx->m_loader;
 
-	StringRaii filenameExt(&ResourceMemoryPool::getSingleton());
+	String filenameExt;
 	getFilepathFilename(filename, filenameExt);
 
 	TextureInitInfo init(filenameExt);

+ 4 - 4
AnKi/Resource/MaterialResource.cpp

@@ -139,7 +139,7 @@ const MaterialVariable* MaterialResource::tryFindVariableInternal(CString name)
 
 Error MaterialResource::load(const ResourceFilename& filename, Bool async)
 {
-	XmlDocument doc(&ResourceMemoryPool::getSingleton());
+	ResourceXmlDocument doc;
 	XmlElement el;
 	ANKI_CHECK(openFileParseXml(filename, doc));
 
@@ -318,7 +318,7 @@ Error MaterialResource::createVars(Program& prog)
 
 				// All good, add it
 				var = m_vars.emplaceBack();
-				var->m_name.create(memberName);
+				var->m_name = memberName;
 				var->m_offsetInLocalUniforms = offsetof;
 				var->m_dataType = member.m_type;
 
@@ -409,7 +409,7 @@ Error MaterialResource::createVars(Program& prog)
 
 				// All good, add it
 				var = m_vars.emplaceBack();
-				var->m_name.create(opaqueName);
+				var->m_name = opaqueName;
 				var->m_opaqueBinding = opaque.m_binding;
 				var->m_dataType = opaque.m_type;
 			}
@@ -434,7 +434,7 @@ Error MaterialResource::parseMutators(XmlElement mutatorsEl, Program& prog)
 	ANKI_CHECK(mutatorEl.getSiblingElementsCount(mutatorCount));
 	++mutatorCount;
 	ANKI_ASSERT(mutatorCount > 0);
-	prog.m_partialMutation.create(mutatorCount);
+	prog.m_partialMutation.resize(mutatorCount);
 	mutatorCount = 0;
 
 	do

+ 5 - 9
AnKi/Resource/MeshBinaryLoader.cpp

@@ -8,11 +8,6 @@
 
 namespace anki {
 
-MeshBinaryLoader::~MeshBinaryLoader()
-{
-	m_subMeshes.destroy(*m_pool);
-}
-
 Error MeshBinaryLoader::load(const ResourceFilename& filename)
 {
 	// Load header + submeshes
@@ -26,7 +21,7 @@ Error MeshBinaryLoader::load(const ResourceFilename& filename)
 
 Error MeshBinaryLoader::loadSubmeshes()
 {
-	m_subMeshes.create(*m_pool, m_header.m_subMeshCount);
+	m_subMeshes.resize(m_header.m_subMeshCount);
 	ANKI_CHECK(m_file->read(&m_subMeshes[0], m_subMeshes.getSizeInBytes()));
 
 	// Checks
@@ -299,8 +294,8 @@ Error MeshBinaryLoader::storeIndicesAndPosition(U32 lod, ResourceDynamicArray<U3
 		indices.resize(m_header.m_totalIndexCounts[lod]);
 
 		// Store to staging buff
-		DynamicArrayRaii<U8, PtrSize> staging(m_pool);
-		staging.create(getIndexBufferSize(lod));
+		DynamicArray<U8, MemoryPoolPtrWrapper<BaseMemoryPool>, PtrSize> staging(m_subMeshes.getMemoryPool());
+		staging.resize(getIndexBufferSize(lod));
 		ANKI_CHECK(storeIndexBuffer(lod, &staging[0], staging.getSizeInBytes()));
 
 		// Copy from staging
@@ -314,7 +309,8 @@ Error MeshBinaryLoader::storeIndicesAndPosition(U32 lod, ResourceDynamicArray<U3
 	// Store positions
 	{
 		const MeshBinaryVertexAttribute& attrib = m_header.m_vertexAttributes[VertexStreamId::kPosition];
-		DynamicArrayRaii<U16Vec4> tempPositions(m_header.m_totalVertexCounts[lod], m_pool);
+		DynamicArray<U16Vec4, MemoryPoolPtrWrapper<BaseMemoryPool>> tempPositions(m_subMeshes.getMemoryPool());
+		tempPositions.resize(m_header.m_totalVertexCounts[lod]);
 		static_assert(kMeshRelatedVertexStreamFormats[VertexStreamId::kPosition] == Format::kR16G16B16A16_Unorm,
 					  "Incorrect format");
 		ANKI_CHECK(storeVertexBuffer(lod, attrib.m_bufferIndex, &tempPositions[0], tempPositions.getSizeInBytes()));

+ 3 - 4
AnKi/Resource/MeshBinaryLoader.h

@@ -27,12 +27,12 @@ class MeshBinaryLoader
 {
 public:
 	MeshBinaryLoader(BaseMemoryPool* pool)
-		: m_pool(pool)
+		: m_subMeshes(pool)
 	{
 		ANKI_ASSERT(pool);
 	}
 
-	~MeshBinaryLoader();
+	~MeshBinaryLoader() = default;
 
 	Error load(const ResourceFilename& filename);
 
@@ -55,12 +55,11 @@ public:
 	}
 
 private:
-	BaseMemoryPool* m_pool = nullptr;
 	ResourceFilePtr m_file;
 
 	MeshBinaryHeader m_header;
 
-	DynamicArray<MeshBinarySubMesh> m_subMeshes;
+	DynamicArray<MeshBinarySubMesh, MemoryPoolPtrWrapper<BaseMemoryPool>> m_subMeshes;
 
 	Bool isLoaded() const
 	{

+ 3 - 3
AnKi/Resource/MeshResource.cpp

@@ -71,7 +71,7 @@ Error MeshResource::load(const ResourceFilename& filename, Bool async)
 	LoadContext* ctx;
 	LoadContext localCtx(this);
 
-	StringRaii basename(&ResourceMemoryPool::getSingleton());
+	String basename;
 	getFilepathFilename(filename, basename);
 
 	const Bool rayTracingEnabled = GrManager::getSingleton().getDeviceCapabilities().m_rayTracingEnabled;
@@ -100,7 +100,7 @@ Error MeshResource::load(const ResourceFilename& filename, Bool async)
 	m_positionsTranslation = Vec3(&header.m_vertexAttributes[VertexStreamId::kPosition].m_translation[0]);
 
 	// Submeshes
-	m_subMeshes.create(header.m_subMeshCount);
+	m_subMeshes.resize(header.m_subMeshCount);
 	for(U32 i = 0; i < m_subMeshes.getSize(); ++i)
 	{
 		m_subMeshes[i].m_firstIndices = loader.getSubMeshes()[i].m_firstIndices;
@@ -110,7 +110,7 @@ Error MeshResource::load(const ResourceFilename& filename, Bool async)
 	}
 
 	// LODs
-	m_lods.create(header.m_lodCount);
+	m_lods.resize(header.m_lodCount);
 	for(I32 l = I32(header.m_lodCount - 1); l >= 0; --l)
 	{
 		Lod& lod = m_lods[l];

+ 2 - 3
AnKi/Resource/ModelResource.cpp

@@ -113,8 +113,7 @@ Error ModelResource::load(const ResourceFilename& filename, Bool async)
 {
 	// Load
 	//
-	XmlElement el;
-	XmlDocument doc(&ResourceMemoryPool::getSingleton());
+	ResourceXmlDocument doc;
 	ANKI_CHECK(openFileParseXml(filename, doc));
 
 	XmlElement rootEl;
@@ -143,7 +142,7 @@ Error ModelResource::load(const ResourceFilename& filename, Bool async)
 		return Error::kUserData;
 	}
 
-	m_modelPatches.create(count);
+	m_modelPatches.resize(count);
 
 	count = 0;
 	ANKI_CHECK(modelPatchesEl.getChildElement("modelPatch", modelPatchEl));

+ 1 - 1
AnKi/Resource/ParticleEmitterResource.cpp

@@ -26,7 +26,7 @@ Error getXmlVal(const XmlElement& el, const CString& tag, Vec3& out, Bool& found
 
 Error ParticleEmitterResource::load(const ResourceFilename& filename, Bool async)
 {
-	XmlDocument doc(&ResourceMemoryPool::getSingleton());
+	ResourceXmlDocument doc;
 	ANKI_CHECK(openFileParseXml(filename, doc));
 	XmlElement rootEl; // Root element
 	ANKI_CHECK(doc.getChildElement("particleEmitter", rootEl));

+ 15 - 16
AnKi/Resource/ResourceFilesystem.cpp

@@ -136,7 +136,7 @@ public:
 	Error readAllText(ResourceString& out) override
 	{
 		ANKI_ASSERT(m_size);
-		out.create('?', m_size);
+		out = ResourceString('?', m_size);
 		return read(&out[0], m_size);
 	}
 
@@ -200,11 +200,11 @@ Error ResourceFilesystem::init()
 	// Workaround the fact that : is used in drives in Windows
 #if ANKI_OS_WINDOWS
 	ResourceStringList paths2;
-	StringListRaii::Iterator it = paths.getBegin();
+	ResourceStringList::Iterator it = paths.getBegin();
 	while(it != paths.getEnd())
 	{
-		const String& s = *it;
-		StringListRaii::Iterator it2 = it + 1;
+		const ResourceString& s = *it;
+		ResourceStringList::Iterator it2 = it + 1;
 		if(s.getLength() == 1 && (s[0] >= 'a' && s[0] <= 'z') || (s[0] >= 'A' && s[0] <= 'Z') && it2 != paths.getEnd())
 		{
 			paths2.pushBackSprintf("%s:%s", s.cstr(), it2->cstr());
@@ -249,7 +249,7 @@ Error ResourceFilesystem::addNewPath(const CString& filepath, const ResourceStri
 	constexpr CString extension(".ankizip");
 
 	auto rejectPath = [&](CString p) -> Bool {
-		for(const String& s : excludedStrings)
+		for(const ResourceString& s : excludedStrings)
 		{
 			if(p.find(s) != CString::kNpos)
 			{
@@ -310,16 +310,15 @@ Error ResourceFilesystem::addNewPath(const CString& filepath, const ResourceStri
 	{
 		// It's simple directory
 
-		ANKI_CHECK(walkDirectoryTree(filepath, ResourceMemoryPool::getSingleton(),
-									 [&](const CString& fname, Bool isDir) -> Error {
-										 if(!isDir && !rejectPath(fname))
-										 {
-											 path.m_files.pushBackSprintf("%s", fname.cstr());
-											 ++fileCount;
-										 }
+		ANKI_CHECK(walkDirectoryTree(filepath, [&](const CString& fname, Bool isDir) -> Error {
+			if(!isDir && !rejectPath(fname))
+			{
+				path.m_files.pushBackSprintf("%s", fname.cstr());
+				++fileCount;
+			}
 
-										 return Error::kNone;
-									 }));
+			return Error::kNone;
+		}));
 	}
 
 	ANKI_ASSERT(path.m_files.getSize() == fileCount);
@@ -337,7 +336,7 @@ Error ResourceFilesystem::addNewPath(const CString& filepath, const ResourceStri
 
 	if(false)
 	{
-		for(const String& s : m_paths.getFront().m_files)
+		for(const ResourceString& s : m_paths.getFront().m_files)
 		{
 			printf("%s\n", s.cstr());
 		}
@@ -372,7 +371,7 @@ Error ResourceFilesystem::openFileInternal(const ResourceFilename& filename, Res
 	// Search for the fname in reverse order
 	for(const Path& p : m_paths)
 	{
-		for(const String& pfname : p.m_files)
+		for(const ResourceString& pfname : p.m_files)
 		{
 			if(pfname != filename)
 			{

+ 1 - 1
AnKi/Resource/ResourceFilesystem.h

@@ -99,7 +99,7 @@ public:
 	{
 		for(const Path& path : m_paths)
 		{
-			for(const String& fname : path.m_files)
+			for(const ResourceString& fname : path.m_files)
 			{
 				ANKI_CHECK(func(fname.toCString()));
 			}

+ 1 - 1
AnKi/Resource/ResourceObject.cpp

@@ -26,7 +26,7 @@ Error ResourceObject::openFileReadAllText(const CString& filename, ResourceStrin
 	return Error::kNone;
 }
 
-Error ResourceObject::openFileParseXml(const CString& filename, XmlDocument& xml)
+Error ResourceObject::openFileParseXml(const CString& filename, ResourceXmlDocument& xml)
 {
 	ResourceString txt;
 	ANKI_CHECK(openFileReadAllText(filename, txt));

+ 2 - 6
AnKi/Resource/ResourceObject.h

@@ -12,10 +12,6 @@
 
 namespace anki {
 
-// Forward
-class XmlDocument;
-class GrManager;
-
 /// @addtogroup resource
 /// @{
 
@@ -55,7 +51,7 @@ public:
 	ANKI_INTERNAL void setFilename(const CString& fname)
 	{
 		ANKI_ASSERT(m_fname.isEmpty());
-		m_fname.create(fname);
+		m_fname = fname;
 	}
 
 	ANKI_INTERNAL void setUuid(U64 uuid)
@@ -75,7 +71,7 @@ public:
 
 	ANKI_INTERNAL Error openFileReadAllText(const ResourceFilename& filename, ResourceString& file);
 
-	ANKI_INTERNAL Error openFileParseXml(const ResourceFilename& filename, XmlDocument& xml);
+	ANKI_INTERNAL Error openFileParseXml(const ResourceFilename& filename, ResourceXmlDocument& xml);
 
 private:
 	mutable Atomic<I32> m_refcount = {0};

+ 3 - 3
AnKi/Resource/ShaderProgramResource.cpp

@@ -47,7 +47,7 @@ Error ShaderProgramResource::load(const ResourceFilename& filename, [[maybe_unus
 	// Create the mutators
 	if(binary.m_mutators.getSize() > 0)
 	{
-		m_mutators.create(binary.m_mutators.getSize());
+		m_mutators.resize(binary.m_mutators.getSize());
 
 		for(U32 i = 0; i < binary.m_mutators.getSize(); ++i)
 		{
@@ -89,7 +89,7 @@ Error ShaderProgramResource::load(const ResourceFilename& filename, [[maybe_unus
 
 		// Create new one
 		ShaderProgramResourceConstant& in = *m_consts.emplaceBack();
-		in.m_name.create(name);
+		in.m_name = name;
 		in.m_index = m_consts.getSize() - 1;
 
 		if(componentCount == 1)
@@ -361,7 +361,7 @@ ShaderProgramResource::createNewVariant(const ShaderProgramResourceVariantInitIn
 	if(!!(m_shaderStages & (ShaderTypeBit::kAllGraphics | ShaderTypeBit::kCompute)))
 	{
 		// Create the program name
-		StringRaii progName(&ResourceMemoryPool::getSingleton());
+		String progName;
 		getFilepathFilename(getFilename(), progName);
 		char* cprogName = const_cast<char*>(progName.cstr());
 		if(progName.getLength() > kMaxGrObjectNameLength)

+ 6 - 6
AnKi/Resource/ShaderProgramResourceSystem.cpp

@@ -20,7 +20,7 @@ namespace anki {
 U64 ShaderProgramRaytracingLibrary::generateShaderGroupGroupHash(CString resourceFilename, U64 mutationHash)
 {
 	ANKI_ASSERT(resourceFilename.getLength() > 0);
-	StringRaii basename(&ResourceMemoryPool::getSingleton());
+	String basename;
 	getFilepathFilename(resourceFilename, basename);
 	const U64 hash = appendHash(basename.cstr(), basename.getLength(), mutationHash);
 	return hash;
@@ -145,7 +145,7 @@ Error ShaderProgramResourceSystem::createRayTracingPrograms(
 
 	ANKI_CHECK(ResourceManager::getSingleton().getFilesystem().iterateAllFilenames([&](CString filename) -> Error {
 		// Check file extension
-		StringRaii extension(&ResourceMemoryPool::getSingleton());
+		String extension;
 		getFilepathExtension(filename, extension);
 		const Char binExtension[] = "ankiprogbin";
 		if(extension.getLength() != sizeof(binExtension) - 1 || extension != binExtension)
@@ -179,7 +179,7 @@ Error ShaderProgramResourceSystem::createRayTracingPrograms(
 		}
 
 		// Create the program name
-		StringRaii progName(&ResourceMemoryPool::getSingleton());
+		String progName;
 		getFilepathFilename(filename, progName);
 
 		// Find or create the lib
@@ -198,7 +198,7 @@ Error ShaderProgramResourceSystem::createRayTracingPrograms(
 			{
 				libs.emplaceBack();
 				lib = &libs.getBack();
-				lib->m_name.create(CString(&binary.m_libraryName[0]));
+				lib->m_name = CString(&binary.m_libraryName[0]);
 			}
 		}
 
@@ -356,7 +356,7 @@ Error ShaderProgramResourceSystem::createRayTracingPrograms(
 	// See the ShaderProgram class for info.
 	if(libs.getSize() != 0)
 	{
-		outLibs.create(libs.getSize());
+		outLibs.resize(libs.getSize());
 
 		for(U32 libIdx = 0; libIdx < libs.getSize(); ++libIdx)
 		{
@@ -376,7 +376,7 @@ Error ShaderProgramResourceSystem::createRayTracingPrograms(
 				return Error::kUserData;
 			}
 
-			outLib.m_libraryName.create(inLib.m_name);
+			outLib.m_libraryName = inLib.m_name;
 			outLib.m_rayTypeCount = inLib.m_rayTypeCount;
 
 			ResourceDynamicArray<RayTracingHitGroup> initInfoHitGroups;

+ 3 - 3
AnKi/Resource/SkeletonResource.cpp

@@ -12,7 +12,7 @@ namespace anki {
 
 Error SkeletonResource::load(const ResourceFilename& filename, [[maybe_unused]] Bool async)
 {
-	XmlDocument doc(&ResourceMemoryPool::getSingleton());
+	ResourceXmlDocument doc;
 	ANKI_CHECK(openFileParseXml(filename, doc));
 
 	XmlElement rootEl;
@@ -28,7 +28,7 @@ Error SkeletonResource::load(const ResourceFilename& filename, [[maybe_unused]]
 	ANKI_CHECK(boneEl.getSiblingElementsCount(boneCount));
 	++boneCount;
 
-	m_bones.create(boneCount);
+	m_bones.resize(boneCount);
 
 	ResourceStringList boneParents;
 
@@ -42,7 +42,7 @@ Error SkeletonResource::load(const ResourceFilename& filename, [[maybe_unused]]
 		// name
 		CString name;
 		ANKI_CHECK(boneEl.getAttributeText("name", name));
-		bone.m_name.create(name);
+		bone.m_name = name;
 
 		// transform
 		ANKI_CHECK(boneEl.getAttributeNumbers("transform", bone.m_transform));

+ 1 - 1
AnKi/Resource/SkeletonResource.h

@@ -96,7 +96,7 @@ public:
 	/// Load file
 	Error load(const ResourceFilename& filename, Bool async);
 
-	const DynamicArray<Bone>& getBones() const
+	ConstWeakArray<Bone> getBones() const
 	{
 		return m_bones;
 	}

+ 4 - 9
AnKi/Resource/TransferGpuAllocator.cpp

@@ -38,11 +38,6 @@ TransferGpuAllocator::TransferGpuAllocator()
 
 TransferGpuAllocator::~TransferGpuAllocator()
 {
-	for(Pool& pool : m_pools)
-	{
-		ANKI_ASSERT(pool.m_pendingReleases == 0);
-		pool.m_fences.destroy(ResourceMemoryPool::getSingleton());
-	}
 }
 
 Error TransferGpuAllocator::init(PtrSize maxSize)
@@ -97,7 +92,7 @@ Error TransferGpuAllocator::allocate(PtrSize size, TransferGpuAllocatorHandle& h
 				const Bool done = fence->clientWait(kMaxFenceWaitTime);
 				if(done)
 				{
-					pool->m_fences.popFront(ResourceMemoryPool::getSingleton());
+					pool->m_fences.popFront();
 				}
 			}
 		}
@@ -124,14 +119,14 @@ Error TransferGpuAllocator::allocate(PtrSize size, TransferGpuAllocatorHandle& h
 	// decriptors in Linux and we don't want to exceed the process' limit of max open file descriptors
 	for(Pool& p : m_pools)
 	{
-		List<FencePtr>::Iterator it = p.m_fences.getBegin();
+		ResourceList<FencePtr>::Iterator it = p.m_fences.getBegin();
 		while(it != p.m_fences.getEnd())
 		{
 			const Bool fenceDone = (*it)->clientWait(0.0);
 			if(fenceDone)
 			{
 				auto nextIt = it + 1;
-				p.m_fences.erase(ResourceMemoryPool::getSingleton(), it);
+				p.m_fences.erase(it);
 				it = nextIt;
 			}
 			else
@@ -154,7 +149,7 @@ void TransferGpuAllocator::release(TransferGpuAllocatorHandle& handle, FencePtr
 	{
 		LockGuard<Mutex> lock(m_mtx);
 
-		pool.m_fences.pushBack(ResourceMemoryPool::getSingleton(), fence);
+		pool.m_fences.pushBack(fence);
 
 		ANKI_ASSERT(pool.m_pendingReleases > 0);
 		--pool.m_pendingReleases;

+ 1 - 1
AnKi/Resource/TransferGpuAllocator.h

@@ -193,7 +193,7 @@ private:
 	{
 	public:
 		StackAllocatorBuilder<Chunk, StackAllocatorBuilderInterface, DummyMutex> m_stackAlloc;
-		List<FencePtr> m_fences;
+		ResourceList<FencePtr> m_fences;
 		U32 m_pendingReleases = 0;
 	};
 

+ 9 - 7
AnKi/Scene/Components/ModelComponent.cpp

@@ -183,7 +183,8 @@ Error ModelComponent::update(SceneComponentUpdateInfo& info, Bool& updated)
 		}
 
 		// Upload the uniforms
-		DynamicArrayRaii<U32> allUniforms(U32(m_gpuSceneUniforms.m_size / 4), info.m_framePool);
+		DynamicArray<U32, MemoryPoolPtrWrapper<StackMemoryPool>> allUniforms(info.m_framePool);
+		allUniforms.resize(U32(m_gpuSceneUniforms.m_size / 4));
 		U32 count = 0;
 		for(U32 i = 0; i < modelPatchCount; ++i)
 		{
@@ -238,7 +239,7 @@ Error ModelComponent::update(SceneComponentUpdateInfo& info, Bool& updated)
 	return Error::kNone;
 }
 
-void ModelComponent::setupRenderableQueueElements(U32 lod, RenderingTechnique technique, StackMemoryPool& tmpPool,
+void ModelComponent::setupRenderableQueueElements(U32 lod, RenderingTechnique technique,
 												  WeakArray<RenderableQueueElement>& outRenderables) const
 {
 	ANKI_ASSERT(isEnabled());
@@ -263,8 +264,9 @@ void ModelComponent::setupRenderableQueueElements(U32 lod, RenderingTechnique te
 		return;
 	}
 
-	RenderableQueueElement* renderables = static_cast<RenderableQueueElement*>(
-		tmpPool.allocate(sizeof(RenderableQueueElement) * renderableCount, alignof(RenderableQueueElement)));
+	RenderableQueueElement* renderables =
+		static_cast<RenderableQueueElement*>(SceneGraph::getSingleton().getFrameMemoryPool().allocate(
+			sizeof(RenderableQueueElement) * renderableCount, alignof(RenderableQueueElement)));
 
 	outRenderables.setArray(renderables, renderableCount);
 
@@ -319,7 +321,6 @@ void ModelComponent::setupRenderableQueueElements(U32 lod, RenderingTechnique te
 }
 
 void ModelComponent::setupRayTracingInstanceQueueElements(U32 lod, RenderingTechnique technique,
-														  StackMemoryPool& tmpPool,
 														  WeakArray<RayTracingInstanceQueueElement>& outInstances) const
 {
 	ANKI_ASSERT(isEnabled());
@@ -344,8 +345,9 @@ void ModelComponent::setupRayTracingInstanceQueueElements(U32 lod, RenderingTech
 		return;
 	}
 
-	RayTracingInstanceQueueElement* instances = static_cast<RayTracingInstanceQueueElement*>(tmpPool.allocate(
-		sizeof(RayTracingInstanceQueueElement) * instanceCount, alignof(RayTracingInstanceQueueElement)));
+	RayTracingInstanceQueueElement* instances =
+		static_cast<RayTracingInstanceQueueElement*>(SceneGraph::getSingleton().getFrameMemoryPool().allocate(
+			sizeof(RayTracingInstanceQueueElement) * instanceCount, alignof(RayTracingInstanceQueueElement)));
 
 	outInstances.setArray(instances, instanceCount);
 

+ 2 - 2
AnKi/Scene/Components/ModelComponent.h

@@ -43,10 +43,10 @@ public:
 		return m_castsShadow;
 	}
 
-	void setupRenderableQueueElements(U32 lod, RenderingTechnique technique, StackMemoryPool& tmpPool,
+	void setupRenderableQueueElements(U32 lod, RenderingTechnique technique,
 									  WeakArray<RenderableQueueElement>& outRenderables) const;
 
-	void setupRayTracingInstanceQueueElements(U32 lod, RenderingTechnique technique, StackMemoryPool& tmpPool,
+	void setupRayTracingInstanceQueueElements(U32 lod, RenderingTechnique technique,
 											  WeakArray<RayTracingInstanceQueueElement>& outRenderables) const;
 
 private:

+ 5 - 4
AnKi/Scene/Components/ParticleEmitterComponent.cpp

@@ -267,7 +267,7 @@ void ParticleEmitterComponent::loadParticleEmitterResource(CString filename)
 	}
 	else
 	{
-		m_simpleParticles.create(m_props.m_maxNumOfParticles);
+		m_simpleParticles.resize(m_props.m_maxNumOfParticles);
 	}
 
 	// GPU scene allocations
@@ -445,7 +445,7 @@ void ParticleEmitterComponent::simulate(Second prevUpdateTime, Second crntTime,
 	}
 }
 
-void ParticleEmitterComponent::setupRenderableQueueElements(RenderingTechnique technique, StackMemoryPool& tmpPool,
+void ParticleEmitterComponent::setupRenderableQueueElements(RenderingTechnique technique,
 															WeakArray<RenderableQueueElement>& outRenderables) const
 {
 	if(!(m_particleEmitterResource->getMaterial()->getRenderingTechniques() & RenderingTechniqueBit(1 << technique))
@@ -460,8 +460,9 @@ void ParticleEmitterComponent::setupRenderableQueueElements(RenderingTechnique t
 	ShaderProgramPtr prog;
 	m_particleEmitterResource->getRenderingInfo(key, prog);
 
-	RenderableQueueElement* el = static_cast<RenderableQueueElement*>(
-		tmpPool.allocate(sizeof(RenderableQueueElement), alignof(RenderableQueueElement)));
+	RenderableQueueElement* el =
+		static_cast<RenderableQueueElement*>(SceneGraph::getSingleton().getFrameMemoryPool().allocate(
+			sizeof(RenderableQueueElement), alignof(RenderableQueueElement)));
 
 	el->m_mergeKey = 0; // Not mergable
 	el->m_program = prog.get();

+ 1 - 1
AnKi/Scene/Components/ParticleEmitterComponent.h

@@ -36,7 +36,7 @@ public:
 		return m_particleEmitterResource.isCreated();
 	}
 
-	void setupRenderableQueueElements(RenderingTechnique technique, StackMemoryPool& tmpPool,
+	void setupRenderableQueueElements(RenderingTechnique technique,
 									  WeakArray<RenderableQueueElement>& outRenderables) const;
 
 private:

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

@@ -15,7 +15,6 @@ namespace anki {
 
 SkinComponent::SkinComponent(SceneNode* node)
 	: SceneComponent(node, getStaticClassId())
-	, m_node(node)
 {
 }
 
@@ -46,9 +45,9 @@ void SkinComponent::loadSkeletonResource(CString fname)
 
 	// Create
 	const U32 boneCount = m_skeleton->getBones().getSize();
-	m_boneTrfs[0].create(boneCount, Mat3x4::getIdentity());
-	m_boneTrfs[1].create(boneCount, Mat3x4::getIdentity());
-	m_animationTrfs.create(boneCount, {Vec3(0.0f), Quat::getIdentity(), 1.0f});
+	m_boneTrfs[0].resize(boneCount, Mat3x4::getIdentity());
+	m_boneTrfs[1].resize(boneCount, Mat3x4::getIdentity());
+	m_animationTrfs.resize(boneCount, Trf{Vec3(0.0f), Quat::getIdentity(), 1.0f});
 
 	GpuSceneMemoryPool::getSingleton().allocate(sizeof(Mat4) * boneCount * 2, 4, m_boneTransformsGpuSceneOffset);
 }
@@ -75,8 +74,6 @@ void SkinComponent::playAnimation(U32 track, AnimationResourcePtr anim, const An
 
 Error SkinComponent::update(SceneComponentUpdateInfo& info, Bool& updated)
 {
-	ANKI_ASSERT(info.m_node == m_node);
-
 	updated = false;
 	if(!m_skeleton.isCreated())
 	{
@@ -194,7 +191,8 @@ Error SkinComponent::update(SceneComponentUpdateInfo& info, Bool& updated)
 
 		// Update the GPU scene
 		const U32 boneCount = m_skeleton->getBones().getSize();
-		DynamicArrayRaii<Mat3x4> trfs(boneCount * 2, info.m_framePool);
+		DynamicArray<Mat3x4, MemoryPoolPtrWrapper<StackMemoryPool>> trfs(info.m_framePool);
+		trfs.resize(boneCount * 2);
 		for(U32 i = 0; i < boneCount; ++i)
 		{
 			trfs[i * 2 + 0] = getBoneTransforms()[i];

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

@@ -101,7 +101,6 @@ private:
 		F32 m_scale;
 	};
 
-	SceneNode* m_node;
 	SkeletonResourcePtr m_skeleton;
 	Array<SceneDynamicArray<Mat3x4>, 2> m_boneTrfs;
 	SceneDynamicArray<Trf> m_animationTrfs;

+ 0 - 1
AnKi/Scene/Components/SkyboxComponent.cpp

@@ -14,7 +14,6 @@ namespace anki {
 
 SkyboxComponent::SkyboxComponent(SceneNode* node)
 	: SceneComponent(node, getStaticClassId())
-	, m_node(node)
 	, m_spatial(this)
 {
 	m_spatial.setAlwaysVisible(true);

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

@@ -118,7 +118,6 @@ public:
 	void setupSkyboxQueueElement(SkyboxQueueElement& queueElement) const;
 
 private:
-	SceneNode* m_node;
 	Spatial m_spatial;
 	SkyboxType m_type = SkyboxType::kSolidColor;
 	Vec3 m_color = Vec3(0.0f, 0.0f, 0.5f);

+ 1 - 1
AnKi/Scene/Components/UiComponent.cpp

@@ -14,7 +14,7 @@ UiComponent ::~UiComponent()
 	m_spatial.removeFromOctree(SceneGraph::getSingleton().getOctree());
 }
 
-Error UiComponent::updateReal([[maybe_unused]] SceneComponentUpdateInfo& info, Bool& updated)
+Error UiComponent::update([[maybe_unused]] SceneComponentUpdateInfo& info, Bool& updated)
 {
 	updated = m_spatial.update(SceneGraph::getSingleton().getOctree());
 	return Error::kNone;

+ 1 - 1
AnKi/Scene/Components/UiComponent.h

@@ -51,7 +51,7 @@ private:
 	void* m_userData = nullptr;
 	Spatial m_spatial;
 
-	Error updateReal(SceneComponentUpdateInfo& info, Bool& updated);
+	Error update(SceneComponentUpdateInfo& info, Bool& updated);
 };
 /// @}
 

+ 1 - 1
AnKi/Scene/ContiguousArrayAllocator.cpp

@@ -29,7 +29,7 @@ AllGpuSceneContiguousArrays::Index AllGpuSceneContiguousArrays::ContiguousArrayA
 		GpuSceneMemoryPool::getSingleton().allocate(m_objectSize * m_initialArraySize, alignment, m_poolToken);
 		m_nextSlotIndex = 0;
 
-		m_freeSlotStack.create(m_initialArraySize);
+		m_freeSlotStack.resize(m_initialArraySize);
 		for(U32 i = 0; i < m_initialArraySize; ++i)
 		{
 			m_freeSlotStack[i] = i;

+ 1 - 1
AnKi/Scene/ContiguousArrayAllocator.h

@@ -77,7 +77,7 @@ private:
 		~ContiguousArrayAllocator()
 		{
 			ANKI_ASSERT(m_nextSlotIndex == 0 && "Forgot to deallocate");
-			for([[maybe_unused]] const DynamicArray<Index>& arr : m_garbage)
+			for([[maybe_unused]] const SceneDynamicArray<Index>& arr : m_garbage)
 			{
 				ANKI_ASSERT(arr.getSize() == 0);
 			}

+ 2 - 1
AnKi/Scene/Events/EventManager.cpp

@@ -111,7 +111,8 @@ void EventManager::deleteEventsMarkedForDeletion(Bool fullCleanup)
 	if(fullCleanup)
 	{
 		// Gather in an array because we can't call setMarkedForDeletion while iterating m_events
-		DynamicArrayRaii<Event*> markedForDeletion(&SceneGraph::getSingleton().getFrameMemoryPool());
+		DynamicArray<Event*, MemoryPoolPtrWrapper<StackMemoryPool>> markedForDeletion(
+			&SceneGraph::getSingleton().getFrameMemoryPool());
 		for(Event& event : m_events)
 		{
 			for(SceneNode* node : event.m_associatedNodes)

+ 1 - 1
AnKi/Scene/Events/ScriptEvent.cpp

@@ -26,7 +26,7 @@ Error ScriptEvent::init(Second startTime, Second duration, CString script)
 	Event::init(startTime, duration);
 
 	// Do the rest
-	StringRaii extension(&SceneMemoryPool::getSingleton());
+	String extension;
 	getFilepathExtension(script, extension);
 
 	if(!extension.isEmpty() && extension == "lua")

+ 0 - 192
AnKi/Scene/Octree.cpp

@@ -34,25 +34,6 @@ static Vec3 heatmap(F32 factor)
 	}
 }
 
-class Octree::GatherParallelCtx
-{
-public:
-	Octree* m_octree = nullptr;
-	SpinLock m_lock;
-	Array<Plane, 6> m_frustumPlanes;
-	U32 m_testId = kMaxU32;
-	OctreeNodeVisibilityTestCallback m_testCallback = nullptr;
-	void* m_testCallbackUserData = nullptr;
-	DynamicArrayRaii<void*>* m_out = nullptr;
-};
-
-class Octree::GatherParallelTaskCtx
-{
-public:
-	GatherParallelCtx* m_ctx = nullptr;
-	Leaf* m_leaf = nullptr;
-};
-
 Octree::~Octree()
 {
 	ANKI_ASSERT(m_placeableCount == 0);
@@ -348,54 +329,6 @@ void Octree::removeInternal(OctreePlaceable& placeable)
 	}
 }
 
-void Octree::gatherVisibleRecursive(const Plane frustumPlanes[6], U32 testId,
-									OctreeNodeVisibilityTestCallback testCallback, void* testCallbackUserData,
-									Leaf* leaf, DynamicArrayRaii<void*>& out)
-{
-	ANKI_ASSERT(leaf);
-
-	// Add the placeables that belong to that leaf
-	for(PlaceableNode& placeableNode : leaf->m_placeables)
-	{
-		if(!placeableNode.m_placeable->alreadyVisited(testId))
-		{
-			ANKI_ASSERT(placeableNode.m_placeable->m_userData);
-			out.emplaceBack(placeableNode.m_placeable->m_userData);
-		}
-	}
-
-	// Move to children leafs
-	Aabb aabb;
-	for(Leaf* child : leaf->m_children)
-	{
-		if(child)
-		{
-			aabb.setMin(child->m_aabbMin);
-			aabb.setMax(child->m_aabbMax);
-
-			Bool inside = true;
-			for(U i = 0; i < 6; ++i)
-			{
-				if(testPlane(frustumPlanes[i], aabb) < 0.0f)
-				{
-					inside = false;
-					break;
-				}
-			}
-
-			if(inside && testCallback != nullptr)
-			{
-				inside = testCallback(testCallbackUserData, aabb);
-			}
-
-			if(inside)
-			{
-				gatherVisibleRecursive(frustumPlanes, testId, testCallback, testCallbackUserData, child, out);
-			}
-		}
-	}
-}
-
 void Octree::cleanupRecursive(Leaf* leaf, Bool& canDeleteLeafUponReturn)
 {
 	ANKI_ASSERT(leaf);
@@ -456,129 +389,4 @@ void Octree::debugDrawRecursive(const Leaf& leaf, OctreeDebugDrawer& drawer) con
 	}
 }
 
-void Octree::gatherVisibleParallel(const Plane frustumPlanes[6], U32 testId,
-								   OctreeNodeVisibilityTestCallback testCallback, void* testCallbackUserData,
-								   DynamicArrayRaii<void*>* out, ThreadHive& hive, ThreadHiveSemaphore* waitSemaphore,
-								   ThreadHiveSemaphore*& signalSemaphore)
-{
-	ANKI_ASSERT(out && frustumPlanes);
-
-	// Create the ctx
-	GatherParallelCtx* ctx = static_cast<GatherParallelCtx*>(
-		hive.allocateScratchMemory(sizeof(GatherParallelCtx), alignof(GatherParallelCtx)));
-	ctx->m_octree = this;
-	memcpy(&ctx->m_frustumPlanes[0], frustumPlanes, sizeof(ctx->m_frustumPlanes));
-	ctx->m_testId = testId;
-	ctx->m_testCallback = testCallback;
-	ctx->m_testCallbackUserData = testCallbackUserData;
-	ctx->m_out = out;
-
-	// Create the first test ctx
-	GatherParallelTaskCtx* taskCtx = static_cast<GatherParallelTaskCtx*>(
-		hive.allocateScratchMemory(sizeof(GatherParallelTaskCtx), alignof(GatherParallelTaskCtx)));
-	taskCtx->m_ctx = ctx;
-	taskCtx->m_leaf = m_rootLeaf;
-
-	// Create signal semaphore
-	signalSemaphore = hive.newSemaphore(1);
-
-	// Fire the first task
-	ThreadHiveTask task;
-	task.m_callback = gatherVisibleTaskCallback;
-	task.m_argument = taskCtx;
-	task.m_signalSemaphore = signalSemaphore;
-	task.m_waitSemaphore = waitSemaphore;
-
-	hive.submitTasks(&task, 1);
-}
-
-void Octree::gatherVisibleTaskCallback(void* ud, U32 threadId, ThreadHive& hive, ThreadHiveSemaphore* sem)
-{
-	ANKI_ASSERT(ud);
-	GatherParallelTaskCtx* taskCtx = static_cast<GatherParallelTaskCtx*>(ud);
-	taskCtx->m_ctx->m_octree->gatherVisibleParallelTask(threadId, hive, sem, *taskCtx);
-}
-
-void Octree::gatherVisibleParallelTask([[maybe_unused]] U32 threadId, ThreadHive& hive, ThreadHiveSemaphore* sem,
-									   GatherParallelTaskCtx& taskCtx)
-{
-	ANKI_ASSERT(taskCtx.m_ctx && taskCtx.m_leaf);
-	GatherParallelCtx& ctx = *taskCtx.m_ctx;
-
-	Leaf* const leaf = taskCtx.m_leaf;
-	DynamicArrayRaii<void*>& out = *ctx.m_out;
-	OctreeNodeVisibilityTestCallback testCallback = ctx.m_testCallback;
-	void* testCallbackUserData = ctx.m_testCallbackUserData;
-	const U32 testId = ctx.m_testId;
-
-	// Add the placeables that belong to that leaf
-	if(leaf->m_placeables.getSize() > 0)
-	{
-		LockGuard<SpinLock> lock(taskCtx.m_ctx->m_lock);
-
-		for(PlaceableNode& placeableNode : leaf->m_placeables)
-		{
-			if(!placeableNode.m_placeable->alreadyVisited(testId))
-			{
-				ANKI_ASSERT(placeableNode.m_placeable->m_userData);
-				out.emplaceBack(placeableNode.m_placeable->m_userData);
-			}
-		}
-	}
-
-	// Move to children leafs
-	Array<ThreadHiveTask, 8> tasks;
-	U32 taskCount = 0;
-	Aabb aabb;
-	for(Leaf* child : leaf->m_children)
-	{
-		if(child)
-		{
-			aabb.setMin(child->m_aabbMin);
-			aabb.setMax(child->m_aabbMax);
-
-			Bool inside = true;
-			for(U i = 0; i < 6; ++i)
-			{
-				if(testPlane(taskCtx.m_ctx->m_frustumPlanes[i], aabb) < 0.0f)
-				{
-					inside = false;
-					break;
-				}
-			}
-
-			if(inside && testCallback != nullptr)
-			{
-				inside = testCallback(testCallbackUserData, aabb);
-			}
-
-			if(inside)
-			{
-				// New task ctx
-				GatherParallelTaskCtx* newTaskCtx = static_cast<GatherParallelTaskCtx*>(
-					hive.allocateScratchMemory(sizeof(GatherParallelTaskCtx), alignof(GatherParallelTaskCtx)));
-				newTaskCtx->m_ctx = taskCtx.m_ctx;
-				newTaskCtx->m_leaf = child;
-
-				// Populate the task
-				ThreadHiveTask& task = tasks[taskCount++];
-				task.m_callback = gatherVisibleTaskCallback;
-				task.m_argument = newTaskCtx;
-				task.m_signalSemaphore = sem;
-			}
-		}
-	}
-
-	// Submit all tasks at once
-	if(taskCount)
-	{
-		// At this point do a trick. Increase the semaphore value to keep blocking the tasks that depend on the
-		// gather
-		sem->increaseSemaphore(taskCount);
-
-		// Submit
-		hive.submitTasks(&tasks[0], taskCount);
-	}
-}
-
 } // end namespace anki

+ 9 - 41
AnKi/Scene/Octree.h

@@ -62,25 +62,6 @@ public:
 	/// @note It's thread-safe against place and remove methods.
 	void remove(OctreePlaceable& placeable);
 
-	/// Gather visible placeables.
-	/// @param frustumPlanes The frustum planes to test against.
-	/// @param testId A unique index for this test.
-	/// @param testCallback A ptr to a function that will be used to perform an additional test to the box of the
-	///                     Octree node. Can be nullptr.
-	/// @param testCallbackUserData Parameter to the testCallback. Can be nullptr.
-	/// @param out The output of the tests.
-	/// @note It's thread-safe against other gatherVisible calls.
-	void gatherVisible(const Plane frustumPlanes[6], U32 testId, OctreeNodeVisibilityTestCallback testCallback,
-					   void* testCallbackUserData, DynamicArrayRaii<void*>& out)
-	{
-		gatherVisibleRecursive(frustumPlanes, testId, testCallback, testCallbackUserData, m_rootLeaf, out);
-	}
-
-	/// Similar to gatherVisible but it spawns ThreadHive tasks.
-	void gatherVisibleParallel(const Plane frustumPlanes[6], U32 testId, OctreeNodeVisibilityTestCallback testCallback,
-							   void* testCallbackUserData, DynamicArrayRaii<void*>* out, ThreadHive& hive,
-							   ThreadHiveSemaphore* waitSemaphore, ThreadHiveSemaphore*& signalSemaphore);
-
 	/// Walk the tree.
 	/// @tparam TTestAabbFunc The lambda that will test an Aabb. Signature of lambda: Bool(*)(const Aabb& leafBox)
 	/// @tparam TNewPlaceableFunc The lambda to do something with a visible placeable.
@@ -115,9 +96,6 @@ public:
 	}
 
 private:
-	class GatherParallelCtx;
-	class GatherParallelTaskCtx;
-
 	/// List node.
 	class PlaceableNode : public IntrusiveListEnabled<PlaceableNode>
 	{
@@ -202,9 +180,9 @@ private:
 	Vec3 m_sceneAabbMax = Vec3(0.0f);
 	mutable Mutex m_globalMtx;
 
-	ObjectAllocatorSameType<Leaf, 256> m_leafAlloc;
-	ObjectAllocatorSameType<LeafNode, 128> m_leafNodeAlloc;
-	ObjectAllocatorSameType<PlaceableNode, 256> m_placeableNodeAlloc;
+	ObjectAllocatorSameType<Leaf, SingletonMemoryPoolWrapper<SceneMemoryPool>, 256> m_leafAlloc;
+	ObjectAllocatorSameType<LeafNode, SingletonMemoryPoolWrapper<SceneMemoryPool>, 128> m_leafNodeAlloc;
+	ObjectAllocatorSameType<PlaceableNode, SingletonMemoryPoolWrapper<SceneMemoryPool>, 256> m_placeableNodeAlloc;
 
 	Leaf* m_rootLeaf = nullptr;
 	U32 m_placeableCount = 0;
@@ -215,38 +193,38 @@ private:
 
 	Leaf* newLeaf()
 	{
-		return m_leafAlloc.newInstance(SceneMemoryPool::getSingleton());
+		return m_leafAlloc.newInstance();
 	}
 
 	void releaseLeaf(Leaf* leaf)
 	{
-		m_leafAlloc.deleteInstance(SceneMemoryPool::getSingleton(), leaf);
+		m_leafAlloc.deleteInstance(leaf);
 	}
 
 	PlaceableNode* newPlaceableNode(OctreePlaceable* placeable)
 	{
 		ANKI_ASSERT(placeable);
-		PlaceableNode* out = m_placeableNodeAlloc.newInstance(SceneMemoryPool::getSingleton());
+		PlaceableNode* out = m_placeableNodeAlloc.newInstance();
 		out->m_placeable = placeable;
 		return out;
 	}
 
 	void releasePlaceableNode(PlaceableNode* placeable)
 	{
-		m_placeableNodeAlloc.deleteInstance(SceneMemoryPool::getSingleton(), placeable);
+		m_placeableNodeAlloc.deleteInstance(placeable);
 	}
 
 	LeafNode* newLeafNode(Leaf* leaf)
 	{
 		ANKI_ASSERT(leaf);
-		LeafNode* out = m_leafNodeAlloc.newInstance(SceneMemoryPool::getSingleton());
+		LeafNode* out = m_leafNodeAlloc.newInstance();
 		out->m_leaf = leaf;
 		return out;
 	}
 
 	void releaseLeafNode(LeafNode* node)
 	{
-		m_leafNodeAlloc.deleteInstance(SceneMemoryPool::getSingleton(), node);
+		m_leafNodeAlloc.deleteInstance(node);
 	}
 
 	void placeRecursive(const Aabb& volume, OctreePlaceable* placeable, Leaf* parent, U32 depth);
@@ -259,16 +237,6 @@ private:
 	/// Remove a placeable from the tree.
 	void removeInternal(OctreePlaceable& placeable);
 
-	static void gatherVisibleRecursive(const Plane frustumPlanes[6], U32 testId,
-									   OctreeNodeVisibilityTestCallback testCallback, void* testCallbackUserData,
-									   Leaf* leaf, DynamicArrayRaii<void*>& out);
-
-	/// ThreadHive callback.
-	static void gatherVisibleTaskCallback(void* ud, U32 threadId, ThreadHive& hive, ThreadHiveSemaphore* sem);
-
-	void gatherVisibleParallelTask(U32 threadId, ThreadHive& hive, ThreadHiveSemaphore* sem,
-								   GatherParallelTaskCtx& taskCtx);
-
 	/// Remove a leaf.
 	void cleanupRecursive(Leaf* leaf, Bool& canDeleteLeafUponReturn);
 

+ 0 - 2
AnKi/Scene/SceneNode.cpp

@@ -31,8 +31,6 @@ SceneNode::~SceneNode()
 
 		SceneMemoryPool::getSingleton().free(comp);
 	}
-
-	Base::destroy(SceneMemoryPool::getSingleton());
 }
 
 void SceneNode::setMarkedForDeletion()

+ 3 - 3
AnKi/Scene/SceneNode.h

@@ -21,12 +21,12 @@ class SceneGraphExternalSubsystems;
 /// @{
 
 /// Interface class backbone of scene
-class SceneNode : public Hierarchy<SceneNode>, public IntrusiveListEnabled<SceneNode>
+class SceneNode : public SceneHierarchy<SceneNode>, public IntrusiveListEnabled<SceneNode>
 {
 	friend class SceneComponent;
 
 public:
-	using Base = Hierarchy<SceneNode>;
+	using Base = SceneHierarchy<SceneNode>;
 
 	/// The one and only constructor.
 	/// @param scene The owner scene.
@@ -73,7 +73,7 @@ public:
 
 	void addChild(SceneNode* obj)
 	{
-		Base::addChild(SceneMemoryPool::getSingleton(), obj);
+		Base::addChild(obj);
 	}
 
 	/// This is called by the scenegraph every frame after all component updates. By default it does nothing.

+ 1 - 2
AnKi/Scene/SoftwareRasterizer.cpp

@@ -26,8 +26,7 @@ void SoftwareRasterizer::prepare(const Mat4& mv, const Mat4& p, U32 width, U32 h
 	U32 size = width * height;
 	if(m_zbuffer.getSize() < size)
 	{
-		m_zbuffer.destroy();
-		m_zbuffer.create(size);
+		m_zbuffer.resize(size);
 	}
 	memset(&m_zbuffer[0], 0xFF, sizeof(m_zbuffer[0]) * size);
 }

+ 77 - 77
AnKi/Scene/Visibility.cpp

@@ -116,8 +116,6 @@ void VisibilityContext::submitNewWork(const VisibilityFrustum& frustum, const Vi
 		rqueue.m_cameraFovX = rqueue.m_cameraFovY = 0.0f;
 	}
 
-	StackMemoryPool& pool = m_scene->getFrameMemoryPool();
-
 	// Check if this frc was tested before
 	{
 		LockGuard<Mutex> l(m_testedFrustumsMtx);
@@ -132,15 +130,16 @@ void VisibilityContext::submitNewWork(const VisibilityFrustum& frustum, const Vi
 		}
 
 		// Not there, push it
-		m_testedFrustums.pushBack(pool, frustum.m_frustum);
+		m_testedFrustums.pushBack(frustum.m_frustum);
 	}
 
 	// Prepare the ctx
-	FrustumVisibilityContext* frcCtx = newInstance<FrustumVisibilityContext>(pool);
+	FrustumVisibilityContext* frcCtx =
+		newInstance<FrustumVisibilityContext>(SceneGraph::getSingleton().getFrameMemoryPool());
 	frcCtx->m_visCtx = this;
 	frcCtx->m_frustum = frustum;
 	frcCtx->m_primaryFrustum = primaryFrustum;
-	frcCtx->m_queueViews.create(pool, hive.getThreadCount());
+	frcCtx->m_queueViews.resize(hive.getThreadCount());
 	frcCtx->m_visTestsSignalSem = hive.newSemaphore(1);
 	frcCtx->m_renderQueue = &rqueue;
 
@@ -152,9 +151,10 @@ void VisibilityContext::submitNewWork(const VisibilityFrustum& frustum, const Vi
 	if(frustum.m_coverageBuffer && frustum.m_frustum->hasCoverageBuffer())
 	{
 		// Gather triangles task
-		ThreadHiveTask fillDepthTask =
-			ANKI_THREAD_HIVE_TASK({ self->fill(); }, newInstance<FillRasterizerWithCoverageTask>(pool, frcCtx), nullptr,
-								  hive.newSemaphore(1));
+		ThreadHiveTask fillDepthTask = ANKI_THREAD_HIVE_TASK(
+			{ self->fill(); },
+			newInstance<FillRasterizerWithCoverageTask>(SceneGraph::getSingleton().getFrameMemoryPool(), frcCtx),
+			nullptr, hive.newSemaphore(1));
 
 		hive.submitTasks(&fillDepthTask, 1);
 
@@ -170,15 +170,17 @@ void VisibilityContext::submitNewWork(const VisibilityFrustum& frustum, const Vi
 	}
 
 	// Gather visibles from the octree. No need to signal anything because it will spawn new tasks
-	ThreadHiveTask gatherTask =
-		ANKI_THREAD_HIVE_TASK({ self->gather(hive); }, newInstance<GatherVisiblesFromOctreeTask>(pool, frcCtx),
-							  prepareRasterizerSem, nullptr);
+	ThreadHiveTask gatherTask = ANKI_THREAD_HIVE_TASK(
+		{ self->gather(hive); },
+		newInstance<GatherVisiblesFromOctreeTask>(SceneGraph::getSingleton().getFrameMemoryPool(), frcCtx),
+		prepareRasterizerSem, nullptr);
 	hive.submitTasks(&gatherTask, 1);
 
 	// Combind results task
 	ANKI_ASSERT(frcCtx->m_visTestsSignalSem);
 	ThreadHiveTask combineTask = ANKI_THREAD_HIVE_TASK(
-		{ self->combine(); }, newInstance<CombineResultsTask>(pool, frcCtx), frcCtx->m_visTestsSignalSem, nullptr);
+		{ self->combine(); }, newInstance<CombineResultsTask>(SceneGraph::getSingleton().getFrameMemoryPool(), frcCtx),
+		frcCtx->m_visTestsSignalSem, nullptr);
 	hive.submitTasks(&combineTask, 1);
 }
 
@@ -186,8 +188,6 @@ void FillRasterizerWithCoverageTask::fill()
 {
 	ANKI_TRACE_SCOPED_EVENT(SceneVisFillDepth);
 
-	StackMemoryPool& pool = m_frcCtx->m_visCtx->m_scene->getFrameMemoryPool();
-
 	// Get the C-Buffer
 	ConstWeakArray<F32> depthBuff;
 	U32 width;
@@ -198,7 +198,7 @@ void FillRasterizerWithCoverageTask::fill()
 	// Init the rasterizer
 	if(true)
 	{
-		m_frcCtx->m_r = newInstance<SoftwareRasterizer>(pool);
+		m_frcCtx->m_r = newInstance<SoftwareRasterizer>(SceneGraph::getSingleton().getFrameMemoryPool());
 		m_frcCtx->m_r->prepare(
 			Mat4(m_frcCtx->m_frustum.m_frustum->getPreviousViewMatrix(1), Vec4(0.0f, 0.0f, 0.0f, 1.0f)),
 			m_frcCtx->m_frustum.m_frustum->getPreviousProjectionMatrix(1), width, height);
@@ -215,7 +215,7 @@ void GatherVisiblesFromOctreeTask::gather(ThreadHive& hive)
 	U32 testIdx = m_frcCtx->m_visCtx->m_testsCount.fetchAdd(1);
 
 	// Walk the tree
-	m_frcCtx->m_visCtx->m_scene->getOctree().walkTree(
+	SceneGraph::getSingleton().getOctree().walkTree(
 		testIdx,
 		[&](const Aabb& box) {
 			Bool visible = m_frcCtx->m_frustum.m_frustum->insideFrustum(box);
@@ -255,7 +255,7 @@ void GatherVisiblesFromOctreeTask::flush(ThreadHive& hive)
 	{
 		// Create the task
 		VisibilityTestTask* vis =
-			newInstance<VisibilityTestTask>(m_frcCtx->m_visCtx->m_scene->getFrameMemoryPool(), m_frcCtx);
+			newInstance<VisibilityTestTask>(SceneGraph::getSingleton().getFrameMemoryPool(), m_frcCtx);
 		memcpy(&vis->m_spatialsToTest[0], &m_spatials[0], sizeof(m_spatials[0]) * m_spatialCount);
 		vis->m_spatialToTestCount = m_spatialCount;
 
@@ -281,7 +281,7 @@ void VisibilityTestTask::test(ThreadHive& hive, U32 taskId)
 	const FrustumFlags frustumFlags = m_frcCtx->m_frustum;
 	const Frustum& primaryFrustum = *m_frcCtx->m_primaryFrustum.m_frustum;
 
-	StackMemoryPool& pool = m_frcCtx->m_visCtx->m_scene->getFrameMemoryPool();
+	StackMemoryPool& framePool = SceneGraph::getSingleton().getFrameMemoryPool();
 
 	const Bool wantsEarlyZ = m_frcCtx->m_frustum.m_earlyZ && testedFrustum.getEarlyZDistance() > 0.0f;
 
@@ -316,40 +316,45 @@ void VisibilityTestTask::test(ThreadHive& hive, U32 taskId)
 
 			WeakArray<RenderableQueueElement> elements;
 			modelc.setupRenderableQueueElements(
-				lod, (isShadowFrustum) ? RenderingTechnique::kShadow : RenderingTechnique::kGBuffer, pool, elements);
+				lod, (isShadowFrustum) ? RenderingTechnique::kShadow : RenderingTechnique::kGBuffer, elements);
 			for(RenderableQueueElement& el : elements)
 			{
 				el.m_distanceFromCamera = distanceFromCamera;
-				*result.m_renderables.newElement(pool) = el;
+				*result.m_renderables.newElement() = el;
 			}
 
-			modelc.setupRenderableQueueElements(lod, RenderingTechnique::kForward, pool, elements);
+			modelc.setupRenderableQueueElements(lod, RenderingTechnique::kForward, elements);
 			for(RenderableQueueElement& el : elements)
 			{
 				el.m_distanceFromCamera = distanceFromCamera;
-				*result.m_forwardShadingRenderables.newElement(pool) = el;
+				*result.m_forwardShadingRenderables.newElement() = el;
 			}
 
 			if(wantsEarlyZ && distanceFromCamera < testedFrustum.getEarlyZDistance())
 			{
-				modelc.setupRenderableQueueElements(lod, RenderingTechnique::kGBufferEarlyZ, pool, elements);
+				modelc.setupRenderableQueueElements(lod, RenderingTechnique::kGBufferEarlyZ, elements);
 				for(RenderableQueueElement& el : elements)
 				{
 					el.m_distanceFromCamera = distanceFromCamera;
-					*result.m_earlyZRenderables.newElement(pool) = el;
+					*result.m_earlyZRenderables.newElement() = el;
 				}
 			}
 
 			if(frustumFlags.m_gatherRayTracingModelComponents)
 			{
 				WeakArray<RayTracingInstanceQueueElement> rtElements;
-				modelc.setupRayTracingInstanceQueueElements(lod, RenderingTechnique::kRtShadow, pool, rtElements);
+				modelc.setupRayTracingInstanceQueueElements(lod, RenderingTechnique::kRtShadow, rtElements);
 
 				for(RayTracingInstanceQueueElement& el : rtElements)
 				{
-					*result.m_rayTracingInstances.newElement(pool) = el;
+					*result.m_rayTracingInstances.newElement() = el;
 				}
 			}
+
+			// Update timestamp
+			ANKI_ASSERT(comp.getTimestamp() > 0);
+			m_frcCtx->m_queueViews[taskId].m_timestamp =
+				max(m_frcCtx->m_queueViews[taskId].m_timestamp, comp.getTimestamp());
 		}
 		else if(comp.getClassId() == ParticleEmitterComponent::getStaticClassId())
 		{
@@ -363,19 +368,24 @@ void VisibilityTestTask::test(ThreadHive& hive, U32 taskId)
 			const F32 distanceFromCamera = max(0.0f, testPlane(nearPlane, aabb));
 
 			WeakArray<RenderableQueueElement> elements;
-			partemitc.setupRenderableQueueElements(RenderingTechnique::kGBuffer, pool, elements);
+			partemitc.setupRenderableQueueElements(RenderingTechnique::kGBuffer, elements);
 			for(RenderableQueueElement& el : elements)
 			{
 				el.m_distanceFromCamera = distanceFromCamera;
-				*result.m_renderables.newElement(pool) = el;
+				*result.m_renderables.newElement() = el;
 			}
 
-			partemitc.setupRenderableQueueElements(RenderingTechnique::kForward, pool, elements);
+			partemitc.setupRenderableQueueElements(RenderingTechnique::kForward, elements);
 			for(RenderableQueueElement& el : elements)
 			{
 				el.m_distanceFromCamera = distanceFromCamera;
-				*result.m_forwardShadingRenderables.newElement(pool) = el;
+				*result.m_forwardShadingRenderables.newElement() = el;
 			}
+
+			// Update timestamp
+			ANKI_ASSERT(comp.getTimestamp() > 0);
+			m_frcCtx->m_queueViews[taskId].m_timestamp =
+				max(m_frcCtx->m_queueViews[taskId].m_timestamp, comp.getTimestamp());
 		}
 		else if(comp.getClassId() == LightComponent::getStaticClassId())
 		{
@@ -407,13 +417,13 @@ void VisibilityTestTask::test(ThreadHive& hive, U32 taskId)
 			{
 			case LightComponentType::kPoint:
 			{
-				PointLightQueueElement* el = result.m_pointLights.newElement(pool);
+				PointLightQueueElement* el = result.m_pointLights.newElement();
 				lightc.setupPointLightQueueElement(*el);
 
 				if(castsShadow && frustumFlags.m_nonDirectionalLightsCastShadow)
 				{
-					nextQueues = WeakArray<RenderQueue>(newArray<RenderQueue>(pool, 6), 6);
-					nextFrustums = WeakArray<VisibilityFrustum>(newArray<VisibilityFrustum>(pool, 6), 6);
+					nextQueues = WeakArray<RenderQueue>(newArray<RenderQueue>(framePool, 6), 6);
+					nextFrustums = WeakArray<VisibilityFrustum>(newArray<VisibilityFrustum>(framePool, 6), 6);
 
 					for(U32 f = 0; f < 6; ++f)
 					{
@@ -431,15 +441,15 @@ void VisibilityTestTask::test(ThreadHive& hive, U32 taskId)
 			}
 			case LightComponentType::kSpot:
 			{
-				SpotLightQueueElement* el = result.m_spotLights.newElement(pool);
+				SpotLightQueueElement* el = result.m_spotLights.newElement();
 				lightc.setupSpotLightQueueElement(*el);
 
 				if(castsShadow && frustumFlags.m_nonDirectionalLightsCastShadow)
 				{
-					nextQueues = WeakArray<RenderQueue>(newInstance<RenderQueue>(pool), 1);
+					nextQueues = WeakArray<RenderQueue>(newInstance<RenderQueue>(framePool), 1);
 					el->m_shadowRenderQueue = &nextQueues[0];
 
-					nextFrustums = WeakArray<VisibilityFrustum>(newInstance<VisibilityFrustum>(pool), 1);
+					nextFrustums = WeakArray<VisibilityFrustum>(newInstance<VisibilityFrustum>(framePool), 1);
 					nextFrustums[0].m_frustum = &lightc.getFrustums()[0];
 					static_cast<FrustumFlags&>(nextFrustums[0]) = getLightFrustumFlags();
 				}
@@ -467,10 +477,10 @@ void VisibilityTestTask::test(ThreadHive& hive, U32 taskId)
 				WeakArray<Frustum> frustums;
 				if(cascadeCount)
 				{
-					nextQueues = WeakArray<RenderQueue>(newArray<RenderQueue>(pool, cascadeCount), cascadeCount);
-					nextFrustums =
-						WeakArray<VisibilityFrustum>(newArray<VisibilityFrustum>(pool, cascadeCount), cascadeCount);
-					frustums = WeakArray<Frustum>(newArray<Frustum>(pool, cascadeCount), cascadeCount);
+					nextQueues = WeakArray<RenderQueue>(newArray<RenderQueue>(framePool, cascadeCount), cascadeCount);
+					nextFrustums = WeakArray<VisibilityFrustum>(newArray<VisibilityFrustum>(framePool, cascadeCount),
+																cascadeCount);
+					frustums = WeakArray<Frustum>(newArray<Frustum>(framePool, cascadeCount), cascadeCount);
 				}
 
 				for(U32 i = 0; i < cascadeCount; ++i)
@@ -503,7 +513,7 @@ void VisibilityTestTask::test(ThreadHive& hive, U32 taskId)
 				continue;
 			}
 
-			LensFlareQueueElement* el = result.m_lensFlares.newElement(pool);
+			LensFlareQueueElement* el = result.m_lensFlares.newElement();
 			flarec.setupLensFlareQueueElement(*el);
 		}
 		else if(comp.getClassId() == ReflectionProbeComponent::getStaticClassId())
@@ -517,14 +527,15 @@ void VisibilityTestTask::test(ThreadHive& hive, U32 taskId)
 
 			if(reflc.getReflectionNeedsRefresh() && m_frcCtx->m_reflectionProbesForRefreshCount.fetchAdd(1) == 0)
 			{
-				ReflectionProbeQueueElementForRefresh* el = newInstance<ReflectionProbeQueueElementForRefresh>(pool);
+				ReflectionProbeQueueElementForRefresh* el =
+					newInstance<ReflectionProbeQueueElementForRefresh>(framePool);
 				m_frcCtx->m_reflectionProbeForRefresh = el;
 
 				reflc.setupReflectionProbeQueueElementForRefresh(*el);
 				reflc.setReflectionNeedsRefresh(false);
 
-				nextQueues = WeakArray<RenderQueue>(newArray<RenderQueue>(pool, 6), 6);
-				nextFrustums = WeakArray<VisibilityFrustum>(newArray<VisibilityFrustum>(pool, 6), 6);
+				nextQueues = WeakArray<RenderQueue>(newArray<RenderQueue>(framePool, 6), 6);
+				nextFrustums = WeakArray<VisibilityFrustum>(newArray<VisibilityFrustum>(framePool, 6), 6);
 
 				for(U32 i = 0; i < 6; ++i)
 				{
@@ -536,7 +547,7 @@ void VisibilityTestTask::test(ThreadHive& hive, U32 taskId)
 			}
 			else if(!reflc.getReflectionNeedsRefresh())
 			{
-				ReflectionProbeQueueElement* el = result.m_reflectionProbes.newElement(pool);
+				ReflectionProbeQueueElement* el = result.m_reflectionProbes.newElement();
 				reflc.setupReflectionProbeQueueElement(*el);
 			}
 		}
@@ -549,7 +560,7 @@ void VisibilityTestTask::test(ThreadHive& hive, U32 taskId)
 				continue;
 			}
 
-			DecalQueueElement* el = result.m_decals.newElement(pool);
+			DecalQueueElement* el = result.m_decals.newElement();
 			decalc.setupDecalQueueElement(*el);
 		}
 		else if(comp.getClassId() == FogDensityComponent::getStaticClassId())
@@ -561,7 +572,7 @@ void VisibilityTestTask::test(ThreadHive& hive, U32 taskId)
 
 			const FogDensityComponent& fogc = static_cast<FogDensityComponent&>(comp);
 
-			FogDensityQueueElement* el = result.m_fogDensityVolumes.newElement(pool);
+			FogDensityQueueElement* el = result.m_fogDensityVolumes.newElement();
 			fogc.setupFogDensityQueueElement(*el);
 		}
 		else if(comp.getClassId() == GlobalIlluminationProbeComponent::getStaticClassId())
@@ -575,11 +586,11 @@ void VisibilityTestTask::test(ThreadHive& hive, U32 taskId)
 
 			if(giprobec.needsRefresh() && m_frcCtx->m_giProbesForRefreshCount.fetchAdd(1) == 0)
 			{
-				nextQueues = WeakArray<RenderQueue>(newArray<RenderQueue>(pool, 6), 6);
-				nextFrustums = WeakArray<VisibilityFrustum>(newArray<VisibilityFrustum>(pool, 6), 6);
+				nextQueues = WeakArray<RenderQueue>(newArray<RenderQueue>(framePool, 6), 6);
+				nextFrustums = WeakArray<VisibilityFrustum>(newArray<VisibilityFrustum>(framePool, 6), 6);
 
 				GlobalIlluminationProbeQueueElementForRefresh* el =
-					newInstance<GlobalIlluminationProbeQueueElementForRefresh>(pool);
+					newInstance<GlobalIlluminationProbeQueueElementForRefresh>(framePool);
 
 				m_frcCtx->m_giProbeForRefresh = el;
 
@@ -594,7 +605,7 @@ void VisibilityTestTask::test(ThreadHive& hive, U32 taskId)
 				}
 			}
 
-			GlobalIlluminationProbeQueueElement* el = result.m_giProbes.newElement(pool);
+			GlobalIlluminationProbeQueueElement* el = result.m_giProbes.newElement();
 			giprobec.setupGlobalIlluminationProbeQueueElement(*el);
 		}
 		else if(comp.getClassId() == UiComponent::getStaticClassId())
@@ -605,7 +616,7 @@ void VisibilityTestTask::test(ThreadHive& hive, U32 taskId)
 			}
 
 			const UiComponent& uic = static_cast<UiComponent&>(comp);
-			UiQueueElement* el = result.m_uis.newElement(pool);
+			UiQueueElement* el = result.m_uis.newElement();
 			uic.setupUiQueueElement(*el);
 		}
 		else if(comp.getClassId() == SkyboxComponent::getStaticClassId())
@@ -633,28 +644,13 @@ void VisibilityTestTask::test(ThreadHive& hive, U32 taskId)
 				m_frcCtx->m_visCtx->submitNewWork(nextFrustums[i], m_frcCtx->m_primaryFrustum, nextQueues[i], hive);
 			}
 		}
-
-		// Update timestamp
-		ANKI_ASSERT(comp.getTimestamp() > 0);
-		m_frcCtx->m_queueViews[taskId].m_timestamp =
-			max(m_frcCtx->m_queueViews[taskId].m_timestamp, comp.getTimestamp());
 	} // end for
-
-	if(testedFrustum.getUpdatedThisFrame())
-	{
-		m_frcCtx->m_queueViews[taskId].m_timestamp = GlobalFrameIndex::getSingleton().m_value;
-	}
-	else
-	{
-		m_frcCtx->m_queueViews[taskId].m_timestamp = max<Timestamp>(m_frcCtx->m_queueViews[taskId].m_timestamp, 1);
-	}
 }
 
 void CombineResultsTask::combine()
 {
 	ANKI_TRACE_SCOPED_EVENT(SceneVisCombine);
 
-	StackMemoryPool& pool = m_frcCtx->m_visCtx->m_scene->getFrameMemoryPool();
 	RenderQueue& results = *m_frcCtx->m_renderQueue;
 
 	// Compute the timestamp
@@ -671,13 +667,18 @@ void CombineResultsTask::combine()
 
 	if(renderableCount)
 	{
-		ANKI_ASSERT(results.m_shadowRenderablesLastUpdateTimestamp);
+		ANKI_ASSERT(results.m_shadowRenderablesLastUpdateTimestamp > 0);
 	}
 	else
 	{
 		ANKI_ASSERT(results.m_shadowRenderablesLastUpdateTimestamp == 0);
 	}
 
+	if(m_frcCtx->m_frustum.m_frustum->getUpdatedThisFrame())
+	{
+		results.m_shadowRenderablesLastUpdateTimestamp = GlobalFrameIndex::getSingleton().m_value;
+	}
+
 #define ANKI_VIS_COMBINE(t_, member_) \
 	{ \
 		Array<TRenderQueueElementStorage<t_>, 64> subStorages; \
@@ -685,8 +686,8 @@ void CombineResultsTask::combine()
 		{ \
 			subStorages[i] = m_frcCtx->m_queueViews[i].member_; \
 		} \
-		combineQueueElements<t_>(pool, WeakArray<TRenderQueueElementStorage<t_>>(&subStorages[0], threadCount), \
-								 nullptr, results.member_, nullptr); \
+		combineQueueElements<t_>(WeakArray<TRenderQueueElementStorage<t_>>(&subStorages[0], threadCount), nullptr, \
+								 results.member_, nullptr); \
 	}
 
 	ANKI_VIS_COMBINE(RenderableQueueElement, m_renderables);
@@ -762,7 +763,7 @@ void CombineResultsTask::combine()
 				  }
 			  });
 
-	const AllGpuSceneContiguousArrays& arrays = m_frcCtx->m_visCtx->m_scene->getAllGpuSceneContiguousArrays();
+	const AllGpuSceneContiguousArrays& arrays = SceneGraph::getSingleton().getAllGpuSceneContiguousArrays();
 
 	auto setOffset = [&](ClusteredObjectType type, GpuSceneContiguousArrayType type2) {
 		results.m_clustererObjectsArrayOffsets[type] = arrays.getElementCount(type2) ? arrays.getArrayBase(type2) : 0;
@@ -784,11 +785,12 @@ void CombineResultsTask::combine()
 }
 
 template<typename T>
-void CombineResultsTask::combineQueueElements(StackMemoryPool& pool,
-											  WeakArray<TRenderQueueElementStorage<T>> subStorages,
+void CombineResultsTask::combineQueueElements(WeakArray<TRenderQueueElementStorage<T>> subStorages,
 											  WeakArray<TRenderQueueElementStorage<U32>>* ptrSubStorages,
 											  WeakArray<T>& combined, WeakArray<T*>* ptrCombined)
 {
+	StackMemoryPool& framePool = SceneGraph::getSingleton().getFrameMemoryPool();
+
 	U32 totalElCount = subStorages[0].m_elementCount;
 	U32 biggestSubStorageIdx = 0;
 	for(U32 i = 1; i < subStorages.getSize(); ++i)
@@ -821,7 +823,7 @@ void CombineResultsTask::combineQueueElements(StackMemoryPool& pool,
 		// Create the new storage
 		if(ptrTotalElCount > 0)
 		{
-			ptrIt = newArray<T*>(pool, ptrTotalElCount);
+			ptrIt = newArray<T*>(framePool, ptrTotalElCount);
 			*ptrCombined = WeakArray<T*>(ptrIt, ptrTotalElCount);
 		}
 	}
@@ -831,7 +833,7 @@ void CombineResultsTask::combineQueueElements(StackMemoryPool& pool,
 	{
 		// Can't reuse any of the existing storage, will allocate a brand new one
 
-		it = newArray<T>(pool, totalElCount);
+		it = newArray<T>(framePool, totalElCount);
 		biggestSubStorageIdx = kMaxU32;
 
 		combined = WeakArray<T>(it, totalElCount);
@@ -885,7 +887,6 @@ void SceneGraph::doVisibilityTests(SceneNode& camera, SceneGraph& scene, RenderQ
 	ThreadHive& hive = CoreThreadHive::getSingleton();
 
 	VisibilityContext ctx;
-	ctx.m_scene = &scene;
 	CameraComponent& camerac = camera.getFirstComponentOfType<CameraComponent>();
 	VisibilityFrustum visFrustum;
 	visFrustum.m_frustum = &camerac.getFrustum();
@@ -903,7 +904,6 @@ void SceneGraph::doVisibilityTests(SceneNode& camera, SceneGraph& scene, RenderQ
 	}
 
 	hive.waitAllTasks();
-	ctx.m_testedFrustums.destroy(scene.getFrameMemoryPool());
 }
 
 } // end namespace anki

+ 31 - 7
AnKi/Scene/VisibilityInternal.h

@@ -21,6 +21,30 @@ namespace anki {
 
 constexpr U32 kMaxSpatialsPerVisTest = 48; ///< Num of spatials to test in a single ThreadHive task.
 
+class FrameMemoryPoolWrapper
+{
+public:
+	StackMemoryPool* operator&()
+	{
+		return &SceneGraph::getSingleton().getFrameMemoryPool();
+	}
+
+	operator StackMemoryPool&()
+	{
+		return SceneGraph::getSingleton().getFrameMemoryPool();
+	}
+
+	void* allocate(PtrSize size, PtrSize alignmentBytes)
+	{
+		return SceneGraph::getSingleton().getFrameMemoryPool().allocate(size, alignmentBytes);
+	}
+
+	void free(void* ptr)
+	{
+		SceneGraph::getSingleton().getFrameMemoryPool().free(ptr);
+	}
+};
+
 /// Sort objects on distance
 template<typename T>
 class DistanceSortFunctor
@@ -61,14 +85,15 @@ public:
 	U32 m_elementCount = 0;
 	U32 m_elementStorage = 0;
 
-	T* newElement(StackMemoryPool& pool)
+	T* newElement()
 	{
 		if(m_elementCount + 1 > m_elementStorage) [[unlikely]]
 		{
 			m_elementStorage = max(kInitialStorage, m_elementStorage * kStorageGrowRate);
 
 			const T* oldElements = m_elements;
-			m_elements = static_cast<T*>(pool.allocate(m_elementStorage * sizeof(T), alignof(T)));
+			m_elements = static_cast<T*>(
+				SceneGraph::getSingleton().getFrameMemoryPool().allocate(m_elementStorage * sizeof(T), alignof(T)));
 
 			if(oldElements)
 			{
@@ -142,10 +167,9 @@ public:
 class VisibilityContext
 {
 public:
-	SceneGraph* m_scene = nullptr;
 	Atomic<U32> m_testsCount = {0};
 
-	List<const Frustum*> m_testedFrustums;
+	List<const Frustum*, FrameMemoryPoolWrapper> m_testedFrustums;
 	Mutex m_testedFrustumsMtx;
 
 	void submitNewWork(const VisibilityFrustum& frustum, const VisibilityFrustum& primaryFrustum, RenderQueue& result,
@@ -164,11 +188,11 @@ public:
 
 	// S/W rasterizer members
 	SoftwareRasterizer* m_r = nullptr;
-	DynamicArray<Vec3> m_verts;
+	DynamicArray<Vec3, FrameMemoryPoolWrapper> m_verts;
 	Atomic<U32> m_rasterizedVertCount = {0}; ///< That will be used by the RasterizeTrianglesTask.
 
 	// Visibility test members
-	DynamicArray<RenderQueueView> m_queueViews; ///< Sub result. Will be combined later.
+	DynamicArray<RenderQueueView, FrameMemoryPoolWrapper> m_queueViews; ///< Sub result. Will be combined later.
 	ThreadHiveSemaphore* m_visTestsSignalSem = nullptr;
 
 	// Gather results members
@@ -263,7 +287,7 @@ public:
 
 private:
 	template<typename T>
-	static void combineQueueElements(StackMemoryPool& pool, WeakArray<TRenderQueueElementStorage<T>> subStorages,
+	static void combineQueueElements(WeakArray<TRenderQueueElementStorage<T>> subStorages,
 									 WeakArray<TRenderQueueElementStorage<U32>>* ptrSubStorage, WeakArray<T>& combined,
 									 WeakArray<T*>* ptrCombined);
 };

+ 1 - 1
AnKi/ShaderCompiler/Common.h

@@ -29,7 +29,7 @@ using MutatorValue = I32; ///< The type of the mutator value
 class ShaderProgramFilesystemInterface
 {
 public:
-	virtual Error readAllText(CString filename, StringRaii& txt) = 0;
+	virtual Error readAllText(CString filename, String& txt) = 0;
 };
 
 /// This controls if the compilation will continue after the parsing stage.

+ 29 - 28
AnKi/ShaderCompiler/Dxc.cpp

@@ -50,55 +50,56 @@ static CString profile(ShaderType shaderType)
 	return "";
 }
 
-Error compileHlslToSpirv(CString src, ShaderType shaderType, Bool compileWith16bitTypes, BaseMemoryPool& tmpPool,
-						 DynamicArrayRaii<U8>& spirv, StringRaii& errorMessage)
+Error compileHlslToSpirv(CString src, ShaderType shaderType, Bool compileWith16bitTypes, DynamicArray<U8>& spirv,
+						 String& errorMessage)
 {
 	Array<U64, 3> toHash = {g_nextFileId.fetchAdd(1), getCurrentProcessId(), getRandom() & kMaxU32};
 	const U64 rand = computeHash(&toHash[0], sizeof(toHash));
 
-	StringRaii tmpDir(&tmpPool);
+	String tmpDir;
 	ANKI_CHECK(getTempDirectory(tmpDir));
 
 	// Store HLSL to a file
-	StringRaii hlslFilename(&tmpPool);
+	String hlslFilename;
 	hlslFilename.sprintf("%s/%" PRIu64 ".hlsl", tmpDir.cstr(), rand);
 
 	File hlslFile;
 	ANKI_CHECK(hlslFile.open(hlslFilename, FileOpenFlag::kWrite));
-	CleanupFile hlslFileCleanup(&tmpPool, hlslFilename);
+	CleanupFile hlslFileCleanup(hlslFilename);
 	ANKI_CHECK(hlslFile.writeText(src));
 	hlslFile.close();
 
 	// Call DXC
-	StringRaii spvFilename(&tmpPool);
+	String spvFilename;
 	spvFilename.sprintf("%s/%" PRIu64 ".spv", tmpDir.cstr(), rand);
 
-	DynamicArrayRaii<StringRaii> dxcArgs(&tmpPool);
-	dxcArgs.emplaceBack("-Fo", &tmpPool);
-	dxcArgs.emplaceBack(spvFilename, &tmpPool);
-	dxcArgs.emplaceBack("-Wall", &tmpPool);
-	dxcArgs.emplaceBack("-Wextra", &tmpPool);
-	dxcArgs.emplaceBack("-Wno-conversion", &tmpPool);
-	dxcArgs.emplaceBack("-Werror", &tmpPool);
-	dxcArgs.emplaceBack("-Wfatal-errors", &tmpPool);
-	dxcArgs.emplaceBack("-Wundef", &tmpPool);
-	dxcArgs.emplaceBack("-Wno-unused-const-variable", &tmpPool);
-	dxcArgs.emplaceBack("-HV", &tmpPool);
-	dxcArgs.emplaceBack("2021", &tmpPool);
-	dxcArgs.emplaceBack("-E", &tmpPool);
-	dxcArgs.emplaceBack("main", &tmpPool);
-	dxcArgs.emplaceBack("-T", &tmpPool);
-	dxcArgs.emplaceBack(profile(shaderType), &tmpPool);
-	dxcArgs.emplaceBack("-spirv", &tmpPool);
-	dxcArgs.emplaceBack("-fspv-target-env=vulkan1.1spirv1.4", &tmpPool);
+	DynamicArray<String> dxcArgs;
+	dxcArgs.emplaceBack("-Fo");
+	dxcArgs.emplaceBack(spvFilename);
+	dxcArgs.emplaceBack("-Wall");
+	dxcArgs.emplaceBack("-Wextra");
+	dxcArgs.emplaceBack("-Wno-conversion");
+	dxcArgs.emplaceBack("-Werror");
+	dxcArgs.emplaceBack("-Wfatal-errors");
+	dxcArgs.emplaceBack("-Wundef");
+	dxcArgs.emplaceBack("-Wno-unused-const-variable");
+	dxcArgs.emplaceBack("-HV");
+	dxcArgs.emplaceBack("2021");
+	dxcArgs.emplaceBack("-E");
+	dxcArgs.emplaceBack("main");
+	dxcArgs.emplaceBack("-T");
+	dxcArgs.emplaceBack(profile(shaderType));
+	dxcArgs.emplaceBack("-spirv");
+	dxcArgs.emplaceBack("-fspv-target-env=vulkan1.1spirv1.4");
 	dxcArgs.emplaceBack(hlslFilename);
 
 	if(compileWith16bitTypes)
 	{
-		dxcArgs.emplaceBack("-enable-16bit-types", &tmpPool);
+		dxcArgs.emplaceBack("-enable-16bit-types");
 	}
 
-	DynamicArrayRaii<CString> dxcArgs2(dxcArgs.getSize(), &tmpPool);
+	DynamicArray<CString> dxcArgs2;
+	dxcArgs2.resize(dxcArgs.getSize());
 	for(U32 i = 0; i < dxcArgs.getSize(); ++i)
 	{
 		dxcArgs2[i] = dxcArgs[i];
@@ -107,7 +108,7 @@ Error compileHlslToSpirv(CString src, ShaderType shaderType, Bool compileWith16b
 	while(true)
 	{
 		I32 exitCode;
-		StringRaii stdOut(&tmpPool);
+		String stdOut;
 
 #if ANKI_OS_WINDOWS
 		CString dxcBin = ANKI_SOURCE_DIRECTORY "/ThirdParty/Bin/Windows64/dxc.exe";
@@ -149,7 +150,7 @@ Error compileHlslToSpirv(CString src, ShaderType shaderType, Bool compileWith16b
 		}
 	}
 
-	CleanupFile spvFileCleanup(&tmpPool, spvFilename);
+	CleanupFile spvFileCleanup(spvFilename);
 
 	// Read the spirv back
 	File spvFile;

+ 2 - 2
AnKi/ShaderCompiler/Dxc.h

@@ -14,8 +14,8 @@ namespace anki {
 /// @{
 
 /// Compile HLSL to SPIR-V.
-Error compileHlslToSpirv(CString src, ShaderType shaderType, Bool compileWith16bitTypes, BaseMemoryPool& tmpPool,
-						 DynamicArrayRaii<U8>& spirv, StringRaii& errorMessage);
+Error compileHlslToSpirv(CString src, ShaderType shaderType, Bool compileWith16bitTypes, DynamicArray<U8>& spirv,
+						 String& errorMessage);
 /// @}
 
 } // end namespace anki

+ 9 - 9
AnKi/ShaderCompiler/MaliOfflineCompiler.cpp

@@ -71,26 +71,27 @@ static CString hwUnitToStr(MaliOfflineCompilerHwUnit u)
 	return out;
 }
 
-void MaliOfflineCompilerOut::toString(StringRaii& str) const
+String MaliOfflineCompilerOut::toString() const
 {
-	str.destroy();
+	String str;
 	str.sprintf("Regs %u Spilling %u "
 				"FMA %f CVT %f SFU %f LS %f VAR %f TEX %f Bound %s "
 				"FP16 %f%%",
 				m_workRegisters, m_spilling, m_fma, m_cvt, m_sfu, m_loadStore, m_varying, m_texture,
 				hwUnitToStr(m_boundUnit).cstr(), m_fp16ArithmeticPercentage);
+	return str;
 }
 
 Error runMaliOfflineCompiler(CString maliocExecutable, ConstWeakArray<U8> spirv, ShaderType shaderType,
-							 BaseMemoryPool& tmpPool, MaliOfflineCompilerOut& out)
+							 MaliOfflineCompilerOut& out)
 {
 	out = {};
 	const U32 rand = g_nextFileId.fetchAdd(1) + getCurrentProcessId();
 
 	// Create temp file to dump the spirv
-	StringRaii tmpDir(&tmpPool);
+	String tmpDir;
 	ANKI_CHECK(getTempDirectory(tmpDir));
-	StringRaii spirvFilename(&tmpPool);
+	String spirvFilename;
 	spirvFilename.sprintf("%s/AnKiMaliocInputSpirv_%u.spv", tmpDir.cstr(), rand);
 
 	File spirvFile;
@@ -101,7 +102,7 @@ Error runMaliOfflineCompiler(CString maliocExecutable, ConstWeakArray<U8> spirv,
 	CleanupFile cleanupSpirvFile(spirvFilename);
 
 	// Tmp filename
-	StringRaii analysisFilename(&tmpPool);
+	String analysisFilename;
 	analysisFilename.sprintf("%s/AnKiMaliocOut_%u.txt", tmpDir.cstr(), rand);
 
 	// Set the arguments
@@ -143,7 +144,7 @@ Error runMaliOfflineCompiler(CString maliocExecutable, ConstWeakArray<U8> spirv,
 	// Read the output file
 	File analysisFile;
 	ANKI_CHECK(analysisFile.open(analysisFilename, FileOpenFlag::kRead));
-	StringRaii analysisText(&tmpPool);
+	String analysisText;
 	ANKI_CHECK(analysisFile.readAllText(analysisText));
 	analysisText.replaceAll("\r", "");
 	analysisFile.close();
@@ -308,8 +309,7 @@ Error runMaliOfflineCompiler(CString maliocExecutable, ConstWeakArray<U8> spirv,
 	if(false)
 	{
 		printf("%s\n", analysisText.cstr());
-		StringRaii str(&tmpPool);
-		out.toString(str);
+		String str = out.toString();
 		printf("%s\n", str.cstr());
 	}
 

+ 2 - 2
AnKi/ShaderCompiler/MaliOfflineCompiler.h

@@ -41,12 +41,12 @@ public:
 	U32 m_spilling = 0;
 	F32 m_fp16ArithmeticPercentage = 0.0f;
 
-	void toString(StringRaii& str) const;
+	String toString() const;
 };
 
 /// Run the mali offline compiler and get some info back.
 Error runMaliOfflineCompiler(CString maliocExecutable, ConstWeakArray<U8> spirv, ShaderType shaderType,
-							 BaseMemoryPool& tmpPool, MaliOfflineCompilerOut& out);
+							 MaliOfflineCompilerOut& out);
 /// @}
 
 } // end namespace anki

+ 9 - 10
AnKi/ShaderCompiler/RadeonGpuAnalyzer.cpp

@@ -34,16 +34,15 @@ static CString getPipelineStageString(ShaderType shaderType)
 	return out;
 }
 
-Error runRadeonGpuAnalyzer(CString rgaExecutable, ConstWeakArray<U8> spirv, ShaderType shaderType,
-						   BaseMemoryPool& tmpPool, RgaOutput& out)
+Error runRadeonGpuAnalyzer(CString rgaExecutable, ConstWeakArray<U8> spirv, ShaderType shaderType, RgaOutput& out)
 {
 	ANKI_ASSERT(spirv.getSize() > 0);
 	const U32 rand = g_nextFileId.fetchAdd(1) + getCurrentProcessId();
 
 	// Store SPIRV
-	StringRaii tmpDir(&tmpPool);
+	String tmpDir;
 	ANKI_CHECK(getTempDirectory(tmpDir));
-	StringRaii spvFilename(&tmpPool);
+	String spvFilename;
 	spvFilename.sprintf("%s/AnKiRgaInput_%u.spv", tmpDir.cstr(), rand);
 	File spvFile;
 	ANKI_CHECK(spvFile.open(spvFilename, FileOpenFlag::kWrite | FileOpenFlag::kBinary));
@@ -52,7 +51,7 @@ Error runRadeonGpuAnalyzer(CString rgaExecutable, ConstWeakArray<U8> spirv, Shad
 	CleanupFile spvFileCleanup(spvFilename);
 
 	// Call RGA
-	StringRaii analysisFilename(&tmpPool);
+	String analysisFilename;
 	analysisFilename.sprintf("%s/AnKiRgaOutAnalysis_%u.csv", tmpDir.cstr(), rand);
 
 	Array<CString, 7> args;
@@ -74,7 +73,7 @@ Error runRadeonGpuAnalyzer(CString rgaExecutable, ConstWeakArray<U8> spirv, Shad
 	}
 
 	// Construct the output filename
-	StringRaii outFilename(&tmpPool);
+	String outFilename;
 	outFilename.sprintf("%s/gfx1030_AnKiRgaOutAnalysis_%u_%s.csv", tmpDir.cstr(), rand,
 						getPipelineStageString(shaderType).cstr());
 
@@ -83,13 +82,13 @@ Error runRadeonGpuAnalyzer(CString rgaExecutable, ConstWeakArray<U8> spirv, Shad
 	// Read the file
 	File analysisFile;
 	ANKI_CHECK(analysisFile.open(outFilename, FileOpenFlag::kRead));
-	StringRaii analysisText(&tmpPool);
+	String analysisText;
 	ANKI_CHECK(analysisFile.readAllText(analysisText));
 	analysisText.replaceAll("\r", "");
 	analysisFile.close();
 
 	// Parse the text
-	StringListRaii lines(&tmpPool);
+	StringList lines;
 	lines.splitString(analysisText, '\n');
 	if(lines.getSize() != 2)
 	{
@@ -97,10 +96,10 @@ Error runRadeonGpuAnalyzer(CString rgaExecutable, ConstWeakArray<U8> spirv, Shad
 		return Error::kFunctionFailed;
 	}
 
-	StringListRaii tokens(&tmpPool);
+	StringList tokens;
 	tokens.splitString(lines.getFront(), ',');
 
-	StringListRaii values(&tmpPool);
+	StringList values;
 	values.splitString(*(lines.getBegin() + 1), ',');
 
 	if(tokens.getSize() != tokens.getSize())

+ 2 - 3
AnKi/ShaderCompiler/RadeonGpuAnalyzer.h

@@ -21,12 +21,11 @@ public:
 	U32 m_sgprCount;
 	U32 m_isaSize;
 
-	void toString(StringRaii& str) const;
+	void toString(String& str) const;
 };
 
 /// Run the mali offline compiler and get some info back.
-Error runRadeonGpuAnalyzer(CString rgaExecutable, ConstWeakArray<U8> spirv, ShaderType shaderType,
-						   BaseMemoryPool& tmpPool, RgaOutput& out);
+Error runRadeonGpuAnalyzer(CString rgaExecutable, ConstWeakArray<U8> spirv, ShaderType shaderType, RgaOutput& out);
 /// @}
 
 } // end namespace anki

+ 84 - 89
AnKi/ShaderCompiler/ShaderProgramCompiler.cpp

@@ -128,7 +128,7 @@ void ShaderProgramBinaryWrapper::cleanup()
 }
 
 /// Spin the dials. Used to compute all mutator combinations.
-static Bool spinDials(DynamicArrayRaii<U32>& dials, ConstWeakArray<ShaderProgramParserMutator> mutators)
+static Bool spinDials(DynamicArray<U32>& dials, ConstWeakArray<ShaderProgramParserMutator> mutators)
 {
 	ANKI_ASSERT(dials.getSize() == mutators.getSize() && dials.getSize() > 0);
 	Bool done = true;
@@ -164,8 +164,7 @@ static Bool spinDials(DynamicArrayRaii<U32>& dials, ConstWeakArray<ShaderProgram
 }
 
 static Error compileSpirv(ConstWeakArray<MutatorValue> mutation, const ShaderProgramParser& parser,
-						  BaseMemoryPool& tempPool, Array<DynamicArrayRaii<U8>, U32(ShaderType::kCount)>& spirv,
-						  StringRaii& errorLog)
+						  Array<DynamicArray<U8>, U32(ShaderType::kCount)>& spirv, String& errorLog)
 {
 	// Generate the source and the rest for the variant
 	ShaderProgramParserVariant parserVariant;
@@ -181,44 +180,38 @@ static Error compileSpirv(ConstWeakArray<MutatorValue> mutation, const ShaderPro
 
 		// Compile
 		ANKI_CHECK(compileHlslToSpirv(parserVariant.getSource(shaderType), shaderType, parser.compileWith16bitTypes(),
-									  tempPool, spirv[shaderType], errorLog));
+									  spirv[shaderType], errorLog));
 		ANKI_ASSERT(spirv[shaderType].getSize() > 0);
 	}
 
 	return Error::kNone;
 }
 
-static void compileVariantAsync(ConstWeakArray<MutatorValue> mutation, const ShaderProgramParser& parser,
-								ShaderProgramBinaryVariant& variant,
-								DynamicArrayRaii<ShaderProgramBinaryCodeBlock>& codeBlocks,
-								DynamicArrayRaii<U64>& codeBlockHashes, BaseMemoryPool& tmpPool,
-								BaseMemoryPool& binaryPool, ShaderProgramAsyncTaskInterface& taskManager, Mutex& mtx,
-								Atomic<I32>& error)
+static void
+compileVariantAsync(ConstWeakArray<MutatorValue> mutation, const ShaderProgramParser& parser,
+					ShaderProgramBinaryVariant& variant,
+					DynamicArray<ShaderProgramBinaryCodeBlock, MemoryPoolPtrWrapper<BaseMemoryPool>>& codeBlocks,
+					DynamicArray<U64>& codeBlockHashes, BaseMemoryPool& binaryPool,
+					ShaderProgramAsyncTaskInterface& taskManager, Mutex& mtx, Atomic<I32>& error)
 {
 	variant = {};
 
 	class Ctx
 	{
 	public:
-		BaseMemoryPool* m_tmpPool;
 		BaseMemoryPool* m_binaryPool;
-		DynamicArrayRaii<MutatorValue> m_mutation = {m_tmpPool};
+		DynamicArray<MutatorValue> m_mutation;
 		const ShaderProgramParser* m_parser;
 		ShaderProgramBinaryVariant* m_variant;
-		DynamicArrayRaii<ShaderProgramBinaryCodeBlock>* m_codeBlocks;
-		DynamicArrayRaii<U64>* m_codeBlockHashes;
+		DynamicArray<ShaderProgramBinaryCodeBlock, MemoryPoolPtrWrapper<BaseMemoryPool>>* m_codeBlocks;
+		DynamicArray<U64>* m_codeBlockHashes;
 		Mutex* m_mtx;
 		Atomic<I32>* m_err;
-
-		Ctx(BaseMemoryPool* tmpPool)
-			: m_tmpPool(tmpPool)
-		{
-		}
 	};
 
-	Ctx* ctx = newInstance<Ctx>(tmpPool, &tmpPool);
+	Ctx* ctx = newInstance<Ctx>(DefaultMemoryPool::getSingleton());
 	ctx->m_binaryPool = &binaryPool;
-	ctx->m_mutation.create(mutation.getSize());
+	ctx->m_mutation.resize(mutation.getSize());
 	memcpy(ctx->m_mutation.getBegin(), mutation.getBegin(), mutation.getSizeInBytes());
 	ctx->m_parser = &parser;
 	ctx->m_variant = &variant;
@@ -229,30 +222,18 @@ static void compileVariantAsync(ConstWeakArray<MutatorValue> mutation, const Sha
 
 	auto callback = [](void* userData) {
 		Ctx& ctx = *static_cast<Ctx*>(userData);
-		BaseMemoryPool& tmpPool = *ctx.m_tmpPool;
 
 		if(ctx.m_err->load() != 0)
 		{
 			// Cleanup and return
-			deleteInstance(tmpPool, &ctx);
+			deleteInstance(DefaultMemoryPool::getSingleton(), &ctx);
 			return;
 		}
 
 		// All good, compile the variant
-		Array<DynamicArrayRaii<U8>, U32(ShaderType::kCount)> spirvs = {{{&tmpPool},
-																		{&tmpPool},
-																		{&tmpPool},
-																		{&tmpPool},
-																		{&tmpPool},
-																		{&tmpPool},
-																		{&tmpPool},
-																		{&tmpPool},
-																		{&tmpPool},
-																		{&tmpPool},
-																		{&tmpPool},
-																		{&tmpPool}}};
-		StringRaii errorLog(&tmpPool);
-		const Error err = compileSpirv(ctx.m_mutation, *ctx.m_parser, tmpPool, spirvs, errorLog);
+		Array<DynamicArray<U8>, U32(ShaderType::kCount)> spirvs;
+		String errorLog;
+		const Error err = compileSpirv(ctx.m_mutation, *ctx.m_parser, spirvs, errorLog);
 
 		if(!err)
 		{
@@ -262,7 +243,7 @@ static void compileVariantAsync(ConstWeakArray<MutatorValue> mutation, const Sha
 
 			for(ShaderType shaderType : EnumIterable<ShaderType>())
 			{
-				DynamicArrayRaii<U8>& spirv = spirvs[shaderType];
+				DynamicArray<U8>& spirv = spirvs[shaderType];
 
 				if(spirv.isEmpty())
 				{
@@ -312,7 +293,7 @@ static void compileVariantAsync(ConstWeakArray<MutatorValue> mutation, const Sha
 		}
 
 		// Cleanup
-		deleteInstance(tmpPool, &ctx);
+		deleteInstance(DefaultMemoryPool::getSingleton(), &ctx);
 	};
 
 	taskManager.enqueueTask(callback, ctx);
@@ -328,31 +309,40 @@ public:
 	/// @{
 
 	/// [blockType][blockIdx]
-	Array<DynamicArrayRaii<ShaderProgramBinaryBlock>, 3> m_blocks = {{{m_pool}, {m_pool}, {m_pool}}};
+	Array<DynamicArray<ShaderProgramBinaryBlock, MemoryPoolPtrWrapper<BaseMemoryPool>>, 3> m_blocks = {
+		{{m_pool}, {m_pool}, {m_pool}}};
 
 	/// [blockType][blockIdx][varIdx]
-	Array<DynamicArrayRaii<DynamicArrayRaii<ShaderProgramBinaryVariable>>, 3> m_vars = {{{m_pool}, {m_pool}, {m_pool}}};
+	Array<DynamicArray<DynamicArray<ShaderProgramBinaryVariable, MemoryPoolPtrWrapper<BaseMemoryPool>>,
+					   MemoryPoolPtrWrapper<BaseMemoryPool>>,
+		  3>
+		m_vars = {{{m_pool}, {m_pool}, {m_pool}}};
 
-	DynamicArrayRaii<ShaderProgramBinaryOpaque> m_opaque = {m_pool};
-	DynamicArrayRaii<ShaderProgramBinaryConstant> m_consts = {m_pool};
+	DynamicArray<ShaderProgramBinaryOpaque, MemoryPoolPtrWrapper<BaseMemoryPool>> m_opaque = {m_pool};
+	DynamicArray<ShaderProgramBinaryConstant, MemoryPoolPtrWrapper<BaseMemoryPool>> m_consts = {m_pool};
 
-	DynamicArrayRaii<ShaderProgramBinaryStruct> m_structs = {m_pool};
+	DynamicArray<ShaderProgramBinaryStruct, MemoryPoolPtrWrapper<BaseMemoryPool>> m_structs = {m_pool};
 	/// [structIndex][memberIndex]
-	DynamicArrayRaii<DynamicArrayRaii<ShaderProgramBinaryStructMember>> m_structMembers = {m_pool};
+	DynamicArray<DynamicArray<ShaderProgramBinaryStructMember, MemoryPoolPtrWrapper<BaseMemoryPool>>,
+				 MemoryPoolPtrWrapper<BaseMemoryPool>>
+		m_structMembers = {m_pool};
 	/// @}
 
 	/// Will be stored in a variant
 	/// @{
 
 	/// [blockType][blockInstanceIdx]
-	Array<DynamicArrayRaii<ShaderProgramBinaryBlockInstance>, 3> m_blockInstances = {{{m_pool}, {m_pool}, {m_pool}}};
+	Array<DynamicArray<ShaderProgramBinaryBlockInstance, MemoryPoolPtrWrapper<BaseMemoryPool>>, 3> m_blockInstances = {
+		{{m_pool}, {m_pool}, {m_pool}}};
 
-	DynamicArrayRaii<ShaderProgramBinaryOpaqueInstance> m_opaqueInstances = {m_pool};
-	DynamicArrayRaii<ShaderProgramBinaryConstantInstance> m_constInstances = {m_pool};
+	DynamicArray<ShaderProgramBinaryOpaqueInstance, MemoryPoolPtrWrapper<BaseMemoryPool>> m_opaqueInstances = {m_pool};
+	DynamicArray<ShaderProgramBinaryConstantInstance, MemoryPoolPtrWrapper<BaseMemoryPool>> m_constInstances = {m_pool};
 
-	DynamicArrayRaii<ShaderProgramBinaryStructInstance> m_structInstances = {m_pool};
+	DynamicArray<ShaderProgramBinaryStructInstance, MemoryPoolPtrWrapper<BaseMemoryPool>> m_structInstances = {m_pool};
 	/// [structInstance][memberInstance]
-	DynamicArrayRaii<DynamicArrayRaii<ShaderProgramBinaryStructMemberInstance>> m_structMemberInstances = {m_pool};
+	DynamicArray<DynamicArray<ShaderProgramBinaryStructMemberInstance, MemoryPoolPtrWrapper<BaseMemoryPool>>,
+				 MemoryPoolPtrWrapper<BaseMemoryPool>>
+		m_structMemberInstances = {m_pool};
 
 	Array<U32, 3> m_workgroupSizes = {kMaxU32, kMaxU32, kMaxU32};
 	Array<U32, 3> m_workgroupSizesConstants = {kMaxU32, kMaxU32, kMaxU32};
@@ -403,16 +393,16 @@ public:
 	Error setCounts(U32 uniformBlockCount, U32 storageBlockCount, U32 opaqueCount, Bool pushConstantBlock,
 					U32 constCount, U32 structCount) final
 	{
-		m_blockInstances[0].create(uniformBlockCount);
-		m_blockInstances[1].create(storageBlockCount);
+		m_blockInstances[0].resize(uniformBlockCount);
+		m_blockInstances[1].resize(storageBlockCount);
 		if(pushConstantBlock)
 		{
-			m_blockInstances[2].create(1);
+			m_blockInstances[2].resize(1);
 		}
-		m_opaqueInstances.create(opaqueCount);
-		m_constInstances.create(constCount);
-		m_structInstances.create(structCount);
-		m_structMemberInstances.create(structCount, {m_pool});
+		m_opaqueInstances.resize(opaqueCount);
+		m_constInstances.resize(constCount);
+		m_structInstances.resize(structCount);
+		m_structMemberInstances.resize(structCount, m_pool);
 		return Error::kNone;
 	}
 
@@ -584,7 +574,7 @@ public:
 		instance.m_index = structIdx;
 		instance.m_size = size;
 
-		m_structMemberInstances[instanceIdx].create(memberCount);
+		m_structMemberInstances[instanceIdx].resize(memberCount);
 
 		return Error::kNone;
 	}
@@ -597,7 +587,8 @@ public:
 		[[maybe_unused]] const Bool structFound = findStruct(structName, realStructIdx);
 		ANKI_ASSERT(structFound);
 		const ShaderProgramBinaryStruct& s = m_structs[realStructIdx];
-		DynamicArrayRaii<ShaderProgramBinaryStructMember>& members = m_structMembers[realStructIdx];
+		DynamicArray<ShaderProgramBinaryStructMember, MemoryPoolPtrWrapper<BaseMemoryPool>>& members =
+			m_structMembers[realStructIdx];
 
 		// Find member
 		U32 realMemberIdx = kMaxU32;
@@ -761,10 +752,10 @@ public:
 
 static Error doGhostStructReflection(const StringList& symbolsToReflect,
 									 ConstWeakArray<ShaderProgramParserGhostStruct> ghostStructs,
-									 ShaderProgramBinary& binary, BaseMemoryPool& tmpPool, BaseMemoryPool& binaryPool)
+									 ShaderProgramBinary& binary, BaseMemoryPool& binaryPool)
 {
 	// Count reflectable ghost structs
-	DynamicArrayRaii<U32> ghostStructIndices(&tmpPool);
+	DynamicArray<U32> ghostStructIndices;
 	for(U32 i = 0; i < ghostStructs.getSize(); ++i)
 	{
 		for(const String& s : symbolsToReflect)
@@ -784,8 +775,8 @@ static Error doGhostStructReflection(const StringList& symbolsToReflect,
 
 	// Add the ghost structs to binary structs
 	const U32 nonGhostStructCount = binary.m_structs.getSize();
-	DynamicArrayRaii<ShaderProgramBinaryStruct> structs(nonGhostStructCount + ghostStructIndices.getSize(),
-														&binaryPool);
+	DynamicArray<ShaderProgramBinaryStruct, MemoryPoolPtrWrapper<BaseMemoryPool>> structs(&binaryPool);
+	structs.resize(nonGhostStructCount + ghostStructIndices.getSize());
 
 	for(U32 i = 0; i < binary.m_structs.getSize(); ++i)
 	{
@@ -799,7 +790,8 @@ static Error doGhostStructReflection(const StringList& symbolsToReflect,
 
 		ANKI_CHECK(Refl::setName(in.m_name, out.m_name));
 
-		DynamicArrayRaii<ShaderProgramBinaryStructMember> members(in.m_members.getSize(), &binaryPool);
+		DynamicArray<ShaderProgramBinaryStructMember, MemoryPoolPtrWrapper<BaseMemoryPool>> members(&binaryPool);
+		members.resize(in.m_members.getSize());
 		for(U32 j = 0; j < in.m_members.getSize(); ++j)
 		{
 			const ShaderProgramParserMember& inMember = in.m_members[j];
@@ -820,8 +812,7 @@ static Error doGhostStructReflection(const StringList& symbolsToReflect,
 	return Error::kNone;
 }
 
-static Error doReflection(const StringList& symbolsToReflect, ShaderProgramBinary& binary, BaseMemoryPool& tmpPool,
-						  BaseMemoryPool& binaryPool)
+static Error doReflection(const StringList& symbolsToReflect, ShaderProgramBinary& binary, BaseMemoryPool& binaryPool)
 {
 	ANKI_ASSERT(binary.m_variants.getSize() > 0);
 
@@ -838,7 +829,7 @@ static Error doReflection(const StringList& symbolsToReflect, ShaderProgramBinar
 			}
 		}
 
-		ANKI_CHECK(performSpirvReflection(spirvs, tmpPool, refl));
+		ANKI_CHECK(performSpirvReflection(spirvs, refl));
 
 		// Store the instances
 		if(refl.m_blockInstances[0].getSize())
@@ -986,7 +977,7 @@ static Error doReflection(const StringList& symbolsToReflect, ShaderProgramBinar
 
 Error compileShaderProgramInternal(CString fname, ShaderProgramFilesystemInterface& fsystem,
 								   ShaderProgramPostParseInterface* postParseCallback,
-								   ShaderProgramAsyncTaskInterface* taskManager_, BaseMemoryPool& tempPool,
+								   ShaderProgramAsyncTaskInterface* taskManager_,
 								   const ShaderCompilerOptions& compilerOptions, ShaderProgramBinaryWrapper& binaryW)
 {
 	// Initialize the binary
@@ -999,7 +990,7 @@ Error compileShaderProgramInternal(CString fname, ShaderProgramFilesystemInterfa
 	memcpy(&binary.m_magic[0], kShaderBinaryMagic, 8);
 
 	// Parse source
-	ShaderProgramParser parser(fname, &fsystem, &tempPool, compilerOptions);
+	ShaderProgramParser parser(fname, &fsystem, compilerOptions);
 	ANKI_CHECK(parser.parse());
 
 	if(postParseCallback && postParseCallback->skipCompilation(parser.getHash()))
@@ -1054,13 +1045,16 @@ Error compileShaderProgramInternal(CString fname, ShaderProgramFilesystemInterfa
 	if(parser.getMutators().getSize() > 0)
 	{
 		// Initialize
-		DynamicArrayRaii<MutatorValue> mutationValues(parser.getMutators().getSize(), &tempPool);
-		DynamicArrayRaii<U32> dials(parser.getMutators().getSize(), 0, &tempPool);
-		DynamicArrayRaii<ShaderProgramBinaryVariant> variants(&binaryPool);
-		DynamicArrayRaii<ShaderProgramBinaryCodeBlock> codeBlocks(&binaryPool);
-		DynamicArrayRaii<ShaderProgramBinaryMutation> mutations(mutationCount, &binaryPool);
-		DynamicArrayRaii<U64> codeBlockHashes(&tempPool);
-		HashMapRaii<U64, U32> mutationHashToIdx(&tempPool);
+		DynamicArray<MutatorValue> mutationValues;
+		mutationValues.resize(parser.getMutators().getSize());
+		DynamicArray<U32> dials;
+		dials.resize(parser.getMutators().getSize(), 0);
+		DynamicArray<ShaderProgramBinaryVariant, MemoryPoolPtrWrapper<BaseMemoryPool>> variants(&binaryPool);
+		DynamicArray<ShaderProgramBinaryCodeBlock, MemoryPoolPtrWrapper<BaseMemoryPool>> codeBlocks(&binaryPool);
+		DynamicArray<ShaderProgramBinaryMutation, MemoryPoolPtrWrapper<BaseMemoryPool>> mutations(&binaryPool);
+		mutations.resize(mutationCount);
+		DynamicArray<U64> codeBlockHashes;
+		HashMap<U64, U32> mutationHashToIdx;
 
 		// Grow the storage of the variants array. Can't have it resize, threads will work on stale data
 		variants.resizeStorage(mutationCount);
@@ -1097,7 +1091,7 @@ Error compileShaderProgramInternal(CString fname, ShaderProgramFilesystemInterfa
 				ShaderProgramBinaryVariant& variant = *variants.emplaceBack();
 				baseVariant = (baseVariant == nullptr) ? variants.getBegin() : baseVariant;
 
-				compileVariantAsync(mutationValues, parser, variant, codeBlocks, codeBlockHashes, tempPool, binaryPool,
+				compileVariantAsync(mutationValues, parser, variant, codeBlocks, codeBlockHashes, binaryPool,
 									taskManager, mtx, errorAtomic);
 
 				mutation.m_variantIndex = variants.getSize() - 1;
@@ -1112,7 +1106,6 @@ Error compileShaderProgramInternal(CString fname, ShaderProgramFilesystemInterfa
 
 		// Done, wait the threads
 		ANKI_CHECK(taskManager.joinTasks());
-		ANKI_CHECK(Error(errorAtomic.getNonAtomically()));
 
 		// Store temp containers to binary
 		U32 size, storage;
@@ -1127,16 +1120,19 @@ Error compileShaderProgramInternal(CString fname, ShaderProgramFilesystemInterfa
 		ShaderProgramBinaryMutation* firstMutation;
 		mutations.moveAndReset(firstMutation, size, storage);
 		binary.m_mutations.setArray(firstMutation, size);
+
+		// Now error out
+		ANKI_CHECK(Error(errorAtomic.getNonAtomically()));
 	}
 	else
 	{
-		DynamicArrayRaii<MutatorValue> mutation(&tempPool);
-		DynamicArrayRaii<ShaderProgramBinaryCodeBlock> codeBlocks(&binaryPool);
-		DynamicArrayRaii<U64> codeBlockHashes(&tempPool);
+		DynamicArray<MutatorValue> mutation;
+		DynamicArray<ShaderProgramBinaryCodeBlock, MemoryPoolPtrWrapper<BaseMemoryPool>> codeBlocks(&binaryPool);
+		DynamicArray<U64> codeBlockHashes;
 
 		binary.m_variants.setArray(newInstance<ShaderProgramBinaryVariant>(binaryPool), 1);
 
-		compileVariantAsync(mutation, parser, binary.m_variants[0], codeBlocks, codeBlockHashes, tempPool, binaryPool,
+		compileVariantAsync(mutation, parser, binary.m_variants[0], codeBlocks, codeBlockHashes, binaryPool,
 							taskManager, mtx, errorAtomic);
 
 		ANKI_CHECK(taskManager.joinTasks());
@@ -1178,20 +1174,19 @@ Error compileShaderProgramInternal(CString fname, ShaderProgramFilesystemInterfa
 	binary.m_presentShaderTypes = parser.getShaderTypes();
 
 	// Reflection
-	ANKI_CHECK(doReflection(parser.getSymbolsToReflect(), binary, tempPool, binaryPool));
-	ANKI_CHECK(
-		doGhostStructReflection(parser.getSymbolsToReflect(), parser.getGhostStructs(), binary, tempPool, binaryPool));
+	ANKI_CHECK(doReflection(parser.getSymbolsToReflect(), binary, binaryPool));
+	ANKI_CHECK(doGhostStructReflection(parser.getSymbolsToReflect(), parser.getGhostStructs(), binary, binaryPool));
 
 	return Error::kNone;
 }
 
 Error compileShaderProgram(CString fname, ShaderProgramFilesystemInterface& fsystem,
 						   ShaderProgramPostParseInterface* postParseCallback,
-						   ShaderProgramAsyncTaskInterface* taskManager, BaseMemoryPool& tempPool,
-						   const ShaderCompilerOptions& compilerOptions, ShaderProgramBinaryWrapper& binaryW)
+						   ShaderProgramAsyncTaskInterface* taskManager, const ShaderCompilerOptions& compilerOptions,
+						   ShaderProgramBinaryWrapper& binaryW)
 {
-	const Error err = compileShaderProgramInternal(fname, fsystem, postParseCallback, taskManager, tempPool,
-												   compilerOptions, binaryW);
+	const Error err =
+		compileShaderProgramInternal(fname, fsystem, postParseCallback, taskManager, compilerOptions, binaryW);
 	if(err)
 	{
 		ANKI_SHADER_COMPILER_LOGE("Failed to compile: %s", fname.cstr());

+ 3 - 3
AnKi/ShaderCompiler/ShaderProgramCompiler.h

@@ -23,7 +23,7 @@ class ShaderProgramBinaryWrapper
 {
 	friend Error compileShaderProgramInternal(CString fname, ShaderProgramFilesystemInterface& fsystem,
 											  ShaderProgramPostParseInterface* postParseCallback,
-											  ShaderProgramAsyncTaskInterface* taskManager, BaseMemoryPool& tempPool,
+											  ShaderProgramAsyncTaskInterface* taskManager,
 											  const ShaderCompilerOptions& compilerOptions,
 											  ShaderProgramBinaryWrapper& binary);
 
@@ -84,8 +84,8 @@ Error ShaderProgramBinaryWrapper::deserializeFromAnyFile(TFile& file)
 /// Takes an AnKi special shader program and spits a binary.
 Error compileShaderProgram(CString fname, ShaderProgramFilesystemInterface& fsystem,
 						   ShaderProgramPostParseInterface* postParseCallback,
-						   ShaderProgramAsyncTaskInterface* taskManager, BaseMemoryPool& tempPool,
-						   const ShaderCompilerOptions& compilerOptions, ShaderProgramBinaryWrapper& binary);
+						   ShaderProgramAsyncTaskInterface* taskManager, const ShaderCompilerOptions& compilerOptions,
+						   ShaderProgramBinaryWrapper& binary);
 /// @}
 
 } // end namespace anki

Some files were not shown because too many files changed in this diff