Преглед изворни кода

Added ref counting for shaders used by material.

bkaradzic пре 13 година
родитељ
комит
3bb48b4ab2
3 измењених фајлова са 87 додато и 60 уклоњено
  1. 52 44
      src/bgfx_p.h
  2. 4 2
      src/renderer_d3d11.cpp
  3. 31 14
      tools/shaderc.cpp

+ 52 - 44
src/bgfx_p.h

@@ -1334,33 +1334,6 @@ namespace bgfx
 		bool m_discard;
 		bool m_discard;
 	};
 	};
 
 
-	struct MaterialRef
-	{
-		MaterialRef()
-		{
-		}
-
-		MaterialHandle find(uint32_t _hash)
-		{
-			MaterialMap::const_iterator it = m_materialMap.find(_hash);
-			if (it != m_materialMap.end() )
-			{
-				return it->second;
-			}
-
-			MaterialHandle result = BGFX_INVALID_HANDLE;
-			return result;
-		}
-
-		void add(MaterialHandle _handle, uint32_t _hash)
-		{
-			m_materialMap.insert(stl::make_pair(_hash, _handle) );
-		}
-
-		typedef stl::unordered_map<uint32_t, MaterialHandle> MaterialMap;
-		MaterialMap m_materialMap;
-	};
-
 	struct VertexDeclRef
 	struct VertexDeclRef
 	{
 	{
 		VertexDeclRef()
 		VertexDeclRef()
@@ -1928,6 +1901,7 @@ namespace bgfx
 		VertexShaderHandle createVertexShader(const Memory* _mem)
 		VertexShaderHandle createVertexShader(const Memory* _mem)
 		{
 		{
 			VertexShaderHandle handle = { m_vertexShaderHandle.alloc() };
 			VertexShaderHandle handle = { m_vertexShaderHandle.alloc() };
+			m_vertexShaderRef[handle.idx] = 1;
 			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateVertexShader);
 			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateVertexShader);
 			cmdbuf.write(handle);
 			cmdbuf.write(handle);
 			cmdbuf.write(_mem);
 			cmdbuf.write(_mem);
@@ -1936,14 +1910,29 @@ namespace bgfx
 
 
 		void destroyVertexShader(VertexShaderHandle _handle)
 		void destroyVertexShader(VertexShaderHandle _handle)
 		{
 		{
-			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::DestroyVertexShader);
-			cmdbuf.write(_handle);
-			m_submit->free(_handle);
+			vertexShaderDecRef(_handle);
+		}
+
+		void vertexShaderIncRef(VertexShaderHandle _handle)
+		{
+			++m_vertexShaderRef[_handle.idx];
+		}
+
+		void vertexShaderDecRef(VertexShaderHandle _handle)
+		{
+			int32_t refs = --m_vertexShaderRef[_handle.idx];
+			if (0 == refs)
+			{
+				CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::DestroyVertexShader);
+				cmdbuf.write(_handle);
+				m_submit->free(_handle);
+			}
 		}
 		}
 
 
 		FragmentShaderHandle createFragmentShader(const Memory* _mem)
 		FragmentShaderHandle createFragmentShader(const Memory* _mem)
 		{
 		{
 			FragmentShaderHandle handle = { m_fragmentShaderHandle.alloc() };
 			FragmentShaderHandle handle = { m_fragmentShaderHandle.alloc() };
+			m_fragmentShaderRef[handle.idx] = 1;
 			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateFragmentShader);
 			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateFragmentShader);
 			cmdbuf.write(handle);
 			cmdbuf.write(handle);
 			cmdbuf.write(_mem);
 			cmdbuf.write(_mem);
