Просмотр исходного кода

Gr: Some work on the render graph

Panagiotis Christopoulos Charitos 8 лет назад
Родитель
Сommit
1cc4b0afe3
4 измененных файлов с 73 добавлено и 47 удалено
  1. 13 0
      src/anki/gr/Common.h
  2. 35 20
      src/anki/gr/RenderGraph.cpp
  3. 16 15
      src/anki/gr/RenderGraph.h
  4. 9 12
      tests/gr/Gr.cpp

+ 13 - 0
src/anki/gr/Common.h

@@ -155,6 +155,19 @@ public:
 		return m_level == b.m_level && m_depth == b.m_depth && m_face == b.m_face && m_layer == b.m_layer;
 	}
 
+	U64 computeHash() const
+	{
+		ANKI_ASSERT(m_level < MAX_U16 && m_depth < MAX_U16 && m_face < MAX_U16 && m_layer < MAX_U16);
+		U64 hash = m_level;
+		hash <<= 16;
+		hash |= m_depth;
+		hash <<= 16;
+		hash |= m_face + 1; // Add one so we won't end up with zero hash
+		hash <<= 16;
+		hash |= m_layer;
+		return hash;
+	}
+
 	U32 m_level = 0;
 	U32 m_depth = 0;
 	U32 m_face = 0;

+ 35 - 20
src/anki/gr/RenderGraph.cpp

@@ -18,7 +18,12 @@ namespace anki
 class RenderGraph::RT
 {
 public:
-	TextureUsageBit m_usage;
+	HashMap<TextureSurfaceInfo, TextureUsageBit> m_surfUsageMap;
+
+	RT()
+		: m_surfUsageMap(8, 4)
+	{
+	}
 };
 
 /// Pipeline barrier of texture or buffer.
@@ -273,10 +278,6 @@ void RenderGraph::compileNewGraph(const RenderGraphDescription& descr)
 
 	// Init the render targets
 	ctx.m_rts.create(descr.m_renderTargets.getSize());
-	for(U i = 0; i < descr.m_renderTargets.getSize(); ++i)
-	{
-		ctx.m_rts[i].m_usage = descr.m_renderTargets[i].m_usage;
-	}
 
 	// Find the dependencies between passes
 	for(U i = 0; i < passCount; ++i)
@@ -337,6 +338,8 @@ void RenderGraph::compileNewGraph(const RenderGraphDescription& descr)
 
 void RenderGraph::setBatchBarriers(BakeContext& ctx) const
 {
+	const StackAllocator<U8>& alloc = ctx.m_alloc;
+
 	// For all batches
 	for(Batch& batch : ctx.m_batches)
 	{
@@ -350,15 +353,27 @@ void RenderGraph::setBatchBarriers(BakeContext& ctx) const
 			{
 				if(consumer.m_isTexture)
 				{
+					const U32 rtIdx = consumer.m_texture.m_handle;
 					const TextureUsageBit consumerUsage = consumer.m_texture.m_usage;
-					TextureUsageBit& crntUsage = ctx.m_rts[consumer.m_texture.m_handle].m_usage;
+
+					// Get current suage
+					TextureUsageBit crntUsage;
+					auto it = ctx.m_rts[rtIdx].m_surfUsageMap.find(consumer.m_texture.m_surface);
+					if(it != ctx.m_rts[rtIdx].m_surfUsageMap.getEnd())
+					{
+						crntUsage = *it;
+						*it = consumerUsage;
+					}
+					else
+					{
+						crntUsage = ctx.m_descr->m_renderTargets[rtIdx].m_usage;
+						ctx.m_rts[rtIdx].m_surfUsageMap.emplace(alloc, consumer.m_texture.m_surface, consumerUsage);
+					}
 
 					if(crntUsage != consumerUsage)
 					{
 						batch.m_barriersBefore.emplaceBack(
 							consumer.m_texture.m_handle, crntUsage, consumerUsage, consumer.m_texture.m_surface);
-
-						crntUsage = consumerUsage;
 					}
 				}
 				else
@@ -367,27 +382,26 @@ void RenderGraph::setBatchBarriers(BakeContext& ctx) const
 				}
 			}
 
-			// For all producers
+// For all producers, just check some stuff
+#if ANKI_EXTRA_CHECKS
 			for(const RenderPassDependency& producer : pass.m_producers)
 			{
 				if(producer.m_isTexture)
 				{
-					const TextureUsageBit producerUsage = producer.m_texture.m_usage;
-					TextureUsageBit& crntUsage = ctx.m_rts[producer.m_texture.m_handle].m_usage;
+					const U32 rtIdx = producer.m_texture.m_handle;
 
-					if(crntUsage != producerUsage)
-					{
-						batch.m_barriersAfter.emplaceBack(
-							producer.m_texture.m_handle, producerUsage, crntUsage, producer.m_texture.m_surface);
+					auto it = ctx.m_rts[rtIdx].m_surfUsageMap.find(producer.m_texture.m_surface);
+					ANKI_ASSERT(it != ctx.m_rts[rtIdx].m_surfUsageMap.getEnd()
+						&& "There should have been a consumer that added a map entry");
 
-						crntUsage = producerUsage;
-					}
+					ANKI_ASSERT(*it == producer.m_texture.m_usage && "The consumer should have set that");
 				}
 				else
 				{
 					// TODO
 				}
 			}
+#endif
 		}
 	}
 }
