Răsfoiți Sursa

Replace the callbacks in the rendergraph with Function<>

Panagiotis Christopoulos Charitos 4 ani în urmă
părinte
comite
8826e9c71c
56 a modificat fișierele cu 239 adăugiri și 532 ștergeri
  1. 3 6
      AnKi/Gr/RenderGraph.cpp
  2. 12 11
      AnKi/Gr/RenderGraph.h
  3. 4 11
      AnKi/Renderer/AccelerationStructureBuilder.cpp
  4. 0 2
      AnKi/Renderer/AccelerationStructureBuilder.h
  5. 31 41
      AnKi/Renderer/Bloom.cpp
  6. 0 3
      AnKi/Renderer/Bloom.h
  7. 28 36
      AnKi/Renderer/ClusterBinning.cpp
  8. 0 1
      AnKi/Renderer/ClusterBinning.h
  9. 4 0
      AnKi/Renderer/Common.h
  10. 2 7
      AnKi/Renderer/Dbg.cpp
  11. 0 1
      AnKi/Renderer/Dbg.h
  12. 5 9
      AnKi/Renderer/DepthDownscale.cpp
  13. 1 2
      AnKi/Renderer/DepthDownscale.h
  14. 3 13
      AnKi/Renderer/DownscaleBlur.cpp
  15. 1 2
      AnKi/Renderer/DownscaleBlur.h
  16. 1 7
      AnKi/Renderer/FinalComposite.cpp
  17. 0 6
      AnKi/Renderer/FinalComposite.h
  18. 3 9
      AnKi/Renderer/GBuffer.cpp
  19. 0 2
      AnKi/Renderer/GBuffer.h
  20. 2 6
      AnKi/Renderer/GBufferPost.cpp
  21. 1 7
      AnKi/Renderer/GBufferPost.h
  22. 9 16
      AnKi/Renderer/GenericCompute.cpp
  23. 1 7
      AnKi/Renderer/GenericCompute.h
  24. 8 26
      AnKi/Renderer/GlobalIllumination.cpp
  25. 1 1
      AnKi/Renderer/GlobalIllumination.h
  26. 1 7
      AnKi/Renderer/LensFlare.cpp
  27. 0 1
      AnKi/Renderer/LensFlare.h
  28. 3 6
      AnKi/Renderer/LightShading.cpp
  29. 1 2
      AnKi/Renderer/LightShading.h
  30. 19 26
      AnKi/Renderer/MainRenderer.cpp
  31. 0 3
      AnKi/Renderer/MainRenderer.h
  32. 2 7
      AnKi/Renderer/MotionVectors.cpp
  33. 1 2
      AnKi/Renderer/MotionVectors.h
  34. 7 31
      AnKi/Renderer/ProbeReflections.cpp
  35. 0 16
      AnKi/Renderer/ProbeReflections.h
  36. 6 0
      AnKi/Renderer/Renderer.cpp
  37. 17 43
      AnKi/Renderer/RtShadows.cpp
  38. 6 8
      AnKi/Renderer/RtShadows.h
  39. 2 12
      AnKi/Renderer/Scale.cpp
  40. 3 10
      AnKi/Renderer/ShadowMapping.cpp
  41. 2 6
      AnKi/Renderer/ShadowmapsResolve.cpp
  42. 1 2
      AnKi/Renderer/ShadowmapsResolve.h
  43. 4 25
      AnKi/Renderer/Ssao.cpp
  44. 0 1
      AnKi/Renderer/Ssao.h
  45. 5 16
      AnKi/Renderer/Ssgi.cpp
  46. 1 1
      AnKi/Renderer/Ssgi.h
  47. 2 5
      AnKi/Renderer/Ssr.cpp
  48. 1 2
      AnKi/Renderer/Ssr.h
  49. 17 25
      AnKi/Renderer/TemporalAA.cpp
  50. 0 3
      AnKi/Renderer/TemporalAA.h
  51. 12 20
      AnKi/Renderer/Tonemapping.cpp
  52. 0 2
      AnKi/Renderer/Tonemapping.h
  53. 2 7
      AnKi/Renderer/VolumetricFog.cpp
  54. 1 2
      AnKi/Renderer/VolumetricFog.h
  55. 2 7
      AnKi/Renderer/VolumetricLightingAccumulation.cpp
  56. 1 2
      AnKi/Renderer/VolumetricLightingAccumulation.h

+ 3 - 6
AnKi/Gr/RenderGraph.cpp

@@ -111,8 +111,7 @@ public:
 
 	DynamicArray<RenderPassDependency::TextureInfo> m_consumedTextures;
 
-	RenderPassWorkCallback m_callback;
-	void* m_userData;
+	Function<void(RenderPassWorkContext&)> m_callback;
 
 	DynamicArray<CommandBufferPtr> m_secondLevelCmdbs;
 	/// Will reuse the m_secondLevelCmdbInitInfo.m_framebuffer to get the framebuffer.
@@ -341,6 +340,7 @@ void RenderGraph::reset()
 	{
 		p.fb().reset(nullptr);
 		p.m_secondLevelCmdbs.destroy(m_ctx->m_alloc);
+		p.m_callback.destroy(m_ctx->m_alloc);
 	}
 
 	m_ctx->m_graphicsCmdbs.destroy(m_ctx->m_alloc);
@@ -756,8 +756,7 @@ void RenderGraph::initRenderPassesAndSetDeps(const RenderGraphDescription& descr
 		const RenderPassDescriptionBase& inPass = *descr.m_passes[passIdx];
 		Pass& outPass = ctx.m_passes[passIdx];
 
-		outPass.m_callback = inPass.m_callback;
-		outPass.m_userData = inPass.m_userData;
+		outPass.m_callback.copy(inPass.m_callback, alloc);
 
 		// Create consumer info
 		outPass.m_consumedTextures.resize(alloc, inPass.m_rtDeps.getSize());
@@ -1233,7 +1232,6 @@ void RenderGraph::runSecondLevel(U32 threadIdx)
 			ctx.m_secondLevelCommandBufferCount = size;
 			ctx.m_passIdx = U32(&p - &m_ctx->m_passes[0]);
 			ctx.m_batchIdx = p.m_batchIdx;
-			ctx.m_userData = p.m_userData;
 
 			ANKI_ASSERT(ctx.m_commandBuffer.isCreated());
 
@@ -1293,7 +1291,6 @@ void RenderGraph::run() const
 			const U size = pass.m_secondLevelCmdbs.getSize();
 			if(size == 0)
 			{
-				ctx.m_userData = pass.m_userData;
 				ctx.m_passIdx = passIdx;
 				ctx.m_batchIdx = pass.m_batchIdx;
 

+ 12 - 11
AnKi/Gr/RenderGraph.h

@@ -17,6 +17,7 @@
 #include <AnKi/Util/HashMap.h>
 #include <AnKi/Util/BitSet.h>
 #include <AnKi/Util/WeakArray.h>
+#include <AnKi/Util/Function.h>
 
 namespace anki
 {
@@ -118,7 +119,6 @@ class RenderPassWorkContext
 	friend class RenderGraph;
 
 public:
-	void* m_userData ANKI_DEBUG_CODE(= nullptr); ///< The userData passed in RenderPassDescriptionBase::setWork
 	CommandBufferPtr m_commandBuffer;
 	U32 m_currentSecondLevelCommandBufferIndex ANKI_DEBUG_CODE(= 0);
 	U32 m_secondLevelCommandBufferCount ANKI_DEBUG_CODE(= 0);
@@ -223,10 +223,6 @@ private:
 	TexturePtr getTexture(RenderTargetHandle handle) const;
 };
 
-/// Work callback for a RenderGraph pass.
-/// @memberof RenderGraphDescription
-using RenderPassWorkCallback = void (*)(RenderPassWorkContext& ctx);
-
 /// RenderGraph pass dependency.
 /// @memberof RenderGraphDescription
 class RenderPassDependency
@@ -322,17 +318,23 @@ public:
 		m_rtDeps.destroy(m_alloc);
 		m_buffDeps.destroy(m_alloc);
 		m_asDeps.destroy(m_alloc);
+		m_callback.destroy(m_alloc);
 	}
 
-	void setWork(RenderPassWorkCallback callback, void* userData, U32 secondLeveCmdbCount)
+	template<typename TFunc>
+	void setWork(U32 secondLeveCmdbCount, TFunc func)
 	{
-		ANKI_ASSERT(callback);
 		ANKI_ASSERT(m_type == Type::GRAPHICS || secondLeveCmdbCount == 0);
-		m_callback = callback;
-		m_userData = userData;
+		m_callback.init(m_alloc, func);
 		m_secondLevelCmdbsCount = secondLeveCmdbCount;
 	}
 
+	template<typename TFunc>
+	void setWork(TFunc func)
+	{
+		setWork(0, func);
+	}
+
 	/// Add a new consumer or producer dependency.
 	void newDependency(const RenderPassDependency& dep);
 
@@ -348,8 +350,7 @@ protected:
 	StackAllocator<U8> m_alloc;
 	RenderGraphDescription* m_descr;
 
-	RenderPassWorkCallback m_callback = nullptr;
-	void* m_userData = nullptr;
+	Function<void(RenderPassWorkContext&)> m_callback;
 	U32 m_secondLevelCmdbsCount = 0;
 
 	DynamicArray<RenderPassDependency> m_rtDeps;

+ 4 - 11
AnKi/Renderer/AccelerationStructureBuilder.cpp

@@ -57,19 +57,12 @@ void AccelerationStructureBuilder::populateRenderGraph(RenderingContext& ctx)
 	RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
 	m_runCtx.m_tlasHandle = rgraph.importAccelerationStructure(m_runCtx.m_tlas, AccelerationStructureUsageBit::NONE);
 	ComputeRenderPassDescription& rpass = rgraph.newComputeRenderPass("BuildTlas");
-	rpass.setWork(
-		[](RenderPassWorkContext& rgraphCtx) {
-			static_cast<AccelerationStructureBuilder*>(rgraphCtx.m_userData)->run(rgraphCtx);
-		},
-		this, 0);
+	rpass.setWork([this](RenderPassWorkContext& rgraphCtx) {
+		ANKI_TRACE_SCOPED_EVENT(R_TLAS);
+		rgraphCtx.m_commandBuffer->buildAccelerationStructure(m_runCtx.m_tlas);
+	});
 
 	rpass.newDependency(RenderPassDependency(m_runCtx.m_tlasHandle, AccelerationStructureUsageBit::BUILD));
 }
 
-void AccelerationStructureBuilder::run(RenderPassWorkContext& rgraphCtx)
-{
-	ANKI_TRACE_SCOPED_EVENT(R_TLAS);
-	rgraphCtx.m_commandBuffer->buildAccelerationStructure(m_runCtx.m_tlas);
-}
-
 } // end namespace anki

+ 0 - 2
AnKi/Renderer/AccelerationStructureBuilder.h

@@ -45,8 +45,6 @@ public:
 		AccelerationStructurePtr m_tlas;
 		AccelerationStructureHandle m_tlasHandle;
 	} m_runCtx;
-
-	void run(RenderPassWorkContext& rgraphCtx);
 };
 /// @}
 

+ 31 - 41
AnKi/Renderer/Bloom.cpp

@@ -92,14 +92,32 @@ void Bloom::populateRenderGraph(RenderingContext& ctx)
 
 		// Set the render pass
 		ComputeRenderPassDescription& rpass = rgraph.newComputeRenderPass("Bloom Main");
-		rpass.setWork(
-			[](RenderPassWorkContext& rgraphCtx) { static_cast<Bloom*>(rgraphCtx.m_userData)->runExposure(rgraphCtx); },
-			this, 0);
 
 		TextureSubresourceInfo inputTexSubresource;
 		inputTexSubresource.m_firstMipmap = m_r->getDownscaleBlur().getMipmapCount() - 1;
 		rpass.newDependency({m_r->getDownscaleBlur().getRt(), TextureUsageBit::SAMPLED_COMPUTE, inputTexSubresource});
 		rpass.newDependency({m_runCtx.m_exposureRt, TextureUsageBit::IMAGE_COMPUTE_WRITE});
+
+		rpass.setWork([this](RenderPassWorkContext& rgraphCtx) {
+			CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
+
+			cmdb->bindShaderProgram(m_exposure.m_grProg);
+
+			TextureSubresourceInfo inputTexSubresource;
+			inputTexSubresource.m_firstMipmap = m_r->getDownscaleBlur().getMipmapCount() - 1;
+
+			cmdb->bindSampler(0, 0, m_r->getSamplers().m_trilinearClamp);
+			rgraphCtx.bindTexture(0, 1, m_r->getDownscaleBlur().getRt(), inputTexSubresource);
+
+			Vec4 uniforms(m_exposure.m_threshold, m_exposure.m_scale, 0.0f, 0.0f);
+			cmdb->setPushConstants(&uniforms, sizeof(uniforms));
+
+			rgraphCtx.bindStorageBuffer(0, 2, m_r->getTonemapping().getAverageLuminanceBuffer());
+
+			rgraphCtx.bindImage(0, 3, m_runCtx.m_exposureRt, TextureSubresourceInfo());
+
+			dispatchPPCompute(cmdb, m_workgroupSize[0], m_workgroupSize[1], m_exposure.m_width, m_exposure.m_height);
+		});
 	}
 
 	// Upscale & SSLF pass
