bkaradzic 13 éve
szülő
commit
e866a7b2e3
2 módosított fájl, 153 hozzáadás és 70 törlés
  1. 59 14
      src/renderer_gl.cpp
  2. 94 56
      src/renderer_gl.h

+ 59 - 14
src/renderer_gl.cpp

@@ -720,6 +720,8 @@ namespace bgfx
 	{
 		GL_CHECK(glUseProgram(0) );
 		GL_CHECK(glDeleteProgram(m_id) );
+
+		m_vcref.invalidate(s_renderCtx.m_vaoCache);
 	}
 
 	void Program::init()
@@ -917,6 +919,22 @@ namespace bgfx
 		}
 	}
 
+	void IndexBuffer::destroy()
+	{
+		GL_CHECK(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0) );
+		GL_CHECK(glDeleteBuffers(1, &m_id) );
+
+		m_vcref.invalidate(s_renderCtx.m_vaoCache);
+	}
+
+	void VertexBuffer::destroy()
+	{
+		GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, 0) );
+		GL_CHECK(glDeleteBuffers(1, &m_id) );
+
+		m_vcref.invalidate(s_renderCtx.m_vaoCache);
+	}
+
 	static void texImage(GLenum _target, GLint _level, GLint _internalFormat, GLsizei _width, GLsizei _height, GLsizei _depth, GLint _border, GLenum _format, GLenum _type, const GLvoid* _pixels)
 	{
 #if BGFX_CONFIG_RENDERER_OPENGL|BGFX_CONFIG_RENDERER_OPENGLES3
@@ -1829,7 +1847,7 @@ namespace bgfx
 			}
 
 #if !BGFX_CONFIG_RENDERER_OPENGLES3
-			if (NULL != glVertexAttribDivisor
+			if (false && NULL != glVertexAttribDivisor
 			&&  NULL != glDrawArraysInstanced
 			&&  NULL != glDrawElementsInstanced)
 			{
@@ -1995,6 +2013,13 @@ namespace bgfx
 
 	void Context::rendererSubmit()
 	{
+		if (s_renderCtx.m_vaoSupport)
+		{
+			GL_CHECK(glBindVertexArray(0) );
+		}
+
+		GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, 0) );
+
 		s_renderCtx.updateResolution(m_render->m_resolution);
 
 		int64_t elapsed = -bx::getHPCounter();
@@ -2041,8 +2066,7 @@ namespace bgfx
 		GLenum primType = m_render->m_debug&BGFX_DEBUG_WIREFRAME ? GL_LINES : GL_TRIANGLES;
 		uint32_t primNumVerts = 3;
 		uint32_t baseVertex = 0;
-
-		GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, 0) );
+		GLuint currentVao = 0;
 
 		uint32_t statsNumPrimsSubmitted = 0;
 		uint32_t statsNumIndices = 0;
@@ -2504,19 +2528,22 @@ namespace bgfx
 						}
 					}
 
