Преглед изворни кода

Move Bloom to the render graph

Panagiotis Christopoulos Charitos пре 8 година
родитељ
комит
7475c974bf

+ 33 - 1
src/anki/gr/RenderGraph.cpp

@@ -120,14 +120,44 @@ public:
 
 
 void GraphicsRenderPassFramebufferDescription::bake()
 void GraphicsRenderPassFramebufferDescription::bake()
 {
 {
+	ANKI_ASSERT(m_hash == 0 && "Already baked");
 	if(m_defaultFb)
 	if(m_defaultFb)
 	{
 	{
+		m_fbInitInfo.m_colorAttachmentCount = 1;
 		m_hash = 1;
 		m_hash = 1;
 		return;
 		return;
 	}
 	}
 
 
-	m_hash = 0;
+	// Populate the FB init info
+	m_fbInitInfo.m_colorAttachmentCount = m_colorAttachmentCount;
+	for(U i = 0; i < m_colorAttachmentCount; ++i)
+	{
+		FramebufferAttachmentInfo& out = m_fbInitInfo.m_colorAttachments[i];
+		const GraphicsRenderPassFramebufferDescriptionAttachment& in = m_colorAttachments[i];
+
+		out.m_surface = in.m_surface;
+		out.m_clearValue = in.m_clearValue;
+		out.m_loadOperation = in.m_loadOperation;
+		out.m_storeOperation = in.m_storeOperation;
+	}
+
+	if(!!m_depthStencilAttachment.m_aspect)
+	{
+		FramebufferAttachmentInfo& out = m_fbInitInfo.m_depthStencilAttachment;
+		const GraphicsRenderPassFramebufferDescriptionAttachment& in = m_depthStencilAttachment;
 
 
+		out.m_surface = in.m_surface;
+		out.m_loadOperation = in.m_loadOperation;
+		out.m_storeOperation = in.m_storeOperation;
+		out.m_clearValue = in.m_clearValue;
+
+		out.m_stencilLoadOperation = in.m_stencilLoadOperation;
+		out.m_stencilStoreOperation = in.m_stencilStoreOperation;
+
+		out.m_aspect = in.m_aspect;
+	}
+
+	m_hash = 0;
 	ANKI_ASSERT(m_fbInitInfo.m_colorAttachmentCount > 0 || !!m_fbInitInfo.m_depthStencilAttachment.m_aspect);
 	ANKI_ASSERT(m_fbInitInfo.m_colorAttachmentCount > 0 || !!m_fbInitInfo.m_depthStencilAttachment.m_aspect);
 
 
 	// First the depth attachments
 	// First the depth attachments
@@ -322,11 +352,13 @@ FramebufferPtr RenderGraph::getOrCreateFramebuffer(
 			for(U i = 0; i < fbInit.m_colorAttachmentCount; ++i)
 			for(U i = 0; i < fbInit.m_colorAttachmentCount; ++i)
 			{
 			{
 				fbInit.m_colorAttachments[i].m_texture = m_ctx->m_rts[rtHandles[i]].m_texture;
 				fbInit.m_colorAttachments[i].m_texture = m_ctx->m_rts[rtHandles[i]].m_texture;
+				ANKI_ASSERT(fbInit.m_colorAttachments[i].m_texture.isCreated());
 			}
 			}
 
 
 			if(!!fbInit.m_depthStencilAttachment.m_aspect)
 			if(!!fbInit.m_depthStencilAttachment.m_aspect)
 			{
 			{
 				fbInit.m_depthStencilAttachment.m_texture = m_ctx->m_rts[rtHandles[MAX_COLOR_ATTACHMENTS]].m_texture;
 				fbInit.m_depthStencilAttachment.m_texture = m_ctx->m_rts[rtHandles[MAX_COLOR_ATTACHMENTS]].m_texture;
+				ANKI_ASSERT(fbInit.m_depthStencilAttachment.m_texture.isCreated());
 			}
 			}
 		}
 		}
 
 

+ 31 - 41
src/anki/gr/RenderGraph.h

@@ -41,6 +41,15 @@ class RenderTargetDescription : public TextureInitInfo
 	friend class RenderGraphDescription;
 	friend class RenderGraphDescription;
 
 
 public:
 public:
+	RenderTargetDescription()
+	{
+	}
+
+	RenderTargetDescription(CString name)
+		: TextureInitInfo(name)
+	{
+	}
+
 	/// Create an internal hash.
 	/// Create an internal hash.
 	void bake()
 	void bake()
 	{
 	{
@@ -193,51 +202,32 @@ protected:
 	}
 	}
 };
 };
 
 
+/// Framebuffer attachment info.
+/// @memberof GraphicsRenderPassFramebufferDescription
+class GraphicsRenderPassFramebufferDescriptionAttachment
+{
+public:
+	TextureSurfaceInfo m_surface;
+	AttachmentLoadOperation m_loadOperation = AttachmentLoadOperation::CLEAR;
+	AttachmentStoreOperation m_storeOperation = AttachmentStoreOperation::STORE;
+	ClearValue m_clearValue;
+
+	AttachmentLoadOperation m_stencilLoadOperation = AttachmentLoadOperation::CLEAR;
+	AttachmentStoreOperation m_stencilStoreOperation = AttachmentStoreOperation::STORE;
+
+	DepthStencilAspectBit m_aspect = DepthStencilAspectBit::NONE; ///< Relevant only for depth stencil textures.
+};
+
 /// Describes a framebuffer.
 /// Describes a framebuffer.
