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

Move ShadowMapping to the render graph

Panagiotis Christopoulos Charitos 8 лет назад
Родитель
Сommit
e91b8582c0

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

@@ -181,10 +181,10 @@ void ForwardShading::buildCommandBuffers(RenderingContext& ctx, U threadId, U th
 		TextureSurfaceInfo(0, 0, 0, 0),
 		TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ);
 	cmdb->informTextureCurrentUsage(m_rt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE);
-	cmdb->informTextureCurrentUsage(m_r->getShadowMapping().m_shadowAtlas, TextureUsageBit::SAMPLED_FRAGMENT);
+	// TODO: cmdb->informTextureCurrentUsage(m_r->getShadowMapping().m_shadowAtlas, TextureUsageBit::SAMPLED_FRAGMENT);
 
 	cmdb->bindTexture(0, 0, m_r->getDepthDownscale().m_qd.m_colorRt);
-	cmdb->bindTexture(0, 1, m_r->getShadowMapping().m_shadowAtlas);
+	// TODO: cmdb->bindTexture(0, 1, m_r->getShadowMapping().m_shadowAtlas);
 	bindUniforms(cmdb, 0, 0, ctx.m_lightShading.m_commonToken);
 	bindUniforms(cmdb, 0, 1, ctx.m_lightShading.m_pointLightsToken);
 	bindUniforms(cmdb, 0, 2, ctx.m_lightShading.m_spotLightsToken);

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

@@ -164,7 +164,7 @@ void LightShading::run(RenderingContext& ctx)
 	cmdb->informTextureCurrentUsage(m_r->getSsao().getRt(), TextureUsageBit::SAMPLED_FRAGMENT);
 	cmdb->bindTexture(1, 4, m_r->getSsao().getRt());
 