-					if (s_renderCtx.m_vaoSupport)
+					if (s_renderCtx.m_vaoSupport
+					&&  0 == state.m_startVertex
+					&&  0 == state.m_instanceDataOffset)
 					{
 						if (programChanged
 						||  currentState.m_vertexBuffer.idx != state.m_vertexBuffer.idx
-						||  baseVertex != state.m_startVertex
-						||  currentState.m_indexBuffer.idx != state.m_indexBuffer.idx)
+						||  currentState.m_indexBuffer.idx != state.m_indexBuffer.idx
+						||  currentState.m_instanceDataBuffer.idx != state.m_instanceDataBuffer.idx)
 						{
-							uint64_t hash = (uint64_t(state.m_vertexBuffer.idx)<<48)
-								| (uint64_t(state.m_indexBuffer.idx)<<32)
-								| (uint64_t(state.m_instanceDataBuffer.idx)<<16)
-								| programIdx
-								;
-							hash ^= state.m_startVertex;
+							bx::HashMurmur2A murmur;
+							murmur.begin();
+							murmur.add(state.m_vertexBuffer.idx);
+							murmur.add(state.m_indexBuffer.idx);
+							murmur.add(state.m_instanceDataBuffer.idx);
+							murmur.add(programIdx);
+							uint32_t hash = murmur.end();
 
 							currentState.m_vertexBuffer = state.m_vertexBuffer;
 							currentState.m_indexBuffer = state.m_indexBuffer;
@@ -2525,25 +2552,32 @@ namespace bgfx
 							GLuint id = s_renderCtx.m_vaoCache.find(hash);
 							if (UINT32_MAX != id)
 							{
+								currentVao = id;
 								GL_CHECK(glBindVertexArray(id) );
 							}
 							else
 							{
 								id = s_renderCtx.m_vaoCache.add(hash);
+								currentVao = id;
 								GL_CHECK(glBindVertexArray(id) );
 
+								Program& program = s_renderCtx.m_program[programIdx];
+								program.add(hash);
+
 								if (invalidHandle != state.m_vertexBuffer.idx)
 								{
 									VertexBuffer& vb = s_renderCtx.m_vertexBuffers[state.m_vertexBuffer.idx];
+									vb.add(hash);
 									GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, vb.m_id) );
 
 									uint16_t decl = vb.m_decl.idx == invalidHandle ? state.m_vertexDecl.idx : vb.m_decl.idx;
-									const Program& program = s_renderCtx.m_program[programIdx];
 									program.bindAttributes(s_renderCtx.m_vertexDecls[decl], state.m_startVertex);
 
 									if (invalidHandle != state.m_instanceDataBuffer.idx)
 									{
-										GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, s_renderCtx.m_vertexBuffers[state.m_instanceDataBuffer.idx].m_id) );
+										VertexBuffer& instanceVb = s_renderCtx.m_vertexBuffers[state.m_instanceDataBuffer.idx];
+										instanceVb.add(hash);
+										GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, instanceVb.m_id) );
 										program.bindInstanceData(state.m_instanceDataStride, state.m_instanceDataOffset);
 									}
 								}
@@ -2555,6 +2589,7 @@ namespace bgfx
 								if (invalidHandle != state.m_indexBuffer.idx)
 								{
 									IndexBuffer& ib = s_renderCtx.m_indexBuffers[state.m_indexBuffer.idx];
+									ib.add(hash);
 									GL_CHECK(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ib.m_id) );
 								}
 								else
@@ -2566,6 +2601,16 @@ namespace bgfx
 					}
 					else
 					{
+						if (s_renderCtx.m_vaoSupport
+						&&  0 != currentVao)
+						{
+							GL_CHECK(glBindVertexArray(0) );
+							currentState.m_vertexBuffer.idx = invalidHandle;
+							currentState.m_indexBuffer.idx = invalidHandle;
+							bindAttribs = true;
+							currentVao = 0;
+						}
+
 						if (programChanged
 						||  currentState.m_vertexBuffer.idx != state.m_vertexBuffer.idx)
 						{

+ 94 - 56
src/renderer_gl.h

@@ -178,6 +178,8 @@ typedef void (*PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC)(GLuint shader, GLsizei b
 #	define glClearDepth glClearDepthf
 #endif // !BGFX_CONFIG_RENDERER_OPENGL
 
+#include <set>
+
 namespace bgfx
 {
 	typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBDIVISORBGFXPROC)(GLuint _index, GLuint _divisor);
@@ -229,6 +231,82 @@ namespace bgfx
 	
 	class ConstantBuffer;
 	
+	class VaoCache
+	{
+	public:
+		GLuint add(uint32_t _hash)
+		{
+			invalidate(_hash);
+
+			GLuint arrayId;
+			GL_CHECK(glGenVertexArrays(1, &arrayId) );
+
+			m_hashMap.insert(stl::make_pair(_hash, arrayId) );
+
+			return arrayId;
+		}
+
+		GLuint find(uint32_t _hash)
+		{
+			HashMap::iterator it = m_hashMap.find(_hash);
+			if (it != m_hashMap.end() )
+			{
+				return it->second;
+			}
+
+			return UINT32_MAX;
+		}
+
+		void invalidate(uint32_t _hash)
+		{
+			GL_CHECK(glBindVertexArray(0) );
+
+			HashMap::iterator it = m_hashMap.find(_hash);
+			if (it != m_hashMap.end() )
+			{
+				GL_CHECK(glDeleteVertexArrays(1, &it->second) );
+				m_hashMap.erase(it);
+			}
+		}
+
+		void invalidate()
+		{
+			GL_CHECK(glBindVertexArray(0) );
+
+			for (HashMap::iterator it = m_hashMap.begin(), itEnd = m_hashMap.end(); it != itEnd; ++it)
+			{
+				GL_CHECK(glDeleteVertexArrays(1, &it->second) );
+			}
+			m_hashMap.clear();
+		}
+
+	private:
+		typedef stl::unordered_map<uint32_t, GLuint> HashMap;
+		HashMap m_hashMap;
+	};
+
+	class VaoCacheRef
+	{
+	public:
+		void add(uint32_t _hash)
+		{
+			m_vaoSet.insert(_hash);
+		}
+
+		void invalidate(VaoCache& _vaoCache)
+		{
+			for (VaoSet::iterator it = m_vaoSet.begin(), itEnd = m_vaoSet.end(); it != itEnd; ++it)
+			{
+				_vaoCache.invalidate(*it);
+			}
+
+			m_vaoSet.clear();
+		}
+
+		typedef stl::set<uint32_t> VaoSet;
+		VaoSet m_vaoSet;
+	};
+
 	struct IndexBuffer
 	{
 		void create(uint32_t _size, void* _data)
@@ -257,14 +335,16 @@ namespace bgfx
 			GL_CHECK(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0) );
 		}
 
-		void destroy()
+		void destroy();
+
+		void add(uint32_t _hash)
 		{
-			glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
-			glDeleteBuffers(1, &m_id);
+			m_vcref.add(_hash);
 		}
 
 		GLuint m_id;
 		uint32_t m_size;
+		VaoCacheRef m_vcref;
 	};
 	
 	struct VertexBuffer
@@ -296,65 +376,17 @@ namespace bgfx
 			GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, 0) );
 		}
 