+/// @memberof GraphicsRenderPassDescription
 class GraphicsRenderPassFramebufferDescription
 class GraphicsRenderPassFramebufferDescription
 {
 {
 	friend class GraphicsRenderPassDescription;
 	friend class GraphicsRenderPassDescription;
 
 
 public:
 public:
-	void attachRenderTarget(U32 location,
-		const TextureSurfaceInfo& surf,
-		AttachmentLoadOperation loadOperation = AttachmentLoadOperation::DONT_CARE,
-		AttachmentStoreOperation storeOperation = AttachmentStoreOperation::STORE,
-		const ClearValue& clearValue = ClearValue())
-	{
-		FramebufferAttachmentInfo& att = m_fbInitInfo.m_colorAttachments[location];
-		att.m_surface = surf;
-		att.m_loadOperation = loadOperation;
-		att.m_storeOperation = storeOperation;
-		att.m_clearValue = clearValue;
-
-		m_fbInitInfo.m_colorAttachmentCount = location + 1;
-		m_defaultFb = false;
-	}
-
-	void attachDepthStencilRenderTarget(const TextureSurfaceInfo& surf,
-		AttachmentLoadOperation loadOperation = AttachmentLoadOperation::CLEAR,
-		AttachmentStoreOperation storeOperation = AttachmentStoreOperation::STORE,
-		AttachmentLoadOperation stencilLoadOperation = AttachmentLoadOperation::CLEAR,
-		AttachmentStoreOperation stencilStoreOperation = AttachmentStoreOperation::STORE,
-		DepthStencilAspectBit aspect = DepthStencilAspectBit::DEPTH,
-		F32 depthClear = 1.0f,
-		I32 stencilClear = 0)
-	{
-		ANKI_ASSERT(!!(aspect & DepthStencilAspectBit::DEPTH_STENCIL));
-
-		FramebufferAttachmentInfo& att = m_fbInitInfo.m_depthStencilAttachment;
-		att.m_surface = surf;
-		att.m_loadOperation = loadOperation;
-		att.m_storeOperation = storeOperation;
-		att.m_clearValue.m_depthStencil.m_depth = depthClear;
-		att.m_clearValue.m_depthStencil.m_stencil = stencilClear;
-		att.m_stencilLoadOperation = stencilLoadOperation;
-		att.m_stencilStoreOperation = stencilStoreOperation;
-		att.m_aspect = aspect;
-
-		m_defaultFb = false;
-	}
+	Array<GraphicsRenderPassFramebufferDescriptionAttachment, MAX_COLOR_ATTACHMENTS> m_colorAttachments;
+	U32 m_colorAttachmentCount = 0;
+	GraphicsRenderPassFramebufferDescriptionAttachment m_depthStencilAttachment;
 
 
 	void setDefaultFramebuffer()
 	void setDefaultFramebuffer()
 	{
 	{
@@ -360,14 +350,14 @@ public:
 	}
 	}
 
 
 	/// Get or create a new render target.
 	/// Get or create a new render target.
-	RenderTargetHandle newRenderTarget(CString name, const RenderTargetDescription& initInf)
+	RenderTargetHandle newRenderTarget(const RenderTargetDescription& initInf)
 	{
 	{
 		ANKI_ASSERT(initInf.m_hash && "Forgot to call RenderTargetDescription::bake");
 		ANKI_ASSERT(initInf.m_hash && "Forgot to call RenderTargetDescription::bake");
 		RT& rt = m_renderTargets.emplaceBack(m_alloc);
 		RT& rt = m_renderTargets.emplaceBack(m_alloc);
 		rt.m_initInfo = initInf;
 		rt.m_initInfo = initInf;
 		rt.m_hash = initInf.m_hash;
 		rt.m_hash = initInf.m_hash;
 		rt.m_usage = TextureUsageBit::NONE;
 		rt.m_usage = TextureUsageBit::NONE;
-		rt.setName(name);
+		rt.setName(initInf.getName());
 		return m_renderTargets.getSize() - 1;
 		return m_renderTargets.getSize() - 1;
 	}
 	}
 
 

+ 106 - 93
src/anki/renderer/Bloom.cpp

@@ -13,148 +13,161 @@
 namespace anki
 namespace anki
 {
 {
 
 
-BloomExposure::~BloomExposure()
+Bloom::Bloom(Renderer* r)
+	: RendererObject(r)
 {
 {
 }
 }
 
 
-Error BloomExposure::init(const ConfigSet& config)
+Bloom::~Bloom()
 {
 {
-	GrManager& gr = getGrManager();
+}
 
 
-	m_width = m_r->getDownscaleBlur().getPassWidth(MAX_U) * 2;
-	m_height = m_r->getDownscaleBlur().getPassHeight(MAX_U) * 2;
+Error Bloom::initExposure(const ConfigSet& config)
+{
+	m_exposure.m_width = m_r->getDownscaleBlur().getPassWidth(MAX_U) * 2;
+	m_exposure.m_height = m_r->getDownscaleBlur().getPassHeight(MAX_U) * 2;
 
 
-	m_threshold = config.getNumber("r.bloom.threshold");
-	m_scale = config.getNumber("r.bloom.scale");
+	m_exposure.m_threshold = config.getNumber("r.bloom.threshold");
+	m_exposure.m_scale = config.getNumber("r.bloom.scale");
 
 
-	// Create RT
-	m_rt = m_r->createAndClearRenderTarget(m_r->create2DRenderTargetInitInfo(m_width,
-		m_height,
+	// Create RT info
+	m_exposure.m_rtDescr = m_r->create2DRenderTargetDescription(m_exposure.m_width,
+		m_exposure.m_height,
 		BLOOM_RT_PIXEL_FORMAT,
 		BLOOM_RT_PIXEL_FORMAT,
 		TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE,
 		TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE,
 		SamplingFilter::LINEAR,
 		SamplingFilter::LINEAR,
-		1,
-		"bloomexp"));
+		"bloomexp");
+	m_exposure.m_rtDescr.bake();
 
 
-	// Create FBs
-	FramebufferInitInfo fbInit("bloomexp");
-	fbInit.m_colorAttachmentCount = 1;
-	fbInit.m_colorAttachments[0].m_texture = m_rt;
-	fbInit.m_colorAttachments[0].m_loadOperation = AttachmentLoadOperation::DONT_CARE;
-	m_fb = gr.newInstance<Framebuffer>(fbInit);
+	// Create FB info
+	m_exposure.m_fbDescr.m_colorAttachmentCount = 1;
+	m_exposure.m_fbDescr.m_colorAttachments[0].m_loadOperation = AttachmentLoadOperation::DONT_CARE;
+	m_exposure.m_fbDescr.bake();
 
 
 	// init shaders
 	// init shaders
-	ANKI_CHECK(getResourceManager().loadResource("programs/Bloom.ankiprog", m_prog));
+	ANKI_CHECK(getResourceManager().loadResource("programs/Bloom.ankiprog", m_exposure.m_prog));
 
 
-	ShaderProgramResourceConstantValueInitList<1> consts(m_prog);
+	ShaderProgramResourceConstantValueInitList<1> consts(m_exposure.m_prog);
 	consts.add(
 	consts.add(
 		"TEX_SIZE", Vec2(m_r->getDownscaleBlur().getPassWidth(MAX_U), m_r->getDownscaleBlur().getPassHeight(MAX_U)));
 		"TEX_SIZE", Vec2(m_r->getDownscaleBlur().getPassWidth(MAX_U), m_r->getDownscaleBlur().getPassHeight(MAX_U)));
 
 
 	const ShaderProgramResourceVariant* variant;
 	const ShaderProgramResourceVariant* variant;
-	m_prog->getOrCreateVariant(consts.get(), variant);
-	m_grProg = variant->getProgram();
+	m_exposure.m_prog->getOrCreateVariant(consts.get(), variant);
+	m_exposure.m_grProg = variant->getProgram();
 
 
 	return Error::NONE;
 	return Error::NONE;
 }
 }
 
 
-void BloomExposure::setPreRunBarriers(RenderingContext& ctx)
-{
-	ctx.m_commandBuffer->setTextureSurfaceBarrier(
-		m_rt, TextureUsageBit::NONE, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE, TextureSurfaceInfo(0, 0, 0, 0));
-}
-
-void BloomExposure::setPostRunBarriers(RenderingContext& ctx)
+Error Bloom::initUpscale(const ConfigSet& config)
 {
 {
-	ctx.m_commandBuffer->setTextureSurfaceBarrier(m_rt,
-		TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE,
-		TextureUsageBit::SAMPLED_FRAGMENT,
-		TextureSurfaceInfo(0, 0, 0, 0));
-}
+	m_upscale.m_width = m_r->getWidth() / BLOOM_FRACTION;
+	m_upscale.m_height = m_r->getHeight() / BLOOM_FRACTION;
 
 
-void BloomExposure::run(RenderingContext& ctx)
-{
-	CommandBufferPtr& cmdb = ctx.m_commandBuffer;
+	// Create RT descr
+	m_upscale.m_rtDescr = m_r->create2DRenderTargetDescription(m_upscale.m_width,
+		m_upscale.m_height,
+		BLOOM_RT_PIXEL_FORMAT,
+		TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE,
+		SamplingFilter::LINEAR,
+		"bloomupscale");
+	m_upscale.m_rtDescr.bake();
 
 
-	cmdb->beginRenderPass(m_fb);
-	cmdb->setViewport(0, 0, m_width, m_height);
-	cmdb->bindShaderProgram(m_grProg);
-	cmdb->bindTexture(0, 0, m_r->getDownscaleBlur().getPassTexture(MAX_U));
+	// Create FB descr
+	m_upscale.m_fbDescr.m_colorAttachmentCount = 1;
+	m_upscale.m_fbDescr.m_colorAttachments[0].m_loadOperation = AttachmentLoadOperation::DONT_CARE;
+	m_upscale.m_fbDescr.bake();
 
 
-	Vec4* uniforms = allocateAndBindUniforms<Vec4*>(sizeof(Vec4), cmdb, 0, 0);
-	*uniforms = Vec4(m_threshold, m_scale, 0.0, 0.0);
+	// init shaders
+	ANKI_CHECK(getResourceManager().loadResource("programs/BloomUpscale.ankiprog", m_upscale.m_prog));
 
 
-	cmdb->bindStorageBuffer(0, 0, m_r->getTonemapping().m_luminanceBuff, 0, MAX_PTR_SIZE);
+	ShaderProgramResourceConstantValueInitList<1> consts(m_upscale.m_prog);
+	consts.add("TEX_SIZE", Vec2(m_upscale.m_width, m_upscale.m_height));
 
 
-	m_r->drawQuad(cmdb);
-	cmdb->endRenderPass();
-}
+	const ShaderProgramResourceVariant* variant;
+	m_upscale.m_prog->getOrCreateVariant(consts.get(), variant);
+	m_upscale.m_grProg = variant->getProgram();
 
 
-BloomUpscale::~BloomUpscale()
-{
+	return Error::NONE;
 }
 }
 
 
-Error BloomUpscale::init(const ConfigSet& config)
+Error Bloom::initSslf(const ConfigSet& cfg)
 {
 {
-	GrManager& gr = getGrManager();
-
-	m_width = m_r->getWidth() / BLOOM_FRACTION;
-	m_height = m_r->getHeight() / BLOOM_FRACTION;
-
-	// Create RTs
-	m_rt = m_r->createAndClearRenderTarget(m_r->create2DRenderTargetInitInfo(m_width,
-		m_height,
-		BLOOM_RT_PIXEL_FORMAT,
-		TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE,
-		SamplingFilter::LINEAR,
-		1,
-		"bloomupscale"));
+	ANKI_CHECK(getResourceManager().loadResource("engine_data/LensDirt.ankitex", m_sslf.m_lensDirtTex));
+	ANKI_CHECK(getResourceManager().loadResource("programs/ScreenSpaceLensFlare.ankiprog", m_sslf.m_prog));
 
 
-	// Create FBs
-	FramebufferInitInfo fbInit("bloomupscale");
-	fbInit.m_colorAttachmentCount = 1;
-	fbInit.m_colorAttachments[0].m_texture = m_rt;
-	fbInit.m_colorAttachments[0].m_loadOperation = AttachmentLoadOperation::DONT_CARE;
-	m_fb = gr.newInstance<Framebuffer>(fbInit);
-
-	// init shaders
-	ANKI_CHECK(getResourceManager().loadResource("programs/BloomUpscale.ankiprog", m_prog));
-
-	ShaderProgramResourceConstantValueInitList<1> consts(m_prog);
-	consts.add("TEX_SIZE", Vec2(m_width, m_height));
+	ShaderProgramResourceConstantValueInitList<1> consts(m_sslf.m_prog);
+	consts.add("INPUT_TEX_SIZE", UVec2(m_exposure.m_width, m_exposure.m_height));
 
 
 	const ShaderProgramResourceVariant* variant;
 	const ShaderProgramResourceVariant* variant;
-	m_prog->getOrCreateVariant(consts.get(), variant);
-	m_grProg = variant->getProgram();
+	m_sslf.m_prog->getOrCreateVariant(consts.get(), variant);
+	m_sslf.m_grProg = variant->getProgram();
 
 
 	return Error::NONE;
 	return Error::NONE;
 }
 }
 
 
-void BloomUpscale::setPreRunBarriers(RenderingContext& ctx)
+void Bloom::populateRenderGraph(RenderingContext& ctx)
 {
 {
-	ctx.m_commandBuffer->setTextureSurfaceBarrier(
-		m_rt, TextureUsageBit::NONE, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE, TextureSurfaceInfo(0, 0, 0, 0));
+	RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
+
+	// Main pass
+	{
+		// Ask for render target
+		m_exposure.m_rt = rgraph.newRenderTarget(m_exposure.m_rtDescr);
+
+		// Set the render pass
+		GraphicsRenderPassDescription& rpass = ctx.m_renderGraphDescr.newGraphicsRenderPass("bloom main");
+		rpass.newConsumer({m_exposure.m_rt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE, TextureSurfaceInfo()});
+		rpass.newProducer({m_exposure.m_rt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE, TextureSurfaceInfo()});
+		ANKI_ASSERT(!"TODO Missing deps");
+		rpass.setWork(runExposureCallback, this, 0);
+	}
+
+	// Upscale & SSLF pass
+	{
+		// Ask for render target
+		m_upscale.m_rt = rgraph.newRenderTarget(m_upscale.m_rtDescr);
+
+		// Set the render pass
+		GraphicsRenderPassDescription& rpass = ctx.m_renderGraphDescr.newGraphicsRenderPass("bloom upscale");
+		rpass.newConsumer({m_upscale.m_rt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE, TextureSurfaceInfo()});
+		rpass.newProducer({m_upscale.m_rt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE, TextureSurfaceInfo()});
+		ANKI_ASSERT(!"TODO Missing deps");
+		rpass.setWork(runUpscaleAndSslfCallback, this, 0);
+	}
 }
 }
 
 
-void BloomUpscale::setPostRunBarriers(RenderingContext& ctx)
+void Bloom::runExposure(CommandBufferPtr& cmdb)
 {
 {
-	ctx.m_commandBuffer->setTextureSurfaceBarrier(m_rt,
-		TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE,
-		TextureUsageBit::SAMPLED_FRAGMENT,
-		TextureSurfaceInfo(0, 0, 0, 0));
+	cmdb->setViewport(0, 0, m_exposure.m_width, m_exposure.m_height);
+	cmdb->bindShaderProgram(m_exposure.m_grProg);
+	// TODO: cmdb->bindTexture(0, 0, m_r->getDownscaleBlur().getPassTexture(MAX_U));
+	ANKI_ASSERT(!"TODO");
+
+	Vec4* uniforms = allocateAndBindUniforms<Vec4*>(sizeof(Vec4), cmdb, 0, 0);
+	*uniforms = Vec4(m_exposure.m_threshold, m_exposure.m_scale, 0.0, 0.0);
+
+	// TODO: cmdb->bindStorageBuffer(0, 0, m_r->getTonemapping().m_luminanceBuff, 0, MAX_PTR_SIZE);
+	ANKI_ASSERT(!"TODO");
+
+	m_r->drawQuad(cmdb);
 }
 }
 
 
-void BloomUpscale::run(RenderingContext& ctx)
+void Bloom::runUpscaleAndSslf(CommandBufferPtr& cmdb, const RenderGraph& rgraph)
 {
 {
-	CommandBufferPtr& cmdb = ctx.m_commandBuffer;
+	// Upscale
+	cmdb->setViewport(0, 0, m_upscale.m_width, m_upscale.m_height);
+	cmdb->bindShaderProgram(m_upscale.m_grProg);
+	cmdb->bindTexture(0, 0, rgraph.getTexture(m_exposure.m_rt));
+	m_r->drawQuad(cmdb);
 
 
-	cmdb->setViewport(0, 0, m_width, m_height);
-	cmdb->beginRenderPass(m_fb);
-	cmdb->bindShaderProgram(m_grProg);
-	cmdb->bindTexture(0, 0, m_r->getBloom().m_extractExposure.m_rt);
+	// SSLF
+	cmdb->bindShaderProgram(m_sslf.m_grProg);
+	cmdb->setBlendFactors(0, BlendFactor::ONE, BlendFactor::ONE);
+	cmdb->bindTexture(0, 1, m_sslf.m_lensDirtTex->getGrTexture());
 	m_r->drawQuad(cmdb);
 	m_r->drawQuad(cmdb);
 
 
-	m_r->getBloom().m_sslf.run(ctx);
-	cmdb->endRenderPass();
+	// Retore state
+	cmdb->setBlendFactors(0, BlendFactor::ONE, BlendFactor::ZERO);
 }
 }
 
 
 } // end namespace anki
 } // end namespace anki

+ 69 - 75
src/anki/renderer/Bloom.h

@@ -6,7 +6,6 @@
 #pragma once
 #pragma once
 
 
 #include <anki/renderer/RendererObject.h>
 #include <anki/renderer/RendererObject.h>
-#include <anki/renderer/ScreenSpaceLensFlare.h>
 #include <anki/Gr.h>
 #include <anki/Gr.h>
 #include <anki/resource/TextureResource.h>
 #include <anki/resource/TextureResource.h>
 
 
@@ -18,106 +17,101 @@ namespace anki
 
 
 const PixelFormat BLOOM_RT_PIXEL_FORMAT(ComponentFormat::R8G8B8, TransformFormat::UNORM);
 const PixelFormat BLOOM_RT_PIXEL_FORMAT(ComponentFormat::R8G8B8, TransformFormat::UNORM);
 
 
-class BloomExposure : public RendererObject
+/// Bloom passes.
+class Bloom : public RendererObject
 {
 {
 anki_internal:
 anki_internal:
-	U32 m_width = 0;
-	U32 m_height = 0;
-	TexturePtr m_rt;
+	Bloom(Renderer* r);
+
+	~Bloom();
 
 
-	BloomExposure(Renderer* r)
-		: RendererObject(r)
+	ANKI_USE_RESULT Error init(const ConfigSet& cfg)
 	{
 	{
+		ANKI_R_LOGI("Initializing bloom passes");
+		Error err = initInternal(cfg);
+		if(err)
+		{
+			ANKI_R_LOGE("Failed to initialize bloom passes");
+		}
+		return err;
 	}
 	}
 
 
-	~BloomExposure();
-
-	ANKI_USE_RESULT Error init(const ConfigSet& initializer);
-
-	void setPreRunBarriers(RenderingContext& ctx);
-
-	void run(RenderingContext& ctx);
-
-	void setPostRunBarriers(RenderingContext& ctx);
+	/// Populate the rendergraph.
+	void populateRenderGraph(RenderingContext& ctx);
 
 
 private:
 private:
-	FramebufferPtr m_fb;
-
-	ShaderProgramResourcePtr m_prog;
-	ShaderProgramPtr m_grProg;
-
-	F32 m_threshold = 10.0; ///< How bright it is
-	F32 m_scale = 1.0;
-};
-
-class BloomUpscale : public RendererObject
-{
-anki_internal:
-	U32 m_width = 0;
-	U32 m_height = 0;
-	TexturePtr m_rt;
-
-	BloomUpscale(Renderer* r)
-		: RendererObject(r)
+	class
 	{
 	{
-	}
+	public:
+		ShaderProgramResourcePtr m_prog;
+		ShaderProgramPtr m_grProg;
 
 
-	~BloomUpscale();
+		F32 m_threshold = 10.0; ///< How bright it is
+		F32 m_scale = 1.0;
+		U32 m_width = 0;
+		U32 m_height = 0;
 
 
-	ANKI_USE_RESULT Error init(const ConfigSet& initializer);
+		GraphicsRenderPassFramebufferDescription m_fbDescr;
+		RenderTargetDescription m_rtDescr;
+		RenderTargetHandle m_rt = 0;
+	} m_exposure;
 
 
-	void setPreRunBarriers(RenderingContext& ctx);
+	class
+	{
+	public:
+		ShaderProgramResourcePtr m_prog;
+		ShaderProgramPtr m_grProg;
 
 
-	void run(RenderingContext& ctx);
+		U32 m_width = 0;
+		U32 m_height = 0;
 
 
-	void setPostRunBarriers(RenderingContext& ctx);
+		RenderTargetDescription m_rtDescr;
+		GraphicsRenderPassFramebufferDescription m_fbDescr;
+		RenderTargetHandle m_rt = 0;
+	} m_upscale;
 
 
-private:
-	FramebufferPtr m_fb;
+	class
+	{
+	public:
+		ShaderProgramResourcePtr m_prog;
+		ShaderProgramPtr m_grProg;
+		TextureResourcePtr m_lensDirtTex;
+	} m_sslf;
 
 
-	ShaderProgramResourcePtr m_prog;
-	ShaderProgramPtr m_grProg;
-};
+	ANKI_USE_RESULT Error initExposure(const ConfigSet& cfg);
+	ANKI_USE_RESULT Error initUpscale(const ConfigSet& cfg);
+	ANKI_USE_RESULT Error initSslf(const ConfigSet& cfg);
 
 
-/// Bloom passes.
-class Bloom : public RendererObject
-{
-anki_internal:
-	BloomExposure m_extractExposure;
-	BloomUpscale m_upscale;
-	ScreenSpaceLensFlare m_sslf;
-
-	Bloom(Renderer* r)
-		: RendererObject(r)
-		, m_extractExposure(r)
-		, m_upscale(r)
-		, m_sslf(r)
+	ANKI_USE_RESULT Error initInternal(const ConfigSet& cfg)
 	{
 	{
+		ANKI_CHECK(initExposure(cfg));
+		ANKI_CHECK(initUpscale(cfg));
+		ANKI_CHECK(initSslf(cfg));
+		return Error::NONE;
 	}
 	}
 
 
-	~Bloom()
+	static void runExposureCallback(void* userData,
+		CommandBufferPtr cmdb,
+		U32 secondLevelCmdbIdx,
+		U32 secondLevelCmdbCount,
+		const RenderGraph& rgraph)
 	{
 	{
+		ANKI_ASSERT(userData);
+		static_cast<Bloom*>(userData)->runExposure(cmdb);
 	}
 	}
 
 
-	ANKI_USE_RESULT Error init(const ConfigSet& cfg)
+	static void runUpscaleAndSslfCallback(void* userData,
+		CommandBufferPtr cmdb,
+		U32 secondLevelCmdbIdx,
+		U32 secondLevelCmdbCount,
+		const RenderGraph& rgraph)
 	{
 	{
-		ANKI_R_LOGI("Initializing bloom passes");
-		Error err = initInternal(cfg);
-		if(err)
-		{
-			ANKI_R_LOGE("Failed to initialize bloom passes");
-		}
-		return err;
+		ANKI_ASSERT(userData);
+		static_cast<Bloom*>(userData)->runUpscaleAndSslf(cmdb, rgraph);
 	}
 	}
 
 
-private:
-	ANKI_USE_RESULT Error initInternal(const ConfigSet& cfg)
-	{
-		ANKI_CHECK(m_extractExposure.init(cfg));
-		ANKI_CHECK(m_upscale.init(cfg));
-		ANKI_CHECK(m_sslf.init(cfg));
-		return Error::NONE;
-	}
+	void runExposure(CommandBufferPtr& cmdb);
+	void runUpscaleAndSslf(CommandBufferPtr& cmdb, const RenderGraph& rgraph);
 };
 };
 
 
 /// @}
 /// @}

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

@@ -25,7 +25,6 @@ class LightShading;
 class ForwardShading;
 class ForwardShading;
 class LensFlare;
 class LensFlare;
 class Ssao;
 class Ssao;
-class ScreenSpaceLensFlare;
 class Tonemapping;
 class Tonemapping;
 class Bloom;
 class Bloom;
 class FinalComposite;
 class FinalComposite;

+ 3 - 1
src/anki/renderer/FinalComposite.cpp

@@ -7,7 +7,6 @@
 #include <anki/renderer/Renderer.h>
 #include <anki/renderer/Renderer.h>
 #include <anki/renderer/Bloom.h>
 #include <anki/renderer/Bloom.h>
 #include <anki/renderer/TemporalAA.h>
 #include <anki/renderer/TemporalAA.h>
-#include <anki/renderer/ScreenSpaceLensFlare.h>
 #include <anki/renderer/Tonemapping.h>
 #include <anki/renderer/Tonemapping.h>
 #include <anki/renderer/LightShading.h>
 #include <anki/renderer/LightShading.h>
 #include <anki/renderer/GBuffer.h>
 #include <anki/renderer/GBuffer.h>
@@ -104,6 +103,8 @@ Error FinalComposite::loadColorGradingTexture(CString filename)
 
 
 Error FinalComposite::run(RenderingContext& ctx)
 Error FinalComposite::run(RenderingContext& ctx)
 {
 {
+	ANKI_ASSERT(!"TODO");
+#if 0
 	// Get the drawing parameters
 	// Get the drawing parameters
 	const Bool drawToDefaultFb = ctx.m_outFb.isCreated();
 	const Bool drawToDefaultFb = ctx.m_outFb.isCreated();
 	const Bool dbgEnabled = m_r->getDbg().getEnabled();
 	const Bool dbgEnabled = m_r->getDbg().getEnabled();
@@ -166,6 +167,7 @@ Error FinalComposite::run(RenderingContext& ctx)
 			TextureUsageBit::SAMPLED_FRAGMENT,
 			TextureUsageBit::SAMPLED_FRAGMENT,
 			TextureSurfaceInfo(0, 0, 0, 0));
 			TextureSurfaceInfo(0, 0, 0, 0));
 	}
 	}
