Browse Source

Fixing Dbg & fixing a bug in GL vertex state

Panagiotis Christopoulos Charitos 9 years ago
parent
commit
ea966ecf7a

+ 8 - 1
include/anki/gr/gl/GlState.h

@@ -48,11 +48,16 @@ public:
 	GLenum m_blendDfunc = GL_ZERO;
 	GLenum m_blendDfunc = GL_ZERO;
 	/// @}
 	/// @}
 
 
-	/// @name Pipeline state
+	/// @name Pipeline/resource group state
 	/// @{
 	/// @{
 	U64 m_lastPplineBoundUuid = MAX_U64;
 	U64 m_lastPplineBoundUuid = MAX_U64;
 
 
+	Array<GLuint, MAX_VERTEX_ATTRIBUTES> m_vertBuffNames;
+	Array<GLintptr, MAX_VERTEX_ATTRIBUTES> m_vertBuffOffsets;
 	Array<GLsizei, MAX_VERTEX_ATTRIBUTES> m_vertexBindingStrides;
 	Array<GLsizei, MAX_VERTEX_ATTRIBUTES> m_vertexBindingStrides;
+	U8 m_vertBindingCount = 0;
+	Bool8 m_vertBindingsDirty = true;
+
 	GLenum m_topology = 0;
 	GLenum m_topology = 0;
 	U8 m_indexSize = 4;
 	U8 m_indexSize = 4;
 
 
@@ -115,6 +120,8 @@ public:
 
 
 	void checkDynamicMemoryConsumption();
 	void checkDynamicMemoryConsumption();
 
 
+	void flushVertexState();
+
 private:
 private:
 	GrManager* m_manager;
 	GrManager* m_manager;
 
 

+ 23 - 27
include/anki/renderer/DebugDrawer.h

@@ -31,22 +31,16 @@ public:
 	DebugDrawer();
 	DebugDrawer();
 	~DebugDrawer();
 	~DebugDrawer();
 
 
-	ANKI_USE_RESULT Error create(Renderer* r);
+	ANKI_USE_RESULT Error init(Renderer* r);
 
 
 	void drawGrid();
 	void drawGrid();
 	void drawSphere(F32 radius, I complexity = 8);
 	void drawSphere(F32 radius, I complexity = 8);
 	void drawCube(F32 size = 1.0);
 	void drawCube(F32 size = 1.0);
 	void drawLine(const Vec3& from, const Vec3& to, const Vec4& color);
 	void drawLine(const Vec3& from, const Vec3& to, const Vec4& color);
 
 
-	void prepareDraw(CommandBufferPtr& jobs)
-	{
-		m_cmdb = jobs;
-	}
+	void prepareFrame(CommandBufferPtr& jobs);
 
 
-	void finishDraw()
-	{
-		m_cmdb = CommandBufferPtr(); // Release job chain
-	}
+	void finishFrame();
 
 
 	/// @name Render functions. Imitate the GL 1.1 immediate mode
 	/// @name Render functions. Imitate the GL 1.1 immediate mode
 	/// @{
 	/// @{
@@ -83,9 +77,6 @@ public:
 		return m_depthTestEnabled;
 		return m_depthTestEnabled;
 	}
 	}
 
 
-	/// This is the function that actualy draws
-	ANKI_USE_RESULT Error flush();
-
 private:
 private:
 	class Vertex
 	class Vertex
 	{
 	{
@@ -94,33 +85,38 @@ private:
 		Vec4 m_color;
 		Vec4 m_color;
 	};
 	};
 
 
+	static const U MAX_VERTS_PER_FRAME = 1024 * 1024;
+
 	Renderer* m_r;
 	Renderer* m_r;
 	ShaderResourcePtr m_frag;
 	ShaderResourcePtr m_frag;
 	ShaderResourcePtr m_vert;
 	ShaderResourcePtr m_vert;
