Browse Source

Some optimizations

Panagiotis Christopoulos Charitos 10 years ago
parent
commit
5770fd3d53

+ 1 - 1
include/anki/gr/gl/RenderingThread.h

@@ -14,7 +14,7 @@ namespace anki {
 /// @addtogroup opengl
 /// @{
 
-#define ANKI_DISABLE_GL_RENDERING_THREAD 1
+#define ANKI_DISABLE_GL_RENDERING_THREAD 0
 
 /// Command queue. It's essentialy a queue of command buffers waiting for
 /// execution and a server

+ 37 - 16
include/anki/gr/gl/ResourceGroupImpl.h

@@ -7,6 +7,7 @@
 
 #include "anki/gr/gl/GlObject.h"
 #include "anki/gr/ResourceGroup.h"
+#include "anki/util/DArray.h"
 
 namespace anki {
 
@@ -22,7 +23,9 @@ public:
 	{}
 
 	~ResourceGroupImpl()
-	{}
+	{
+		m_refs.destroy(getAllocator());
+	}
 
 	void create(const ResourceGroupInitializer& init);
 
@@ -30,23 +33,41 @@ public:
 	void bind(GlState& state);
 
 private:
-	ResourceGroupInitializer m_in; ///< That will hold the references
-
-	class
+	class InternalBufferBinding
 	{
 	public:
-		Array<GLuint, MAX_TEXTURE_BINDINGS> m_textureNames;
-		Array<GLuint, MAX_TEXTURE_BINDINGS> m_samplerNames;
-		U8 m_textureNamesCount = 0;
-		Bool8 m_allSamplersZero = false;
-
-		U8 m_ubosCount = 0;
-		U8 m_ssbosCount = 0;
-
-		Array<GLuint, MAX_VERTEX_ATTRIBUTES> m_vertBuffNames;
-		Array<GLintptr, MAX_VERTEX_ATTRIBUTES> m_vertBuffOffsets;
-		U8 m_vertBindingsCount = 0;
-	} m_cache;
+		GLuint m_name = 0;
+		U32 m_offset = 0;
+		U32 m_range = 0;
+	};
+
+	Array<GLuint, MAX_TEXTURE_BINDINGS> m_textureNames;
+	Array<GLuint, MAX_TEXTURE_BINDINGS> m_samplerNames;
+	U8 m_textureNamesCount = 0;
+	Bool8 m_allSamplersZero = false;
+
+	Array<InternalBufferBinding, MAX_UNIFORM_BUFFER_BINDINGS> m_ubos;
+	U8 m_ubosCount = 0;
+
+	Array<InternalBufferBinding, MAX_STORAGE_BUFFER_BINDINGS> m_ssbos;
+	U8 m_ssbosCount = 0;
+
+	Array<GLuint, MAX_VERTEX_ATTRIBUTES> m_vertBuffNames;
+	Array<GLintptr, MAX_VERTEX_ATTRIBUTES> m_vertBuffOffsets;
+	U8 m_vertBindingsCount = 0;
+
+	GLuint m_indexBuffName = 0;
+	U8 m_indexSize = 0;
+
+	/// Holds the references to the resources. Used to release the references
+	/// gracefully
+	DArray<IntrusivePtr<GrObject>> m_refs;
+
+	template<typename InBindings, typename OutBindings>
+	void initBuffers(const InBindings& in, OutBindings& out, U8& count,
+		U& resourcesCount);
+
+	void initResourceReferences(const ResourceGroupInitializer& init, U count);
 };
 /// @}
 

+ 1 - 3
include/anki/scene/RenderComponent.h

@@ -3,8 +3,7 @@
 // Code licensed under the BSD License.
 // http://www.anki3d.org/LICENSE
 
-#ifndef ANKI_SCENE_RENDER_COMPONENT_H
-#define ANKI_SCENE_RENDER_COMPONENT_H
+#pragma once
 
 #include "anki/scene/Common.h"
 #include "anki/scene/SceneComponent.h"
