Browse Source

GR interface: Work on restoring state after 2nd level command buffers

Panagiotis Christopoulos Charitos 9 years ago
parent
commit
81c41449ea

+ 25 - 6
src/anki/gr/gl/CommandBuffer.cpp

@@ -873,7 +873,25 @@ void CommandBuffer::beginRenderPass(FramebufferPtr fb)
 
 void CommandBuffer::endRenderPass()
 {
-	// Nothing for GL
+// Restore state
+#if 0
+	if(m_impl->m_state.m_lastSecondLevelCmdb)
+	{
+		// Renderpass had 2nd level cmdbs, need to restore the state
+
+		const StateTracker& olds = m_impl->m_state.m_lastSecondLevelCmdb->m_state;
+		StateTracker& news = m_impl->m_state;
+
+		// Vertex state
+		class VertIndexStateCmd final : public GlCommand
+		{
+		public:
+			Array<StateTracker::VertexAttribute, MAX_VERTEX_ATTRIBUTES> m_attribs;
+			Array<StateTracker::VertexBuffer, MAX_VERTEX_ATTRIBUTES> m_vertBuffs;
+		};
+	}
+#endif
+
 	m_impl->m_state.endRenderPass();
 }
 
@@ -914,20 +932,20 @@ void CommandBuffer::drawElements(
 	m_impl->flushDrawcall(*this);
 
 	U idxBytes;
-	if(m_impl->m_state.m_indexType == GL_UNSIGNED_SHORT)
+	if(m_impl->m_state.m_idx.m_indexType == GL_UNSIGNED_SHORT)
 	{
 		idxBytes = sizeof(U16);
 	}
 	else
 	{
-		ANKI_ASSERT(m_impl->m_state.m_indexType == GL_UNSIGNED_INT);
+		ANKI_ASSERT(m_impl->m_state.m_idx.m_indexType == GL_UNSIGNED_INT);
 		idxBytes = sizeof(U32);
 	}
 
-	firstIndex = firstIndex + m_impl->m_state.m_indexBuffOffset / idxBytes;
+	firstIndex = firstIndex + m_impl->m_state.m_idx.m_offset / idxBytes;
 
 	DrawElementsIndirectInfo info(count, instanceCount, firstIndex, baseVertex, baseInstance);
-	m_impl->pushBackNewCommand<Cmd>(convertPrimitiveTopology(topology), m_impl->m_state.m_indexType, info);
+	m_impl->pushBackNewCommand<Cmd>(convertPrimitiveTopology(topology), m_impl->m_state.m_idx.m_indexType, info);
 }
 
 void CommandBuffer::drawArrays(PrimitiveTopology topology, U32 count, U32 instanceCount, U32 first, U32 baseInstance)
@@ -1004,7 +1022,7 @@ void CommandBuffer::drawElementsIndirect(
 	m_impl->m_state.checkIndexedDracall();
 	m_impl->flushDrawcall(*this);
 	m_impl->pushBackNewCommand<DrawElementsIndirectCommand>(
-		convertPrimitiveTopology(topology), m_impl->m_state.m_indexType, drawCount, offset, indirectBuff);
+		convertPrimitiveTopology(topology), m_impl->m_state.m_idx.m_indexType, drawCount, offset, indirectBuff);
 }
 
 void CommandBuffer::drawArraysIndirect(
@@ -1293,6 +1311,7 @@ void CommandBuffer::pushSecondLevelCommandBuffer(CommandBufferPtr cmdb)
 		}
 	};
 
+	m_impl->m_state.m_lastSecondLevelCmdb = cmdb->m_impl.get();
 	m_impl->pushBackNewCommand<ExecCmdbCommand>(cmdb);
 }
 

+ 8 - 2
src/anki/gr/gl/CommandBufferImpl.cpp

@@ -250,7 +250,10 @@ void CommandBufferImpl::flushDrawcall(CommandBuffer& cmdb)
 		}
 	};
 