+#endif
 
 
 	return Error::NONE;
 	return Error::NONE;
 }
 }

+ 26 - 0
src/anki/renderer/Renderer.cpp

@@ -252,6 +252,8 @@ Error Renderer::render(RenderingContext& ctx)
 		m_resourcesDirty = false;
 		m_resourcesDirty = false;
 	}
 	}
 
 
+	ANKI_ASSERT(!"TODO");
+#if 0
 	// Prepare SM. Do that first because it touches the render queue elements
 	// Prepare SM. Do that first because it touches the render queue elements
 	m_shadowMapping->prepareBuildCommandBuffers(ctx);
 	m_shadowMapping->prepareBuildCommandBuffers(ctx);
 
 
@@ -374,6 +376,7 @@ Error Renderer::render(RenderingContext& ctx)
 
 
 	// Passes
 	// Passes
 	ANKI_CHECK(m_finalComposite->run(ctx));
 	ANKI_CHECK(m_finalComposite->run(ctx));
+#endif
 
 
 	++m_frameCount;
 	++m_frameCount;
 	m_prevViewProjMat = ctx.m_renderQueue->m_viewProjectionMatrix;
 	m_prevViewProjMat = ctx.m_renderQueue->m_viewProjectionMatrix;
@@ -430,6 +433,29 @@ TextureInitInfo Renderer::create2DRenderTargetInitInfo(
 	return init;
 	return init;
 }
 }
 
 