-	cmdb->bindTexture(0, 0, m_r->getShadowMapping().m_shadowAtlas);
+	// TODO: cmdb->bindTexture(0, 0, m_r->getShadowMapping().m_shadowAtlas);
 	cmdb->bindTexture(0, 1, m_r->getIndirect().getReflectionTexture());
 	cmdb->bindTexture(0, 2, m_r->getIndirect().getIrradianceTexture());
 	cmdb->bindTextureAndSampler(

+ 1 - 1
src/anki/renderer/Renderer.cpp

@@ -542,7 +542,7 @@ void Renderer::buildCommandBuffersInternal(RenderingContext& ctx, U32 threadId,
 
 	// SM
 	//
-	m_shadowMapping->buildCommandBuffers(ctx, threadId, threadCount);
+	// TODO: m_shadowMapping->buildCommandBuffers(ctx, threadId, threadCount);
 
 	// FS
 	//

+ 74 - 128
src/anki/renderer/ShadowMapping.cpp

@@ -47,20 +47,20 @@ Error ShadowMapping::initScratch(const ConfigSet& cfg)
 		m_scratchTileCount = cfg.getNumber("r.shadowMapping.scratchTileCount");
 		m_scratchTileResolution = cfg.getNumber("r.shadowMapping.resolution");
 
-		m_scratchRt = m_r->createAndClearRenderTarget(
-			m_r->create2DRenderTargetInitInfo(m_scratchTileResolution * m_scratchTileCount,
-				m_scratchTileResolution,
-				SHADOW_DEPTH_PIXEL_FORMAT,
-				TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE,
-				SamplingFilter::LINEAR,
-				1,
-				"scratch_smap"));
-
-		FramebufferInitInfo fbInit("scratch_smap");
-		fbInit.m_depthStencilAttachment.m_texture = m_scratchRt;
-		fbInit.m_depthStencilAttachment.m_loadOperation = AttachmentLoadOperation::CLEAR;
-		fbInit.m_depthStencilAttachment.m_clearValue.m_depthStencil.m_depth = 1.0;
-		m_scratchFb = getGrManager().newInstance<Framebuffer>(fbInit);
+		// RT
+		m_scratchRtDescr = m_r->create2DRenderTargetDescription(m_scratchTileResolution * m_scratchTileCount,
+			m_scratchTileResolution,
+			SHADOW_DEPTH_PIXEL_FORMAT,
+			TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE,
+			SamplingFilter::LINEAR,
+			"scratch_smap");
+		m_scratchRtDescr.bake();
+
+		// FB
+		m_scratchFbDescr.m_depthStencilAttachment.m_loadOperation = AttachmentLoadOperation::CLEAR;
+		m_scratchFbDescr.m_depthStencilAttachment.m_clearValue.m_depthStencil.m_depth = 1.0;
+		m_scratchFbDescr.m_depthStencilAttachment.m_aspect = DepthStencilAspectBit::DEPTH;
+		m_scratchFbDescr.bake();
 	}
 
 	return Error::NONE;
@@ -74,6 +74,7 @@ Error ShadowMapping::initEsm(const ConfigSet& cfg)
 		m_tileCountPerRowOrColumn = cfg.getNumber("r.shadowMapping.tileCountPerRowOrColumn");
 		m_atlasResolution = m_tileResolution * m_tileCountPerRowOrColumn;
 
+		// RT
 		TextureInitInfo texinit = m_r->create2DRenderTargetInitInfo(m_atlasResolution,
 			m_atlasResolution,
 			SHADOW_COLOR_PIXEL_FORMAT,
@@ -84,13 +85,12 @@ Error ShadowMapping::initEsm(const ConfigSet& cfg)
 		texinit.m_initialUsage = TextureUsageBit::SAMPLED_FRAGMENT;
 		ClearValue clearVal;
 		clearVal.m_colorf[0] = 1.0f;
-		m_shadowAtlas = m_r->createAndClearRenderTarget(texinit, clearVal);
+		m_esmAtlas = m_r->createAndClearRenderTarget(texinit, clearVal);
 
-		FramebufferInitInfo fbInit("esm");
-		fbInit.m_colorAttachments[0].m_texture = m_shadowAtlas;
-		fbInit.m_colorAttachments[0].m_loadOperation = AttachmentLoadOperation::LOAD;
-		fbInit.m_colorAttachmentCount = 1;
-		m_esmFb = getGrManager().newInstance<Framebuffer>(fbInit);
+		// FB
+		m_esmFbDescr.m_colorAttachments[0].m_loadOperation = AttachmentLoadOperation::LOAD;
+		m_esmFbDescr.m_colorAttachmentCount = 1;
+		m_esmFbDescr.bake();
 	}
 
 	// Tiles
@@ -144,77 +144,39 @@ Error ShadowMapping::initInternal(const ConfigSet& cfg)
 	return Error::NONE;
 }
 