@@ -525,9 +539,10 @@ Error RenderGraph::dumpDependencyDotFile(const BakeContext& ctx, CString path) c
 
 	File file;
 	ANKI_CHECK(file.open(StringAuto(alloc).sprintf("%s/rgraph.dot", &path[0]).toCString(), FileOpenFlag::WRITE));
-	StringAuto final(alloc);
-	slist.join("\n", final);
-	ANKI_CHECK(file.writeText("%s", &final[0]));
+	for(const String& s : slist)
+	{
+		ANKI_CHECK(file.writeText("%s", &s[0]));
+	}
 
 	return Error::NONE;
 }

+ 16 - 15
src/anki/gr/RenderGraph.h

@@ -234,6 +234,20 @@ private:
 	TexturePtr m_importedTex;
 	TextureUsageBit m_usage;
 	Array<char, MAX_GR_OBJECT_NAME_LENGTH + 1> m_name;
+
+	void setName(CString name)
+	{
+		const U len = name.getLength();
+		if(len)
+		{
+			ANKI_ASSERT(len <= MAX_GR_OBJECT_NAME_LENGTH);
+			strcpy(&m_name[0], &name[0]);
+		}
+		else
+		{
+			strcpy(&m_name[0], "unnamed");
+		}
+	}
 };
 
 /// XXX
@@ -274,14 +288,7 @@ public:
 		RenderTarget rt;
 		rt.m_importedTex = tex;
 		rt.m_usage = usage;
-		const U len = name.getLength();
-		if(len)
-		{
-			ANKI_ASSERT(len <= MAX_GR_OBJECT_NAME_LENGTH);
-			memcpy(&rt.m_name[0], &name[0], len);
-		}
-		rt.m_name[len] = '\0';
-
+		rt.setName(name);
 		m_renderTargets.emplaceBack(m_alloc, rt);
 		return m_renderTargets.getSize() - 1;
 	}
@@ -292,13 +299,7 @@ public:
 		RenderTarget rt;
 		rt.m_initInfo = initInf;
 		rt.m_usage = TextureUsageBit::NONE;
-		const U len = name.getLength();
-		if(len)
-		{
-			ANKI_ASSERT(len <= MAX_GR_OBJECT_NAME_LENGTH);
-			memcpy(&rt.m_name[0], &name[0], len);
-		}
-		rt.m_name[len] = '\0';
+		rt.setName(name);
 		m_renderTargets.emplaceBack(m_alloc, rt);
 		return m_renderTargets.getSize() - 1;
 	}

