Răsfoiți Sursa

Resources use the new allocator

Panagiotis Christopoulos Charitos 8 ani în urmă
părinte
comite
e97e2bbc24

+ 1 - 0
src/anki/Gr.h

@@ -13,6 +13,7 @@
 #include <anki/gr/Framebuffer.h>
 #include <anki/gr/CommandBuffer.h>
 #include <anki/gr/OcclusionQuery.h>
+#include <anki/gr/Fence.h>
 #include <anki/gr/GrManager.h>
 #include <anki/gr/GrObjectCache.h>
 

+ 9 - 3
src/anki/core/App.cpp

@@ -256,7 +256,6 @@ Error App::initInternal(const ConfigSet& config_, AllocAlignedCallback allocCb,
 	//
 	ResourceManagerInitInfo rinit;
 	rinit.m_gr = m_gr;
-	rinit.m_stagingMem = m_stagingMem;
 	rinit.m_physics = m_physics;
 	rinit.m_resourceFs = m_resourceFs;
 	rinit.m_config = &config;
@@ -288,8 +287,15 @@ Error App::initInternal(const ConfigSet& config_, AllocAlignedCallback allocCb,
 	//
 	m_scene = m_heapAlloc.newInstance<SceneGraph>();
 
-	ANKI_CHECK(m_scene->init(
-		m_allocCb, m_allocCbData, m_threadpool, m_threadHive, m_resources, m_input, &m_globalTimestamp, config));
+	ANKI_CHECK(m_scene->init(m_allocCb,
+		m_allocCbData,
+		m_threadpool,
+		m_threadHive,
+		m_resources,
+		m_stagingMem,
+		m_input,
+		&m_globalTimestamp,
+		config));
 
 	//
 	// Script

+ 3 - 0
src/anki/gr/gl/CommandBuffer.cpp

@@ -57,6 +57,9 @@ void CommandBuffer::flush(FencePtr* fence)
 	if(!m_impl->isSecondLevel())
 	{
 		ANKI_ASSERT(!m_impl->m_state.insideRenderPass());
+	}
+	else
+	{
 		ANKI_ASSERT(fence == nullptr);
 	}
 

+ 44 - 67
src/anki/resource/Mesh.cpp

@@ -9,7 +9,6 @@
 #include <anki/resource/AsyncLoader.h>
 #include <anki/util/Functions.h>
 #include <anki/misc/Xml.h>
-#include <anki/core/StagingGpuMemoryManager.h>
 
 namespace anki
 {
@@ -19,9 +18,9 @@ class MeshLoadTask : public AsyncLoaderTask
 {
 public:
 	ResourceManager* m_manager ANKI_DBG_NULLIFY;
+	MeshLoader m_loader;
 	BufferPtr m_vertBuff;
 	BufferPtr m_indicesBuff;
-	MeshLoader m_loader;
 
 	MeshLoadTask(ResourceManager* manager)
 		: m_manager(manager)
@@ -35,80 +34,58 @@ public:
 Error MeshLoadTask::operator()(AsyncLoaderTaskContext& ctx)
 {
 	GrManager& gr = m_manager->getGrManager();
-	StagingGpuMemoryManager& stagingMem = m_manager->getStagingGpuMemoryManager();
-	CommandBufferPtr cmdb;
+	TransferGpuAllocator& transferAlloc = m_manager->getTransferGpuAllocator();
+	Array<TransferGpuAllocatorHandle, 2> handles;
+
+	CommandBufferInitInfo cmdbinit;
+	cmdbinit.m_flags = CommandBufferFlag::SMALL_BATCH | CommandBufferFlag::TRANSFER_WORK;
+	CommandBufferPtr cmdb = gr.newInstance<CommandBuffer>(cmdbinit);
 
 	// Write vert buff
-	if(m_vertBuff)
 	{
-		StagingGpuMemoryToken token;
-		void* data = stagingMem.tryAllocateFrame(m_loader.getVertexDataSize(), StagingGpuMemoryType::TRANSFER, token);
-
-		if(data)
-		{
-			memcpy(data, m_loader.getVertexData(), m_loader.getVertexDataSize());
-			CommandBufferInitInfo cmdbinit;
-			cmdbinit.m_flags = CommandBufferFlag::SMALL_BATCH;
-			cmdb = gr.newInstance<CommandBuffer>(cmdbinit);
-
-			cmdb->setBufferBarrier(
-				m_vertBuff, BufferUsageBit::VERTEX, BufferUsageBit::BUFFER_UPLOAD_DESTINATION, 0, MAX_PTR_SIZE);
-
-			cmdb->copyBufferToBuffer(token.m_buffer, token.m_offset, m_vertBuff, 0, token.m_range);
-
-			cmdb->setBufferBarrier(
-				m_vertBuff, BufferUsageBit::BUFFER_UPLOAD_DESTINATION, BufferUsageBit::VERTEX, 0, MAX_PTR_SIZE);
-
-			m_vertBuff.reset(nullptr);
-		}
-		else
-		{
-			ctx.m_pause = true;
-			ctx.m_resubmitTask = true;
-			return ErrorCode::NONE;
-		}
+		ANKI_CHECK(transferAlloc.allocate(m_loader.getVertexDataSize(), handles[0]));
+		void* data = handles[0].getMappedMemory();
+		ANKI_ASSERT(data);
+
+		memcpy(data, m_loader.getVertexData(), m_loader.getVertexDataSize());
+
+		cmdb->setBufferBarrier(
+			m_vertBuff, BufferUsageBit::VERTEX, BufferUsageBit::BUFFER_UPLOAD_DESTINATION, 0, MAX_PTR_SIZE);
+
+		cmdb->copyBufferToBuffer(handles[0].getBuffer(), handles[0].getOffset(), m_vertBuff, 0, handles[0].getRange());
+
+		cmdb->setBufferBarrier(
+			m_vertBuff, BufferUsageBit::BUFFER_UPLOAD_DESTINATION, BufferUsageBit::VERTEX, 0, MAX_PTR_SIZE);
+
+		m_vertBuff.reset(nullptr);
 	}
 
 	// Create index buffer
 	{
-		StagingGpuMemoryToken token;
-		void* data = stagingMem.tryAllocateFrame(m_loader.getIndexDataSize(), StagingGpuMemoryType::TRANSFER, token);
-
-		if(data)
-		{
-			memcpy(data, m_loader.getIndexData(), m_loader.getIndexDataSize());
-
-			if(!cmdb)
-			{
-				CommandBufferInitInfo cmdbinit;
-				cmdbinit.m_flags = CommandBufferFlag::SMALL_BATCH;
-				cmdb = gr.newInstance<CommandBuffer>(cmdbinit);
-			}
-
-			cmdb->setBufferBarrier(
-				m_indicesBuff, BufferUsageBit::INDEX, BufferUsageBit::BUFFER_UPLOAD_DESTINATION, 0, MAX_PTR_SIZE);
-
-			cmdb->copyBufferToBuffer(token.m_buffer, token.m_offset, m_indicesBuff, 0, token.m_range);
-
-			cmdb->setBufferBarrier(
-				m_indicesBuff, BufferUsageBit::BUFFER_UPLOAD_DESTINATION, BufferUsageBit::INDEX, 0, MAX_PTR_SIZE);
-
-			cmdb->flush();
-		}
-		else
-		{
-			// Submit prev work
-			if(cmdb)
-			{
-				cmdb->flush();
-			}
-
-			ctx.m_pause = true;
-			ctx.m_resubmitTask = true;
-			return ErrorCode::NONE;
-		}
+		ANKI_CHECK(transferAlloc.allocate(m_loader.getIndexDataSize(), handles[1]));
+		void* data = handles[1].getMappedMemory();
+		ANKI_ASSERT(data);
+
+		memcpy(data, m_loader.getIndexData(), m_loader.getIndexDataSize());
+
+		cmdb->setBufferBarrier(
+			m_indicesBuff, BufferUsageBit::INDEX, BufferUsageBit::BUFFER_UPLOAD_DESTINATION, 0, MAX_PTR_SIZE);
+
+		cmdb->copyBufferToBuffer(
+			handles[1].getBuffer(), handles[1].getOffset(), m_indicesBuff, 0, handles[1].getRange());
+
+		cmdb->setBufferBarrier(
+			m_indicesBuff, BufferUsageBit::BUFFER_UPLOAD_DESTINATION, BufferUsageBit::INDEX, 0, MAX_PTR_SIZE);
+
+		m_indicesBuff.reset(nullptr);
 	}
 
+	FencePtr fence;
+	cmdb->flush(&fence);
+
+	transferAlloc.release(handles[0], fence);
+	transferAlloc.release(handles[1], fence);
+
 	return ErrorCode::NONE;
 }
 

+ 0 - 1
src/anki/resource/ResourceManager.cpp

@@ -38,7 +38,6 @@ ResourceManager::~ResourceManager()
 Error ResourceManager::init(ResourceManagerInitInfo& init)
 {
 	m_gr = init.m_gr;
-	m_stagingMem = init.m_stagingMem;
 	m_physics = init.m_physics;
 	m_fs = init.m_resourceFs;
 	m_alloc = ResourceAllocator<U8>(init.m_allocCallback, init.m_allocCallbackData);

+ 0 - 9
src/anki/resource/ResourceManager.h

@@ -21,7 +21,6 @@ class ResourceManager;
 class AsyncLoader;
 class ResourceManagerModel;
 class Renderer;
-class StagingGpuMemoryManager;
 
 /// @addtogroup resource
 /// @{
@@ -93,7 +92,6 @@ class ResourceManagerInitInfo
 {
 public:
 	GrManager* m_gr = nullptr;
-	StagingGpuMemoryManager* m_stagingMem = nullptr;
 	PhysicsWorld* m_physics = nullptr;
 	ResourceFilesystem* m_resourceFs = nullptr;
 	const ConfigSet* m_config = nullptr;
@@ -163,12 +161,6 @@ anki_internal:
 		return *m_gr;
 	}
 
-	StagingGpuMemoryManager& getStagingGpuMemoryManager()
-	{
-		ANKI_ASSERT(m_stagingMem);
-		return *m_stagingMem;
-	}
-
 	TransferGpuAllocator& getTransferGpuAllocator()
 	{
 		return m_transferGpuAlloc;
@@ -236,7 +228,6 @@ anki_internal:
 
 private:
 	GrManager* m_gr = nullptr;
-	StagingGpuMemoryManager* m_stagingMem = nullptr;
 	PhysicsWorld* m_physics = nullptr;
 	ResourceFilesystem* m_fs = nullptr;
 	ResourceAllocator<U8> m_alloc;

+ 66 - 68
src/anki/resource/TextureResource.cpp

@@ -7,7 +7,6 @@
 #include <anki/resource/ImageLoader.h>
 #include <anki/resource/ResourceManager.h>
 #include <anki/resource/AsyncLoader.h>
-#include <anki/core/StagingGpuMemoryManager.h>
 
 namespace anki
 {
@@ -16,41 +15,60 @@ namespace anki
 class TexUploadTask : public AsyncLoaderTask
 {
 public:
+	static constexpr U MAX_COPIES_BEFORE_FLUSH = 8;
+
 	ImageLoader m_loader;
 	TexturePtr m_tex;
 	GrManager* m_gr ANKI_DBG_NULLIFY;
-	StagingGpuMemoryManager* m_stagingMem ANKI_DBG_NULLIFY;
+	TransferGpuAllocator* m_transferAlloc ANKI_DBG_NULLIFY;
 	U m_layers = 0;
 	U m_faces = 0;
 	TextureType m_texType;
 
-	class
-	{
-	public:
-		U m_face = 0;
-		U m_mip = 0;
-		U m_layer = 0;
-	} m_ctx;
-
 	TexUploadTask(GenericMemoryPoolAllocator<U8> alloc)
 		: m_loader(alloc)
 	{
 	}
 
 	Error operator()(AsyncLoaderTaskContext& ctx) final;
+
+	void flush(WeakArray<TransferGpuAllocatorHandle> handles, CommandBufferPtr& cmdb);
 };
 
+void TexUploadTask::flush(WeakArray<TransferGpuAllocatorHandle> handles, CommandBufferPtr& cmdb)
+{
+	FencePtr fence;
+	cmdb->flush(&fence);
+
+	for(TransferGpuAllocatorHandle& handle : handles)
+	{
+		m_transferAlloc->release(handle, fence);
+	}
+
+	cmdb.reset(nullptr);
+}
+
 Error TexUploadTask::operator()(AsyncLoaderTaskContext& ctx)
 {
 	CommandBufferPtr cmdb;
 
+	Array<TransferGpuAllocatorHandle, MAX_COPIES_BEFORE_FLUSH> handles;
+	U handleCount = 0;
+
 	// Upload the data
-	for(U layer = m_ctx.m_layer; layer < m_layers; ++layer)
+	for(U layer = 0; layer < m_layers; ++layer)
 	{
-		for(U face = m_ctx.m_face; face < m_faces; ++face)
+		for(U face = 0; face < m_faces; ++face)
 		{
-			for(U mip = m_ctx.m_mip; mip < m_loader.getMipLevelsCount(); ++mip)
+			for(U mip = 0; mip < m_loader.getMipLevelsCount(); ++mip)
 			{
+				if(!cmdb)
+				{
+					CommandBufferInitInfo ci;
+					ci.m_flags = CommandBufferFlag::TRANSFER_WORK | CommandBufferFlag::SMALL_BATCH;
+					cmdb = m_gr->newInstance<CommandBuffer>(ci);
+				}
+
 				PtrSize surfOrVolSize;
 				const void* surfOrVolData;
 				PtrSize allocationSize;
@@ -74,78 +92,58 @@ Error TexUploadTask::operator()(AsyncLoaderTaskContext& ctx)
 
 				ANKI_ASSERT(allocationSize >= surfOrVolSize);
 
-				StagingGpuMemoryToken token;
-				void* data = m_stagingMem->tryAllocateFrame(allocationSize, StagingGpuMemoryType::TRANSFER, token);
-
-				if(data)
-				{
-					// There is enough transfer memory
-
-					memcpy(data, surfOrVolData, surfOrVolSize);
-
-					if(!cmdb)
-					{
-						CommandBufferInitInfo ci;
-						ci.m_flags = CommandBufferFlag::TRANSFER_WORK | CommandBufferFlag::SMALL_BATCH;
-
-						cmdb = m_gr->newInstance<CommandBuffer>(ci);
-					}
+				TransferGpuAllocatorHandle& handle = handles[handleCount++];
+				ANKI_CHECK(m_transferAlloc->allocate(allocationSize, handle));
+				void* data = handle.getMappedMemory();
+				ANKI_ASSERT(data);
 
-					if(m_texType == TextureType::_3D)
-					{
-						TextureVolumeInfo vol(mip);
+				memcpy(data, surfOrVolData, surfOrVolSize);
 
-						cmdb->setTextureVolumeBarrier(
-							m_tex, TextureUsageBit::NONE, TextureUsageBit::TRANSFER_DESTINATION, vol);
-
-						cmdb->copyBufferToTextureVolume(token.m_buffer, token.m_offset, token.m_range, m_tex, vol);
-
-						cmdb->setTextureVolumeBarrier(m_tex,
-							TextureUsageBit::TRANSFER_DESTINATION,
-							TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::SAMPLED_TESSELLATION_EVALUATION,
-							vol);
-					}
-					else
-					{
-						TextureSurfaceInfo surf(mip, 0, face, layer);
+				if(m_texType == TextureType::_3D)
+				{
+					TextureVolumeInfo vol(mip);
 
-						cmdb->setTextureSurfaceBarrier(
-							m_tex, TextureUsageBit::NONE, TextureUsageBit::TRANSFER_DESTINATION, surf);
+					cmdb->setTextureVolumeBarrier(
+						m_tex, TextureUsageBit::NONE, TextureUsageBit::TRANSFER_DESTINATION, vol);
 
-						cmdb->copyBufferToTextureSurface(token.m_buffer, token.m_offset, token.m_range, m_tex, surf);
+					cmdb->copyBufferToTextureVolume(
+						handle.getBuffer(), handle.getOffset(), handle.getRange(), m_tex, vol);
 
-						cmdb->setTextureSurfaceBarrier(m_tex,
-							TextureUsageBit::TRANSFER_DESTINATION,
-							TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::SAMPLED_TESSELLATION_EVALUATION,
-							surf);
-					}
+					cmdb->setTextureVolumeBarrier(m_tex,
+						TextureUsageBit::TRANSFER_DESTINATION,
+						TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::SAMPLED_TESSELLATION_EVALUATION,
+						vol);
 				}
 				else
 				{
-					// Not enough transfer memory. Move the work to the future
+					TextureSurfaceInfo surf(mip, 0, face, layer);
 
-					if(cmdb)
-					{
-						cmdb->flush();
-					}
+					cmdb->setTextureSurfaceBarrier(
+						m_tex, TextureUsageBit::NONE, TextureUsageBit::TRANSFER_DESTINATION, surf);
 
-					m_ctx.m_mip = mip;
-					m_ctx.m_face = face;
-					m_ctx.m_layer = layer;
+					cmdb->copyBufferToTextureSurface(
+						handle.getBuffer(), handle.getOffset(), handle.getRange(), m_tex, surf);
 
-					ctx.m_pause = true;
-					ctx.m_resubmitTask = true;
+					cmdb->setTextureSurfaceBarrier(m_tex,
+						TextureUsageBit::TRANSFER_DESTINATION,
+						TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::SAMPLED_TESSELLATION_EVALUATION,
+						surf);
+				}
 
-					return ErrorCode::NONE;
+				// Check if you should flush the batch
+				if(handleCount == handles.getSize())
+				{
+					flush({&handles[0], handleCount}, cmdb);
+					handleCount = 0;
 				}
 			}
 		}
 	}
 
-	// Finaly enque the command buffer
-	if(cmdb)
+	// Enque what remains
+	if(handleCount)
 	{
-		cmdb->flush();
+		flush({&handles[0], handleCount}, cmdb);
 	}
 
 	return ErrorCode::NONE;
@@ -275,7 +273,7 @@ Error TextureResource::load(const ResourceFilename& filename)
 	task->m_layers = init.m_layerCount;
 	task->m_faces = faces;
 	task->m_gr = &getManager().getGrManager();
-	task->m_stagingMem = &getManager().getStagingGpuMemoryManager();
+	task->m_transferAlloc = &getManager().getTransferGpuAllocator();
 	task->m_tex = m_tex;
 	task->m_texType = init.m_type;
 

+ 3 - 2
src/anki/resource/TransferGpuAllocator.cpp

@@ -74,7 +74,7 @@ void* TransferGpuAllocatorHandle::getMappedMemory() const
 	ANKI_ASSERT(m_handle.m_memory);
 	const TransferGpuAllocator::Memory* mm = static_cast<const TransferGpuAllocator::Memory*>(m_handle.m_memory);
 	ANKI_ASSERT(mm->m_mappedMemory);
-	return mm->m_mappedMemory;
+	return static_cast<U8*>(mm->m_mappedMemory) + m_handle.m_offset;
 }
 
 TransferGpuAllocator::TransferGpuAllocator()
@@ -163,6 +163,7 @@ Error TransferGpuAllocator::allocate(PtrSize size, TransferGpuAllocatorHandle& h
 	handle.m_range = size;
 	handle.m_frame = frame - &m_frames[0];
 	m_crntFrameAllocatedSize += size;
+	++frame->m_pendingReleases;
 
 	return ErrorCode::NONE;
 }
@@ -185,7 +186,7 @@ void TransferGpuAllocator::release(TransferGpuAllocatorHandle& handle, FencePtr
 		m_condVar.notifyOne();
 	}
 
-	handle = {};
+	handle.invalidate();
 }
 
 } // end namespace anki

+ 14 - 2
src/anki/resource/TransferGpuAllocator.h

@@ -21,7 +21,9 @@ class TransferGpuAllocatorHandle
 	friend class TransferGpuAllocator;
 
 public:
-	TransferGpuAllocatorHandle() = default;
+	TransferGpuAllocatorHandle()
+	{
+	}
 
 	TransferGpuAllocatorHandle(const TransferGpuAllocatorHandle&) = delete;
 
@@ -38,7 +40,9 @@ public:
 	TransferGpuAllocatorHandle& operator=(TransferGpuAllocatorHandle&& b)
 	{
 		m_handle = b.m_handle;
-		b.m_handle = {};
+		m_range = b.m_range;
+		m_frame = b.m_frame;
+		b.invalidate();
 		return *this;
 	}
 
@@ -68,6 +72,14 @@ private:
 	{
 		return m_range != 0 && m_frame < MAX_U8;
 	}
+
+	void invalidate()
+	{
+		m_handle.m_memory = nullptr;
+		m_handle.m_offset = 0;
+		m_range = 0;
+		m_frame = MAX_U8;
+	}
 };
 
 /// GPU memory allocator for GPU buffers used in transfer operations.

+ 1 - 1
src/anki/scene/ParticleEmitter.cpp

@@ -364,7 +364,7 @@ Error ParticleEmitter::frameUpdate(F32 prevUpdateTime, F32 crntTime)
 	Vec4 aabbmax(MIN_F32, MIN_F32, MIN_F32, 0.0);
 	m_aliveParticlesCount = 0;
 
-	F32* verts = static_cast<F32*>(getResourceManager().getStagingGpuMemoryManager().allocateFrame(
+	F32* verts = static_cast<F32*>(getSceneGraph().getStagingGpuMemoryManager().allocateFrame(
 		m_vertBuffSize, StagingGpuMemoryType::VERTEX, m_vertBuffToken));
 
 	const F32* verts_base = verts;

+ 2 - 0
src/anki/scene/SceneGraph.cpp

@@ -68,6 +68,7 @@ Error SceneGraph::init(AllocAlignedCallback allocCb,
 	ThreadPool* threadpool,
 	ThreadHive* threadHive,
 	ResourceManager* resources,
+	StagingGpuMemoryManager* stagingMem,
 	Input* input,
 	const Timestamp* globalTimestamp,
 	const ConfigSet& config)
@@ -76,6 +77,7 @@ Error SceneGraph::init(AllocAlignedCallback allocCb,
 	m_threadpool = threadpool;
 	m_threadHive = threadHive;
 	m_resources = resources;
+	m_stagingAlloc = stagingMem;
 	m_objectsMarkedForDeletionCount.store(0);
 	m_gr = &m_resources->getGrManager();
 	m_physics = &m_resources->getPhysicsWorld();

+ 8 - 0
src/anki/scene/SceneGraph.h

@@ -48,6 +48,7 @@ public:
 		ThreadPool* threadpool,
 		ThreadHive* thraedHive,
 		ResourceManager* resources,
+		StagingGpuMemoryManager* stagingAlloc,
 		Input* input,
 		const Timestamp* globalTimestamp,
 		const ConfigSet& config);
@@ -112,6 +113,12 @@ public:
 		return *m_threadHive;
 	}
 
+	StagingGpuMemoryManager& getStagingGpuMemoryManager()
+	{
+		ANKI_ASSERT(m_stagingAlloc);
+		return *m_stagingAlloc;
+	}
+
 	ANKI_USE_RESULT Error update(F32 prevUpdateTime, F32 crntTime, MainRenderer& renderer);
 
 	SceneNode& findSceneNode(const CString& name);
@@ -212,6 +219,7 @@ private:
 	GrManager* m_gr = nullptr;
 	PhysicsWorld* m_physics = nullptr;
 	Input* m_input = nullptr;
+	StagingGpuMemoryManager* m_stagingAlloc = nullptr;
 
 	SceneAllocator<U8> m_alloc;
 	SceneFrameAllocator<U8> m_frameAlloc;