-void ShadowMapping::run(RenderingContext& ctx)
+void ShadowMapping::runEsm(CommandBufferPtr& cmdb, const RenderGraph& rgraph)
 {
+	ANKI_ASSERT(m_esmResolveWorkItems.getSize());
 	ANKI_TRACE_SCOPED_EVENT(RENDER_SM);
-	CommandBufferPtr& cmdb = ctx.m_commandBuffer;
-
-	if(m_scratchWorkItems.getSize())
-	{
-		// Run the scratch pass
-		ANKI_ASSERT(m_freeScratchTiles < m_scratchTileCount);
-		cmdb->beginRenderPass(m_scratchFb,
-			0,
-			0,
-			(m_scratchTileCount - m_freeScratchTiles) * m_scratchTileResolution,
-			m_scratchTileResolution);
-
-		for(U tid = 0; tid < m_r->getThreadPool().getThreadsCount(); ++tid)
-		{
-			cmdb->pushSecondLevelCommandBuffer(m_scratchSecondLevelCmdbs[tid]);
-			m_scratchSecondLevelCmdbs[tid].reset(nullptr);
-		}
 
-		cmdb->endRenderPass();
+	cmdb->bindShaderProgram(m_esmResolveGrProg);
+	cmdb->bindTexture(0, 0, rgraph.getTexture(m_scratchRt));
 
-		// Barriers
-		cmdb->setTextureSurfaceBarrier(m_scratchRt,
-			TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE,
-			TextureUsageBit::SAMPLED_FRAGMENT,
-			TextureSurfaceInfo(0, 0, 0, 0));
-		cmdb->setTextureSurfaceBarrier(m_shadowAtlas,
-			TextureUsageBit::SAMPLED_FRAGMENT,
-			TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE,
-			TextureSurfaceInfo(0, 0, 0, 0));
-
-		// ESM pass
-		cmdb->bindShaderProgram(m_esmResolveGrProg);
-		cmdb->bindTexture(0, 0, m_scratchRt);
-		cmdb->beginRenderPass(m_esmFb);
+	for(const EsmResolveWorkItem& workItem : m_esmResolveWorkItems)
+	{
+		ANKI_TRACE_INC_COUNTER(RENDERER_SHADOW_PASSES, 1);
 
-		for(const EsmResolveWorkItem& workItem : m_esmResolveWorkItems)
-		{
-			ANKI_TRACE_INC_COUNTER(RENDERER_SHADOW_PASSES, 1);
-
-			cmdb->setViewport(workItem.m_viewportOut[0],
-				workItem.m_viewportOut[1],
-				workItem.m_viewportOut[2],
-				workItem.m_viewportOut[3]);
-			cmdb->setScissor(workItem.m_viewportOut[0],
-				workItem.m_viewportOut[1],
-				workItem.m_viewportOut[2],
-				workItem.m_viewportOut[3]);
-
-			Vec4* unis = allocateAndBindUniforms<Vec4*>(sizeof(Vec4) * 2, cmdb, 0, 0);
-			unis[0] = Vec4(workItem.m_cameraNear, workItem.m_cameraFar, 0.0f, 0.0f);
-			unis[1] = workItem.m_uvIn;
-
-			m_r->drawQuad(cmdb);
-		}
+		cmdb->setViewport(
+			workItem.m_viewportOut[0], workItem.m_viewportOut[1], workItem.m_viewportOut[2], workItem.m_viewportOut[3]);
+		cmdb->setScissor(
+			workItem.m_viewportOut[0], workItem.m_viewportOut[1], workItem.m_viewportOut[2], workItem.m_viewportOut[3]);
 
-		cmdb->endRenderPass();
+		Vec4* unis = allocateAndBindUniforms<Vec4*>(sizeof(Vec4) * 2, cmdb, 0, 0);
+		unis[0] = Vec4(workItem.m_cameraNear, workItem.m_cameraFar, 0.0f, 0.0f);
+		unis[1] = workItem.m_uvIn;
 
-		// Restore GR state
-		cmdb->setScissor(0, 0, MAX_U16, MAX_U16);
+		m_r->drawQuad(cmdb);
 	}
+
+	// Restore GR state
+	cmdb->setScissor(0, 0, MAX_U16, MAX_U16);
 }
 
-void ShadowMapping::buildCommandBuffers(RenderingContext& ctx, U threadId, U threadCount)
+void ShadowMapping::runShadowMapping(CommandBufferPtr& cmdb, U32 threadId)
 {
+	ANKI_ASSERT(m_scratchWorkItems.getSize());
 	ANKI_TRACE_SCOPED_EVENT(RENDER_SM);
 
-	CommandBufferPtr cmdb;
-
 	for(ScratchBufferWorkItem& work : m_scratchWorkItems)
 	{
 		if(work.m_threadPoolTaskIdx != threadId)
@@ -222,23 +184,6 @@ void ShadowMapping::buildCommandBuffers(RenderingContext& ctx, U threadId, U thr
 			continue;
 		}
 
-		// Lazily create the command buffer
-		if(!cmdb.isCreated())
-		{
-			CommandBufferInitInfo cinf;
-			cinf.m_flags = CommandBufferFlag::SECOND_LEVEL | CommandBufferFlag::GRAPHICS_WORK;
-			cinf.m_framebuffer = m_scratchFb;
-			if(work.m_renderableElementCount < COMMAND_BUFFER_SMALL_BATCH_MAX_COMMANDS)
-			{
-				cinf.m_flags |= CommandBufferFlag::SMALL_BATCH;
-			}
-			cmdb = m_r->getGrManager().newInstance<CommandBuffer>(cinf);
-
-			// Inform on Rts
-			cmdb->informTextureSurfaceCurrentUsage(
-				m_scratchRt, TextureSurfaceInfo(0, 0, 0, 0), TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE);
-		}
-
 		// Set state
 		cmdb->setViewport(work.m_viewport[0], work.m_viewport[1], work.m_viewport[2], work.m_viewport[3]);
 		cmdb->setScissor(work.m_viewport[0], work.m_viewport[1], work.m_viewport[2], work.m_viewport[3]);
@@ -251,43 +196,50 @@ void ShadowMapping::buildCommandBuffers(RenderingContext& ctx, U threadId, U thr
 			work.m_renderQueue->m_renderables.getBegin() + work.m_firstRenderableElement
 				+ work.m_renderableElementCount);
 	}
-
-	if(cmdb.isCreated())
-	{
-		cmdb->flush();
-		m_scratchSecondLevelCmdbs[threadId] = cmdb;
-	}
 }
 
-void ShadowMapping::setPreRunBarriers(RenderingContext& ctx)
+void ShadowMapping::populateRenderGraph(RenderingContext& ctx)
 {
 	ANKI_TRACE_SCOPED_EVENT(RENDER_SM);
 
+	// First process the lights
+	processLights(ctx);
+
+	// Build the render graph
+	RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
 	if(m_scratchWorkItems.getSize())
 	{
-		CommandBufferPtr& cmdb = ctx.m_commandBuffer;
-		cmdb->setTextureSurfaceBarrier(m_scratchRt,
-			TextureUsageBit::NONE,
-			TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE,
-			TextureSurfaceInfo(0, 0, 0, 0));
-	}
-}
+		// Will have to create render passes
 
-void ShadowMapping::setPostRunBarriers(RenderingContext& ctx)
-{
-	ANKI_TRACE_SCOPED_EVENT(RENDER_SM);
-	CommandBufferPtr& cmdb = ctx.m_commandBuffer;
+		// Scratch pass
+		{
+			GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass("SM scratch");
 
-	if(m_scratchWorkItems.getSize())
-	{
-		cmdb->setTextureSurfaceBarrier(m_shadowAtlas,
-			TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE,
-			TextureUsageBit::SAMPLED_FRAGMENT,
-			TextureSurfaceInfo(0, 0, 0, 0));
+			m_scratchRt = rgraph.newRenderTarget(m_scratchRtDescr);
+			pass.setFramebufferInfo(m_scratchFbDescr, {}, m_scratchRt);
+			pass.setWork(runShadowmappingCallback, this, m_r->getThreadPool().getThreadsCount());
+
+			pass.newConsumer({m_scratchRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE, TextureSurfaceInfo()});
+			pass.newProducer({m_scratchRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE, TextureSurfaceInfo()});
+		}
+
+		// ESM pass
+		{
+			GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass("ESM");
+
+			m_esmRt = rgraph.importRenderTarget("ESM", m_esmAtlas, TextureUsageBit::SAMPLED_FRAGMENT);
+			pass.setFramebufferInfo(m_esmFbDescr, {{m_esmRt}}, {});
+			pass.setWork(runEsmCallback, this, 0);
+
+			pass.newConsumer({m_scratchRt, TextureUsageBit::SAMPLED_FRAGMENT, TextureSurfaceInfo()});
+			pass.newConsumer({m_esmRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE, TextureSurfaceInfo()});
+			pass.newProducer({m_esmRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE, TextureSurfaceInfo()});
+		}
 	}
 	else
 	{
-		cmdb->informTextureCurrentUsage(m_shadowAtlas, TextureUsageBit::SAMPLED_FRAGMENT);
+		// No need for shadowmapping passes, just import the ESM atlas
+		m_esmRt = rgraph.importRenderTarget("ESM", m_esmAtlas, TextureUsageBit::SAMPLED_FRAGMENT);
 	}
 }
 
@@ -311,10 +263,8 @@ Mat4 ShadowMapping::createSpotLightTextureMatrix(const Tile& tile)
 		1.0);
 }
 
