فهرست منبع

Add yet another allocator

Panagiotis Christopoulos Charitos 2 سال پیش
والد
کامیت
0219adb759
37فایلهای تغییر یافته به همراه529 افزوده شده و 384 حذف شده
  1. 9 4
      AnKi/Core/App.cpp
  2. 8 4
      AnKi/Core/CMakeLists.txt
  3. 9 107
      AnKi/Core/GpuMemory/GpuSceneBuffer.cpp
  4. 0 175
      AnKi/Core/GpuMemory/GpuSceneBuffer.h
  5. 70 0
      AnKi/Core/GpuMemory/GpuVisibleTransientMemoryPool.h
  6. 90 0
      AnKi/Core/GpuMemory/RebarTransientMemoryPool.cpp
  7. 90 0
      AnKi/Core/GpuMemory/RebarTransientMemoryPool.h
  8. 34 0
      AnKi/Core/GpuMemory/UnifiedGeometryBuffer.cpp
  9. 117 0
      AnKi/Core/GpuMemory/UnifiedGeometryBuffer.h
  10. 2 0
      AnKi/Gr/Utils/SegregatedListsGpuMemoryPool.h
  11. 1 1
      AnKi/Gr/Utils/StackGpuMemoryPool.cpp
  12. 8 8
      AnKi/Renderer/ClusterBinning.cpp
  13. 4 4
      AnKi/Renderer/ClusterBinning.h
  14. 0 1
      AnKi/Renderer/Common.h
  15. 22 22
      AnKi/Renderer/DebugDrawer.cpp
  16. 3 3
      AnKi/Renderer/DebugDrawer.h
  17. 9 6
      AnKi/Renderer/Drawer.cpp
  18. 1 1
      AnKi/Renderer/GenericCompute.cpp
  19. 5 4
      AnKi/Renderer/PackVisibleClusteredObjects.cpp
  20. 1 1
      AnKi/Renderer/RenderQueue.h
  21. 1 0
      AnKi/Renderer/Renderer.cpp
  22. 0 1
      AnKi/Renderer/Renderer.h
  23. 6 6
      AnKi/Renderer/RendererObject.cpp
  24. 8 8
      AnKi/Renderer/RendererObject.h
  25. 7 5
      AnKi/Renderer/RtShadows.cpp
  26. 0 1
      AnKi/Resource/MeshResource.cpp
  27. 1 1
      AnKi/Resource/MeshResource.h
  28. 0 1
      AnKi/Scene/Common.h
  29. 1 0
      AnKi/Scene/Components/DecalComponent.cpp
  30. 1 0
      AnKi/Scene/Components/FogDensityComponent.cpp
  31. 1 0
      AnKi/Scene/Components/SkinComponent.h
  32. 1 1
      AnKi/Scene/ContiguousArrayAllocator.h
  33. 1 0
      AnKi/Scene/RenderStateBucket.h
  34. 6 7
      AnKi/Ui/Canvas.cpp
  35. 7 7
      Tests/Gr/Gr.cpp
  36. 4 4
      Tests/Ui/Ui.cpp
  37. 1 1
      Tests/Util/Tracer.cpp

+ 9 - 4
AnKi/Core/App.cpp

@@ -6,6 +6,7 @@
 
 #include <AnKi/Core/App.h>
 #include <AnKi/Core/ConfigSet.h>
+#include <AnKi/Core/GpuMemory/UnifiedGeometryBuffer.h>
 #include <AnKi/Util/Logger.h>
 #include <AnKi/Util/File.h>
 #include <AnKi/Util/Filesystem.h>
@@ -14,6 +15,8 @@
 #include <AnKi/Util/Tracer.h>
 #include <AnKi/Util/HighRezTimer.h>
 #include <AnKi/Core/CoreTracer.h>
+#include <AnKi/Core/GpuMemory/RebarTransientMemoryPool.h>
+#include <AnKi/Core/GpuMemory/GpuVisibleTransientMemoryPool.h>
 #include <AnKi/Core/DeveloperConsole.h>
 #include <AnKi/Core/StatsUi.h>
 #include <AnKi/Window/NativeWindow.h>
@@ -27,7 +30,6 @@
 #include <AnKi/Script/ScriptManager.h>
 #include <AnKi/Resource/ResourceFilesystem.h>
 #include <AnKi/Resource/AsyncLoader.h>
-#include <AnKi/Core/GpuMemoryPools.h>
 #include <AnKi/Ui/UiManager.h>
 #include <AnKi/Ui/Canvas.h>
 #include <csignal>
@@ -128,7 +130,8 @@ void App::cleanup()
 	GpuSceneMicroPatcher::freeSingleton();
 	ResourceManager::freeSingleton();
 	PhysicsWorld::freeSingleton();
-	RebarStagingGpuMemoryPool::freeSingleton();
+	RebarTransientMemoryPool::freeSingleton();
+	GpuVisibleTransientMemoryPool::freeSingleton();
 	UnifiedGeometryBuffer::freeSingleton();
 	GpuSceneBuffer::freeSingleton();
 	CoreThreadHive::freeSingleton();
@@ -284,7 +287,8 @@ Error App::initInternal()
 	//
 	UnifiedGeometryBuffer::allocateSingleton().init();
 	GpuSceneBuffer::allocateSingleton().init();
-	RebarStagingGpuMemoryPool::allocateSingleton().init();
+	RebarTransientMemoryPool::allocateSingleton().init();
+	GpuVisibleTransientMemoryPool::allocateSingleton();
 
 	//
 	// Physics
@@ -466,9 +470,10 @@ Error App::mainLoop()
 				grTime = HighRezTimer::getCurrentTime() - grTime;
 			}
 
-			const PtrSize rebarMemUsed = RebarStagingGpuMemoryPool::getSingleton().endFrame();
+			const PtrSize rebarMemUsed = RebarTransientMemoryPool::getSingleton().endFrame();
 			UnifiedGeometryBuffer::getSingleton().endFrame();
 			GpuSceneBuffer::getSingleton().endFrame();
+			GpuVisibleTransientMemoryPool::getSingleton().endFrame();
 
 			// Update the trace info with some async loader stats
 			U64 asyncTaskCount = ResourceManager::getSingleton().getAsyncLoader().getCompletedTaskCount();

+ 8 - 4
AnKi/Core/CMakeLists.txt

@@ -1,11 +1,13 @@
 set(sources
 	App.cpp
 	ConfigSet.cpp
-	GpuMemoryPools.cpp
 	DeveloperConsole.cpp
 	CoreTracer.cpp
 	MaliHwCounters.cpp
-	StatsUi.cpp)
+	StatsUi.cpp
+	GpuMemory/UnifiedGeometryBuffer.cpp
+	GpuMemory/GpuSceneBuffer.cpp
+	GpuMemory/RebarTransientMemoryPool.cpp)
 
 set(headers
 	AllConfigVars.defs.h
@@ -15,11 +17,13 @@ set(headers
 	ConfigVars.defs.h
 	CoreTracer.h
 	DeveloperConsole.h
-	GpuMemoryPools.h
 	MaliHwCounters.h
 	StatsUi.h
 	StatsUi.defs.h
-	StdinListener.h)
+	StdinListener.h
+	GpuMemory/UnifiedGeometryBuffer.h
+	GpuMemory/GpuSceneBuffer.h
+	GpuMemory/RebarTransientMemoryPool.h)
 
 add_library(AnKiCore ${sources} ${headers})
 

+ 9 - 107
AnKi/Core/GpuMemoryPools.cpp → AnKi/Core/GpuMemory/GpuSceneBuffer.cpp

@@ -3,37 +3,15 @@
 // Code licensed under the BSD License.
 // http://www.anki3d.org/LICENSE
 
-#include <AnKi/Core/GpuMemoryPools.h>
+#include <AnKi/Core/GpuMemory/GpuSceneBuffer.h>
+#include <AnKi/Core/GpuMemory/RebarTransientMemoryPool.h>
 #include <AnKi/Core/ConfigSet.h>
-#include <AnKi/Gr/GrManager.h>
-#include <AnKi/Gr/CommandBuffer.h>
 #include <AnKi/Util/Tracer.h>
 #include <AnKi/Resource/ResourceManager.h>