@@ -1952,25 +1941,34 @@ namespace bgfx
 
 
 		void destroyFragmentShader(FragmentShaderHandle _handle)
 		void destroyFragmentShader(FragmentShaderHandle _handle)
 		{
 		{
-			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::DestroyFragmentShader);
-			cmdbuf.write(_handle);
-			m_submit->free(_handle);
+			fragmentShaderDecRef(_handle);
+		}
+
+		void fragmentShaderIncRef(FragmentShaderHandle _handle)
+		{
+			++m_fragmentShaderRef[_handle.idx];
+		}
+
+		void fragmentShaderDecRef(FragmentShaderHandle _handle)
+		{
+			int32_t refs = --m_fragmentShaderRef[_handle.idx];
+			if (0 == refs)
+			{
+				CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::DestroyFragmentShader);
+				cmdbuf.write(_handle);
+				m_submit->free(_handle);
+			}
 		}
 		}
 
 
 		MaterialHandle createMaterial(VertexShaderHandle _vsh, FragmentShaderHandle _fsh)
 		MaterialHandle createMaterial(VertexShaderHandle _vsh, FragmentShaderHandle _fsh)
 		{
 		{
 			MaterialHandle handle;
 			MaterialHandle handle;
-// 			uint32_t hash = _vsh.idx<<16 | _fsh.idx;
-// 
-// 			MaterialHandle handle = m_materialRef.find(hash);
-// 
-// 			if (invalidHandle != handle.idx)
-// 			{
-// 				return handle;
-// 			}
-// 
  			handle.idx = m_materialHandle.alloc();
  			handle.idx = m_materialHandle.alloc();
-// 			m_materialRef.add(handle, hash);
+
+			vertexShaderIncRef(_vsh);
+			fragmentShaderIncRef(_fsh);
+			m_materialRef[handle.idx].m_vsh = _vsh;
+			m_materialRef[handle.idx].m_fsh = _fsh;
 
 
 			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateMaterial);
 			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateMaterial);
 			cmdbuf.write(handle);
 			cmdbuf.write(handle);
@@ -1984,6 +1982,9 @@ namespace bgfx
 			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::DestroyMaterial);
 			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::DestroyMaterial);
 			cmdbuf.write(_handle);
 			cmdbuf.write(_handle);
 			m_submit->free(_handle);
 			m_submit->free(_handle);
+
+			vertexShaderDecRef(m_materialRef[_handle.idx].m_vsh);
+			fragmentShaderDecRef(m_materialRef[_handle.idx].m_fsh);
 		}
 		}
 
 
 		TextureHandle createTexture(const Memory* _mem, uint32_t _flags, uint16_t* _width, uint16_t* _height)
 		TextureHandle createTexture(const Memory* _mem, uint32_t _flags, uint16_t* _width, uint16_t* _height)
@@ -2787,7 +2788,14 @@ namespace bgfx
 		HandleAlloc m_renderTargetHandle;
 		HandleAlloc m_renderTargetHandle;
 		HandleAlloc m_uniformHandle;
 		HandleAlloc m_uniformHandle;
 
 
-		MaterialRef m_materialRef;
+		int32_t m_vertexShaderRef[BGFX_CONFIG_MAX_VERTEX_SHADERS];
+		int32_t m_fragmentShaderRef[BGFX_CONFIG_MAX_FRAGMENT_SHADERS];
+		struct MaterialRef
+		{
+			VertexShaderHandle m_vsh;
+			FragmentShaderHandle m_fsh;
+		};
+		MaterialRef m_materialRef[BGFX_CONFIG_MAX_MATERIALS];
 		VertexDeclRef m_declRef;
 		VertexDeclRef m_declRef;
 
 
 		RenderTargetHandle m_rt[BGFX_CONFIG_MAX_VIEWS];
 		RenderTargetHandle m_rt[BGFX_CONFIG_MAX_VIEWS];

+ 4 - 2
src/renderer_d3d11.cpp