-void ShadowMapping::prepareBuildCommandBuffers(RenderingContext& ctx)
+void ShadowMapping::processLights(RenderingContext& ctx)
 {
-	ANKI_TRACE_SCOPED_EVENT(RENDER_SM);
-
 	// Reset stuff
 	m_freeScratchTiles = m_scratchTileCount;
 
@@ -431,7 +381,7 @@ void ShadowMapping::prepareBuildCommandBuffers(RenderingContext& ctx)
 		}
 		else
 		{
-			// Doesn't have renderables or the allocation failed, won't be shadow caster
+			// Doesn't have renderables or the allocation failed, won't be a shadow caster
 			light->m_shadowRenderQueue = nullptr;
 		}
 	}
@@ -499,15 +449,11 @@ void ShadowMapping::prepareBuildCommandBuffers(RenderingContext& ctx)
 			ANKI_ASSERT(esmItems && itemSize && itemStorageSize);
 			m_esmResolveWorkItems = WeakArray<EsmResolveWorkItem>(esmItems, itemSize);
 		}
-
-		m_scratchSecondLevelCmdbs =
-			WeakArray<CommandBufferPtr>(ctx.m_tempAllocator.newArray<CommandBufferPtr>(threadCount), threadCount);
 	}
 	else
 	{
 		m_scratchWorkItems = WeakArray<ScratchBufferWorkItem>();
 		m_esmResolveWorkItems = WeakArray<EsmResolveWorkItem>();
-		m_scratchSecondLevelCmdbs = WeakArray<CommandBufferPtr>();
 	}
 }
 