@@ -298,4 +297,3 @@ private:
 
 } // end namespace anki
 
-#endif

+ 2 - 2
include/anki/util/Ptr.h

@@ -321,8 +321,8 @@ public:
 	}
 
 	/// Copy, compatible.
-	template<typename Y>
-	IntrusivePtr& operator=(const IntrusivePtr<Y, TDeleter>& other)
+	template<typename Y, typename YDeleter>
+	IntrusivePtr& operator=(const IntrusivePtr<Y, YDeleter>& other)
 	{
 		reset(other.m_ptr);
 		return *this;

+ 145 - 70
src/gr/gl/ResourceGroupImpl.cpp

@@ -17,146 +17,221 @@
 
 namespace anki {
 
+//==============================================================================
+template<typename InBindings, typename OutBindings>
+void ResourceGroupImpl::initBuffers(
+	const InBindings& in, OutBindings& out, U8& count, U& resourcesCount)
+{
+	count = 0;
+
+	for(U i = 0; i < in.getSize(); ++i)
+	{
+		const BufferBinding& binding = in[i];
+
+		if(binding.m_buffer.isCreated())
+		{
+			const BufferImpl& buff = binding.m_buffer->getImplementation();
+			InternalBufferBinding& outBinding = out[count];
+
+			outBinding.m_name = buff.getGlName();
+			outBinding.m_offset = binding.m_offset;
+			outBinding.m_range =
+				(binding.m_range != 0)
+				? binding.m_range
+				: (buff.m_size - binding.m_offset);
+
+			ANKI_ASSERT(
+				outBinding.m_offset + outBinding.m_range <= buff.m_size);
+			ANKI_ASSERT(outBinding.m_range > 0);
+
+			++count;
+			++resourcesCount;
+		}
+	}
+}
+
 //==============================================================================
 void ResourceGroupImpl::create(const ResourceGroupInitializer& init)
 {
-	m_in = init;
+	U resourcesCount = 0;
 
 	// Init textures & samplers
-	m_cache.m_textureNamesCount = 0;
-	m_cache.m_allSamplersZero = true;
-	for(U i = 0; i < MAX_TEXTURE_BINDINGS; ++i)
+	m_textureNamesCount = 0;
+	m_allSamplersZero = true;
+	for(U i = 0; i < init.m_textures.getSize(); ++i)
 	{
-		if(m_in.m_textures[i].m_texture.isCreated())
+		if(init.m_textures[i].m_texture.isCreated())
 		{
-			m_cache.m_textureNames[i] =
-				m_in.m_textures[i].m_texture->getImplementation().getGlName();
-			++m_cache.m_textureNamesCount;
+			m_textureNames[i] =
+				init.m_textures[i].m_texture->getImplementation().getGlName();
+			++m_textureNamesCount;
+			++resourcesCount;
 		}
 		else
 		{
-			m_cache.m_textureNames[i] = 0;
+			m_textureNames[i] = 0;
 		}
 
-		if(m_in.m_textures[i].m_sampler.isCreated())
+		if(init.m_textures[i].m_sampler.isCreated())
 		{
-			m_cache.m_samplerNames[i] =
-				m_in.m_textures[i].m_sampler->getImplementation().getGlName();
-			m_cache.m_allSamplersZero = false;
+			m_samplerNames[i] =
+				init.m_textures[i].m_sampler->getImplementation().getGlName();
+			m_allSamplersZero = false;
+			++resourcesCount;
 		}
 		else
 		{
-			m_cache.m_samplerNames[i] = 0;
+			m_samplerNames[i] = 0;
 		}
 	}
 
 	// Init buffers
-	m_cache.m_ubosCount = 0;
-	for(U i = 0; i < MAX_UNIFORM_BUFFER_BINDINGS; ++i)
+	initBuffers(init.m_uniformBuffers, m_ubos, m_ubosCount, resourcesCount);
+	initBuffers(init.m_storageBuffers, m_ssbos, m_ssbosCount, resourcesCount);
+
+	// Init vert buffers
+	m_vertBindingsCount = 0;
+	for(U i = 0; i < init.m_vertexBuffers.getSize(); ++i)
 	{
-		if(m_in.m_uniformBuffers[i].m_buffer.isCreated())
+		const BufferBinding& binding = init.m_vertexBuffers[i];
+		if(binding.m_buffer.isCreated())
 		{
-			++m_cache.m_ubosCount;
+			m_vertBuffNames[i] =
+				binding.m_buffer->getImplementation().getGlName();
+			m_vertBuffOffsets[i] = binding.m_offset;
+
+			++m_vertBindingsCount;
+			++resourcesCount;
 		}
+		else
+		{
+			m_vertBuffNames[i] = 0;
+			m_vertBuffOffsets[i] = 0;
+		}
+	}
+
+	// Init index buffer
+	if(init.m_indexBuffer.m_buffer.isCreated())
+	{
+		const BufferImpl& buff =
+			init.m_indexBuffer.m_buffer->getImplementation();
+
+		ANKI_ASSERT(init.m_indexSize == 2 || init.m_indexSize == 4);
+
+		m_indexBuffName = buff.getGlName();
+		m_indexSize = init.m_indexSize;
+		++resourcesCount;
 	}
 
-	m_cache.m_ssbosCount = 0;
-	for(U i = 0; i < MAX_STORAGE_BUFFER_BINDINGS; ++i)
+	// Hold references
+	initResourceReferences(init, resourcesCount);
+}
+
+//==============================================================================
+void ResourceGroupImpl::initResourceReferences(
+	const ResourceGroupInitializer& init, U refCount)
+{
+	m_refs.create(getAllocator(), refCount);
+
+	U count = 0;
+
+	for(U i = 0; i < init.m_textures.getSize(); ++i)
 	{
-		if(m_in.m_storageBuffers[i].m_buffer.isCreated())
+		if(init.m_textures[i].m_texture.isCreated())
 		{
-			++m_cache.m_ssbosCount;
+			m_refs[count++] = init.m_textures[i].m_texture;
+		}
+
+		if(init.m_textures[i].m_sampler.isCreated())
+		{
+			m_refs[count++] = init.m_textures[i].m_sampler;
 		}
 	}
 
-	// Init vert buffers
-	m_cache.m_vertBindingsCount = 0;
-	for(U i = 0; i < MAX_VERTEX_ATTRIBUTES; ++i)
+	for(U i = 0; i < init.m_uniformBuffers.getSize(); ++i)
 	{
-		const BufferBinding& binding = m_in.m_vertexBuffers[i];
+		const BufferBinding& binding = init.m_uniformBuffers[i];
 		if(binding.m_buffer.isCreated())
 		{
-			m_cache.m_vertBuffNames[i] =
-				binding.m_buffer->getImplementation().getGlName();
-			m_cache.m_vertBuffOffsets[i] = binding.m_offset;
+			m_refs[count++] = binding.m_buffer;
+		}
+	}
 
-			++m_cache.m_vertBindingsCount;
+	for(U i = 0; i < init.m_storageBuffers.getSize(); ++i)
+	{
+		const BufferBinding& binding = init.m_storageBuffers[i];
+		if(binding.m_buffer.isCreated())
+		{
+			m_refs[count++] = binding.m_buffer;
 		}
-		else
+	}
+
+	for(U i = 0; i < init.m_vertexBuffers.getSize(); ++i)
+	{
+		const BufferBinding& binding = init.m_vertexBuffers[i];
+		if(binding.m_buffer.isCreated())
 		{
-			m_cache.m_vertBuffNames[i] = 0;
-			m_cache.m_vertBuffOffsets[i] = 0;
+			m_refs[count++] = binding.m_buffer;
 		}
 	}
+
+	if(init.m_indexBuffer.m_buffer.isCreated())
+	{
+		m_refs[count++] = init.m_indexBuffer.m_buffer;
+	}
+
+	ANKI_ASSERT(refCount == count);
 }
 
 //==============================================================================
 void ResourceGroupImpl::bind(GlState& state)
 {
 	// Bind textures
-	if(m_cache.m_textureNamesCount)
+	if(m_textureNamesCount)
 	{
 		glBindTextures(
-			0, m_cache.m_textureNamesCount, &m_cache.m_textureNames[0]);
+			0, m_textureNamesCount, &m_textureNames[0]);
 
-		if(m_cache.m_allSamplersZero)
+		if(m_allSamplersZero)
 		{
-			glBindSamplers(0, m_cache.m_textureNamesCount, nullptr);
+			glBindSamplers(0, m_textureNamesCount, nullptr);
 		}
 		else
 		{
 			glBindSamplers(
-				0, m_cache.m_textureNamesCount, &m_cache.m_samplerNames[0]);
+				0, m_textureNamesCount, &m_samplerNames[0]);
 		}
 	}
 
 	// Uniform buffers
-	for(U i = 0; i < m_cache.m_ubosCount; ++i)
+	for(U i = 0; i < m_ubosCount; ++i)
 	{
-		const BufferBinding& binding = m_in.m_uniformBuffers[i];
-
-		if(binding.m_buffer.isCreated())
-		{
-			const BufferImpl& buff = binding.m_buffer->getImplementation();
-			PtrSize range = (binding.m_range != 0)
-				? binding.m_range
-				: (buff.m_size - binding.m_offset);
-			buff.bind(GL_UNIFORM_BUFFER, i, binding.m_offset, range);
-		}
+		const auto& binding = m_ubos[i];
+		glBindBufferRange(GL_UNIFORM_BUFFER, i, binding.m_name,
+			binding.m_offset, binding.m_range);
 	}
 
 	// Storage buffers
-	for(U i = 0; i < m_cache.m_ssbosCount; ++i)
+	for(U i = 0; i < m_ssbosCount; ++i)
 	{
-		BufferBinding& binding = m_in.m_storageBuffers[i];
-
-		if(binding.m_buffer.isCreated())
-		{
-			const BufferImpl& buff = binding.m_buffer->getImplementation();
-			PtrSize range = (binding.m_range != 0)
-				? binding.m_range
-				: (buff.m_size - binding.m_offset);
-			buff.bind(GL_SHADER_STORAGE_BUFFER, i, binding.m_offset, range);
-		}
+		const auto& binding = m_ssbos[i];
+		glBindBufferRange(GL_SHADER_STORAGE_BUFFER, i, binding.m_name,
+			binding.m_offset, binding.m_range);
 	}
 
 	// Vertex buffers
-	if(m_cache.m_vertBindingsCount)
+	if(m_vertBindingsCount)
 	{
 		glBindVertexBuffers(
-			0, m_cache.m_vertBindingsCount, &m_cache.m_vertBuffNames[0],
-			&m_cache.m_vertBuffOffsets[0], &state.m_vertexBindingStrides[0]);
+			0, m_vertBindingsCount, &m_vertBuffNames[0],
+			&m_vertBuffOffsets[0], &state.m_vertexBindingStrides[0]);
 	}
 
 	// Index buffer
-	if(m_in.m_indexBuffer.m_buffer.isCreated())
+	if(m_indexSize > 0)
 	{
-		const BufferImpl& buff =
-			m_in.m_indexBuffer.m_buffer->getImplementation();
-		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buff.getGlName());
-
-		ANKI_ASSERT(m_in.m_indexSize == 2 || m_in.m_indexSize == 4);
-		state.m_indexSize = m_in.m_indexSize;
+		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffName);
+		state.m_indexSize = m_indexSize;
 	}
 }