Browse Source

Framebuffer work

Panagiotis Christopoulos Charitos 10 years ago
parent
commit
c63fabcf15

+ 0 - 15
include/anki/gr/Common.h

@@ -97,21 +97,6 @@ private:
 /// @addtogroup opengl_containers
 /// @{
 
-/// Attachment load operation.
-enum class GlAttachmentLoadOperation: U8
-{
-	LOAD,
-	CLEAR,
-	DONT_CARE
-};
-
-/// Attachment store operation.
-enum class GlAttachmentStoreOperation: U8
-{
-	STORE,
-	DONT_CARE
-};
-
 /// Using an AnKi typename get the ShaderVariableDataType. Used for debugging.
 template<typename T>
 ShaderVariableDataType getShaderVariableTypeFromTypename();

+ 16 - 0
include/anki/gr/Enums.h

@@ -231,6 +231,22 @@ enum class OcclusionQueryResult: U8
 	VISIBLE,
 	NOT_VISIBLE
 };
+
+/// Attachment load operation.
+enum class AttachmentLoadOperation: U8
+{
+	LOAD,
+	CLEAR,
+	DONT_CARE
+};
+
+/// Attachment store operation.
+enum class AttachmentStoreOperation: U8
+{
+	STORE,
+	RESOLVE_MSAA,
+	DONT_CARE
+};
 /// @}
 
 } // end namespace anki

+ 55 - 3
include/anki/gr/FramebufferCommon.h

@@ -13,20 +13,72 @@ namespace anki {
 
 /// @addtogroup graphics
 /// @{
-
-struct Attachment
+class Attachment
 {
+public:
 	TextureHandle m_texture;
 	U32 m_layer = 0;
 	U32 m_mipmap = 0;
+	PixelFormat m_format;
+	AttachmentLoadOperation m_loadOperation = AttachmentLoadOperation::CLEAR;
+	AttachmentStoreOperation m_storeOperation = AttachmentStoreOperation::STORE;
+	struct
+	{
+		Array<F32, 4> m_float = {{0.0, 0.0, 0.0, 0.0}};
+		Array<I32, 4> m_int = {{0, 0, 0, 0}};
+		Array<U32, 4> m_uint = {{0, 0, 0, 0}};
+	} m_clearColor;
+
+	Attachment() = default;
+
+	Attachment(const Attachment& b)
+	{
+		operator=(b);
+	}
+
+	~Attachment() = default;
+
+	Attachment& operator=(const Attachment& b)
+	{
+		m_texture = b.m_texture;
+		m_layer = b.m_layer;
+		m_mipmap = b.m_mipmap;
+		m_format = b.m_format;
+		m_loadOperation = b.m_loadOperation;
+		m_storeOperation = b.m_storeOperation;
+		memcpy(&m_clearColor, &b.m_clearColor, sizeof(m_clearColor));
+		return *this;
+	}
 };
 
 /// Framebuffer initializer.
-struct FramebufferInitializer
+class FramebufferInitializer
 {
+public:
 	Array<Attachment, MAX_COLOR_ATTACHMENTS> m_colorAttachments;
 	U32 m_colorAttachmentsCount = 0;
 	Attachment m_depthStencilAttachment;
+
+	FramebufferInitializer() = default;
+
+	FramebufferInitializer(const FramebufferInitializer& b)
+	{
+		operator=(b);
+	}
+
+	~FramebufferInitializer() = default;
+
+	FramebufferInitializer& operator=(const FramebufferInitializer& b)
+	{
+		for(U i = 0; i < b.m_colorAttachmentsCount; i++)
+		{
+			m_colorAttachments[i] = b.m_colorAttachments[i];
+		}
+
+		m_colorAttachments = b.m_colorAttachments;
+		m_depthStencilAttachment = b.m_depthStencilAttachment;
+		return *this;
+	}
 };
 /// @}
 

+ 2 - 3
include/anki/gr/FramebufferHandle.h

@@ -29,10 +29,9 @@ public:
 	ANKI_USE_RESULT Error create(CommandBufferHandle& commands,
 		Initializer& attachments);
 
-	/// Bind it to the state
+	/// Bind it to the command buffer
 	/// @param commands The command buffer
-	/// @param invalidate If true invalidate the FB after binding it
-	void bind(CommandBufferHandle& commands, Bool invalidate);
+	void bind(CommandBufferHandle& commands);
 
 	/// Blit another framebuffer to this
 	/// @param[in, out] commands The command buffer

+ 2 - 2
include/anki/gr/PipelineCommon.h

@@ -90,10 +90,10 @@ enum class SubStateBit: U16
 	TESSELLATION = 1 << 2,
 	VIEWPORT = 1 << 3,
 	RASTERIZER = 1 << 4,
-	DEPTH = 1 << 5,
+	DEPTH_STENCIL = 1 << 5,
 	COLOR = 1 << 6,
 	ALL = VERTEX | INPUT_ASSEMBLER | TESSELLATION | VIEWPORT | RASTERIZER 
-		| DEPTH | COLOR
+		| DEPTH_STENCIL | COLOR
 };
 ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(SubStateBit, inline)
 