+RenderTargetDescription Renderer::create2DRenderTargetDescription(
+	U32 w, U32 h, const PixelFormat& format, TextureUsageBit usage, SamplingFilter filter, CString name)
+{
+	ANKI_ASSERT(!!(usage & TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE));
+	RenderTargetDescription init(name);
+
+	init.m_width = w;
+	init.m_height = h;
+	init.m_depth = 1;
+	init.m_layerCount = 1;
+	init.m_type = TextureType::_2D;
+	init.m_format = format;
+	init.m_mipmapsCount = 1;
+	init.m_samples = 1;
+	init.m_usage = usage;
+	init.m_sampling.m_minMagFilter = filter;
+	init.m_sampling.m_mipmapFilter = filter;
+	init.m_sampling.m_repeat = false;
+	init.m_sampling.m_anisotropyLevel = 0;
+
+	return init;
+}
+
 TexturePtr Renderer::createAndClearRenderTarget(const TextureInitInfo& inf, const ClearValue& clearVal)
 TexturePtr Renderer::createAndClearRenderTarget(const TextureInitInfo& inf, const ClearValue& clearVal)
 {
 {
 	ANKI_ASSERT(!!(inf.m_usage & TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE));
 	ANKI_ASSERT(!!(inf.m_usage & TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE));

+ 9 - 2
src/anki/renderer/Renderer.h

@@ -30,8 +30,12 @@ class StagingGpuMemoryManager;
 class RenderingContext
 class RenderingContext
 {
 {
 public:
 public:
+	StackAllocator<U8> m_tempAllocator;
+
 	RenderQueue* m_renderQueue ANKI_DBG_NULLIFY;
 	RenderQueue* m_renderQueue ANKI_DBG_NULLIFY;
 
 
+	RenderGraphDescription m_renderGraphDescr;
+
 	// Extra matrices
 	// Extra matrices
 	Mat4 m_projMatJitter;
 	Mat4 m_projMatJitter;
 	Mat4 m_viewProjMatJitter;
 	Mat4 m_viewProjMatJitter;
@@ -44,8 +48,6 @@ public:
 	CommandBufferPtr m_commandBuffer; ///< Primary command buffer.
 	CommandBufferPtr m_commandBuffer; ///< Primary command buffer.
 	CommandBufferPtr m_defaultFbCommandBuffer; ///< The default framebuffer renderpass is in a separate cmdb.
 	CommandBufferPtr m_defaultFbCommandBuffer; ///< The default framebuffer renderpass is in a separate cmdb.
 
 
-	StackAllocator<U8> m_tempAllocator;
-
 	class GBuffer
 	class GBuffer
 	{
 	{
 	public:
 	public:
@@ -92,6 +94,7 @@ public:
 
 
 	RenderingContext(const StackAllocator<U8>& alloc)
 	RenderingContext(const StackAllocator<U8>& alloc)
 		: m_tempAllocator(alloc)
 		: m_tempAllocator(alloc)
+		, m_renderGraphDescr(alloc)
 		, m_lensFlare(alloc)
 		, m_lensFlare(alloc)
 	{
 	{
 	}
 	}
@@ -273,6 +276,10 @@ anki_internal:
 		U mipsCount = 1,
 		U mipsCount = 1,
 		CString name = {});
 		CString name = {});
 
 
+	/// Create the init info for a 2D texture that will be used as a render target.
+	ANKI_USE_RESULT RenderTargetDescription create2DRenderTargetDescription(
+		U32 w, U32 h, const PixelFormat& format, TextureUsageBit usage, SamplingFilter filter, CString name = {});
+
 	ANKI_USE_RESULT TexturePtr createAndClearRenderTarget(
 	ANKI_USE_RESULT TexturePtr createAndClearRenderTarget(
 		const TextureInitInfo& inf, const ClearValue& clearVal = ClearValue());
 		const TextureInitInfo& inf, const ClearValue& clearVal = ClearValue());
 
 

+ 0 - 60
src/anki/renderer/ScreenSpaceLensFlare.cpp

@@ -1,60 +0,0 @@
-// Copyright (C) 2009-2017, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#include <anki/renderer/ScreenSpaceLensFlare.h>
-#include <anki/renderer/Renderer.h>
-#include <anki/renderer/Bloom.h>
-#include <anki/misc/ConfigSet.h>
-
-namespace anki
-{
-
-Error ScreenSpaceLensFlare::init(const ConfigSet& config)
-{
-	ANKI_R_LOGI("Initializing screen space lens flare");
-
-	Error err = initInternal(config);
-	if(err)
-	{
-		ANKI_R_LOGE("Failed to init screen space lens flare");
-	}
-
-	return err;
-}
-
-Error ScreenSpaceLensFlare::initInternal(const ConfigSet& config)
-{
-	ANKI_CHECK(getResourceManager().loadResource("engine_data/LensDirt.ankitex", m_lensDirtTex));
-
-	ANKI_CHECK(getResourceManager().loadResource("programs/ScreenSpaceLensFlare.ankiprog", m_prog));
-
-	ShaderProgramResourceConstantValueInitList<1> consts(m_prog);
-	consts.add(
-		"INPUT_TEX_SIZE", UVec2(m_r->getBloom().m_extractExposure.m_width, m_r->getBloom().m_extractExposure.m_height));
-
-	const ShaderProgramResourceVariant* variant;
-	m_prog->getOrCreateVariant(consts.get(), variant);
-	m_grProg = variant->getProgram();
-
-	return Error::NONE;
-}
-
-void ScreenSpaceLensFlare::run(RenderingContext& ctx)
-{
-	CommandBufferPtr& cmdb = ctx.m_commandBuffer;
-
-	// Draw to the SSLF FB
-	cmdb->bindShaderProgram(m_grProg);
-	cmdb->setBlendFactors(0, BlendFactor::ONE, BlendFactor::ONE);
-	cmdb->bindTexture(0, 0, m_r->getBloom().m_extractExposure.m_rt);
-	cmdb->bindTexture(0, 1, m_lensDirtTex->getGrTexture());
-
-	m_r->drawQuad(cmdb);
-
-	// Retore state
-	cmdb->setBlendFactors(0, BlendFactor::ONE, BlendFactor::ZERO);
-}
-
-} // end namespace anki

+ 0 - 37
src/anki/renderer/ScreenSpaceLensFlare.h

@@ -1,37 +0,0 @@
-// Copyright (C) 2009-2017, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#pragma once
-
-#include <anki/renderer/RendererObject.h>
-
-namespace anki
-{
-
-/// @addtogroup renderer
-/// @{
-
-/// Screen space lens flare pass.
-class ScreenSpaceLensFlare : public RendererObject
-{
-anki_internal:
-	ScreenSpaceLensFlare(Renderer* r)
-		: RendererObject(r)
-	{
-	}
-
-	ANKI_USE_RESULT Error init(const ConfigSet& config);
-	void run(RenderingContext& ctx);
-
-private:
-	ShaderProgramResourcePtr m_prog;
-	ShaderProgramPtr m_grProg;
-	TextureResourcePtr m_lensDirtTex;
-
-	ANKI_USE_RESULT Error initInternal(const ConfigSet& config);
-};
-/// @}
-
-} // end namespace anki