-		void destroy()
+		void destroy();
+
+		void add(uint32_t _hash)
 		{
-			GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, 0) );
-			GL_CHECK(glDeleteBuffers(1, &m_id) );
+			m_vcref.add(_hash);
 		}
 
 		GLuint m_id;
 		uint32_t m_size;
 		VertexDeclHandle m_decl;
-	};
-
-	class VaoCache
-	{
-	public:
-		GLuint add(uint64_t _hash)
-		{
-			invalidate(_hash);
-
-			GLuint arrayId;
-			GL_CHECK(glGenVertexArrays(1, &arrayId) );
-
-			m_hashMap.insert(stl::make_pair(_hash, arrayId) );
-
-			return arrayId;
-		}
-
-		GLuint find(uint64_t _hash)
-		{
-			HashMap::iterator it = m_hashMap.find(_hash);
-			if (it != m_hashMap.end() )
-			{
-				return it->second;
-			}
-
-			return UINT32_MAX;
-		}
-
-		void invalidate(uint64_t _hash)
-		{
-			HashMap::iterator it = m_hashMap.find(_hash);
-			if (it != m_hashMap.end() )
-			{
-				GL_CHECK(glDeleteVertexArrays(1, &it->second) );
-				m_hashMap.erase(it);
-			}
-		}
-
-		void invalidate()
-		{
-			for (HashMap::iterator it = m_hashMap.begin(), itEnd = m_hashMap.end(); it != itEnd; ++it)
-			{
-				GL_CHECK(glDeleteVertexArrays(1, &it->second) );
-			}
-			m_hashMap.clear();
-		}
-
-	private:
-		typedef stl::unordered_map<uint64_t, GLuint> HashMap;
-		HashMap m_hashMap;
+		VaoCacheRef m_vcref;
 	};
 
 	struct Texture
@@ -456,6 +488,11 @@ namespace bgfx
 			m_constantBuffer->commit();
 		}
  
+		void add(uint32_t _hash)
+		{
+			m_vcref.add(_hash);
+		}
+
 		GLuint m_id;
 
 		uint8_t m_used[Attrib::Count+1]; // dense
@@ -468,6 +505,7 @@ namespace bgfx
 		ConstantBuffer* m_constantBuffer;
 		PredefinedUniform m_predefined[PredefinedUniform::Count];
 		uint8_t m_numPredefined;
+		VaoCacheRef m_vcref;
 	};
 
 #if BGFX_CONFIG_RENDERER_OPENGL