-	PipelinePtr m_pplineLinesDepth;
-	PipelinePtr m_pplineLinesNoDepth;
+	Array2d<PipelinePtr, 2, 2> m_pplines;
+	Array<ResourceGroupPtr, MAX_FRAMES_IN_FLIGHT> m_rcGroup;
+	Array<BufferPtr, MAX_FRAMES_IN_FLIGHT> m_vertBuff;
+
 	CommandBufferPtr m_cmdb;
 	CommandBufferPtr m_cmdb;
-	ResourceGroupPtr m_rcGroup;
+	WArray<Vertex> m_clientVerts;
 
 
-	static const U MAX_POINTS_PER_DRAW = 256;
 	Mat4 m_mMat;
 	Mat4 m_mMat;
 	Mat4 m_vpMat;
 	Mat4 m_vpMat;
-	Mat4 m_mvpMat; ///< Optimization
-	U32 m_lineVertCount;
-	U32 m_triVertCount;
-	Vec3 m_crntCol;
-	PrimitiveTopology m_primitive;
-
-	BufferPtr m_vertBuff;
-
-	Array<Vertex, MAX_POINTS_PER_DRAW> m_clientLineVerts;
-	Array<Vertex, MAX_POINTS_PER_DRAW> m_clientTriVerts;
+	Mat4 m_mvpMat; ///< Optimization.
+	Vec3 m_crntCol = Vec3(1.0, 0.0, 0.0);
+	PrimitiveTopology m_primitive = PrimitiveTopology::LINES;
+	U32 m_frameVertCount = 0;
+	U32 m_crntDrawVertCount = 0;
 
 
 	DArray<Vec3> m_sphereVerts;
 	DArray<Vec3> m_sphereVerts;
 
 
 	Bool8 m_depthTestEnabled = true;
 	Bool8 m_depthTestEnabled = true;
 
 
-	ANKI_USE_RESULT Error flushInternal(PrimitiveTopology topology);
+	PipelinePtr& getPpline(Bool depth, PrimitiveTopology topology)
+	{
+		U i = (depth == false) ? 0 : 1;
+		U j = (topology == PrimitiveTopology::LINES) ? 0 : 1;
+		return m_pplines[i][j];
+	}
+
+	void flush();
 };
 };
 
 
 /// Contains methods to render the collision shapes
 /// Contains methods to render the collision shapes

+ 4 - 0
src/gr/gl/CommandBuffer.cpp