@@ -109,52 +127,24 @@ void Bloom::populateRenderGraph(RenderingContext& ctx)
 
 		// Set the render pass
 		ComputeRenderPassDescription& rpass = rgraph.newComputeRenderPass("Bloom Upscale");
-		rpass.setWork(
-			[](RenderPassWorkContext& rgraphCtx) {
-				static_cast<Bloom*>(rgraphCtx.m_userData)->runUpscaleAndSslf(rgraphCtx);
-			},
-			this, 0);
 
 		rpass.newDependency({m_runCtx.m_exposureRt, TextureUsageBit::SAMPLED_COMPUTE});
 		rpass.newDependency({m_runCtx.m_upscaleRt, TextureUsageBit::IMAGE_COMPUTE_WRITE});
-	}
-}
-
-void Bloom::runExposure(RenderPassWorkContext& rgraphCtx)
-{
-	CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
-
-	cmdb->bindShaderProgram(m_exposure.m_grProg);
-
-	TextureSubresourceInfo inputTexSubresource;
-	inputTexSubresource.m_firstMipmap = m_r->getDownscaleBlur().getMipmapCount() - 1;
 
-	cmdb->bindSampler(0, 0, m_r->getSamplers().m_trilinearClamp);
-	rgraphCtx.bindTexture(0, 1, m_r->getDownscaleBlur().getRt(), inputTexSubresource);
+		rpass.setWork([this](RenderPassWorkContext& rgraphCtx) {
+			CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
 
-	Vec4 uniforms(m_exposure.m_threshold, m_exposure.m_scale, 0.0f, 0.0f);
-	cmdb->setPushConstants(&uniforms, sizeof(uniforms));
+			cmdb->bindShaderProgram(m_upscale.m_grProg);
 
-	rgraphCtx.bindStorageBuffer(0, 2, m_r->getTonemapping().getAverageLuminanceBuffer());
+			cmdb->bindSampler(0, 0, m_r->getSamplers().m_trilinearClamp);
+			rgraphCtx.bindColorTexture(0, 1, m_runCtx.m_exposureRt);
+			cmdb->bindTexture(0, 2, m_upscale.m_lensDirtImage->getTextureView());
 
-	rgraphCtx.bindImage(0, 3, m_runCtx.m_exposureRt, TextureSubresourceInfo());
+			rgraphCtx.bindImage(0, 3, m_runCtx.m_upscaleRt, TextureSubresourceInfo());
 
-	dispatchPPCompute(cmdb, m_workgroupSize[0], m_workgroupSize[1], m_exposure.m_width, m_exposure.m_height);
-}
-
-void Bloom::runUpscaleAndSslf(RenderPassWorkContext& rgraphCtx)
-{
-	CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
-
-	cmdb->bindShaderProgram(m_upscale.m_grProg);
-
-	cmdb->bindSampler(0, 0, m_r->getSamplers().m_trilinearClamp);
-	rgraphCtx.bindColorTexture(0, 1, m_runCtx.m_exposureRt);
-	cmdb->bindTexture(0, 2, m_upscale.m_lensDirtImage->getTextureView());
-
-	rgraphCtx.bindImage(0, 3, m_runCtx.m_upscaleRt, TextureSubresourceInfo());
-
-	dispatchPPCompute(cmdb, m_workgroupSize[0], m_workgroupSize[1], m_upscale.m_width, m_upscale.m_height);
+			dispatchPPCompute(cmdb, m_workgroupSize[0], m_workgroupSize[1], m_upscale.m_width, m_upscale.m_height);
+		});
+	}
 }
 
 } // end namespace anki

+ 0 - 3
AnKi/Renderer/Bloom.h

@@ -110,9 +110,6 @@ private:
 		ANKI_CHECK(initUpscale(cfg));
 		return Error::NONE;
 	}
-
-	void runExposure(RenderPassWorkContext& rgraphCtx);
-	void runUpscaleAndSslf(RenderPassWorkContext& rgraphCtx);
 };
 
 /// @}

+ 28 - 36
AnKi/Renderer/ClusterBinning.cpp

@@ -53,14 +53,13 @@ Error ClusterBinning::init(const ConfigSet& config)
 void ClusterBinning::populateRenderGraph(RenderingContext& ctx)
 {
 	m_runCtx.m_ctx = &ctx;
-
 	writeClustererBuffers(ctx);
 
 	ctx.m_clusteredShading.m_clustersBufferHandle = ctx.m_renderGraphDescr.importBuffer(
 		ctx.m_clusteredShading.m_clustersToken.m_buffer, BufferUsageBit::NONE,
 		ctx.m_clusteredShading.m_clustersToken.m_offset, ctx.m_clusteredShading.m_clustersToken.m_range);
 
-	const RenderQueue& rqueue = *m_runCtx.m_ctx->m_renderQueue;
+	const RenderQueue& rqueue = *ctx.m_renderQueue;
 	if(ANKI_LIKELY(rqueue.m_pointLights.getSize() || rqueue.m_spotLights.getSize() || rqueue.m_decals.getSize()
 				   || rqueue.m_reflectionProbes.getSize() || rqueue.m_fogDensityVolumes.getSize()
 				   || rqueue.m_giProbes.getSize()))
@@ -68,43 +67,36 @@ void ClusterBinning::populateRenderGraph(RenderingContext& ctx)
 		RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
 		ComputeRenderPassDescription& pass = rgraph.newComputeRenderPass("Cluster Binning");
 
-		pass.setWork(
-			[](RenderPassWorkContext& rgraphCtx) {
-				static_cast<ClusterBinning*>(rgraphCtx.m_userData)->run(rgraphCtx);
-			},
-			this, 0);
-
 		pass.newDependency(
 			RenderPassDependency(ctx.m_clusteredShading.m_clustersBufferHandle, BufferUsageBit::STORAGE_COMPUTE_WRITE));
-	}
-}
 
-void ClusterBinning::run(RenderPassWorkContext& rgraphCtx)
-{
-	CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
-
-	const ClusteredShadingContext& tokens = m_runCtx.m_ctx->m_clusteredShading;
-
-	cmdb->bindShaderProgram(m_grProg);
-	bindUniforms(cmdb, 0, 0, tokens.m_clusteredShadingUniformsToken);
-	bindStorage(cmdb, 0, 1, tokens.m_clustersToken);
-	bindUniforms(cmdb, 0, 2, tokens.m_pointLightsToken);
-	bindUniforms(cmdb, 0, 3, tokens.m_spotLightsToken);
-	bindUniforms(cmdb, 0, 4, tokens.m_reflectionProbesToken);
-	bindUniforms(cmdb, 0, 5, tokens.m_globalIlluminationProbesToken);
-	bindUniforms(cmdb, 0, 6, tokens.m_fogDensityVolumesToken);
-	bindUniforms(cmdb, 0, 7, tokens.m_decalsToken);
-
-	const U32 sampleCount = 4;
-	const U32 sizex = m_tileCount * sampleCount;
-	const RenderQueue& rqueue = *m_runCtx.m_ctx->m_renderQueue;
-	U32 clusterObjectCounts = rqueue.m_pointLights.getSize();
-	clusterObjectCounts += rqueue.m_spotLights.getSize();
-	clusterObjectCounts += rqueue.m_reflectionProbes.getSize();
-	clusterObjectCounts += rqueue.m_giProbes.getSize();
-	clusterObjectCounts += rqueue.m_fogDensityVolumes.getSize();
-	clusterObjectCounts += rqueue.m_decals.getSize();
-	cmdb->dispatchCompute((sizex + 64 - 1) / 64, clusterObjectCounts, 1);
+		pass.setWork([this, &ctx](RenderPassWorkContext& rgraphCtx) {
+			CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
+
+			const ClusteredShadingContext& tokens = ctx.m_clusteredShading;
+
+			cmdb->bindShaderProgram(m_grProg);
+			bindUniforms(cmdb, 0, 0, tokens.m_clusteredShadingUniformsToken);
+			bindStorage(cmdb, 0, 1, tokens.m_clustersToken);
+			bindUniforms(cmdb, 0, 2, tokens.m_pointLightsToken);
+			bindUniforms(cmdb, 0, 3, tokens.m_spotLightsToken);
+			bindUniforms(cmdb, 0, 4, tokens.m_reflectionProbesToken);
+			bindUniforms(cmdb, 0, 5, tokens.m_globalIlluminationProbesToken);
+			bindUniforms(cmdb, 0, 6, tokens.m_fogDensityVolumesToken);
+			bindUniforms(cmdb, 0, 7, tokens.m_decalsToken);
+
+			const U32 sampleCount = 4;
+			const U32 sizex = m_tileCount * sampleCount;
+			const RenderQueue& rqueue = *ctx.m_renderQueue;
+			U32 clusterObjectCounts = rqueue.m_pointLights.getSize();
+			clusterObjectCounts += rqueue.m_spotLights.getSize();
+			clusterObjectCounts += rqueue.m_reflectionProbes.getSize();
+			clusterObjectCounts += rqueue.m_giProbes.getSize();
+			clusterObjectCounts += rqueue.m_fogDensityVolumes.getSize();
+			clusterObjectCounts += rqueue.m_decals.getSize();
+			cmdb->dispatchCompute((sizex + 64 - 1) / 64, clusterObjectCounts, 1);
+		});
+	}
 }
 
 void ClusterBinning::writeClustererBuffers(RenderingContext& ctx)

+ 0 - 1
AnKi/Renderer/ClusterBinning.h

@@ -43,7 +43,6 @@ private:
 		RenderingContext* m_ctx = nullptr;
 	} m_runCtx;
 
-	void run(RenderPassWorkContext& rgraphCtx);
 	void writeClustererBuffers(RenderingContext& ctx);
 	void writeClustererBuffersTask();
 };

+ 4 - 0
AnKi/Renderer/Common.h

@@ -142,6 +142,10 @@ public:
 		, m_renderGraphDescr(alloc)
 	{
 	}
+
+	RenderingContext(const RenderingContext&) = delete;
+
+	RenderingContext& operator=(const RenderingContext&) = delete;
 };
 
 /// A convenience function to find empty cache entries. Used for various probes.

+ 2 - 7
AnKi/Renderer/Dbg.cpp

@@ -177,7 +177,6 @@ void Dbg::populateRenderGraph(RenderingContext& ctx)
 		m_initialized = true;
 	}
 
-	m_runCtx.m_ctx = &ctx;
 	RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
 
 	// Create RT
@@ -186,12 +185,8 @@ void Dbg::populateRenderGraph(RenderingContext& ctx)
 	// Create pass
 	GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass("DBG");
 
-	pass.setWork(
-		[](RenderPassWorkContext& rgraphCtx) {
-			Dbg* self = static_cast<Dbg*>(rgraphCtx.m_userData);
-			self->run(rgraphCtx, *self->m_runCtx.m_ctx);
-		},
-		this, computeNumberOfSecondLevelCommandBuffers(ctx.m_renderQueue->m_renderables.getSize()));
+	pass.setWork(computeNumberOfSecondLevelCommandBuffers(ctx.m_renderQueue->m_renderables.getSize()),
+				 [this, &ctx](RenderPassWorkContext& rgraphCtx) { run(rgraphCtx, ctx); });
 
 	pass.setFramebufferInfo(m_fbDescr, {m_runCtx.m_rt}, m_r->getGBuffer().getDepthRt());
 

+ 0 - 1
AnKi/Renderer/Dbg.h

@@ -85,7 +85,6 @@ private:
 	{
 	public:
 		RenderTargetHandle m_rt;
-		RenderingContext* m_ctx = nullptr;
 	} m_runCtx;
 
 	ANKI_USE_RESULT Error lazyInit();

+ 5 - 9
AnKi/Renderer/DepthDownscale.cpp

@@ -103,11 +103,11 @@ void DepthDownscale::importRenderTargets(RenderingContext& ctx)
 void DepthDownscale::populateRenderGraph(RenderingContext& ctx)
 {
 	RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
-	m_runCtx.m_mip = 0;
 
 	static const Array<CString, 5> passNames = {"HiZ #0", "HiZ #1", "HiZ #2", "HiZ #3", "HiZ #4"};
 
 	// Every pass can do MIPS_WRITTEN_PER_PASS mips
+	U32 firstMipToWrite = 0;
 	for(U32 i = 0; i < m_mipCount; i += MIPS_WRITTEN_PER_PASS)
 	{
 		const U mipsToFill = (i + 1 < m_mipCount) ? MIPS_WRITTEN_PER_PASS : 1;
@@ -137,20 +137,16 @@ void DepthDownscale::populateRenderGraph(RenderingContext& ctx)
 			pass.newDependency({m_runCtx.m_hizRt, TextureUsageBit::IMAGE_COMPUTE_WRITE, subresource});
 		}
 
-		auto callback = [](RenderPassWorkContext& rgraphCtx) {
-			DepthDownscale* const self = static_cast<DepthDownscale*>(rgraphCtx.m_userData);
-			self->run(rgraphCtx);
-		};
-		pass.setWork(callback, this, 0);
+		pass.setWork([this, firstMipToWrite](RenderPassWorkContext& rgraphCtx) { run(firstMipToWrite, rgraphCtx); });
+		firstMipToWrite += MIPS_WRITTEN_PER_PASS;
 	}
 }
 