+#include <AnKi/Gr/CommandBuffer.h>
 
 namespace anki {
 
-void UnifiedGeometryBuffer::init()
-{
-	const PtrSize poolSize = ConfigSet::getSingleton().getCoreGlobalVertexMemorySize();
-
-	const Array classes = {1_KB, 8_KB, 32_KB, 128_KB, 512_KB, 4_MB, 8_MB, 16_MB, poolSize};
-
-	BufferUsageBit buffUsage = BufferUsageBit::kVertex | BufferUsageBit::kIndex | BufferUsageBit::kTransferDestination
-							   | (BufferUsageBit::kAllTexture & BufferUsageBit::kAllRead);
-
-	if(GrManager::getSingleton().getDeviceCapabilities().m_rayTracingEnabled)
-	{
-		buffUsage |= BufferUsageBit::kAccelerationStructureBuild;
-	}
-
-	m_pool.init(buffUsage, classes, poolSize, "UnifiedGeometry", false);
-
-	// Allocate something dummy to force creating the GPU buffer
-	UnifiedGeometryBufferAllocation alloc;
-	allocate(16, 4, alloc);
-	deferredFree(alloc);
-}
-
 void GpuSceneBuffer::init()
 {
 	const PtrSize poolSize = ConfigSet::getSingleton().getCoreGpuSceneInitialSize();
@@ -50,82 +28,6 @@ void GpuSceneBuffer::init()
 	deferredFree(alloc);
 }
 
-RebarStagingGpuMemoryPool::~RebarStagingGpuMemoryPool()
-{
-	GrManager::getSingleton().finish();
-
-	m_buffer->unmap();
-	m_buffer.reset(nullptr);
-}
-
-void RebarStagingGpuMemoryPool::init()
-{
-	BufferInitInfo buffInit("ReBar");
-	buffInit.m_mapAccess = BufferMapAccessBit::kWrite;
-	buffInit.m_size = ConfigSet::getSingleton().getCoreRebarGpuMemorySize();
-	buffInit.m_usage = BufferUsageBit::kAllUniform | BufferUsageBit::kAllStorage | BufferUsageBit::kVertex
-					   | BufferUsageBit::kIndex | BufferUsageBit::kShaderBindingTable;
-	m_buffer = GrManager::getSingleton().newBuffer(buffInit);
-
-	m_bufferSize = buffInit.m_size;
-
-	m_alignment = GrManager::getSingleton().getDeviceCapabilities().m_uniformBufferBindOffsetAlignment;
-	m_alignment =
-		max(m_alignment, GrManager::getSingleton().getDeviceCapabilities().m_storageBufferBindOffsetAlignment);
-	m_alignment = max(m_alignment, GrManager::getSingleton().getDeviceCapabilities().m_sbtRecordAlignment);
-
-	m_mappedMem = static_cast<U8*>(m_buffer->map(0, kMaxPtrSize, BufferMapAccessBit::kWrite));
-}
-
-void* RebarStagingGpuMemoryPool::allocateFrame(PtrSize size, RebarGpuMemoryToken& token)
-{
-	void* address = tryAllocateFrame(size, token);
-	if(address == nullptr) [[unlikely]]
-	{
-		ANKI_CORE_LOGF("Out of ReBAR GPU memory");
-	}
-
-	return address;
-}
-
-void* RebarStagingGpuMemoryPool::tryAllocateFrame(PtrSize origSize, RebarGpuMemoryToken& token)
-{
-	const PtrSize size = getAlignedRoundUp(m_alignment, origSize);
-
-	// Try in a loop because we may end up with an allocation its offset crosses the buffer's end
-	PtrSize offset;
-	Bool done = false;
-	do
-	{
-		offset = m_offset.fetchAdd(size) % m_bufferSize;
-		const PtrSize end = (offset + origSize) % (m_bufferSize + 1);
-
-		done = offset < end;
-	} while(!done);
-
-	void* address = m_mappedMem + offset;
-	token.m_offset = offset;
-	token.m_range = origSize;
-
-	return address;
-}
-
-PtrSize RebarStagingGpuMemoryPool::endFrame()
-{
-	const PtrSize crntOffset = m_offset.getNonAtomically();
-
-	const PtrSize usedMemory = crntOffset - m_previousFrameEndOffset;
-	m_previousFrameEndOffset = crntOffset;
-
-	if(usedMemory >= PtrSize(0.8 * F64(m_bufferSize / kMaxFramesInFlight)))
-	{
-		ANKI_CORE_LOGW("Frame used more that 80%% of its safe limit of ReBAR memory");
-	}
-
-	ANKI_TRACE_INC_COUNTER(ReBarUsedMemory, usedMemory);
-	return usedMemory;
-}
-
 /// It packs the source and destination offsets as well as the size of the patch itself.
 class GpuSceneMicroPatcher::PatchHeader
 {
@@ -209,18 +111,18 @@ void GpuSceneMicroPatcher::patchGpuScene(CommandBuffer& cmdb)
 	ANKI_TRACE_INC_COUNTER(GpuSceneMicroPatches, m_crntFramePatchHeaders.getSize());
 	ANKI_TRACE_INC_COUNTER(GpuSceneMicroPatchUploadData, m_crntFramePatchData.getSizeInBytes());
 
-	RebarGpuMemoryToken headersToken;
+	RebarAllocation headersToken;
 	void* mapped =
-		RebarStagingGpuMemoryPool::getSingleton().allocateFrame(m_crntFramePatchHeaders.getSizeInBytes(), headersToken);
+		RebarTransientMemoryPool::getSingleton().allocateFrame(m_crntFramePatchHeaders.getSizeInBytes(), headersToken);
 	memcpy(mapped, &m_crntFramePatchHeaders[0], m_crntFramePatchHeaders.getSizeInBytes());
 
-	RebarGpuMemoryToken dataToken;
-	mapped = RebarStagingGpuMemoryPool::getSingleton().allocateFrame(m_crntFramePatchData.getSizeInBytes(), dataToken);
+	RebarAllocation dataToken;
+	mapped = RebarTransientMemoryPool::getSingleton().allocateFrame(m_crntFramePatchData.getSizeInBytes(), dataToken);
 	memcpy(mapped, &m_crntFramePatchData[0], m_crntFramePatchData.getSizeInBytes());
 
-	cmdb.bindStorageBuffer(0, 0, RebarStagingGpuMemoryPool::getSingleton().getBuffer(), headersToken.m_offset,
+	cmdb.bindStorageBuffer(0, 0, RebarTransientMemoryPool::getSingleton().getBuffer(), headersToken.m_offset,
 						   headersToken.m_range);
-	cmdb.bindStorageBuffer(0, 1, RebarStagingGpuMemoryPool::getSingleton().getBuffer(), dataToken.m_offset,
+	cmdb.bindStorageBuffer(0, 1, RebarTransientMemoryPool::getSingleton().getBuffer(), dataToken.m_offset,
 						   dataToken.m_range);
 	cmdb.bindStorageBuffer(0, 2, GpuSceneBuffer::getSingleton().getBuffer(), 0, kMaxPtrSize);
 

+ 0 - 175
AnKi/Core/GpuMemoryPools.h → AnKi/Core/GpuMemory/GpuSceneBuffer.h

@@ -6,8 +6,6 @@
 #pragma once
 
 #include <AnKi/Core/Common.h>
-#include <AnKi/Gr/Buffer.h>
-#include <AnKi/Gr/Utils/StackGpuMemoryPool.h>
 #include <AnKi/Gr/Utils/SegregatedListsGpuMemoryPool.h>
 #include <AnKi/Resource/ShaderProgramResource.h>
 
@@ -16,106 +14,6 @@ namespace anki {
 /// @addtogroup core
 /// @{
 
-/// @memberof UnifiedGeometryBuffer
-class UnifiedGeometryBufferAllocation
-{
-	friend class UnifiedGeometryBuffer;
-
-public:
-	UnifiedGeometryBufferAllocation() = default;
-
-	UnifiedGeometryBufferAllocation(const UnifiedGeometryBufferAllocation&) = delete;
-
-	UnifiedGeometryBufferAllocation(UnifiedGeometryBufferAllocation&& b)
-	{
-		*this = std::move(b);
-	}
-
-	~UnifiedGeometryBufferAllocation();
-
-	UnifiedGeometryBufferAllocation& operator=(const UnifiedGeometryBufferAllocation&) = delete;
-
-	UnifiedGeometryBufferAllocation& operator=(UnifiedGeometryBufferAllocation&& b)
-	{
-		ANKI_ASSERT(!isValid() && "Forgot to delete");
-		m_token = b.m_token;
-		b.m_token = {};
-		return *this;
-	}
-
-	Bool isValid() const
-	{
-		return m_token.m_offset != kMaxPtrSize;
-	}
-
-	/// Get offset in the Unified Geometry Buffer buffer.
-	U32 getOffset() const
-	{
-		ANKI_ASSERT(isValid());
-		return U32(m_token.m_offset);
-	}
-
-	U32 getAllocatedSize() const
-	{
-		ANKI_ASSERT(isValid());
-		return U32(m_token.m_size);
-	}
-
-private:
-	SegregatedListsGpuMemoryPoolToken m_token;
-};
-
-/// Manages vertex and index memory for the whole application.
-class UnifiedGeometryBuffer : public MakeSingleton<UnifiedGeometryBuffer>
-{
-	template<typename>
-	friend class MakeSingleton;
-
-public:
-	UnifiedGeometryBuffer(const UnifiedGeometryBuffer&) = delete; // Non-copyable
-
-	UnifiedGeometryBuffer& operator=(const UnifiedGeometryBuffer&) = delete; // Non-copyable
-
-	void init();
-
-	void allocate(PtrSize size, U32 alignment, UnifiedGeometryBufferAllocation& alloc)
-	{
-		m_pool.allocate(size, alignment, alloc.m_token);
-	}
-
-	void deferredFree(UnifiedGeometryBufferAllocation& alloc)
-	{
-		m_pool.deferredFree(alloc.m_token);
-	}
-
-	void endFrame()
-	{
-		m_pool.endFrame();
-	}
-
-	const BufferPtr& getBuffer() const
-	{
-		return m_pool.getGpuBuffer();
-	}
-
-	void getStats(F32& externalFragmentation, PtrSize& userAllocatedSize, PtrSize& totalSize) const
-	{
-		m_pool.getStats(externalFragmentation, userAllocatedSize, totalSize);
-	}
-
-private:
-	SegregatedListsGpuMemoryPool m_pool;
-
-	UnifiedGeometryBuffer() = default;
-
-	~UnifiedGeometryBuffer() = default;
-};
-
-inline UnifiedGeometryBufferAllocation::~UnifiedGeometryBufferAllocation()
-{
-	UnifiedGeometryBuffer::getSingleton().deferredFree(*this);
-}
-
 /// @memberof GpuSceneBuffer
 class GpuSceneBufferAllocation
 {
@@ -216,79 +114,6 @@ inline GpuSceneBufferAllocation::~GpuSceneBufferAllocation()
 	GpuSceneBuffer::getSingleton().deferredFree(*this);
 }
 
-/// Token that gets returned when requesting for memory to write to a resource.
-class RebarGpuMemoryToken
-{
-public:
-	PtrSize m_offset = 0;
-	PtrSize m_range = 0;
-
-	RebarGpuMemoryToken() = default;
-
-	~RebarGpuMemoryToken() = default;
-
-	Bool operator==(const RebarGpuMemoryToken& b) const
-	{
-		return m_offset == b.m_offset && m_range == b.m_range;
-	}
-
-	void markUnused()
-	{
-		m_offset = m_range = kMaxU32;
-	}
-
-	Bool isUnused() const
-	{
-		return m_offset == kMaxU32 && m_range == kMaxU32;
-	}
-};
-
-/// Manages staging GPU memory.
-class RebarStagingGpuMemoryPool : public MakeSingleton<RebarStagingGpuMemoryPool>
-{
-	template<typename>
-	friend class MakeSingleton;
-
-public:
-	RebarStagingGpuMemoryPool(const RebarStagingGpuMemoryPool&) = delete; // Non-copyable
-
-	~RebarStagingGpuMemoryPool();
-
-	RebarStagingGpuMemoryPool& operator=(const RebarStagingGpuMemoryPool&) = delete; // Non-copyable
-
-	void init();
-
-	PtrSize endFrame();
-
-	/// Allocate staging memory for various operations. The memory will be reclaimed at the begining of the
-	/// N-(kMaxFramesInFlight-1) frame.
-	void* allocateFrame(PtrSize size, RebarGpuMemoryToken& token);
-
-	/// Allocate staging memory for various operations. The memory will be reclaimed at the begining of the
-	/// N-(kMaxFramesInFlight-1) frame.
-	void* tryAllocateFrame(PtrSize size, RebarGpuMemoryToken& token);
-
-	ANKI_PURE const BufferPtr& getBuffer() const
-	{
-		return m_buffer;
-	}
-
-	U8* getBufferMappedAddress()
-	{
-		return m_mappedMem;
-	}
-
-private:
-	BufferPtr m_buffer;
-	U8* m_mappedMem = nullptr; ///< Cache it.
-	PtrSize m_bufferSize = 0; ///< Cache it.
-	Atomic<PtrSize> m_offset = {0};
-	PtrSize m_previousFrameEndOffset = 0;
-	U32 m_alignment = 0;
-
-	RebarStagingGpuMemoryPool() = default;
-};
-
 /// Creates the copy jobs that will patch the GPU Scene.
 class GpuSceneMicroPatcher : public MakeSingleton<GpuSceneMicroPatcher>
 {

+ 70 - 0
AnKi/Core/GpuMemory/GpuVisibleTransientMemoryPool.h

@@ -0,0 +1,70 @@
+// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#pragma once
+
+#include <AnKi/Core/Common.h>
+#include <AnKi/Gr/Utils/StackGpuMemoryPool.h>
+#include <AnKi/Gr/GrManager.h>
+
+namespace anki {
+
+/// @addtogroup core
+/// @{
+
+/// @memberof GpuVisibleTransientMemoryPool
+class GpuVisibleTransientMemoryAllocation
+{
+public:
+	Buffer* m_buffer = nullptr;
+	PtrSize m_offset = kMaxPtrSize;
+};
+
+/// GPU only transient memory. Used for temporary allocations. Allocations will get reset after each frame.
+class GpuVisibleTransientMemoryPool : public MakeSingleton<GpuVisibleTransientMemoryPool>
+{
+	template<typename>
+	friend class MakeSingleton;
+
+public:
+	GpuVisibleTransientMemoryAllocation allocate(PtrSize size)
+	{
+		GpuVisibleTransientMemoryAllocation out;
+		m_pool.allocate(size, out.m_offset, out.m_buffer);
+		return out;
+	}
+
+	void endFrame()
+	{
+		if(m_frame == 0)
+		{
+			m_pool.reset();
+		}
+
+		m_frame = (m_frame + 1) % kMaxFramesInFlight;
+	}
+
+private:
+	StackGpuMemoryPool m_pool;
+	U32 m_frame = 0;
+
+	GpuVisibleTransientMemoryPool()
+	{
+		U32 alignment = GrManager::getSingleton().getDeviceCapabilities().m_uniformBufferBindOffsetAlignment;
+		alignment =
+			max(alignment, GrManager::getSingleton().getDeviceCapabilities().m_storageBufferBindOffsetAlignment);
+		alignment = max(alignment, GrManager::getSingleton().getDeviceCapabilities().m_sbtRecordAlignment);
+
+		const BufferUsageBit buffUsage = BufferUsageBit::kAllUniform | BufferUsageBit::kAllStorage
+										 | BufferUsageBit::kIndirectDraw | BufferUsageBit::kVertex;
+		m_pool.init(10_MB, 2.0, 0, alignment, buffUsage, BufferMapAccessBit::kNone, true,
+					"GpuVisibleTransientMemoryPool");
+	}
+
+	~GpuVisibleTransientMemoryPool() = default;
+};
+/// @}
+
+} // end namespace anki

+ 90 - 0
AnKi/Core/GpuMemory/RebarTransientMemoryPool.cpp

@@ -0,0 +1,90 @@
+// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#include <AnKi/Core/GpuMemory/RebarTransientMemoryPool.h>
+#include <AnKi/Core/ConfigSet.h>
+#include <AnKi/Util/Tracer.h>
+#include <AnKi/Gr/GrManager.h>
+#include <AnKi/Gr/Buffer.h>
+
+namespace anki {
+
+RebarTransientMemoryPool::~RebarTransientMemoryPool()
+{
+	GrManager::getSingleton().finish();
+
+	m_buffer->unmap();
+	m_buffer.reset(nullptr);
+}
+
+void RebarTransientMemoryPool::init()
+{
+	BufferInitInfo buffInit("ReBar");
+	buffInit.m_mapAccess = BufferMapAccessBit::kWrite;
+	buffInit.m_size = ConfigSet::getSingleton().getCoreRebarGpuMemorySize();
+	buffInit.m_usage = BufferUsageBit::kAllUniform | BufferUsageBit::kAllStorage | BufferUsageBit::kVertex
+					   | BufferUsageBit::kIndex | BufferUsageBit::kShaderBindingTable;
+	m_buffer = GrManager::getSingleton().newBuffer(buffInit);
+
+	m_bufferSize = buffInit.m_size;
+
+	m_alignment = GrManager::getSingleton().getDeviceCapabilities().m_uniformBufferBindOffsetAlignment;
+	m_alignment =
+		max(m_alignment, GrManager::getSingleton().getDeviceCapabilities().m_storageBufferBindOffsetAlignment);
+	m_alignment = max(m_alignment, GrManager::getSingleton().getDeviceCapabilities().m_sbtRecordAlignment);
+
+	m_mappedMem = static_cast<U8*>(m_buffer->map(0, kMaxPtrSize, BufferMapAccessBit::kWrite));
+}
+
+void* RebarTransientMemoryPool::allocateFrame(PtrSize size, RebarAllocation& token)
+{
+	void* address = tryAllocateFrame(size, token);
+	if(address == nullptr) [[unlikely]]
+	{
+		ANKI_CORE_LOGF("Out of ReBAR GPU memory");
+	}
+
+	return address;
+}
+
+void* RebarTransientMemoryPool::tryAllocateFrame(PtrSize origSize, RebarAllocation& token)
+{
+	const PtrSize size = getAlignedRoundUp(m_alignment, origSize);
+
+	// Try in a loop because we may end up with an allocation its offset crosses the buffer's end
+	PtrSize offset;
+	Bool done = false;
+	do
+	{
+		offset = m_offset.fetchAdd(size) % m_bufferSize;
+		const PtrSize end = (offset + origSize) % (m_bufferSize + 1);
+
+		done = offset < end;
+	} while(!done);
+
+	void* address = m_mappedMem + offset;
+	token.m_offset = offset;
+	token.m_range = origSize;
+
+	return address;
+}
+
+PtrSize RebarTransientMemoryPool::endFrame()
+{
+	const PtrSize crntOffset = m_offset.getNonAtomically();
+
+	const PtrSize usedMemory = crntOffset - m_previousFrameEndOffset;
+	m_previousFrameEndOffset = crntOffset;
+
+	if(usedMemory >= PtrSize(0.8 * F64(m_bufferSize / kMaxFramesInFlight)))
+	{
+		ANKI_CORE_LOGW("Frame used more that 80%% of its safe limit of ReBAR memory");
+	}
+
+	ANKI_TRACE_INC_COUNTER(ReBarUsedMemory, usedMemory);
+	return usedMemory;
+}
+
+} // end namespace anki

+ 90 - 0
AnKi/Core/GpuMemory/RebarTransientMemoryPool.h

@@ -0,0 +1,90 @@
+// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#pragma once
+
+#include <AnKi/Core/Common.h>
+#include <AnKi/Gr/Buffer.h>
+
+namespace anki {
+
+/// @addtogroup core
+/// @{
+
+/// Token that gets returned when requesting for memory to write to a resource.
+class RebarAllocation
+{
+public:
+	PtrSize m_offset = 0;
+	PtrSize m_range = 0;
+
+	RebarAllocation() = default;
+
+	~RebarAllocation() = default;
+
+	Bool operator==(const RebarAllocation& b) const
+	{
+		return m_offset == b.m_offset && m_range == b.m_range;
+	}
+
+	void markUnused()
+	{
+		m_offset = m_range = kMaxU32;
+	}
+
+	Bool isUnused() const
+	{
+		return m_offset == kMaxU32 && m_range == kMaxU32;
+	}
+};
+
+/// Manages staging GPU memory.
+class RebarTransientMemoryPool : public MakeSingleton<RebarTransientMemoryPool>
+{
+	template<typename>
+	friend class MakeSingleton;
+
+public:
+	RebarTransientMemoryPool(const RebarTransientMemoryPool&) = delete; // Non-copyable
+
+	~RebarTransientMemoryPool();
+
+	RebarTransientMemoryPool& operator=(const RebarTransientMemoryPool&) = delete; // Non-copyable
+
+	void init();
+
+	PtrSize endFrame();
+
+	/// Allocate staging memory for various operations. The memory will be reclaimed at the begining of the
+	/// N-(kMaxFramesInFlight-1) frame.
+	void* allocateFrame(PtrSize size, RebarAllocation& token);
+
+	/// Allocate staging memory for various operations. The memory will be reclaimed at the begining of the
+	/// N-(kMaxFramesInFlight-1) frame.
+	void* tryAllocateFrame(PtrSize size, RebarAllocation& token);
+
+	ANKI_PURE const BufferPtr& getBuffer() const
+	{
+		return m_buffer;
+	}
+
+	U8* getBufferMappedAddress()
+	{
+		return m_mappedMem;
+	}
+
+private:
+	BufferPtr m_buffer;
+	U8* m_mappedMem = nullptr; ///< Cache it.
+	PtrSize m_bufferSize = 0; ///< Cache it.
+	Atomic<PtrSize> m_offset = {0};
+	PtrSize m_previousFrameEndOffset = 0;
+	U32 m_alignment = 0;
+
+	RebarTransientMemoryPool() = default;
+};
+/// @}
+
+} // end namespace anki

+ 34 - 0
AnKi/Core/GpuMemory/UnifiedGeometryBuffer.cpp

@@ -0,0 +1,34 @@
+// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#include <AnKi/Core/GpuMemory/UnifiedGeometryBuffer.h>
+#include <AnKi/Core/ConfigSet.h>
+#include <AnKi/Gr/GrManager.h>
+
+namespace anki {
+
+void UnifiedGeometryBuffer::init()
+{
+	const PtrSize poolSize = ConfigSet::getSingleton().getCoreGlobalVertexMemorySize();
+
+	const Array classes = {1_KB, 8_KB, 32_KB, 128_KB, 512_KB, 4_MB, 8_MB, 16_MB, poolSize};
+
+	BufferUsageBit buffUsage = BufferUsageBit::kVertex | BufferUsageBit::kIndex | BufferUsageBit::kTransferDestination
+							   | (BufferUsageBit::kAllTexture & BufferUsageBit::kAllRead);
+
+	if(GrManager::getSingleton().getDeviceCapabilities().m_rayTracingEnabled)
+	{
+		buffUsage |= BufferUsageBit::kAccelerationStructureBuild;
+	}
+
+	m_pool.init(buffUsage, classes, poolSize, "UnifiedGeometry", false);
+
+	// Allocate something dummy to force creating the GPU buffer
+	UnifiedGeometryBufferAllocation alloc;
+	allocate(16, 4, alloc);
+	deferredFree(alloc);
+}
+
+} // end namespace anki

+ 117 - 0
AnKi/Core/GpuMemory/UnifiedGeometryBuffer.h

@@ -0,0 +1,117 @@
+// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#pragma once
+
+#include <AnKi/Core/Common.h>
+#include <AnKi/Gr/Utils/SegregatedListsGpuMemoryPool.h>
+
+namespace anki {
+
+/// @addtogroup core
+/// @{
+
+/// @memberof UnifiedGeometryBuffer
+class UnifiedGeometryBufferAllocation
+{
+	friend class UnifiedGeometryBuffer;
+
+public:
+	UnifiedGeometryBufferAllocation() = default;
+
+	UnifiedGeometryBufferAllocation(const UnifiedGeometryBufferAllocation&) = delete;
+
+	UnifiedGeometryBufferAllocation(UnifiedGeometryBufferAllocation&& b)
+	{
+		*this = std::move(b);
+	}
+
+	~UnifiedGeometryBufferAllocation();
+
+	UnifiedGeometryBufferAllocation& operator=(const UnifiedGeometryBufferAllocation&) = delete;
+
+	UnifiedGeometryBufferAllocation& operator=(UnifiedGeometryBufferAllocation&& b)
+	{
+		ANKI_ASSERT(!isValid() && "Forgot to delete");
+		m_token = b.m_token;
+		b.m_token = {};
+		return *this;
+	}
+
+	Bool isValid() const
+	{
+		return m_token.m_offset != kMaxPtrSize;
+	}
+
+	/// Get offset in the Unified Geometry Buffer buffer.
+	U32 getOffset() const
+	{
+		ANKI_ASSERT(isValid());
+		return U32(m_token.m_offset);
+	}
+
+	U32 getAllocatedSize() const
+	{
+		ANKI_ASSERT(isValid());
+		return U32(m_token.m_size);
+	}
+
+private:
+	SegregatedListsGpuMemoryPoolToken m_token;
+};
+
+/// Manages vertex and index memory for the WHOLE application.
+class UnifiedGeometryBuffer : public MakeSingleton<UnifiedGeometryBuffer>
+{
+	template<typename>
+	friend class MakeSingleton;
+
+public:
+	UnifiedGeometryBuffer(const UnifiedGeometryBuffer&) = delete; // Non-copyable
+
+	UnifiedGeometryBuffer& operator=(const UnifiedGeometryBuffer&) = delete; // Non-copyable
+
+	void init();
+
+	void allocate(PtrSize size, U32 alignment, UnifiedGeometryBufferAllocation& alloc)
+	{
+		m_pool.allocate(size, alignment, alloc.m_token);
+	}
+
+	void deferredFree(UnifiedGeometryBufferAllocation& alloc)
+	{
+		m_pool.deferredFree(alloc.m_token);
+	}
+
+	void endFrame()
+	{
+		m_pool.endFrame();
+	}
+
+	const BufferPtr& getBuffer() const
+	{
+		return m_pool.getGpuBuffer();
+	}
+
+	void getStats(F32& externalFragmentation, PtrSize& userAllocatedSize, PtrSize& totalSize) const
+	{
+		m_pool.getStats(externalFragmentation, userAllocatedSize, totalSize);
+	}
+
+private:
+	SegregatedListsGpuMemoryPool m_pool;
+
+	UnifiedGeometryBuffer() = default;
+
+	~UnifiedGeometryBuffer() = default;
+};
+
+inline UnifiedGeometryBufferAllocation::~UnifiedGeometryBufferAllocation()
+{
+	UnifiedGeometryBuffer::getSingleton().deferredFree(*this);
+}
+/// @}
+
+} // end namespace anki

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

@@ -3,6 +3,8 @@
 // Code licensed under the BSD License.
 // http://www.anki3d.org/LICENSE
 
+#pragma once
+
 #include <AnKi/Util/SegregatedListsAllocatorBuilder.h>
 #include <AnKi/Gr/Buffer.h>
 

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

@@ -123,7 +123,7 @@ void StackGpuMemoryPool::init(PtrSize initialSize, F64 nextChunkGrowScale, PtrSi
 {
 	ANKI_ASSERT(m_builder == nullptr);
 	ANKI_ASSERT(initialSize > 0 && alignment > 0);
-	ANKI_ASSERT(nextChunkGrowScale >= 1.0 && nextChunkGrowBias > 0);
+	ANKI_ASSERT(nextChunkGrowScale >= 1.0);
 
 	m_builder = newInstance<Builder>(GrMemoryPool::getSingleton());
 	BuilderInterface& inter = m_builder->getInterface();

+ 8 - 8
AnKi/Renderer/ClusterBinning.cpp

@@ -55,9 +55,9 @@ void ClusterBinning::populateRenderGraph(RenderingContext& ctx)
 	m_runCtx.m_ctx = &ctx;
 	writeClustererBuffers(ctx);
 
-	m_runCtx.m_rebarHandle = ctx.m_renderGraphDescr.importBuffer(
-		RebarStagingGpuMemoryPool::getSingleton().getBuffer(), BufferUsageBit::kNone, m_runCtx.m_clustersToken.m_offset,
-		m_runCtx.m_clustersToken.m_range);
+	m_runCtx.m_rebarHandle =
+		ctx.m_renderGraphDescr.importBuffer(RebarTransientMemoryPool::getSingleton().getBuffer(), BufferUsageBit::kNone,
+											m_runCtx.m_clustersToken.m_offset, m_runCtx.m_clustersToken.m_range);
 
 	const RenderQueue& rqueue = *ctx.m_renderQueue;
 	if(rqueue.m_pointLights.getSize() == 0 && rqueue.m_spotLights.getSize() == 0 && rqueue.m_decals.getSize() == 0
@@ -149,9 +149,9 @@ void ClusterBinning::writeClustererBuffers(RenderingContext& ctx)
 	}
 
 	// Allocate buffers
-	RebarStagingGpuMemoryPool::getSingleton().allocateFrame(sizeof(ClusteredShadingUniforms),
-															m_runCtx.m_clusteredShadingUniformsToken);
-	RebarStagingGpuMemoryPool::getSingleton().allocateFrame(sizeof(Cluster) * m_clusterCount, m_runCtx.m_clustersToken);
+	RebarTransientMemoryPool::getSingleton().allocateFrame(sizeof(ClusteredShadingUniforms),
+														   m_runCtx.m_clusteredShadingUniformsToken);
+	RebarTransientMemoryPool::getSingleton().allocateFrame(sizeof(Cluster) * m_clusterCount, m_runCtx.m_clustersToken);
 }
 
 void ClusterBinning::writeClusterBuffersAsync()
@@ -174,7 +174,7 @@ void ClusterBinning::writeClustererBuffersTask()
 	// General uniforms
 	{
 		ClusteredShadingUniforms& unis = *reinterpret_cast<ClusteredShadingUniforms*>(
-			RebarStagingGpuMemoryPool::getSingleton().getBufferMappedAddress()
+			RebarTransientMemoryPool::getSingleton().getBufferMappedAddress()
 			+ m_runCtx.m_clusteredShadingUniformsToken.m_offset);
 
 		unis.m_renderingSize =
@@ -249,7 +249,7 @@ void ClusterBinning::writeClustererBuffersTask()
 
 	// Zero the memory because atomics will happen
 	U8* clustersAddress =
-		RebarStagingGpuMemoryPool::getSingleton().getBufferMappedAddress() + m_runCtx.m_clustersToken.m_offset;
+		RebarTransientMemoryPool::getSingleton().getBufferMappedAddress() + m_runCtx.m_clustersToken.m_offset;
 	memset(clustersAddress, 0, sizeof(Cluster) * m_clusterCount);
 }
 

+ 4 - 4
AnKi/Renderer/ClusterBinning.h

@@ -29,12 +29,12 @@ public:
 	/// called after the render queue is finalized.
 	void writeClusterBuffersAsync();
 
-	const RebarGpuMemoryToken& getClusteredUniformsRebarToken() const
+	const RebarAllocation& getClusteredUniformsRebarToken() const
 	{
 		return m_runCtx.m_clusteredShadingUniformsToken;
 	}
 
-	const RebarGpuMemoryToken& getClustersRebarToken() const
+	const RebarAllocation& getClustersRebarToken() const
 	{
 		return m_runCtx.m_clustersToken;
 	}
@@ -55,8 +55,8 @@ private:
 	{
 	public:
 		RenderingContext* m_ctx = nullptr;
-		RebarGpuMemoryToken m_clusteredShadingUniformsToken;
-		RebarGpuMemoryToken m_clustersToken;
+		RebarAllocation m_clusteredShadingUniformsToken;
+		RebarAllocation m_clustersToken;
 		BufferHandle m_rebarHandle; ///< For dependency tracking.
 	} m_runCtx;
 

+ 0 - 1
AnKi/Renderer/Common.h

@@ -6,7 +6,6 @@
 #pragma once
 
 #include <AnKi/Gr.h>
-#include <AnKi/Core/GpuMemoryPools.h>
 #include <AnKi/Util/Ptr.h>
 #include <AnKi/Shaders/Include/MiscRendererTypes.h>
 #include <AnKi/Shaders/Include/ClusteredShadingTypes.h>

+ 22 - 22
AnKi/Renderer/DebugDrawer.cpp

@@ -6,16 +6,16 @@
 #include <AnKi/Renderer/DebugDrawer.h>
 #include <AnKi/Resource/ResourceManager.h>
 #include <AnKi/Renderer/RenderQueue.h>
-#include <AnKi/Core/GpuMemoryPools.h>
+#include <AnKi/Core/GpuMemory/RebarTransientMemoryPool.h>
 #include <AnKi/Physics/PhysicsWorld.h>
 #include <AnKi/Gr/Buffer.h>
 
 namespace anki {
 
-void allocateAndPopulateDebugBox(RebarGpuMemoryToken& vertsToken, RebarGpuMemoryToken& indicesToken, U32& indexCount)
+void allocateAndPopulateDebugBox(RebarAllocation& vertsToken, RebarAllocation& indicesToken, U32& indexCount)
 {
 	Vec3* verts =
-		static_cast<Vec3*>(RebarStagingGpuMemoryPool::getSingleton().allocateFrame(sizeof(Vec3) * 8, vertsToken));
+		static_cast<Vec3*>(RebarTransientMemoryPool::getSingleton().allocateFrame(sizeof(Vec3) * 8, vertsToken));
 
 	constexpr F32 kSize = 1.0f;
 	verts[0] = Vec3(kSize, kSize, kSize); // front top right
@@ -29,7 +29,7 @@ void allocateAndPopulateDebugBox(RebarGpuMemoryToken& vertsToken, RebarGpuMemory
 
 	constexpr U kIndexCount = 12 * 2;
 	U16* indices = static_cast<U16*>(
-		RebarStagingGpuMemoryPool::getSingleton().allocateFrame(sizeof(U16) * kIndexCount, indicesToken));
+		RebarTransientMemoryPool::getSingleton().allocateFrame(sizeof(U16) * kIndexCount, indicesToken));
 
 	U c = 0;
 	indices[c++] = 0;
@@ -140,9 +140,9 @@ void DebugDrawer2::drawCubes(ConstWeakArray<Mat4> mvps, const Vec4& color, F32 l
 							 F32 cubeSideSize, CommandBufferPtr& cmdb) const
 {
 	// Set the uniforms
-	RebarGpuMemoryToken unisToken;
+	RebarAllocation unisToken;
 	Mat4* pmvps = static_cast<Mat4*>(
-		RebarStagingGpuMemoryPool::getSingleton().allocateFrame(sizeof(Mat4) * mvps.getSize(), unisToken));
+		RebarTransientMemoryPool::getSingleton().allocateFrame(sizeof(Mat4) * mvps.getSize(), unisToken));
 
 	if(cubeSideSize == 2.0f)
 	{
@@ -167,7 +167,7 @@ void DebugDrawer2::drawCubes(ConstWeakArray<Mat4> mvps, const Vec4& color, F32 l
 	cmdb->bindVertexBuffer(0, m_cubePositionsBuffer, 0, sizeof(Vec3));
 	cmdb->bindIndexBuffer(m_cubeIndicesBuffer, 0, IndexType::kU16);
 
-	cmdb->bindStorageBuffer(0, 0, RebarStagingGpuMemoryPool::getSingleton().getBuffer(), unisToken.m_offset,
+	cmdb->bindStorageBuffer(0, 0, RebarTransientMemoryPool::getSingleton().getBuffer(), unisToken.m_offset,
 							unisToken.m_range);
 
 	cmdb->setLineWidth(lineSize);
@@ -182,15 +182,15 @@ void DebugDrawer2::drawLines(ConstWeakArray<Mat4> mvps, const Vec4& color, F32 l
 	ANKI_ASSERT(linePositions.getSize() > 0 && (linePositions.getSize() % 2) == 0);
 
 	// Verts
-	RebarGpuMemoryToken vertsToken;
+	RebarAllocation vertsToken;
 	Vec3* verts = static_cast<Vec3*>(
-		RebarStagingGpuMemoryPool::getSingleton().allocateFrame(sizeof(Vec3) * linePositions.getSize(), vertsToken));
+		RebarTransientMemoryPool::getSingleton().allocateFrame(sizeof(Vec3) * linePositions.getSize(), vertsToken));
 	memcpy(verts, linePositions.getBegin(), linePositions.getSizeInBytes());
 
 	// Set the uniforms
-	RebarGpuMemoryToken unisToken;
+	RebarAllocation unisToken;
 	Mat4* pmvps = static_cast<Mat4*>(
-		RebarStagingGpuMemoryPool::getSingleton().allocateFrame(sizeof(Mat4) * mvps.getSize(), unisToken));
+		RebarTransientMemoryPool::getSingleton().allocateFrame(sizeof(Mat4) * mvps.getSize(), unisToken));
 	memcpy(pmvps, &mvps[0], mvps.getSizeInBytes());
 
 	// Setup state
@@ -204,9 +204,9 @@ void DebugDrawer2::drawLines(ConstWeakArray<Mat4> mvps, const Vec4& color, F32 l
 	cmdb->setPushConstants(&color, sizeof(color));
 
 	cmdb->setVertexAttribute(0, 0, Format::kR32G32B32_Sfloat, 0);
-	cmdb->bindVertexBuffer(0, RebarStagingGpuMemoryPool::getSingleton().getBuffer(), vertsToken.m_offset, sizeof(Vec3));
+	cmdb->bindVertexBuffer(0, RebarTransientMemoryPool::getSingleton().getBuffer(), vertsToken.m_offset, sizeof(Vec3));
 
-	cmdb->bindStorageBuffer(0, 0, RebarStagingGpuMemoryPool::getSingleton().getBuffer(), unisToken.m_offset,
+	cmdb->bindStorageBuffer(0, 0, RebarTransientMemoryPool::getSingleton().getBuffer(), unisToken.m_offset,
 							unisToken.m_range);
 
 	cmdb->setLineWidth(lineSize);
@@ -217,17 +217,17 @@ void DebugDrawer2::drawBillboardTextures(const Mat4& projMat, const Mat3x4& view
 										 const Vec4& color, Bool ditherFailedDepth, TextureViewPtr tex,
 										 SamplerPtr sampler, Vec2 billboardSize, CommandBufferPtr& cmdb) const
 {
-	RebarGpuMemoryToken positionsToken;
+	RebarAllocation positionsToken;
 	Vec3* verts =
-		static_cast<Vec3*>(RebarStagingGpuMemoryPool::getSingleton().allocateFrame(sizeof(Vec3) * 4, positionsToken));
+		static_cast<Vec3*>(RebarTransientMemoryPool::getSingleton().allocateFrame(sizeof(Vec3) * 4, positionsToken));
 
 	verts[0] = Vec3(-0.5f, -0.5f, 0.0f);
 	verts[1] = Vec3(+0.5f, -0.5f, 0.0f);
 	verts[2] = Vec3(-0.5f, +0.5f, 0.0f);
 	verts[3] = Vec3(+0.5f, +0.5f, 0.0f);
 
-	RebarGpuMemoryToken uvsToken;
-	Vec2* uvs = static_cast<Vec2*>(RebarStagingGpuMemoryPool::getSingleton().allocateFrame(sizeof(Vec2) * 4, uvsToken));
+	RebarAllocation uvsToken;
+	Vec2* uvs = static_cast<Vec2*>(RebarTransientMemoryPool::getSingleton().allocateFrame(sizeof(Vec2) * 4, uvsToken));
 
 	uvs[0] = Vec2(0.0f, 0.0f);
 	uvs[1] = Vec2(1.0f, 0.0f);
@@ -235,9 +235,9 @@ void DebugDrawer2::drawBillboardTextures(const Mat4& projMat, const Mat3x4& view
 	uvs[3] = Vec2(1.0f, 1.0f);
 
 	// Set the uniforms
-	RebarGpuMemoryToken unisToken;
+	RebarAllocation unisToken;
 	Mat4* pmvps = static_cast<Mat4*>(
-		RebarStagingGpuMemoryPool::getSingleton().allocateFrame(sizeof(Mat4) * positions.getSize(), unisToken));
+		RebarTransientMemoryPool::getSingleton().allocateFrame(sizeof(Mat4) * positions.getSize(), unisToken));
 
 	const Mat4 camTrf = Mat4(viewMat, Vec4(0.0f, 0.0f, 0.0f, 1.0f)).getInverse();
 	const Vec3 zAxis = camTrf.getZAxis().xyz().getNormalized();
@@ -272,11 +272,11 @@ void DebugDrawer2::drawBillboardTextures(const Mat4& projMat, const Mat3x4& view
 
 	cmdb->setVertexAttribute(0, 0, Format::kR32G32B32_Sfloat, 0);
 	cmdb->setVertexAttribute(1, 1, Format::kR32G32_Sfloat, 0);
-	cmdb->bindVertexBuffer(0, RebarStagingGpuMemoryPool::getSingleton().getBuffer(), positionsToken.m_offset,
+	cmdb->bindVertexBuffer(0, RebarTransientMemoryPool::getSingleton().getBuffer(), positionsToken.m_offset,
 						   sizeof(Vec3));
-	cmdb->bindVertexBuffer(1, RebarStagingGpuMemoryPool::getSingleton().getBuffer(), uvsToken.m_offset, sizeof(Vec2));
+	cmdb->bindVertexBuffer(1, RebarTransientMemoryPool::getSingleton().getBuffer(), uvsToken.m_offset, sizeof(Vec2));
 
-	cmdb->bindStorageBuffer(0, 0, RebarStagingGpuMemoryPool::getSingleton().getBuffer(), unisToken.m_offset,
+	cmdb->bindStorageBuffer(0, 0, RebarTransientMemoryPool::getSingleton().getBuffer(), unisToken.m_offset,
 							unisToken.m_range);
 	cmdb->bindSampler(0, 3, sampler);
 	cmdb->bindTexture(0, 4, tex);

+ 3 - 3
AnKi/Renderer/DebugDrawer.h

@@ -15,14 +15,14 @@
 namespace anki {
 
 // Forward
-class RebarStagingGpuMemoryPool;
-class RebarGpuMemoryToken;
+class RebarTransientMemoryPool;
+class RebarAllocation;
 
 /// @addtogroup renderer
 /// @{
 
 /// Allocate memory for a line cube and populate it.
-void allocateAndPopulateDebugBox(RebarGpuMemoryToken& vertsToken, RebarGpuMemoryToken& indicesToken, U32& indexCount);
+void allocateAndPopulateDebugBox(RebarAllocation& vertsToken, RebarAllocation& indicesToken, U32& indexCount);
 
 /// Debug drawer.
 class DebugDrawer2

+ 9 - 6
AnKi/Renderer/Drawer.cpp

@@ -11,6 +11,9 @@
 #include <AnKi/Util/Logger.h>
 #include <AnKi/Shaders/Include/MaterialTypes.h>
 #include <AnKi/Shaders/Include/GpuSceneFunctions.h>
+#include <AnKi/Core/GpuMemory/UnifiedGeometryBuffer.h>
+#include <AnKi/Core/GpuMemory/RebarTransientMemoryPool.h>
+#include <AnKi/Core/GpuMemory/GpuSceneBuffer.h>
 
 namespace anki {
 
@@ -36,9 +39,9 @@ void RenderableDrawer::drawRange(const RenderableDrawerArguments& args, const Re
 
 	// Allocate, set and bind global uniforms
 	{
-		RebarGpuMemoryToken globalUniformsToken;
+		RebarAllocation globalUniformsToken;
 		MaterialGlobalUniforms* globalUniforms =
-			static_cast<MaterialGlobalUniforms*>(RebarStagingGpuMemoryPool::getSingleton().allocateFrame(
+			static_cast<MaterialGlobalUniforms*>(RebarTransientMemoryPool::getSingleton().allocateFrame(
 				sizeof(MaterialGlobalUniforms), globalUniformsToken));
 
 		globalUniforms->m_viewProjectionMatrix = args.m_viewProjectionMatrix;
@@ -49,7 +52,7 @@ void RenderableDrawer::drawRange(const RenderableDrawerArguments& args, const Re
 		memcpy(&globalUniforms->m_cameraTransform, &args.m_cameraTransform, sizeof(args.m_cameraTransform));
 
 		cmdb->bindUniformBuffer(U32(MaterialSet::kGlobal), U32(MaterialBinding::kGlobalUniforms),
-								RebarStagingGpuMemoryPool::getSingleton().getBuffer(), globalUniformsToken.m_offset,
+								RebarTransientMemoryPool::getSingleton().getBuffer(), globalUniformsToken.m_offset,
 								globalUniformsToken.m_range);
 	}
 
@@ -87,9 +90,9 @@ void RenderableDrawer::flushDrawcall(Context& ctx)
 	CommandBufferPtr cmdb = ctx.m_commandBuffer;
 
 	// Instance buffer
-	RebarGpuMemoryToken token;
+	RebarAllocation token;
 	GpuSceneRenderablePacked* instances =
-		static_cast<GpuSceneRenderablePacked*>(RebarStagingGpuMemoryPool::getSingleton().allocateFrame(
+		static_cast<GpuSceneRenderablePacked*>(RebarTransientMemoryPool::getSingleton().allocateFrame(
 			sizeof(GpuSceneRenderablePacked) * ctx.m_cachedRenderElementCount, token));
 	for(U32 i = 0; i < ctx.m_cachedRenderElementCount; ++i)
 	{
@@ -101,7 +104,7 @@ void RenderableDrawer::flushDrawcall(Context& ctx)
 		instances[i] = packGpuSceneRenderable(renderable);
 	}
 
-	cmdb->bindVertexBuffer(0, RebarStagingGpuMemoryPool::getSingleton().getBuffer(), token.m_offset,
+	cmdb->bindVertexBuffer(0, RebarTransientMemoryPool::getSingleton().getBuffer(), token.m_offset,
 						   sizeof(GpuSceneRenderablePacked), VertexStepRate::kInstance);
 
 	// Set state

+ 1 - 1
AnKi/Renderer/GenericCompute.cpp

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

+ 5 - 4
AnKi/Renderer/PackVisibleClusteredObjects.cpp

@@ -9,6 +9,7 @@
 #include <AnKi/Resource/ResourceManager.h>
 #include <AnKi/Shaders/Include/GpuSceneTypes.h>
 #include <AnKi/Shaders/Include/MiscRendererTypes.h>
+#include <AnKi/Core/GpuMemory/GpuSceneBuffer.h>
 
 namespace anki {
 
@@ -62,10 +63,10 @@ void PackVisibleClusteredObjects::dispatchType(WeakArray<TRenderQueueElement> ar
 		return;
 	}
 
-	RebarGpuMemoryToken token;
+	RebarAllocation token;
 	U32* indices = allocateStorage<U32*>(array.getSize() * sizeof(U32), token);
 
-	RebarGpuMemoryToken extrasToken;
+	RebarAllocation extrasToken;
 	PointLightExtra* plightExtras = nullptr;
 	SpotLightExtra* slightExtras = nullptr;
 	if constexpr(std::is_same_v<TClustererType, PointLight>)
@@ -117,11 +118,11 @@ void PackVisibleClusteredObjects::dispatchType(WeakArray<TRenderQueueElement> ar
 	cmdb->bindStorageBuffer(0, 1, m_allClustererObjects, m_structureBufferOffsets[kType],
 							array.getSize() * sizeof(TClustererType));
 
-	cmdb->bindStorageBuffer(0, 2, RebarStagingGpuMemoryPool::getSingleton().getBuffer(), token.m_offset, token.m_range);
+	cmdb->bindStorageBuffer(0, 2, RebarTransientMemoryPool::getSingleton().getBuffer(), token.m_offset, token.m_range);
 
 	if constexpr(std::is_same_v<TClustererType, PointLight> || std::is_same_v<TClustererType, SpotLight>)
 	{
-		cmdb->bindStorageBuffer(0, 3, RebarStagingGpuMemoryPool::getSingleton().getBuffer(), extrasToken.m_offset,
+		cmdb->bindStorageBuffer(0, 3, RebarTransientMemoryPool::getSingleton().getBuffer(), extrasToken.m_offset,
 								extrasToken.m_range);
 	}
 

+ 1 - 1
AnKi/Renderer/RenderQueue.h

@@ -86,7 +86,7 @@ class GenericGpuComputeJobQueueElementContext final : public RenderingMatrices
 {
 public:
 	CommandBufferPtr m_commandBuffer;
-	RebarStagingGpuMemoryPool* m_rebarStagingPool ANKI_DEBUG_CODE(= nullptr);
+	class RebarTransientMemoryPool* m_rebarStagingPool ANKI_DEBUG_CODE(= nullptr);
 };
 
 /// Callback for GenericGpuComputeJobQueueElement.

+ 1 - 0
AnKi/Renderer/Renderer.cpp

@@ -13,6 +13,7 @@
 #include <AnKi/Collision/Plane.h>
 #include <AnKi/Collision/Functions.h>
 #include <AnKi/Shaders/Include/ClusteredShadingTypes.h>
+#include <AnKi/Core/GpuMemory/GpuSceneBuffer.h>
 
 #include <AnKi/Renderer/ProbeReflections.h>
 #include <AnKi/Renderer/GBuffer.h>

+ 0 - 1
AnKi/Renderer/Renderer.h

@@ -10,7 +10,6 @@
 #include <AnKi/Math.h>
 #include <AnKi/Gr.h>
 #include <AnKi/Resource/Forward.h>
-#include <AnKi/Core/GpuMemoryPools.h>
 #include <AnKi/Collision/Forward.h>
 
 namespace anki {

+ 6 - 6
AnKi/Renderer/RendererObject.cpp

@@ -16,16 +16,16 @@ Renderer& RendererObject::getRenderer()
 	return MainRenderer::getSingleton().getOffscreenRenderer();
 }
 
-void* RendererObject::allocateRebarStagingMemory(PtrSize size, RebarGpuMemoryToken& token)
+void* RendererObject::allocateRebarStagingMemory(PtrSize size, RebarAllocation& token)
 {
-	return RebarStagingGpuMemoryPool::getSingleton().allocateFrame(size, token);
+	return RebarTransientMemoryPool::getSingleton().allocateFrame(size, token);
 }
 
-void RendererObject::bindUniforms(CommandBufferPtr& cmdb, U32 set, U32 binding, const RebarGpuMemoryToken& token) const
+void RendererObject::bindUniforms(CommandBufferPtr& cmdb, U32 set, U32 binding, const RebarAllocation& token) const
 {
 	if(!token.isUnused())
 	{
-		cmdb->bindUniformBuffer(set, binding, RebarStagingGpuMemoryPool::getSingleton().getBuffer(), token.m_offset,
+		cmdb->bindUniformBuffer(set, binding, RebarTransientMemoryPool::getSingleton().getBuffer(), token.m_offset,
 								token.m_range);
 	}
 	else
@@ -35,11 +35,11 @@ void RendererObject::bindUniforms(CommandBufferPtr& cmdb, U32 set, U32 binding,
 	}
 }
 
-void RendererObject::bindStorage(CommandBufferPtr& cmdb, U32 set, U32 binding, const RebarGpuMemoryToken& token) const
+void RendererObject::bindStorage(CommandBufferPtr& cmdb, U32 set, U32 binding, const RebarAllocation& token) const
 {
 	if(!token.isUnused())
 	{
-		cmdb->bindStorageBuffer(set, binding, RebarStagingGpuMemoryPool::getSingleton().getBuffer(), token.m_offset,
+		cmdb->bindStorageBuffer(set, binding, RebarTransientMemoryPool::getSingleton().getBuffer(), token.m_offset,
 								token.m_range);
 	}
 	else

+ 8 - 8
AnKi/Renderer/RendererObject.h

@@ -10,7 +10,7 @@
 #include <AnKi/Gr.h>
 #include <AnKi/Resource/ResourceManager.h>
 #include <AnKi/Resource/ShaderProgramResource.h>
-#include <AnKi/Core/GpuMemoryPools.h>
+#include <AnKi/Core/GpuMemory/RebarTransientMemoryPool.h>
 
 namespace anki {
 
@@ -39,7 +39,7 @@ public:
 protected:
 	static ANKI_PURE Renderer& getRenderer();
 
-	void* allocateRebarStagingMemory(PtrSize size, RebarGpuMemoryToken& token);
+	void* allocateRebarStagingMemory(PtrSize size, RebarAllocation& token);
 
 	U32 computeNumberOfSecondLevelCommandBuffers(U32 drawcallCount) const;
 
@@ -68,34 +68,34 @@ protected:
 	}
 
 	template<typename TPtr>
-	TPtr allocateUniforms(PtrSize size, RebarGpuMemoryToken& token)
+	TPtr allocateUniforms(PtrSize size, RebarAllocation& token)
 	{
 		return static_cast<TPtr>(allocateRebarStagingMemory(size, token));
 	}
 
-	void bindUniforms(CommandBufferPtr& cmdb, U32 set, U32 binding, const RebarGpuMemoryToken& token) const;
+	void bindUniforms(CommandBufferPtr& cmdb, U32 set, U32 binding, const RebarAllocation& token) const;
 
 	template<typename TPtr>
 	TPtr allocateAndBindUniforms(PtrSize size, CommandBufferPtr& cmdb, U32 set, U32 binding)
 	{
-		RebarGpuMemoryToken token;
+		RebarAllocation token;
 		TPtr ptr = allocateUniforms<TPtr>(size, token);
 		bindUniforms(cmdb, set, binding, token);
 		return ptr;
 	}
 
 	template<typename TPtr>
-	TPtr allocateStorage(PtrSize size, RebarGpuMemoryToken& token)
+	TPtr allocateStorage(PtrSize size, RebarAllocation& token)
 	{
 		return static_cast<TPtr>(allocateRebarStagingMemory(size, token));
 	}
 
-	void bindStorage(CommandBufferPtr& cmdb, U32 set, U32 binding, const RebarGpuMemoryToken& token) const;
+	void bindStorage(CommandBufferPtr& cmdb, U32 set, U32 binding, const RebarAllocation& token) const;
 
 	template<typename TPtr>
 	TPtr allocateAndBindStorage(PtrSize size, CommandBufferPtr& cmdb, U32 set, U32 binding)
 	{
-		RebarGpuMemoryToken token;
+		RebarAllocation token;
 		TPtr ptr = allocateStorage<TPtr>(size, token);
 		bindStorage(cmdb, set, binding, token);
 		return ptr;

+ 7 - 5
AnKi/Renderer/RtShadows.cpp

@@ -17,6 +17,8 @@
 #include <AnKi/Core/ConfigSet.h>
 #include <AnKi/Shaders/Include/MaterialTypes.h>
 #include <AnKi/Shaders/Include/GpuSceneTypes.h>
+#include <AnKi/Core/GpuMemory/UnifiedGeometryBuffer.h>
+#include <AnKi/Core/GpuMemory/GpuSceneBuffer.h>
 
 namespace anki {
 
@@ -450,15 +452,15 @@ void RtShadows::run(RenderPassWorkContext& rgraphCtx)
 
 	// Allocate, set and bind global uniforms
 	{
-		RebarGpuMemoryToken globalUniformsToken;
+		RebarAllocation globalUniformsToken;
 		MaterialGlobalUniforms* globalUniforms =
-			static_cast<MaterialGlobalUniforms*>(RebarStagingGpuMemoryPool::getSingleton().allocateFrame(
+			static_cast<MaterialGlobalUniforms*>(RebarTransientMemoryPool::getSingleton().allocateFrame(
 				sizeof(MaterialGlobalUniforms), globalUniformsToken));
 
 		memset(globalUniforms, 0, sizeof(*globalUniforms)); // Don't care for now
 
 		cmdb->bindUniformBuffer(U32(MaterialSet::kGlobal), U32(MaterialBinding::kGlobalUniforms),
-								RebarStagingGpuMemoryPool::getSingleton().getBuffer(), globalUniformsToken.m_offset,
+								RebarTransientMemoryPool::getSingleton().getBuffer(), globalUniformsToken.m_offset,
 								globalUniformsToken.m_range);
 	}
 
@@ -643,10 +645,10 @@ void RtShadows::buildSbt(RenderingContext& ctx)
 	m_runCtx.m_hitGroupCount = instanceCount;
 
 	// Allocate SBT
-	RebarGpuMemoryToken token;
+	RebarAllocation token;
 	U8* sbt = allocateStorage<U8*>(PtrSize(m_sbtRecordSize) * (instanceCount + extraSbtRecords), token);
 	[[maybe_unused]] const U8* sbtStart = sbt;
-	m_runCtx.m_sbtBuffer = RebarStagingGpuMemoryPool::getSingleton().getBuffer();
+	m_runCtx.m_sbtBuffer = RebarTransientMemoryPool::getSingleton().getBuffer();
 	m_runCtx.m_sbtOffset = token.m_offset;
 
 	// Set the miss and ray gen handles

+ 0 - 1
AnKi/Resource/MeshResource.cpp

@@ -7,7 +7,6 @@
 #include <AnKi/Resource/ResourceManager.h>
 #include <AnKi/Resource/MeshBinaryLoader.h>
 #include <AnKi/Resource/AsyncLoader.h>
-#include <AnKi/Core/GpuMemoryPools.h>
 #include <AnKi/Util/Functions.h>
 #include <AnKi/Util/Filesystem.h>
 

+ 1 - 1
AnKi/Resource/MeshResource.h

@@ -10,7 +10,7 @@
 #include <AnKi/Gr.h>
 #include <AnKi/Collision/Aabb.h>
 #include <AnKi/Shaders/Include/MeshTypes.h>
-#include <AnKi/Core/GpuMemoryPools.h>
+#include <AnKi/Core/GpuMemory/UnifiedGeometryBuffer.h>
 
 namespace anki {
 

+ 0 - 1
AnKi/Scene/Common.h

@@ -7,7 +7,6 @@
 
 #include <AnKi/Util/String.h>
 #include <AnKi/Scene/Forward.h>
-#include <AnKi/Core/GpuMemoryPools.h>
 #include <AnKi/Shaders/Include/GpuSceneTypes.h>
 #include <functional>
 

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

@@ -7,6 +7,7 @@
 #include <AnKi/Scene/SceneGraph.h>
 #include <AnKi/Resource/ResourceManager.h>
 #include <AnKi/Shaders/Include/ClusteredShadingTypes.h>
+#include <AnKi/Core/GpuMemory/GpuSceneBuffer.h>
 
 namespace anki {
 

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

@@ -6,6 +6,7 @@
 #include <AnKi/Scene/Components/FogDensityComponent.h>
 #include <AnKi/Scene/SceneNode.h>
 #include <AnKi/Scene/SceneGraph.h>
+#include <AnKi/Core/GpuMemory/GpuSceneBuffer.h>
 
 namespace anki {
 

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

@@ -11,6 +11,7 @@
 #include <AnKi/Util/Forward.h>
 #include <AnKi/Util/WeakArray.h>
 #include <AnKi/Math.h>
+#include <AnKi/Core/GpuMemory/GpuSceneBuffer.h>
 
 namespace anki {
 

+ 1 - 1
AnKi/Scene/ContiguousArrayAllocator.h

@@ -6,7 +6,7 @@
 #pragma once
 
 #include <AnKi/Scene/Common.h>
-#include <AnKi/Core/GpuMemoryPools.h>
+#include <AnKi/Core/GpuMemory/GpuSceneBuffer.h>
 
 namespace anki {
 

+ 1 - 0
AnKi/Scene/RenderStateBucket.h

@@ -7,6 +7,7 @@
 
 #include <AnKi/Scene/Common.h>
 #include <AnKi/Resource/RenderingKey.h>
+#include <AnKi/Gr/ShaderProgram.h>
 
 namespace anki {
 

+ 6 - 7
AnKi/Ui/Canvas.cpp

@@ -7,7 +7,7 @@
 #include <AnKi/Ui/Font.h>
 #include <AnKi/Ui/UiManager.h>
 #include <AnKi/Resource/ResourceManager.h>
-#include <AnKi/Core/GpuMemoryPools.h>
+#include <AnKi/Core/GpuMemory/RebarTransientMemoryPool.h>
 #include <AnKi/Window/Input.h>
 #include <AnKi/Gr/Sampler.h>
 #include <AnKi/Gr/GrManager.h>
@@ -190,7 +190,7 @@ void Canvas::appendToCommandBufferInternal(CommandBufferPtr& cmdb)
 	ImDrawData& drawData = *ImGui::GetDrawData();
 
 	// Allocate index and vertex buffers
-	RebarGpuMemoryToken vertsToken, indicesToken;
+	RebarAllocation vertsToken, indicesToken;
 	{
 		const U32 verticesSize = U32(drawData.TotalVtxCount) * sizeof(ImDrawVert);
 		const U32 indicesSize = U32(drawData.TotalIdxCount) * sizeof(ImDrawIdx);
@@ -201,9 +201,9 @@ void Canvas::appendToCommandBufferInternal(CommandBufferPtr& cmdb)
 		}
 
 		ImDrawVert* verts =
-			static_cast<ImDrawVert*>(RebarStagingGpuMemoryPool::getSingleton().allocateFrame(verticesSize, vertsToken));
+			static_cast<ImDrawVert*>(RebarTransientMemoryPool::getSingleton().allocateFrame(verticesSize, vertsToken));
 		ImDrawIdx* indices =
-			static_cast<ImDrawIdx*>(RebarStagingGpuMemoryPool::getSingleton().allocateFrame(indicesSize, indicesToken));
+			static_cast<ImDrawIdx*>(RebarTransientMemoryPool::getSingleton().allocateFrame(indicesSize, indicesToken));
 
 		for(I n = 0; n < drawData.CmdListsCount; ++n)
 		{
@@ -222,14 +222,13 @@ void Canvas::appendToCommandBufferInternal(CommandBufferPtr& cmdb)
 	const F32 fbHeight = drawData.DisplaySize.y * drawData.FramebufferScale.y;
 	cmdb->setViewport(0, 0, U32(fbWidth), U32(fbHeight));
 
-	cmdb->bindVertexBuffer(0, RebarStagingGpuMemoryPool::getSingleton().getBuffer(), vertsToken.m_offset,
+	cmdb->bindVertexBuffer(0, RebarTransientMemoryPool::getSingleton().getBuffer(), vertsToken.m_offset,
 						   sizeof(ImDrawVert));
 	cmdb->setVertexAttribute(0, 0, Format::kR32G32_Sfloat, 0);
 	cmdb->setVertexAttribute(1, 0, Format::kR8G8B8A8_Unorm, sizeof(Vec2) * 2);
 	cmdb->setVertexAttribute(2, 0, Format::kR32G32_Sfloat, sizeof(Vec2));
 
-	cmdb->bindIndexBuffer(RebarStagingGpuMemoryPool::getSingleton().getBuffer(), indicesToken.m_offset,
-						  IndexType::kU16);
+	cmdb->bindIndexBuffer(RebarTransientMemoryPool::getSingleton().getBuffer(), indicesToken.m_offset, IndexType::kU16);
 
 	// Will project scissor/clipping rectangles into framebuffer space
 	const Vec2 clipOff = drawData.DisplayPos; // (0,0) unless using multi-viewports

+ 7 - 7
Tests/Gr/Gr.cpp

@@ -10,8 +10,8 @@
 #include <AnKi/Window/NativeWindow.h>
 #include <AnKi/Window/Input.h>
 #include <AnKi/Core/ConfigSet.h>
+#include <AnKi/Core/GpuMemory/RebarTransientMemoryPool.h>
 #include <AnKi/Util/HighRezTimer.h>
-#include <AnKi/Core/GpuMemoryPools.h>
 #include <AnKi/Resource/TransferGpuAllocator.h>
 #include <AnKi/ShaderCompiler/ShaderProgramParser.h>
 #include <AnKi/Collision/Aabb.h>
@@ -231,7 +231,7 @@ void main()
 
 static NativeWindow* g_win = nullptr;
 static GrManager* g_gr = nullptr;
-static RebarStagingGpuMemoryPool* stagingMem = nullptr;
+static RebarTransientMemoryPool* stagingMem = nullptr;
 static Input* input = nullptr;
 
 #define COMMON_BEGIN() \
@@ -245,8 +245,8 @@ static Input* input = nullptr;
 	g_win = createWindow(cfg); \
 	ANKI_TEST_EXPECT_NO_ERR(Input::allocateSingleton().init()); \
 	g_gr = createGrManager(g_win); \
-	RebarStagingGpuMemoryPool::allocateSingleton().init(); \
-	stagingMem = &RebarStagingGpuMemoryPool::getSingleton(); \
+	RebarTransientMemoryPool::allocateSingleton().init(); \
+	stagingMem = &RebarTransientMemoryPool::getSingleton(); \
 	TransferGpuAllocator* transfAlloc = new TransferGpuAllocator(); \
 	ANKI_TEST_EXPECT_NO_ERR(transfAlloc->init(128_MB)); \
 	while(true) \
@@ -257,7 +257,7 @@ static Input* input = nullptr;
 	} \
 	g_gr->finish(); \
 	delete transfAlloc; \
-	RebarStagingGpuMemoryPool::freeSingleton(); \
+	RebarTransientMemoryPool::freeSingleton(); \
 	GrManager::freeSingleton(); \
 	Input::freeSingleton(); \
 	NativeWindow::freeSingleton(); \
@@ -267,7 +267,7 @@ static Input* input = nullptr;
 
 static void* setUniforms(PtrSize size, CommandBufferPtr& cmdb, U32 set, U32 binding)
 {
-	RebarGpuMemoryToken token;
+	RebarAllocation token;
 	void* ptr = stagingMem->allocateFrame(size, token);
 	cmdb->bindUniformBuffer(set, binding, stagingMem->getBuffer(), token.m_offset, token.m_range);
 	return ptr;
@@ -275,7 +275,7 @@ static void* setUniforms(PtrSize size, CommandBufferPtr& cmdb, U32 set, U32 bind
 
 static void* setStorage(PtrSize size, CommandBufferPtr& cmdb, U32 set, U32 binding)
 {
-	RebarGpuMemoryToken token;
+	RebarAllocation token;
 	void* ptr = stagingMem->allocateFrame(size, token);
 	cmdb->bindStorageBuffer(set, binding, stagingMem->getBuffer(), token.m_offset, token.m_range);
 	return ptr;

+ 4 - 4
Tests/Ui/Ui.cpp

@@ -5,10 +5,10 @@
 
 #include <Tests/Framework/Framework.h>
 #include <AnKi/Core/ConfigSet.h>
+#include <AnKi/Core/GpuMemory/RebarTransientMemoryPool.h>
 #include <AnKi/Util/HighRezTimer.h>
 #include <AnKi/Ui.h>
 #include <AnKi/Window.h>
-#include <AnKi/Core/GpuMemoryPools.h>
 
 using namespace anki;
 
@@ -71,7 +71,7 @@ ANKI_TEST(Ui, Ui)
 	createResourceManager(gr);
 	UiManager* ui = &UiManager::allocateSingleton();
 
-	RebarStagingGpuMemoryPool::allocateSingleton().init();
+	RebarTransientMemoryPool::allocateSingleton().init();
 
 	ANKI_TEST_EXPECT_NO_ERR(ui->init(allocAligned, nullptr));
 
@@ -137,7 +137,7 @@ ANKI_TEST(Ui, Ui)
 			cmdb->flush();
 
 			gr->swapBuffers();
-			RebarStagingGpuMemoryPool::getSingleton().endFrame();
+			RebarTransientMemoryPool::getSingleton().endFrame();
 
 			timer.stop();
 			const F32 TICK = 1.0f / 30.0f;
@@ -149,7 +149,7 @@ ANKI_TEST(Ui, Ui)
 	}
 
 	UiManager::freeSingleton();
-	RebarStagingGpuMemoryPool::freeSingleton();
+	RebarTransientMemoryPool::freeSingleton();
 	ResourceManager::freeSingleton();
 	GrManager::freeSingleton();
 	Input::freeSingleton();

+ 1 - 1
Tests/Util/Tracer.cpp

@@ -12,7 +12,7 @@
 ANKI_TEST(Util, Tracer)
 {
 	HeapMemoryPool alloc(allocAligned, nullptr);
-	CoreTracer::allocateSingleton().init("./");
+	ANKI_TEST_EXPECT_NO_ERR(CoreTracer::allocateSingleton().init("./"));
 	Tracer::getSingleton().setEnabled(true);
 
 	// 1st frame