@@ -292,6 +292,8 @@ public:
 
 
 		if(!m_query.isCreated() || !m_query->getImplementation().skipDrawcall())
 		if(!m_query.isCreated() || !m_query->getImplementation().skipDrawcall())
 		{
 		{
+			state.flushVertexState();
+
 			glDrawElementsInstancedBaseVertexBaseInstance(state.m_topology,
 			glDrawElementsInstancedBaseVertexBaseInstance(state.m_topology,
 				m_info.m_count,
 				m_info.m_count,
 				indicesType,
 				indicesType,
@@ -341,6 +343,8 @@ public:
 	{
 	{
 		if(!m_query.isCreated() || !m_query->getImplementation().skipDrawcall())
 		if(!m_query.isCreated() || !m_query->getImplementation().skipDrawcall())
 		{
 		{
+			state.flushVertexState();
+
 			glDrawArraysInstancedBaseInstance(state.m_topology,
 			glDrawArraysInstancedBaseInstance(state.m_topology,
 				m_info.m_first,
 				m_info.m_first,
 				m_info.m_count,
 				m_info.m_count,

+ 15 - 0
src/gr/gl/GlState.cpp

@@ -263,4 +263,19 @@ void GlState::destroy()
 	m_transferBuffer.destroy(m_manager->getAllocator());
 	m_transferBuffer.destroy(m_manager->getAllocator());
 }
 }
 
 
+//==============================================================================
+void GlState::flushVertexState()
+{
+	if(m_vertBindingsDirty)
+	{
+		m_vertBindingsDirty = false;
+
+		glBindVertexBuffers(0,
+			m_vertBindingCount,
+			&m_vertBuffNames[0],
+			&m_vertBuffOffsets[0],
+			&m_vertexBindingStrides[0]);
+	}
+}
+
 } // end namespace anki
 } // end namespace anki

+ 6 - 0
src/gr/gl/PipelineImpl.cpp

@@ -485,6 +485,12 @@ void PipelineImpl::setVertexState(GlState& state) const
 		ANKI_ASSERT(m_in.m_vertex.m_bindings[i].m_stride > 0);
 		ANKI_ASSERT(m_in.m_vertex.m_bindings[i].m_stride > 0);
 		state.m_vertexBindingStrides[i] = m_in.m_vertex.m_bindings[i].m_stride;
 		state.m_vertexBindingStrides[i] = m_in.m_vertex.m_bindings[i].m_stride;
 	}
 	}
+
+	if(m_in.m_vertex.m_bindingCount)
+	{
+		state.m_vertBindingCount = m_in.m_vertex.m_bindingCount;
+		state.m_vertBindingsDirty = true;
+	}
 }
 }
 
 
 //==============================================================================
 //==============================================================================

+ 12 - 9
src/gr/gl/ResourceGroupImpl.cpp

@@ -352,11 +352,9 @@ void ResourceGroupImpl::bind(
 
 
 		if(!m_hasDynamicVertexBuff)
 		if(!m_hasDynamicVertexBuff)
 		{
 		{
-			glBindVertexBuffers(0,
-				m_vertBindingsCount,
-				&m_vertBuffNames[0],
+			memcpy(&state.m_vertBuffOffsets[0],
 				&m_vertBuffOffsets[0],
 				&m_vertBuffOffsets[0],
-				&state.m_vertexBindingStrides[0]);
+				sizeof(m_vertBuffOffsets[0]) * m_vertBindingsCount);
 		}
 		}
 		else
 		else
 		{
 		{
@@ -376,13 +374,18 @@ void ResourceGroupImpl::bind(
 				}
 				}
 			}
 			}
 
 
-			// Bind
-			glBindVertexBuffers(0,
-				m_vertBindingsCount,
-				&m_vertBuffNames[0],
+			// Bind to state
+			memcpy(&state.m_vertBuffOffsets[0],
 				&offsets[0],
 				&offsets[0],
-				&state.m_vertexBindingStrides[0]);
+				sizeof(offsets[0]) * m_vertBindingsCount);
 		}
 		}
+
+		memcpy(&state.m_vertBuffNames[0],
+			&m_vertBuffNames[0],
+			sizeof(m_vertBuffNames[0]) * m_vertBindingsCount);
+
+		state.m_vertBindingCount = m_vertBindingsCount;
+		state.m_vertBindingsDirty = true;
 	}
 	}
 
 
 	// Index buffer
 	// Index buffer

+ 3 - 4
src/renderer/Dbg.cpp

@@ -66,7 +66,7 @@ Error Dbg::init(const ConfigSet& initializer)
 	m_fb = getGrManager().newInstance<Framebuffer>(fbInit);
 	m_fb = getGrManager().newInstance<Framebuffer>(fbInit);
 
 
 	m_drawer = getAllocator().newInstance<DebugDrawer>();
 	m_drawer = getAllocator().newInstance<DebugDrawer>();
-	ANKI_CHECK(m_drawer->create(m_r));
+	ANKI_CHECK(m_drawer->init(m_r));
 
 
 	getGrManager().finish();
 	getGrManager().finish();
 	return ErrorCode::NONE;
 	return ErrorCode::NONE;