@@ -541,8 +541,9 @@ namespace bgfx
 			{
 			{
 				D3D11_INPUT_ELEMENT_DESC vertexElements[Attrib::Count+1+BGFX_CONFIG_MAX_INSTANCE_DATA_COUNT];
 				D3D11_INPUT_ELEMENT_DESC vertexElements[Attrib::Count+1+BGFX_CONFIG_MAX_INSTANCE_DATA_COUNT];
 				D3D11_INPUT_ELEMENT_DESC* elem = fillVertexDecl(vertexElements, Attrib::Count, _vertexDecl);
 				D3D11_INPUT_ELEMENT_DESC* elem = fillVertexDecl(vertexElements, Attrib::Count, _vertexDecl);
-				/*DX_CHECK*/(m_device->CreateInputLayout(vertexElements
-					, uint32_t(elem-vertexElements)
+				ptrdiff_t num = elem-vertexElements;
+				DX_CHECK(m_device->CreateInputLayout(vertexElements
+					, uint32_t(num)
 					, _material.m_vsh->m_code->data
 					, _material.m_vsh->m_code->data
 					, _material.m_vsh->m_code->size
 					, _material.m_vsh->m_code->size
 					, &layout
 					, &layout
@@ -1162,6 +1163,7 @@ namespace bgfx
 		m_constantBuffer->finish();
 		m_constantBuffer->finish();
 
 
 		const DWORD* code = (const DWORD*)stream.getDataPtr();
 		const DWORD* code = (const DWORD*)stream.getDataPtr();
+		stream.skip(shaderSize);
 
 
 		if (_fragment)
 		if (_fragment)
 		{
 		{

+ 31 - 14
tools/shaderc.cpp

@@ -3,6 +3,8 @@
  * License: http://www.opensource.org/licenses/BSD-2-Clause
  * License: http://www.opensource.org/licenses/BSD-2-Clause
  */
  */
 
 
+#define SHADERC_DEBUG 0
+
 #define NOMINMAX
 #define NOMINMAX
 #include <stdio.h>
 #include <stdio.h>
 #include <stdint.h>
 #include <stdint.h>
@@ -19,7 +21,7 @@ extern "C"
 #include <fpp.h>
 #include <fpp.h>
 } // extern "C"
 } // extern "C"
 
 
-#if 1
+#if SHADERC_DEBUG
 #	define BX_TRACE(_format, ...) fprintf(stderr, "" _format "\n", ##__VA_ARGS__)
 #	define BX_TRACE(_format, ...) fprintf(stderr, "" _format "\n", ##__VA_ARGS__)
 #endif // DEBUG
 #endif // DEBUG
 
 
@@ -251,6 +253,15 @@ public:
 		write(&_value, sizeof(Ty) );
 		write(&_value, sizeof(Ty) );
 	}
 	}
 
 
+	void writeString(const char* _str)
+	{
+		uint16_t len = (uint16_t)strlen(_str);
+		write(len);
+		write(_str);
+		char term = '\0';
+		write(term);
+	}
+
 // 	template<typename Ty>
 // 	template<typename Ty>
 // 	void write(Ty _value)
 // 	void write(Ty _value)
 // 	{
 // 	{
@@ -1339,27 +1350,33 @@ int main(int _argc, const char* _argv[])
 				}
 				}
 			}
 			}
 
 
+#if SHADERC_DEBUG
+			stream->writeString(filePath);
+#endif // SHADERC_DEBUG
+
 			stream->close();
 			stream->close();
 			delete stream;
 			delete stream;
 		}
 		}
 
 
-		if (compiled
-		&&  depends)
+		if (compiled)
 		{
 		{
-			std::string ofp = outFilePath;
-			ofp += ".d";
-			FileWriter stream(ofp.c_str() );
-			if (stream.open() )
+			if (depends)
 			{
 			{
-				stream.write(outFilePath);
-				stream.write(":");
-				stream.write(preprocessor.m_depends.c_str() );
-				stream.write("\n");
-				stream.close();
+				std::string ofp = outFilePath;
+				ofp += ".d";
+				FileWriter stream(ofp.c_str() );
+				if (stream.open() )
+				{
+					stream.write(outFilePath);
+					stream.write(":");
+					stream.write(preprocessor.m_depends.c_str() );
+					stream.write("\n");
+					stream.close();
+				}
 			}
 			}
-		}
 
 
-		return EXIT_SUCCESS;
+			return EXIT_SUCCESS;
+		}
 	}
 	}
 
 
 	fprintf(stderr, "Failed to build shader.\n");
 	fprintf(stderr, "Failed to build shader.\n");