+ 6 - 5
include/anki/gr/gl/FramebufferImpl.h

@@ -7,7 +7,7 @@
 #define ANKI_GR_GL_FRAMEBUFFER_IMPL_H
 
 #include "anki/gr/gl/GlObject.h"
-#include "anki/gr/TextureHandle.h"
+#include "anki/gr/FramebufferCommon.h"
 
 namespace anki {
 
@@ -15,7 +15,7 @@ namespace anki {
 /// @{
 
 /// Framebuffer implementation.
-class FramebufferImpl: public GlObject
+class FramebufferImpl: public GlObject, private FramebufferInitializer
 {
 public:
 	using Base = GlObject;
@@ -35,15 +35,16 @@ public:
 	ANKI_USE_RESULT Error create(Initializer& init);
 
 	/// Bind it to the state. Call it in rendering thread
-	/// @param invalidate If true invalidate the FB after binding it
-	void bind(Bool invalidate);
+	void bind();
 
 	/// Blit another framebuffer to this
 	void blit(const FramebufferImpl& fb, const Array<U32, 4>& sourceRect,
 		const Array<U32, 4>& destRect, GLbitfield attachmentMask, Bool linear);
 
 private:
-	Array<TextureHandle, MAX_COLOR_ATTACHMENTS + 1> m_attachments;
+	Array<GLenum, MAX_COLOR_ATTACHMENTS> m_drawBuffers;
+	Array<GLenum, MAX_COLOR_ATTACHMENTS + 1> m_invalidateBuffers;
+	U8 m_invalidateBuffersCount = 0;
 	Bool8 m_bindDefault = false;
 
 	/// Attach a texture

+ 15 - 9
include/anki/gr/gl/PipelineImpl.h

@@ -79,15 +79,21 @@ private:
 	void initDepthStencilState();
 	void initColorState();
 
-	void setVertexState(GlState& state);
-	void setInputAssemblerState(GlState& state);
-	void setTessellationState(GlState& state);
-	void setRasterizerState(GlState& state);
-	void setDepthStencilState(GlState& state);
-	void setColorState(GlState& state);
-
-	const PipelineImpl* getPipelineForState(const SubStateBit bit) const;
-	const PipelineImpl* chosePipelineForState(const SubStateBit bit) const;
+	void setVertexState(GlState& state) const;
+	void setInputAssemblerState(GlState& state) const;
+	void setTessellationState(GlState& state) const;
+	void setViewportState(GlState& state) const
+	{}
+	void setRasterizerState(GlState& state) const;
+	void setDepthStencilState(GlState& state) const;
+	void setColorState(GlState& state) const;
+
+	const PipelineImpl* getPipelineForState(
+		const SubStateBit bit, 
+		const PipelineImpl* lastPpline,
+		const PipelineImpl* lastPplineTempl,
+		const PipelineImpl* pplineTempl) const; 
+
 };
 /// @}
 

+ 5 - 8
src/gr/gl/FramebufferHandle.cpp

@@ -44,16 +44,14 @@ class BindFramebufferCommand: public GlCommand
 {
 public:
 	FramebufferHandle m_fb;
-	Bool8 m_invalidate;
 
-	BindFramebufferCommand(FramebufferHandle& fb, Bool invalidate)
-	:	m_fb(fb), 
-		m_invalidate(invalidate)
+	BindFramebufferCommand(FramebufferHandle& fb)
+	:	m_fb(fb) 
 	{}
 
 	Error operator()(CommandBufferImpl*)
 	{
-		m_fb.get().bind(m_invalidate);
+		m_fb.get().bind();
 		return ErrorCode::NONE;
 	}
 };
@@ -121,10 +119,9 @@ Error FramebufferHandle::create(CommandBufferHandle& commands,
 }
 
 //==============================================================================
-void FramebufferHandle::bind(CommandBufferHandle& commands, Bool invalidate)
+void FramebufferHandle::bind(CommandBufferHandle& commands)
 {
-	commands.get().pushBackNewCommand<BindFramebufferCommand>(
-		*this, invalidate);
+	commands.get().pushBackNewCommand<BindFramebufferCommand>(*this);
 }
 
 //==============================================================================

+ 44 - 86
src/gr/gl/FramebufferImpl.cpp

@@ -13,8 +13,10 @@ namespace anki {
 //==============================================================================
 Error FramebufferImpl::create(Initializer& init)
 {
-	if(init.m_colorAttachmentsCount == 0 
-		&& !init.m_depthStencilAttachment.m_texture.isCreated())
+	*static_cast<FramebufferInitializer*>(this) = init;
+
+	if(m_colorAttachmentsCount == 0 
+		&& !m_depthStencilAttachment.m_texture.isCreated())
 	{
 		m_bindDefault = true;
 		return ErrorCode::NONE;
@@ -22,79 +24,39 @@ Error FramebufferImpl::create(Initializer& init)
 
 	m_bindDefault = false;
 
-	Array<U, MAX_COLOR_ATTACHMENTS + 1> layers;
-	GLenum depthStencilBindingPoint = GL_NONE;
-
-	// Do color attachments
-	for(U i = 0; i < init.m_colorAttachmentsCount; ++i)
-	{
-		auto& attachment = init.m_colorAttachments[i];
-		ANKI_ASSERT(attachment.m_texture.isCreated());
-		m_attachments[i] = attachment.m_texture;
-		layers[i] = attachment.m_layer;
-	}
-
-	// Do depth stencil
-	if(init.m_depthStencilAttachment.m_texture.isCreated())
-	{
-		m_attachments[MAX_COLOR_ATTACHMENTS] = 
-			init.m_depthStencilAttachment.m_texture;
-		layers[MAX_COLOR_ATTACHMENTS] = 
-			init.m_depthStencilAttachment.m_layer;
-
-		depthStencilBindingPoint = GL_DEPTH_ATTACHMENT;
-	}
-
-	// Now create the FBO
-	Error err = createFbo(layers, depthStencilBindingPoint);
-	glBindFramebuffer(GL_FRAMEBUFFER, 0);
-
-	return err;
-}
-
-//==============================================================================
-void FramebufferImpl::destroy()
-{
-	if(m_glName != 0)
-	{
-		glDeleteFramebuffers(1, &m_glName);
-		m_glName = 0;
-	}
-}
-
-//==============================================================================
-Error FramebufferImpl::createFbo(
-	const Array<U, MAX_COLOR_ATTACHMENTS + 1>& layers,
-	GLenum depthStencilBindingPoint)
-{
-	Error err = ErrorCode::NONE;
-
-	ANKI_ASSERT(!isCreated());
 	glGenFramebuffers(1, &m_glName);
 	ANKI_ASSERT(m_glName != 0);
 	const GLenum target = GL_FRAMEBUFFER;
 	glBindFramebuffer(target, m_glName);
 
 	// Attach color
-	for(U i = 0; i < MAX_COLOR_ATTACHMENTS; i++)
+	for(U i = 0; i < m_colorAttachmentsCount; i++)
 	{
-		if(!m_attachments[i].isCreated())
+		const Attachment& att = m_colorAttachments[i];
+		const GLenum binding = GL_COLOR_ATTACHMENT0 + i;
+
+		attachTextureInternal(binding, att.m_texture.get(), att.m_layer);
+
+		m_drawBuffers[i] = binding;
+
+		if(att.m_loadOperation == AttachmentLoadOperation::DONT_CARE)
 		{
-			continue;
+			m_invalidateBuffers[m_invalidateBuffersCount++] = binding;
 		}
-		
-		const TextureImpl& tex = m_attachments[i].get();
-		attachTextureInternal(GL_COLOR_ATTACHMENT0 + i, tex, layers[i]);
 	}
 
 	// Attach depth/stencil
-	if(m_attachments[MAX_COLOR_ATTACHMENTS].isCreated())
+	if(m_depthStencilAttachment.m_texture.isCreated())
 	{
-		ANKI_ASSERT(depthStencilBindingPoint != GL_NONE);
+		const Attachment& att = m_depthStencilAttachment;
+		const GLenum binding = GL_DEPTH_ATTACHMENT;
+			
+		attachTextureInternal(binding, att.m_texture.get(), att.m_layer);
 
-		const TextureImpl& tex = m_attachments[MAX_COLOR_ATTACHMENTS].get();
-		attachTextureInternal(depthStencilBindingPoint, tex, 
-			layers[MAX_COLOR_ATTACHMENTS]);
+		if(att.m_loadOperation == AttachmentLoadOperation::DONT_CARE)
+		{
+			m_invalidateBuffers[m_invalidateBuffersCount++] = binding;
+		}
 	}
 
 	// Check completeness
@@ -103,10 +65,21 @@ Error FramebufferImpl::createFbo(
 	{
 		ANKI_LOGE("FBO is incomplete");
 		destroy();
-		err = ErrorCode::FUNCTION_FAILED;
+		return ErrorCode::FUNCTION_FAILED;
 	}
 
-	return err;
+	glBindFramebuffer(GL_FRAMEBUFFER, 0);
+	return ErrorCode::NONE;
+}
+
+//==============================================================================
+void FramebufferImpl::destroy()
+{
+	if(m_glName != 0)
+	{
+		glDeleteFramebuffers(1, &m_glName);
+		m_glName = 0;
+	}
 }
 
 //==============================================================================
@@ -142,7 +115,7 @@ void FramebufferImpl::attachTextureInternal(
 }
 
 //==============================================================================
-void FramebufferImpl::bind(Bool invalidate)
+void FramebufferImpl::bind()
 {
 	if(m_bindDefault)
 	{
@@ -154,34 +127,19 @@ void FramebufferImpl::bind(Bool invalidate)
 		glBindFramebuffer(GL_FRAMEBUFFER, m_glName);
 
 		// Set the draw buffers
-		U count = 0;
-		Array<GLenum, MAX_COLOR_ATTACHMENTS> colorAttachEnums;
-
-		// Draw buffers
-		for(U i = 0; i < MAX_COLOR_ATTACHMENTS; i++)
+		if(m_colorAttachmentsCount)
 		{
-			if(m_attachments[i].isCreated())
-			{
-				colorAttachEnums[count++] = GL_COLOR_ATTACHMENT0 + i;
-			}
+			glDrawBuffers(m_colorAttachmentsCount, &m_drawBuffers[0]);
 		}
-		ANKI_ASSERT(count > 0
-			|| m_attachments[MAX_COLOR_ATTACHMENTS].isCreated());
-		glDrawBuffers(count, &colorAttachEnums[0]);
 
 		// Invalidate
-		if(invalidate)
+		if(m_invalidateBuffersCount)
 		{
-			static const Array<GLenum, MAX_COLOR_ATTACHMENTS + 1>
-				ATTACHMENT_TOKENS = {{
-					GL_DEPTH_STENCIL_ATTACHMENT, GL_COLOR_ATTACHMENT0, 
-					GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, 
-					GL_COLOR_ATTACHMENT3}};
-
-			glInvalidateFramebuffer(
-				GL_FRAMEBUFFER, ATTACHMENT_TOKENS.size(), 
-				&ATTACHMENT_TOKENS[0]);
+			glInvalidateFramebuffer(GL_FRAMEBUFFER, m_invalidateBuffersCount, 
+				&m_invalidateBuffers[0]);
 		}
+
+		ANKI_ASSERT(0 && "TODO clear buffers");
 	}
 }
 

+ 68 - 35
src/gr/gl/PipelineImpl.cpp

@@ -240,22 +240,50 @@ void PipelineImpl::bind()
 	auto& state = 
 		getManager().getImplementation().getRenderingThread().getState();
 
-	const PipelineImpl* last = nullptr;
-	const PipelineImpl* lastTempl = nullptr;
+	const PipelineImpl* lastPpline = nullptr;
+	const PipelineImpl* lastPplineTempl = nullptr;
 	if(state.m_lastPipeline.isCreated())
 	{
-		last = &state.m_lastPipeline.get();
+		lastPpline = &state.m_lastPipeline.get();
 
-		if(last->m_templatePipeline.isCreated())
+		if(ANKI_UNLIKELY(lastPpline == this))
 		{
-			lastTempl = &last->m_templatePipeline.get();
+			// Binding the same pipeline, early out
+			return;
+		}
+
+		if(lastPpline->m_templatePipeline.isCreated())
+		{
+			lastPplineTempl = &lastPpline->m_templatePipeline.get();
 		}
 	}
-	
-	/*if(!lastPpline.isCreated() || !templPpline.isCreated())
+
+	// Get crnt pipeline template
+	const PipelineImpl* pplineTempl = nullptr;
+	if(m_templatePipeline.isCreated())
 	{
-		// Bind state
-	}*/
+		pplineTempl = &m_templatePipeline.get();
+	}
+	
+#define ANKI_PPLINE_BIND(enum_, method_) \
+	do { \
+		const PipelineImpl* ppline = getPipelineForState(SubStateBit::enum_, \
+			lastPpline, lastPplineTempl, pplineTempl); \
+		if(ppline) { \
+			ppline->method_(state); \
+		} \
+	} while(0) \
+
+	ANKI_PPLINE_BIND(VERTEX, setVertexState);
+	ANKI_PPLINE_BIND(INPUT_ASSEMBLER, setInputAssemblerState);
+	ANKI_PPLINE_BIND(TESSELLATION, setTessellationState);
+	ANKI_PPLINE_BIND(VIEWPORT, setViewportState);
+	ANKI_PPLINE_BIND(RASTERIZER, setRasterizerState);
+	ANKI_PPLINE_BIND(DEPTH_STENCIL, setDepthStencilState);
+	ANKI_PPLINE_BIND(COLOR, setColorState);
+
+#undef ANKI_PPLINE_BIND
+
 #endif
 }
 
@@ -430,7 +458,7 @@ void PipelineImpl::initColorState()
 }
 
 //==============================================================================
-void PipelineImpl::setVertexState(GlState&)
+void PipelineImpl::setVertexState(GlState&) const
 {
 	for(U i = 0; i < m_vertex.m_attributeCount; ++i)
 	{
@@ -444,7 +472,7 @@ void PipelineImpl::setVertexState(GlState&)
 }
 
 //==============================================================================
-void PipelineImpl::setInputAssemblerState(GlState& state)
+void PipelineImpl::setInputAssemblerState(GlState& state) const
 {
 	if(m_inputAssembler.m_primitiveRestartEnabled 
 		!= state.m_primitiveRestartEnabled)
@@ -466,7 +494,7 @@ void PipelineImpl::setInputAssemblerState(GlState& state)
 }
 
 //==============================================================================
-void PipelineImpl::setTessellationState(GlState& state)
+void PipelineImpl::setTessellationState(GlState& state) const
 {
 	if(m_tessellation.m_patchControlPointsCount 
 		!= state.m_patchControlPointsCount)
@@ -480,7 +508,7 @@ void PipelineImpl::setTessellationState(GlState& state)
 }
 
 //==============================================================================
-void PipelineImpl::setRasterizerState(GlState& state)
+void PipelineImpl::setRasterizerState(GlState& state) const
 {
 	if(m_fillMode != state.m_fillMode)
 	{
@@ -496,7 +524,7 @@ void PipelineImpl::setRasterizerState(GlState& state)
 }
 
 //==============================================================================
-void PipelineImpl::setDepthStencilState(GlState& state)
+void PipelineImpl::setDepthStencilState(GlState& state) const
 {
 	if(m_depthCompareFunction != state.m_depthCompareFunction)
 	{
@@ -516,7 +544,7 @@ void PipelineImpl::setDepthStencilState(GlState& state)
 }
 
 //==============================================================================
-void PipelineImpl::setColorState(GlState&)
+void PipelineImpl::setColorState(GlState&) const
 {
 	for(U i = 0; i < m_color.m_colorAttachmentsCount; ++i)
 	{
@@ -530,34 +558,39 @@ void PipelineImpl::setColorState(GlState&)
 }
 
 //==============================================================================
-const PipelineImpl* getPipelineForState(const SubStateBit bit) const
+const PipelineImpl* PipelineImpl::getPipelineForState(
+	const SubStateBit bit, 
+	const PipelineImpl* lastPpline,
+	const PipelineImpl* lastPplineTempl,
+	const PipelineImpl* pplineTempl) const 
 {
-	PipelineImpl* out = this;
+	const PipelineImpl* out = nullptr;
 
-	if(m_templatePipeline.isCreated() && !(m_definedState | bit))
+	if(pplineTempl == nullptr || (m_definedState | bit) != SubStateBit::NONE)
 	{
-		// Template pipeline has the defined state
-		out = &m_templatePipeline.get();
+		// Current pipeline overrides the state
+		out = this;
 	}
+	else
+	{
+		// Need to get the state from the templates
 
-	return out;
-}
-
-//==============================================================================
-const PipelineImpl* PipelineImpl::chosePipelineForState(
-	const SubStateBit bit, const PipelineImpl& crntBoundPipeline) const 
-{
-	const PipelineImpl* out = nullptr;
+		if(lastPplineTempl == nullptr 
+			|| lastPplineTempl != pplineTempl
+			|| (lastPpline->m_definedState | bit) != SubStateBit::NONE)
+		{
+			// Last template cannot be used
 
-	// Get previously bound pipeline template
-	const PipelineImpl* last = nullptr;
-	if(crntBoundPipeline.m_templatePipeline.isCreated() 
-		&& !(crntBoundPipeline.m_definedState | bit))
-	{
-		last = &crntBoundPipeline.m_templatePipeline.get();
+			out = pplineTempl;
+		}
+		else
+		{
+			// Last template can be used but since it's already bound skipp
+			out = nullptr;
+		}
 	}
 
-	if(last)
+	return out;
 }
 
 } // end namespace anki

+ 3 - 1
src/renderer/Dbg.cpp

@@ -59,6 +59,8 @@ Error Dbg::init(const ConfigSet& initializer)
 	{
 		fbInit.m_colorAttachments[0].m_texture = m_r->getIs()._getRt();
 	}
+	fbInit.m_colorAttachments[0].m_loadOperation = 
+		AttachmentLoadOperation::LOAD;
 
 	err = m_fb.create(cmdb, fbInit);
 	if(!err)
@@ -93,7 +95,7 @@ Error Dbg::run(CommandBufferHandle& cmdb)
 
 	SceneGraph& scene = m_r->getSceneGraph();
 
-	m_fb.bind(cmdb, false);
+	m_fb.bind(cmdb);
 	cmdb.enableDepthTest(m_depthTest);
 
 	Camera& cam = scene.getActiveCamera();

+ 5 - 1
src/renderer/Fs.cpp

@@ -23,7 +23,11 @@ Error Fs::init(const ConfigSet&)
 	FramebufferHandle::Initializer fbInit;
 	fbInit.m_colorAttachmentsCount = 1;
 	fbInit.m_colorAttachments[0].m_texture = m_r->getIs()._getRt();
+	fbInit.m_colorAttachments[0].m_loadOperation = 
+		AttachmentLoadOperation::LOAD;
 	fbInit.m_depthStencilAttachment.m_texture = m_r->getMs()._getDepthRt();
+	fbInit.m_depthStencilAttachment.m_loadOperation = 
+		AttachmentLoadOperation::LOAD;
 	ANKI_CHECK(m_fb.create(cmdb,fbInit));
 
 	cmdb.flush();
@@ -36,7 +40,7 @@ Error Fs::run(CommandBufferHandle& cmdb)
 {
 	Error err = ErrorCode::NONE;
 
-	m_fb.bind(cmdb, false);
+	m_fb.bind(cmdb);
 
 	cmdb.enableDepthTest(true);
 	cmdb.setDepthWriteMask(false);

+ 4 - 2
src/renderer/Hdr.cpp

@@ -28,6 +28,8 @@ Error Hdr::initFb(FramebufferHandle& fb, TextureHandle& rt)
 	FramebufferHandle::Initializer fbInit;
 	fbInit.m_colorAttachmentsCount = 1;
 	fbInit.m_colorAttachments[0].m_texture = rt;
+	fbInit.m_colorAttachments[0].m_loadOperation = 
+		AttachmentLoadOperation::DONT_CARE;
 	ANKI_CHECK(fb.create(cmdb, fbInit));
 
 	cmdb.finish();
@@ -168,12 +170,12 @@ Error Hdr::run(CommandBufferHandle& cmdb)
 		}
 
 		// hpass
-		m_hblurFb.bind(cmdb, true);
+		m_hblurFb.bind(cmdb);
 		m_hblurPpline.bind(cmdb);		
 		m_r->drawQuad(cmdb);
 
 		// vpass
-		m_vblurFb.bind(cmdb, true);
+		m_vblurFb.bind(cmdb);
 		m_vblurPpline.bind(cmdb);
 		m_r->drawQuad(cmdb);
 	}

+ 3 - 2
src/renderer/Is.cpp

@@ -227,6 +227,8 @@ Error Is::initInternal(const ConfigSet& config)
 	FramebufferHandle::Initializer fbInit;
 	fbInit.m_colorAttachmentsCount = 1;
 	fbInit.m_colorAttachments[0].m_texture = m_rt;
+	fbInit.m_colorAttachments[0].m_loadOperation = 
+		AttachmentLoadOperation::DONT_CARE;
 	ANKI_CHECK(m_fb.create(cmdBuff, fbInit));
 
 	//
@@ -772,8 +774,7 @@ void Is::setState(CommandBufferHandle& cmdBuff)
 	}
 	else
 	{
-		m_fb.bind(cmdBuff, true);
-
+		m_fb.bind(cmdBuff);
 		cmdBuff.setViewport(0, 0, m_r->getWidth(), m_r->getHeight());
 	}
 }

+ 3 - 1
src/renderer/Lf.cpp

@@ -177,6 +177,8 @@ Error Lf::initInternal(const ConfigSet& config)
 	FramebufferHandle::Initializer fbInit;
 	fbInit.m_colorAttachmentsCount = 1;
 	fbInit.m_colorAttachments[0].m_texture = m_rt;
+	fbInit.m_colorAttachments[0].m_loadOperation = 
+		AttachmentLoadOperation::DONT_CARE;
 	ANKI_CHECK(m_fb.create(cmdBuff, fbInit));
 
 	// Blit
@@ -276,7 +278,7 @@ Error Lf::run(CommandBufferHandle& cmdBuff)
 	//
 
 	// Set the common state
-	m_fb.bind(cmdBuff, true);
+	m_fb.bind(cmdBuff);
 	cmdBuff.setViewport(0, 0, m_r->getPps().getHdr()._getWidth(), 
 		m_r->getPps().getHdr()._getHeight());
 

+ 16 - 32
src/renderer/Ms.cpp

@@ -21,54 +21,38 @@ Ms::~Ms()
 //==============================================================================
 Error Ms::createRt(U32 index, U32 samples)
 {
-	Error err = ErrorCode::NONE;
-
 	Plane& plane = m_planes[index];
 
-	err = m_r->createRenderTarget(m_r->getWidth(), m_r->getHeight(),
-		GL_DEPTH_COMPONENT24, samples, plane.m_depthRt);
-	if(err)
-	{
-		return err;
-	}
+	ANKI_CHECK(m_r->createRenderTarget(m_r->getWidth(), m_r->getHeight(),
+		GL_DEPTH_COMPONENT24, samples, plane.m_depthRt));
 
-	err = m_r->createRenderTarget(m_r->getWidth(), m_r->getHeight(), GL_RGBA8,
-			samples, plane.m_rt0);
-	if(err)
-	{
-		return err;
-	}
+	ANKI_CHECK(m_r->createRenderTarget(m_r->getWidth(), m_r->getHeight(), 
+		GL_RGBA8, samples, plane.m_rt0));
 
-	err = m_r->createRenderTarget(m_r->getWidth(), m_r->getHeight(), GL_RGBA8,
-		samples, plane.m_rt1);
-	if(err)
-	{
-		return err;
-	}
+	ANKI_CHECK(m_r->createRenderTarget(m_r->getWidth(), m_r->getHeight(), 
+		GL_RGBA8, samples, plane.m_rt1));
 
 	GrManager& gl = getGrManager();
 	CommandBufferHandle cmdb;
-	err = cmdb.create(&gl);
-	if(err)
-	{
-		return err;
-	}
+	ANKI_CHECK(cmdb.create(&gl));
 
 	FramebufferHandle::Initializer fbInit;
 	fbInit.m_colorAttachmentsCount = 2;
 	fbInit.m_colorAttachments[0].m_texture = plane.m_rt0;
+	fbInit.m_colorAttachments[0].m_loadOperation = 
+		AttachmentLoadOperation::DONT_CARE;
 	fbInit.m_colorAttachments[1].m_texture = plane.m_rt1;
+	fbInit.m_colorAttachments[1].m_loadOperation = 
+		AttachmentLoadOperation::DONT_CARE;
 	fbInit.m_depthStencilAttachment.m_texture = plane.m_depthRt;
+	fbInit.m_depthStencilAttachment.m_loadOperation = 
+		AttachmentLoadOperation::CLEAR;
+	fbInit.m_depthStencilAttachment.m_clearColor.m_float[0] = 1.0;
 
-	err = plane.m_fb.create(cmdb, fbInit);
-	if(err)
-	{
-		return err;
-	}
-
+	ANKI_CHECK(plane.m_fb.create(cmdb, fbInit));
 	cmdb.finish();
 
-	return err;
+	return ErrorCode::NONE;
 }
 
 //==============================================================================

+ 8 - 11
src/renderer/Pps.cpp

@@ -53,6 +53,8 @@ Error Pps::initInternal(const ConfigSet& config)
 	FramebufferHandle::Initializer fbInit;
 	fbInit.m_colorAttachmentsCount = 1;
 	fbInit.m_colorAttachments[0].m_texture = m_rt;
+	fbInit.m_colorAttachments[0].m_loadOperation = 
+		AttachmentLoadOperation::DONT_CARE;
 	ANKI_CHECK(m_fb.create(cmdBuff, fbInit));
 
 	// SProg
@@ -98,32 +100,27 @@ Error Pps::init(const ConfigSet& config)
 Error Pps::run(CommandBufferHandle& cmdBuff)
 {
 	ANKI_ASSERT(m_enabled);
-	Error err = ErrorCode::NONE;
 
 	// First SSAO because it depends on MS where HDR depends on IS
 	if(m_ssao.getEnabled())
 	{
-		err = m_ssao.run(cmdBuff);
-		if(err) return err;
+		ANKI_CHECK(m_ssao.run(cmdBuff));
 	}
 
 	// Then SSLR because HDR depends on it
 	if(m_sslr.getEnabled())
 	{
-		err = m_sslr.run(cmdBuff);
-		if(err) return err;
+		ANKI_CHECK(m_sslr.run(cmdBuff));
 	}
 
 	if(m_hdr.getEnabled())
 	{
-		err = m_hdr.run(cmdBuff);
-		if(err) return err;
+		ANKI_CHECK(m_hdr.run(cmdBuff));
 	}
 
 	if(m_lf.getEnabled())
 	{
-		err = m_lf.run(cmdBuff);
-		if(err) return err;
+		ANKI_CHECK(m_lf.run(cmdBuff));
 	}
 
 	/*Bool drawToDefaultFbo = 
@@ -141,7 +138,7 @@ Error Pps::run(CommandBufferHandle& cmdBuff)
 	}
 	else
 	{
-		m_fb.bind(cmdBuff, true);
+		m_fb.bind(cmdBuff);
 		cmdBuff.setViewport(0, 0, m_r->getWidth(), m_r->getHeight());
 	}
 
@@ -165,7 +162,7 @@ Error Pps::run(CommandBufferHandle& cmdBuff)
 
 	m_r->drawQuad(cmdBuff);
 
-	return err;
+	return ErrorCode::NONE;
 }
 
 } // end namespace anki

+ 3 - 0
src/renderer/Sm.cpp

@@ -73,6 +73,9 @@ Error Sm::init(const ConfigSet& initializer)
 		FramebufferHandle::Initializer fbInit;
 		fbInit.m_depthStencilAttachment.m_texture = m_sm2DArrayTex;
 		fbInit.m_depthStencilAttachment.m_layer = layer;
+		fbInit.m_depthStencilAttachment.m_loadOperation = 
+			AttachmentLoadOperation::CLEAR;
+		fbInit.m_depthStencilAttachment.m_clearColor.m_float[0] = 1.0;
 		ANKI_CHECK(sm.m_fb.create(cmdBuff, fbInit));
 
 		++layer;

+ 5 - 3
src/renderer/Ssao.cpp

@@ -80,6 +80,8 @@ Error Ssao::createFb(FramebufferHandle& fb, TextureHandle& rt)
 	FramebufferHandle::Initializer fbInit;
 	fbInit.m_colorAttachmentsCount = 1;
 	fbInit.m_colorAttachments[0].m_texture = rt;
+	fbInit.m_colorAttachments[0].m_loadOperation = 
+		AttachmentLoadOperation::DONT_CARE;
 	ANKI_CHECK(fb.create(cmdBuff, fbInit));
 
 	cmdBuff.flush();
@@ -242,7 +244,7 @@ Error Ssao::run(CommandBufferHandle& cmdb)
 
 	// 1st pass
 	//
-	m_vblurFb.bind(cmdb, true);
+	m_vblurFb.bind(cmdb);
 	m_ssaoPpline.bind(cmdb);
 
 	m_uniformsBuff.bindShaderBuffer(cmdb, 0);
@@ -283,12 +285,12 @@ Error Ssao::run(CommandBufferHandle& cmdb)
 		}
 
 		// hpass
-		m_hblurFb.bind(cmdb, true);
+		m_hblurFb.bind(cmdb);
 		m_hblurPpline.bind(cmdb);
 		m_r->drawQuad(cmdb);
 
 		// vpass
-		m_vblurFb.bind(cmdb, true);
+		m_vblurFb.bind(cmdb);
 		m_vblurPpline.bind(cmdb);
 		m_r->drawQuad(cmdb);
 	}

+ 3 - 1
src/renderer/Sslr.cpp

@@ -75,6 +75,8 @@ Error Sslr::init(const ConfigSet& config)
 		FramebufferHandle::Initializer fbInit;
 		fbInit.m_colorAttachmentsCount = 1;
 		fbInit.m_colorAttachments[0].m_texture = dir.m_rt;
+		fbInit.m_colorAttachments[0].m_loadOperation = 
+			AttachmentLoadOperation::DONT_CARE;
 		ANKI_CHECK(dir.m_fb.create(cmdBuff, fbInit));
 	}
 
@@ -90,7 +92,7 @@ Error Sslr::run(CommandBufferHandle& cmdBuff)
 
 	// Compute the reflection
 	//
-	m_dirs[(U)DirectionEnum::VERTICAL].m_fb.bind(cmdBuff, true);
+	m_dirs[(U)DirectionEnum::VERTICAL].m_fb.bind(cmdBuff);
 	cmdBuff.setViewport(0, 0, m_width, m_height);
 
 	m_reflectionPpline.bind(cmdBuff);

+ 3 - 1
src/renderer/Tiler.cpp

@@ -111,6 +111,8 @@ Error Tiler::initInternal()
 	FramebufferHandle::Initializer fbInit;
 	fbInit.m_colorAttachmentsCount = 1;
 	fbInit.m_colorAttachments[0].m_texture = m_rt;
+	fbInit.m_colorAttachments[0].m_loadOperation = 
+		AttachmentLoadOperation::DONT_CARE;
 	ANKI_CHECK(m_fb.create(cmdBuff, fbInit));
 
 	// Init planes. One plane for each direction, plus near/far plus the world
@@ -194,7 +196,7 @@ void Tiler::runMinMax(TextureHandle& depthMap,
 	if(m_enableGpuTests)
 	{
 		// Issue the min/max job
-		m_fb.bind(cmd, true);
+		m_fb.bind(cmd);
 		m_ppline.bind(cmd);
 		depthMap.bind(cmd, 0);
 		cmd.setViewport(