@@ -84,7 +84,7 @@ Error Dbg::run(RenderingContext& ctx)
 
 
 	FrustumComponent& camFr = *ctx.m_frustumComponent;
 	FrustumComponent& camFr = *ctx.m_frustumComponent;
 	SceneNode& cam = camFr.getSceneNode();
 	SceneNode& cam = camFr.getSceneNode();
-	m_drawer->prepareDraw(cmdb);
+	m_drawer->prepareFrame(cmdb);
 	m_drawer->setViewProjectionMatrix(camFr.getViewProjectionMatrix());
 	m_drawer->setViewProjectionMatrix(camFr.getViewProjectionMatrix());
 	m_drawer->setModelMatrix(Mat4::getIdentity());
 	m_drawer->setModelMatrix(Mat4::getIdentity());
 	// m_drawer->drawGrid();
 	// m_drawer->drawGrid();
@@ -242,8 +242,7 @@ Error Dbg::run(RenderingContext& ctx)
 	}
 	}
 #endif
 #endif
 
 
-	ANKI_CHECK(m_drawer->flush());
-
+	m_drawer->finishFrame();
 	cmdb->endRenderPass();
 	cmdb->endRenderPass();
 	return ErrorCode::NONE;
 	return ErrorCode::NONE;
 }
 }

+ 82 - 100
src/renderer/DebugDrawer.cpp