+ 9 - 12
tests/gr/Gr.cpp

@@ -1535,7 +1535,7 @@ ANKI_TEST(Gr, RenderGraph)
 {
 	COMMON_BEGIN()
 
-	StackAllocator<U8> alloc(allocAligned, nullptr, 1_MB);
+	StackAllocator<U8> alloc(allocAligned, nullptr, 2_MB);
 	RenderGraphDescription descr(alloc);
 	RenderGraphPtr rgraph = gr->newInstance<RenderGraph>();
 
@@ -1559,7 +1559,7 @@ ANKI_TEST(Gr, RenderGraph)
 	{
 		GraphicsRenderPassInfo& pass = descr.newGraphicsRenderPass("ESM");
 		pass.newConsumer({smScratchRt, TextureUsageBit::SAMPLED_FRAGMENT});
-		pass.newConsumer({smExpRt, TextureUsageBit::SAMPLED_FRAGMENT});
+		pass.newConsumer({smExpRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
 		pass.newProducer({smExpRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
 	}
 
@@ -1569,9 +1569,9 @@ ANKI_TEST(Gr, RenderGraph)
 	RenderTargetHandle giGbuffDepthRt = descr.newRenderTarget("GI gbuff depth", texInf);
 	{
 		GraphicsRenderPassInfo& pass = descr.newGraphicsRenderPass("GI gbuff");
-		pass.newConsumer({giGbuffNormRt, TextureUsageBit::NONE});
-		pass.newConsumer({giGbuffDepthRt, TextureUsageBit::NONE});
-		pass.newConsumer({giGbuffDiffRt, TextureUsageBit::NONE});
+		pass.newConsumer({giGbuffNormRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
+		pass.newConsumer({giGbuffDepthRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
+		pass.newConsumer({giGbuffDiffRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
 
 		pass.newProducer({giGbuffNormRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
 		pass.newProducer({giGbuffDepthRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
@@ -1584,7 +1584,8 @@ ANKI_TEST(Gr, RenderGraph)
 	{
 		GraphicsRenderPassInfo& pass =
 			descr.newGraphicsRenderPass(StringAuto(alloc).sprintf("GI li%u", faceIdx).toCString());
-		pass.newConsumer({giGiLightRt, TextureUsageBit::NONE, TextureSurfaceInfo(0, 0, faceIdx, 0)});
+		pass.newConsumer(
+			{giGiLightRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE, TextureSurfaceInfo(0, 0, faceIdx, 0)});
 		pass.newConsumer({giGbuffNormRt, TextureUsageBit::SAMPLED_FRAGMENT});
 		pass.newConsumer({giGbuffDepthRt, TextureUsageBit::SAMPLED_FRAGMENT});
 		pass.newConsumer({giGbuffDiffRt, TextureUsageBit::SAMPLED_FRAGMENT});
@@ -1600,14 +1601,10 @@ ANKI_TEST(Gr, RenderGraph)
 			GraphicsRenderPassInfo& pass =
 				descr.newGraphicsRenderPass(StringAuto(alloc).sprintf("GI mip%u", faceIdx).toCString());
 
-			pass.newConsumer(
-				{giGiLightRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE, TextureSurfaceInfo(0, 0, faceIdx, 0)});
-			pass.newConsumer({giGiLightRt, TextureUsageBit::GENERATE_MIPMAPS, TextureSurfaceInfo(0, 0, faceIdx, 0)});
-
-			for(U mip = 1; mip < GI_MIP_COUNT; ++mip)
+			for(U mip = 0; mip < GI_MIP_COUNT; ++mip)
 			{
 				TextureSurfaceInfo surf(mip, 0, faceIdx, 0);
-				pass.newConsumer({giGiLightRt, TextureUsageBit::NONE, surf});
+				pass.newConsumer({giGiLightRt, TextureUsageBit::GENERATE_MIPMAPS, surf});
 				pass.newProducer({giGiLightRt, TextureUsageBit::GENERATE_MIPMAPS, surf});
 			}
 		}