-void DepthDownscale::run(RenderPassWorkContext& rgraphCtx)
+void DepthDownscale::run(U32 mipToWrite, RenderPassWorkContext& rgraphCtx)
 {
 	CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
 
-	const U32 level = m_runCtx.m_mip;
-	m_runCtx.m_mip += MIPS_WRITTEN_PER_PASS;
+	const U32 level = mipToWrite;
 	const U32 mipsToFill = (level + 1 < m_mipCount) ? MIPS_WRITTEN_PER_PASS : 1;
 	const U32 copyToClientLevel = (level + mipsToFill == m_mipCount) ? mipsToFill - 1 : MAX_U32;
 

+ 1 - 2
AnKi/Renderer/DepthDownscale.h

@@ -66,7 +66,6 @@ private:
 	{
 	public:
 		RenderTargetHandle m_hizRt;
-		U32 m_mip;
 	} m_runCtx; ///< Run context.
 
 	class
@@ -79,7 +78,7 @@ private:
 
 	ANKI_USE_RESULT Error initInternal(const ConfigSet& cfg);
 
-	void run(RenderPassWorkContext& rgraphCtx);
+	void run(U32 mipToWrite, RenderPassWorkContext& rgraphCtx);
 };
 /// @}
 

+ 3 - 13
AnKi/Renderer/DownscaleBlur.cpp