+ 40 - 16
src/anki/renderer/ShadowMapping.h

@@ -8,7 +8,6 @@
 #include <anki/renderer/RendererObject.h>
 #include <anki/Gr.h>
 #include <anki/resource/TextureResource.h>
-#include <anki/util/Array.h>
 
 namespace anki
 {
@@ -20,8 +19,6 @@ namespace anki
 class ShadowMapping : public RendererObject
 {
 anki_internal:
-	TexturePtr m_shadowAtlas; ///< ESM texture atlas.
-
 	ShadowMapping(Renderer* r)
 		: RendererObject(r)
 	{
@@ -31,15 +28,8 @@ anki_internal:
 
 	ANKI_USE_RESULT Error init(const ConfigSet& initializer);
 
-	void prepareBuildCommandBuffers(RenderingContext& ctx);
-
-	void buildCommandBuffers(RenderingContext& ctx, U threadId, U threadCount);
-
-	void setPreRunBarriers(RenderingContext& ctx);
-
-	void run(RenderingContext& ctx);
-
-	void setPostRunBarriers(RenderingContext& ctx);
+	/// Populate the rendergraph.
+	void populateRenderGraph(RenderingContext& ctx);
 
 private:
 	/// @name ESM stuff
@@ -58,6 +48,7 @@ private:
 		Array<U32, 4> m_viewport;
 	};
 
+	/// A HashMap key.
 	class TileKey
 	{
 	public:
@@ -70,7 +61,10 @@ private:
 		}
 	};
 
-	FramebufferPtr m_esmFb;
+	GraphicsRenderPassFramebufferDescription m_esmFbDescr; ///< The FB for ESM
+	TexturePtr m_esmAtlas; ///< ESM texture atlas.
+	RenderTargetHandle m_esmRt = {};
+
 	U32 m_tileResolution = 0; ///< Tile resolution.
 	U32 m_atlasResolution = 0; ///< Atlas size is (m_atlasResolution, m_atlasResolution)
 	U32 m_tileCountPerRowOrColumn = 0;
@@ -97,12 +91,27 @@ private:
 	ANKI_USE_RESULT Error initEsm(const ConfigSet& cfg);
 
 	static Mat4 createSpotLightTextureMatrix(const Tile& tile);
+
+	/// A RenderPassWorkCallback for ESM
+	static void runEsmCallback(void* userData,
+		CommandBufferPtr cmdb,
+		U32 secondLevelCmdbIdx,
+		U32 secondLevelCmdbCount,
+		const RenderGraph& rgraph)
+	{
+		ANKI_ASSERT(userData);
+		static_cast<ShadowMapping*>(userData)->runEsm(cmdb, rgraph);
+	}
+
+	void runEsm(CommandBufferPtr& cmdb, const RenderGraph& rgraph);
 	/// @}
 
 	/// @name Scratch buffer stuff
 	/// @{
-	TexturePtr m_scratchRt; ///< Size of the RT is (m_scratchTileSize * m_scratchTileCount, m_scratchTileSize).
-	FramebufferPtr m_scratchFb;
+	RenderTargetHandle m_scratchRt; ///< Size of the RT is (m_scratchTileSize * m_scratchTileCount, m_scratchTileSize).
+	GraphicsRenderPassFramebufferDescription m_scratchFbDescr; ///< FB info.
+	RenderTargetDescription m_scratchRtDescr; ///< Render target.
+
 	U32 m_scratchTileCount = 0;
 	U32 m_scratchTileResolution = 0;
 	U32 m_freeScratchTiles = 0;
@@ -120,9 +129,21 @@ private:
 	struct LightToRenderToScratchInfo;
 
 	WeakArray<ScratchBufferWorkItem> m_scratchWorkItems;
-	WeakArray<CommandBufferPtr> m_scratchSecondLevelCmdbs;
 
 	ANKI_USE_RESULT Error initScratch(const ConfigSet& cfg);
+
+	/// A RenderPassWorkCallback for shadow passes.
+	static void runShadowmappingCallback(void* userData,
+		CommandBufferPtr cmdb,
+		U32 secondLevelCmdbIdx,
+		U32 secondLevelCmdbCount,
+		const RenderGraph& rgraph)
+	{
+		ANKI_ASSERT(userData);
+		static_cast<ShadowMapping*>(userData)->runShadowMapping(cmdb, secondLevelCmdbIdx);
+	}
+
+	void runShadowMapping(CommandBufferPtr& cmdb, U32 treadId);
 	/// @}
 
 	/// @name Misc & common
@@ -144,6 +165,9 @@ private:
 		DynamicArrayAuto<EsmResolveWorkItem>& esmResolveWorkItem,
 		U32& drawcallCount) const;
 
+	/// Iterate lights and create work items.
+	void processLights(RenderingContext& ctx);
+
 	ANKI_USE_RESULT Error initInternal(const ConfigSet& config);
 	/// @}
 };

+ 1 - 1
src/anki/renderer/Volumetric.cpp

@@ -88,7 +88,7 @@ void VolumetricMain::run(RenderingContext& ctx)
 	TexturePtr& history = m_rt[(m_r->getFrameCount() + 1) & 1];
 	cmdb->informTextureCurrentUsage(history, TextureUsageBit::SAMPLED_FRAGMENT);
 	cmdb->bindTexture(0, 2, history);
-	cmdb->bindTexture(0, 3, m_r->getShadowMapping().m_shadowAtlas);
+	// TODO: cmdb->bindTexture(0, 3, m_r->getShadowMapping().m_shadowAtlas);
 
 	bindUniforms(cmdb, 0, 0, ctx.m_lightShading.m_commonToken);
 	bindUniforms(cmdb, 0, 1, ctx.m_lightShading.m_pointLightsToken);