@@ -33,11 +33,12 @@ DebugDrawer::~DebugDrawer()
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-Error DebugDrawer::create(Renderer* r)
+Error DebugDrawer::init(Renderer* r)
 {
 {
 	m_r = r;
 	m_r = r;
 	GrManager& gr = r->getGrManager();
 	GrManager& gr = r->getGrManager();
 
 
+	// Create the pipelines
 	ANKI_CHECK(
 	ANKI_CHECK(
 		r->getResourceManager().loadResource("shaders/Dbg.vert.glsl", m_vert));
 		r->getResourceManager().loadResource("shaders/Dbg.vert.glsl", m_vert));
 	ANKI_CHECK(
 	ANKI_CHECK(
@@ -63,29 +64,72 @@ Error DebugDrawer::create(Renderer* r)
 	init.m_shaders[U(ShaderType::VERTEX)] = m_vert->getGrShader();
 	init.m_shaders[U(ShaderType::VERTEX)] = m_vert->getGrShader();
 	init.m_shaders[U(ShaderType::FRAGMENT)] = m_frag->getGrShader();
 	init.m_shaders[U(ShaderType::FRAGMENT)] = m_frag->getGrShader();
 
 
-	m_pplineLinesDepth = gr.newInstance<Pipeline>(init);
+	getPpline(true, PrimitiveTopology::LINES) = gr.newInstance<Pipeline>(init);
+
+	init.m_inputAssembler.m_topology = PrimitiveTopology::TRIANGLES;
+	getPpline(true, PrimitiveTopology::TRIANGLES) =
+		gr.newInstance<Pipeline>(init);
 
 
 	init.m_depthStencil.m_depthCompareFunction = CompareOperation::ALWAYS;
 	init.m_depthStencil.m_depthCompareFunction = CompareOperation::ALWAYS;
-	m_pplineLinesNoDepth = gr.newInstance<Pipeline>(init);
+	getPpline(false, PrimitiveTopology::TRIANGLES) =
+		gr.newInstance<Pipeline>(init);
 
 
-	m_vertBuff = gr.newInstance<Buffer>(sizeof(m_clientLineVerts),
-		BufferUsageBit::VERTEX,
-		BufferAccessBit::CLIENT_WRITE);
+	init.m_inputAssembler.m_topology = PrimitiveTopology::LINES;
+	getPpline(false, PrimitiveTopology::LINES) = gr.newInstance<Pipeline>(init);
 
 
-	ResourceGroupInitInfo rcinit;
-	rcinit.m_vertexBuffers[0].m_buffer = m_vertBuff;
-	m_rcGroup = gr.newInstance<ResourceGroup>(rcinit);
+	// Create the vert buffs
+	for(BufferPtr& v : m_vertBuff)
+	{
+		v = gr.newInstance<Buffer>(sizeof(Vertex) * MAX_VERTS_PER_FRAME,
+			BufferUsageBit::VERTEX,
+			BufferAccessBit::CLIENT_MAP_WRITE);
+	}
+
+	// Create the resouce groups
+	U c = 0;
+	for(ResourceGroupPtr& rc : m_rcGroup)
+	{
+		ResourceGroupInitInfo rcinit;
+		rcinit.m_vertexBuffers[0].m_buffer = m_vertBuff[c++];
+		rc = gr.newInstance<ResourceGroup>(rcinit);
+	}
 
 
-	m_lineVertCount = 0;
-	m_triVertCount = 0;
 	m_mMat.setIdentity();
 	m_mMat.setIdentity();
 	m_vpMat.setIdentity();
 	m_vpMat.setIdentity();
 	m_mvpMat.setIdentity();
 	m_mvpMat.setIdentity();
-	m_crntCol = Vec3(1.0, 0.0, 0.0);
 
 
 	return ErrorCode::NONE;
 	return ErrorCode::NONE;
 }
 }
 
 
+//==============================================================================
+void DebugDrawer::prepareFrame(CommandBufferPtr& jobs)
+{
+	m_cmdb = jobs;
+
+	U frame = m_r->getFrameCount() % MAX_FRAMES_IN_FLIGHT;
+	void* mapped = m_vertBuff[frame]->map(0,
+		MAX_VERTS_PER_FRAME * sizeof(Vertex),
+		BufferAccessBit::CLIENT_MAP_WRITE);
+	m_clientVerts =
+		WArray<Vertex>(static_cast<Vertex*>(mapped), MAX_VERTS_PER_FRAME);
+
+	m_cmdb->bindResourceGroup(m_rcGroup[frame], 0, nullptr);
+
+	m_frameVertCount = 0;
+	m_crntDrawVertCount = 0;
+}
+
+//==============================================================================
+void DebugDrawer::finishFrame()
+{
+	U frame = m_r->getFrameCount() % MAX_FRAMES_IN_FLIGHT;
+	m_vertBuff[frame]->unmap();
+
+	flush();
+
+	m_cmdb = CommandBufferPtr(); // Release job chain
+}
+
 //==============================================================================
 //==============================================================================
 void DebugDrawer::setModelMatrix(const Mat4& m)
 void DebugDrawer::setModelMatrix(const Mat4& m)
 {
 {
@@ -105,118 +149,56 @@ void DebugDrawer::begin(PrimitiveTopology topology)
 {
 {
 	ANKI_ASSERT(topology == PrimitiveTopology::LINES
 	ANKI_ASSERT(topology == PrimitiveTopology::LINES
 		|| topology == PrimitiveTopology::TRIANGLES);
 		|| topology == PrimitiveTopology::TRIANGLES);
-	m_primitive = topology;
-}
 
 
-//==============================================================================
-void DebugDrawer::end()
-{
-	if(m_primitive == PrimitiveTopology::LINES)
+	if(topology != m_primitive)
 	{
 	{
-		if(m_lineVertCount % 2 != 0)
-		{
-			pushBackVertex(Vec3(0.0));
-			ANKI_LOGW("Forgot to close the line loop");
-		}
-	}
-	else
-	{
-		if(m_triVertCount % 3 != 0)
-		{
-			pushBackVertex(Vec3(0.0));
-			pushBackVertex(Vec3(0.0));
-			ANKI_LOGW("Forgot to close the line loop");
-		}
+		flush();
 	}
 	}
+
+	m_primitive = topology;
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-Error DebugDrawer::flush()
+void DebugDrawer::end()
 {
 {
-	Error err = flushInternal(PrimitiveTopology::LINES);
-
-	if(!err)
-	{
-		err = flushInternal(PrimitiveTopology::TRIANGLES);
-	}
-
-	return err;
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-Error DebugDrawer::flushInternal(PrimitiveTopology topology)
+void DebugDrawer::pushBackVertex(const Vec3& pos)
 {
 {
-	if((m_primitive == PrimitiveTopology::LINES && m_lineVertCount == 0)
-		|| (m_primitive == PrimitiveTopology::TRIANGLES && m_triVertCount == 0))
-	{
-		// Early exit
-		return ErrorCode::NONE;
-	}
-
-	U clientVerts;
-	void* vertBuff;
-	if(m_primitive == PrimitiveTopology::LINES)
-	{
-		clientVerts = m_lineVertCount;
-		vertBuff = &m_clientLineVerts[0];
-		m_lineVertCount = 0;
-	}
-	else
+	if(m_frameVertCount < MAX_VERTS_PER_FRAME)
 	{
 	{
-		clientVerts = m_triVertCount;
-		vertBuff = &m_clientTriVerts[0];
-		m_triVertCount = 0;
-	}
-
-	U size = sizeof(Vertex) * clientVerts;
+		m_clientVerts[m_frameVertCount].m_position = m_mvpMat * Vec4(pos, 1.0);
+		m_clientVerts[m_frameVertCount].m_color = Vec4(m_crntCol, 1.0);
 
 
-	DynamicBufferToken token;
-	void* data = m_r->getGrManager().allocateFrameHostVisibleMemory(
-		size, BufferUsage::TRANSFER, token);
-	memcpy(data, vertBuff, size);
-	m_cmdb->writeBuffer(m_vertBuff, 0, token);
-
-	if(m_depthTestEnabled)
-	{
-		m_cmdb->bindPipeline(m_pplineLinesDepth);
+		++m_frameVertCount;
+		++m_crntDrawVertCount;
 	}
 	}
 	else
 	else
 	{
 	{
-		m_cmdb->bindPipeline(m_pplineLinesNoDepth);
+		ANKI_LOGW("Increase DebugDrawer::MAX_VERTS_PER_FRAME");
 	}
 	}
-
-	m_cmdb->bindResourceGroup(m_rcGroup, 0, nullptr);
-	m_cmdb->drawArrays(clientVerts);
-
-	return ErrorCode::NONE;
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-void DebugDrawer::pushBackVertex(const Vec3& pos)
+void DebugDrawer::flush()
 {
 {
-	U32* vertCount;
-	Vertex* vertBuff;
-	if(m_primitive == PrimitiveTopology::LINES)
-	{
-		vertCount = &m_lineVertCount;
-		vertBuff = &m_clientLineVerts[0];
-	}
-	else
+	if(m_crntDrawVertCount > 0)
 	{
 	{
-		vertCount = &m_triVertCount;
-		vertBuff = &m_clientTriVerts[0];
-	}
-
-	vertBuff[*vertCount].m_position = m_mvpMat * Vec4(pos, 1.0);
-	vertBuff[*vertCount].m_color = Vec4(m_crntCol, 1.0);
+		if(m_primitive == PrimitiveTopology::LINES)
+		{
+			ANKI_ASSERT((m_crntDrawVertCount % 2) == 0);
+		}
+		else
+		{
+			ANKI_ASSERT((m_crntDrawVertCount % 3) == 0);
+		}
 
 
-	++(*vertCount);
+		m_cmdb->bindPipeline(getPpline(m_depthTestEnabled, m_primitive));
+		U firstVert = m_frameVertCount - m_crntDrawVertCount;
+		m_cmdb->drawArrays(m_crntDrawVertCount, 1, firstVert);
 
 
-	if(*vertCount == MAX_POINTS_PER_DRAW)
-	{
-		Error err = flush();
-		// TODO Don't ignore
-		(void)err;
+		m_crntDrawVertCount = 0;
 	}
 	}
 }
 }