-	m_state.maybeEnableDepthTest([=](Bool enable) { pushBackNewCommand<DepthTestCmd>(enable); });
+	if(m_state.maybeEnableDepthTest())
+	{
+		pushBackNewCommand<DepthTestCmd>(m_state.m_depthTestEnabled);
+	}
 
 	class StencilTestCmd final : public GlCommand
 	{
@@ -276,7 +279,10 @@ void CommandBufferImpl::flushDrawcall(CommandBuffer& cmdb)
 		}
 	};
 
-	m_state.maybeEnableStencilTest([=](Bool enable) { pushBackNewCommand<StencilTestCmd>(enable); });
+	if(m_state.maybeEnableStencilTest())
+	{
+		pushBackNewCommand<StencilTestCmd>(m_state.m_stencilTestEnabled);
+	}
 }
 
 } // end namespace anki

+ 21 - 13
src/anki/gr/gl/StateTracker.h

@@ -89,15 +89,19 @@ public:
 		return true;
 	}
 
-	BufferPtr m_indexBuff;
-	PtrSize m_indexBuffOffset = MAX_PTR_SIZE;
-	GLenum m_indexType = 0;
+	class Index
+	{
+	public:
+		BufferPtr m_buff;
+		PtrSize m_offset = MAX_PTR_SIZE;
+		GLenum m_indexType = 0;
+	} m_idx;
 
 	Bool bindIndexBuffer(BufferPtr buff, PtrSize offset, IndexType type)
 	{
-		m_indexBuff = buff;
-		m_indexBuffOffset = offset;
-		m_indexType = convertIndexType(type);
+		m_idx.m_buff = buff;
+		m_idx.m_offset = offset;
+		m_idx.m_indexType = convertIndexType(type);
 		return true;
 	}
 	/// @}
@@ -179,8 +183,7 @@ public:
 	/// @{
 	Bool8 m_stencilTestEnabled = 2;
 
-	template<typename TFunc>
-	void maybeEnableStencilTest(TFunc func)
+	Bool maybeEnableStencilTest()
 	{
 		Bool enable = !stencilTestDisabled(
 			m_stencilFail[0], m_stencilPassDepthFail[0], m_stencilPassDepthPass[0], m_stencilCompare[0]);
@@ -191,8 +194,9 @@ public:
 		if(enable != m_stencilTestEnabled)
 		{
 			m_stencilTestEnabled = enable;
-			func(enable);
+			return true;
 		}
+		return false;
 	}
 
 	Array<StencilOperation, 2> m_stencilFail = {{StencilOperation::COUNT, StencilOperation::COUNT}};
@@ -310,8 +314,7 @@ public:
 
 	Bool8 m_depthTestEnabled = 2; ///< 2 means don't know
 
-	template<typename TFunc>
-	void maybeEnableDepthTest(TFunc func)
+	Bool maybeEnableDepthTest()
 	{
 		ANKI_ASSERT(m_depthWrite != 2 && m_depthOp != CompareOperation::COUNT);
 		Bool enable = m_depthWrite || m_depthOp != CompareOperation::ALWAYS;
@@ -319,8 +322,10 @@ public:
 		if(enable != m_depthTestEnabled)
 		{
 			m_depthTestEnabled = enable;
-			func(enable);
+			return true;
 		}
+
+		return false;
 	}
 
 	Bool8 m_depthWrite = 2;
@@ -510,6 +515,7 @@ public:
 	{
 		ANKI_ASSERT(!insideRenderPass() && "Already inside a renderpass");
 		m_fb = fb;
+		m_lastSecondLevelCmdb = nullptr;
 		return true;
 	}
 
@@ -523,13 +529,15 @@ public:
 	{
 		return m_fb.isCreated();
 	}
+
+	CommandBufferImpl* m_lastSecondLevelCmdb = nullptr;
 	/// @}
 
 	/// @name drawcalls
 	/// @{
 	void checkIndexedDracall() const
 	{
-		ANKI_ASSERT(m_indexType != 0 && "Forgot to bind index buffer");
+		ANKI_ASSERT(m_idx.m_indexType != 0 && "Forgot to bind index buffer");
 		checkDrawcall();
 	}