@@ -92,7 +92,6 @@ void DownscaleBlur::importRenderTargets(RenderingContext& ctx)
 void DownscaleBlur::populateRenderGraph(RenderingContext& ctx)
 {
 	RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
-	m_runCtx.m_crntPassIdx = 0;
 
 	// Create passes
 	static const Array<CString, 8> passNames = {"DownBlur #0",  "Down/Blur #1", "Down/Blur #2", "Down/Blur #3",
@@ -102,11 +101,7 @@ void DownscaleBlur::populateRenderGraph(RenderingContext& ctx)
 		for(U32 i = 0; i < m_passCount; ++i)
 		{
 			ComputeRenderPassDescription& pass = rgraph.newComputeRenderPass(passNames[i]);
-			pass.setWork(
-				[](RenderPassWorkContext& rgraphCtx) {
-					static_cast<DownscaleBlur*>(rgraphCtx.m_userData)->run(rgraphCtx);
-				},
-				this, 0);
+			pass.setWork([this, i](RenderPassWorkContext& rgraphCtx) { run(i, rgraphCtx); });
 
 			if(i > 0)
 			{
@@ -133,11 +128,7 @@ void DownscaleBlur::populateRenderGraph(RenderingContext& ctx)
 		for(U32 i = 0; i < m_passCount; ++i)
 		{
 			GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass(passNames[i]);
-			pass.setWork(
-				[](RenderPassWorkContext& rgraphCtx) {
-					static_cast<DownscaleBlur*>(rgraphCtx.m_userData)->run(rgraphCtx);
-				},
-				this, 0);
+			pass.setWork([this, i](RenderPassWorkContext& rgraphCtx) { run(i, rgraphCtx); });
 			pass.setFramebufferInfo(m_fbDescrs[i], {m_runCtx.m_rt}, {});
 
 			if(i > 0)
@@ -162,13 +153,12 @@ void DownscaleBlur::populateRenderGraph(RenderingContext& ctx)
 	}
 }
 
-void DownscaleBlur::run(RenderPassWorkContext& rgraphCtx)
+void DownscaleBlur::run(U32 passIdx, RenderPassWorkContext& rgraphCtx)
 {
 	CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
 
 	cmdb->bindShaderProgram(m_grProg);
 
-	const U32 passIdx = m_runCtx.m_crntPassIdx++;
 	const U32 vpWidth = m_rtTex->getWidth() >> passIdx;
 	const U32 vpHeight = m_rtTex->getHeight() >> passIdx;
 

+ 1 - 2
AnKi/Renderer/DownscaleBlur.h

@@ -69,13 +69,12 @@ private:
 	{
 	public:
 		RenderTargetHandle m_rt;
-		U32 m_crntPassIdx = MAX_U32;
 	} m_runCtx;
 
 	ANKI_USE_RESULT Error initInternal(const ConfigSet& cfg);
 	ANKI_USE_RESULT Error initSubpass(U idx, const UVec2& inputTexSize);
 
-	void run(RenderPassWorkContext& rgraphCtx);
+	void run(U32 passIdx, RenderPassWorkContext& rgraphCtx);
 };
 /// @}
 

+ 1 - 7
AnKi/Renderer/FinalComposite.cpp

@@ -95,17 +95,11 @@ Error FinalComposite::loadColorGradingTextureImage(CString filename)
 void FinalComposite::populateRenderGraph(RenderingContext& ctx)
 {
 	RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
-	m_runCtx.m_ctx = &ctx;
 
 	// Create the pass
 	GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass("Final Composite");
 
-	pass.setWork(
-		[](RenderPassWorkContext& rgraphCtx) {
-			FinalComposite* self = static_cast<FinalComposite*>(rgraphCtx.m_userData);
-			self->run(*self->m_runCtx.m_ctx, rgraphCtx);
-		},
-		this, 0);
+	pass.setWork([this, &ctx](RenderPassWorkContext& rgraphCtx) { run(ctx, rgraphCtx); });
 	pass.setFramebufferInfo(m_fbDescr, {ctx.m_outRenderTarget}, {});
 
 	pass.newDependency({ctx.m_outRenderTarget, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});

+ 0 - 6
AnKi/Renderer/FinalComposite.h

@@ -43,12 +43,6 @@ private:
 	ImageResourcePtr m_lut; ///< Color grading lookup texture.
 	ImageResourcePtr m_blueNoise;
 
-	class
-	{
-	public:
-		RenderingContext* m_ctx = nullptr;
-	} m_runCtx;
-
 	ANKI_USE_RESULT Error initInternal(const ConfigSet& config);
 
 	void run(RenderingContext& ctx, RenderPassWorkContext& rgraphCtx);

+ 3 - 9
AnKi/Renderer/GBuffer.cpp

@@ -148,7 +148,6 @@ void GBuffer::populateRenderGraph(RenderingContext& ctx)
 {
 	ANKI_TRACE_SCOPED_EVENT(R_MS);
 
-	m_runCtx.m_ctx = &ctx;
 	RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
 
 	// Create RTs
@@ -179,14 +178,9 @@ void GBuffer::populateRenderGraph(RenderingContext& ctx)
 
 	pass.setFramebufferInfo(m_fbDescr, ConstWeakArray<RenderTargetHandle>(&rts[0], GBUFFER_COLOR_ATTACHMENT_COUNT),
 							m_runCtx.m_crntFrameDepthRt);
-	pass.setWork(
-		[](RenderPassWorkContext& rgraphCtx) {
-			GBuffer* self = static_cast<GBuffer*>(rgraphCtx.m_userData);
-			self->runInThread(*self->m_runCtx.m_ctx, rgraphCtx);
-		},
-		this,
-		computeNumberOfSecondLevelCommandBuffers(ctx.m_renderQueue->m_earlyZRenderables.getSize()
-												 + ctx.m_renderQueue->m_renderables.getSize()));
+	pass.setWork(computeNumberOfSecondLevelCommandBuffers(ctx.m_renderQueue->m_earlyZRenderables.getSize()
+														  + ctx.m_renderQueue->m_renderables.getSize()),
+				 [this, &ctx](RenderPassWorkContext& rgraphCtx) { runInThread(ctx, rgraphCtx); });
 
 	for(U i = 0; i < GBUFFER_COLOR_ATTACHMENT_COUNT; ++i)
 	{

+ 0 - 2
AnKi/Renderer/GBuffer.h

@@ -77,8 +77,6 @@ private:
 	class
 	{
 	public:
-		RenderingContext* m_ctx = nullptr;
-
 		Array<RenderTargetHandle, GBUFFER_COLOR_ATTACHMENT_COUNT> m_colorRts;
 		RenderTargetHandle m_crntFrameDepthRt;
 		RenderTargetHandle m_prevFrameDepthRt;

+ 2 - 6
AnKi/Renderer/GBufferPost.cpp

@@ -54,14 +54,11 @@ Error GBufferPost::initInternal(const ConfigSet& cfg)
 void GBufferPost::populateRenderGraph(RenderingContext& ctx)
 {
 	RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
-	m_runCtx.m_ctx = &ctx;
 
 	// Create pass
 	GraphicsRenderPassDescription& rpass = rgraph.newGraphicsRenderPass("GBuffPost");
 
-	rpass.setWork(
-		[](RenderPassWorkContext& rgraphCtx) { static_cast<GBufferPost*>(rgraphCtx.m_userData)->run(rgraphCtx); }, this,
-		0);
+	rpass.setWork([this, &ctx](RenderPassWorkContext& rgraphCtx) { run(ctx, rgraphCtx); });
 
 	rpass.setFramebufferInfo(m_fbDescr, {m_r->getGBuffer().getColorRt(0), m_r->getGBuffer().getColorRt(1)}, {});
 
@@ -75,9 +72,8 @@ void GBufferPost::populateRenderGraph(RenderingContext& ctx)
 		RenderPassDependency(ctx.m_clusteredShading.m_clustersBufferHandle, BufferUsageBit::STORAGE_FRAGMENT_READ));
 }
 
-void GBufferPost::run(RenderPassWorkContext& rgraphCtx)
+void GBufferPost::run(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx)
 {
-	const RenderingContext& ctx = *m_runCtx.m_ctx;
 	const ClusteredShadingContext& rsrc = ctx.m_clusteredShading;
 	CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
 

+ 1 - 7
AnKi/Renderer/GBufferPost.h

@@ -35,15 +35,9 @@ private:
 
 	FramebufferDescription m_fbDescr;
 
-	class
-	{
-	public:
-		RenderingContext* m_ctx ANKI_DEBUG_CODE(= nullptr);
-	} m_runCtx;
-
 	ANKI_USE_RESULT Error initInternal(const ConfigSet& cfg);
 
-	void run(RenderPassWorkContext& rgraphCtx);
+	void run(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx);
 };
 /// @}
 

+ 9 - 16
AnKi/Renderer/GenericCompute.cpp

@@ -22,37 +22,30 @@ void GenericCompute::populateRenderGraph(RenderingContext& ctx)
 		return;
 	}
 
-	m_runCtx.m_ctx = &ctx;
-
 	ComputeRenderPassDescription& pass = ctx.m_renderGraphDescr.newComputeRenderPass("Generic compute");
 
-	pass.setWork(
-		[](RenderPassWorkContext& rgraphCtx) {
-			GenericCompute* const self = static_cast<GenericCompute*>(rgraphCtx.m_userData);
-			self->run(rgraphCtx);
-		},
-		this, 0);
+	pass.setWork([this, &ctx](RenderPassWorkContext& rgraphCtx) { run(ctx, rgraphCtx); });
 
 	pass.newDependency({m_r->getDepthDownscale().getHiZRt(), TextureUsageBit::SAMPLED_COMPUTE});
 }
 
-void GenericCompute::run(RenderPassWorkContext& rgraphCtx)
+void GenericCompute::run(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx)
 {
-	ANKI_ASSERT(m_runCtx.m_ctx->m_renderQueue->m_genericGpuComputeJobs.getSize() > 0);
+	ANKI_ASSERT(ctx.m_renderQueue->m_genericGpuComputeJobs.getSize() > 0);
 
 	GenericGpuComputeJobQueueElementContext elementCtx;
 	elementCtx.m_commandBuffer = rgraphCtx.m_commandBuffer;
 	elementCtx.m_stagingGpuAllocator = &m_r->getStagingGpuMemoryManager();
-	elementCtx.m_viewMatrix = m_runCtx.m_ctx->m_matrices.m_view;
-	elementCtx.m_viewProjectionMatrix = m_runCtx.m_ctx->m_matrices.m_viewProjection;
-	elementCtx.m_projectionMatrix = m_runCtx.m_ctx->m_matrices.m_projection;
-	elementCtx.m_previousViewProjectionMatrix = m_runCtx.m_ctx->m_prevMatrices.m_viewProjection;
-	elementCtx.m_cameraTransform = m_runCtx.m_ctx->m_matrices.m_cameraTransform;
+	elementCtx.m_viewMatrix = ctx.m_matrices.m_view;
+	elementCtx.m_viewProjectionMatrix = ctx.m_matrices.m_viewProjection;
+	elementCtx.m_projectionMatrix = ctx.m_matrices.m_projection;
+	elementCtx.m_previousViewProjectionMatrix = ctx.m_prevMatrices.m_viewProjection;
+	elementCtx.m_cameraTransform = ctx.m_matrices.m_cameraTransform;
 
 	// Bind some state
 	rgraphCtx.bindTexture(0, 0, m_r->getDepthDownscale().getHiZRt(), TextureSubresourceInfo());
 
-	for(const GenericGpuComputeJobQueueElement& element : m_runCtx.m_ctx->m_renderQueue->m_genericGpuComputeJobs)
+	for(const GenericGpuComputeJobQueueElement& element : ctx.m_renderQueue->m_genericGpuComputeJobs)
 	{
 		ANKI_ASSERT(element.m_callback);
 		element.m_callback(elementCtx, element.m_userData);

+ 1 - 7
AnKi/Renderer/GenericCompute.h

@@ -34,13 +34,7 @@ public:
 	void populateRenderGraph(RenderingContext& ctx);
 
 private:
-	class
-	{
-	public:
-		const RenderingContext* m_ctx = nullptr;
-	} m_runCtx;
-
-	void run(RenderPassWorkContext& rgraphCtx);
+	void run(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx);
 };
 /// @}
 

+ 8 - 26
AnKi/Renderer/GlobalIllumination.cpp

@@ -71,7 +71,7 @@ GlobalIllumination::getVolumeRenderTarget(const GlobalIlluminationProbeQueueElem
 	return m_giCtx->m_irradianceProbeRts[idx];
 }
 
-void GlobalIllumination::setRenderGraphDependencies(RenderingContext& ctx, RenderPassDescriptionBase& pass,
+void GlobalIllumination::setRenderGraphDependencies(const RenderingContext& ctx, RenderPassDescriptionBase& pass,
 													TextureUsageBit usage) const
 {
 	for(U32 idx = 0; idx < ctx.m_renderQueue->m_giProbes.getSize(); ++idx)
@@ -241,10 +241,10 @@ void GlobalIllumination::populateRenderGraph(RenderingContext& rctx)
 	ANKI_TRACE_SCOPED_EVENT(R_GI);
 
 	InternalContext* giCtx = rctx.m_tempAllocator.newInstance<InternalContext>();
+	m_giCtx = giCtx;
 	giCtx->m_gi = this;
 	giCtx->m_ctx = &rctx;
 	RenderGraphDescription& rgraph = rctx.m_renderGraphDescr;
-	m_giCtx = giCtx;
 
 	// Prepare the probes
 	prepareProbes(*giCtx);
@@ -287,12 +287,8 @@ void GlobalIllumination::populateRenderGraph(RenderingContext& rctx)
 		// Pass
 		GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass("GI gbuff");
 		pass.setFramebufferInfo(m_gbuffer.m_fbDescr, giCtx->m_gbufferColorRts, giCtx->m_gbufferDepthRt);
-		pass.setWork(
-			[](RenderPassWorkContext& rgraphCtx) {
-				InternalContext* giCtx = static_cast<InternalContext*>(rgraphCtx.m_userData);
-				giCtx->m_gi->runGBufferInThread(rgraphCtx, *giCtx);
-			},
-			giCtx, gbufferTaskCount);
+		pass.setWork(gbufferTaskCount,
+					 [this, giCtx](RenderPassWorkContext& rgraphCtx) { runGBufferInThread(rgraphCtx, *giCtx); });
 
 		for(U i = 0; i < GBUFFER_COLOR_ATTACHMENT_COUNT; ++i)
 		{
@@ -332,12 +328,8 @@ void GlobalIllumination::populateRenderGraph(RenderingContext& rctx)
 		// Pass
 		GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass("GI SM");
 		pass.setFramebufferInfo(m_shadowMapping.m_fbDescr, {}, giCtx->m_shadowsRt);
-		pass.setWork(
-			[](RenderPassWorkContext& rgraphCtx) {
-				InternalContext* giCtx = static_cast<InternalContext*>(rgraphCtx.m_userData);
-				giCtx->m_gi->runShadowmappingInThread(rgraphCtx, *giCtx);
-			},
-			giCtx, smTaskCount);
+		pass.setWork(smTaskCount,
+					 [this, giCtx](RenderPassWorkContext& rgraphCtx) { runShadowmappingInThread(rgraphCtx, *giCtx); });
 
 		TextureSubresourceInfo subresource(DepthStencilAspectBit::DEPTH);
 		pass.newDependency({giCtx->m_shadowsRt, TextureUsageBit::ALL_FRAMEBUFFER_ATTACHMENT, subresource});
@@ -355,12 +347,7 @@ void GlobalIllumination::populateRenderGraph(RenderingContext& rctx)
 		// Pass
 		GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass("GI LS");
 		pass.setFramebufferInfo(m_lightShading.m_fbDescr, {{giCtx->m_lightShadingRt}}, {});
-		pass.setWork(
-			[](RenderPassWorkContext& rgraphCtx) {
-				InternalContext* giCtx = static_cast<InternalContext*>(rgraphCtx.m_userData);
-				giCtx->m_gi->runLightShading(rgraphCtx, *giCtx);
-			},
-			giCtx, 1);
+		pass.setWork(1, [this, giCtx](RenderPassWorkContext& rgraphCtx) { runLightShading(rgraphCtx, *giCtx); });
 
 		pass.newDependency({giCtx->m_lightShadingRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
 
@@ -381,12 +368,7 @@ void GlobalIllumination::populateRenderGraph(RenderingContext& rctx)
 	{
 		ComputeRenderPassDescription& pass = rgraph.newComputeRenderPass("GI IR");
 
-		pass.setWork(
-			[](RenderPassWorkContext& rgraphCtx) {
-				InternalContext* giCtx = static_cast<InternalContext*>(rgraphCtx.m_userData);
-				giCtx->m_gi->runIrradiance(rgraphCtx, *giCtx);
-			},
-			giCtx, 0);
+		pass.setWork([this, giCtx](RenderPassWorkContext& rgraphCtx) { runIrradiance(rgraphCtx, *giCtx); });
 
 		pass.newDependency({giCtx->m_lightShadingRt, TextureUsageBit::SAMPLED_COMPUTE});
 

+ 1 - 1
AnKi/Renderer/GlobalIllumination.h

@@ -39,7 +39,7 @@ public:
 	const RenderTargetHandle& getVolumeRenderTarget(const GlobalIlluminationProbeQueueElement& probe) const;
 
 	/// Set the render graph dependencies.
-	void setRenderGraphDependencies(RenderingContext& ctx, RenderPassDescriptionBase& pass,
+	void setRenderGraphDependencies(const RenderingContext& ctx, RenderPassDescriptionBase& pass,
 									TextureUsageBit usage) const;
 
 	/// Bind the volume textures to a command buffer.

+ 1 - 7
AnKi/Renderer/LensFlare.cpp

@@ -115,7 +115,6 @@ void LensFlare::populateRenderGraph(RenderingContext& ctx)
 		return;
 	}
 
-	m_runCtx.m_ctx = &ctx;
 	RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
 
 	// Import buffer
@@ -125,12 +124,7 @@ void LensFlare::populateRenderGraph(RenderingContext& ctx)
 	{
 		ComputeRenderPassDescription& rpass = rgraph.newComputeRenderPass("LF Upd Ind/ct");
 
-		rpass.setWork(
-			[](RenderPassWorkContext& rgraphCtx) {
-				LensFlare* const self = static_cast<LensFlare*>(rgraphCtx.m_userData);
-				self->updateIndirectInfo(*self->m_runCtx.m_ctx, rgraphCtx);
-			},
-			this, 0);
+		rpass.setWork([this, &ctx](RenderPassWorkContext& rgraphCtx) { updateIndirectInfo(ctx, rgraphCtx); });
 
 		rpass.newDependency({m_runCtx.m_indirectBuffHandle, BufferUsageBit::STORAGE_COMPUTE_WRITE});
 		rpass.newDependency({m_r->getDepthDownscale().getHiZRt(), TextureUsageBit::SAMPLED_COMPUTE, HIZ_QUARTER_DEPTH});

+ 0 - 1
AnKi/Renderer/LensFlare.h

@@ -54,7 +54,6 @@ private:
 	class
 	{
 	public:
-		RenderingContext* m_ctx = nullptr;
 		BufferHandle m_indirectBuffHandle;
 	} m_runCtx;
 

+ 3 - 6
AnKi/Renderer/LightShading.cpp

@@ -104,9 +104,8 @@ Error LightShading::initApplyFog(const ConfigSet& config)
 	return Error::NONE;
 }
 
-void LightShading::run(RenderPassWorkContext& rgraphCtx)
+void LightShading::run(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx)
 {
-	const RenderingContext& ctx = *m_runCtx.m_ctx;
 	CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
 
 	cmdb->setViewport(0, 0, m_r->getInternalResolution().x(), m_r->getInternalResolution().y());
@@ -198,7 +197,6 @@ void LightShading::run(RenderPassWorkContext& rgraphCtx)
 
 void LightShading::populateRenderGraph(RenderingContext& ctx)
 {
-	m_runCtx.m_ctx = &ctx;
 	RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
 
 	// Create RT
@@ -207,9 +205,8 @@ void LightShading::populateRenderGraph(RenderingContext& ctx)
 	// Create pass
 	GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass("Light&FW Shad.");
 
-	pass.setWork(
-		[](RenderPassWorkContext& rgraphCtx) { static_cast<LightShading*>(rgraphCtx.m_userData)->run(rgraphCtx); },
-		this, computeNumberOfSecondLevelCommandBuffers(ctx.m_renderQueue->m_forwardShadingRenderables.getSize()));
+	pass.setWork(computeNumberOfSecondLevelCommandBuffers(ctx.m_renderQueue->m_forwardShadingRenderables.getSize()),
+				 [this, &ctx](RenderPassWorkContext& rgraphCtx) { run(ctx, rgraphCtx); });
 	pass.setFramebufferInfo(m_lightShading.m_fbDescr, {{m_runCtx.m_rt}}, {m_r->getGBuffer().getDepthRt()});
 
 	// Light shading

+ 1 - 2
AnKi/Renderer/LightShading.h

@@ -54,13 +54,12 @@ private:
 	{
 	public:
 		RenderTargetHandle m_rt;
-		RenderingContext* m_ctx;
 	} m_runCtx; ///< Run context.
 
 	ANKI_USE_RESULT Error initLightShading(const ConfigSet& config);
 	ANKI_USE_RESULT Error initApplyFog(const ConfigSet& config);
 
-	void run(RenderPassWorkContext& rgraphCtx);
+	void run(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx);
 };
 /// @}
 

+ 19 - 26
AnKi/Renderer/MainRenderer.cpp

@@ -57,9 +57,12 @@ Error MainRenderer::init(ThreadHive* hive, ResourceManager* resources, GrManager
 		m_blitGrProg = variant->getProgram();
 
 		// The RT desc
-		m_tmpRtDesc = m_r->create2DRenderTargetDescription(U32(F32(m_swapchainResolution.x()) * m_renderScaling),
-														   U32(F32(m_swapchainResolution.y()) * m_renderScaling),
-														   Format::R8G8B8_UNORM, "Final Composite");
+		const Vec2 fresolution = Vec2(F32(config.getNumberU32("width")), F32(config.getNumberU32("height")));
+		UVec2 resolution = UVec2(fresolution * m_renderScaling);
+		alignRoundDown(2, resolution.x());
+		alignRoundDown(2, resolution.y());
+		m_tmpRtDesc = m_r->create2DRenderTargetDescription(resolution.x(), resolution.y(), Format::R8G8B8_UNORM,
+														   "Final Composite");
 		m_tmpRtDesc.bake();
 
 		// FB descr
@@ -121,12 +124,16 @@ Error MainRenderer::render(RenderQueue& rqueue, TexturePtr presentTex)
 		GraphicsRenderPassDescription& pass = ctx.m_renderGraphDescr.newGraphicsRenderPass("Final Blit");
 
 		pass.setFramebufferInfo(m_fbDescr, {{presentRt}}, {});
-		pass.setWork(
-			[](RenderPassWorkContext& rgraphCtx) {
-				MainRenderer* const self = static_cast<MainRenderer*>(rgraphCtx.m_userData);
-				self->runBlit(rgraphCtx);
-			},
-			this, 0);
+		pass.setWork([this](RenderPassWorkContext& rgraphCtx) {
+			CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
+			cmdb->setViewport(0, 0, m_swapchainResolution.x(), m_swapchainResolution.y());
+
+			cmdb->bindShaderProgram(m_blitGrProg);
+			cmdb->bindSampler(0, 0, m_r->getSamplers().m_trilinearClamp);
+			rgraphCtx.bindColorTexture(0, 1, m_runCtx.m_ctx->m_outRenderTarget);
+
+			cmdb->drawArrays(PrimitiveTopology::TRIANGLES, 3, 1);
+		});
 
 		pass.newDependency({presentRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
 		pass.newDependency({ctx.m_outRenderTarget, TextureUsageBit::SAMPLED_FRAGMENT});
@@ -136,11 +143,9 @@ Error MainRenderer::render(RenderQueue& rqueue, TexturePtr presentTex)
 	{
 		ComputeRenderPassDescription& pass = ctx.m_renderGraphDescr.newComputeRenderPass("Present");
 
-		pass.setWork(
-			[](RenderPassWorkContext& rgraphCtx) {
-				// Do nothing. This pass is dummy
-			},
-			nullptr, 0);
+		pass.setWork([](RenderPassWorkContext& rgraphCtx) {
+			// Do nothing. This pass is dummy
+		});
 		pass.newDependency({presentRt, TextureUsageBit::PRESENT});
 	}
 
@@ -186,18 +191,6 @@ Error MainRenderer::render(RenderQueue& rqueue, TexturePtr presentTex)
 	return Error::NONE;
 }
 
-void MainRenderer::runBlit(RenderPassWorkContext& rgraphCtx)
-{
-	CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
-	cmdb->setViewport(0, 0, m_swapchainResolution.x(), m_swapchainResolution.y());
-
-	cmdb->bindShaderProgram(m_blitGrProg);
-	cmdb->bindSampler(0, 0, m_r->getSamplers().m_trilinearClamp);
-	rgraphCtx.bindColorTexture(0, 1, m_runCtx.m_ctx->m_outRenderTarget);
-
-	cmdb->drawArrays(PrimitiveTopology::TRIANGLES, 3, 1);
-}
-
 Dbg& MainRenderer::getDbg()
 {
 	return m_r->getDbg();

+ 0 - 3
AnKi/Renderer/MainRenderer.h

@@ -94,9 +94,6 @@ private:
 		const RenderingContext* m_ctx = nullptr;
 		Atomic<U32> m_secondaryTaskId = {0};
 	} m_runCtx;
-
-	void runBlit(RenderPassWorkContext& rgraphCtx);
-	void present(RenderPassWorkContext& rgraphCtx);
 };
 /// @}
 

+ 2 - 7
AnKi/Renderer/MotionVectors.cpp

@@ -41,7 +41,6 @@ Error MotionVectors::init(const ConfigSet& config)
 
 void MotionVectors::populateRenderGraph(RenderingContext& ctx)
 {
-	m_runCtx.m_ctx = &ctx;
 	RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
 
 	m_runCtx.m_motionVectorsRtHandle = rgraph.newRenderTarget(m_motionVectorsRtDescr);
@@ -49,10 +48,7 @@ void MotionVectors::populateRenderGraph(RenderingContext& ctx)
 
 	ComputeRenderPassDescription& pass = rgraph.newComputeRenderPass("Motion vectors");
 
-	auto callback = [](RenderPassWorkContext& rgraphCtx) -> void {
-		static_cast<MotionVectors*>(rgraphCtx.m_userData)->run(rgraphCtx);
-	};
-	pass.setWork(callback, this, 0);
+	pass.setWork([this, &ctx](RenderPassWorkContext& rgraphCtx) -> void { run(ctx, rgraphCtx); });
 
 	pass.newDependency({m_runCtx.m_motionVectorsRtHandle, TextureUsageBit::IMAGE_COMPUTE_WRITE});
 	pass.newDependency({m_runCtx.m_rejectionFactorRtHandle, TextureUsageBit::IMAGE_COMPUTE_WRITE});
@@ -61,9 +57,8 @@ void MotionVectors::populateRenderGraph(RenderingContext& ctx)
 	pass.newDependency({m_r->getGBuffer().getPreviousFrameDepthRt(), TextureUsageBit::SAMPLED_COMPUTE});
 }
 
-void MotionVectors::run(RenderPassWorkContext& rgraphCtx)
+void MotionVectors::run(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx)
 {
-	RenderingContext& ctx = *m_runCtx.m_ctx;
 	CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
 
 	cmdb->bindShaderProgram(m_grProg);

+ 1 - 2
AnKi/Renderer/MotionVectors.h

@@ -64,12 +64,11 @@ private:
 	class
 	{
 	public:
-		RenderingContext* m_ctx = nullptr;
 		RenderTargetHandle m_motionVectorsRtHandle;
 		RenderTargetHandle m_rejectionFactorRtHandle;
 	} m_runCtx;
 
-	void run(RenderPassWorkContext& rgraphCtx);
+	void run(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx);
 };
 /// @}
 

+ 7 - 31
AnKi/Renderer/ProbeReflections.cpp

@@ -552,11 +552,7 @@ void ProbeReflections::populateRenderGraph(RenderingContext& rctx)
 		// Pass
 		GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass("CubeRefl gbuff");
 		pass.setFramebufferInfo(m_gbuffer.m_fbDescr, rts, m_ctx.m_gbufferDepthRt);
-		pass.setWork(
-			[](RenderPassWorkContext& rgraphCtx) {
-				static_cast<ProbeReflections*>(rgraphCtx.m_userData)->runGBuffer(rgraphCtx);
-			},
-			this, taskCount);
+		pass.setWork(taskCount, [this](RenderPassWorkContext& rgraphCtx) { runGBuffer(rgraphCtx); });
 
 		for(U i = 0; i < GBUFFER_COLOR_ATTACHMENT_COUNT; ++i)
 		{
@@ -603,11 +599,7 @@ void ProbeReflections::populateRenderGraph(RenderingContext& rctx)
 		// Pass
 		GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass("CubeRefl SM");
 		pass.setFramebufferInfo(m_shadowMapping.m_fbDescr, {}, m_ctx.m_shadowMapRt);
-		pass.setWork(
-			[](RenderPassWorkContext& rgraphCtx) {
-				static_cast<ProbeReflections*>(rgraphCtx.m_userData)->runShadowMapping(rgraphCtx);
-			},
-			this, taskCount);
+		pass.setWork(taskCount, [this](RenderPassWorkContext& rgraphCtx) { runShadowMapping(rgraphCtx); });
 
 		TextureSubresourceInfo subresource(DepthStencilAspectBit::DEPTH);
 		pass.newDependency({m_ctx.m_shadowMapRt, TextureUsageBit::ALL_FRAMEBUFFER_ATTACHMENT, subresource});
@@ -619,10 +611,6 @@ void ProbeReflections::populateRenderGraph(RenderingContext& rctx)
 
 	// Light shading passes
 	{
-		Array<RenderPassWorkCallback, 6> callbacks = {runLightShadingCallback<0>, runLightShadingCallback<1>,
-													  runLightShadingCallback<2>, runLightShadingCallback<3>,
-													  runLightShadingCallback<4>, runLightShadingCallback<5>};
-
 		// RT
 		m_ctx.m_lightShadingRt = rgraph.importRenderTarget(m_lightShading.m_cubeArr, TextureUsageBit::SAMPLED_FRAGMENT);
 
@@ -635,7 +623,7 @@ void ProbeReflections::populateRenderGraph(RenderingContext& rctx)
 			GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass(passNames[faceIdx]);
 			pass.setFramebufferInfo(m_cacheEntries[probeToUpdateCacheEntryIdx].m_lightShadingFbDescrs[faceIdx],
 									{{m_ctx.m_lightShadingRt}}, {});
-			pass.setWork(callbacks[faceIdx], this, 0);
+			pass.setWork([this, faceIdx](RenderPassWorkContext& rgraphCtx) { runLightShading(faceIdx, rgraphCtx); });
 
 			TextureSubresourceInfo subresource(TextureSurfaceInfo(0, 0, faceIdx, probeToUpdateCacheEntryIdx));
 			pass.newDependency({m_ctx.m_lightShadingRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE, subresource});
@@ -661,11 +649,7 @@ void ProbeReflections::populateRenderGraph(RenderingContext& rctx)
 
 		ComputeRenderPassDescription& pass = rgraph.newComputeRenderPass("CubeRefl Irradiance");
 
-		pass.setWork(
-			[](RenderPassWorkContext& rgraphCtx) {
-				static_cast<ProbeReflections*>(rgraphCtx.m_userData)->runIrradiance(rgraphCtx);
-			},
-			this, 0);
+		pass.setWork([this](RenderPassWorkContext& rgraphCtx) { runIrradiance(rgraphCtx); });
 
 		// Read a cube but only one layer and level
 		TextureSubresourceInfo readSubresource;
@@ -680,11 +664,7 @@ void ProbeReflections::populateRenderGraph(RenderingContext& rctx)
 	{
 		ComputeRenderPassDescription& pass = rgraph.newComputeRenderPass("CubeRefl apply indirect");
 
-		pass.setWork(
-			[](RenderPassWorkContext& rgraphCtx) {
-				static_cast<ProbeReflections*>(rgraphCtx.m_userData)->runIrradianceToRefl(rgraphCtx);
-			},
-			this, 0);
+		pass.setWork([this](RenderPassWorkContext& rgraphCtx) { runIrradianceToRefl(rgraphCtx); });
 
 		for(U i = 0; i < GBUFFER_COLOR_ATTACHMENT_COUNT - 1; ++i)
 		{
@@ -702,17 +682,13 @@ void ProbeReflections::populateRenderGraph(RenderingContext& rctx)
 
 	// Mipmapping "passes"
 	{
-		static const Array<RenderPassWorkCallback, 6> callbacks = {
-			{runMipmappingOfLightShadingCallback<0>, runMipmappingOfLightShadingCallback<1>,
-			 runMipmappingOfLightShadingCallback<2>, runMipmappingOfLightShadingCallback<3>,
-			 runMipmappingOfLightShadingCallback<4>, runMipmappingOfLightShadingCallback<5>}};
-
 		static const Array<CString, 6> passNames = {"CubeRefl Mip #0", "CubeRefl Mip #1", "CubeRefl Mip #2",
 													"CubeRefl Mip #3", "CubeRefl Mip #4", "CubeRefl Mip #5"};
 		for(U32 faceIdx = 0; faceIdx < 6; ++faceIdx)
 		{
 			GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass(passNames[faceIdx]);
-			pass.setWork(callbacks[faceIdx], this, 0);
+			pass.setWork(
+				[this, faceIdx](RenderPassWorkContext& rgraphCtx) { runMipmappingOfLightShading(faceIdx, rgraphCtx); });
 
 			TextureSubresourceInfo subresource(TextureSurfaceInfo(0, 0, faceIdx, probeToUpdateCacheEntryIdx));
 			subresource.m_mipmapCount = m_lightShading.m_mipCount;

+ 0 - 16
AnKi/Renderer/ProbeReflections.h

@@ -151,22 +151,6 @@ private:
 	void runMipmappingOfLightShading(U32 faceIdx, RenderPassWorkContext& rgraphCtx);
 	void runIrradiance(RenderPassWorkContext& rgraphCtx);
 	void runIrradianceToRefl(RenderPassWorkContext& rgraphCtx);
-
-	// A RenderPassWorkCallback for the light shading pass into a single face.
-	template<U faceIdx>
-	static void runLightShadingCallback(RenderPassWorkContext& rgraphCtx)
-	{
-		ProbeReflections* const self = static_cast<ProbeReflections*>(rgraphCtx.m_userData);
-		self->runLightShading(faceIdx, rgraphCtx);
-	}
-
-	// A RenderPassWorkCallback for the mipmapping of light shading result.
-	template<U faceIdx>
-	static void runMipmappingOfLightShadingCallback(RenderPassWorkContext& rgraphCtx)
-	{
-		ProbeReflections* const self = static_cast<ProbeReflections*>(rgraphCtx.m_userData);
-		self->runMipmappingOfLightShading(faceIdx, rgraphCtx);
-	}
 };
 /// @}
 

+ 6 - 0
AnKi/Renderer/Renderer.cpp

@@ -93,7 +93,13 @@ Error Renderer::initInternal(const ConfigSet& config)
 
 	const Vec2 fresolution = Vec2(F32(config.getNumberU32("width")), F32(config.getNumberU32("height")));
 	m_postProcessResolution = UVec2(fresolution * renderScaling);
+	alignRoundDown(2, m_postProcessResolution.x());
+	alignRoundDown(2, m_postProcessResolution.y());
+
 	m_internalResolution = UVec2(fresolution * internalRenderScaling);
+	alignRoundDown(2, m_internalResolution.x());
+	alignRoundDown(2, m_internalResolution.y());
+
 	ANKI_R_LOGI("Initializing offscreen renderer. Size %ux%u. Internal size %ux%u", m_postProcessResolution.x(),
 				m_postProcessResolution.y(), m_internalResolution.x(), m_internalResolution.y());
 

+ 17 - 43
AnKi/Renderer/RtShadows.cpp

@@ -203,9 +203,8 @@ void RtShadows::populateRenderGraph(RenderingContext& ctx)
 	ANKI_TRACE_SCOPED_EVENT(R_RT_SHADOWS);
 
 	RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
-	m_runCtx.m_ctx = &ctx;
 
-	buildSbt();
+	buildSbt(ctx);
 	const U32 prevRtIdx = m_r->getFrameCount() & 1;
 
 	// Import RTs
@@ -264,9 +263,7 @@ void RtShadows::populateRenderGraph(RenderingContext& ctx)
 	// RT shadows pass
 	{
 		ComputeRenderPassDescription& rpass = rgraph.newComputeRenderPass("RtShadows");
-		rpass.setWork(
-			[](RenderPassWorkContext& rgraphCtx) { static_cast<RtShadows*>(rgraphCtx.m_userData)->run(rgraphCtx); },
-			this, 0);
+		rpass.setWork([this, &ctx](RenderPassWorkContext& rgraphCtx) { run(ctx, rgraphCtx); });
 
 		rpass.newDependency(RenderPassDependency(m_runCtx.m_historyRt, TextureUsageBit::SAMPLED_TRACE_RAYS));
 		rpass.newDependency(
@@ -296,11 +293,7 @@ void RtShadows::populateRenderGraph(RenderingContext& ctx)
 	if(!m_useSvgf)
 	{
 		ComputeRenderPassDescription& rpass = rgraph.newComputeRenderPass("RtShadows Denoise Horizontal");
-		rpass.setWork(
-			[](RenderPassWorkContext& rgraphCtx) {
-				static_cast<RtShadows*>(rgraphCtx.m_userData)->runDenoise(rgraphCtx);
-			},
-			this, 0);
+		rpass.setWork([this, &ctx](RenderPassWorkContext& rgraphCtx) { runDenoise(ctx, rgraphCtx); });
 
 		rpass.newDependency(
 			RenderPassDependency(m_runCtx.m_intermediateShadowsRts[0], TextureUsageBit::SAMPLED_COMPUTE));
@@ -317,11 +310,7 @@ void RtShadows::populateRenderGraph(RenderingContext& ctx)
 	if(!m_useSvgf)
 	{
 		ComputeRenderPassDescription& rpass = rgraph.newComputeRenderPass("RtShadows Denoise Vertical");
-		rpass.setWork(
-			[](RenderPassWorkContext& rgraphCtx) {
-				static_cast<RtShadows*>(rgraphCtx.m_userData)->runDenoise(rgraphCtx);
-			},
-			this, 0);
+		rpass.setWork([this, &ctx](RenderPassWorkContext& rgraphCtx) { runDenoise(ctx, rgraphCtx); });
 
 		rpass.newDependency(
 			RenderPassDependency(m_runCtx.m_intermediateShadowsRts[1], TextureUsageBit::SAMPLED_COMPUTE));
@@ -337,11 +326,7 @@ void RtShadows::populateRenderGraph(RenderingContext& ctx)
 	if(m_useSvgf)
 	{
 		ComputeRenderPassDescription& rpass = rgraph.newComputeRenderPass("RtShadows SVGF Variance");
-		rpass.setWork(
-			[](RenderPassWorkContext& rgraphCtx) {
-				static_cast<RtShadows*>(rgraphCtx.m_userData)->runSvgfVariance(rgraphCtx);
-			},
-			this, 0);
+		rpass.setWork([this, &ctx](RenderPassWorkContext& rgraphCtx) { runSvgfVariance(ctx, rgraphCtx); });
 
 		rpass.newDependency(
 			RenderPassDependency(m_runCtx.m_intermediateShadowsRts[0], TextureUsageBit::SAMPLED_COMPUTE));
@@ -370,11 +355,7 @@ void RtShadows::populateRenderGraph(RenderingContext& ctx)
 			atrousWriteRtIdx = !readRtIdx;
 
 			ComputeRenderPassDescription& rpass = rgraph.newComputeRenderPass("RtShadows SVGF Atrous");
-			rpass.setWork(
-				[](RenderPassWorkContext& rgraphCtx) {
-					static_cast<RtShadows*>(rgraphCtx.m_userData)->runSvgfAtrous(rgraphCtx);
-				},
-				this, 0);
+			rpass.setWork([this, &ctx](RenderPassWorkContext& rgraphCtx) { runSvgfAtrous(ctx, rgraphCtx); });
 
 			rpass.newDependency(depthDependency);
 			rpass.newDependency(
@@ -402,11 +383,7 @@ void RtShadows::populateRenderGraph(RenderingContext& ctx)
 	// Upscale
 	{
 		ComputeRenderPassDescription& rpass = rgraph.newComputeRenderPass("RtShadows Upscale");
-		rpass.setWork(
-			[](RenderPassWorkContext& rgraphCtx) {
-				static_cast<RtShadows*>(rgraphCtx.m_userData)->runUpscale(rgraphCtx);
-			},
-			this, 0);
+		rpass.setWork([this, &ctx](RenderPassWorkContext& rgraphCtx) { runUpscale(ctx, rgraphCtx); });
 
 		rpass.newDependency(RenderPassDependency(m_runCtx.m_historyRt, TextureUsageBit::SAMPLED_COMPUTE));
 		rpass.newDependency(RenderPassDependency(m_r->getGBuffer().getDepthRt(), TextureUsageBit::SAMPLED_COMPUTE));
@@ -417,7 +394,7 @@ void RtShadows::populateRenderGraph(RenderingContext& ctx)
 
 	// Find out the lights that will take part in RT pass
 	{
-		RenderQueue& rqueue = *m_runCtx.m_ctx->m_renderQueue;
+		RenderQueue& rqueue = *ctx.m_renderQueue;
 		m_runCtx.m_layersWithRejectedHistory.unsetAll();
 
 		if(rqueue.m_directionalLight.hasShadow())
@@ -483,9 +460,8 @@ void RtShadows::populateRenderGraph(RenderingContext& ctx)
 	}
 }
 
-void RtShadows::run(RenderPassWorkContext& rgraphCtx)
+void RtShadows::run(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx)
 {
-	const RenderingContext& ctx = *m_runCtx.m_ctx;
 	CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
 	const ClusteredShadingContext& rsrc = ctx.m_clusteredShading;
 
@@ -530,7 +506,7 @@ void RtShadows::run(RenderPassWorkContext& rgraphCtx)
 					m_r->getInternalResolution().x() / 2, m_r->getInternalResolution().y() / 2, 1);
 }
 
-void RtShadows::runDenoise(RenderPassWorkContext& rgraphCtx)
+void RtShadows::runDenoise(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx)
 {
 	CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
 
@@ -548,7 +524,7 @@ void RtShadows::runDenoise(RenderPassWorkContext& rgraphCtx)
 		0, 7, (m_runCtx.m_denoiseOrientation == 0) ? m_runCtx.m_intermediateShadowsRts[1] : m_runCtx.m_historyRt);
 
 	RtShadowsDenoiseUniforms unis;
-	unis.invViewProjMat = m_runCtx.m_ctx->m_matrices.m_invertedViewProjectionJitter;
+	unis.invViewProjMat = ctx.m_matrices.m_invertedViewProjectionJitter;
 	unis.time = F32(m_r->getGlobalTimestamp());
 	cmdb->setPushConstants(&unis, sizeof(unis));
 
@@ -557,7 +533,7 @@ void RtShadows::runDenoise(RenderPassWorkContext& rgraphCtx)
 	m_runCtx.m_denoiseOrientation = !m_runCtx.m_denoiseOrientation;
 }
 
-void RtShadows::runSvgfVariance(RenderPassWorkContext& rgraphCtx)
+void RtShadows::runSvgfVariance(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx)
 {
 	CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
 
@@ -574,13 +550,13 @@ void RtShadows::runSvgfVariance(RenderPassWorkContext& rgraphCtx)
 	rgraphCtx.bindImage(0, 6, m_runCtx.m_intermediateShadowsRts[1]);
 	rgraphCtx.bindImage(0, 7, m_runCtx.m_varianceRts[1]);
 
-	const Mat4& invProjMat = m_runCtx.m_ctx->m_matrices.m_projectionJitter.getInverse();
+	const Mat4& invProjMat = ctx.m_matrices.m_projectionJitter.getInverse();
 	cmdb->setPushConstants(&invProjMat, sizeof(invProjMat));
 
 	dispatchPPCompute(cmdb, 8, 8, m_r->getInternalResolution().x() / 2, m_r->getInternalResolution().y() / 2);
 }
 
-void RtShadows::runSvgfAtrous(RenderPassWorkContext& rgraphCtx)
+void RtShadows::runSvgfAtrous(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx)
 {
 	CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
 
@@ -613,7 +589,7 @@ void RtShadows::runSvgfAtrous(RenderPassWorkContext& rgraphCtx)
 		rgraphCtx.bindImage(0, 5, m_runCtx.m_historyRt);
 	}
 
-	const Mat4& invProjMat = m_runCtx.m_ctx->m_matrices.m_projectionJitter.getInverse();
+	const Mat4& invProjMat = ctx.m_matrices.m_projectionJitter.getInverse();
 	cmdb->setPushConstants(&invProjMat, sizeof(invProjMat));
 
 	dispatchPPCompute(cmdb, 8, 8, m_r->getInternalResolution().x() / 2, m_r->getInternalResolution().y() / 2);
@@ -621,7 +597,7 @@ void RtShadows::runSvgfAtrous(RenderPassWorkContext& rgraphCtx)
 	++m_runCtx.m_atrousPassIdx;
 }
 
-void RtShadows::runUpscale(RenderPassWorkContext& rgraphCtx)
+void RtShadows::runUpscale(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx)
 {
 	CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
 
@@ -638,11 +614,9 @@ void RtShadows::runUpscale(RenderPassWorkContext& rgraphCtx)
 	dispatchPPCompute(cmdb, 8, 8, m_r->getInternalResolution().x(), m_r->getInternalResolution().y());
 }
 
-void RtShadows::buildSbt()
+void RtShadows::buildSbt(RenderingContext& ctx)
 {
 	// Get some things
-	RenderingContext& ctx = *m_runCtx.m_ctx;
-
 	ANKI_ASSERT(ctx.m_renderQueue->m_rayTracingQueue);
 	ConstWeakArray<RayTracingInstanceQueueElement> instanceElements =
 		ctx.m_renderQueue->m_rayTracingQueue->m_rayTracingInstances;

+ 6 - 8
AnKi/Renderer/RtShadows.h

@@ -102,8 +102,6 @@ public:
 	class
 	{
 	public:
-		RenderingContext* m_ctx = nullptr;
-
 		Array<RenderTargetHandle, 2> m_intermediateShadowsRts;
 		RenderTargetHandle m_historyRt;
 		RenderTargetHandle m_upscaledRt;
@@ -128,13 +126,13 @@ public:
 
 	ANKI_USE_RESULT Error initInternal(const ConfigSet& cfg);
 
-	void run(RenderPassWorkContext& rgraphCtx);
-	void runDenoise(RenderPassWorkContext& rgraphCtx);
-	void runSvgfVariance(RenderPassWorkContext& rgraphCtx);
-	void runSvgfAtrous(RenderPassWorkContext& rgraphCtx);
-	void runUpscale(RenderPassWorkContext& rgraphCtx);
+	void run(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx);
+	void runDenoise(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx);
+	void runSvgfVariance(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx);
+	void runSvgfAtrous(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx);
+	void runUpscale(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx);
 
-	void buildSbt();
+	void buildSbt(RenderingContext& ctx);
 
 	Bool findShadowLayer(U64 lightUuid, U32& layerIdx, Bool& rejectHistoryBuffer);
 

+ 2 - 12
AnKi/Renderer/Scale.cpp

@@ -98,12 +98,7 @@ void Scale::populateRenderGraph(RenderingContext& ctx)
 			RenderPassDependency(m_r->getTemporalAA().getTonemappedRt(), TextureUsageBit::SAMPLED_COMPUTE));
 		pass.newDependency(RenderPassDependency(m_runCtx.m_scaledRt, TextureUsageBit::IMAGE_COMPUTE_WRITE));
 
-		pass.setWork(
-			[](RenderPassWorkContext& rgraphCtx) {
-				Scale* const self = static_cast<Scale*>(rgraphCtx.m_userData);
-				self->runScaling(rgraphCtx);
-			},
-			this, 0);
+		pass.setWork([this](RenderPassWorkContext& rgraphCtx) { runScaling(rgraphCtx); });
 	}
 
 	if(doSharpening())
@@ -118,12 +113,7 @@ void Scale::populateRenderGraph(RenderingContext& ctx)
 								 TextureUsageBit::SAMPLED_COMPUTE));
 		pass.newDependency(RenderPassDependency(m_runCtx.m_sharpenedRt, TextureUsageBit::IMAGE_COMPUTE_WRITE));
 
-		pass.setWork(
-			[](RenderPassWorkContext& rgraphCtx) {
-				Scale* const self = static_cast<Scale*>(rgraphCtx.m_userData);
-				self->runSharpening(rgraphCtx);
-			},
-			this, 0);
+		pass.setWork([this](RenderPassWorkContext& rgraphCtx) { runSharpening(rgraphCtx); });
 	}
 }
 

+ 3 - 10
AnKi/Renderer/ShadowMapping.cpp

@@ -236,11 +236,8 @@ void ShadowMapping::populateRenderGraph(RenderingContext& ctx)
 			pass.setFramebufferInfo(m_scratch.m_fbDescr, {}, m_scratch.m_rt, minx, miny, width, height);
 			ANKI_ASSERT(threadCountForScratchPass
 						&& threadCountForScratchPass <= m_r->getThreadHive().getThreadCount());
-			pass.setWork(
-				[](RenderPassWorkContext& rgraphCtx) {
-					static_cast<ShadowMapping*>(rgraphCtx.m_userData)->runShadowMapping(rgraphCtx);
-				},
-				this, threadCountForScratchPass);
+			pass.setWork(threadCountForScratchPass,
+						 [this](RenderPassWorkContext& rgraphCtx) { runShadowMapping(rgraphCtx); });
 
 			TextureSubresourceInfo subresource = TextureSubresourceInfo(DepthStencilAspectBit::DEPTH);
 			pass.newDependency({m_scratch.m_rt, TextureUsageBit::ALL_FRAMEBUFFER_ATTACHMENT, subresource});
@@ -251,11 +248,7 @@ void ShadowMapping::populateRenderGraph(RenderingContext& ctx)
 			ComputeRenderPassDescription& pass = rgraph.newComputeRenderPass("SM atlas");
 
 			m_atlas.m_rt = rgraph.importRenderTarget(m_atlas.m_tex, TextureUsageBit::SAMPLED_FRAGMENT);
-			pass.setWork(
-				[](RenderPassWorkContext& rgraphCtx) {
-					static_cast<ShadowMapping*>(rgraphCtx.m_userData)->runAtlas(rgraphCtx);
-				},
-				this, 0);
+			pass.setWork([this](RenderPassWorkContext& rgraphCtx) { runAtlas(rgraphCtx); });
 
 			pass.newDependency({m_scratch.m_rt, TextureUsageBit::SAMPLED_COMPUTE,
 								TextureSubresourceInfo(DepthStencilAspectBit::DEPTH)});

+ 2 - 6
AnKi/Renderer/ShadowmapsResolve.cpp

@@ -54,13 +54,10 @@ Error ShadowmapsResolve::initInternal(const ConfigSet& cfg)
 void ShadowmapsResolve::populateRenderGraph(RenderingContext& ctx)
 {
 	RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
-	m_runCtx.m_ctx = &ctx;
 	m_runCtx.m_rt = rgraph.newRenderTarget(m_rtDescr);
 
 	ComputeRenderPassDescription& rpass = rgraph.newComputeRenderPass("SM resolve");
-	rpass.setWork(
-		[](RenderPassWorkContext& rgraphCtx) { static_cast<ShadowmapsResolve*>(rgraphCtx.m_userData)->run(rgraphCtx); },
-		this, 0);
+	rpass.setWork([this, &ctx](RenderPassWorkContext& rgraphCtx) { run(ctx, rgraphCtx); });
 
 	rpass.newDependency(RenderPassDependency(m_runCtx.m_rt, TextureUsageBit::IMAGE_COMPUTE_WRITE));
 	rpass.newDependency(RenderPassDependency(m_r->getGBuffer().getDepthRt(), TextureUsageBit::SAMPLED_COMPUTE));
@@ -71,9 +68,8 @@ void ShadowmapsResolve::populateRenderGraph(RenderingContext& ctx)
 		RenderPassDependency(ctx.m_clusteredShading.m_clustersBufferHandle, BufferUsageBit::STORAGE_COMPUTE_READ));
 }
 
-void ShadowmapsResolve::run(RenderPassWorkContext& rgraphCtx)
+void ShadowmapsResolve::run(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx)
 {
-	const RenderingContext& ctx = *m_runCtx.m_ctx;
 	CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
 	const ClusteredShadingContext& rsrc = ctx.m_clusteredShading;
 

+ 1 - 2
AnKi/Renderer/ShadowmapsResolve.h

@@ -52,12 +52,11 @@ public:
 	{
 	public:
 		RenderTargetHandle m_rt;
-		RenderingContext* m_ctx = nullptr;
 	} m_runCtx;
 
 	ANKI_USE_RESULT Error initInternal(const ConfigSet& cfg);
 
-	void run(RenderPassWorkContext& rgraphCtx);
+	void run(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx);
 };
 /// @}
 

+ 4 - 25
AnKi/Renderer/Ssao.cpp

@@ -191,7 +191,6 @@ void Ssao::runBlur(RenderPassWorkContext& rgraphCtx)
 
 void Ssao::populateRenderGraph(RenderingContext& ctx)
 {
-	m_runCtx.m_ctx = &ctx;
 	RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
 
 	// Create RTs
@@ -212,12 +211,7 @@ void Ssao::populateRenderGraph(RenderingContext& ctx)
 			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(
-				[](RenderPassWorkContext& rgraphCtx) {
-					Ssao* const self = static_cast<Ssao*>(rgraphCtx.m_userData);
-					self->runMain(*self->m_runCtx.m_ctx, rgraphCtx);
-				},
-				this, 0);
+			pass.setWork([this, &ctx](RenderPassWorkContext& rgraphCtx) { runMain(ctx, rgraphCtx); });
 		}
 		else
 		{
@@ -234,12 +228,7 @@ void Ssao::populateRenderGraph(RenderingContext& ctx)
 				{m_r->getDepthDownscale().getHiZRt(), TextureUsageBit::SAMPLED_FRAGMENT, HIZ_HALF_DEPTH});
 			pass.newDependency({m_runCtx.m_rts[0], TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
 
-			pass.setWork(
-				[](RenderPassWorkContext& rgraphCtx) {
-					Ssao* const self = static_cast<Ssao*>(rgraphCtx.m_userData);
-					self->runMain(*self->m_runCtx.m_ctx, rgraphCtx);
-				},
-				this, 0);
+			pass.setWork([this, &ctx](RenderPassWorkContext& rgraphCtx) { runMain(ctx, rgraphCtx); });
 		}
 	}
 
@@ -249,12 +238,7 @@ void Ssao::populateRenderGraph(RenderingContext& ctx)
 		{
 			ComputeRenderPassDescription& pass = rgraph.newComputeRenderPass("SSAO blur");
 
-			pass.setWork(
-				[](RenderPassWorkContext& rgraphCtx) {
-					Ssao* const self = static_cast<Ssao*>(rgraphCtx.m_userData);
-					self->runBlur(rgraphCtx);
-				},
-				this, 0);
+			pass.setWork([this](RenderPassWorkContext& rgraphCtx) { runBlur(rgraphCtx); });
 
 			pass.newDependency({m_runCtx.m_rts[1], TextureUsageBit::IMAGE_COMPUTE_WRITE});
 			pass.newDependency({m_runCtx.m_rts[0], TextureUsageBit::SAMPLED_COMPUTE});
@@ -263,12 +247,7 @@ void Ssao::populateRenderGraph(RenderingContext& ctx)
 		{
 			GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass("SSAO blur");
 
-			pass.setWork(
-				[](RenderPassWorkContext& rgraphCtx) {
-					Ssao* const self = static_cast<Ssao*>(rgraphCtx.m_userData);
-					self->runBlur(rgraphCtx);
-				},
-				this, 0);
+			pass.setWork([this](RenderPassWorkContext& rgraphCtx) { runBlur(rgraphCtx); });
 			pass.setFramebufferInfo(m_fbDescr, {{m_runCtx.m_rts[1]}}, {});
 
 			pass.newDependency({m_runCtx.m_rts[1], TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});

+ 0 - 1
AnKi/Renderer/Ssao.h

@@ -66,7 +66,6 @@ private:
 	{
 	public:
 		Array<RenderTargetHandle, 2> m_rts;
-		const RenderingContext* m_ctx = nullptr;
 	} m_runCtx; ///< Runtime context.
 
 	Array<RenderTargetDescription, 2> m_rtDescrs;

+ 5 - 16
AnKi/Renderer/Ssgi.cpp

@@ -135,9 +135,7 @@ void Ssgi::populateRenderGraph(RenderingContext& ctx)
 
 		// Create pass
 		ComputeRenderPassDescription& rpass = rgraph.newComputeRenderPass("SSGI");
-		rpass.setWork(
-			[](RenderPassWorkContext& rgraphCtx) { static_cast<Ssgi*>(rgraphCtx.m_userData)->run(rgraphCtx); }, this,
-			0);
+		rpass.setWork([this, &ctx](RenderPassWorkContext& rgraphCtx) { run(ctx, rgraphCtx); });
 
 		rpass.newDependency({m_runCtx.m_intermediateRts[WRITE], TextureUsageBit::IMAGE_COMPUTE_WRITE});
 		rpass.newDependency({m_runCtx.m_finalRt, TextureUsageBit::SAMPLED_COMPUTE});
@@ -160,9 +158,7 @@ void Ssgi::populateRenderGraph(RenderingContext& ctx)
 		rpass.newDependency({m_r->getGBuffer().getColorRt(2), TextureUsageBit::SAMPLED_COMPUTE});
 		rpass.newDependency({m_r->getGBuffer().getDepthRt(), TextureUsageBit::SAMPLED_COMPUTE});
 
-		rpass.setWork(
-			[](RenderPassWorkContext& rgraphCtx) { static_cast<Ssgi*>(rgraphCtx.m_userData)->runVBlur(rgraphCtx); },
-			this, 0);
+		rpass.setWork([this](RenderPassWorkContext& rgraphCtx) { runVBlur(rgraphCtx); });
 	}
 
 	// Blur horizontal
@@ -174,9 +170,7 @@ void Ssgi::populateRenderGraph(RenderingContext& ctx)
 		rpass.newDependency({m_r->getGBuffer().getColorRt(2), TextureUsageBit::SAMPLED_COMPUTE});
 		rpass.newDependency({m_r->getGBuffer().getDepthRt(), TextureUsageBit::SAMPLED_COMPUTE});
 
-		rpass.setWork(
-			[](RenderPassWorkContext& rgraphCtx) { static_cast<Ssgi*>(rgraphCtx.m_userData)->runHBlur(rgraphCtx); },
-			this, 0);
+		rpass.setWork([this](RenderPassWorkContext& rgraphCtx) { runHBlur(rgraphCtx); });
 	}
 
 	// Reconstruction
@@ -188,17 +182,12 @@ void Ssgi::populateRenderGraph(RenderingContext& ctx)
 		rpass.newDependency({m_r->getGBuffer().getDepthRt(), TextureUsageBit::SAMPLED_COMPUTE});
 		rpass.newDependency({m_r->getGBuffer().getColorRt(2), TextureUsageBit::SAMPLED_COMPUTE});
 
-		rpass.setWork(
-			[](RenderPassWorkContext& rgraphCtx) {
-				static_cast<Ssgi*>(rgraphCtx.m_userData)->runRecontruct(rgraphCtx);
-			},
-			this, 0);
+		rpass.setWork([this](RenderPassWorkContext& rgraphCtx) { runRecontruct(rgraphCtx); });
 	}
 }
 
-void Ssgi::run(RenderPassWorkContext& rgraphCtx)
+void Ssgi::run(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx)
 {
-	RenderingContext& ctx = *m_runCtx.m_ctx;
 	CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
 	cmdb->bindShaderProgram(m_main.m_grProg[m_r->getFrameCount() % 4]);
 

+ 1 - 1
AnKi/Renderer/Ssgi.h

@@ -83,7 +83,7 @@ private:
 
 	ANKI_USE_RESULT Error initInternal(const ConfigSet& cfg);
 
-	void run(RenderPassWorkContext& rgraphCtx);
+	void run(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx);
 	void runVBlur(RenderPassWorkContext& rgraphCtx);
 	void runHBlur(RenderPassWorkContext& rgraphCtx);
 	void runRecontruct(RenderPassWorkContext& rgraphCtx);

+ 2 - 5
AnKi/Renderer/Ssr.cpp

@@ -70,15 +70,13 @@ Error Ssr::initInternal(const ConfigSet& cfg)
 void Ssr::populateRenderGraph(RenderingContext& ctx)
 {
 	RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
-	m_runCtx.m_ctx = &ctx;
 
 	// Create RTs
 	m_runCtx.m_rt = rgraph.importRenderTarget(m_rt, TextureUsageBit::SAMPLED_FRAGMENT);
 
 	// Create pass
 	ComputeRenderPassDescription& rpass = rgraph.newComputeRenderPass("SSR");
-	rpass.setWork([](RenderPassWorkContext& rgraphCtx) { static_cast<Ssr*>(rgraphCtx.m_userData)->run(rgraphCtx); },
-				  this, 0);
+	rpass.setWork([this, &ctx](RenderPassWorkContext& rgraphCtx) { run(ctx, rgraphCtx); });
 
 	rpass.newDependency({m_runCtx.m_rt, TextureUsageBit::IMAGE_COMPUTE_READ | TextureUsageBit::IMAGE_COMPUTE_WRITE});
 	rpass.newDependency({m_r->getGBuffer().getColorRt(1), TextureUsageBit::SAMPLED_COMPUTE});
@@ -91,9 +89,8 @@ void Ssr::populateRenderGraph(RenderingContext& ctx)
 	rpass.newDependency({m_r->getDownscaleBlur().getRt(), TextureUsageBit::SAMPLED_COMPUTE});
 }
 
-void Ssr::run(RenderPassWorkContext& rgraphCtx)
+void Ssr::run(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx)
 {
-	RenderingContext& ctx = *m_runCtx.m_ctx;
 	CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
 	cmdb->bindShaderProgram(m_grProg[m_r->getFrameCount() & 1u]);
 

+ 1 - 2
AnKi/Renderer/Ssr.h

@@ -51,12 +51,11 @@ private:
 	{
 	public:
 		RenderTargetHandle m_rt;
-		RenderingContext* m_ctx ANKI_DEBUG_CODE(= nullptr);
 	} m_runCtx;
 
 	ANKI_USE_RESULT Error initInternal(const ConfigSet& cfg);
 
-	void run(RenderPassWorkContext& rgraphCtx);
+	void run(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx);
 
 	void getDebugRenderTarget(CString rtName, RenderTargetHandle& handle,
 							  ShaderProgramPtr& optionalShaderProgram) const override

+ 17 - 25
AnKi/Renderer/TemporalAA.cpp

@@ -77,7 +77,6 @@ Error TemporalAA::initInternal(const ConfigSet& config)
 
 void TemporalAA::populateRenderGraph(RenderingContext& ctx)
 {
-	m_runCtx.m_ctx = &ctx;
 	RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
 
 	const U32 historyRtIdx = (m_r->getFrameCount() + 1) & 1;
@@ -100,12 +99,23 @@ void TemporalAA::populateRenderGraph(RenderingContext& ctx)
 	// Create pass
 	ComputeRenderPassDescription& pass = rgraph.newComputeRenderPass("TemporalAA");
 
-	pass.setWork(
-		[](RenderPassWorkContext& rgraphCtx) {
-			TemporalAA* const self = static_cast<TemporalAA*>(rgraphCtx.m_userData);
-			self->run(*self->m_runCtx.m_ctx, rgraphCtx);
-		},
-		this, 0);
+	pass.setWork([this](RenderPassWorkContext& rgraphCtx) {
+		CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
+
+		cmdb->bindShaderProgram(m_grProgs[m_r->getFrameCount() & 1]);
+
+		cmdb->bindSampler(0, 0, m_r->getSamplers().m_trilinearClamp);
+		rgraphCtx.bindTexture(0, 1, m_r->getGBuffer().getDepthRt(),
+							  TextureSubresourceInfo(DepthStencilAspectBit::DEPTH));
+		rgraphCtx.bindColorTexture(0, 2, m_r->getLightShading().getRt());
+		rgraphCtx.bindColorTexture(0, 3, m_runCtx.m_historyRt);
+		rgraphCtx.bindColorTexture(0, 4, m_r->getMotionVectors().getMotionVectorsRt());
+		rgraphCtx.bindImage(0, 5, m_runCtx.m_renderRt, TextureSubresourceInfo());
+		rgraphCtx.bindImage(0, 6, m_runCtx.m_tonemappedRt, TextureSubresourceInfo());
+		rgraphCtx.bindUniformBuffer(0, 7, m_r->getTonemapping().getAverageLuminanceBuffer());
+
+		dispatchPPCompute(cmdb, 8, 8, m_r->getInternalResolution().x(), m_r->getInternalResolution().y());
+	});
 
 	pass.newDependency({m_runCtx.m_renderRt, TextureUsageBit::IMAGE_COMPUTE_WRITE});
 	pass.newDependency({m_runCtx.m_tonemappedRt, TextureUsageBit::IMAGE_COMPUTE_WRITE});
@@ -116,22 +126,4 @@ void TemporalAA::populateRenderGraph(RenderingContext& ctx)
 	pass.newDependency({m_r->getMotionVectors().getMotionVectorsRt(), TextureUsageBit::SAMPLED_COMPUTE});
 }
 
-void TemporalAA::run(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx)
-{
-	CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
-
-	cmdb->bindShaderProgram(m_grProgs[m_r->getFrameCount() & 1]);
-
-	cmdb->bindSampler(0, 0, m_r->getSamplers().m_trilinearClamp);
-	rgraphCtx.bindTexture(0, 1, m_r->getGBuffer().getDepthRt(), TextureSubresourceInfo(DepthStencilAspectBit::DEPTH));
-	rgraphCtx.bindColorTexture(0, 2, m_r->getLightShading().getRt());
-	rgraphCtx.bindColorTexture(0, 3, m_runCtx.m_historyRt);
-	rgraphCtx.bindColorTexture(0, 4, m_r->getMotionVectors().getMotionVectorsRt());
-	rgraphCtx.bindImage(0, 5, m_runCtx.m_renderRt, TextureSubresourceInfo());
-	rgraphCtx.bindImage(0, 6, m_runCtx.m_tonemappedRt, TextureSubresourceInfo());
-	rgraphCtx.bindUniformBuffer(0, 7, m_r->getTonemapping().getAverageLuminanceBuffer());
-
-	dispatchPPCompute(cmdb, 8, 8, m_r->getInternalResolution().x(), m_r->getInternalResolution().y());
-}
-
 } // end namespace anki

+ 0 - 3
AnKi/Renderer/TemporalAA.h

@@ -47,15 +47,12 @@ private:
 	class
 	{
 	public:
-		RenderingContext* m_ctx = nullptr;
 		RenderTargetHandle m_renderRt;
 		RenderTargetHandle m_historyRt;
 		RenderTargetHandle m_tonemappedRt;
 	} m_runCtx;
 
 	ANKI_USE_RESULT Error initInternal(const ConfigSet& cfg);
-
-	void run(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx);
 };
 /// @}
 

+ 12 - 20
AnKi/Renderer/Tonemapping.cpp

@@ -77,33 +77,25 @@ void Tonemapping::populateRenderGraph(RenderingContext& ctx)
 	// Create the pass
 	ComputeRenderPassDescription& pass = rgraph.newComputeRenderPass("Avg lum");
 
-	pass.setWork(
-		[](RenderPassWorkContext& rgraphCtx) {
-			Tonemapping* const self = static_cast<Tonemapping*>(rgraphCtx.m_userData);
-			self->run(rgraphCtx);
-		},
-		this, 0);
+	pass.setWork([this](RenderPassWorkContext& rgraphCtx) {
+		CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
 
-	pass.newDependency(
-		{m_runCtx.m_buffHandle, BufferUsageBit::STORAGE_COMPUTE_READ | BufferUsageBit::STORAGE_COMPUTE_WRITE});
+		cmdb->bindShaderProgram(m_grProg);
+		rgraphCtx.bindStorageBuffer(0, 1, m_runCtx.m_buffHandle);
 
-	TextureSubresourceInfo inputTexSubresource;
-	inputTexSubresource.m_firstMipmap = m_inputTexMip;
-	pass.newDependency({m_r->getDownscaleBlur().getRt(), TextureUsageBit::SAMPLED_COMPUTE, inputTexSubresource});
-}
+		TextureSubresourceInfo inputTexSubresource;
+		inputTexSubresource.m_firstMipmap = m_inputTexMip;
+		rgraphCtx.bindTexture(0, 0, m_r->getDownscaleBlur().getRt(), inputTexSubresource);
 
-void Tonemapping::run(RenderPassWorkContext& rgraphCtx)
-{
-	CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
+		cmdb->dispatchCompute(1, 1, 1);
+	});
 
-	cmdb->bindShaderProgram(m_grProg);
-	rgraphCtx.bindStorageBuffer(0, 1, m_runCtx.m_buffHandle);
+	pass.newDependency(
+		{m_runCtx.m_buffHandle, BufferUsageBit::STORAGE_COMPUTE_READ | BufferUsageBit::STORAGE_COMPUTE_WRITE});
 
 	TextureSubresourceInfo inputTexSubresource;
 	inputTexSubresource.m_firstMipmap = m_inputTexMip;
-	rgraphCtx.bindTexture(0, 0, m_r->getDownscaleBlur().getRt(), inputTexSubresource);
-
-	cmdb->dispatchCompute(1, 1, 1);
+	pass.newDependency({m_r->getDownscaleBlur().getRt(), TextureUsageBit::SAMPLED_COMPUTE, inputTexSubresource});
 }
 
 } // end namespace anki

+ 0 - 2
AnKi/Renderer/Tonemapping.h

@@ -48,8 +48,6 @@ private:
 	} m_runCtx;
 
 	ANKI_USE_RESULT Error initInternal(const ConfigSet& cfg);
-
-	void run(RenderPassWorkContext& rgraphCtx);
 };
 /// @}
 

+ 2 - 7
AnKi/Renderer/VolumetricFog.cpp

@@ -51,10 +51,9 @@ Error VolumetricFog::init(const ConfigSet& config)
 	return Error::NONE;
 }
 
-void VolumetricFog::run(RenderPassWorkContext& rgraphCtx)
+void VolumetricFog::run(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx)
 {
 	CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
-	const RenderingContext& ctx = *m_runCtx.m_ctx;
 
 	cmdb->bindShaderProgram(m_grProg);
 
@@ -87,17 +86,13 @@ void VolumetricFog::run(RenderPassWorkContext& rgraphCtx)
 
 void VolumetricFog::populateRenderGraph(RenderingContext& ctx)
 {
-	m_runCtx.m_ctx = &ctx;
 	RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
 
 	m_runCtx.m_rt = rgraph.newRenderTarget(m_rtDescr);
 
 	ComputeRenderPassDescription& pass = rgraph.newComputeRenderPass("Vol fog");
 
-	auto callback = [](RenderPassWorkContext& rgraphCtx) -> void {
-		static_cast<VolumetricFog*>(rgraphCtx.m_userData)->run(rgraphCtx);
-	};
-	pass.setWork(callback, this, 0);
+	pass.setWork([this, &ctx](RenderPassWorkContext& rgraphCtx) -> void { run(ctx, rgraphCtx); });
 
 	pass.newDependency({m_runCtx.m_rt, TextureUsageBit::IMAGE_COMPUTE_WRITE});
 	pass.newDependency({m_r->getVolumetricLightingAccumulation().getRt(), TextureUsageBit::SAMPLED_COMPUTE});

+ 1 - 2
AnKi/Renderer/VolumetricFog.h

@@ -87,10 +87,9 @@ private:
 	{
 	public:
 		RenderTargetHandle m_rt;
-		const RenderingContext* m_ctx = nullptr;
 	} m_runCtx; ///< Runtime context.
 
-	void run(RenderPassWorkContext& rgraphCtx);
+	void run(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx);
 };
 /// @}
 

+ 2 - 7
AnKi/Renderer/VolumetricLightingAccumulation.cpp

@@ -76,7 +76,6 @@ Error VolumetricLightingAccumulation::init(const ConfigSet& config)
 
 void VolumetricLightingAccumulation::populateRenderGraph(RenderingContext& ctx)
 {
-	m_runCtx.m_ctx = &ctx;
 	RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
 
 	const U readRtIdx = m_r->getFrameCount() & 1;
@@ -86,10 +85,7 @@ void VolumetricLightingAccumulation::populateRenderGraph(RenderingContext& ctx)
 
 	ComputeRenderPassDescription& pass = rgraph.newComputeRenderPass("Vol light");
 
-	auto callback = [](RenderPassWorkContext& rgraphCtx) -> void {
-		static_cast<VolumetricLightingAccumulation*>(rgraphCtx.m_userData)->run(rgraphCtx);
-	};
-	pass.setWork(callback, this, 0);
+	pass.setWork([this, &ctx](RenderPassWorkContext& rgraphCtx) { run(ctx, rgraphCtx); });
 
 	pass.newDependency(RenderPassDependency(m_runCtx.m_rts[0], TextureUsageBit::SAMPLED_COMPUTE));
 	pass.newDependency(RenderPassDependency(m_runCtx.m_rts[1], TextureUsageBit::IMAGE_COMPUTE_WRITE));
@@ -102,10 +98,9 @@ void VolumetricLightingAccumulation::populateRenderGraph(RenderingContext& ctx)
 	m_r->getGlobalIllumination().setRenderGraphDependencies(ctx, pass, TextureUsageBit::SAMPLED_COMPUTE);
 }
 
-void VolumetricLightingAccumulation::run(RenderPassWorkContext& rgraphCtx)
+void VolumetricLightingAccumulation::run(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx)
 {
 	CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
-	RenderingContext& ctx = *m_runCtx.m_ctx;
 	const ClusteredShadingContext& rsrc = ctx.m_clusteredShading;
 
 	cmdb->bindShaderProgram(m_grProg);

+ 1 - 2
AnKi/Renderer/VolumetricLightingAccumulation.h

@@ -51,11 +51,10 @@ private:
 	class
 	{
 	public:
-		RenderingContext* m_ctx = nullptr;
 		Array<RenderTargetHandle, 2> m_rts;
 	} m_runCtx; ///< Runtime context.
 
-	void run(RenderPassWorkContext& rgraphCtx);
+	void run(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx);
 };
 /// @}