Browse Source

Simplify the RenderGraph dependencies

Panagiotis Christopoulos Charitos 7 years ago
parent
commit
85394611b0

+ 39 - 41
src/anki/gr/Enums.h

@@ -380,10 +380,8 @@ inline Bool textureTypeIsCube(const TextureType t)
 /// Texture usage hints. They are very important.
 enum class TextureUsageBit : U16
 {
-	NONE,
+	NONE = 0,
 
-	/// @name Sampled
-	/// @{
 	SAMPLED_VERTEX = 1 << 0,
 	SAMPLED_TESSELLATION_CONTROL = 1 << 1,
 	SAMPLED_TESSELLATION_EVALUATION = 1 << 2,
@@ -393,43 +391,30 @@ enum class TextureUsageBit : U16
 	SAMPLED_ALL_GRAPHICS = SAMPLED_VERTEX | SAMPLED_TESSELLATION_CONTROL | SAMPLED_TESSELLATION_EVALUATION
 						   | SAMPLED_GEOMETRY | SAMPLED_FRAGMENT,
 	SAMPLED_ALL = SAMPLED_ALL_GRAPHICS | SAMPLED_COMPUTE,
-	/// @}
 
-	/// @name Image_load_store
-	/// @{
 	IMAGE_COMPUTE_READ = 1 << 6,
 	IMAGE_COMPUTE_WRITE = 1 << 7,
 	IMAGE_COMPUTE_READ_WRITE = IMAGE_COMPUTE_READ | IMAGE_COMPUTE_WRITE,
 	IMAGE_ALL = IMAGE_COMPUTE_READ_WRITE,
-	/// @}
 
-	/// @name Attachment
-	/// @{
 	FRAMEBUFFER_ATTACHMENT_READ = 1 << 8,
 	FRAMEBUFFER_ATTACHMENT_WRITE = 1 << 9,
 	FRAMEBUFFER_ATTACHMENT_READ_WRITE = FRAMEBUFFER_ATTACHMENT_READ | FRAMEBUFFER_ATTACHMENT_WRITE,
-	/// @}
 
-	/// @name Transfer
-	/// @{
 	TRANSFER_DESTINATION = 1 << 10,
-	TRANSFER_ANY = TRANSFER_DESTINATION,
-	/// @}
+	TRANSFER_ALL = TRANSFER_DESTINATION,
 
-	/// @name Misc
-	/// @{
+	// Misc
 	GENERATE_MIPMAPS = 1 << 11,
-	CLEAR = 1 << 12, ///< Will be used in CommandBuffer::clearImage.
+	CLEAR = 1 << 12, ///< Will be used in CommandBuffer::clearTextureView.
 	PRESENT = 1 << 13,
-	/// @}
-
-	/// @name Groups
-	/// @{
-	ANY_COMPUTE = SAMPLED_COMPUTE | IMAGE_COMPUTE_READ_WRITE,
-	ANY_GRAPHICS = SAMPLED_ALL_GRAPHICS | FRAMEBUFFER_ATTACHMENT_READ_WRITE,
-	ANY_READ = SAMPLED_ALL | IMAGE_COMPUTE_READ | FRAMEBUFFER_ATTACHMENT_READ,
-	ANY_WRITE = IMAGE_COMPUTE_WRITE | FRAMEBUFFER_ATTACHMENT_WRITE | TRANSFER_DESTINATION | GENERATE_MIPMAPS | CLEAR,
-	/// @}
+
+	// Derived
+	ALL_COMPUTE = SAMPLED_COMPUTE | IMAGE_COMPUTE_READ_WRITE,
+	ALL_GRAPHICS = SAMPLED_ALL_GRAPHICS | FRAMEBUFFER_ATTACHMENT_READ_WRITE,
+	ALL_READ = SAMPLED_ALL | IMAGE_COMPUTE_READ | FRAMEBUFFER_ATTACHMENT_READ | PRESENT | GENERATE_MIPMAPS,
+	ALL_WRITE =
+		IMAGE_COMPUTE_WRITE | FRAMEBUFFER_ATTACHMENT_WRITE | TRANSFER_DESTINATION | GENERATE_MIPMAPS | CLEAR | PRESENT,
 };
 ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(TextureUsageBit, inline)
 
@@ -568,20 +553,25 @@ enum class BufferUsageBit : U64
 	STORAGE_COMPUTE_READ = 1 << 16,
 	STORAGE_COMPUTE_WRITE = 1 << 17,
 	STORAGE_COMPUTE_READ_WRITE = STORAGE_COMPUTE_READ | STORAGE_COMPUTE_WRITE,
-	STORAGE_ALL_GRAPHICS = STORAGE_VERTEX_READ | STORAGE_VERTEX_WRITE | STORAGE_TESSELLATION_EVALUATION_READ
-						   | STORAGE_TESSELLATION_EVALUATION_WRITE | STORAGE_TESSELLATION_CONTROL_READ
-						   | STORAGE_TESSELLATION_CONTROL_WRITE | STORAGE_GEOMETRY_READ | STORAGE_GEOMETRY_WRITE
-						   | STORAGE_FRAGMENT_READ | STORAGE_FRAGMENT_WRITE,
+	STORAGE_ALL_GRAPHICS = STORAGE_VERTEX_READ_WRITE | STORAGE_TESSELLATION_EVALUATION_READ_WRITE
+						   | STORAGE_TESSELLATION_CONTROL_READ_WRITE | STORAGE_GEOMETRY_READ_WRITE
+						   | STORAGE_FRAGMENT_READ_WRITE,
 	STORAGE_ALL = STORAGE_ALL_GRAPHICS | STORAGE_COMPUTE_READ_WRITE,
-
-	TEXTURE_VERTEX_READ = 1 << 18,
-	TEXTURE_TESSELLATION_EVALUATION_READ = 1 << 19,
-	TEXTURE_TESSELLATION_CONTROL_READ = 1 << 20,
-	TEXTURE_GEOMETRY_READ = 1 << 21,
-	TEXTURE_FRAGMENT_READ = 1 << 22,
-	TEXTURE_COMPUTE_READ = 1 << 23,
-	TEXTURE_ALL = TEXTURE_VERTEX_READ | TEXTURE_TESSELLATION_EVALUATION_READ | TEXTURE_TESSELLATION_CONTROL_READ
-				  | TEXTURE_GEOMETRY_READ | TEXTURE_FRAGMENT_READ | TEXTURE_COMPUTE_READ,
+	STORAGE_ALL_READ = STORAGE_VERTEX_READ | STORAGE_TESSELLATION_EVALUATION_READ | STORAGE_TESSELLATION_CONTROL_READ
+					   | STORAGE_GEOMETRY_READ | STORAGE_FRAGMENT_READ | STORAGE_COMPUTE_READ,
+	STORAGE_ALL_WRITE = STORAGE_VERTEX_WRITE | STORAGE_TESSELLATION_EVALUATION_WRITE
+						| STORAGE_TESSELLATION_CONTROL_WRITE | STORAGE_GEOMETRY_WRITE | STORAGE_FRAGMENT_WRITE
+						| STORAGE_COMPUTE_WRITE,
+
+	TEXTURE_VERTEX = 1 << 18,
+	TEXTURE_TESSELLATION_EVALUATION = 1 << 19,
+	TEXTURE_TESSELLATION_CONTROL = 1 << 20,
+	TEXTURE_GEOMETRY = 1 << 21,
+	TEXTURE_FRAGMENT = 1 << 22,
+	TEXTURE_COMPUTE = 1 << 23,
+	TEXTURE_ALL_GRAPHICS = TEXTURE_VERTEX | TEXTURE_TESSELLATION_EVALUATION | TEXTURE_TESSELLATION_CONTROL
+						   | TEXTURE_GEOMETRY | TEXTURE_FRAGMENT,
+	TEXTURE_ALL = TEXTURE_ALL_GRAPHICS | TEXTURE_COMPUTE,
 
 	INDEX = 1 << 24,
 	VERTEX = 1 << 25,
@@ -591,8 +581,16 @@ enum class BufferUsageBit : U64
 	BUFFER_UPLOAD_SOURCE = 1 << 28,
 	BUFFER_UPLOAD_DESTINATION = 1 << 29, ///< Destination of buffer upload.
 	TEXTURE_UPLOAD_SOURCE = 1 << 30, ///< Source for texture upload.
-	QUERY_RESULT = 1u << 31u, ///< Source to store query results.
-	TRANSFER_ALL = FILL | BUFFER_UPLOAD_SOURCE | BUFFER_UPLOAD_DESTINATION | TEXTURE_UPLOAD_SOURCE | QUERY_RESULT,
+	QUERY_RESULT = 1u << 31u, ///< Destination to store query results.
+	TRANSFER_ALL_READ = BUFFER_UPLOAD_SOURCE | TEXTURE_UPLOAD_SOURCE,
+	TRANSFER_ALL_WRITE = FILL | BUFFER_UPLOAD_DESTINATION | QUERY_RESULT,
+	TRANSFER_ALL = TRANSFER_ALL_READ | TRANSFER_ALL_WRITE,
+
+	// Derived
+	ALL_GRAPHICS = UNIFORM_ALL_GRAPHICS | STORAGE_ALL_GRAPHICS | TEXTURE_ALL_GRAPHICS | INDEX | VERTEX | INDIRECT,
+	ALL_COMPUTE = UNIFORM_COMPUTE | STORAGE_COMPUTE_READ_WRITE | TEXTURE_COMPUTE | INDIRECT,
+	ALL_READ = UNIFORM_ALL | STORAGE_ALL_READ | TEXTURE_ALL | INDEX | VERTEX | INDIRECT | TRANSFER_ALL_READ,
+	ALL_WRITE = STORAGE_ALL_WRITE | TRANSFER_ALL_WRITE,
 };
 ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(BufferUsageBit, inline)
 

+ 77 - 69
src/anki/gr/RenderGraph.cpp

@@ -429,30 +429,14 @@ Bool RenderGraph::overlappingTextureSubresource(const TextureSubresourceInfo& su
 	return overlappingFaces && overlappingLayers && overlappingMips;
 }
 
-template<Bool isTexture>
-Bool RenderGraph::overlappingDependency(const RenderPassDependency& a, const RenderPassDependency& b) const
-{
-	ANKI_ASSERT(a.m_isTexture == isTexture && b.m_isTexture == isTexture);
-
-	if(isTexture)
-	{
-		return a.m_texture.m_handle == b.m_texture.m_handle
-			   && overlappingTextureSubresource(a.m_texture.m_subresource, b.m_texture.m_subresource);
-	}
-	else
-	{
-		return a.m_buffer.m_handle == b.m_buffer.m_handle;
-	}
-}
-
-Bool RenderGraph::passADependsOnB(const RenderPassDescriptionBase& a, const RenderPassDescriptionBase& b) const
+Bool RenderGraph::passADependsOnB(const RenderPassDescriptionBase& a, const RenderPassDescriptionBase& b)
 {
 	// Render targets
 	{
 		// Compute the 3 types of dependencies
-		BitSet<MAX_RENDER_GRAPH_RENDER_TARGETS, U64> aReadBWrite = a.m_consumerRtMask & b.m_producerRtMask;
-		BitSet<MAX_RENDER_GRAPH_RENDER_TARGETS, U64> aWriteBRead = a.m_producerRtMask & b.m_consumerRtMask;
-		BitSet<MAX_RENDER_GRAPH_RENDER_TARGETS, U64> aWriteBWrite = a.m_producerRtMask & b.m_producerRtMask;
+		BitSet<MAX_RENDER_GRAPH_RENDER_TARGETS, U64> aReadBWrite = a.m_readRtMask & b.m_writeRtMask;
+		BitSet<MAX_RENDER_GRAPH_RENDER_TARGETS, U64> aWriteBRead = a.m_writeRtMask & b.m_readRtMask;
+		BitSet<MAX_RENDER_GRAPH_RENDER_TARGETS, U64> aWriteBWrite = a.m_writeRtMask & b.m_writeRtMask;
 
 		BitSet<MAX_RENDER_GRAPH_RENDER_TARGETS, U64> fullDep = aReadBWrite | aWriteBRead | aWriteBWrite;
 
@@ -460,16 +444,29 @@ Bool RenderGraph::passADependsOnB(const RenderPassDescriptionBase& a, const Rend
 		{
 			// There might be an overlap
 
-			for(const RenderPassDependency& consumer : a.m_rtConsumers)
+			for(const RenderPassDependency& aDep : a.m_rtDeps)
 			{
-				if(fullDep.get(consumer.m_texture.m_handle.m_idx))
+				if(!fullDep.get(aDep.m_texture.m_handle.m_idx))
+				{
+					continue;
+				}
+
+				for(const RenderPassDependency& bDep : b.m_rtDeps)
 				{
-					for(const RenderPassDependency& producer : b.m_rtProducers)
+					if(aDep.m_texture.m_handle != bDep.m_texture.m_handle)
 					{
-						if(overlappingDependency<true>(producer, consumer))
-						{
-							return true;
-						}
+						continue;
+					}
+
+					if(!((aDep.m_texture.m_usage | bDep.m_texture.m_usage) & TextureUsageBit::ALL_WRITE))
+					{
+						// Don't care about read to read deps
+						continue;
+					}
+
+					if(overlappingTextureSubresource(aDep.m_texture.m_subresource, bDep.m_texture.m_subresource))
+					{
+						return true;
 					}
 				}
 			}
@@ -479,9 +476,9 @@ Bool RenderGraph::passADependsOnB(const RenderPassDescriptionBase& a, const Rend
 	// Buffers
 	if(a.m_hasBufferDeps)
 	{
-		BitSet<MAX_RENDER_GRAPH_BUFFERS, U64> aReadBWrite = a.m_consumerBufferMask & b.m_producerBufferMask;
-		BitSet<MAX_RENDER_GRAPH_BUFFERS, U64> aWriteBRead = a.m_producerBufferMask & b.m_consumerBufferMask;
-		BitSet<MAX_RENDER_GRAPH_BUFFERS, U64> aWriteBWrite = a.m_producerBufferMask & b.m_producerBufferMask;
+		BitSet<MAX_RENDER_GRAPH_BUFFERS, U64> aReadBWrite = a.m_readBuffMask & b.m_writeBuffMask;
+		BitSet<MAX_RENDER_GRAPH_BUFFERS, U64> aWriteBRead = a.m_writeBuffMask & b.m_readBuffMask;
+		BitSet<MAX_RENDER_GRAPH_BUFFERS, U64> aWriteBWrite = a.m_writeBuffMask & b.m_writeBuffMask;
 
 		BitSet<MAX_RENDER_GRAPH_BUFFERS, U64> fullDep = aReadBWrite | aWriteBRead | aWriteBWrite;
 
@@ -489,17 +486,28 @@ Bool RenderGraph::passADependsOnB(const RenderPassDescriptionBase& a, const Rend
 		{
 			// There might be an overlap
 
-			for(const RenderPassDependency& consumer : a.m_buffConsumers)
+			for(const RenderPassDependency& aDep : a.m_buffDeps)
 			{
-				if(fullDep.get(consumer.m_buffer.m_handle.m_idx))
+				if(!fullDep.get(aDep.m_buffer.m_handle.m_idx))
+				{
+					continue;
+				}
+
+				for(const RenderPassDependency& bDep : b.m_buffDeps)
 				{
-					for(const RenderPassDependency& producer : b.m_buffProducers)
+					if(aDep.m_buffer.m_handle != bDep.m_buffer.m_handle)
 					{
-						if(overlappingDependency<false>(producer, consumer))
-						{
-							return true;
-						}
+						continue;
 					}
+
+					if(!((aDep.m_buffer.m_usage | bDep.m_buffer.m_usage) & BufferUsageBit::ALL_WRITE))
+					{
+						// Don't care about read to read deps
+						continue;
+					}
+
+					// TODO: Take into account the ranges
+					return true;
 				}
 			}
 		}
@@ -609,16 +617,16 @@ void RenderGraph::initRenderPassesAndSetDeps(const RenderGraphDescription& descr
 		outPass.m_userData = inPass.m_userData;
 
 		// Create consumer info
-		for(U consumerIdx = 0; consumerIdx < inPass.m_rtConsumers.getSize(); ++consumerIdx)
+		for(U depIdx = 0; depIdx < inPass.m_rtDeps.getSize(); ++depIdx)
 		{
-			const RenderPassDependency& inConsumer = inPass.m_rtConsumers[consumerIdx];
-			ANKI_ASSERT(inConsumer.m_isTexture);
+			const RenderPassDependency& inDep = inPass.m_rtDeps[depIdx];
+			ANKI_ASSERT(inDep.m_isTexture);
 
 			outPass.m_consumedTextures.emplaceBack(alloc);
 			Pass::ConsumedTextureInfo& inf = outPass.m_consumedTextures.getBack();
 
-			ANKI_ASSERT(sizeof(inf) == sizeof(inConsumer.m_texture));
-			memcpy(&inf, &inConsumer.m_texture, sizeof(inf));
+			ANKI_ASSERT(sizeof(inf) == sizeof(inDep.m_texture));
+			memcpy(&inf, &inDep.m_texture, sizeof(inf));
 		}
 
 		// Create command buffers and framebuffer
@@ -766,34 +774,34 @@ void RenderGraph::iterateSurfsOrVolumes(const TexturePtr& tex, const TextureSubr
 	}
 }
 
-void RenderGraph::setTextureBarrier(Batch& batch, const RenderPassDependency& consumer)
+void RenderGraph::setTextureBarrier(Batch& batch, const RenderPassDependency& dep)
 {
-	ANKI_ASSERT(consumer.m_isTexture);
+	ANKI_ASSERT(dep.m_isTexture);
 
 	BakeContext& ctx = *m_ctx;
 	const U batchIdx = &batch - &ctx.m_batches[0];
-	const U rtIdx = consumer.m_texture.m_handle.m_idx;
-	const TextureUsageBit consumerUsage = consumer.m_texture.m_usage;
+	const U rtIdx = dep.m_texture.m_handle.m_idx;
+	const TextureUsageBit depUsage = dep.m_texture.m_usage;
 	RT& rt = ctx.m_rts[rtIdx];
 
 	iterateSurfsOrVolumes(
-		rt.m_texture, consumer.m_texture.m_subresource, [&](U surfOrVolIdx, const TextureSurfaceInfo& surf) {
+		rt.m_texture, dep.m_texture.m_subresource, [&](U surfOrVolIdx, const TextureSurfaceInfo& surf) {
 			TextureUsageBit& crntUsage = rt.m_surfOrVolUsages[surfOrVolIdx];
-			if(crntUsage != consumerUsage)
+			if(crntUsage != depUsage)
 			{
 				// Check if we can merge barriers
 				if(rt.m_lastBatchThatTransitionedIt[surfOrVolIdx] == batchIdx)
 				{
 					// Will merge the barriers
 
-					crntUsage |= consumerUsage;
+					crntUsage |= depUsage;
 
 					Bool found = false;
 					for(Barrier& b : batch.m_barriersBefore)
 					{
 						if(b.m_isTexture && b.m_texture.m_idx == rtIdx && b.m_texture.m_surface == surf)
 						{
-							b.m_texture.m_usageAfter |= consumerUsage;
+							b.m_texture.m_usageAfter |= depUsage;
 							found = true;
 							break;
 						}
@@ -806,9 +814,9 @@ void RenderGraph::setTextureBarrier(Batch& batch, const RenderPassDependency& co
 				{
 					// Create a new barrier for this surface
 
-					batch.m_barriersBefore.emplaceBack(ctx.m_alloc, rtIdx, crntUsage, consumerUsage, surf);
+					batch.m_barriersBefore.emplaceBack(ctx.m_alloc, rtIdx, crntUsage, depUsage, surf);
 
-					crntUsage = consumerUsage;
+					crntUsage = depUsage;
 					rt.m_lastBatchThatTransitionedIt[surfOrVolIdx] = batchIdx;
 				}
 			}
@@ -832,18 +840,18 @@ void RenderGraph::setBatchBarriers(const RenderGraphDescription& descr)
 		{
 			const RenderPassDescriptionBase& pass = *descr.m_passes[passIdx];
 
-			// For all consumers
-			for(const RenderPassDependency& consumer : pass.m_rtConsumers)
+			// For all deps
+			for(const RenderPassDependency& dep : pass.m_rtDeps)
 			{
-				setTextureBarrier(batch, consumer);
+				setTextureBarrier(batch, dep);
 			}
 
-			for(const RenderPassDependency& consumer : pass.m_buffConsumers)
+			for(const RenderPassDependency& dep : pass.m_buffDeps)
 			{
-				const U32 buffIdx = consumer.m_buffer.m_handle.m_idx;
-				const BufferUsageBit consumerUsage = consumer.m_buffer.m_usage;
+				const U32 buffIdx = dep.m_buffer.m_handle.m_idx;
+				const BufferUsageBit depUsage = dep.m_buffer.m_usage;
 
-				if(consumerUsage != ctx.m_buffers[buffIdx].m_usage)
+				if(depUsage != ctx.m_buffers[buffIdx].m_usage)
 				{
 					const Bool buffHasBarrier = buffHasBarrierMask.get(buffIdx);
 
@@ -851,10 +859,9 @@ void RenderGraph::setBatchBarriers(const RenderGraphDescription& descr)
 					{
 						// Buff hasn't had a barrier in this batch, add a new barrier
 
-						batch.m_barriersBefore.emplaceBack(
-							alloc, buffIdx, ctx.m_buffers[buffIdx].m_usage, consumerUsage);
+						batch.m_barriersBefore.emplaceBack(alloc, buffIdx, ctx.m_buffers[buffIdx].m_usage, depUsage);
 
-						ctx.m_buffers[buffIdx].m_usage = consumerUsage;
+						ctx.m_buffers[buffIdx].m_usage = depUsage;
 						buffHasBarrierMask.set(buffIdx);
 					}
 					else
@@ -873,7 +880,7 @@ void RenderGraph::setBatchBarriers(const RenderGraphDescription& descr)
 
 						ANKI_ASSERT(barrierToMergeTo);
 						ANKI_ASSERT(!!barrierToMergeTo->m_buffer.m_usageAfter);
-						barrierToMergeTo->m_buffer.m_usageAfter |= consumerUsage;
+						barrierToMergeTo->m_buffer.m_usageAfter |= depUsage;
 						ctx.m_buffers[buffIdx].m_usage = barrierToMergeTo->m_buffer.m_usageAfter;
 					}
 				}
@@ -1105,6 +1112,7 @@ StringAuto RenderGraph::textureUsageToStr(StackAllocator<U8>& alloc, TextureUsag
 	ANKI_TEX_USAGE(TRANSFER_DESTINATION);
 	ANKI_TEX_USAGE(GENERATE_MIPMAPS);
 	ANKI_TEX_USAGE(CLEAR);
+	ANKI_TEX_USAGE(PRESENT);
 
 	if(!usage)
 	{
@@ -1147,12 +1155,12 @@ StringAuto RenderGraph::bufferUsageToStr(StackAllocator<U8>& alloc, BufferUsageB
 	ANKI_BUFF_USAGE(STORAGE_FRAGMENT_WRITE);
 	ANKI_BUFF_USAGE(STORAGE_COMPUTE_READ);
 	ANKI_BUFF_USAGE(STORAGE_COMPUTE_WRITE);
-	ANKI_BUFF_USAGE(TEXTURE_VERTEX_READ);
-	ANKI_BUFF_USAGE(TEXTURE_TESSELLATION_EVALUATION_READ);
-	ANKI_BUFF_USAGE(TEXTURE_TESSELLATION_CONTROL_READ);
-	ANKI_BUFF_USAGE(TEXTURE_GEOMETRY_READ);
-	ANKI_BUFF_USAGE(TEXTURE_FRAGMENT_READ);
-	ANKI_BUFF_USAGE(TEXTURE_COMPUTE_READ);
+	ANKI_BUFF_USAGE(TEXTURE_VERTEX);
+	ANKI_BUFF_USAGE(TEXTURE_TESSELLATION_EVALUATION);
+	ANKI_BUFF_USAGE(TEXTURE_TESSELLATION_CONTROL);
+	ANKI_BUFF_USAGE(TEXTURE_GEOMETRY);
+	ANKI_BUFF_USAGE(TEXTURE_FRAGMENT);
+	ANKI_BUFF_USAGE(TEXTURE_COMPUTE);
 	ANKI_BUFF_USAGE(INDEX);
 	ANKI_BUFF_USAGE(VERTEX);
 	ANKI_BUFF_USAGE(INDIRECT);

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

@@ -81,6 +81,11 @@ public:
 		return m_idx == b.m_idx;
 	}
 
+	bool operator!=(const RenderPassBufferHandle& b) const
+	{
+		return m_idx != b.m_idx;
+	}
+
 private:
 	U32 m_idx = MAX_U32;
 
@@ -265,10 +270,8 @@ public:
 	virtual ~RenderPassDescriptionBase()
 	{
 		m_name.destroy(m_alloc); // To avoid the assertion
-		m_rtConsumers.destroy(m_alloc);
-		m_rtProducers.destroy(m_alloc);
-		m_buffConsumers.destroy(m_alloc);
-		m_buffProducers.destroy(m_alloc);
+		m_rtDeps.destroy(m_alloc);
+		m_buffDeps.destroy(m_alloc);
 	}
 
 	void setWork(RenderPassWorkCallback callback, void* userData, U32 secondLeveCmdbCount)
@@ -280,17 +283,8 @@ public:
 		m_secondLevelCmdbsCount = secondLeveCmdbCount;
 	}
 
-	/// Add new consumer dependency.
-	void newConsumer(const RenderPassDependency& dep);
-
-	/// Add new producer dependency.
-	void newProducer(const RenderPassDependency& dep);
-
-	void newConsumerAndProducer(const RenderPassDependency& dep)
-	{
-		newConsumer(dep);
-		newProducer(dep);
-	}
+	/// Add a new consumer or producer dependency.
+	void newDependency(const RenderPassDependency& dep);
 
 protected:
 	enum class Type : U8
@@ -308,15 +302,13 @@ protected:
 	void* m_userData = nullptr;
 	U32 m_secondLevelCmdbsCount = 0;
 
-	DynamicArray<RenderPassDependency> m_rtConsumers;
-	DynamicArray<RenderPassDependency> m_rtProducers;
-	DynamicArray<RenderPassDependency> m_buffConsumers;
-	DynamicArray<RenderPassDependency> m_buffProducers;
+	DynamicArray<RenderPassDependency> m_rtDeps;
+	DynamicArray<RenderPassDependency> m_buffDeps;
 
-	BitSet<MAX_RENDER_GRAPH_RENDER_TARGETS, U64> m_consumerRtMask = {false};
-	BitSet<MAX_RENDER_GRAPH_RENDER_TARGETS, U64> m_producerRtMask = {false};
-	BitSet<MAX_RENDER_GRAPH_BUFFERS, U64> m_consumerBufferMask = {false};
-	BitSet<MAX_RENDER_GRAPH_BUFFERS, U64> m_producerBufferMask = {false};
+	BitSet<MAX_RENDER_GRAPH_RENDER_TARGETS, U64> m_readRtMask = {false};
+	BitSet<MAX_RENDER_GRAPH_RENDER_TARGETS, U64> m_writeRtMask = {false};
+	BitSet<MAX_RENDER_GRAPH_BUFFERS, U64> m_readBuffMask = {false};
+	BitSet<MAX_RENDER_GRAPH_BUFFERS, U64> m_writeBuffMask = {false};
 	Bool8 m_hasBufferDeps = false; ///< Opt.
 
 	String m_name;
@@ -670,13 +662,10 @@ private:
 		CString name,
 		Bool& drawsToPresentableTex);
 
-	ANKI_HOT Bool passADependsOnB(const RenderPassDescriptionBase& a, const RenderPassDescriptionBase& b) const;
+	ANKI_HOT static Bool passADependsOnB(const RenderPassDescriptionBase& a, const RenderPassDescriptionBase& b);
 
 	static Bool overlappingTextureSubresource(const TextureSubresourceInfo& suba, const TextureSubresourceInfo& subb);
 
-	template<Bool isTexture>
-	ANKI_HOT Bool overlappingDependency(const RenderPassDependency& a, const RenderPassDependency& b) const;
-
 	static Bool passHasUnmetDependencies(const BakeContext& ctx, U32 passIdx);
 
 	void setTextureBarrier(Batch& batch, const RenderPassDependency& consumer);

+ 43 - 28
src/anki/gr/RenderGraph.inl.h

@@ -62,53 +62,68 @@ inline void RenderPassDescriptionBase::validateDep(const RenderPassDependency& d
 		(void)usage;
 		if(m_type == Type::GRAPHICS)
 		{
-			ANKI_ASSERT(!(usage & TextureUsageBit::ANY_COMPUTE));
+			ANKI_ASSERT(!(usage & TextureUsageBit::ALL_COMPUTE));
 		}
 		else
 		{
-			ANKI_ASSERT(!(usage & TextureUsageBit::ANY_GRAPHICS));
+			ANKI_ASSERT(!(usage & TextureUsageBit::ALL_GRAPHICS));
 		}
-	}
-}
-
-inline void RenderPassDescriptionBase::newConsumer(const RenderPassDependency& dep)
-{
-	validateDep(dep);
-
-	DynamicArray<RenderPassDependency>& consumers = (dep.m_isTexture) ? m_rtConsumers : m_buffConsumers;
-
-	consumers.emplaceBack(m_alloc, dep);
-
-	if(dep.m_isTexture && dep.m_texture.m_usage != TextureUsageBit::NONE)
-	{
-		fixSubresource(consumers.getBack());
-		m_consumerRtMask.set(dep.m_texture.m_handle.m_idx);
 
-		// Try to derive the usage by that dep
-		m_descr->m_renderTargets[dep.m_texture.m_handle.m_idx].m_usageDerivedByDeps |= dep.m_texture.m_usage;
+		ANKI_ASSERT(!!(usage & TextureUsageBit::ALL_READ) || !!(usage & TextureUsageBit::ALL_WRITE));
 	}
-	else if(dep.m_buffer.m_usage != BufferUsageBit::NONE)
+	else
 	{
-		m_consumerBufferMask.set(dep.m_buffer.m_handle.m_idx);
-		m_hasBufferDeps = true;
+		BufferUsageBit usage = dep.m_buffer.m_usage;
+		(void)usage;
+		if(m_type == Type::GRAPHICS)
+		{
+			ANKI_ASSERT(!(usage & BufferUsageBit::ALL_COMPUTE));
+		}
+		else
+		{
+			ANKI_ASSERT(!(usage & BufferUsageBit::ALL_GRAPHICS));
+		}
+
+		ANKI_ASSERT(!!(usage & BufferUsageBit::ALL_READ) || !!(usage & BufferUsageBit::ALL_WRITE));
 	}
 }
 
-inline void RenderPassDescriptionBase::newProducer(const RenderPassDependency& dep)
+inline void RenderPassDescriptionBase::newDependency(const RenderPassDependency& dep)
 {
 	validateDep(dep);
 
-	DynamicArray<RenderPassDependency>& producers = (dep.m_isTexture) ? m_rtProducers : m_buffProducers;
+	DynamicArray<RenderPassDependency>& deps = (dep.m_isTexture) ? m_rtDeps : m_buffDeps;
+	deps.emplaceBack(m_alloc, dep);
 
-	producers.emplaceBack(m_alloc, dep);
 	if(dep.m_isTexture)
 	{
-		fixSubresource(producers.getBack());
-		m_producerRtMask.set(dep.m_texture.m_handle.m_idx);
+		fixSubresource(deps.getBack());
+
+		if(!!(dep.m_texture.m_usage & TextureUsageBit::ALL_READ))
+		{
+			m_readRtMask.set(dep.m_texture.m_handle.m_idx);
+		}
+
+		if(!!(dep.m_texture.m_usage & TextureUsageBit::ALL_WRITE))
+		{
+			m_writeRtMask.set(dep.m_texture.m_handle.m_idx);
+		}
+
+		// Try to derive the usage by that dep
+		m_descr->m_renderTargets[dep.m_texture.m_handle.m_idx].m_usageDerivedByDeps |= dep.m_texture.m_usage;
 	}
 	else
 	{
-		m_producerBufferMask.set(dep.m_buffer.m_handle.m_idx);
+		if(!!(dep.m_buffer.m_usage & BufferUsageBit::ALL_READ))
+		{
+			m_readBuffMask.set(dep.m_buffer.m_handle.m_idx);
+		}
+
+		if(!!(dep.m_buffer.m_usage & BufferUsageBit::ALL_WRITE))
+		{
+			m_writeBuffMask.set(dep.m_buffer.m_handle.m_idx);
+		}
+
 		m_hasBufferDeps = true;
 	}
 }

+ 2 - 2
src/anki/gr/vulkan/TextureImpl.cpp

@@ -222,7 +222,7 @@ Error TextureImpl::initImage(const TextureInitInfo& init_)
 		else if(init.m_format == Format::S8_UINT)
 		{
 			ANKI_ASSERT(
-				!(init.m_usage & (TextureUsageBit::IMAGE_ALL | TextureUsageBit::TRANSFER_ANY)) && "Can't do that ATM");
+				!(init.m_usage & (TextureUsageBit::IMAGE_ALL | TextureUsageBit::TRANSFER_ALL)) && "Can't do that ATM");
 			init.m_format = Format::D24_UNORM_S8_UINT;
 			m_format = init.m_format;
 			m_vkFormat = convertFormat(m_format);
@@ -231,7 +231,7 @@ Error TextureImpl::initImage(const TextureInitInfo& init_)
 		else if(init.m_format == Format::D24_UNORM_S8_UINT)
 		{
 			ANKI_ASSERT(
-				!(init.m_usage & (TextureUsageBit::IMAGE_ALL | TextureUsageBit::TRANSFER_ANY)) && "Can't do that ATM");
+				!(init.m_usage & (TextureUsageBit::IMAGE_ALL | TextureUsageBit::TRANSFER_ALL)) && "Can't do that ATM");
 			init.m_format = Format::D32_SFLOAT_S8_UINT;
 			m_format = init.m_format;
 			m_vkFormat = convertFormat(m_format);

+ 4 - 4
src/anki/renderer/Bloom.cpp

@@ -92,8 +92,8 @@ void Bloom::populateRenderGraph(RenderingContext& ctx)
 
 		TextureSubresourceInfo inputTexSubresource;
 		inputTexSubresource.m_firstMipmap = m_r->getDownscaleBlur().getMipmapCount() - 1;
-		rpass.newConsumer({m_r->getDownscaleBlur().getRt(), TextureUsageBit::SAMPLED_COMPUTE, inputTexSubresource});
-		rpass.newConsumerAndProducer({m_runCtx.m_exposureRt, TextureUsageBit::IMAGE_COMPUTE_WRITE});
+		rpass.newDependency({m_r->getDownscaleBlur().getRt(), TextureUsageBit::SAMPLED_COMPUTE, inputTexSubresource});
+		rpass.newDependency({m_runCtx.m_exposureRt, TextureUsageBit::IMAGE_COMPUTE_WRITE});
 	}
 
 	// Upscale & SSLF pass
@@ -105,8 +105,8 @@ void Bloom::populateRenderGraph(RenderingContext& ctx)
 		ComputeRenderPassDescription& rpass = rgraph.newComputeRenderPass("Bloom Upscale");
 		rpass.setWork(runUpscaleAndSslfCallback, this, 0);
 
-		rpass.newConsumerAndProducer({m_runCtx.m_upscaleRt, TextureUsageBit::IMAGE_COMPUTE_WRITE});
-		rpass.newConsumer({m_runCtx.m_exposureRt, TextureUsageBit::SAMPLED_COMPUTE});
+		rpass.newDependency({m_runCtx.m_exposureRt, TextureUsageBit::SAMPLED_COMPUTE});
+		rpass.newDependency({m_runCtx.m_upscaleRt, TextureUsageBit::IMAGE_COMPUTE_WRITE});
 	}
 }
 

+ 1 - 1
src/anki/renderer/Common.h

@@ -94,7 +94,7 @@ const U AVERAGE_LUMINANCE_RENDER_TARGET_SIZE = 128;
 
 extern const Array<Format, GBUFFER_COLOR_ATTACHMENT_COUNT> MS_COLOR_ATTACHMENT_PIXEL_FORMATS;
 
-const Format GBUFFER_DEPTH_ATTACHMENT_PIXEL_FORMAT = Format::D24_UNORM_S8_UINT;
+const Format GBUFFER_DEPTH_ATTACHMENT_PIXEL_FORMAT = Format::D32_SFLOAT;
 
 const Format LIGHT_SHADING_COLOR_ATTACHMENT_PIXEL_FORMAT = Format::B10G11R11_UFLOAT_PACK32;
 

+ 2 - 3
src/anki/renderer/Dbg.cpp

@@ -111,10 +111,9 @@ void Dbg::populateRenderGraph(RenderingContext& ctx)
 	pass.setWork(runCallback, this, 0);
 	pass.setFramebufferInfo(m_fbDescr, {{m_runCtx.m_rt}}, m_r->getGBuffer().getDepthRt());
 
-	pass.newConsumer({m_runCtx.m_rt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
-	pass.newConsumer({m_r->getGBuffer().getDepthRt(),
+	pass.newDependency({m_runCtx.m_rt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
+	pass.newDependency({m_r->getGBuffer().getDepthRt(),
 		TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ});
-	pass.newProducer({m_runCtx.m_rt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
 }
 
 } // end namespace anki

+ 5 - 10
src/anki/renderer/DepthDownscale.cpp

@@ -135,12 +135,9 @@ void DepthDownscale::populateRenderGraph(RenderingContext& ctx)
 
 		TextureSubresourceInfo subresource = TextureSubresourceInfo(DepthStencilAspectBit::DEPTH); // First mip
 
-		pass.newConsumer({m_r->getGBuffer().getDepthRt(), TextureUsageBit::SAMPLED_FRAGMENT, subresource});
-		pass.newConsumer({m_runCtx.m_halfDepthRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE, subresource});
-		pass.newConsumer({m_runCtx.m_hizRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE, subresource});
-
-		pass.newProducer({m_runCtx.m_halfDepthRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE, subresource});
-		pass.newProducer({m_runCtx.m_hizRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
+		pass.newDependency({m_r->getGBuffer().getDepthRt(), TextureUsageBit::SAMPLED_FRAGMENT, subresource});
+		pass.newDependency({m_runCtx.m_halfDepthRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE, subresource});
+		pass.newDependency({m_runCtx.m_hizRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE, subresource});
 	}
 
 	// Rest of the passes
@@ -155,10 +152,8 @@ void DepthDownscale::populateRenderGraph(RenderingContext& ctx)
 		subresourceRead.m_firstMipmap = i - 1;
 		subresourceWrite.m_firstMipmap = i;
 
-		pass.newConsumer({m_runCtx.m_hizRt, TextureUsageBit::SAMPLED_FRAGMENT, subresourceRead});
-		pass.newConsumer({m_runCtx.m_hizRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE, subresourceWrite});
-
-		pass.newProducer({m_runCtx.m_hizRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE, subresourceWrite});
+		pass.newDependency({m_runCtx.m_hizRt, TextureUsageBit::SAMPLED_FRAGMENT, subresourceRead});
+		pass.newDependency({m_runCtx.m_hizRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE, subresourceWrite});
 	}
 }
 

+ 8 - 16
src/anki/renderer/DownscaleBlur.cpp

@@ -117,19 +117,15 @@ void DownscaleBlur::populateRenderGraph(RenderingContext& ctx)
 				sampleSubresource.m_firstMipmap = i - 1;
 				renderSubresource.m_firstMipmap = i;
 
-				pass.newConsumer({m_runCtx.m_rt, TextureUsageBit::IMAGE_COMPUTE_WRITE, renderSubresource});
-				pass.newConsumer({m_runCtx.m_rt, TextureUsageBit::SAMPLED_COMPUTE, sampleSubresource});
-
-				pass.newProducer({m_runCtx.m_rt, TextureUsageBit::IMAGE_COMPUTE_WRITE, renderSubresource});
+				pass.newDependency({m_runCtx.m_rt, TextureUsageBit::IMAGE_COMPUTE_WRITE, renderSubresource});
+				pass.newDependency({m_runCtx.m_rt, TextureUsageBit::SAMPLED_COMPUTE, sampleSubresource});
 			}
 			else
 			{
 				TextureSubresourceInfo renderSubresource;
 
-				pass.newConsumer({m_runCtx.m_rt, TextureUsageBit::IMAGE_COMPUTE_WRITE, renderSubresource});
-				pass.newConsumer({m_r->getTemporalAA().getRt(), TextureUsageBit::SAMPLED_COMPUTE});
-
-				pass.newProducer({m_runCtx.m_rt, TextureUsageBit::IMAGE_COMPUTE_WRITE, renderSubresource});
+				pass.newDependency({m_runCtx.m_rt, TextureUsageBit::IMAGE_COMPUTE_WRITE, renderSubresource});
+				pass.newDependency({m_r->getTemporalAA().getRt(), TextureUsageBit::SAMPLED_COMPUTE});
 			}
 		}
 	}
@@ -149,19 +145,15 @@ void DownscaleBlur::populateRenderGraph(RenderingContext& ctx)
 				sampleSubresource.m_firstMipmap = i - 1;
 				renderSubresource.m_firstMipmap = i;
 
-				pass.newConsumer({m_runCtx.m_rt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE, renderSubresource});
-				pass.newConsumer({m_runCtx.m_rt, TextureUsageBit::SAMPLED_FRAGMENT, sampleSubresource});
-
-				pass.newProducer({m_runCtx.m_rt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE, renderSubresource});
+				pass.newDependency({m_runCtx.m_rt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE, renderSubresource});
+				pass.newDependency({m_runCtx.m_rt, TextureUsageBit::SAMPLED_FRAGMENT, sampleSubresource});
 			}
 			else
 			{
 				TextureSubresourceInfo renderSubresource;
 
-				pass.newConsumer({m_runCtx.m_rt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE, renderSubresource});
-				pass.newConsumer({m_r->getTemporalAA().getRt(), TextureUsageBit::SAMPLED_FRAGMENT});
-
-				pass.newProducer({m_runCtx.m_rt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE, renderSubresource});
+				pass.newDependency({m_runCtx.m_rt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE, renderSubresource});
+				pass.newDependency({m_r->getTemporalAA().getRt(), TextureUsageBit::SAMPLED_FRAGMENT});
 			}
 		}
 	}

+ 6 - 7
src/anki/renderer/FinalComposite.cpp

@@ -142,19 +142,18 @@ void FinalComposite::populateRenderGraph(RenderingContext& ctx)
 	pass.setWork(runCallback, this, 0);
 	pass.setFramebufferInfo(m_fbDescr, {{ctx.m_outRenderTarget}}, {});
 
-	pass.newConsumer({ctx.m_outRenderTarget, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
-	pass.newProducer({ctx.m_outRenderTarget, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
+	pass.newDependency({ctx.m_outRenderTarget, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
 
 	if(m_r->getDbg().getEnabled())
 	{
-		pass.newConsumer({m_r->getDbg().getRt(), TextureUsageBit::SAMPLED_FRAGMENT});
+		pass.newDependency({m_r->getDbg().getRt(), TextureUsageBit::SAMPLED_FRAGMENT});
 	}
 
-	pass.newConsumer({m_r->getTemporalAA().getRt(), TextureUsageBit::SAMPLED_FRAGMENT});
-	pass.newConsumer({m_r->getBloom().getRt(), TextureUsageBit::SAMPLED_FRAGMENT});
+	pass.newDependency({m_r->getTemporalAA().getRt(), TextureUsageBit::SAMPLED_FRAGMENT});
+	pass.newDependency({m_r->getBloom().getRt(), TextureUsageBit::SAMPLED_FRAGMENT});
 
-	pass.newConsumer({m_r->getGBuffer().getColorRt(3), TextureUsageBit::SAMPLED_FRAGMENT});
-	pass.newConsumer({m_r->getGBuffer().getDepthRt(), TextureUsageBit::SAMPLED_FRAGMENT});
+	pass.newDependency({m_r->getGBuffer().getColorRt(3), TextureUsageBit::SAMPLED_FRAGMENT});
+	pass.newDependency({m_r->getGBuffer().getDepthRt(), TextureUsageBit::SAMPLED_FRAGMENT});
 }
 
 } // end namespace anki

+ 7 - 9
src/anki/renderer/ForwardShading.cpp

@@ -170,21 +170,19 @@ void ForwardShading::populateRenderGraph(RenderingContext& ctx)
 		computeNumberOfSecondLevelCommandBuffers(ctx.m_renderQueue->m_forwardShadingRenderables.getSize()));
 	pass.setFramebufferInfo(m_fbDescr, {{m_runCtx.m_rt}}, m_r->getDepthDownscale().getHalfDepthRt());
 
-	pass.newConsumer({m_runCtx.m_rt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE});
-	pass.newConsumer({m_r->getDepthDownscale().getHalfDepthRt(),
+	pass.newDependency({m_runCtx.m_rt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE});
+	pass.newDependency({m_r->getDepthDownscale().getHalfDepthRt(),
 		TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ,
 		TextureSubresourceInfo(DepthStencilAspectBit::DEPTH)});
-	pass.newConsumer({m_r->getDepthDownscale().getHiZRt(), TextureUsageBit::SAMPLED_FRAGMENT, HIZ_HALF_DEPTH});
-	pass.newConsumer({m_r->getDepthDownscale().getHiZRt(), TextureUsageBit::SAMPLED_FRAGMENT, HIZ_QUARTER_DEPTH});
-	pass.newConsumer({m_r->getVolumetric().getRt(), TextureUsageBit::SAMPLED_FRAGMENT});
-	pass.newConsumer({m_r->getShadowMapping().getShadowmapRt(), TextureUsageBit::SAMPLED_FRAGMENT});
+	pass.newDependency({m_r->getDepthDownscale().getHiZRt(), TextureUsageBit::SAMPLED_FRAGMENT, HIZ_HALF_DEPTH});
+	pass.newDependency({m_r->getDepthDownscale().getHiZRt(), TextureUsageBit::SAMPLED_FRAGMENT, HIZ_QUARTER_DEPTH});
+	pass.newDependency({m_r->getVolumetric().getRt(), TextureUsageBit::SAMPLED_FRAGMENT});
+	pass.newDependency({m_r->getShadowMapping().getShadowmapRt(), TextureUsageBit::SAMPLED_FRAGMENT});
 
 	if(ctx.m_renderQueue->m_lensFlares.getSize())
 	{
-		pass.newConsumer({m_r->getLensFlare().getIndirectDrawBuffer(), BufferUsageBit::INDIRECT});
+		pass.newDependency({m_r->getLensFlare().getIndirectDrawBuffer(), BufferUsageBit::INDIRECT});
 	}
-
-	pass.newProducer({m_runCtx.m_rt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE});
 }
 
 } // end namespace anki

+ 2 - 4
src/anki/renderer/GBuffer.cpp

@@ -163,13 +163,11 @@ void GBuffer::populateRenderGraph(RenderingContext& ctx)
 
 	for(U i = 0; i < GBUFFER_COLOR_ATTACHMENT_COUNT; ++i)
 	{
-		pass.newConsumer({m_colorRts[i], TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
-		pass.newProducer({m_colorRts[i], TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
+		pass.newDependency({m_colorRts[i], TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
 	}
 
 	TextureSubresourceInfo subresource(DepthStencilAspectBit::DEPTH);
-	pass.newConsumer({m_depthRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE, subresource});
-	pass.newProducer({m_depthRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE, subresource});
+	pass.newDependency({m_depthRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE, subresource});
 }
 
 } // end namespace anki

+ 3 - 6
src/anki/renderer/GBufferPost.cpp

@@ -62,14 +62,11 @@ void GBufferPost::populateRenderGraph(RenderingContext& ctx)
 	rpass.setWork(runCallback, this, 0);
 	rpass.setFramebufferInfo(m_fbDescr, {{m_r->getGBuffer().getColorRt(0), m_r->getGBuffer().getColorRt(1)}}, {});
 
-	rpass.newConsumer({m_r->getGBuffer().getColorRt(0), TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE});
-	rpass.newConsumer({m_r->getGBuffer().getColorRt(1), TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE});
-	rpass.newConsumer({m_r->getGBuffer().getDepthRt(),
+	rpass.newDependency({m_r->getGBuffer().getColorRt(0), TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE});
+	rpass.newDependency({m_r->getGBuffer().getColorRt(1), TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE});
+	rpass.newDependency({m_r->getGBuffer().getDepthRt(),
 		TextureUsageBit::SAMPLED_FRAGMENT,
 		TextureSubresourceInfo(DepthStencilAspectBit::DEPTH)});
-
-	rpass.newProducer({m_r->getGBuffer().getColorRt(0), TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE});
-	rpass.newProducer({m_r->getGBuffer().getColorRt(1), TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE});
 }
 
 void GBufferPost::run(RenderPassWorkContext& rgraphCtx)

+ 13 - 19
src/anki/renderer/Indirect.cpp

@@ -520,13 +520,12 @@ void Indirect::populateRenderGraph(RenderingContext& rctx)
 
 			for(U i = 0; i < GBUFFER_COLOR_ATTACHMENT_COUNT; ++i)
 			{
-				pass.newConsumer({m_ctx.m_gbufferColorRts[i], TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
-				pass.newProducer({m_ctx.m_gbufferColorRts[i], TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
+				pass.newDependency({m_ctx.m_gbufferColorRts[i], TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
 			}
 
 			TextureSubresourceInfo subresource(DepthStencilAspectBit::DEPTH);
-			pass.newConsumer({m_ctx.m_gbufferDepthRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE, subresource});
-			pass.newProducer({m_ctx.m_gbufferDepthRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE, subresource});
+			pass.newDependency(
+				{m_ctx.m_gbufferDepthRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE, subresource});
 		}
 
 		// Light shading passes
@@ -558,14 +557,14 @@ void Indirect::populateRenderGraph(RenderingContext& rctx)
 				pass.setWork(callbacks[faceIdx], this, 0);
 
 				TextureSubresourceInfo subresource(TextureSurfaceInfo(0, 0, faceIdx, probeToUpdateCacheEntryIdx));
-				pass.newConsumer({m_ctx.m_lightShadingRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE, subresource});
-				pass.newProducer({m_ctx.m_lightShadingRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE, subresource});
+				pass.newDependency(
+					{m_ctx.m_lightShadingRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE, subresource});
 
 				for(U i = 0; i < GBUFFER_COLOR_ATTACHMENT_COUNT; ++i)
 				{
-					pass.newConsumer({m_ctx.m_gbufferColorRts[i], TextureUsageBit::SAMPLED_FRAGMENT});
+					pass.newDependency({m_ctx.m_gbufferColorRts[i], TextureUsageBit::SAMPLED_FRAGMENT});
 				}
-				pass.newConsumer({m_ctx.m_gbufferDepthRt,
+				pass.newDependency({m_ctx.m_gbufferDepthRt,
 					TextureUsageBit::SAMPLED_FRAGMENT,
 					TextureSubresourceInfo(DepthStencilAspectBit::DEPTH)});
 			}
@@ -599,12 +598,10 @@ void Indirect::populateRenderGraph(RenderingContext& rctx)
 				TextureSubresourceInfo readSubresource;
 				readSubresource.m_faceCount = 6;
 				readSubresource.m_firstLayer = probeToUpdateCacheEntryIdx;
-				pass.newConsumer({m_ctx.m_lightShadingRt, TextureUsageBit::SAMPLED_FRAGMENT, readSubresource});
+				pass.newDependency({m_ctx.m_lightShadingRt, TextureUsageBit::SAMPLED_FRAGMENT, readSubresource});
 
 				TextureSubresourceInfo writeSubresource(TextureSurfaceInfo(0, 0, faceIdx, probeToUpdateCacheEntryIdx));
-				pass.newConsumer(
-					{m_ctx.m_irradianceRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE, writeSubresource});
-				pass.newProducer(
+				pass.newDependency(
 					{m_ctx.m_irradianceRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE, writeSubresource});
 			}
 		}
@@ -637,18 +634,16 @@ void Indirect::populateRenderGraph(RenderingContext& rctx)
 
 				for(U i = 0; i < GBUFFER_COLOR_ATTACHMENT_COUNT; ++i)
 				{
-					pass.newConsumer({m_ctx.m_gbufferColorRts[i], TextureUsageBit::SAMPLED_FRAGMENT});
+					pass.newDependency({m_ctx.m_gbufferColorRts[i], TextureUsageBit::SAMPLED_FRAGMENT});
 				}
 
 				TextureSubresourceInfo readSubresource;
 				readSubresource.m_faceCount = 6;
 				readSubresource.m_firstLayer = probeToUpdateCacheEntryIdx;
-				pass.newConsumer({m_ctx.m_irradianceRt, TextureUsageBit::SAMPLED_FRAGMENT, readSubresource});
+				pass.newDependency({m_ctx.m_irradianceRt, TextureUsageBit::SAMPLED_FRAGMENT, readSubresource});
 
 				TextureSubresourceInfo writeSubresource(TextureSurfaceInfo(0, 0, faceIdx, probeToUpdateCacheEntryIdx));
-				pass.newConsumer(
-					{m_ctx.m_lightShadingRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE, writeSubresource});
-				pass.newProducer(
+				pass.newDependency(
 					{m_ctx.m_lightShadingRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE, writeSubresource});
 			}
 		}
@@ -672,8 +667,7 @@ void Indirect::populateRenderGraph(RenderingContext& rctx)
 				TextureSubresourceInfo subresource(TextureSurfaceInfo(0, 0, faceIdx, probeToUpdateCacheEntryIdx));
 				subresource.m_mipmapCount = m_lightShading.m_mipCount;
 
-				pass.newConsumer({m_ctx.m_lightShadingRt, TextureUsageBit::GENERATE_MIPMAPS, subresource});
-				pass.newProducer({m_ctx.m_lightShadingRt, TextureUsageBit::GENERATE_MIPMAPS, subresource});
+				pass.newDependency({m_ctx.m_lightShadingRt, TextureUsageBit::GENERATE_MIPMAPS, subresource});
 			}
 		}
 	}

+ 2 - 4
src/anki/renderer/LensFlare.cpp

@@ -131,10 +131,8 @@ void LensFlare::populateRenderGraph(RenderingContext& ctx)
 
 		rpass.setWork(runUpdateIndirectCallback, this, 0);
 
-		rpass.newConsumer({m_runCtx.m_indirectBuffHandle, BufferUsageBit::STORAGE_COMPUTE_WRITE});
-		rpass.newConsumer({m_r->getDepthDownscale().getHiZRt(), TextureUsageBit::SAMPLED_COMPUTE, HIZ_QUARTER_DEPTH});
-
-		rpass.newProducer({m_runCtx.m_indirectBuffHandle, BufferUsageBit::STORAGE_COMPUTE_WRITE});
+		rpass.newDependency({m_runCtx.m_indirectBuffHandle, BufferUsageBit::STORAGE_COMPUTE_WRITE});
+		rpass.newDependency({m_r->getDepthDownscale().getHiZRt(), TextureUsageBit::SAMPLED_COMPUTE, HIZ_QUARTER_DEPTH});
 	}
 }
 

+ 12 - 12
src/anki/renderer/LightShading.cpp

@@ -223,24 +223,24 @@ void LightShading::populateRenderGraph(RenderingContext& ctx)
 	pass.setFramebufferInfo(m_fbDescr, {{m_runCtx.m_rt}}, {});
 
 	// Light shading
-	pass.newConsumerAndProducer({m_runCtx.m_rt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
-	pass.newConsumer({m_r->getGBuffer().getColorRt(0), TextureUsageBit::SAMPLED_FRAGMENT});
-	pass.newConsumer({m_r->getGBuffer().getColorRt(1), TextureUsageBit::SAMPLED_FRAGMENT});
-	pass.newConsumer({m_r->getGBuffer().getColorRt(2), TextureUsageBit::SAMPLED_FRAGMENT});
-	pass.newConsumer({m_r->getGBuffer().getDepthRt(),
+	pass.newDependency({m_runCtx.m_rt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
+	pass.newDependency({m_r->getGBuffer().getColorRt(0), TextureUsageBit::SAMPLED_FRAGMENT});
+	pass.newDependency({m_r->getGBuffer().getColorRt(1), TextureUsageBit::SAMPLED_FRAGMENT});
+	pass.newDependency({m_r->getGBuffer().getColorRt(2), TextureUsageBit::SAMPLED_FRAGMENT});
+	pass.newDependency({m_r->getGBuffer().getDepthRt(),
 		TextureUsageBit::SAMPLED_FRAGMENT,
 		TextureSubresourceInfo(DepthStencilAspectBit::DEPTH)});
-	pass.newConsumer({m_r->getShadowMapping().getShadowmapRt(), TextureUsageBit::SAMPLED_FRAGMENT});
-	pass.newConsumer({m_r->getSsao().getRt(), TextureUsageBit::SAMPLED_FRAGMENT});
+	pass.newDependency({m_r->getShadowMapping().getShadowmapRt(), TextureUsageBit::SAMPLED_FRAGMENT});
+	pass.newDependency({m_r->getSsao().getRt(), TextureUsageBit::SAMPLED_FRAGMENT});
 
 	// Refl & indirect
-	pass.newConsumer({m_r->getSsr().getRt(), TextureUsageBit::SAMPLED_FRAGMENT});
-	pass.newConsumer({m_r->getIndirect().getReflectionRt(), TextureUsageBit::SAMPLED_FRAGMENT});
-	pass.newConsumer({m_r->getIndirect().getIrradianceRt(), TextureUsageBit::SAMPLED_FRAGMENT});
+	pass.newDependency({m_r->getSsr().getRt(), TextureUsageBit::SAMPLED_FRAGMENT});
+	pass.newDependency({m_r->getIndirect().getReflectionRt(), TextureUsageBit::SAMPLED_FRAGMENT});
+	pass.newDependency({m_r->getIndirect().getIrradianceRt(), TextureUsageBit::SAMPLED_FRAGMENT});
 
 	// For forward shading
-	pass.newConsumer({m_r->getDepthDownscale().getHiZRt(), TextureUsageBit::SAMPLED_FRAGMENT, HIZ_HALF_DEPTH});
-	pass.newConsumer({m_r->getForwardShading().getRt(), TextureUsageBit::SAMPLED_FRAGMENT});
+	pass.newDependency({m_r->getDepthDownscale().getHiZRt(), TextureUsageBit::SAMPLED_FRAGMENT, HIZ_HALF_DEPTH});
+	pass.newDependency({m_r->getForwardShading().getRt(), TextureUsageBit::SAMPLED_FRAGMENT});
 }
 
 void LightShading::updateCommonBlock(RenderingContext& ctx)

+ 3 - 3
src/anki/renderer/MainRenderer.cpp

@@ -131,8 +131,8 @@ Error MainRenderer::render(RenderQueue& rqueue, TexturePtr presentTex)
 		pass.setFramebufferInfo(fbDescr, {{presentRt}}, {});
 		pass.setWork(runCallback, this, 0);
 
-		pass.newConsumerAndProducer({presentRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
-		pass.newConsumer({ctx.m_outRenderTarget, TextureUsageBit::SAMPLED_FRAGMENT});
+		pass.newDependency({presentRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
+		pass.newDependency({ctx.m_outRenderTarget, TextureUsageBit::SAMPLED_FRAGMENT});
 	}
 
 	// Create a dummy pass to transition the presentable image to present
@@ -140,7 +140,7 @@ Error MainRenderer::render(RenderQueue& rqueue, TexturePtr presentTex)
 		ComputeRenderPassDescription& pass = ctx.m_renderGraphDescr.newComputeRenderPass("Present");
 
 		pass.setWork(presentCallback, nullptr, 0);
-		pass.newConsumerAndProducer({presentRt, TextureUsageBit::PRESENT});
+		pass.newDependency({presentRt, TextureUsageBit::PRESENT});
 	}
 
 	// Bake the render graph

+ 3 - 5
src/anki/renderer/ShadowMapping.cpp

@@ -230,8 +230,7 @@ void ShadowMapping::populateRenderGraph(RenderingContext& ctx)
 			pass.setWork(runShadowmappingCallback, this, threadCountForScratchPass);
 
 			TextureSubresourceInfo subresource = TextureSubresourceInfo(DepthStencilAspectBit::DEPTH);
-			pass.newConsumer({m_scratchRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE, subresource});
-			pass.newProducer({m_scratchRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE, subresource});
+			pass.newDependency({m_scratchRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE, subresource});
 		}
 
 		// ESM pass
@@ -242,10 +241,9 @@ void ShadowMapping::populateRenderGraph(RenderingContext& ctx)
 			pass.setFramebufferInfo(m_esmFbDescr, {{m_esmRt}}, {});
 			pass.setWork(runEsmCallback, this, 0);
 
-			pass.newConsumer(
+			pass.newDependency(
 				{m_scratchRt, TextureUsageBit::SAMPLED_FRAGMENT, TextureSubresourceInfo(DepthStencilAspectBit::DEPTH)});
-			pass.newConsumer({m_esmRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
-			pass.newProducer({m_esmRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
+			pass.newDependency({m_esmRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
 		}
 	}
 	else

+ 11 - 14
src/anki/renderer/Ssao.cpp

@@ -203,12 +203,11 @@ void Ssao::populateRenderGraph(RenderingContext& ctx)
 
 			if(m_useNormal)
 			{
-				pass.newConsumer({m_r->getGBuffer().getColorRt(2), TextureUsageBit::SAMPLED_COMPUTE});
+				pass.newDependency({m_r->getGBuffer().getColorRt(2), TextureUsageBit::SAMPLED_COMPUTE});
 			}
 
-			pass.newConsumer({m_r->getDepthDownscale().getHiZRt(), TextureUsageBit::SAMPLED_COMPUTE, HIZ_HALF_DEPTH});
-			pass.newConsumer({m_runCtx.m_rts[0], TextureUsageBit::IMAGE_COMPUTE_WRITE});
-			pass.newProducer({m_runCtx.m_rts[0], TextureUsageBit::IMAGE_COMPUTE_WRITE});
+			pass.newDependency({m_r->getDepthDownscale().getHiZRt(), TextureUsageBit::SAMPLED_COMPUTE, HIZ_HALF_DEPTH});
+			pass.newDependency({m_runCtx.m_rts[0], TextureUsageBit::IMAGE_COMPUTE_WRITE});
 
 			pass.setWork(runMainCallback, this, 0);
 		}
@@ -220,12 +219,12 @@ void Ssao::populateRenderGraph(RenderingContext& ctx)
 
 			if(m_useNormal)
 			{
-				pass.newConsumer({m_r->getGBuffer().getColorRt(2), TextureUsageBit::SAMPLED_FRAGMENT});
+				pass.newDependency({m_r->getGBuffer().getColorRt(2), TextureUsageBit::SAMPLED_FRAGMENT});
 			}
 
-			pass.newConsumer({m_r->getDepthDownscale().getHiZRt(), TextureUsageBit::SAMPLED_FRAGMENT, HIZ_HALF_DEPTH});
-			pass.newConsumer({m_runCtx.m_rts[0], TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
-			pass.newProducer({m_runCtx.m_rts[0], TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
+			pass.newDependency(
+				{m_r->getDepthDownscale().getHiZRt(), TextureUsageBit::SAMPLED_FRAGMENT, HIZ_HALF_DEPTH});
+			pass.newDependency({m_runCtx.m_rts[0], TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
 
 			pass.setWork(runMainCallback, this, 0);
 		}
@@ -239,9 +238,8 @@ void Ssao::populateRenderGraph(RenderingContext& ctx)
 
 			pass.setWork(runBlurCallback, this, 0);
 
-			pass.newConsumer({m_runCtx.m_rts[1], TextureUsageBit::IMAGE_COMPUTE_WRITE});
-			pass.newConsumer({m_runCtx.m_rts[0], TextureUsageBit::SAMPLED_COMPUTE});
-			pass.newProducer({m_runCtx.m_rts[1], TextureUsageBit::IMAGE_COMPUTE_WRITE});
+			pass.newDependency({m_runCtx.m_rts[1], TextureUsageBit::IMAGE_COMPUTE_WRITE});
+			pass.newDependency({m_runCtx.m_rts[0], TextureUsageBit::SAMPLED_COMPUTE});
 		}
 		else
 		{
@@ -250,9 +248,8 @@ void Ssao::populateRenderGraph(RenderingContext& ctx)
 			pass.setWork(runBlurCallback, this, 0);
 			pass.setFramebufferInfo(m_fbDescr, {{m_runCtx.m_rts[1]}}, {});
 
-			pass.newConsumer({m_runCtx.m_rts[1], TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
-			pass.newConsumer({m_runCtx.m_rts[0], TextureUsageBit::SAMPLED_FRAGMENT});
-			pass.newProducer({m_runCtx.m_rts[1], TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
+			pass.newDependency({m_runCtx.m_rts[1], TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
+			pass.newDependency({m_runCtx.m_rts[0], TextureUsageBit::SAMPLED_FRAGMENT});
 		}
 	}
 }

+ 5 - 5
src/anki/renderer/Ssr.cpp

@@ -74,14 +74,14 @@ void Ssr::populateRenderGraph(RenderingContext& ctx)
 	ComputeRenderPassDescription& rpass = rgraph.newComputeRenderPass("SSR");
 	rpass.setWork(runCallback, this, 0);
 
-	rpass.newConsumerAndProducer({m_runCtx.m_rt, TextureUsageBit::IMAGE_COMPUTE_WRITE});
-	rpass.newConsumer({m_r->getGBuffer().getColorRt(1), TextureUsageBit::SAMPLED_COMPUTE});
-	rpass.newConsumer({m_r->getGBuffer().getColorRt(2), TextureUsageBit::SAMPLED_COMPUTE});
+	rpass.newDependency({m_runCtx.m_rt, TextureUsageBit::IMAGE_COMPUTE_WRITE});
+	rpass.newDependency({m_r->getGBuffer().getColorRt(1), TextureUsageBit::SAMPLED_COMPUTE});
+	rpass.newDependency({m_r->getGBuffer().getColorRt(2), TextureUsageBit::SAMPLED_COMPUTE});
 
 	TextureSubresourceInfo hizSubresource; // Only first mip
-	rpass.newConsumer({m_r->getDepthDownscale().getHiZRt(), TextureUsageBit::SAMPLED_COMPUTE, hizSubresource});
+	rpass.newDependency({m_r->getDepthDownscale().getHiZRt(), TextureUsageBit::SAMPLED_COMPUTE, hizSubresource});
 
-	rpass.newConsumer({m_r->getDownscaleBlur().getRt(), TextureUsageBit::SAMPLED_COMPUTE});
+	rpass.newDependency({m_r->getDownscaleBlur().getRt(), TextureUsageBit::SAMPLED_COMPUTE});
 }
 
 void Ssr::run(RenderPassWorkContext& rgraphCtx)

+ 4 - 4
src/anki/renderer/TemporalAA.cpp

@@ -105,12 +105,12 @@ void TemporalAA::populateRenderGraph(RenderingContext& ctx)
 
 	pass.setWork(runCallback, this, 0);
 
-	pass.newConsumerAndProducer({m_runCtx.m_renderRt, TextureUsageBit::IMAGE_COMPUTE_WRITE});
-	pass.newConsumer({m_r->getGBuffer().getDepthRt(),
+	pass.newDependency({m_runCtx.m_renderRt, TextureUsageBit::IMAGE_COMPUTE_WRITE});
+	pass.newDependency({m_r->getGBuffer().getDepthRt(),
 		TextureUsageBit::SAMPLED_COMPUTE,
 		TextureSubresourceInfo(DepthStencilAspectBit::DEPTH)});
-	pass.newConsumer({m_r->getLightShading().getRt(), TextureUsageBit::SAMPLED_COMPUTE});
-	pass.newConsumer({m_runCtx.m_historyRt, TextureUsageBit::SAMPLED_COMPUTE});
+	pass.newDependency({m_r->getLightShading().getRt(), TextureUsageBit::SAMPLED_COMPUTE});
+	pass.newDependency({m_runCtx.m_historyRt, TextureUsageBit::SAMPLED_COMPUTE});
 }
 
 } // end namespace anki

+ 2 - 2
src/anki/renderer/Tonemapping.cpp

@@ -80,11 +80,11 @@ void Tonemapping::populateRenderGraph(RenderingContext& ctx)
 
 	pass.setWork(runCallback, this, 0);
 
-	pass.newConsumerAndProducer({m_runCtx.m_buffHandle, BufferUsageBit::STORAGE_COMPUTE_READ_WRITE});
+	pass.newDependency({m_runCtx.m_buffHandle, BufferUsageBit::STORAGE_COMPUTE_READ_WRITE});
 
 	TextureSubresourceInfo inputTexSubresource;
 	inputTexSubresource.m_firstMipmap = m_inputTexMip;
-	pass.newConsumer({m_r->getDownscaleBlur().getRt(), TextureUsageBit::SAMPLED_COMPUTE, inputTexSubresource});
+	pass.newDependency({m_r->getDownscaleBlur().getRt(), TextureUsageBit::SAMPLED_COMPUTE, inputTexSubresource});
 }
 
 void Tonemapping::run(RenderPassWorkContext& rgraphCtx)

+ 8 - 11
src/anki/renderer/Volumetric.cpp

@@ -205,11 +205,10 @@ void Volumetric::populateRenderGraph(RenderingContext& ctx)
 		pass.setWork(runMainCallback, this, 0);
 		pass.setFramebufferInfo(m_fbDescr, {{m_runCtx.m_rts[rtToRenderIdx]}}, {});
 
-		pass.newConsumer({m_r->getDepthDownscale().getHiZRt(), TextureUsageBit::SAMPLED_FRAGMENT, HIZ_QUARTER_DEPTH});
-		pass.newConsumer({m_r->getShadowMapping().getShadowmapRt(), TextureUsageBit::SAMPLED_FRAGMENT});
-		pass.newConsumer({m_runCtx.m_rts[rtToRenderIdx], TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
-		pass.newConsumer({m_runCtx.m_rts[rtToReadIdx], TextureUsageBit::SAMPLED_FRAGMENT});
-		pass.newProducer({m_runCtx.m_rts[rtToRenderIdx], TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
+		pass.newDependency({m_r->getDepthDownscale().getHiZRt(), TextureUsageBit::SAMPLED_FRAGMENT, HIZ_QUARTER_DEPTH});
+		pass.newDependency({m_r->getShadowMapping().getShadowmapRt(), TextureUsageBit::SAMPLED_FRAGMENT});
+		pass.newDependency({m_runCtx.m_rts[rtToRenderIdx], TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
+		pass.newDependency({m_runCtx.m_rts[rtToReadIdx], TextureUsageBit::SAMPLED_FRAGMENT});
 	}
 
 	// Create HBlur pass
@@ -219,9 +218,8 @@ void Volumetric::populateRenderGraph(RenderingContext& ctx)
 		pass.setWork(runHBlurCallback, this, 0);
 		pass.setFramebufferInfo(m_fbDescr, {{m_runCtx.m_rts[rtToReadIdx]}}, {});
 
-		pass.newConsumer({m_runCtx.m_rts[rtToReadIdx], TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
-		pass.newConsumer({m_runCtx.m_rts[rtToRenderIdx], TextureUsageBit::SAMPLED_FRAGMENT});
-		pass.newProducer({m_runCtx.m_rts[rtToReadIdx], TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
+		pass.newDependency({m_runCtx.m_rts[rtToReadIdx], TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
+		pass.newDependency({m_runCtx.m_rts[rtToRenderIdx], TextureUsageBit::SAMPLED_FRAGMENT});
 	}
 
 	// Create VBlur pass
@@ -231,9 +229,8 @@ void Volumetric::populateRenderGraph(RenderingContext& ctx)
 		pass.setWork(runVBlurCallback, this, 0);
 		pass.setFramebufferInfo(m_fbDescr, {{m_runCtx.m_rts[rtToRenderIdx]}}, {});
 
-		pass.newConsumer({m_runCtx.m_rts[rtToRenderIdx], TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
-		pass.newConsumer({m_runCtx.m_rts[rtToReadIdx], TextureUsageBit::SAMPLED_FRAGMENT});
-		pass.newProducer({m_runCtx.m_rts[rtToRenderIdx], TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
+		pass.newDependency({m_runCtx.m_rts[rtToRenderIdx], TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
+		pass.newDependency({m_runCtx.m_rts[rtToReadIdx], TextureUsageBit::SAMPLED_FRAGMENT});
 	}
 }
 

+ 47 - 73
tests/gr/Gr.cpp

@@ -1634,17 +1634,15 @@ ANKI_TEST(Gr, RenderGraph)
 	RenderTargetHandle smScratchRt = descr.newRenderTarget(newRTDescr("SM scratch"));
 	{
 		GraphicsRenderPassDescription& pass = descr.newGraphicsRenderPass("SM");
-		pass.newConsumer({smScratchRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE});
-		pass.newProducer({smScratchRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE});
+		pass.newDependency({smScratchRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE});
 	}
 
 	// SM to exponential SM
 	RenderTargetHandle smExpRt = descr.importRenderTarget(dummyTex, TextureUsageBit::SAMPLED_FRAGMENT);
 	{
 		GraphicsRenderPassDescription& pass = descr.newGraphicsRenderPass("ESM");
-		pass.newConsumer({smScratchRt, TextureUsageBit::SAMPLED_FRAGMENT});
-		pass.newConsumer({smExpRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
-		pass.newProducer({smExpRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
+		pass.newDependency({smScratchRt, TextureUsageBit::SAMPLED_FRAGMENT});
+		pass.newDependency({smExpRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
 	}
 
 	// GI gbuff
@@ -1653,13 +1651,9 @@ ANKI_TEST(Gr, RenderGraph)
 	RenderTargetHandle giGbuffDepthRt = descr.newRenderTarget(newRTDescr("GI GBuff depth"));
 	{
 		GraphicsRenderPassDescription& pass = descr.newGraphicsRenderPass("GI gbuff");
-		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});
-		pass.newProducer({giGbuffDiffRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
+		pass.newDependency({giGbuffNormRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
+		pass.newDependency({giGbuffDepthRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
+		pass.newDependency({giGbuffDiffRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
 	}
 
 	// GI light
@@ -1670,12 +1664,10 @@ ANKI_TEST(Gr, RenderGraph)
 
 		GraphicsRenderPassDescription& pass =
 			descr.newGraphicsRenderPass(StringAuto(alloc).sprintf("GI lp%u", faceIdx).toCString());
-		pass.newConsumer({giGiLightRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE, subresource});
-		pass.newConsumer({giGbuffNormRt, TextureUsageBit::SAMPLED_FRAGMENT});
-		pass.newConsumer({giGbuffDepthRt, TextureUsageBit::SAMPLED_FRAGMENT});
-		pass.newConsumer({giGbuffDiffRt, TextureUsageBit::SAMPLED_FRAGMENT});
-
-		pass.newProducer({giGiLightRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE, subresource});
+		pass.newDependency({giGiLightRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE, subresource});
+		pass.newDependency({giGbuffNormRt, TextureUsageBit::SAMPLED_FRAGMENT});
+		pass.newDependency({giGbuffDepthRt, TextureUsageBit::SAMPLED_FRAGMENT});
+		pass.newDependency({giGbuffDiffRt, TextureUsageBit::SAMPLED_FRAGMENT});
 	}
 
 	// GI light mips
@@ -1688,8 +1680,7 @@ ANKI_TEST(Gr, RenderGraph)
 			for(U mip = 0; mip < GI_MIP_COUNT; ++mip)
 			{
 				TextureSurfaceInfo surf(mip, 0, faceIdx, 0);
-				pass.newConsumer({giGiLightRt, TextureUsageBit::GENERATE_MIPMAPS, surf});
-				pass.newProducer({giGiLightRt, TextureUsageBit::GENERATE_MIPMAPS, surf});
+				pass.newDependency({giGiLightRt, TextureUsageBit::GENERATE_MIPMAPS, surf});
 			}
 		}
 	}
@@ -1701,85 +1692,71 @@ ANKI_TEST(Gr, RenderGraph)
 	RenderTargetHandle gbuffDepth = descr.newRenderTarget(newRTDescr("GBuff RT2"));
 	{
 		GraphicsRenderPassDescription& pass = descr.newGraphicsRenderPass("G-Buffer");
-		pass.newConsumer({gbuffRt0, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
-		pass.newConsumer({gbuffRt1, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
-		pass.newConsumer({gbuffRt2, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
-		pass.newConsumer({gbuffDepth, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
-
-		pass.newProducer({gbuffRt0, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
-		pass.newProducer({gbuffRt1, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
-		pass.newProducer({gbuffRt2, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
-		pass.newProducer({gbuffDepth, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
+		pass.newDependency({gbuffRt0, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
+		pass.newDependency({gbuffRt1, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
+		pass.newDependency({gbuffRt2, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
+		pass.newDependency({gbuffDepth, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
 	}
 
 	// Half depth
 	RenderTargetHandle halfDepthRt = descr.newRenderTarget(newRTDescr("Depth/2"));
 	{
 		GraphicsRenderPassDescription& pass = descr.newGraphicsRenderPass("HalfDepth");
-		pass.newConsumer({gbuffDepth, TextureUsageBit::SAMPLED_FRAGMENT});
-		pass.newConsumer({halfDepthRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
-		pass.newProducer({halfDepthRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
+		pass.newDependency({gbuffDepth, TextureUsageBit::SAMPLED_FRAGMENT});
+		pass.newDependency({halfDepthRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
 	}
 
 	// Quarter depth
 	RenderTargetHandle quarterDepthRt = descr.newRenderTarget(newRTDescr("Depth/4"));
 	{
 		GraphicsRenderPassDescription& pass = descr.newGraphicsRenderPass("QuarterDepth");
-		pass.newConsumer({quarterDepthRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
-		pass.newConsumer({halfDepthRt, TextureUsageBit::SAMPLED_FRAGMENT});
-		pass.newProducer({quarterDepthRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
+		pass.newDependency({quarterDepthRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
+		pass.newDependency({halfDepthRt, TextureUsageBit::SAMPLED_FRAGMENT});
 	}
 
 	// SSAO
 	RenderTargetHandle ssaoRt = descr.newRenderTarget(newRTDescr("SSAO"));
 	{
 		GraphicsRenderPassDescription& pass = descr.newGraphicsRenderPass("SSAO main");
-		pass.newConsumer({ssaoRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
-		pass.newConsumer({quarterDepthRt, TextureUsageBit::SAMPLED_FRAGMENT});
-		pass.newConsumer({gbuffRt2, TextureUsageBit::SAMPLED_FRAGMENT});
-		pass.newProducer({ssaoRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
+		pass.newDependency({ssaoRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
+		pass.newDependency({quarterDepthRt, TextureUsageBit::SAMPLED_FRAGMENT});
+		pass.newDependency({gbuffRt2, TextureUsageBit::SAMPLED_FRAGMENT});
 
 		RenderTargetHandle ssaoVBlurRt = descr.newRenderTarget(newRTDescr("SSAO tmp"));
 		GraphicsRenderPassDescription& pass2 = descr.newGraphicsRenderPass("SSAO vblur");
-		pass2.newConsumer({ssaoRt, TextureUsageBit::SAMPLED_FRAGMENT});
-		pass2.newConsumer({ssaoVBlurRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
-		pass2.newProducer({ssaoVBlurRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
+		pass2.newDependency({ssaoRt, TextureUsageBit::SAMPLED_FRAGMENT});
+		pass2.newDependency({ssaoVBlurRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
 
 		GraphicsRenderPassDescription& pass3 = descr.newGraphicsRenderPass("SSAO hblur");
-		pass3.newConsumer({ssaoRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
-		pass3.newProducer({ssaoRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
-		pass3.newConsumer({ssaoVBlurRt, TextureUsageBit::SAMPLED_FRAGMENT});
+		pass3.newDependency({ssaoRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
+		pass3.newDependency({ssaoVBlurRt, TextureUsageBit::SAMPLED_FRAGMENT});
 	}
 
 	// Volumetric
 	RenderTargetHandle volRt = descr.newRenderTarget(newRTDescr("Vol"));
 	{
 		GraphicsRenderPassDescription& pass = descr.newGraphicsRenderPass("Vol main");
-		pass.newConsumer({volRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
-		pass.newConsumer({quarterDepthRt, TextureUsageBit::SAMPLED_FRAGMENT});
-		pass.newProducer({volRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
+		pass.newDependency({volRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
+		pass.newDependency({quarterDepthRt, TextureUsageBit::SAMPLED_FRAGMENT});
 
 		RenderTargetHandle volVBlurRt = descr.newRenderTarget(newRTDescr("Vol tmp"));
 		GraphicsRenderPassDescription& pass2 = descr.newGraphicsRenderPass("Vol vblur");
-		pass2.newConsumer({volRt, TextureUsageBit::SAMPLED_FRAGMENT});
-		pass2.newConsumer({volVBlurRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
-		pass2.newProducer({volVBlurRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
+		pass2.newDependency({volRt, TextureUsageBit::SAMPLED_FRAGMENT});
+		pass2.newDependency({volVBlurRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
 
 		GraphicsRenderPassDescription& pass3 = descr.newGraphicsRenderPass("Vol hblur");
-		pass3.newConsumer({volRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
-		pass3.newProducer({volRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
-		pass3.newConsumer({volVBlurRt, TextureUsageBit::SAMPLED_FRAGMENT});
+		pass3.newDependency({volRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
+		pass3.newDependency({volVBlurRt, TextureUsageBit::SAMPLED_FRAGMENT});
 	}
 
 	// Forward shading
 	RenderTargetHandle fsRt = descr.newRenderTarget(newRTDescr("FS"));
 	{
 		GraphicsRenderPassDescription& pass = descr.newGraphicsRenderPass("Forward shading");
-		pass.newConsumer({fsRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
-		pass.newProducer({fsRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
-		pass.newConsumer(
+		pass.newDependency({fsRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
+		pass.newDependency(
 			{halfDepthRt, TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ});
-		pass.newConsumer({volRt, TextureUsageBit::SAMPLED_FRAGMENT});
+		pass.newDependency({volRt, TextureUsageBit::SAMPLED_FRAGMENT});
 	}
 
 	// Light shading
@@ -1787,17 +1764,15 @@ ANKI_TEST(Gr, RenderGraph)
 	{
 		GraphicsRenderPassDescription& pass = descr.newGraphicsRenderPass("Light shading");
 
-		pass.newConsumer({lightRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
-		pass.newConsumer({gbuffRt0, TextureUsageBit::SAMPLED_FRAGMENT});
-		pass.newConsumer({gbuffRt1, TextureUsageBit::SAMPLED_FRAGMENT});
-		pass.newConsumer({gbuffRt2, TextureUsageBit::SAMPLED_FRAGMENT});
-		pass.newConsumer({gbuffDepth, TextureUsageBit::SAMPLED_FRAGMENT});
-		pass.newConsumer({smExpRt, TextureUsageBit::SAMPLED_FRAGMENT});
-		pass.newConsumer({giGiLightRt, TextureUsageBit::SAMPLED_FRAGMENT});
-		pass.newConsumer({ssaoRt, TextureUsageBit::SAMPLED_FRAGMENT});
-		pass.newConsumer({fsRt, TextureUsageBit::SAMPLED_FRAGMENT});
-
-		pass.newProducer({lightRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
+		pass.newDependency({lightRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
+		pass.newDependency({gbuffRt0, TextureUsageBit::SAMPLED_FRAGMENT});
+		pass.newDependency({gbuffRt1, TextureUsageBit::SAMPLED_FRAGMENT});
+		pass.newDependency({gbuffRt2, TextureUsageBit::SAMPLED_FRAGMENT});
+		pass.newDependency({gbuffDepth, TextureUsageBit::SAMPLED_FRAGMENT});
+		pass.newDependency({smExpRt, TextureUsageBit::SAMPLED_FRAGMENT});
+		pass.newDependency({giGiLightRt, TextureUsageBit::SAMPLED_FRAGMENT});
+		pass.newDependency({ssaoRt, TextureUsageBit::SAMPLED_FRAGMENT});
+		pass.newDependency({fsRt, TextureUsageBit::SAMPLED_FRAGMENT});
 	}
 
 	// TAA
@@ -1806,10 +1781,9 @@ ANKI_TEST(Gr, RenderGraph)
 	{
 		GraphicsRenderPassDescription& pass = descr.newGraphicsRenderPass("Temporal AA");
 
-		pass.newConsumer({lightRt, TextureUsageBit::SAMPLED_FRAGMENT});
-		pass.newConsumer({taaRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
-		pass.newProducer({taaRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
-		pass.newConsumer({taaHistoryRt, TextureUsageBit::SAMPLED_FRAGMENT});
+		pass.newDependency({lightRt, TextureUsageBit::SAMPLED_FRAGMENT});
+		pass.newDependency({taaRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
+		pass.newDependency({taaHistoryRt, TextureUsageBit::SAMPLED_FRAGMENT});
 	}
 
 	rgraph->compileNewGraph(descr, alloc);